def delta_dg(mesh, expr): CG = df.FunctionSpace(mesh, "CG", 1) DG = df.FunctionSpace(mesh, "DG", 0) CG3 = df.VectorFunctionSpace(mesh, "CG", 1) DG3 = df.VectorFunctionSpace(mesh, "DG", 0) m = df.interpolate(expr, DG3) n = df.FacetNormal(mesh) u_dg = df.TrialFunction(DG) v_dg = df.TestFunction(DG) u3 = df.TrialFunction(CG3) v3 = df.TestFunction(CG3) a = u_dg * df.inner(v3, n) * df.ds - u_dg * df.div(v3) * df.dx mm = m.vector().array() mm.shape = (3, -1) K = df.assemble(a).array() L3 = df.assemble(df.dot(v3, df.Constant([1, 1, 1])) * df.dx).array() f = np.dot(K, mm[0]) / L3 fun1 = df.Function(CG3) fun1.vector().set_local(f) df.plot(fun1) a = df.div(u3) * v_dg * df.dx A = df.assemble(a).array() L = df.assemble(v_dg * df.dx).array() h = np.dot(A, f) / L fun = df.Function(DG) fun.vector().set_local(h) df.plot(fun) res = [] for x in xs: res.append(fun(x, 5, 0.5)) """ fun2 =df.interpolate(fun, df.VectorFunctionSpace(mesh, "CG", 1)) file = df.File('field2.pvd') file << fun2 """ return res
def __init__(self, Vh, dX, bcs, form=None): """ Constructor: :code:`Vh`: the finite element space for the state variable. :code:`dX`: the integrator on subdomain `X` where observation are presents. \ E.g. :code:`dX = dl.dx` means observation on all :math:`\Omega` and :code:`dX = dl.ds` means observations on all :math:`\partial \Omega`. :code:`bcs`: If the forward problem imposes Dirichlet boundary conditions :math:`u = u_D \mbox{ on } \Gamma_D`; \ :code:`bcs` is a list of :code:`dolfin.DirichletBC` object that prescribes homogeneuos Dirichlet conditions :math:`u = 0 \mbox{ on } \Gamma_D`. :code:`form`: if :code:`form = None` we compute the :math:`L^2(X)` misfit: :math:`\int_X (u - u_d)^2 dX,` \ otherwise the integrand specified in the given form will be used. """ if form is None: u, v = dl.TrialFunction(Vh), dl.TestFunction(Vh) self.W = dl.assemble(dl.inner(u, v) * dX) else: self.W = dl.assemble(form) if bcs is None: bcs = [] if isinstance(bcs, dl.DirichletBC): bcs = [bcs] if len(bcs): Wt = Transpose(self.W) [bc.zero(Wt) for bc in bcs] self.W = Transpose(Wt) [bc.zero(self.W) for bc in bcs] self.d = dl.Vector(self.W.mpi_comm()) self.W.init_vector(self.d, 1) self.noise_variance = None
def test_custom_mesh_loop_rank1(): # Create mesh and function space mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 64, 64) V = dolfin.FunctionSpace(mesh, ("Lagrange", 1)) # Unpack mesh and dofmap data c = mesh.topology.connectivity(2, 0).connections() pos = mesh.topology.connectivity(2, 0).pos() geom = mesh.geometry.points dofs = V.dofmap().dof_array # Assemble with pure Numba function (two passes, first will include JIT overhead) b0 = dolfin.Function(V) for i in range(2): with b0.vector().localForm() as b: b.set(0.0) start = time.time() assemble_vector(np.asarray(b), (c, pos), geom, dofs) end = time.time() print("Time (numba, pass {}): {}".format(i, end - start)) b0.vector().ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert (b0.vector().sum() == pytest.approx(1.0)) # Test against generated code and general assembler v = dolfin.TestFunction(V) L = inner(1.0, v) * dx start = time.time() b1 = dolfin.fem.assemble_vector(L) end = time.time() print("Time (C++, pass 1):", end - start) with b1.localForm() as b_local: b_local.set(0.0) start = time.time() dolfin.fem.assemble_vector(b1, L) end = time.time() print("Time (C++, passs 2):", end - start) b1.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert ((b1 - b0.vector()).norm() == pytest.approx(0.0)) # Assemble using generated tabulate_tensor kernel and Numba assembler b3 = dolfin.Function(V) ufc_form = dolfin.jit.ffc_jit(L) kernel = ufc_form.create_cell_integral(-1).tabulate_tensor for i in range(2): with b3.vector().localForm() as b: b.set(0.0) start = time.time() assemble_vector_ufc(np.asarray(b), kernel, (c, pos), geom, dofs) end = time.time() print("Time (numba/cffi, pass {}): {}".format(i, end - start)) b3.vector().ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert ((b3.vector() - b0.vector()).norm() == pytest.approx(0.0))
def interactive_impulse_response_plot(apply_A, function_space_V, print_point=True): # Usage: # https://github.com/NickAlger/nalger_helper_functions/tree/master/nalger_helper_functions/interactive_impulse_response_plot.py fig = plt.figure() c = dl.plot(dl.Function(function_space_V)) plt.colorbar(c) plt.title('left click adds points, right click resets') point_source_dual_vector = dl.assemble(dl.Constant(0.0) * dl.TestFunction(function_space_V) * dl.dx) Adelta = dl.Function(function_space_V) def onclick(event): if print_point: print('(', event.xdata, ',', event.ydata, ')') delta_p = dl.PointSource(function_space_V, dl.Point(event.xdata, event.ydata), 1.0) if event.button == 3: point_source_dual_vector[:] = 0. delta_p.apply(point_source_dual_vector) Adelta.vector()[:] = apply_A(point_source_dual_vector) plt.clf() c = dl.plot(Adelta) plt.colorbar(c) plt.title('left click adds points, right click resets') plt.draw() cid = fig.canvas.mpl_connect('button_press_event', onclick) plt.show() return fig, cid
def run_model(kappa,forcing,function_space,boundary_conditions=None): """ Solve complex valued Helmholtz equation by solving coupled system, one for the real part of the solution one for the imaginary part. """ mesh = function_space.mesh() kappa_sq = kappa**2 if boundary_conditions==None: bndry_obj = dl.CompiledSubDomain("on_boundary") boundary_conditions = [['dirichlet',bndry_obj,[0,0]]] num_bndrys = len(boundary_conditions) boundaries = mark_boundaries(mesh,boundary_conditions) dirichlet_bcs = collect_dirichlet_boundaries( function_space,boundary_conditions,boundaries) # To express integrals over the boundary parts using ds(i), we must first # redefine the measure ds in terms of our boundary markers: ds = dl.Measure('ds', domain=mesh, subdomain_data=boundaries) #dx = dl.Measure('dx', domain=mesh) dx = dl.dx (pr, pi) = dl.TrialFunction(function_space) (vr, vi) = dl.TestFunction(function_space) # real part bilinear_form = kappa_sq*(pr*vr - pi*vi)*dx bilinear_form += (-dl.inner(dl.nabla_grad(pr),dl.nabla_grad(vr))+ dl.inner(dl.nabla_grad(pi),dl.nabla_grad(vi)))*dx # imaginary part bilinear_form += kappa_sq*(pr*vi + pi*vr)*dx bilinear_form += -(dl.inner(dl.nabla_grad(pr),dl.nabla_grad(vi))+ dl.inner(dl.nabla_grad(pi),dl.nabla_grad(vr)))*dx for ii in range(num_bndrys): if (boundary_conditions[ii][0]=='robin'): alpha_real, alpha_imag = boundary_conditions[ii][3] bilinear_form -= alpha_real*(pr*vr-pi*vi)*ds(ii) bilinear_form -= alpha_imag*(pr*vi+pi*vr)*ds(ii) forcing_real,forcing_imag=forcing rhs = (forcing_real*vr+forcing_real*vi+forcing_imag*vr-forcing_imag*vi)*dx for ii in range(num_bndrys): if ((boundary_conditions[ii][0]=='robin') or (boundary_conditions[ii][0]=='neumann')): beta_real, beta_imag=boundary_conditions[ii][2] # real part of robin boundary conditions rhs+=(beta_real*vr - beta_imag*vi)*ds(ii) # imag part of robin boundary conditions rhs+=(beta_real*vi + beta_imag*vr)*ds(ii) # compute solution p = dl.Function(function_space) #solve(a == L, p) dl.solve(bilinear_form == rhs, p, bcs=dirichlet_bcs) return p
def __init__(self,V,sigma=1.25,s=0.0625,mean=None,rel_tol=1e-10,max_iter=100,**kwargs): self.V=V self.dim=V.dim() self.dof_coords=get_dof_coords(V) self.sigma=sigma self.s=s self.mean=mean self.mpi_comm=kwargs['mpi_comm'] if 'mpi_comm' in kwargs else df.mpi_comm_world() # mass matrix and its inverse M_form=df.inner(df.TrialFunction(V),df.TestFunction(V))*df.dx self.M=df.PETScMatrix() df.assemble(M_form,tensor=self.M) self.Msolver = df.PETScKrylovSolver("cg", "jacobi") self.Msolver.set_operator(self.M) self.Msolver.parameters["maximum_iterations"] = max_iter self.Msolver.parameters["relative_tolerance"] = rel_tol self.Msolver.parameters["error_on_nonconvergence"] = True self.Msolver.parameters["nonzero_initial_guess"] = False # square root of mass matrix self.rtM=self._get_rtmass() # kernel matrix and its square root self.K=self._get_ker() self.rtK = _get_sqrtm(self.K,'K') # set solvers for op in ['K']: operator=getattr(self, op) solver=self._set_solver(operator,op) setattr(self, op+'solver', solver) if mean is None: self.mean=df.Vector() self.init_vector(self.mean,0)
def test_basic_interior_facet_assembly(): ghost_mode = dolfin.cpp.mesh.GhostMode.none if (dolfin.MPI.size(dolfin.MPI.comm_world) > 1): ghost_mode = dolfin.cpp.mesh.GhostMode.shared_facet mesh = dolfin.RectangleMesh( dolfin.MPI.comm_world, [numpy.array([0.0, 0.0, 0.0]), numpy.array([1.0, 1.0, 0.0])], [5, 5], cell_type=dolfin.cpp.mesh.CellType.Type.triangle, ghost_mode=ghost_mode) V = dolfin.function.FunctionSpace(mesh, ("DG", 1)) u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS A = dolfin.fem.assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) L = ufl.conj(ufl.avg(v)) * ufl.dS b = dolfin.fem.assemble_vector(L) b.assemble() assert isinstance(b, PETSc.Vec)
def assembleA(self, x, assemble_adjoint=False, assemble_rhs=False): """ Assemble the matrices and rhs for the forward/adjoint problems """ trial = dl.TrialFunction(self.Vh[STATE]) test = dl.TestFunction(self.Vh[STATE]) c = vector2Function(x[PARAMETER], self.Vh[PARAMETER]) Avarf = dl.inner( dl.exp(c) * dl.nabla_grad(trial), dl.nabla_grad(test)) * dl.dx if not assemble_adjoint: bform = dl.inner(self.f, test) * dl.dx Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc) else: # Assemble the adjoint of A (i.e. the transpose of A) s = vector2Function(x[STATE], self.Vh[STATE]) bform = dl.inner(dl.Constant(0.), test) * dl.dx Matrix, _ = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0) Bu = -(self.B * x[STATE]) Bu += self.u_o rhs = dl.Vector() self.B.init_vector(rhs, 1) self.B.transpmult(Bu, rhs) rhs *= 1.0 / self.noise_variance if assemble_rhs: return Matrix, rhs else: return Matrix
def __init__(self, Vh, dX, bc, form=None): """ Constructor: - Vh: the finite element space for the state variable. - dX: the integrator on subdomain X where observation are presents. E.g. dX = dl.dx means observation on all \Omega and dX = dl.ds means observations on all \partial \Omega. - bc: If the forward problem imposes Dirichlet boundary conditions u = u_D on \Gamma_D; bc is a dl.DirichletBC object that prescribes homogeneuos Dirichlet conditions u = 0 on \Gamma_D. - form: if form = None we compute the L^2(X) misfit: \int_X (u - ud)^2 dX, otherwise the integrand specified in form will be used. """ if form is None: u, v = dl.TrialFunction(Vh), dl.TestFunction(Vh) self.W = dl.assemble(dl.inner(u, v) * dX) else: self.W = dl.assemble(form) if bc is not None: Wt = Transpose(self.W) self.bc.zero(Wt) self.W = Transpose(Wt) self.bc.zero(self.W) self.d = dl.Vector() self.W.init_vector(self.d, 1) self.noise_variance = 0
def make_mass_matrix_simple_lumping(function_space_V): ML = make_mass_matrix_unlumped(function_space_V) ML.zero() mass_lumps = dl.assemble( dl.Constant(1.0) * dl.TestFunction(function_space_V) * dl.dx) ML.set_diagonal(mass_lumps) return ML
def make_mass_matrix_unlumped(function_space_V): V = function_space_V u_trial = dl.TrialFunction(V) v_test = dl.TestFunction(V) mass_form = u_trial * v_test * dl.dx M = dl.assemble(mass_form) return M
def get_initial_conditions(self,melt_velocity=-1./3600.): """ Set the initial condition to no melted ice and all at the bulk ice temperature Parameters ---------- melt_velocity: float velocity of the downgoing drill (m/s) """ # --- Initial states --- # # ice temperature self.u0_i = dolfin.interpolate(dolfin.Constant(self.Tstar),self.ice_V) # the upward velocity is equal to negative the melt rate (the mesh is Lagrangian following the drill) self.velocity = dolfin.Expression('melt',melt=melt_velocity*self.t0,degree=1) # --- Time Array --- # # Now that we have the melt-out time, we can define the time array self.ts = np.arange(0.,self.t_final+self.dt,self.dt)/self.t0 self.dt /= self.t0 # --- Define the test and trial functions --- # self.u_i = dolfin.TrialFunction(self.ice_V) self.v_i = dolfin.TestFunction(self.ice_V) self.T_i = dolfin.Function(self.ice_V) self.flags.append('get_ic')
def init_variables(self): mesh = self.mesh DG0 = self.DG0 self.n = n = dolfin.FacetNormal(mesh) self.u = u = dolfin.Function(DG0) self.v = v = dolfin.TestFunction(DG0)
def test_anisotropy_field(fixt): """ Compute one anisotropy field by hand and compare with the UniaxialAnisotropy result. """ TOLERANCE = 1e-14 c = df.Constant((1 / np.sqrt(2), 0, 1 / np.sqrt(2))) fixt["m"].set(c) H = fixt["anis"].compute_field() v = df.TestFunction(fixt["m"].functionspace) g_ani = df.Constant(fixt["K1"] / (mu0 * fixt["Ms"].value)) * ( 2 * df.dot(fixt["a"], fixt["m"].f) * df.dot(fixt["a"], v)) * df.dx volume = df.assemble(df.dot(v, df.Constant((1, 1, 1))) * df.dx).array() dE_dm = df.assemble(g_ani).array() / volume print( textwrap.dedent(""" With m = (1, 0, 1)/sqrt(2), expecting: H = {}, got: H = {}. """.format( H.reshape((3, -1)).mean(axis=1), dE_dm.reshape((3, -1)).mean(axis=1)))) assert np.allclose(H, dE_dm, atol=0, rtol=TOLERANCE)
def set_spaces_functions(self, p): # p: int, polynomial order of trial/test functions nvar = self.params['nvar'] mesh = self.mesh # Define finite-element spaces U = d.FunctionSpace(mesh, "CG", p) W = d.VectorFunctionSpace(mesh, "CG", p, dim = nvar-1) # Functions for bilinear and linear form self.ut = d.TrialFunction(U) self.du = d.TestFunction(U) self.un = d.Function(U) self.u = d.Function(U) self.w = d.Function(W) # Auxiliar functions self.sig = d.Function(U) # conductivity value self.f = d.Function(U) # conductivity value # Save Spaces self.U = U self.W = W self.ndofs = U.tabulate_dof_coordinates().shape[0]
def __init__(self, config, feasible_area, attraction_center): ''' Generates the inequality constraints to enforce the turbines in the feasible area. If the turbine is outside the domain, the constraints is equal to the distance between the turbine and the attraction center. ''' self.config = config self.feasible_area = feasible_area # Compute the gradient of the feasible area fs = dolfin.FunctionSpace(feasible_area.function_space().mesh(), "DG", feasible_area.function_space().ufl_element().degree() - 1) feasible_area_grad = (dolfin.Function(fs), dolfin.Function(fs)) t = dolfin.TestFunction(fs) log(INFO, "Solving for gradient of feasible area") for i in range(2): form = dolfin.inner(feasible_area_grad[i], t) * dolfin.dx - dolfin.inner(feasible_area.dx(i), t) * dolfin.dx if dolfin.NonlinearVariationalSolver.default_parameters().has_parameter("linear_solver"): dolfin.solve(form == 0, feasible_area_grad[i], solver_parameters={"linear_solver": "cg", "preconditioner": "amg"}) else: dolfin.solve(form == 0, feasible_area_grad[i], solver_parameters={"newton_solver": {"linear_solver": "cg", "preconditioner": "amg"}}) self.feasible_area_grad = feasible_area_grad self.attraction_center = attraction_center
def linear_solver(self, phi_k): # cast params as constant functions so that, if they are set to 0, FEniCS still understand # what is being integrated mu, M = Constant(self.physics.mu), Constant(self.physics.M) lam = Constant(self.physics.lam) mn, mf = Constant(self.mn), Constant(self.mf) D = self.physics.D # boundary condition Dirichlet_bc = self.get_Dirichlet_bc() # trial and test function phi = d.TrialFunction(self.fem.S) v = d.TestFunction(self.fem.S) # r^(D-1) rD = Expression('pow(x[0],D-1)', D=D, degree=self.fem.func_degree) # bilinear form a and linear form L a = - inner( grad(phi), grad(v) ) * rD * dx + ( (mu/mn)**2 \ - 3.*lam*(mf/mn)**2*phi_k**2 ) * phi * v * rD * dx L = ((mn**(D - 2.) / (mf * M)) * self.source.rho - 2. * lam * (mf / mn)**2 * phi_k**3) * v * rD * dx # define a vector with the solution sol = d.Function(self.fem.S) # solve linearised system pde = d.LinearVariationalProblem(a, L, sol, Dirichlet_bc) solver = d.LinearVariationalSolver(pde) solver.solve() return sol
def __init__(self, V, kappa): ''' Parameters ---------- V : dolfin.FunctionSpace Function space. kappa : float Filter diffusivity constant. ''' if not isinstance(V, dolfin.FunctionSpace): raise TypeError( 'Parameter `V` must be of type `dolfin.FunctionSpace`.') v = dolfin.TestFunction(V) f = dolfin.TrialFunction(V) x = V.mesh().coordinates() l = (x.max(0) - x.min(0)).min() k = Constant(float(kappa) * l**2) a_M = f * v * dx a_D = k * dot(grad(f), grad(v)) * dx A = assemble(a_M + a_D) self._M = assemble(a_M) self.solver = dolfin.LUSolver(A, "mumps") self.solver.parameters["symmetric"] = True
def __init__(self, simulation, u_conv): """ Given a velocity in DG, e.g DG2, produce a velocity in DGT0, i.e. a constant on each facet """ V = u_conv[0].function_space() V_dgt0 = dolfin.FunctionSpace(V.mesh(), 'DGT', 0) u = dolfin.TrialFunction(V_dgt0) v = dolfin.TestFunction(V_dgt0) ndim = simulation.ndim w = u_conv w_new = dolfin.as_vector( [dolfin.Function(V_dgt0) for _ in range(ndim)]) dot, avg, dS, ds = dolfin.dot, dolfin.avg, dolfin.dS, dolfin.ds a = dot(avg(u), avg(v)) * dS + dot(u, v) * ds L = [] for d in range(ndim): L.append(avg(w[d]) * avg(v) * dS + w[d] * v * ds) self.lhs = [dolfin.Form(Li) for Li in L] self.A = dolfin.assemble(a) self.solver = dolfin.PETScKrylovSolver('cg') self.velocity = simulation.data['u_conv_dgt0'] = w_new
def test_custom_mesh_loop_cffi_rank2(set_vals): """Test numba assembler for bilinear form""" mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 64, 64) V = dolfin.FunctionSpace(mesh, ("Lagrange", 1)) # Test against generated code and general assembler u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = inner(u, v) * dx A0 = dolfin.fem.assemble_matrix(a) A0.assemble() A0.zeroEntries() start = time.time() dolfin.fem.assemble_matrix(A0, a) end = time.time() print("Time (C++, pass 2):", end - start) A0.assemble() # Unpack mesh and dofmap data c = mesh.topology.connectivity(2, 0).connections() pos = mesh.topology.connectivity(2, 0).pos() geom = mesh.geometry.points dofs = V.dofmap().dof_array A1 = A0.copy() for i in range(2): A1.zeroEntries() start = time.time() assemble_matrix_cffi(A1.handle, (c, pos), geom, dofs, set_vals, PETSc.InsertMode.ADD_VALUES) end = time.time() print("Time (Numba, pass {}): {}".format(i, end - start)) A1.assemble() assert (A1 - A0).norm() == pytest.approx(0.0)
def inner_product(self, g, grid=None): g = make_dolfin_callable(g, grid=grid, fs=self.fs, offset=-1.0 * self.offset) v = df.TestFunction(self.fs) return df.assemble(g * v * dx).get_local()
def _process_mixed_function(self, prefix, d): edef = self.emit_definition path = self.path code = self.code prefix = path(prefix) space = path(d['space']) if not prefix.endswith('/'): prefix = prefix + '/' edef(prefix + 'trial', lambda s: s['/function_subspace_registry'].Function(s[space])) edef(prefix + 'test', lambda s: dolfin.TestFunction(s[space])) for tt in ('trial', 'test'): edef( ''.join((prefix, tt, '/split')), partial(lambda tt, s: s[space + '/split'](s[prefix + tt], tt), tt)) def _split_dict(s, split_target_prefix='/'): d = {} for tt in ('trial', 'test'): d.update( ((split_target_prefix + k), v) for k, v in s[''.join((prefix, tt, '/split'))].items()) return d edef(prefix + '/split_dict', partial(partial, _split_dict))
def test_basic_assembly(): mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 12, 12) V = dolfin.FunctionSpace(mesh, ("Lagrange", 1)) u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = 1.0 * inner(u, v) * dx L = inner(1.0, v) * dx # Initial assembly A = dolfin.fem.assemble(a) b = dolfin.fem.assemble(L) assert isinstance(A, dolfin.cpp.la.PETScMatrix) assert isinstance(b, dolfin.cpp.la.PETScVector) # Second assembly A = dolfin.fem.assemble(A, a) b = dolfin.fem.assemble(b, L) assert isinstance(A, dolfin.cpp.la.PETScMatrix) assert isinstance(b, dolfin.cpp.la.PETScVector) # Function as coefficient f = dolfin.Function(V) a = f * inner(u, v) * dx A = dolfin.fem.assemble(a) assert isinstance(A, dolfin.cpp.la.PETScMatrix)
def efield_DG0(mesh, phi): Q = df.VectorFunctionSpace(mesh, 'DG', 0) q = df.TestFunction(Q) M = (1.0 / df.CellVolume(mesh)) * df.inner(-df.grad(phi), q) * df.dx E_dg0 = df.assemble(M) return df.Function(Q, E_dg0)
def _construct(self, field_inp): # Read the input self.name = field_inp.get_value('name', required_type='string') self.var_name = field_inp.get_value('variable_name', 'phi', 'string') self.stationary = field_inp.get_value('stationary', False, 'bool') self.radius = field_inp.get_value('radius', required_type='float') self.plot = field_inp.get_value('plot', False, 'bool') # Show the input sim = self.simulation sim.log.info('Creating a free surface zone field %r' % self.name) sim.log.info(' Variable: %r' % self.var_name) sim.log.info(' Stationary: %r' % self.stationary) # Create the level set model mesh = sim.data['mesh'] func_name = '%s_%s' % (self.name, self.var_name) self.V = dolfin.FunctionSpace(mesh, 'DG', 0) self.function = dolfin.Function(self.V) self.function.rename(func_name, func_name) sim.data[func_name] = self.function # Get the level set view level_set_view = sim.multi_phase_model.get_level_set_view() level_set_view.add_update_callback(self.update) # Form to compute the cell average distance to the free surface v = dolfin.TestFunction(self.V) ls = level_set_view.level_set_function cv = dolfin.CellVolume(self.V.mesh()) self.dist_form = dolfin.Form(ls * v / cv * dolfin.dx) if self.plot: sim.io.add_extra_output_function(self.function)
def solve(self, vkscale=1., lscale=1., sscale=1.): """This approach only works for small grids since the memory requirements rapidly become prohibitive. (nl, nk, nv) = (8, 45, 40) is just barely doable on my laptop. If the memory is available, computation time is not significant. """ D = d.Function(self.tensor_space) # diffusion tensor Q = d.Function(self.scalar_space) # source term u = d.TrialFunction(self.scalar_space) # u is my 'f' v = d.TestFunction(self.scalar_space) soln = d.Function(self.scalar_space) a = d.dot(d.dot(D, d.grad(u)), d.grad(v)) * d.dx L = Q * v * d.dx equation = (a == L) soln = d.Function(self.scalar_space) bc = d.DirichletBC(self.scalar_space, d.Constant(0), direct_boundary) dbuf = np.zeros(D.vector().size()).reshape((-1, 3, 3)) dbuf[:,0,0] = self.D_VV * vkscale dbuf[:,1,0] = self.D_VK * vkscale dbuf[:,0,1] = self.D_VK * vkscale dbuf[:,1,1] = self.D_KK * vkscale dbuf[:,2,2] = self.D_LL * lscale D.vector()[:] = dbuf.reshape((-1,)) Q.vector()[:] = self.source_term * sscale d.solve(equation, soln, bc) return self.to_cube(soln.vector().array())
def get_convvec(u0_dolfun=None, V=None, u0_vec=None, femp=None, diribcs=None, invinds=None): """return the convection vector e.g. for explicit schemes given a dolfin function or the coefficient vector """ if u0_vec is not None: if femp is not None: diribcs = femp['diribcs'] invinds = femp['invinds'] u0, p = expand_vp_dolfunc(vc=u0_vec, V=V, diribcs=diribcs, invinds=invinds) else: u0 = u0_dolfun v = dolfin.TestFunction(V) ConvForm = inner(grad(u0) * u0, v) * dx ConvForm = dolfin.assemble(ConvForm) if invinds is not None: ConvVec = ConvForm.array()[invinds] else: ConvVec = ConvForm.array() ConvVec = ConvVec.reshape(len(ConvVec), 1) return ConvVec
def rhs(states, time, parameters, dy=None): """ Compute right hand side """ # Imports import ufl import dolfin # Assign states assert (isinstance(states, dolfin.Function)) assert (states.function_space().depth() == 1) assert (states.function_space().num_sub_spaces() == 2) s, v = dolfin.split(states) # Assign parameters a, b, c_1, c_2, c_3, v_peak, v_rest = parameters v_amp = v_peak - v_rest v_th = v_rest + a * v_amp I = (v - v_rest)*(v - v_th)*(v_peak - v)*c_1/(v_amp*v_amp) - (v -\ v_rest)*c_2*s/v_amp # Init test function _v = dolfin.TestFunction(states.function_space()) # Derivative for state s dy = ((-c_3 * s + v - v_rest) * b) * _v[0] # Derivative for state v dy += (I) * _v[1] dya = dolfin.assemble(dy * dolfin.dx) # Return dy return dy
def __init__(me, function_space_V, initial_points=None): me.V = function_space_V me.N = me.V.dim() u_trial = dl.TrialFunction(me.V) v_test = dl.TestFunction(me.V) mass_form = u_trial * v_test * dl.dx me.M = dl.assemble(mass_form) me.constant_one_function = dl.interpolate(dl.Constant(1.0), me.V) me.NPPSS = NeumannPoissonSolver(me.V) me.solve_neumann_poisson = me.NPPSS.solve me.solve_neumann_point_source = me.NPPSS.solve_point_source me.points = list() me.impulse_responses = list() me.solve_S = lambda x: np.nan me.eta = np.zeros(me.num_pts) me.mu = np.nan me.smooth_basis = list() me.weighting_functions = list() if initial_points is not None: me.add_points(initial_points)
def get_distance_function(config, domains): V = dolfin.FunctionSpace(config.domain.mesh, "CG", 1) v = dolfin.TestFunction(V) d = dolfin.TrialFunction(V) sol = dolfin.Function(V) s = dolfin.interpolate(Constant(1.0), V) domains_func = dolfin.Function(dolfin.FunctionSpace(config.domain.mesh, "DG", 0)) domains_func.vector().set_local(domains.array().astype(numpy.float)) def boundary(x): eps_x = config.params["turbine_x"] eps_y = config.params["turbine_y"] min_val = 1 for e_x, e_y in [(-eps_x, 0), (eps_x, 0), (0, -eps_y), (0, eps_y)]: try: min_val = min(min_val, domains_func((x[0] + e_x, x[1] + e_y))) except RuntimeError: pass return min_val == 1.0 bc = dolfin.DirichletBC(V, 0.0, boundary) # Solve the diffusion problem with a constant source term log(INFO, "Solving diffusion problem to identify feasible area ...") a = dolfin.inner(dolfin.grad(d), dolfin.grad(v)) * dolfin.dx L = dolfin.inner(s, v) * dolfin.dx dolfin.solve(a == L, sol, bc) return sol