def test_mixed_element_vector_element_form(cell_type, sign, order): if cell_type == CellType.triangle or cell_type == CellType.quadrilateral: mesh = create_unit_square(MPI.COMM_WORLD, 2, 2, cell_type) else: mesh = create_unit_cube(MPI.COMM_WORLD, 2, 2, 2, cell_type) if cell_type == CellType.triangle: U_el = MixedElement([VectorElement("Lagrange", ufl.triangle, order), FiniteElement("N1curl", ufl.triangle, order)]) elif cell_type == CellType.quadrilateral: U_el = MixedElement([VectorElement("Lagrange", ufl.quadrilateral, order), FiniteElement("RTCE", ufl.quadrilateral, order)]) elif cell_type == CellType.tetrahedron: U_el = MixedElement([VectorElement("Lagrange", ufl.tetrahedron, order), FiniteElement("N1curl", ufl.tetrahedron, order)]) elif cell_type == CellType.hexahedron: U_el = MixedElement([VectorElement("Lagrange", ufl.hexahedron, order), FiniteElement("NCE", ufl.hexahedron, order)]) U = FunctionSpace(mesh, U_el) u, p = ufl.TrialFunctions(U) v, q = ufl.TestFunctions(U) f = form(inner(u, v) * ufl.dx + inner(p, q)(sign) * ufl.dS) A = dolfinx.fem.assemble_matrix(f) A.assemble() check_symmetry(A)
def build_ufl_element_list(): """Build collection of UFL elements""" elements = [] # Lagrange elements for cell in (interval, triangle, tetrahedron): for p in range(1, 2): elements.append(FiniteElement("Lagrange", cell, p)) elements.append(VectorElement("Lagrange", cell, p)) elements.append( FiniteElement("Discontinuous Lagrange", cell, p - 1)) # Vector elements for cell in (triangle, tetrahedron): for p in range(1, 2): elements.append(FiniteElement("RT", cell, p)) elements.append(FiniteElement("BDM", cell, p)) elements.append(FiniteElement("N1curl", cell, p)) elements.append(FiniteElement("N2curl", cell, p)) elements.append( FiniteElement("Discontinuous Raviart-Thomas", cell, p)) # Mixed elements for cell in (interval, triangle, tetrahedron): for p in range(1, 3): e0 = FiniteElement("Lagrange", cell, p + 1) e1 = FiniteElement("Lagrange", cell, p) e2 = VectorElement("Lagrange", cell, p + 1) elements.append(MixedElement([e0, e0])) elements.append(MixedElement([e0, e1])) elements.append(MixedElement([e1, e0])) elements.append(MixedElement([e2, e1])) elements.append(MixedElement([MixedElement([e1, e1]), e0])) for cell in (triangle, tetrahedron): for p in range(1, 2): e0 = FiniteElement("Lagrange", cell, p + 1) e1 = FiniteElement("Lagrange", cell, p) e2 = VectorElement("Lagrange", cell, p + 1) e3 = FiniteElement("BDM", cell, p) e4 = FiniteElement("RT", cell, p + 1) e5 = FiniteElement("N1curl", cell, p) elements.append(MixedElement([e1, e2])) elements.append(MixedElement([e3, MixedElement([e4, e5])])) # Misc elements for cell in (triangle, ): for p in range(1, 2): elements.append(FiniteElement("HHJ", cell, p)) for cell in (triangle, tetrahedron): elements.append(FiniteElement("CR", cell, 1)) for p in range(1, 2): elements.append(FiniteElement("Regge", cell, p)) return elements
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 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) def z(values, x): 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] 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_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) def z(x): return np.row_stack((x[0] * x[1], x[1] * x[2], x[2] * x[0], x[0] + 3.0 * x[1] + x[2])) zc, zf = Function(Zc), Function(Zf) zc.interpolate(z) zf.interpolate(z) 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_physically_mapped_facet(): mesh = Mesh(VectorElement("P", triangle, 1)) # set up variational problem U = FiniteElement("Morley", mesh.ufl_cell(), 2) V = FiniteElement("P", mesh.ufl_cell(), 1) R = FiniteElement("P", mesh.ufl_cell(), 1) Vv = VectorElement(BrokenElement(V)) Qhat = VectorElement(BrokenElement(V[facet])) Vhat = VectorElement(V[facet]) Z = FunctionSpace(mesh, MixedElement(U, Vv, Qhat, Vhat, R)) z = Coefficient(Z) u, d, qhat, dhat, lam = split(z) s = FacetNormal(mesh) trans = as_matrix([[1, 0], [0, 1]]) mat = trans*grad(grad(u))*trans + outer(d, d) * u J = (u**2*dx + u**3*dx + u**4*dx + inner(mat, mat)*dx + inner(grad(d), grad(d))*dx + dot(s, d)**2*ds) L_match = inner(qhat, dhat - d) L = J + inner(lam, inner(d, d)-1)*dx + (L_match('+') + L_match('-'))*dS + L_match*ds compile_form(L)
def _create_mixed_finiteelement( element: ufl.MixedElement) -> FIAT.MixedElement: elements = [] def rextract(els): for e in els: if isinstance(e, ufl.MixedElement) \ and not isinstance(e, ufl.VectorElement) \ and not isinstance(e, ufl.TensorElement): rextract(e.sub_elements()) else: elements.append(e) rextract(element.sub_elements()) return FIAT.MixedElement(map(_create_element, elements))
def reconstruct_degree(ele, N): """ Reconstruct an element, modifying its polynomial degree. By default, reconstructed EnrichedElements, TensorProductElements, and MixedElements will have the degree of the sub-elements shifted by the same amount so that the maximum degree is N. This is useful to coarsen spaces like NCF(N) x DQ(N-1). :arg ele: a :class:`ufl.FiniteElement` to reconstruct, :arg N: an integer degree. :returns: the reconstructed element """ if isinstance(ele, VectorElement): return VectorElement(PMGBase.reconstruct_degree( ele._sub_element, N), dim=ele.num_sub_elements()) elif isinstance(ele, TensorElement): return TensorElement(PMGBase.reconstruct_degree( ele._sub_element, N), shape=ele.value_shape(), symmetry=ele.symmetry()) elif isinstance(ele, EnrichedElement): shift = N - PMGBase.max_degree(ele) return EnrichedElement( *(PMGBase.reconstruct_degree(e, PMGBase.max_degree(e) + shift) for e in ele._elements)) elif isinstance(ele, TensorProductElement): shift = N - PMGBase.max_degree(ele) return TensorProductElement(*(PMGBase.reconstruct_degree( e, PMGBase.max_degree(e) + shift) for e in ele.sub_elements()), cell=ele.cell()) elif isinstance(ele, MixedElement): shift = N - PMGBase.max_degree(ele) return MixedElement( *(PMGBase.reconstruct_degree(e, PMGBase.max_degree(e) + shift) for e in ele.sub_elements())) else: try: return type(ele)(PMGBase.reconstruct_degree(ele._element, N)) except AttributeError: return ele.reconstruct(degree=N)
def test_block_size(mesh): meshes = [ UnitSquareMesh(8, 8), UnitCubeMesh(4, 4, 4), UnitSquareMesh(8, 8, CellType.quadrilateral), UnitCubeMesh(4, 4, 4, CellType.hexahedron) ] for mesh in meshes: P2 = FiniteElement("Lagrange", mesh.ufl_cell(), 2) V = FunctionSpace(mesh, P2) assert V.dofmap.block_size == 1 V = FunctionSpace(mesh, P2 * P2) assert V.dofmap.index_map.block_size == 2 for i in range(1, 6): W = FunctionSpace(mesh, MixedElement(i * [P2])) assert W.dofmap.index_map.block_size == i V = VectorFunctionSpace(mesh, ("Lagrange", 2)) assert V.dofmap.index_map.block_size == mesh.geometry.dim
def test_delta_elimination(mode): # Code sample courtesy of Marco Morandini: # https://github.com/firedrakeproject/tsfc/issues/182 scheme = "default" degree = 3 element_lambda = FiniteElement("Quadrature", tetrahedron, degree, quad_scheme=scheme) element_eps_p = VectorElement("Quadrature", tetrahedron, degree, dim=6, quad_scheme=scheme) element_chi_lambda = MixedElement(element_eps_p, element_lambda) chi_lambda = Coefficient(element_chi_lambda) delta_chi_lambda = TestFunction(element_chi_lambda) L = inner(delta_chi_lambda, chi_lambda) * dx(degree=degree, scheme=scheme) kernel, = compile_form(L, parameters={'mode': mode})
cr1_tri = FiniteElement("CR", "triangle", 1) rt1_tri = FiniteElement("RT", "triangle", 1) drt2_tri = FiniteElement("DRT", "triangle", 2) bdm1_tri = FiniteElement("BDM", "triangle", 1) ned1_tri = FiniteElement("N1curl", "triangle", 1) dg0_tet = FiniteElement("DG", "tetrahedron", 0) dg1_tet = FiniteElement("DG", "tetrahedron", 1) cg1_tet = FiniteElement("CG", "tetrahedron", 1) cr1_tet = FiniteElement("CR", "tetrahedron", 1) rt1_tet = FiniteElement("RT", "tetrahedron", 1) drt2_tet = FiniteElement("DRT", "tetrahedron", 2) bdm1_tet = FiniteElement("BDM", "tetrahedron", 1) ned1_tet = FiniteElement("N1curl", "tetrahedron", 1) mixed_elements = [MixedElement([dg0_tri]*4), MixedElement([cg1_tri]*3), MixedElement([bdm1_tri]*2),\ MixedElement([dg1_tri, cg1_tri, cr1_tri, rt1_tri, bdm1_tri, ned1_tri]),\ MixedElement([MixedElement([rt1_tri, cr1_tri]), cg1_tri, ned1_tri]),\ MixedElement([ned1_tri, dg1_tri, MixedElement([rt1_tri, cr1_tri])]),\ MixedElement([drt2_tri, cg1_tri]),\ MixedElement([dg0_tet]*4), MixedElement([cg1_tet]*3), MixedElement([bdm1_tet]*2),\ MixedElement([dg1_tet, cg1_tet, cr1_tet, rt1_tet, bdm1_tet, ned1_tet]),\ MixedElement([MixedElement([rt1_tet, cr1_tet]), cg1_tet, ned1_tet]),\ MixedElement([ned1_tet, dg1_tet, MixedElement([rt1_tet, cr1_tet])]),\ MixedElement([drt2_tet, cg1_tet])] ffc_failed = [] gcc_failed = [] run_failed = [] def check_results(values, reference):
def W(V, Q): mesh = V.ufl_domain() return FunctionSpace(mesh, MixedElement(V.ufl_element(), Q.ufl_element()))
def skw(tau): """Define vectorized skew operator""" sk = 2 * skew(tau) return as_vector((sk[0, 1], sk[0, 2], sk[1, 2])) cell = tetrahedron n = 3 # Finite element exterior calculus syntax r = 1 S = VectorElement("P Lambda", cell, r, form_degree=n - 1) V = VectorElement("P Lambda", cell, r - 1, form_degree=n) Q = VectorElement("P Lambda", cell, r - 1, form_degree=n) # Alternative syntax: # S = VectorElement("BDM", cell, r) # V = VectorElement("Discontinuous Lagrange", cell, r-1) # Q = VectorElement("Discontinuous Lagrange", cell, r-1) W = MixedElement(S, V, Q) (sigma, u, gamma) = TrialFunctions(W) (tau, v, eta) = TestFunctions(W) a = (inner(sigma, tau) - tr(sigma) * tr(tau) + dot(div(tau), u) - dot(div(sigma), v) + inner(skw(tau), gamma) + inner(skw(sigma), eta)) * dx