def test_pointsource_mixed_space(mesh, point): """Tests point source when given constructor PointSource(V, point, mag) with a vector for a mixed function space that isn't placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ rank = MPI.rank(mesh.mpi_comm()) ele1 = FiniteElement("CG", mesh.ufl_cell(), 1) ele2 = FiniteElement("DG", mesh.ufl_cell(), 2) ele3 = VectorElement("CG", mesh.ufl_cell(), 2) V = FunctionSpace(mesh, MixedElement([ele1, ele2, ele3])) value_dimension = V.element().value_dimension(0) v = TestFunction(V) b = assemble(dot(Constant([0.0] * value_dimension), v) * dx) if rank == 0: ps = PointSource(V, point, 10.0) else: ps = PointSource(V, []) ps.apply(b) # Checks array sums to correct value b_sum = b.sum() assert round(b_sum - 10.0 * value_dimension) == 0
def setUp(self): from dolfin import (MixedElement as MixE, Function, FunctionSpace, FiniteElement, VectorElement, UnitSquareMesh) self.mesh = mesh = UnitSquareMesh(10, 10) muc = mesh.ufl_cell self.fe1 = FiniteElement("CG", muc(), 1) self.fe2 = FiniteElement("CG", muc(), 2) self.ve1 = VectorElement("CG", muc(), 2, 2) self.me = ( MixE([self.fe1, self.fe2]), MixE([MixE([self.ve1, self.fe2]), self.fe1, self.ve1, self.fe2]), # MixE([self.fe1]), # broken ) self.W = [FunctionSpace(mesh, me) for me in self.me] self.w = [Function(W) for W in self.W] self.reg = FunctionSubspaceRegistry() self.x = dolfin.SpatialCoordinate(mesh) for W in self.W: self.reg.register(W)
def test_pde_constrained(polynomial_order, in_expression): interpolate_expression = Expression(in_expression, degree=3) xmin, xmax = 0., 1. ymin, ymax = 0., 1. property_idx = 1 dt = 1. k = polynomial_order # Make mesh mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40) # Make function spaces and functions W_e = FiniteElement("DG", mesh.ufl_cell(), k) T_e = FiniteElement("DG", mesh.ufl_cell(), 0) Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k) W = FunctionSpace(mesh, W_e) T = FunctionSpace(mesh, T_e) Wbar = FunctionSpace(mesh, Wbar_e) psi_h, psi0_h = Function(W), Function(W) lambda_h = Function(T) psibar_h = Function(Wbar) uadvect = Constant((0, 0)) # Define particles x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500]) s = assign_particle_values(x, interpolate_expression) psi0_h.assign(interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [s], mesh) p.interpolate(psi0_h, 1) # Initialize forms FuncSpace_adv = { 'FuncSpace_local': W, 'FuncSpace_lambda': T, 'FuncSpace_bar': Wbar } forms_pde = FormsPDEMap(mesh, FuncSpace_adv).forms_theta_linear( psi0_h, uadvect, dt, Constant(1.0)) pde_projection = PDEStaticCondensation(mesh, p, forms_pde['N_a'], forms_pde['G_a'], forms_pde['L_a'], forms_pde['H_a'], forms_pde['B_a'], forms_pde['Q_a'], forms_pde['R_a'], forms_pde['S_a'], [], property_idx) # Assemble and solve pde_projection.assemble(True, True) pde_projection.solve_problem(psibar_h, psi_h, lambda_h, 'none', 'default') error_psih = abs(assemble((psi_h - psi0_h) * (psi_h - psi0_h) * dx)) error_lamb = abs(assemble(lambda_h * lambda_h * dx)) assert error_psih < 1e-15 assert error_lamb < 1e-15
def MixedToMixedSpacesCopyComponentToDifferentLocation(mesh): element_0 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element, components=["ux", "uy"]) W = V return (V, W)
def hat_function_collection(vertex_colors, color, element=None): """Return Expression on given element which takes values: 1 ... if vertex_colors[node] == color 0 ... at other nodes This is well defined just on Lagrange 1 element (default) and Dicontinuous Lagrange 1 element. NOTE: This expression provides a little hack as it lacks continuity across MPI partitions boundaries unless vertex_colors is compatible there. In fact, this behaviour is needed in FluxReconstructor.""" assert isinstance(vertex_colors, cpp.VertexFunctionSizet) mesh = vertex_colors.mesh() if not element: element = FiniteElement('Lagrange', mesh.ufl_cell(), 1) assert element.family() in ['Lagrange', 'Discontinuous Lagrange'] assert element.degree() == 1 ufc_element, ufc_dofmap = jit(element, mpi_comm=mesh.mpi_comm()) dolfin_element = cpp.FiniteElement(ufc_element) e = Expression(hats_cpp_code, element=element, domain=mesh) e.vertex_colors = vertex_colors e.color = color e.dolfin_element = dolfin_element return e
def MixedSpacesRestrictionToSubElementSolveAmbiguityWithComponents(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 1) element_00 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element, components=[("ux", "uy"), "p"]) W = FunctionSpace(mesh, element_00) return (V, W)
def MixedSpacesRestrictionToSubElementAmbiguous(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) # Note that we need to use 2nd order FE otherwise element_00 = FiniteElement("Lagrange", mesh.ufl_cell(), 2) # the automatic detection would restrict the element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) # pressure component element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element) W = FunctionSpace(mesh, element_00) return (V, W)
def MixedSpacesExtensionFromSubElementSolveAmbiguityWithComponents(mesh, components): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 1) element_00 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element_00) assert components in (tuple, str) if components is tuple: W = FunctionSpace(mesh, element) else: W = FunctionSpace(mesh, element, components=[("ux", "uy"), "p"]) return (V, W)
def test_global_dof_builder(mesh_factory): func, args = mesh_factory mesh = func(*args) V = VectorElement("CG", mesh.ufl_cell(), 1) Q = FiniteElement("CG", mesh.ufl_cell(), 1) R = FiniteElement("R", mesh.ufl_cell(), 0) W = FunctionSpace(mesh, MixedElement([Q, Q, Q, R])) W = FunctionSpace(mesh, MixedElement([Q, Q, R, Q])) W = FunctionSpace(mesh, V * R) W = FunctionSpace(mesh, R * V) assert (W)
def get_elements_1(): return ( lambda mesh: FiniteElement("Lagrange", mesh.ufl_cell(), 1), pytest.mark.slow(lambda mesh: FiniteElement("Lagrange", mesh.ufl_cell(), 2)), lambda mesh: VectorElement("Lagrange", mesh.ufl_cell(), 1), pytest.mark.slow(lambda mesh: VectorElement("Lagrange", mesh.ufl_cell(), 2)), pytest.mark.slow(lambda mesh: TensorElement("Lagrange", mesh.ufl_cell(), 1)), pytest.mark.slow(lambda mesh: TensorElement("Lagrange", mesh.ufl_cell(), 2)), lambda mesh: StokesElement("Lagrange", mesh.ufl_cell(), 1), pytest.mark.slow(lambda mesh: StokesElement("Lagrange", mesh.ufl_cell(), 2)), lambda mesh: FiniteElement("Real", mesh.ufl_cell(), 0), pytest.mark.slow(lambda mesh: VectorElement("Real", mesh.ufl_cell(), 0)), pytest.mark.slow(lambda mesh: FunctionAndRealElement("Lagrange", mesh.ufl_cell(), 1)), pytest.mark.slow(lambda mesh: FunctionAndRealElement("Lagrange", mesh.ufl_cell(), 2)) )
def _init_spaces(self): P2 = FiniteElement('P', self.mesh.ufl_cell(), 2) N = self.parameters['N'] if N == 1: elem = P2 else: elem = MixedElement([P2 for i in range(N)]) v_elem = VectorElement('P', self.mesh.ufl_cell(), 1) mesh = self.mesh self.state_space = FunctionSpace(mesh, elem) self.vector_space = FunctionSpace(mesh, v_elem) self.pressure_space = FunctionSpace(mesh, P2) self.state = Function(self.state_space, name="m") self.state_previous = Function(self.state_space) self.state_test = TestFunction(self.state_space) self.displacement = Function(self.vector_space, name="du") self.mech_velocity = Function(self.vector_space) self.pressure = [ Function(self.pressure_space, name="p{}".format(i)) for i in range(N) ] self.darcy_flow = [ Function(self.vector_space, name="w{}".format(i)) for i in range(N) ]
def test_save_and_checkpoint_timeseries(tempdir, encoding): mesh = UnitSquareMesh(MPI.comm_world, 16, 16) filename = os.path.join(tempdir, "u2_checkpoint.xdmf") FE = FiniteElement("CG", mesh.ufl_cell(), 2) V = FunctionSpace(mesh, FE) times = [0.5, 0.2, 0.1] u_out = [None] * len(times) u_in = [None] * len(times) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: for i, p in enumerate(times): u_out[i] = interpolate(Expression("x[0]*p", p=p, degree=1), V) file.write_checkpoint(u_out[i], "u_out", p) with XDMFFile(mesh.mpi_comm(), filename) as file: for i, p in enumerate(times): u_in[i] = file.read_checkpoint(V, "u_out", i) for i, p in enumerate(times): u_in[i].vector().axpy(-1.0, u_out[i].vector()) assert u_in[i].vector().norm(cpp.la.Norm.l2) < 1.0e-12 # test reading last with XDMFFile(mesh.mpi_comm(), filename) as file: u_in_last = file.read_checkpoint(V, "u_out", -1) u_out[-1].vector().axpy(-1.0, u_in_last.vector()) assert u_out[-1].vector().norm(cpp.la.Norm.l2) < 1.0e-12
def generate_collapsed_bilinear_form_space(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) U = FunctionSpace(mesh, element) V = U.sub(0).collapse() return (V, U)
def test_tabulate_dofs(mesh_factory): func, args = mesh_factory mesh = func(*args) W0 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) W1 = VectorElement("Lagrange", mesh.ufl_cell(), 1) W = FunctionSpace(mesh, W0 * W1) L0 = W.sub(0) L1 = W.sub(1) L01 = L1.sub(0) L11 = L1.sub(1) for i, cell in enumerate(Cells(mesh)): dofs0 = L0.dofmap().cell_dofs(cell.index()) dofs1 = L01.dofmap().cell_dofs(cell.index()) dofs2 = L11.dofmap().cell_dofs(cell.index()) dofs3 = L1.dofmap().cell_dofs(cell.index()) assert np.array_equal(dofs0, L0.dofmap().cell_dofs(i)) assert np.array_equal(dofs1, L01.dofmap().cell_dofs(i)) assert np.array_equal(dofs2, L11.dofmap().cell_dofs(i)) assert np.array_equal(dofs3, L1.dofmap().cell_dofs(i)) assert len(np.intersect1d(dofs0, dofs1)) == 0 assert len(np.intersect1d(dofs0, dofs2)) == 0 assert len(np.intersect1d(dofs1, dofs2)) == 0 assert np.array_equal(np.append(dofs1, dofs2), dofs3)
def test_save_and_checkpoint_scalar(tempdir, encoding, fe_degree, fe_family, mesh_tdim, mesh_n): if invalid_fe(fe_family, fe_degree): pytest.skip("Trivial finite element") filename = os.path.join(tempdir, "u1_checkpoint.xdmf") mesh = mesh_factory(mesh_tdim, mesh_n) FE = FiniteElement(fe_family, mesh.ufl_cell(), fe_degree) V = FunctionSpace(mesh, FE) u_in = Function(V) u_out = Function(V) if has_petsc_complex: u_out.interpolate(Expression("x[0] + j*x[0]", degree=1)) else: u_out.interpolate(Expression("x[0]", degree=1)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write_checkpoint(u_out, "u_out", 0) with XDMFFile(mesh.mpi_comm(), filename) as file: u_in = file.read_checkpoint(V, "u_out", 0) u_in.vector().axpy(-1.0, u_out.vector()) assert u_in.vector().norm(cpp.la.Norm.l2) < 1.0e-12
def StabilizationParameterSD(wind, viscosity, density=None): """Returns a subclass of :py:class:`dolfin.Expression` representing streamline diffusion stabilization parameter. This kind of stabilization is convenient when a multigrid method is used for the convection term in the Navier-Stokes equation. The idea of the stabilization involves adding an additional term of the form:: delta_sd*inner(dot(grad(u), w), dot(grad(v), w))*dx into the Navier-Stokes equation. Here ``u`` is a trial function, ``v`` is a test function and ``w`` defines so-called "wind" which is a known vector function. Regularization parameter ``delta_sd`` is determined by the local mesh Peclet number (PE), see the implementation below. *Arguments* wind (:py:class:`dolfin.GenericFunction`) A vector field determining convective velocity. viscosity (:py:class:`dolfin.GenericFunction`) A scalar field determining dynamic viscosity. density (:py:class:`dolfin.GenericFunction`) A scalar field determining density (optional). """ if density is None: density = Constant(1.0) mesh = wind.function_space().mesh() element = FiniteElement("DG", mesh.ufl_cell(), 0) delta_sd = Expression(_streamline_diffusion_cpp, element=element, domain=mesh, mpi_comm=mesh.mpi_comm()) delta_sd.wind = wind delta_sd.viscosity = viscosity delta_sd.density = density return delta_sd
def exact_solution(domain): P7 = VectorElement("Lagrange", "triangle", degree=8, dim=2) P2 = FiniteElement("Lagrange", "triangle", 3) coeff = (P_inlet-P_outlet)/(2*Length*visc) u_exact = Expression(("C*x[1]*(H - x[1])", "0.0"), C=coeff,H=Height, element=P7, domain=domain) p_exact = Expression("dP-dP/L*x[0]", dP=(P_inlet-P_outlet), L=Length, element=P2, domain=domain) return u_exact, p_exact
def __init__(self, mesh, mf, bc_dict, move_dict): """ Inititalize Stokes solver with a mesh, its corresponding facet function, a dictionary describing boundary conditions and a dictionary describing which boundaries are fixed in the shape optimization setting """ self.mesh = mesh self.backup = mesh.coordinates().copy() self.mf = mf V2 = VectorElement("CG", mesh.ufl_cell(), 2) S1 = FiniteElement("CG", mesh.ufl_cell(), 1) TH = V2 * S1 self.VQ = FunctionSpace(self.mesh, TH) self.w = Function(self.VQ) self.f = Constant([0.]*mesh.geometric_dimension()) self.S = VectorFunctionSpace(self.mesh, "CG", 1) self.move_dict = move_dict self.J = 0 self._init_bcs(bc_dict) self.solve() self.vfac = 1e4 self.bfac = 1e2 self._init_geometric_functions() self.eval_current_J() self.eval_current_dJ() self.outfile = File("output/u_singlemesh.pvd") self.outfile << self.u self.gradient_scale = 1 self.iteration_counter = 1 self.create_mapping_for_moving_boundary()
def MixedSpacesExtensionSolveAmbiguityWithComponents(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 1) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element_0) W = FunctionSpace(mesh, element, components=[["u", "s"], "p"]) return (V, W)
def test_taylor_hood_cube(): pytest.xfail("Problem with Mixed Function Spaces") meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2) meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5) Ve = VectorElement("CG", meshc.ufl_cell(), 2) Qe = FiniteElement("CG", meshc.ufl_cell(), 1) Ze = MixedElement([Ve, Qe]) Zc = FunctionSpace(meshc, Ze) Zf = FunctionSpace(meshf, Ze) @function.expression.numba_eval def expr_eval(values, x, cell_idx): values[:, 0] = x[:, 0] * x[:, 1] values[:, 1] = x[:, 1] * x[:, 2] values[:, 2] = x[:, 2] * x[:, 0] values[:, 3] = x[:, 0] + 3.0 * x[:, 1] + x[:, 2] z = Expression(expr_eval, shape=(4, )) zc = interpolate(z, Zc) zf = interpolate(z, Zf) mat = PETScDMCollection.create_transfer_matrix(Zc, Zf) Zuc = Function(Zf) mat.mult(zc.vector(), Zuc.vector()) Zuc.vector().update_ghost_values() diff = Function(Zf) diff.assign(Zuc - zf) assert diff.vector().norm("l2") < 1.0e-12
def test_mixed_parallel(): mesh = UnitSquareMesh(MPI.comm_world, 5, 8) V = VectorElement("Lagrange", triangle, 4) Q = FiniteElement("Lagrange", triangle, 5) W = FunctionSpace(mesh, Q * V) F = Function(W) @function.expression.numba_eval def expr_eval(values, x, cell_idx): values[:, 0] = x[:, 0] values[:, 1] = x[:, 1] values[:, 2] = numpy.sin(x[:, 0] + x[:, 1]) F.interpolate(Expression(expr_eval, shape=(3, ))) # Generate random points in this mesh partition (one per cell) x = numpy.zeros(3) for c in Cells(mesh): x[0] = random() x[1] = random() * (1 - x[0]) x[2] = (1 - x[0] - x[1]) p = Point(0.0, 0.0) for i, v in enumerate(VertexRange(c)): p += v.point() * x[i] p = p.array()[:2] val = F(p) assert numpy.allclose(val[0], p[0]) assert numpy.isclose(val[1], p[1]) assert numpy.isclose(val[2], numpy.sin(p[0] + p[1]))
def CollapsedFunctionSpaces(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2, dim=2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) U = FunctionSpace(mesh, element) V = U.sub(0).collapse() return (V, U)
def MixedSpacesExtensionAutomatic(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element_0) W = FunctionSpace(mesh, element) return (V, W)
def MixedSpacesRestrictionAmbiguous(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 1) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element) W = FunctionSpace(mesh, element_0) return (V, W)
def curvilinear_coordinate_1d(mb, p0=0, function=None): "Returns parametrization of a curve" # edge-to-vertex connectivity EE = np.zeros((mb.num_cells(), mb.num_vertices()), dtype=bool) for e in edges(mb): EE[e.index(), e.entities(0)] = True # vertex-to-vertex connectivity (via edges) PP = EE.T @ EE np.fill_diagonal(PP, False) mmap = -np.ones(PP.shape[0], dtype=int) # order vertices mmap[0] = p0 for k in range(PP.shape[0] - 1): neig = np.where(PP[mmap[k], :])[0] mmap[k + 1] = neig[1] if neig[0] in mmap else neig[0] # cumulative length of edges l = np.linalg.norm(np.diff(mb.coordinates()[mmap, :], axis=0), axis=1) s = np.r_[0, np.cumsum(l)] if function is None: P1e = FiniteElement("CG", mb.ufl_cell(), 1) Ve = FunctionSpace(mb, P1e) function = Function(Ve) function.vector()[vertex_to_dof_map(Ve)[mmap]] = s return function else: Ve = function.function_space() function.vector()[vertex_to_dof_map(Ve)[mmap]] = s
def stokes(self): P2 = VectorElement("CG", self.mesh.ufl_cell(), 2) P1 = FiniteElement("CG", self.mesh.ufl_cell(), 1) TH = P2 * P1 VQ = FunctionSpace(self.mesh, TH) mf = self.mf self.no_slip = Constant((0., 0)) self.topflow = Expression(("-x[0] * (x[0] - 1.0) * 6.0 * m", "0.0"), m=self.U_m, degree=2) bc0 = DirichletBC(VQ.sub(0), self.topflow, mf, self.bc_dict["top"]) bc1 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["left"]) bc2 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["bottom"]) bc3 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["right"]) # bc4 = DirichletBC(VQ.sub(1), Constant(0), mf, self.bc_dict["top"]) bcs = [bc0, bc1, bc2, bc3] vup = TestFunction(VQ) up = TrialFunction(VQ) # the solution will be in here: up_ = Function(VQ) u, p = split(up) # Trial vu, vp = split(vup) # Test u_, p_ = split(up_) # Function holding the solution F = self.mu*inner(grad(vu), grad(u))*dx - inner(div(vu), p)*dx \ - inner(vp, div(u))*dx + dot(self.g*self.rho, vu)*dx solve(lhs(F) == rhs(F), up_, bcs=bcs) self.u_.assign(project(u_, self.V)) self.p_.assign(project(p_, self.Q)) return
def test_taylor_hood_cube(): pytest.xfail("Problem with Mixed Function Spaces") meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2) meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5) Ve = VectorElement("CG", meshc.ufl_cell(), 2) Qe = FiniteElement("CG", meshc.ufl_cell(), 1) Ze = MixedElement([Ve, Qe]) Zc = FunctionSpace(meshc, Ze) Zf = FunctionSpace(meshf, Ze) z = Expression( ("x[0]*x[1]", "x[1]*x[2]", "x[2]*x[0]", "x[0] + 3*x[1] + x[2]"), degree=2) zc = interpolate(z, Zc) zf = interpolate(z, Zf) mat = PETScDMCollection.create_transfer_matrix(Zc, Zf) Zuc = Function(Zf) mat.mult(zc.vector(), Zuc.vector()) Zuc.vector().update_ghost_values() diff = Function(Zf) diff.assign(Zuc - zf) assert diff.vector().norm("l2") < 1.0e-12
def compute_error(problem, mesh_size): mesh = problem.mesh_generator(mesh_size) u = problem.solution['u'] u_sol = Expression((ccode(u['value'][0]), ccode(u['value'][1])), degree=u['degree']) p = problem.solution['p'] p_sol = Expression(ccode(p['value']), degree=p['degree']) f = Expression( (ccode(problem.f['value'][0]), ccode(problem.f['value'][1])), degree=problem.f['degree']) W = VectorElement('Lagrange', mesh.ufl_cell(), 2) P = FiniteElement('Lagrange', mesh.ufl_cell(), 1) WP = FunctionSpace(mesh, W * P) # Get Dirichlet boundary conditions u_bcs = DirichletBC(WP.sub(0), u_sol, 'on_boundary') p_bcs = DirichletBC(WP.sub(1), p_sol, 'on_boundary') u_approx, p_approx = flow.stokes.solve(WP, bcs=[u_bcs, p_bcs], mu=problem.mu, f=f, verbose=True, tol=1.0e-12) # compute errors u_error = errornorm(u_sol, u_approx) p_error = errornorm(p_sol, p_approx) return mesh.hmax(), u_error, p_error
def __init__(self, grid, u_degree, p_degree, split=False): w_elem = VectorElement("CG", grid.mesh.ufl_cell(), u_degree) q_elem = FiniteElement("CG", grid.mesh.ufl_cell(), p_degree) self.W = FunctionSpace(grid.mesh, w_elem) self.Q = FunctionSpace(grid.mesh, q_elem) self.split = split if not self.split: self.mixedSpace = BlockFunctionSpace([self.W, self.Q])
def test_tabulate_coord_periodic(mesh_factory): class PeriodicBoundary2(SubDomain): def inside(self, x, on_boundary): return x[0] < DOLFIN_EPS def map(self, x, y): y[0] = x[0] - 1.0 y[1] = x[1] # Create periodic boundary condition periodic_boundary = PeriodicBoundary2() func, args = mesh_factory mesh = func(*args) V = FiniteElement("Lagrange", mesh.ufl_cell(), 1) Q = VectorElement("Lagrange", mesh.ufl_cell(), 1) W = V * Q V = FunctionSpace(mesh, V, constrained_domain=periodic_boundary) W = FunctionSpace(mesh, W, constrained_domain=periodic_boundary) L0 = W.sub(0) L1 = W.sub(1) L01 = L1.sub(0) L11 = L1.sub(1) sdim = V.element().space_dimension() coord0 = np.zeros((sdim, 2), dtype="d") coord1 = np.zeros((sdim, 2), dtype="d") coord2 = np.zeros((sdim, 2), dtype="d") coord3 = np.zeros((sdim, 2), dtype="d") for cell in Cells(mesh): coord0 = V.element().tabulate_dof_coordinates(cell) coord1 = L0.element().tabulate_dof_coordinates(cell) coord2 = L01.element().tabulate_dof_coordinates(cell) coord3 = L11.element().tabulate_dof_coordinates(cell) coord4 = L1.element().tabulate_dof_coordinates(cell) assert (coord0 == coord1).all() assert (coord0 == coord2).all() assert (coord0 == coord3).all() assert (coord4[:sdim] == coord0).all() assert (coord4[sdim:] == coord0).all()
def _test_eigen_solver_sparse(callback_type): from rbnics.backends.dolfin import EigenSolver # Define mesh mesh = UnitSquareMesh(10, 10) # Define function space V_element = VectorElement("Lagrange", mesh.ufl_cell(), 2) Q_element = FiniteElement("Lagrange", mesh.ufl_cell(), 1) W_element = MixedElement(V_element, Q_element) W = FunctionSpace(mesh, W_element) # Create boundaries class Wall(SubDomain): def inside(self, x, on_boundary): return on_boundary and (x[1] < 0 + DOLFIN_EPS or x[1] > 1 - DOLFIN_EPS) boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) wall = Wall() wall.mark(boundaries, 1) # Define variational problem vq = TestFunction(W) (v, q) = split(vq) up = TrialFunction(W) (u, p) = split(up) lhs = inner(grad(u), grad(v)) * dx - div(v) * p * dx - div(u) * q * dx rhs = -inner(p, q) * dx # Define boundary condition bc = [DirichletBC(W.sub(0), Constant((0., 0.)), boundaries, 1)] # Define eigensolver depending on callback type assert callback_type in ("form callbacks", "tensor callbacks") if callback_type == "form callbacks": solver = EigenSolver(W, lhs, rhs, bc) elif callback_type == "tensor callbacks": LHS = assemble(lhs) RHS = assemble(rhs) solver = EigenSolver(W, LHS, RHS, bc) # Solve the eigenproblem solver.set_parameters({ "linear_solver": "mumps", "problem_type": "gen_non_hermitian", "spectrum": "target real", "spectral_transform": "shift-and-invert", "spectral_shift": 1.e-5 }) solver.solve(1) r, c = solver.get_eigenvalue(0) assert abs(c) < 1.e-10 assert r > 0., "r = " + str(r) + " is not positive" print("Sparse inf-sup constant: ", sqrt(r)) return (sqrt(r), solver.condensed_A, solver.condensed_B)