def test_different_element_interpolation(family1, args1, family2, args2,
                                         cell_type, order):
    lower_element = basix.create_element(family1, cell_type, order, *args1)
    higher_element = basix.create_element(family2, cell_type, order, *args2)

    run_test(lower_element, higher_element, order - 1,
             lower_element.value_size)
def test_different_variant_interpolation(cell_type, order, variant1, variant2):
    lower_element = basix.create_element(basix.ElementFamily.P, cell_type,
                                         order, variant1)
    higher_element = basix.create_element(basix.ElementFamily.P, cell_type,
                                          order, variant2)

    run_test(lower_element, higher_element, order, lower_element.value_size)
def test_blocked_interpolation(cell_type, order):
    """Test interpolation of Nedelec's componenets into a Lagrange space."""
    nedelec = basix.create_element(basix.ElementFamily.N2E, cell_type, order)
    lagrange = basix.create_element(basix.ElementFamily.P, cell_type, order,
                                    basix.LagrangeVariant.gll_isaac)

    n_points = nedelec.points
    if nedelec.value_size == 2:
        n_eval = np.concatenate([n_points[:, 0]**order, n_points[:, 1]**order])
    else:
        n_eval = np.concatenate(
            [n_points[:, 0]**order, 0 * n_points[:, 0], n_points[:, 1]**order])
    n_coeffs = nedelec.interpolation_matrix @ n_eval

    l_points = lagrange.points
    if nedelec.value_size == 2:
        values = [l_points[:, 0]**order, l_points[:, 1]**order]
    else:
        values = [
            l_points[:, 0]**order, 0 * l_points[:, 0], l_points[:, 1]**order
        ]
    l_coeffs = np.empty(lagrange.dim * nedelec.value_size)
    for i, v in enumerate(values):
        l_coeffs[i::nedelec.value_size] = v

    # Test interpolation from Nedelec to blocked Lagrange
    i_m = basix.compute_interpolation_operator(nedelec, lagrange)
    assert np.allclose(l_coeffs, i_m @ n_coeffs)

    # Test interpolation from blocked Lagrange to Nedelec
    i_m = basix.compute_interpolation_operator(lagrange, nedelec)
    assert np.allclose(n_coeffs, i_m @ l_coeffs)
예제 #4
0
def create_basix_element(ufl_element):
    # TODO: EnrichedElement
    # TODO: Short/alternative names for elements

    if isinstance(ufl_element, ufl.VectorElement):
        return BlockedElement(
            create_basix_element(ufl_element.sub_elements()[0]),
            ufl_element.num_sub_elements())
    if isinstance(ufl_element, ufl.TensorElement):
        return BlockedElement(
            create_basix_element(ufl_element.sub_elements()[0]),
            ufl_element.num_sub_elements(), None)  # TODO: block shape

    if isinstance(ufl_element, ufl.MixedElement):
        return MixedElement(
            [create_basix_element(e) for e in ufl_element.sub_elements()])

    if ufl_element.family() in ufl_to_basix_names:
        return BasixElement(
            basix.create_element(ufl_to_basix_names[ufl_element.family()],
                                 ufl_element.cell().cellname(),
                                 ufl_element.degree()))

    return BasixElement(
        basix.create_element(ufl_element.family(),
                             ufl_element.cell().cellname(),
                             ufl_element.degree()))
def test_different_order_interpolation_lagrange(cell_type, orders):
    lower_element = basix.create_element(basix.ElementFamily.P, cell_type,
                                         orders[0],
                                         basix.LagrangeVariant.gll_warped)
    higher_element = basix.create_element(basix.ElementFamily.P, cell_type,
                                          orders[1],
                                          basix.LagrangeVariant.gll_warped)

    run_test(lower_element, higher_element, orders[0],
             lower_element.value_size)
예제 #6
0
def test_lagrange(celltype, degree):
    lagrange = basix.create_element(basix.ElementFamily.P, celltype[1], degree,
                                    basix.LagrangeVariant.equispaced)
    pts = basix.create_lattice(celltype[0], 6, basix.LatticeType.equispaced,
                               True)
    w = lagrange.tabulate(0, pts)[0]
    assert (numpy.isclose(numpy.sum(w, axis=1), 1.0).all())
예제 #7
0
def test_cr2d():
    cr2 = basix.create_element(basix.ElementFamily.CR, basix.CellType.triangle,
                               1)
    pts = basix.create_lattice(basix.CellType.triangle, 2,
                               basix.LatticeType.equispaced, True)
    w = cr2.tabulate(0, pts)[0]
    print(w.shape)
예제 #8
0
def test_cr3d():
    cr3 = basix.create_element(basix.ElementFamily.CR,
                               basix.CellType.tetrahedron, 1)
    pts = basix.create_lattice(basix.CellType.tetrahedron, 2,
                               basix.LatticeType.equispaced, True)
    w = cr3.tabulate(0, pts)[0]
    print(w.shape)
예제 #9
0
파일: test_regge.py 프로젝트: FEniCS/basix
def test_regge_tri2():
    # Second order
    regge = basix.create_element(basix.ElementFamily.Regge, basix.CellType.triangle, 2)
    # tabulate at origin
    pts = [[0.0, 0.0]]
    w = regge.tabulate(0, pts)[0].reshape(-1, 2, 2)

    ref = np.array([[[0., -0.5], [-0.5,  0.]],
                    [[0., -0.5], [-0.5, -0.]],
                    [[-0., -0.5], [-0.5,  0.]],
                    [[-0.,  1.5], [1.5,  3.]],
                    [[0., -1.5], [-1.5, -3.]],
                    [[-0.,  0.5], [0.5,  1.]],
                    [[3.,  1.5], [1.5, -0.]],
                    [[-3., -1.5], [-1.5,  0.]],
                    [[1.,  0.5], [0.5, -0.]],
                    [[-0., -0.], [-0., -0.]],
                    [[0., -0.], [-0., -0.]],
                    [[0., -3.], [-3.,  0.]],
                    [[0., -0.], [-0., -0.]],
                    [[-0., -0.], [-0.,  0.]],
                    [[-0.,  2.], [2., -0.]],
                    [[-0.,  0.], [0.,  0.]],
                    [[0.,  0.], [0., -0.]],
                    [[0.,  2.], [2., -0.]]])
    assert(np.isclose(ref, w).all())
예제 #10
0
파일: test_regge.py 프로젝트: FEniCS/basix
def test_regge_tet():
    # Simplest element
    regge = basix.create_element(basix.ElementFamily.Regge, basix.CellType.tetrahedron, 1)
    # tabulate at origin
    pts = [[0.0, 0.0, 0.0]]
    w = regge.tabulate(0, pts)[0].reshape(-1, 3, 3)

    ref = np.array([[[0.,  0.,  0.], [0.,  0.,  0.5], [0.,  0.5, -0.]],
                    [[-0.,  0., -0.], [0., -0.,  0.5], [-0.,  0.5,  0.]],
                    [[0., -0.,  0.5], [-0.,  0.,  0.], [0.5,  0.,  0.]],
                    [[-0.,  0.,  0.5], [0., -0.,  0.], [0.5,  0.,  0.]],
                    [[-0.,  0.5,  0.], [0.5, -0., -0.], [0., -0.,  0.]],
                    [[0.,  0.5,  0.], [0.5, -0.,  0.], [0.,  0.,  0.]],
                    [[0.,  0.,  1.], [0.,  0.,  1.], [1.,  1.,  2.]],
                    [[0., -0., -0.5], [-0.,  0., -0.5], [-0.5, -0.5, -1.]],
                    [[0.,  1., -0.], [1.,  2.,  1.], [-0.,  1., -0.]],
                    [[-0., -0.5, -0.], [-0.5, -1., -0.5], [-0., -0.5, -0.]],
                    [[2.,  1.,  1.], [1., -0.,  0.], [1.,  0.,  0.]],
                    [[-1., -0.5, -0.5], [-0.5, -0.,  0.], [-0.5,  0., -0.]],
                    [[-0.,  0., -0.], [0., -0., -0.], [-0., -0., -0.]],
                    [[-0., -0., -0.], [-0., -0., -0.], [-0., -0., -0.]],
                    [[-0.,  0., -0.], [0.,  0., -0.], [-0., -0., -0.]],
                    [[0., -0.,  0.], [-0., -0., -0.], [0., -0.,  0.]],
                    [[-0., -0., -0.], [-0., -0.,  0.], [-0.,  0.,  0.]],
                    [[-0., -0., -0.], [-0., -0., -1.5], [-0., -1.5, -0.]],
                    [[0., -0.,  0.], [-0.,  0., -0.], [0., -0.,  0.]],
                    [[0., -0., -0.], [-0., -0., -0.], [-0., -0.,  0.]],
                    [[-0.,  0., -1.5], [0., -0., -0.], [-1.5, -0., -0.]],
                    [[-0., -0., -0.], [-0.,  0., -0.], [-0., -0., -0.]],
                    [[0., -0., -0.], [-0., -0., -0.], [-0., -0.,  0.]],
                    [[-0., -1.5, -0.], [-1.5,  0., -0.], [-0., -0., -0.]]])

    assert(np.isclose(ref, w).all())
예제 #11
0
def test_transformation_of_tabulated_data_quadrilateral(element_type, degree, element_args):
    e = basix.create_element(element_type, basix.CellType.quadrilateral, degree, *element_args)
    bt = e.base_transformations()

    N = 4
    points = np.array([[i / N, j / N] for i in range(N + 1) for j in range(N + 1)])
    values = e.tabulate(0, points)[0]

    start = sum(e.num_entity_dofs[0])
    ndofs = e.num_entity_dofs[1][0]
    if ndofs != 0:
        # Check that the 0th transformation undoes the effect of reflecting edge 0
        reflected_points = np.array([[1 - p[0], p[1]] for p in points])
        reflected_values = e.tabulate(0, reflected_points)[0]

        _J = np.array([[-1, 0], [0, 1]])
        J = np.array([_J for p in points])
        detJ = np.array([np.linalg.det(_J) for p in points])
        K = np.array([np.linalg.inv(_J) for p in points])
        mapped_values = e.push_forward(reflected_values, J, detJ, K)
        for i, j in zip(values, mapped_values):
            for d in range(e.value_size):
                i_slice = i[:, d]
                j_slice = j[:, d]
                assert np.allclose((bt[0].dot(i_slice))[start: start + ndofs],
                                   j_slice[start: start + ndofs])
예제 #12
0
def test_interpolation(cell_type, n, element_type):
    element = basix.create_element(element_type, cell_type, n,
                                   basix.LagrangeVariant.gll_warped)
    assert element.interpolation_matrix.shape[0] == element.dim
    assert element.interpolation_matrix.shape[1] == element.points.shape[0]
    assert element.points.shape[1] == len(basix.topology(
        element.cell_type)) - 1
예제 #13
0
파일: test_rt.py 프로젝트: FEniCS/basix
def test_tet(order):
    celltype = basix.CellType.tetrahedron
    g = sympy_rt(celltype, order)
    x = sympy.Symbol("x")
    y = sympy.Symbol("y")
    z = sympy.Symbol("z")
    rt = basix.create_element(basix.ElementFamily.RT,
                              basix.CellType.tetrahedron, order)

    pts = basix.create_lattice(celltype, 5, basix.LatticeType.equispaced, True)
    nderiv = 1
    wtab = rt.tabulate(nderiv, pts)

    for kx in range(nderiv + 1):
        for ky in range(nderiv + 1 - kx):
            for kz in range(nderiv + 1 - kx - ky):
                wsym = numpy.zeros_like(wtab[0])
                for i, gi in enumerate(g):
                    for j, gij in enumerate(gi):
                        wd = sympy.diff(gij, x, kx, y, ky, z, kz)
                        for k, p in enumerate(pts):
                            wsym[k, i, j] = wd.subs([(x, p[0]), (y, p[1]),
                                                     (z, p[2])])

                assert (numpy.isclose(wtab[basix.index(kx, ky, kz)],
                                      wsym).all())
예제 #14
0
def test_dof_transformations_triangle(degree):
    lagrange = basix.create_element(basix.ElementFamily.P,
                                    basix.CellType.triangle, degree,
                                    basix.LagrangeVariant.equispaced)

    permuted = {}
    if degree == 3:
        # Reflect 2 DOFs on edges
        permuted[0] = {3: 4, 4: 3}
        permuted[1] = {5: 6, 6: 5}
        permuted[2] = {7: 8, 8: 7}
    elif degree == 4:
        # Reflect 3 DOFs on edges
        permuted[0] = {3: 5, 5: 3}
        permuted[1] = {6: 8, 8: 6}
        permuted[2] = {9: 11, 11: 9}

    base_transformations = lagrange.base_transformations()
    assert len(base_transformations) == 3

    for i, t in enumerate(base_transformations):
        actual = numpy.zeros_like(t)
        for j, row in enumerate(t):
            if i in permuted and j in permuted[i]:
                actual[j, permuted[i][j]] = 1
            else:
                actual[j, j] = 1
        assert numpy.allclose(t, actual)
예제 #15
0
def test_if_identity(cell_type, element_type, degree, element_args):
    e = basix.create_element(element_type, cell_type, degree, *element_args)

    for t in e.base_transformations():
        if not np.allclose(t, np.eye(t.shape[0])):
            assert not e.dof_transformations_are_identity
            return
    assert e.dof_transformations_are_identity
예제 #16
0
def test_mappings_2d_to_2d(element_type, element_args):
    e = basix.create_element(element_type, basix.CellType.triangle, 1,
                             *element_args)
    J = np.array([[random.random() + 1, random.random()],
                  [random.random(), random.random()]])
    detJ = np.linalg.det(J)
    K = np.linalg.inv(J)
    run_map_test(e, J, detJ, K, e.value_size, e.value_size)
예제 #17
0
 def __init__(self, family_type, cell_type, degree, variant_info,
              discontinuous):
     self.element = basix.create_element(family_type, cell_type, degree,
                                         *variant_info, discontinuous)
     self._family = family_type
     self._cell = cell_type
     self._variant_info = variant_info
     self._discontinuous = discontinuous
예제 #18
0
def test_quadrilateral_transformation_degrees(element_type, degree, element_args):
    e = basix.create_element(element_type, basix.CellType.quadrilateral, degree, *element_args)
    bt = e.base_transformations()
    assert len(bt) == 4
    identity = np.identity(e.dim)
    for i, degree in enumerate([2, 2, 2, 2]):
        assert np.allclose(
            np.linalg.matrix_power(bt[i], degree),
            identity)
예제 #19
0
def test_if_permutations(cell_type, element_type, degree, element_args):
    e = basix.create_element(element_type, cell_type, degree, *element_args)

    for t in e.base_transformations():
        for row in t:
            a = np.argmax(row)
            if not np.isclose(row[a], 1) or not np.allclose(row[:a], 0) or not np.allclose(row[a + 1:], 0):
                assert not e.dof_transformations_are_permutations
                return
    assert e.dof_transformations_are_permutations
예제 #20
0
파일: test_numba.py 프로젝트: FEniCS/basix
def test_dof_transformations_to_transpose(cell, element, degree, block_size,
                                          element_args):
    try:
        import numba  # noqa: F401
    except ImportError:
        pytest.skip("Numba must be installed to run this test.")

    from basix import numba_helpers
    from numba.core import types
    from numba.typed import Dict

    transform_functions = {
        basix.CellType.triangle:
        numba_helpers.apply_dof_transformation_to_transpose_triangle,
        basix.CellType.quadrilateral:
        numba_helpers.apply_dof_transformation_to_transpose_quadrilateral,
        basix.CellType.tetrahedron:
        numba_helpers.apply_dof_transformation_to_transpose_tetrahedron,
        basix.CellType.hexahedron:
        numba_helpers.apply_dof_transformation_to_transpose_hexahedron,
        basix.CellType.prism:
        numba_helpers.apply_dof_transformation_to_transpose_prism,
        basix.CellType.pyramid:
        numba_helpers.apply_dof_transformation_to_transpose_pyramid
    }

    random.seed(1337)

    e = basix.create_element(element, cell, degree, *element_args)
    data = np.array(list(range(e.dim * block_size)), dtype=np.double)

    for i in range(10):
        cell_info = random.randrange(2**30)

        data1 = data.copy()
        data1 = e.apply_dof_transformation_to_transpose(
            data1, block_size, cell_info)
        # Numba function does not use blocked data
        data2 = data.copy().reshape(block_size, e.dim)
        # Mapping lists to numba dictionaries
        entity_transformations = Dict.empty(key_type=types.string,
                                            value_type=types.float64[:, :, :])
        for i, transformation in e.entity_transformations().items():
            entity_transformations[i] = transformation

        entity_dofs = Dict.empty(key_type=types.int64,
                                 value_type=types.int32[:])
        for i, e_dofs in enumerate(e.num_entity_dofs):
            entity_dofs[i] = np.asarray(e_dofs, dtype=np.int32)
        transform_functions[cell](entity_transformations, entity_dofs, data2,
                                  cell_info)
        # Reshape numba output for comparison
        data2 = data2.reshape(-1)
        assert np.allclose(data1, data2)
예제 #21
0
def test_number_of_dofs(cell_type, degree, element_type, element_args):
    element = basix.create_element(element_type, cell_type, degree,
                                   *element_args)

    entity_dofs = element.entity_dofs
    num_entity_dofs = element.num_entity_dofs

    for entity_dofs, num_entity_dofs in zip(element.entity_dofs,
                                            element.num_entity_dofs):
        for dofs, ndofs in zip(entity_dofs, num_entity_dofs):
            assert len(dofs) == ndofs

    assert element.dim == sum(sum(i) for i in element.num_entity_dofs)
예제 #22
0
def test_tensor_product_factorisation_quadrilateral(degree):
    P = degree
    cell_type = basix.CellType.quadrilateral
    element = basix.create_element(basix.ElementFamily.P, cell_type, P,
                                   basix.LagrangeVariant.gll_warped)
    factors = element.get_tensor_product_representation()[0]

    # Quadrature degree
    Q = 2 * P + 2
    points, w = basix.make_quadrature(basix.QuadratureType.Default, cell_type,
                                      Q)
    data = element.tabulate(1, points)
    dphi_x = data[1, :, :, 0]
    dphi_y = data[2, :, :, 0]

    assert points.shape[0] == (P + 2) * (P + 2)

    # FIXME: This test assumes all factors formed by a single element
    perm = factors[1]
    element0 = factors[0][0]
    cell1d = element0.cell_type
    points, w = basix.make_quadrature(basix.QuadratureType.Default, cell1d, Q)
    data = element0.tabulate(1, points)
    phi0 = data[0, :, :, 0]
    dphi0 = data[1, :, :, 0]

    # number of dofs in each direction
    Nd = P + 1
    # number of quadrature points in each direction
    Nq = P + 2

    # Compute derivative of basis function in the x direction
    dphi_tensor = numpy.zeros([Nq, Nq, Nd, Nd])
    for q0 in range(Nq):
        for q1 in range(Nq):
            for i0 in range(Nd):
                for i1 in range(Nd):
                    dphi_tensor[q0, q1, i0, i1] = dphi0[q0, i0] * phi0[q1, i1]
    dphi_tensor = dphi_tensor.reshape([Nq * Nq, Nd * Nd])
    assert numpy.allclose(dphi_x[:, perm], dphi_tensor)

    # Compute derivative of basis function in the y direction
    dphi_tensor = numpy.zeros([Nq, Nq, Nd, Nd])
    for q0 in range(Nq):
        for q1 in range(Nq):
            for i0 in range(Nd):
                for i1 in range(Nd):
                    dphi_tensor[q0, q1, i0, i1] = phi0[q0, i0] * dphi0[q1, i1]

    dphi_tensor = dphi_tensor.reshape([Nq * Nq, Nd * Nd])
    assert numpy.allclose(dphi_y[:, perm], dphi_tensor)
예제 #23
0
def test_mappings_2d_to_3d(element_type, element_args):
    e = basix.create_element(element_type, basix.CellType.triangle, 1,
                             *element_args)

    # Map from (0,0)--(1,0)--(0,1) to (1,0,1)--(2,1,0)--(0,1,1)
    J = np.array([[1., -1.], [1., 1.], [-1., 0.]])
    detJ = np.sqrt(6)
    K = np.array([[0.5, 0.5, 0.], [-0.5, 0.5, 0.]])

    if e.value_size == 1:
        physical_vs = 1
    elif e.value_size == 2:
        physical_vs = 3
    elif e.value_size == 4:
        physical_vs = 9
    run_map_test(e, J, detJ, K, e.value_size, physical_vs)
예제 #24
0
def test_closure_dofs(cell_type, degree, element_type, element_args):
    element = basix.create_element(element_type, cell_type, degree,
                                   *element_args)

    entity_dofs = element.entity_dofs
    entity_closure_dofs = element.entity_closure_dofs

    topology = basix.topology(cell_type)
    connectivity = basix.cell.sub_entity_connectivity(cell_type)

    for dim, t in enumerate(topology):
        for e, _ in enumerate(t):
            for dim2 in range(dim + 1):
                for e2 in connectivity[dim][e][dim2]:
                    for dof in entity_dofs[dim2][e2]:
                        assert dof in entity_closure_dofs[dim][e]
예제 #25
0
def test_line_without_variant(n):
    celltype = basix.CellType.interval
    g = sympy_lagrange(celltype, n)
    x = sympy.Symbol("x")
    lagrange = basix.create_element(basix.ElementFamily.P,
                                    basix.CellType.interval, n)
    pts = basix.create_lattice(celltype, 6, basix.LatticeType.equispaced, True)
    nderiv = n
    wtab = lagrange.tabulate(nderiv, pts)
    for k in range(nderiv + 1):
        wsym = numpy.zeros_like(wtab[k])
        for i in range(n + 1):
            wd = sympy.diff(g[i], x, k)
            for j, p in enumerate(pts):
                wsym[j, i] = wd.subs(x, p[0])

        assert numpy.allclose(wtab[k], wsym)
예제 #26
0
def test_ordering_of_dofs(cell_type, degree, element_type, element_args):
    """
    Check that DOFs are numbered in ascending order by entity.

    This assumption is required for DOF transformations to work correctly.
    """
    element = basix.create_element(element_type, cell_type, degree,
                                   *element_args)

    entity_dofs = element.entity_dofs
    dof = 0
    print(element.entity_dofs)
    for entity_dofs in element.entity_dofs:
        for dofs in entity_dofs:
            for d in sorted(dofs):
                assert d == dof
                dof += 1
예제 #27
0
파일: test_regge.py 프로젝트: FEniCS/basix
def test_regge_tri():
    # Simplest element
    regge = basix.create_element(basix.ElementFamily.Regge, basix.CellType.triangle, 1)

    # tabulate at origin
    pts = [[0.0, 0.0]]
    w = regge.tabulate(0, pts)[0].reshape(-1, 2, 2)

    ref = np.array([[[-0.,  0.5], [0.5, -0.]],
                    [[0.,  0.5], [0.5, -0.]],
                    [[-0.,  1.], [1.,  2.]],
                    [[-0., -0.5], [-0.5, -1.]],
                    [[2.,  1.], [1., -0.]],
                    [[-1., -0.5], [-0.5,  0.]],
                    [[-0.,  0.], [0.,  0.]],
                    [[0., -0.], [-0., -0.]],
                    [[-0., -1.5], [-1.5,  0.]]])

    assert np.allclose(ref, w)
예제 #28
0
def test_dof_transformations_tetrahedron(degree):
    lagrange = basix.create_element(basix.ElementFamily.P,
                                    basix.CellType.tetrahedron, degree,
                                    basix.LagrangeVariant.equispaced)

    permuted = {}
    if degree == 3:
        # Reflect 2 DOFs on edges
        permuted[0] = {4: 5, 5: 4}
        permuted[1] = {6: 7, 7: 6}
        permuted[2] = {8: 9, 9: 8}
        permuted[3] = {10: 11, 11: 10}
        permuted[4] = {12: 13, 13: 12}
        permuted[5] = {14: 15, 15: 14}
    elif degree == 4:
        # Reflect 3 DOFs on edges
        permuted[0] = {4: 6, 6: 4}
        permuted[1] = {7: 9, 9: 7}
        permuted[2] = {10: 12, 12: 10}
        permuted[3] = {13: 15, 15: 13}
        permuted[4] = {16: 18, 18: 16}
        permuted[5] = {19: 21, 21: 19}
        # Rotate and reflect 3 DOFs on faces
        permuted[6] = {22: 24, 23: 22, 24: 23}
        permuted[7] = {23: 24, 24: 23}
        permuted[8] = {25: 27, 26: 25, 27: 26}
        permuted[9] = {26: 27, 27: 26}
        permuted[10] = {28: 30, 29: 28, 30: 29}
        permuted[11] = {29: 30, 30: 29}
        permuted[12] = {31: 33, 32: 31, 33: 32}
        permuted[13] = {32: 33, 33: 32}

    base_transformations = lagrange.base_transformations()
    assert len(base_transformations) == 14

    for i, t in enumerate(base_transformations):
        actual = numpy.zeros_like(t)
        for j, row in enumerate(t):
            if i in permuted and j in permuted[i]:
                actual[j, permuted[i][j]] = 1
            else:
                actual[j, j] = 1
        assert numpy.allclose(t, actual)
예제 #29
0
def test_tensor_product_factorisation(cell_type, degree, element_type,
                                      element_args):
    element = basix.create_element(element_type, cell_type, degree,
                                   *element_args)
    tdim = len(basix.topology(cell_type)) - 1

    # These elements should have a factorisation
    if cell_type in [basix.CellType.quadrilateral,
                     basix.CellType.hexahedron] and element_type in [
                         basix.ElementFamily.P
                     ] and basix.LagrangeVariant.equispaced in element_args:
        assert element.has_tensor_product_factorisation

    if not element.has_tensor_product_factorisation:
        with pytest.raises(RuntimeError):
            element.get_tensor_product_representation()
        pytest.skip()

    factors = element.get_tensor_product_representation()

    lattice = basix.create_lattice(cell_type, 1, basix.LatticeType.equispaced,
                                   True)
    tab1 = element.tabulate(1, lattice)

    for i, point in enumerate(lattice):
        for ds in product(range(2), repeat=tdim):
            if sum(ds) > 1:
                continue
            deriv = basix.index(*ds)
            values1 = tab1[deriv, i, :, :]

            values2 = np.empty((element.dim, 1))
            for fs, perm in factors:
                evals = [
                    e.tabulate(d, [p])[d, 0, :, 0]
                    for e, p, d in zip(fs, point, ds)
                ]
                tab2 = tensor_product(*evals)
                for a, b in enumerate(perm):
                    if b != -1:
                        values2[b, 0] = tab2[a]
            assert np.allclose(values1, values2)
예제 #30
0
def test_tri(order):
    celltype = basix.CellType.triangle
    g = sympy_nedelec(celltype, order)
    x = sympy.Symbol("x")
    y = sympy.Symbol("y")
    nedelec = basix.create_element(basix.ElementFamily.N1E, basix.CellType.triangle, order)
    pts = basix.create_lattice(celltype, 6, basix.LatticeType.equispaced, True)
    nderiv = 3
    wtab = nedelec.tabulate(nderiv, pts)

    for kx in range(nderiv + 1):
        for ky in range(nderiv + 1 - kx):
            wsym = numpy.zeros_like(wtab[0])
            for i, gi in enumerate(g):
                for j, gij in enumerate(gi):
                    wd = sympy.diff(gij, x, kx, y, ky)
                    for k, p in enumerate(pts):
                        wsym[k, i, j] = wd.subs([(x, p[0]), (y, p[1])])

            assert(numpy.isclose(wtab[basix.index(kx, ky)], wsym).all())