コード例 #1
0
ファイル: argyris.py プロジェクト: mscroggs/symfem
    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)
コード例 #2
0
ファイル: q.py プロジェクト: mscroggs/symfem
    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
コード例 #3
0
ファイル: test_guzman_neilan.py プロジェクト: mscroggs/symfem
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)
コード例 #4
0
ファイル: test_guzman_neilan.py プロジェクト: mscroggs/symfem
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)
コード例 #5
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]])
コード例 #6
0
    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)
コード例 #7
0
ファイル: test_polynomials.py プロジェクト: mscroggs/symfem
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
コード例 #8
0
    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))
コード例 #9
0
ファイル: test_polynomials.py プロジェクト: mscroggs/symfem
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
コード例 #10
0
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
コード例 #11
0
ファイル: crouzeix_raviart.py プロジェクト: mscroggs/symfem
    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)
コード例 #12
0
ファイル: generate_gn.py プロジェクト: mscroggs/symfem
    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),
コード例 #13
0
    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)
コード例 #14
0
ファイル: test_polynomials.py プロジェクト: mscroggs/symfem
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]
コード例 #15
0
def plot_reference(matches):
    e = symfem.create_reference(matches[1])
    return f"<center>{plotting.plot_reference(e)}</center>"
コード例 #16
0
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
コード例 #17
0
ファイル: update_readme.py プロジェクト: mscroggs/symfem
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")
コード例 #18
0
ファイル: stiffness_matrix.py プロジェクト: mscroggs/symfem
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)
コード例 #19
0
    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))
コード例 #20
0
ファイル: test_polynomials.py プロジェクト: mscroggs/symfem
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