if args.dirichlet and not args.neumann: problem = ProblemType.DIRICHLET domain_part = DomainPart.LEFT elif args.neumann and not args.dirichlet: problem = ProblemType.NEUMANN domain_part = DomainPart.RIGHT mesh, coupling_boundary, remaining_boundary = get_geometry(domain_part) # Define function space using mesh V = FunctionSpace(mesh, 'P', 2) V_g = VectorFunctionSpace(mesh, 'P', 1) W = V_g.sub(0).collapse() # Define boundary conditions u_D = Expression('1 + x[0]*x[0] + alpha*x[1]*x[1] + beta*t', degree=2, alpha=alpha, beta=beta, t=0) u_D_function = interpolate(u_D, V) if problem is ProblemType.DIRICHLET: # Define flux in x direction f_N = Expression("2 * x[0]", degree=1, alpha=alpha, t=0) f_N_function = interpolate(f_N, W) # Define initial value u_n = interpolate(u_D, V) u_n.rename("Temperature", "") precice, precice_dt, initial_data = None, 0.0, None # Initialize the adapter according to the specific participant if problem is ProblemType.DIRICHLET:
def compute_conv_diff_reac_video(self, initial_condition=None, video_ref=None, video_size=None): names = {'Cl', 'K'} P1 = FiniteElement('P', fe.triangle, 1) element = fe.MixedElement([P1, P1]) V_single = FunctionSpace(self.mesh, P1) V = FunctionSpace(self.mesh, element) self.V_conc = V # load video video = VideoData(element=P1) video.load_video(self.video_filename) if( video_ref is not None and video_size is not None): video.set_reference_frame(video_ref, video_size) print(video) dt = 0.05 t = 0. t_end = 20. u_init = Function(V) (u_cl, u_k) = TrialFunction(V) (v_cl, v_k) = TestFunction(V) #u_na = video if initial_condition is None: #initial_condition = Expression(("f*exp(-0.5*((x[0]-a)*(x[0]-a)+(x[1]-b)*(x[1]-b))/var)/(sqrt(2*pi)*var)", # "0."), a = 80, b= 55, var=10, f=10, pi=fe.pi, element=element) initial_condition = Expression(("f", "0."), a=80, b=55, var=0.1, f=0.1, pi=fe.pi, element=element) u_init = fe.interpolate(initial_condition, V) u_init_cl = u_init[0] u_init_k = u_init[1] u_init_na : VideoData= video assert (self.flow is not None) n = fe.FacetNormal(self.mesh) dx, ds = self.dx, self.ds flow = 5. * self.flow f_in = fe.Constant(0.00) f_in_cl = fe.Constant(-0.05) D = fe.Constant(0.1) C_na = fe.Constant(0.1) k1 = fe.Constant(0.2) k_1 = fe.Constant(0.00001) # explicit F = ( (u_cl - u_init_cl) * v_cl * dx + dt * D * inner(grad(u_cl), grad(v_cl)) * dx + dt * inner(flow, grad(u_cl)) * v_cl * dx #+ (u_na - u_init_na) * v_na * dx #+ dt * D * inner(grad(u_na), grad(v_na)) * dx #+ dt * inner(flow, grad(u_na)) * v_na * dx + (u_k - u_init_k) * v_k * dx + dt * D * inner(grad(u_k), grad(v_k)) * dx + dt * inner(flow, grad(u_k)) * v_k * dx + f_in_cl * v_cl * dx #+ f_in * v_na * dx + f_in * v_k * dx + dt * k1 * u_init_cl * C_na * u_init_na * v_cl * dx #+ dt * k1 * u_init_cl * u_init_na * v_na * dx - dt * k1 * u_init_cl * C_na * u_init_na * v_k * dx - dt * k_1 * u_init_k * v_cl * dx #- dt * k_1 * u_init_k * v_na * dx + dt * k_1 * u_init_k * v_k * dx ) # implicit F = ( (u_cl - u_init_cl) * v_cl * dx + dt * D * inner(grad(u_cl), grad(v_cl)) * dx + dt * inner(flow, grad(u_cl)) * v_cl * dx # + (u_na - u_init_na) * v_na * dx # + dt * D * inner(grad(u_na), grad(v_na)) * dx # + dt * inner(flow, grad(u_na)) * v_na * dx + (u_k - u_init_k) * v_k * dx + dt * D * inner(grad(u_k), grad(v_k)) * dx + dt * inner(flow, grad(u_k)) * v_k * dx + f_in_cl * v_cl * dx # + f_in * v_na * dx + f_in * v_k * dx + dt * k1 * u_cl * C_na * u_init_na * v_cl * dx # + dt * k1 * u_init_cl * u_init_na * v_na * dx - dt * k1 * u_cl * C_na * u_init_na * v_k * dx - dt * k_1 * u_k * v_cl * dx # - dt * k_1 * u_init_k * v_na * dx + dt * k_1 * u_k * v_k * dx ) self.F = F a, L = fe.lhs(F), fe.rhs(F) a_mat = fe.assemble(a) L_vec = fe.assemble(L) output1 = fe.File('/tmp/cl_dyn.pvd') output2 = fe.File('/tmp/na_dyn.pvd') output3 = fe.File('/tmp/k_dyn.pvd') output4 = fe.File('/tmp/all_dyn.pvd') # solve self.sol = [] u_na = Function(V_single) u_na = fe.interpolate(u_init_na,V_single) na_inflow = 0 t_plot = 0.5 t_last_plot = 0 while t < t_end: t = t + dt t_last_plot += dt print(t) u = Function(V) u_init_na.set_time(5*t) a_mat = fe.assemble(a) L_vec = fe.assemble(L) fe.solve(a_mat, u.vector(), L_vec) # NonlinearVariationalProblem(F,u) u_init.assign(u) u_cl, u_k = u.split() # u_init_cl.assign(u_cl) # u_init_na.assign(u_na) # u_init_k.assign(u_k) u_na = fe.interpolate(u_init_na, V_single) u_cl.rename("cl", "cl") u_na.rename("na", "na") u_k.rename("k", "k") output1 << u_cl, t output2 << u_na, t output3 << u_k, t self.sol.append((u_cl, u_na, u_k)) print( fe.assemble(u_cl*self.dx)) if t_last_plot > t_plot: t_last_plot = 0 plt.figure(figsize=(8,16)) plt.subplot(211) fe.plot(u_cl) plt.subplot(212) fe.plot(u_k) plt.show() self.u_cl = u_cl #self.u_na = u_na self.u_k = u_k
x_coupling = 1.5 # x coordinate of coupling interface if problem is ProblemType.DIRICHLET: p0 = Point(x_left, y_bottom) p1 = Point(x_coupling, y_top) elif problem is ProblemType.NEUMANN: p0 = Point(x_coupling, y_bottom) p1 = Point(x_right, y_top) mesh = RectangleMesh(p0, p1, nx, ny) V = FunctionSpace(mesh, 'P', 1) # Define boundary condition u_D = Expression('1 + x[0]*x[0] + alpha*x[1]*x[1] + beta*t', degree=2, alpha=alpha, beta=beta, t=0) u_D_function = interpolate(u_D, V) # Define flux in x direction on coupling interface (grad(u_D) in normal direction) f_N = Expression('2 * x[0]', degree=1) f_N_function = interpolate(f_N, V) coupling_boundary = CouplingBoundary() remaining_boundary = ComplementaryBoundary(coupling_boundary) precice = Adapter() precice.configure( solver_name, config_file_name, coupling_mesh_name, write_data_name, read_data_name ) # TODO in the future we want to remove this function and read these variables from a config file. See #5
def compute_conv_diff_reac(self, initial_condition=None): names = {'Cl', 'Na', 'K'} dt = 0.1 t = 0. t_end = 1. P1 = FiniteElement('P', fe.triangle, 3) element = MixedElement([P1, P1, P1]) V = FunctionSpace(self.mesh, element) self.V_conc = V u_init = Function(V) (u_cl, u_na, u_k) = TrialFunction(V) (v_cl, v_na, v_k) = TestFunction(V) if initial_condition is None: initial_condition = Expression(("exp(-((x[0]-0.1)*(x[0]-0.1)+x[1]*x[1])/0.01)", "exp(-((x[0]-0.12)*(x[0]-0.12)+x[1]*x[1])/0.01)", "0."), element=element) u_init = fe.interpolate(initial_condition, V) u_init_cl = u_init[0] u_init_na = u_init[1] u_init_k = u_init[2] assert (self.flow is not None) n = fe.FacetNormal(self.mesh) dx, ds = self.dx, self.ds flow = 10 * self.flow f_in = fe.Constant(0.00) D = fe.Constant(0.01) k1 = fe.Constant(0.1) k_1 = fe.Constant(0.001) F = ( (u_cl - u_init_cl) * v_cl * dx + dt * D * inner(grad(u_cl), grad(v_cl)) * dx + dt * inner(flow, grad(u_cl)) * v_cl * dx + (u_na - u_init_na) * v_na * dx + dt * D * inner(grad(u_na), grad(v_na)) * dx + dt * inner(flow, grad(u_na)) * v_na * dx + (u_k - u_init_k) * v_k * dx + dt * D * inner(grad(u_k), grad(v_k)) * dx + dt * inner(flow, grad(u_k)) * v_k * dx + f_in * v_cl * dx + f_in * v_na * dx + f_in * v_k * dx + dt * k1 * u_init_cl * u_init_na * v_cl * dx + dt * k1 * u_init_cl * u_init_na * v_na * dx - dt * k1 * u_init_cl * u_init_na * v_k * dx - dt * k_1 * u_init_k * v_cl * dx - dt * k_1 * u_init_k * v_na * dx + dt * k_1 * u_init_k * v_k * dx ) self.F = F a, L = fe.lhs(F), fe.rhs(F) a_mat = fe.assemble(a) L_vec = fe.assemble(L) output1 = fe.File('/tmp/cl_dyn.pvd') output2 = fe.File('/tmp/na_dyn.pvd') output3 = fe.File('/tmp/k_dyn.pvd') output4 = fe.File('/tmp/all_dyn.pvd') # solve self.sol = [] while t < t_end: t = t + dt print(t) u = Function(V) a_mat = fe.assemble(a) L_vec = fe.assemble(L) fe.solve(a_mat, u.vector(), L_vec) # NonlinearVariationalProblem(F,u) u_init.assign(u) u_cl, u_na, u_k = u.split() # u_init_cl.assign(u_cl) # u_init_na.assign(u_na) # u_init_k.assign(u_k) u_cl.rename("cl", "cl") u_na.rename("na", "na") u_k.rename("k", "k") output1 << u_cl, t output2 << u_na, t output3 << u_k, t self.sol.append((u_cl, u_na, u_k)) self.u_cl = u_cl self.u_na = u_na self.u_k = u_k
# BCs tol = 1E-14 # Trial and Test Functions du = TrialFunction(V) v = TestFunction(V) u_np1 = Function(V) saved_u_old = Function(V) # function known from previous timestep u_n = Function(V) v_n = Function(V) a_n = Function(V) f_N_function = interpolate(Expression(("1", "0"), degree=1), V) u_function = interpolate(Expression(("0", "0"), degree=1), V) coupling_boundary = AutoSubDomain(neumann_boundary) precice = Adapter(adapter_config_filename="precice-adapter-config-fsi-s.json") clamped_boundary_domain = AutoSubDomain(clamped_boundary) force_boundary = AutoSubDomain(neumann_boundary) # Initialize the coupling interface precice_dt = precice.initialize(coupling_boundary, mesh, V, dim) fenics_dt = precice_dt # if fenics_dt == precice_dt, no subcycling is applied # fenics_dt = 0.02 # if fenics_dt < precice_dt, subcycling is applied dt = Constant(np.min([precice_dt, fenics_dt]))
def __init__( self, mesh=None, width=1.0, dim=1, nelements=8, degree=2, parameters={}, V=(lambda U: U), U0=[], rho0=None, t0=0.0, debug=False, solver_type = 'gmres', preconditioner_type = 'default', periodic=False, ligands=None ): """Discontinuous Galerkin solver for the Keller-Segel PDE system Keyword parameters: mesh=None: the mesh on which to solve the problem width=1.0: the width of the domain dim=1: # of spatial dimensions. nelements=8: If mesh is not supplied, one will be contructed using UnitIntervalMesh, UnitSquareMesh, or UnitCubeMesh (depending on dim). dim and nelements are not needed if mesh is supplied. degree=2: degree of the polynomial approximation parameters={}: a dict giving the values of scalar parameters of .V, U0, and rho0 Expressions. This dict needs to also define numerical parameters that appear in the PDE. Some of these have defaults: dim = dim: # of spatial dimensions sigma: organism movement rate rho_min=10.0**-7: minimum feasible worm density U_min=10.0**-7: minimum feasible attractant concentration rhopen=10: penalty for discontinuities in rho Upen=1: penalty for discontinuities in U grhopen=1, gUpen=1: penalties for discontinuities in gradients nligands=1, number of ligands V=(lambda Us: Us): a callable taking two arguments, Us and rho, or a single argument, Us. Us is a list of length nligands. rho is a single expression. V returns a single number, V, the potential corresponding to Us (and rho). Use ufl versions of mathematical functions, e.g. ufl.ln, abs, ufl.exp. rho0: Expressions, Functions, or strs specifying the initial condition for rho. U0: a list of nligands Expressions, Functions or strs specifying the initial conditions for the ligands. t0=0.0: initial time solver_type='gmres' preconditioner_type='default' ligands=LigandGroups(): ligand list periodic=False: ignored for compatibility """ logMULTIPLE('creating KSDGSolverMultiple') if not ligands: ligands = LigandGroups() else: ligands = copy.deepcopy(ligands) self.args = dict( mesh=mesh, width=width, dim=dim, nelements=nelements, degree=degree, parameters=parameters, V=V, U0=U0, rho0=rho0, t0=t0, debug=debug, solver_type = solver_type, preconditioner_type = preconditioner_type, periodic=periodic, ligands=ligands ) self.debug = debug self.solver_type = solver_type self.preconditioner_type = preconditioner_type self.periodic = False self.ligands = ligands self.nligands = ligands.nligands() self.params = self.default_params.copy() if (mesh): self.omesh = self.mesh = mesh else: self.omesh = self.mesh = box_mesh(width=width, dim=dim, nelements=nelements) self.nelements = nelements logMULTIPLE('self.mesh', self.mesh) logMULTIPLE('self.mesh.mpi_comm().size', self.mesh.mpi_comm().size) self.nelements = nelements self.degree = degree self.dim = self.mesh.geometry().dim() self.params['dim'] = self.dim self.params.update(parameters) # # Solution spaces and Functions # fss = self.make_function_space() (self.SE, self.SS, self.VE, self.VS) = [ fss[fs] for fs in ('SE', 'SS', 'VE', 'VS') ] logMULTIPLE('self.VS', self.VS) self.sol = Function(self.VS) # sol, current soln logMULTIPLE('self.sol', self.sol) self.srho, self.sUs = self.sol.sub(0), self.sol.split()[1:] splitsol = fe.split(self.sol) self.irho, self.iUs = splitsol[0], splitsol[1:] tfs = TestFunctions(self.VS) self.wrho, self.wUs = tfs[0], tfs[1:] self.tdsol = TrialFunction(self.VS) splittdsol = fe.split(self.tdsol) self.tdrho, self.tdUs = splittdsol[0], splittdsol[1:] self.n = FacetNormal(self.mesh) self.h = CellDiameter(self.mesh) self.havg = fe.avg(self.h) self.dx = fe.dx # self.dx = fe.dx(metadata={'quadrature_degree': min(degree, 10)}) self.dS = fe.dS # self.dS = fe.dS(metadata={'quadrature_degree': min(degree, 10)}) # # record initial state # try: V(self.iUs, self.irho) def realV(Us, rho): return V(Us, rho) except TypeError: def realV(Us, rho): return V(Us) self.V = realV if not U0: U0 = [Constant(0.0)] * self.nligands self.U0s = [Constant(0.0)] * self.nligands for i,U0i in enumerate(U0): if isinstance(U0i, ufl.coefficient.Coefficient): self.U0s[i] = U0i else: self.U0s[i] = Expression(U0i, **self.params, degree=self.degree, domain=self.mesh) if not rho0: rho0 = Constant(0.0) if isinstance(rho0, ufl.coefficient.Coefficient): self.rho0 = rho0 else: self.rho0 = Expression(rho0, **self.params, degree=self.degree, domain=self.mesh) self.t0 = t0 # # initialize state # logMULTIPLE('restarting') self.restart() logMULTIPLE('restart returned') return(None)
beta = 1.3 # parameter beta gamma = args.gamma # parameter gamma, dependence of heat flux on time # Create mesh and separate mesh components for grid, boundary and coupling interface domain_part, problem = get_problem_setup(args) mesh, coupling_boundary, remaining_boundary = get_geometry(domain_part) # Define function space using mesh V = FunctionSpace(mesh, 'P', 2) V_g = VectorFunctionSpace(mesh, 'P', 1) # Define boundary conditions u_D = Expression( '1 + gamma*t*x[0]*x[0] + (1-gamma)*x[0]*x[0] + alpha*x[1]*x[1] + beta*t', degree=2, alpha=alpha, beta=beta, gamma=gamma, t=0) u_D_function = interpolate(u_D, V) # Define flux in x direction on coupling interface (grad(u_D) in normal direction) f_N = Expression(("2 * gamma*t*x[0] + 2 * (1-gamma)*x[0]", "2 * alpha*x[1]"), degree=1, gamma=gamma, alpha=alpha, t=0) f_N_function = interpolate(f_N, V_g) # Define initial value u_n = interpolate(u_D, V) u_n.rename("Temperature", "")
from cslvr import * from fenics import Point, BoxMesh, Expression, sqrt, pi alpha = 0.5 * pi / 180 L = 10000 p1 = Point(0.0, 0.0, 0.0) p2 = Point(L, L, 1) mesh = BoxMesh(p1, p2, 15, 15, 10) model = D3Model(mesh, out_dir='./ISMIP_HOM_A_results/', use_periodic=True) surface = Expression('- x[0] * tan(alpha)', alpha=alpha, element=model.Q.ufl_element()) bed = Expression( '- x[0] * tan(alpha) - 1000.0 + 500.0 * ' \ + ' sin(2*pi*x[0]/L) * sin(2*pi*x[1]/L)', alpha=alpha, L=L, element=model.Q.ufl_element()) model.calculate_boundaries() model.deform_mesh_to_geometry(surface, bed) model.init_mask(1.0) # all grounded model.init_beta(1000) model.init_A(1e-16) model.init_E(1.0) #mom = MomentumBP(model) #mom = MomentumDukowiczBP(model) mom = MomentumDukowiczStokesReduced(model) #mom = MomentumDukowiczBrinkerhoffStokes(model)