def test_dual0():
    space = create_element("dual polygon(4)", "dual", 0)
    q = sympy.Rational(1, 4)
    assert symequal(
        space.tabulate_basis([[q, q], [-q, q], [-q, -q], [q, -q]]),
        ((1, ), (1, ), (1, ), (1, ))
    )
示例#2
0
def test_element(elements_to_test, cells_to_test, cell_type, element_type,
                 order, kwargs, speed):
    """Run tests for each element."""
    if elements_to_test != "ALL" and element_type not in elements_to_test:
        pytest.skip()
    if cells_to_test != "ALL" and cell_type not in cells_to_test:
        pytest.skip()
    if speed == "fast":
        if order > 2:
            pytest.skip()
        if order == 2 and cell_type in [
                "tetrahedron", "hexahedron", "prism", "pyramid"
        ]:
            pytest.skip()

    element = create_element(cell_type, element_type, order, **kwargs)
    try:
        factorised_basis = element._get_basis_functions_tensor()
    except symfem.finite_element.NoTensorProduct:
        pytest.skip(
            "This element does not have a tensor product representation.")
    basis = element.get_basis_functions()

    for i, j in zip(basis, factorised_basis):
        assert symequal(i, j)
示例#3
0
def test_equispaced(order):
    points, weights = quadrature.equispaced(order + 1)

    x = sympy.Symbol("x")
    poly = x

    assert symequal(poly.integrate((x, 0, 1)),
                    sum(i * poly.subs(x, j) for i, j in zip(weights, points)))
示例#4
0
def test_legendre(order):
    points, weights = quadrature.legendre(order)

    x = sympy.Symbol("x")
    poly = x**(2 * order - 1)

    assert symequal(poly.integrate((x, 0, 1)),
                    sum(i * poly.subs(x, j) for i, j in zip(weights, points)))
def test_lagrange_pyramid():
    space = create_element("pyramid", "Lagrange", 1)
    x_i = x[0] / (1 - x[2])
    y_i = x[1] / (1 - x[2])
    z_i = x[2] / (1 - x[2])
    basis = [(1 - x_i) * (1 - y_i) / (1 + z_i),
             x_i * (1 - y_i) / (1 + z_i),
             (1 - x_i) * y_i / (1 + z_i),
             x_i * y_i / (1 + z_i),
             z_i / (1 + z_i)]
    assert symequal(basis, space.get_basis_functions())

    basis = [(1 - x[0] - x[2]) * (1 - x[1] - x[2]) / (1 - x[2]),
             x[0] * (1 - x[1] - x[2]) / (1 - x[2]),
             (1 - x[0] - x[2]) * x[1] / (1 - x[2]),
             x[0] * x[1] / (1 - x[2]),
             x[2]]
    assert symequal(basis, space.get_basis_functions())
def test_dual1():
    space = create_element("dual polygon(4)", "dual", 1)
    h = sympy.Rational(1, 2)
    q = sympy.Rational(1, 4)
    e = sympy.Rational(1, 8)
    assert symequal(
        space.tabulate_basis([[0, 0], [q, q], [h, 0]]),
        ((q, q, q, q),
         (sympy.Rational(5, 8), e, e, e),
         (sympy.Rational(3, 8), e, e, sympy.Rational(3, 8)))
    )
示例#7
0
def test_hct():
    e = symfem.create_element("triangle", "HCT", 3)
    for f in e.get_polynomial_basis():
        # edge from (1,0) to (1/3,1/3)
        f1 = f.get_piece((half, 0))
        f2 = f.get_piece((half, half))
        line = ((1 - 2 * t[0], t[0]))
        f1 = subs(f1, x[:2], line)
        f2 = subs(f2, x[:2], line)
        assert symequal(f1, f2)
        assert symequal(grad(f1, 2), grad(f2, 2))

        # edge from (0,1) to (1/3,1/3)
        f1 = f.get_piece((half, half))
        f2 = f.get_piece((0, half))
        line = ((t[0], 1 - 2 * t[0]))
        f1 = subs(f1, x[:2], line)
        f2 = subs(f2, x[:2], line)
        assert symequal(f1, f2)
        assert symequal(grad(f1, 2), grad(f2, 2))

        # edge from (0,0) to (1/3,1/3)
        f1 = f.get_piece((0, half))
        f2 = f.get_piece((half, 0))
        line = ((t[0], t[0]))
        f1 = subs(f1, x[:2], line)
        f2 = subs(f2, x[:2], line)
        assert symequal(f1, f2)
        assert symequal(grad(f1, 2), grad(f2, 2))
示例#8
0
def test_dual_elements(elements_to_test, cells_to_test, n_tri, order):
    if elements_to_test != "ALL" and "dual" not in elements_to_test:
        pytest.skip()
    if cells_to_test != "ALL" and "dual polygon" not in cells_to_test:
        pytest.skip()

    space = create_element(f"dual polygon({n_tri})", "dual", order)
    sub_e = create_element("triangle", space.fine_space, space.order)
    for f, coeff_list in zip(space.get_basis_functions(),
                             space.dual_coefficients):
        for piece, coeffs in zip(f.pieces, coeff_list):
            map = sub_e.reference.get_map_to(piece[0])
            for dof, value in zip(sub_e.dofs, coeffs):
                point = subs(map, x, dof.point)
                assert symequal(value, subs(piece[1], x, point))
示例#9
0
def test_rhct():
    e = symfem.create_element("triangle", "rHCT", 3)
    for f in e.get_polynomial_basis():
        # edge from (1,0) to (1/3,1/3)
        f1 = f.get_piece((half, 0))
        f2 = f.get_piece((half, half))
        line = ((1 - 2 * t[0], t[0]))
        f1 = subs(f1, x[:2], line)
        f2 = subs(f2, x[:2], line)
        assert symequal(f1, f2)
        assert symequal(grad(f1, 2), grad(f2, 2))

        # edge from (0,1) to (1/3,1/3)
        f1 = f.get_piece((half, half))
        f2 = f.get_piece((0, half))
        line = ((t[0], 1 - 2 * t[0]))
        f1 = subs(f1, x[:2], line)
        f2 = subs(f2, x[:2], line)
        assert symequal(f1, f2)
        assert symequal(grad(f1, 2), grad(f2, 2))

        # edge from (0,0) to (1/3,1/3)
        f1 = f.get_piece((0, half))
        f2 = f.get_piece((half, 0))
        line = ((t[0], t[0]))
        f1 = subs(f1, x[:2], line)
        f2 = subs(f2, x[:2], line)
        assert symequal(f1, f2)
        assert symequal(grad(f1, 2), grad(f2, 2))

        # Check that normal derivatives are linear
        f1 = diff(f.get_piece((half, 0)), x[1]).subs(x[1], 0)
        f2 = f.get_piece((half, half))
        f2 = (diff(f2, x[0]) + diff(f2, x[1])).subs(x[1], 1 - x[0])
        f3 = diff(f.get_piece((0, half)), x[0]).subs(x[0], 0)
        assert diff(f1, x[0], x[0]) == 0
        assert diff(f2, x[0], x[0]) == 0
        assert diff(f3, x[1], x[1]) == 0
def test_lagrange():
    space = create_element("triangle", "Lagrange", 1)
    assert symequal(
        space.tabulate_basis([[0, 0], [0, 1], [1, 0]]),
        ((1, 0, 0), (0, 0, 1), (0, 1, 0)),
    )
def test_Q():
    space = create_element("quadrilateral", "Q", 1)
    assert symequal(
        space.tabulate_basis([[0, 0], [1, 0], [0, 1], [1, 1]]),
        ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)),
    )
def test_rt():
    space = create_element("triangle", "Raviart-Thomas", 1)
    assert symequal(
        space.tabulate_basis([[0, 0], [1, 0], [0, 1]], "xxyyzz"),
        ((0, -1, 0, 0, 0, 1), (-1, 0, -1, 0, 0, 1), (0, -1, 0, -1, 1, 0)),
    )
def test_nedelec():
    space = create_element("triangle", "Nedelec", 1)
    assert symequal(
        space.tabulate_basis([[0, 0], [1, 0], [0, 1]], "xxyyzz"),
        ((0, 0, 1, 0, 1, 0), (0, 0, 1, 1, 0, 1), (-1, 1, 0, 0, 1, 0)),
    )
示例#14
0
# In this demo, we use the function vdot to compute the dot product of two vectors.
# The module symfem.vectors contains many functions that can be used to manipulate
# vectors.
from symfem.vectors import vdot

element = symfem.create_element("triangle", "Nedelec1", 4)
polys = element.get_polynomial_basis()

# Check that the first 20 polynomials in the polynomial basis are
# the polynomials of degree 3
p3 = polynomial_set(2, 2, 3)
assert len(p3) == 20
for i, j in zip(p3, polys[:20]):
    assert i == j

# Check that the rest of the polynomials in the polynomial basis
# satisfy p DOT x = 0
for p in polys[20:]:
    assert vdot(p, x) == 0

# Get the basis functions associated with the interior of the triangle
basis = element.get_basis_functions()
functions = [basis[d] for d in element.entity_dofs(2, 0)]

# Check that these functions have 0 tangential component on each edge
# symequal will simplify the expressions then check that they are equal
for f in functions:
    assert symequal(vdot(subs(f, x[0], 1 - x[1]), (1, -1)), 0)
    assert symequal(vdot(subs(f, x[0], 0), (0, 1)), 0)
    assert symequal(vdot(subs(f, x[1], 0), (1, 0)), 0)
示例#15
0
edge_element = symfem.create_element("interval", "Lagrange", 5)

# Define a parameter that will go from 0 to 1 on the chosen edge
a = sympy.Symbol("a")

# Get the basis functions of the Lagrange space and substitute the parameter into the
# functions on the edge
basis = element.get_basis_functions()
edge_basis = [subs(f, x[0], a) for f in edge_element.get_basis_functions()]

# Get the DOFs on edge 0 (from vertex 1 (1,0) to vertex 2 (0,1))
# (1 - a, a) is a parametrisation of this edge
dofs = element.entity_dofs(0, 1) + element.entity_dofs(
    0, 2) + element.entity_dofs(1, 0)
# Check that the basis functions on this edge are equal
for d, edge_f in zip(dofs, edge_basis):
    # symequal will simplify the expressions then check that they are equal
    assert symequal(subs(basis[d], x[:2], (1 - a, a)), edge_f)

# Get the DOFs on edge 1 (from vertex 0 (0,0) to vertex 2 (0,1), parametrised (0, a))
dofs = element.entity_dofs(0, 0) + element.entity_dofs(
    0, 2) + element.entity_dofs(1, 1)
for d, edge_f in zip(dofs, edge_basis):
    assert symequal(subs(basis[d], x[:2], (0, a)), edge_f)

# Get the DOFs on edge 2 (from vertex 0 (0,0) to vertex 1 (1,0), parametrised (a, 0))
dofs = element.entity_dofs(0, 0) + element.entity_dofs(
    0, 1) + element.entity_dofs(1, 2)
for d, edge_f in zip(dofs, edge_basis):
    assert symequal(subs(basis[d], x[:2], (a, 0)), edge_f)