def __init__(self, reference, order): from symfem import create_reference assert order == 5 assert reference.name == "triangle" dofs = [] for v_n, vs in enumerate(reference.vertices): dofs.append(PointEvaluation(vs, entity=(0, v_n))) for i in range(reference.tdim): direction = tuple(1 if i == j else 0 for j in range(reference.tdim)) dofs.append( PointDirectionalDerivativeEvaluation(vs, direction, entity=(0, v_n))) for i in range(reference.tdim): for j in range(i + 1): dofs.append( PointComponentSecondDerivativeEvaluation(vs, (i, j), entity=(0, v_n))) for e_n, vs in enumerate(reference.sub_entities(1)): sub_ref = create_reference( reference.sub_entity_types[1], vertices=[reference.vertices[v] for v in vs]) midpoint = tuple( sym_sum(i) / len(i) for i in zip(*[reference.vertices[i] for i in vs])) dofs.append( PointNormalDerivativeEvaluation(midpoint, sub_ref, entity=(1, e_n))) super().__init__(reference, order, polynomial_set(reference.tdim, 1, order), dofs, reference.tdim, 1)
def __init__(self, reference, order, variant="equispaced"): from symfem import create_reference if order == 0: dofs = [ PointEvaluation( tuple(sympy.Rational(1, 2) for i in range(reference.tdim)), entity=(reference.tdim, 0))] else: points, _ = get_quadrature(variant, order + 1) dofs = [] for v_n, v in enumerate(reference.vertices): dofs.append(PointEvaluation(v, entity=(0, v_n))) for edim in range(1, 4): for e_n, vs in enumerate(reference.sub_entities(edim)): entity = create_reference( reference.sub_entity_types[edim], vertices=tuple(reference.vertices[i] for i in vs)) for i in product(range(1, order), repeat=edim): dofs.append( PointEvaluation( tuple(o + sum(a[j] * points[b] for a, b in zip(entity.axes, i[::-1])) for j, o in enumerate(entity.origin)), entity=(edim, e_n))) super().__init__( reference, order, quolynomial_set(reference.tdim, 1, order), dofs, reference.tdim, 1) self.variant = variant
def test_piecewise_lagrange_tetrahedron(order): reference = symfem.create_reference("tetrahedron") mid = tuple( sympy.Rational(sum(i), len(i)) for i in zip(*reference.vertices)) sub_tets = [(reference.vertices[0], reference.vertices[1], reference.vertices[2], mid), (reference.vertices[0], reference.vertices[1], reference.vertices[3], mid), (reference.vertices[0], reference.vertices[2], reference.vertices[3], mid), (reference.vertices[1], reference.vertices[2], reference.vertices[3], mid)] N = 5 fs = make_piecewise_lagrange(sub_tets, "tetrahedron", order, zero_on_boundary=True) for f_n in range(reference.sub_entity_count(2)): face = reference.sub_entity(2, f_n) for i in range(N + 1): for j in range(N + 1 - i): point = face.get_point( (sympy.Rational(i, N), sympy.Rational(j, N))) for f in fs: assert subs(f, x, point) == (0, 0, 0) fs = make_piecewise_lagrange(sub_tets, "tetrahedron", order, zero_at_centre=True) for f in fs: assert subs(f, x, mid) == (0, 0, 0)
def test_piecewise_lagrange_triangle(order): reference = symfem.create_reference("triangle") mid = tuple( sympy.Rational(sum(i), len(i)) for i in zip(*reference.vertices)) sub_tris = [(reference.vertices[0], reference.vertices[1], mid), (reference.vertices[0], reference.vertices[2], mid), (reference.vertices[1], reference.vertices[2], mid)] N = 5 fs = make_piecewise_lagrange(sub_tris, "triangle", order, zero_on_boundary=True) for e_n in range(reference.sub_entity_count(1)): edge = reference.sub_entity(1, e_n) for i in range(N + 1): point = edge.get_point((sympy.Rational(i, N), )) for f in fs: assert subs(f, x, point) == (0, 0) fs = make_piecewise_lagrange(sub_tris, "triangle", order, zero_at_centre=True) for f in fs: assert subs(f, x, mid) == (0, 0)
def sub_entity(self, dim, n, reference_vertices=False): """Get the sub entity of a given dimension and number.""" from symfem import create_reference entity_type = self.sub_entity_types[dim] if not isinstance(entity_type, str): entity_type = entity_type[n] if reference_vertices: return create_reference(entity_type, [ self.reference_vertices[i] for i in self.sub_entities(dim)[n] ]) else: if self.tdim == dim: return self else: return create_reference( entity_type, [self.vertices[i] for i in self.sub_entities(dim)[n]])
def __init__(self, reference, order): from symfem import create_reference assert order == 3 assert reference.name == "triangle" dofs = [] for v_n, vs in enumerate(reference.vertices): dofs.append(PointEvaluation(vs, entity=(0, v_n))) dofs.append(DerivativePointEvaluation(vs, (1, 0), entity=(0, v_n))) dofs.append(DerivativePointEvaluation(vs, (0, 1), entity=(0, v_n))) mid = tuple( sympy.Rational(sum(i), len(i)) for i in zip(*reference.vertices)) subs = [(reference.vertices[0], reference.vertices[1], mid), (reference.vertices[1], reference.vertices[2], mid), (reference.vertices[2], reference.vertices[0], mid)] refs = [create_reference("triangle", vs) for vs in subs] polys = [ polynomial_set(reference.tdim, 1, order), [], polynomial_set(reference.tdim, 1, order), ] polys[0].remove(x[0]**2 * x[1]) polys[1] = [ 1, x[0], x[0]**2, x[1], x[0] * x[1], x[1]**2, x[0] * x[1]**2 - x[0]**2 * x[1], x[0]**3 - x[1]**3, x[0]**3 + 3 * x[0] * x[1]**2 ] polys[2].remove(x[0] * x[1]**2) bases = [ P1Hermite(r, 3, p).get_basis_functions() for r, p in zip(refs, polys) ] piece_list = [] piece_list.append((bases[0][0], 0, bases[2][3])) piece_list.append((bases[0][1], 0, bases[2][4])) piece_list.append((bases[0][2], 0, bases[2][5])) piece_list.append((bases[0][3], bases[1][0], 0)) piece_list.append((bases[0][4], bases[1][1], 0)) piece_list.append((bases[0][5], bases[1][2], 0)) # TODO: are these right to remove?? # piece_list.append((bases[0][6], bases[1][6], bases[2][6])) # piece_list.append((bases[0][7], bases[1][7], bases[2][7])) # piece_list.append((bases[0][8], bases[1][8], bases[2][8])) piece_list.append((0, bases[1][3], bases[2][0])) piece_list.append((0, bases[1][4], bases[2][1])) piece_list.append((0, bases[1][5], bases[2][2])) poly = [PiecewiseFunction(list(zip(subs, p))) for p in piece_list] super().__init__(reference, order, poly, dofs, reference.tdim, 1)
def test_MTW_space(reference): e = create_element(reference, "MTW", 3) polynomials = e.get_polynomial_basis() for p in polynomials: assert div(p).is_real for vs in e.reference.sub_entities(1): sub_ref = create_reference(e.reference.sub_entity_types[1], [e.reference.vertices[i] for i in vs]) p_edge = subs(p, x, [ i + t[0] * j for i, j in zip(sub_ref.origin, sub_ref.axes[0]) ]) poly = vdot(p_edge, sub_ref.normal()).expand().simplify() assert poly.is_real or sympy.Poly(poly).degree() <= 1
def __init__(self, reference, order, variant="equispaced"): from symfem import create_reference assert reference.name == "triangle" self.variant = variant poly = [(p[0], p[1], p[1], p[2]) for p in polynomial_set(reference.tdim, 3, order - 1)] poly += [[0, x[1]**2, x[1]**2, -2 * x[1]**2], [-2 * x[0]**2, x[0]**2, x[0]**2, 0], [-2 * x[0] * x[1], x[0] * x[1], x[0] * x[1], 0], [x[0] * (x[0] - x[1]), 0, 0, 0], [x[0]**2, 0, 0, x[0] * x[1]], [x[0]**2, 0, 0, x[1]**2]] dofs = [] for e_n, edge in enumerate(reference.edges): sub_ref = create_reference(reference.sub_entity_types[1], vertices=tuple(reference.vertices[i] for i in edge)) sub_e = Lagrange(sub_ref.default_reference(), 1, variant) for dof_n, dof in enumerate(sub_e.dofs): p = sub_e.get_basis_function(dof_n) for component in [sub_ref.normal(), sub_ref.tangent()]: dofs.append( InnerProductIntegralMoment( sub_ref, p, component, sub_ref.normal(), dof, entity=(1, e_n), mapping="double_contravariant")) sub_e = Lagrange(reference, 0, variant) for dof_n, dof in enumerate(sub_e.dofs): p = sub_e.get_basis_function(dof_n) for component in [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 0, 1)]: dofs.append( VecIntegralMoment(reference, p, component, dof, entity=(2, 0))) super().__init__(reference, order, poly, dofs, reference.tdim, reference.tdim**2, (reference.tdim, reference.tdim))
def test_BDFM_space(reference, order): e = create_element(reference, "BDFM", order) polynomials = e.get_polynomial_basis() tdim = e.reference.tdim for p in polynomials: for vs in e.reference.sub_entities(tdim - 1): sub_ref = create_reference(e.reference.sub_entity_types[tdim - 1], [e.reference.vertices[i] for i in vs]) if tdim == 2: p_edge = subs(p, x, [ i + t[0] * j for i, j in zip(sub_ref.origin, sub_ref.axes[0]) ]) else: p_edge = subs(p, x, [ i + t[0] * j + t[1] * k for i, j, k in zip( sub_ref.origin, sub_ref.axes[0], sub_ref.axes[1]) ]) poly = vdot(p_edge, sub_ref.normal()).expand().simplify() assert poly.is_real or sympy.Poly(poly).degree() <= order - 1
def test_stiffness_matrix(): vertices = [(0, 0), (1, 0), (0, 1), (1, 1)] triangles = [[0, 1, 2], [1, 3, 2]] matrix = [[0 for i in vertices] for j in vertices] element = symfem.create_element("triangle", "Lagrange", 1) for triangle in triangles: vs = [vertices[i] for i in triangle] ref = symfem.create_reference("triangle", vertices=vs) basis = element.map_to_cell(vs) for test_i, test_f in zip(triangle, basis): for trial_i, trial_f in zip(triangle, basis): integrand = vdot(grad(test_f, 2), grad(trial_f, 2)) matrix[test_i][trial_i] += ref.integral(integrand) half = sympy.Rational(1, 2) actual_matrix = [[1, -half, -half, 0], [-half, 1, 0, -half], [-half, 0, 1, -half], [0, -half, -half, 1]] for row1, row2 in zip(matrix, actual_matrix): for i, j in zip(row1, row2): assert i == j
def __init__(self, reference, order, variant="equispaced"): from symfem import create_reference assert reference.name in ["triangle", "tetrahedron"] if order > 1: assert reference.name == "triangle" points, _ = get_quadrature(variant, order + reference.tdim) dofs = [] for e_n, vs in enumerate(reference.sub_entities(reference.tdim - 1)): entity = create_reference( reference.sub_entity_types[reference.tdim - 1], vertices=tuple(reference.vertices[i] for i in vs)) for i in product(range(1, order + 1), repeat=reference.tdim - 1): if sum(i) < order + reference.tdim - 1: dofs.append( PointEvaluation( tuple(o + sum(a[j] * points[b] for a, b in zip(entity.axes, i)) for j, o in enumerate(entity.origin)), entity=(reference.tdim - 1, e_n))) points, _ = get_quadrature(variant, order + reference.tdim - 1) for i in product(range(1, order), repeat=reference.tdim): if sum(i) < order: dofs.append( PointEvaluation( tuple(o + sum(a[j] * points[b] for a, b in zip(reference.axes, i)) for j, o in enumerate(reference.origin)), entity=(reference.tdim, 0))) poly = polynomial_set(reference.tdim, 1, order) self.variant = variant super().__init__(reference, order, poly, dofs, reference.tdim, 1)
res = np.linalg.solve(A, b) fractions = [] for i in res: frac = sympy.Rational(int(round(i * 162000)), 162000) assert i < 10 assert np.isclose(float(frac), i) fractions.append(frac) assert sympy.Matrix(mat) * sympy.Matrix(fractions) == sympy.Matrix(aim) return fractions for ref in ["triangle", "tetrahedron"]: reference = symfem.create_reference(ref) br = symfem.create_element(ref, "Bernardi-Raugel", 1) mid = tuple( sympy.Rational(sum(i), len(i)) for i in zip(*reference.vertices)) if ref == "triangle": fs = br.get_basis_functions()[-3:] sub_cells = [(reference.vertices[0], reference.vertices[1], mid), (reference.vertices[0], reference.vertices[2], mid), (reference.vertices[1], reference.vertices[2], mid)] xx, yy, zz = [i.to_sympy() for i in x] terms = [1, xx, yy] if ref == "tetrahedron": fs = br.get_basis_functions()[-4:] sub_cells = [(reference.vertices[0], reference.vertices[1], reference.vertices[2], mid),
def __init__(self, reference, order): from symfem import create_reference assert order == 3 assert reference.name == "triangle" dofs = [] for v_n, vs in enumerate(reference.vertices): dofs.append(PointEvaluation(vs, entity=(0, v_n))) dofs.append(DerivativePointEvaluation(vs, (1, 0), entity=(0, v_n))) dofs.append(DerivativePointEvaluation(vs, (0, 1), entity=(0, v_n))) for e_n, vs in enumerate(reference.sub_entities(1)): sub_ref = create_reference( reference.sub_entity_types[1], vertices=[reference.vertices[v] for v in vs]) midpoint = tuple( sym_sum(i) / len(i) for i in zip(*[reference.vertices[i] for i in vs])) dofs.append( PointNormalDerivativeEvaluation(midpoint, sub_ref, entity=(1, e_n))) mid = tuple( sympy.Rational(sum(i), len(i)) for i in zip(*reference.vertices)) subs = [(reference.vertices[0], reference.vertices[1], mid), (reference.vertices[1], reference.vertices[2], mid), (reference.vertices[2], reference.vertices[0], mid)] refs = [create_reference("triangle", vs) for vs in subs] hermite_spaces = [Hermite(ref, 3) for ref in refs] piece_list = [] piece_list.append((hermite_spaces[0].get_basis_function(0), 0, hermite_spaces[2].get_basis_function(3))) piece_list.append((hermite_spaces[0].get_basis_function(1), 0, hermite_spaces[2].get_basis_function(4))) piece_list.append((hermite_spaces[0].get_basis_function(2), 0, hermite_spaces[2].get_basis_function(5))) piece_list.append((hermite_spaces[0].get_basis_function(3), hermite_spaces[1].get_basis_function(0), 0)) piece_list.append((hermite_spaces[0].get_basis_function(4), hermite_spaces[1].get_basis_function(1), 0)) piece_list.append((hermite_spaces[0].get_basis_function(5), hermite_spaces[1].get_basis_function(2), 0)) piece_list.append((hermite_spaces[0].get_basis_function(6), hermite_spaces[1].get_basis_function(6), hermite_spaces[2].get_basis_function(6))) piece_list.append((hermite_spaces[0].get_basis_function(7), hermite_spaces[1].get_basis_function(7), hermite_spaces[2].get_basis_function(7))) piece_list.append((hermite_spaces[0].get_basis_function(8), hermite_spaces[1].get_basis_function(8), hermite_spaces[2].get_basis_function(8))) piece_list.append((0, hermite_spaces[1].get_basis_function(3), hermite_spaces[2].get_basis_function(0))) piece_list.append((0, hermite_spaces[1].get_basis_function(4), hermite_spaces[2].get_basis_function(1))) piece_list.append((0, hermite_spaces[1].get_basis_function(5), hermite_spaces[2].get_basis_function(2))) # TODO: are these right to remove?? # piece_list.append((hermite_spaces[0].get_basis_function(9), 0, 0)) # piece_list.append((0, hermite_spaces[1].get_basis_function(9), 0)) # piece_list.append((0, 0, hermite_spaces[2].get_basis_function(9))) poly = [PiecewiseFunction(list(zip(subs, p))) for p in piece_list] super().__init__(reference, order, poly, dofs, reference.tdim, 1)
def test_Hdiv_space(reference, order): ref = create_reference(reference) polynomials = Hdiv_polynomials(ref.tdim, ref.tdim, order) for p in polynomials: for i, j in zip(x, p): assert j / i == p[0] / x[0]
def plot_reference(matches): e = symfem.create_reference(matches[1]) return f"<center>{plotting.plot_reference(e)}</center>"
def make_piecewise_lagrange(sub_cells, cell_name, order, zero_on_boundary=False, zero_at_centre=False): """Make the basis functions of a piecewise Lagrange space.""" from symfem import create_reference lagrange_space = VectorLagrange(create_reference(cell_name), order) lagrange_bases = [lagrange_space.map_to_cell(c) for c in sub_cells] basis_dofs = [] if cell_name == "triangle": # DOFs on vertices nones = [None for i in lagrange_space.entity_dofs(0, 0)] for vertices in [(0, 0, None), (1, None, 0), (None, 1, 1), (2, 2, 2)]: if zero_on_boundary and (0 in vertices or 1 in vertices): continue if zero_at_centre and (2 in vertices): continue for dofs in zip(*[ nones if i is None else lagrange_space.entity_dofs(0, i) for i in vertices ]): basis_dofs.append(dofs) # DOFs on edges nones = [None for i in lagrange_space.entity_dofs(1, 0)] for edge in [(0, None, 1), (1, 1, None), (None, 0, 0), (2, None, None), (None, 2, None), (None, None, 2)]: if zero_on_boundary and 2 in edge: continue for dofs in zip(*[ nones if i is None else lagrange_space.entity_dofs(1, i) for i in edge ]): basis_dofs.append(dofs) # DOFs on interiors nones = [None for i in lagrange_space.entity_dofs(2, 0)] for interior in [(0, None, None), (None, 0, None), (None, None, 0)]: for dofs in zip(*[ nones if i is None else lagrange_space.entity_dofs(2, i) for i in interior ]): basis_dofs.append(dofs) zero = (0, 0) elif cell_name == "tetrahedron": # DOFs on vertices nones = [None for i in lagrange_space.entity_dofs(0, 0)] for vertices in [(0, 0, 0, None), (1, 1, None, 0), (2, None, 1, 1), (None, 2, 2, 2), (3, 3, 3, 3)]: if zero_on_boundary and (0 in vertices or 1 in vertices or 2 in vertices): continue if zero_at_centre and (3 in vertices): continue for dofs in zip(*[ nones if i is None else lagrange_space.entity_dofs(0, i) for i in vertices ]): basis_dofs.append(dofs) # DOFs on edges nones = [None for i in lagrange_space.entity_dofs(1, 0)] for edge in [(2, None, None, 5), (5, 5, None, None), (4, None, 5, None), (None, 2, None, 4), (None, 4, 4, None), (None, None, 2, 2), (3, 3, 3, None), (None, 0, 0, 0), (0, None, 1, 1), (1, 1, None, 3)]: if zero_on_boundary and (2 in edge or 4 in edge or 5 in edge): continue for dofs in zip(*[ nones if i is None else lagrange_space.entity_dofs(1, i) for i in edge ]): basis_dofs.append(dofs) # DOFs on faces nones = [None for i in lagrange_space.entity_dofs(2, 0)] for face in [(0, None, None, 2), (1, None, 2, None), (2, 2, None, None), (3, None, None, None), (None, 0, None, 1), (None, 1, 1, None), (None, 3, None, None), (None, None, 0, 0), (None, None, 3, None), (None, None, None, 3)]: if zero_on_boundary and 3 in face: continue for dofs in zip(*[ nones if i is None else lagrange_space.entity_dofs(2, i) for i in face ]): basis_dofs.append(dofs) # DOFs on interiors nones = [None for i in lagrange_space.entity_dofs(3, 0)] for interior in [(0, None, None, None), (None, 0, None, None), (None, None, 0, None), (None, None, None, 0)]: for dofs in zip(*[ nones if i is None else lagrange_space.entity_dofs(3, i) for i in interior ]): basis_dofs.append(dofs) zero = (0, 0, 0) basis = [] for i in basis_dofs: basis.append( PiecewiseFunction(list(zip(sub_cells, [ zero if j is None else s[j] for s, j in zip(lagrange_bases, i) ]))) ) return basis
for j in elementlist.values(): j.sort(key=lambda x: x.lower()) with open("README.md") as f: pre = f.read().split("# Available cells and elements")[0] with open("README.md", "w") as f: f.write(pre) f.write("# Available cells and elements\n") for cell in cells: f.write(f"## {cell[0].upper()}{cell[1:]}\n") if cell == "dual polygon": f.write(f"The reference {cell} (hexagon example shown) has vertices ") ref = symfem.create_reference("dual polygon(6)") else: f.write(f"The reference {cell} has vertices ") ref = symfem.create_reference(cell) str_v = [f"{v}" for v in ref.vertices] if len(ref.vertices) <= 2: f.write(" and ".join(str_v)) else: f.write(", and ".join([", ".join(str_v[:-1]), str_v[-1]])) f.write(". Its sub-entities are numbered as follows.\n\n") f.write(f"![The numbering of a reference {cell}]" f"(img/{cell.replace(' ', '_')}_numbering.png)\n\n") f.write("### List of supported elements\n") f.write("\n".join([f"- {i}" for i in elementlist[cell]])) f.write("\n\n")
from symfem.vectors import vdot from symfem.calculus import grad # Define the vertived and triangles of the mesh vertices = [(0, 0), (1, 0), (0, 1), (1, 1)] triangles = [[0, 1, 2], [1, 3, 2]] # Create a matrix of zeros with the correct shape matrix = [[0 for i in range(4)] for j in range(4)] # Create a Lagrange element element = symfem.create_element("triangle", "Lagrange", 1) for triangle in triangles: # Get the vertices of the triangle vs = [vertices[i] for i in triangle] # Create a reference cell with these vertices: this will be used # to compute the integral over the triangle ref = symfem.create_reference("triangle", vertices=vs) # Map the basis functions to the cell basis = element.map_to_cell(vs) for test_i, test_f in zip(triangle, basis): for trial_i, trial_f in zip(triangle, basis): # Compute the integral of grad(u)-dot-grad(v) for each pair of basis # functions u and v integrand = vdot(grad(test_f, 2), grad(trial_f, 2)) matrix[test_i][trial_i] += ref.integral(integrand) print(matrix)
def __init__(self, reference, order, variant="equispaced"): from symfem import create_reference assert reference.name == "triangle" self.variant = variant poly = [(p[0], p[1], p[1], p[2]) for p in polynomial_set(reference.tdim, 3, order - 1)] poly += [ ((order - k + 1) * (order - k + 2) * x[0]**k * x[1]**(order - k), -k * (order - k + 2) * x[0]**(k - 1) * x[1]**(order - k + 1), -k * (order - k + 2) * x[0]**(k - 1) * x[1]**(order - k + 1), -k * (k - 1) * x[0]**(k - 2) * x[1]**(order - k + 2)) for k in range(order + 1) ] poly += [(0, x[0]**order, x[0]**order, -order * x[0]**(order - 1) * x[1]), (0, 0, 0, x[0]**order)] dofs = [] for v_n, v in enumerate(reference.vertices): for d in [[(1, 0), (1, 0)], [(1, 0), (0, 1)], [(0, 1), (0, 1)]]: dofs.append( PointInnerProduct(v, d[0], d[1], entity=(0, v_n), mapping="double_contravariant")) for e_n, edge in enumerate(reference.edges): sub_ref = create_reference(reference.sub_entity_types[1], vertices=tuple(reference.vertices[i] for i in edge)) sub_e = Lagrange(sub_ref.default_reference(), order - 2, variant) for dof_n, dof in enumerate(sub_e.dofs): p = sub_e.get_basis_function(dof_n) for component in [sub_ref.normal(), sub_ref.tangent()]: InnerProductIntegralMoment(sub_ref, p, component, sub_ref.normal(), dof, entity=(1, e_n), mapping="double_contravariant") dofs.append( InnerProductIntegralMoment( sub_ref, p, component, sub_ref.normal(), dof, entity=(1, e_n), mapping="double_contravariant")) sub_e = Lagrange(reference, order - 3, variant) for dof_n, dof in enumerate(sub_e.dofs): p = sub_e.get_basis_function(dof_n) for component in [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 0, 1)]: dofs.append( VecIntegralMoment(reference, p, component, dof, entity=(2, 0))) if order >= 4: sub_e = Lagrange(reference, order - 4, variant) for p, dof in zip(sub_e.get_basis_functions(), sub_e.dofs): if sympy.Poly(p, x[:2]).degree() != order - 4: continue f = p * x[0]**2 * x[1]**2 * (1 - x[0] - x[1])**2 J = tuple( diff(f, x[i], x[j]) for i in range(2) for j in range(2)) dofs.append(IntegralMoment(reference, J, dof, entity=(2, 0))) super().__init__(reference, order, poly, dofs, reference.tdim, reference.tdim**2, (reference.tdim, reference.tdim))
def test_Hcurl_space(reference, order): ref = create_reference(reference) polynomials = Hcurl_polynomials(ref.tdim, ref.tdim, order) for p in polynomials: assert vdot(p, x) == 0