Ejemplo n.º 1
0
def test_TFE_2Dx1D_scalar_quad():
    T = UFCInterval()
    P1 = Lagrange(T, 1)
    P1_DG = DiscontinuousLagrange(T, 1)

    elt = TensorProductElement(TensorProductElement(P1, P1_DG), P1)
    assert elt.value_shape() == ()
    tab = elt.tabulate(1, [(0.1, 0.2, 0.3)])
    tA = P1.tabulate(1, [(0.1, )])
    tB = P1_DG.tabulate(1, [(0.2, )])
    tC = P1.tabulate(1, [(0.3, )])
    for da, db, dc in [[(0, ), (0, ), (0, )], [(1, ), (0, ), (0, )],
                       [(0, ), (1, ), (0, )], [(0, ), (0, ), (1, )]]:
        dd = da + db + dc
        assert np.isclose(tab[dd][0][0],
                          tA[da][0][0] * tB[db][0][0] * tC[dc][0][0])
        assert np.isclose(tab[dd][1][0],
                          tA[da][0][0] * tB[db][0][0] * tC[dc][1][0])
        assert np.isclose(tab[dd][2][0],
                          tA[da][0][0] * tB[db][1][0] * tC[dc][0][0])
        assert np.isclose(tab[dd][3][0],
                          tA[da][0][0] * tB[db][1][0] * tC[dc][1][0])
        assert np.isclose(tab[dd][4][0],
                          tA[da][1][0] * tB[db][0][0] * tC[dc][0][0])
        assert np.isclose(tab[dd][5][0],
                          tA[da][1][0] * tB[db][0][0] * tC[dc][1][0])
        assert np.isclose(tab[dd][6][0],
                          tA[da][1][0] * tB[db][1][0] * tC[dc][0][0])
        assert np.isclose(tab[dd][7][0],
                          tA[da][1][0] * tB[db][1][0] * tC[dc][1][0])
Ejemplo n.º 2
0
def construct_dg_element(ref_el, degree):
    """Constructs a discontinuous galerkin element of a given degree
    on a particular reference cell.
    """
    if ref_el.get_shape() in [LINE, TRIANGLE]:
        dg_element = DiscontinuousLagrange(ref_el, degree)

    # Quadrilateral facets could be on a FiredrakeQuadrilateral.
    # In this case, we treat this as an interval x interval cell:
    elif ref_el.get_shape() == QUADRILATERAL:
        dg_a = DiscontinuousLagrange(ufc_simplex(1), degree)
        dg_b = DiscontinuousLagrange(ufc_simplex(1), degree)
        dg_element = TensorProductElement(dg_a, dg_b)

    # This handles the more general case for facets:
    elif ref_el.get_shape() == TENSORPRODUCT:
        assert len(degree) == len(ref_el.cells), (
            "Must provide the same number of degrees as the number "
            "of cells that make up the tensor product cell."
        )
        sub_elements = [construct_dg_element(c, d)
                        for c, d in zip(ref_el.cells, degree)
                        if c.get_shape() != POINT]

        if len(sub_elements) > 1:
            dg_element = TensorProductElement(*sub_elements)
        else:
            dg_element, = sub_elements

    else:
        raise NotImplementedError(
            "Reference cells of type %s not currently supported" % type(ref_el)
        )

    return dg_element
Ejemplo n.º 3
0
def test_TFE_2Dx1D_vector_quad_hdiv():
    T = UFCInterval()
    P1 = Lagrange(T, 1)
    P0 = DiscontinuousLagrange(T, 0)
    P1_DG = DiscontinuousLagrange(T, 1)

    P1P0 = Hdiv(TensorProductElement(P1, P0))
    P0P1 = Hdiv(TensorProductElement(P0, P1))
    horiz_elt = EnrichedElement(P1P0, P0P1)
    elt = Hdiv(TensorProductElement(horiz_elt, P1_DG))
    assert elt.value_shape() == (3, )
    tab = elt.tabulate(1, [(0.1, 0.2, 0.3)])
    tA = P1.tabulate(1, [(0.1, )])
    tB = P0.tabulate(1, [(0.2, )])
    tC = P0.tabulate(1, [(0.1, )])
    tD = P1.tabulate(1, [(0.2, )])
    tE = P1_DG.tabulate(1, [(0.3, )])
    for da, db, dc in [[(0, ), (0, ), (0, )], [(1, ), (0, ), (0, )],
                       [(0, ), (1, ), (0, )], [(0, ), (0, ), (1, )]]:
        dd = da + db + dc
        assert np.isclose(tab[dd][0][0][0],
                          -tA[da][0][0] * tB[db][0][0] * tE[dc][0][0])
        assert np.isclose(tab[dd][1][0][0],
                          -tA[da][0][0] * tB[db][0][0] * tE[dc][1][0])
        assert np.isclose(tab[dd][2][0][0],
                          -tA[da][1][0] * tB[db][0][0] * tE[dc][0][0])
        assert np.isclose(tab[dd][3][0][0],
                          -tA[da][1][0] * tB[db][0][0] * tE[dc][1][0])
        assert tab[dd][4][0][0] == 0.0
        assert tab[dd][5][0][0] == 0.0
        assert tab[dd][6][0][0] == 0.0
        assert tab[dd][7][0][0] == 0.0
        assert tab[dd][0][1][0] == 0.0
        assert tab[dd][1][1][0] == 0.0
        assert tab[dd][2][1][0] == 0.0
        assert tab[dd][3][1][0] == 0.0
        assert np.isclose(tab[dd][4][1][0],
                          tC[da][0][0] * tD[db][0][0] * tE[dc][0][0])
        assert np.isclose(tab[dd][5][1][0],
                          tC[da][0][0] * tD[db][0][0] * tE[dc][1][0])
        assert np.isclose(tab[dd][6][1][0],
                          tC[da][0][0] * tD[db][1][0] * tE[dc][0][0])
        assert np.isclose(tab[dd][7][1][0],
                          tC[da][0][0] * tD[db][1][0] * tE[dc][1][0])
        assert tab[dd][0][2][0] == 0.0
        assert tab[dd][1][2][0] == 0.0
        assert tab[dd][2][2][0] == 0.0
        assert tab[dd][3][2][0] == 0.0
        assert tab[dd][4][2][0] == 0.0
        assert tab[dd][5][2][0] == 0.0
        assert tab[dd][6][2][0] == 0.0
        assert tab[dd][7][2][0] == 0.0
Ejemplo n.º 4
0
def test_flattened_against_tpe_quad():
    T = UFCInterval()
    P1 = Lagrange(T, 1)
    tpe_quad = TensorProductElement(P1, P1)
    flattened_quad = FlattenedDimensions(tpe_quad)
    assert tpe_quad.value_shape() == ()
    tpe_tab = tpe_quad.tabulate(1, [(0.1, 0.2)])
    flattened_tab = flattened_quad.tabulate(1, [(0.1, 0.2)])

    for da, db in [[(0,), (0,)], [(1,), (0,)], [(0,), (1,)]]:
        dc = da + db
        assert np.isclose(tpe_tab[dc][0][0], flattened_tab[dc][0][0])
        assert np.isclose(tpe_tab[dc][1][0], flattened_tab[dc][1][0])
        assert np.isclose(tpe_tab[dc][2][0], flattened_tab[dc][2][0])
        assert np.isclose(tpe_tab[dc][3][0], flattened_tab[dc][3][0])
Ejemplo n.º 5
0
def test_flattened_against_tpe_quad():
    T = UFCInterval()
    P1 = Lagrange(T, 1)
    tpe_quad = TensorProductElement(P1, P1)
    flattened_quad = FlattenedDimensions(tpe_quad)
    assert tpe_quad.value_shape() == ()
    tpe_tab = tpe_quad.tabulate(1, [(0.1, 0.2)])
    flattened_tab = flattened_quad.tabulate(1, [(0.1, 0.2)])

    for da, db in [[(0, ), (0, )], [(1, ), (0, )], [(0, ), (1, )]]:
        dc = da + db
        assert np.isclose(tpe_tab[dc][0][0], flattened_tab[dc][0][0])
        assert np.isclose(tpe_tab[dc][1][0], flattened_tab[dc][1][0])
        assert np.isclose(tpe_tab[dc][2][0], flattened_tab[dc][2][0])
        assert np.isclose(tpe_tab[dc][3][0], flattened_tab[dc][3][0])
Ejemplo n.º 6
0
def test_TFE_2Dx1D_vector_triangle_hcurl():
    S = UFCTriangle()
    T = UFCInterval()
    Ned1 = Nedelec(S, 1)
    P1 = Lagrange(T, 1)

    elt = Hcurl(TensorProductElement(Ned1, P1))
    assert elt.value_shape() == (3, )
    tab = elt.tabulate(1, [(0.1, 0.2, 0.3)])
    tabA = Ned1.tabulate(1, [(0.1, 0.2)])
    tabB = P1.tabulate(1, [(0.3, )])
    for da, db in [[(0, 0), (0, )], [(1, 0), (0, )], [(0, 1), (0, )],
                   [(0, 0), (1, )]]:
        dc = da + db
        assert np.isclose(tab[dc][0][0][0], tabA[da][0][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][1][0][0], tabA[da][0][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][2][0][0], tabA[da][1][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][3][0][0], tabA[da][1][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][4][0][0], tabA[da][2][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][5][0][0], tabA[da][2][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][0][1][0], tabA[da][0][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][1][1][0], tabA[da][0][1][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][2][1][0], tabA[da][1][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][3][1][0], tabA[da][1][1][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][4][1][0], tabA[da][2][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][5][1][0], tabA[da][2][1][0] * tabB[db][1][0])
        assert tab[dc][0][2][0] == 0.0
        assert tab[dc][1][2][0] == 0.0
        assert tab[dc][2][2][0] == 0.0
        assert tab[dc][3][2][0] == 0.0
        assert tab[dc][4][2][0] == 0.0
        assert tab[dc][5][2][0] == 0.0
Ejemplo n.º 7
0
def test_TFE_2Dx1D_vector_triangle_hdiv():
    S = UFCTriangle()
    T = UFCInterval()
    RT1 = RaviartThomas(S, 1)
    P1_DG = DiscontinuousLagrange(T, 1)

    elt = Hdiv(TensorProductElement(RT1, P1_DG))
    assert elt.value_shape() == (3, )
    tab = elt.tabulate(1, [(0.1, 0.2, 0.3)])
    tabA = RT1.tabulate(1, [(0.1, 0.2)])
    tabB = P1_DG.tabulate(1, [(0.3, )])
    for da, db in [[(0, 0), (0, )], [(1, 0), (0, )], [(0, 1), (0, )],
                   [(0, 0), (1, )]]:
        dc = da + db
        assert np.isclose(tab[dc][0][0][0], tabA[da][0][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][1][0][0], tabA[da][0][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][2][0][0], tabA[da][1][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][3][0][0], tabA[da][1][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][4][0][0], tabA[da][2][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][5][0][0], tabA[da][2][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][0][1][0], tabA[da][0][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][1][1][0], tabA[da][0][1][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][2][1][0], tabA[da][1][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][3][1][0], tabA[da][1][1][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][4][1][0], tabA[da][2][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][5][1][0], tabA[da][2][1][0] * tabB[db][1][0])
        assert tab[dc][0][2][0] == 0.0
        assert tab[dc][1][2][0] == 0.0
        assert tab[dc][2][2][0] == 0.0
        assert tab[dc][3][2][0] == 0.0
        assert tab[dc][4][2][0] == 0.0
        assert tab[dc][5][2][0] == 0.0
Ejemplo n.º 8
0
def test_TFE_1Dx1D_scalar():
    T = UFCInterval()
    P1_DG = DiscontinuousLagrange(T, 1)
    P2 = Lagrange(T, 2)

    elt = TensorProductElement(P1_DG, P2)
    assert elt.value_shape() == ()
    tab = elt.tabulate(1, [(0.1, 0.2)])
    tabA = P1_DG.tabulate(1, [(0.1,)])
    tabB = P2.tabulate(1, [(0.2,)])
    for da, db in [[(0,), (0,)], [(1,), (0,)], [(0,), (1,)]]:
        dc = da + db
        assert np.isclose(tab[dc][0][0], tabA[da][0][0]*tabB[db][0][0])
        assert np.isclose(tab[dc][1][0], tabA[da][0][0]*tabB[db][1][0])
        assert np.isclose(tab[dc][2][0], tabA[da][0][0]*tabB[db][2][0])
        assert np.isclose(tab[dc][3][0], tabA[da][1][0]*tabB[db][0][0])
        assert np.isclose(tab[dc][4][0], tabA[da][1][0]*tabB[db][1][0])
        assert np.isclose(tab[dc][5][0], tabA[da][1][0]*tabB[db][2][0])
Ejemplo n.º 9
0
def test_TFE_1Dx1D_vector():
    T = UFCInterval()
    P1_DG = DiscontinuousLagrange(T, 1)
    P2 = Lagrange(T, 2)

    elt = TensorProductElement(P1_DG, P2)
    hdiv_elt = Hdiv(elt)
    hcurl_elt = Hcurl(elt)
    assert hdiv_elt.value_shape() == (2, )
    assert hcurl_elt.value_shape() == (2, )

    tabA = P1_DG.tabulate(1, [(0.1, )])
    tabB = P2.tabulate(1, [(0.2, )])

    hdiv_tab = hdiv_elt.tabulate(1, [(0.1, 0.2)])
    for da, db in [[(0, ), (0, )], [(1, ), (0, )], [(0, ), (1, )]]:
        dc = da + db
        assert hdiv_tab[dc][0][0][0] == 0.0
        assert hdiv_tab[dc][1][0][0] == 0.0
        assert hdiv_tab[dc][2][0][0] == 0.0
        assert hdiv_tab[dc][3][0][0] == 0.0
        assert hdiv_tab[dc][4][0][0] == 0.0
        assert hdiv_tab[dc][5][0][0] == 0.0
        assert np.isclose(hdiv_tab[dc][0][1][0],
                          tabA[da][0][0] * tabB[db][0][0])
        assert np.isclose(hdiv_tab[dc][1][1][0],
                          tabA[da][0][0] * tabB[db][1][0])
        assert np.isclose(hdiv_tab[dc][2][1][0],
                          tabA[da][0][0] * tabB[db][2][0])
        assert np.isclose(hdiv_tab[dc][3][1][0],
                          tabA[da][1][0] * tabB[db][0][0])
        assert np.isclose(hdiv_tab[dc][4][1][0],
                          tabA[da][1][0] * tabB[db][1][0])
        assert np.isclose(hdiv_tab[dc][5][1][0],
                          tabA[da][1][0] * tabB[db][2][0])

    hcurl_tab = hcurl_elt.tabulate(1, [(0.1, 0.2)])
    for da, db in [[(0, ), (0, )], [(1, ), (0, )], [(0, ), (1, )]]:
        dc = da + db
        assert np.isclose(hcurl_tab[dc][0][0][0],
                          tabA[da][0][0] * tabB[db][0][0])
        assert np.isclose(hcurl_tab[dc][1][0][0],
                          tabA[da][0][0] * tabB[db][1][0])
        assert np.isclose(hcurl_tab[dc][2][0][0],
                          tabA[da][0][0] * tabB[db][2][0])
        assert np.isclose(hcurl_tab[dc][3][0][0],
                          tabA[da][1][0] * tabB[db][0][0])
        assert np.isclose(hcurl_tab[dc][4][0][0],
                          tabA[da][1][0] * tabB[db][1][0])
        assert np.isclose(hcurl_tab[dc][5][0][0],
                          tabA[da][1][0] * tabB[db][2][0])
        assert hcurl_tab[dc][0][1][0] == 0.0
        assert hcurl_tab[dc][1][1][0] == 0.0
        assert hcurl_tab[dc][2][1][0] == 0.0
        assert hcurl_tab[dc][3][1][0] == 0.0
        assert hcurl_tab[dc][4][1][0] == 0.0
        assert hcurl_tab[dc][5][1][0] == 0.0
Ejemplo n.º 10
0
def test_TFE_1Dx1D_scalar():
    T = UFCInterval()
    P1_DG = DiscontinuousLagrange(T, 1)
    P2 = Lagrange(T, 2)

    elt = TensorProductElement(P1_DG, P2)
    assert elt.value_shape() == ()
    tab = elt.tabulate(1, [(0.1, 0.2)])
    tabA = P1_DG.tabulate(1, [(0.1, )])
    tabB = P2.tabulate(1, [(0.2, )])
    for da, db in [[(0, ), (0, )], [(1, ), (0, )], [(0, ), (1, )]]:
        dc = da + db
        assert np.isclose(tab[dc][0][0], tabA[da][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][1][0], tabA[da][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][2][0], tabA[da][0][0] * tabB[db][2][0])
        assert np.isclose(tab[dc][3][0], tabA[da][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][4][0], tabA[da][1][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][5][0], tabA[da][1][0] * tabB[db][2][0])
Ejemplo n.º 11
0
def test_flattened_against_tpe_hex():
    T = UFCInterval()
    P1 = Lagrange(T, 1)
    tpe_quad = TensorProductElement(P1, P1)
    tpe_hex = TensorProductElement(tpe_quad, P1)
    flattened_quad = FlattenedDimensions(tpe_quad)
    flattened_hex = FlattenedDimensions(TensorProductElement(flattened_quad, P1))
    assert tpe_quad.value_shape() == ()
    tpe_tab = tpe_hex.tabulate(1, [(0.1, 0.2, 0.3)])
    flattened_tab = flattened_hex.tabulate(1, [(0.1, 0.2, 0.3)])

    for da, db, dc in [[(0,), (0,), (0,)], [(1,), (0,), (0,)], [(0,), (1,), (0,)], [(0,), (0,), (1,)]]:
        dd = da + db + dc
        assert np.isclose(tpe_tab[dd][0][0], flattened_tab[dd][0][0])
        assert np.isclose(tpe_tab[dd][1][0], flattened_tab[dd][1][0])
        assert np.isclose(tpe_tab[dd][2][0], flattened_tab[dd][2][0])
        assert np.isclose(tpe_tab[dd][3][0], flattened_tab[dd][3][0])
        assert np.isclose(tpe_tab[dd][4][0], flattened_tab[dd][4][0])
        assert np.isclose(tpe_tab[dd][5][0], flattened_tab[dd][5][0])
        assert np.isclose(tpe_tab[dd][6][0], flattened_tab[dd][6][0])
        assert np.isclose(tpe_tab[dd][7][0], flattened_tab[dd][7][0])
Ejemplo n.º 12
0
def test_TFE_2Dx1D_scalar_quad():
    T = UFCInterval()
    P1 = Lagrange(T, 1)
    P1_DG = DiscontinuousLagrange(T, 1)

    elt = TensorProductElement(TensorProductElement(P1, P1_DG), P1)
    assert elt.value_shape() == ()
    tab = elt.tabulate(1, [(0.1, 0.2, 0.3)])
    tA = P1.tabulate(1, [(0.1,)])
    tB = P1_DG.tabulate(1, [(0.2,)])
    tC = P1.tabulate(1, [(0.3,)])
    for da, db, dc in [[(0,), (0,), (0,)], [(1,), (0,), (0,)], [(0,), (1,), (0,)], [(0,), (0,), (1,)]]:
        dd = da + db + dc
        assert np.isclose(tab[dd][0][0], tA[da][0][0]*tB[db][0][0]*tC[dc][0][0])
        assert np.isclose(tab[dd][1][0], tA[da][0][0]*tB[db][0][0]*tC[dc][1][0])
        assert np.isclose(tab[dd][2][0], tA[da][0][0]*tB[db][1][0]*tC[dc][0][0])
        assert np.isclose(tab[dd][3][0], tA[da][0][0]*tB[db][1][0]*tC[dc][1][0])
        assert np.isclose(tab[dd][4][0], tA[da][1][0]*tB[db][0][0]*tC[dc][0][0])
        assert np.isclose(tab[dd][5][0], tA[da][1][0]*tB[db][0][0]*tC[dc][1][0])
        assert np.isclose(tab[dd][6][0], tA[da][1][0]*tB[db][1][0]*tC[dc][0][0])
        assert np.isclose(tab[dd][7][0], tA[da][1][0]*tB[db][1][0]*tC[dc][1][0])
Ejemplo n.º 13
0
def test_TFE_2Dx1D_scalar_triangle_hdiv():
    S = UFCTriangle()
    T = UFCInterval()
    P1_DG = DiscontinuousLagrange(S, 1)
    P2 = Lagrange(T, 2)

    elt = Hdiv(TensorProductElement(P1_DG, P2))
    assert elt.value_shape() == (3, )
    tab = elt.tabulate(1, [(0.1, 0.2, 0.3)])
    tabA = P1_DG.tabulate(1, [(0.1, 0.2)])
    tabB = P2.tabulate(1, [(0.3, )])
    for da, db in [[(0, 0), (0, )], [(1, 0), (0, )], [(0, 1), (0, )],
                   [(0, 0), (1, )]]:
        dc = da + db
        assert tab[dc][0][0][0] == 0.0
        assert tab[dc][1][0][0] == 0.0
        assert tab[dc][2][0][0] == 0.0
        assert tab[dc][3][0][0] == 0.0
        assert tab[dc][4][0][0] == 0.0
        assert tab[dc][5][0][0] == 0.0
        assert tab[dc][6][0][0] == 0.0
        assert tab[dc][7][0][0] == 0.0
        assert tab[dc][8][0][0] == 0.0
        assert tab[dc][0][1][0] == 0.0
        assert tab[dc][1][1][0] == 0.0
        assert tab[dc][2][1][0] == 0.0
        assert tab[dc][3][1][0] == 0.0
        assert tab[dc][4][1][0] == 0.0
        assert tab[dc][5][1][0] == 0.0
        assert tab[dc][6][1][0] == 0.0
        assert tab[dc][7][1][0] == 0.0
        assert tab[dc][8][1][0] == 0.0
        assert np.isclose(tab[dc][0][2][0], tabA[da][0][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][1][2][0], tabA[da][0][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][2][2][0], tabA[da][0][0] * tabB[db][2][0])
        assert np.isclose(tab[dc][3][2][0], tabA[da][1][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][4][2][0], tabA[da][1][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][5][2][0], tabA[da][1][0] * tabB[db][2][0])
        assert np.isclose(tab[dc][6][2][0], tabA[da][2][0] * tabB[db][0][0])
        assert np.isclose(tab[dc][7][2][0], tabA[da][2][0] * tabB[db][1][0])
        assert np.isclose(tab[dc][8][2][0], tabA[da][2][0] * tabB[db][2][0])
Ejemplo n.º 14
0
def test_flattened_against_tpe_hex():
    T = UFCInterval()
    P1 = Lagrange(T, 1)
    tpe_quad = TensorProductElement(P1, P1)
    tpe_hex = TensorProductElement(tpe_quad, P1)
    flattened_quad = FlattenedDimensions(tpe_quad)
    flattened_hex = FlattenedDimensions(
        TensorProductElement(flattened_quad, P1))
    assert tpe_quad.value_shape() == ()
    tpe_tab = tpe_hex.tabulate(1, [(0.1, 0.2, 0.3)])
    flattened_tab = flattened_hex.tabulate(1, [(0.1, 0.2, 0.3)])

    for da, db, dc in [[(0, ), (0, ), (0, )], [(1, ), (0, ), (0, )],
                       [(0, ), (1, ), (0, )], [(0, ), (0, ), (1, )]]:
        dd = da + db + dc
        assert np.isclose(tpe_tab[dd][0][0], flattened_tab[dd][0][0])
        assert np.isclose(tpe_tab[dd][1][0], flattened_tab[dd][1][0])
        assert np.isclose(tpe_tab[dd][2][0], flattened_tab[dd][2][0])
        assert np.isclose(tpe_tab[dd][3][0], flattened_tab[dd][3][0])
        assert np.isclose(tpe_tab[dd][4][0], flattened_tab[dd][4][0])
        assert np.isclose(tpe_tab[dd][5][0], flattened_tab[dd][5][0])
        assert np.isclose(tpe_tab[dd][6][0], flattened_tab[dd][6][0])
        assert np.isclose(tpe_tab[dd][7][0], flattened_tab[dd][7][0])
Ejemplo n.º 15
0
def Hdiv(element):
    if not isinstance(element, TensorProductElement):
        raise NotImplementedError

    if element.A.get_formdegree() is None or element.B.get_formdegree(
    ) is None:
        raise ValueError(
            "form degree of sub-element was None (not set during initialisation), Hdiv cannot be done without this information"
        )
    formdegree = element.A.get_formdegree() + element.B.get_formdegree()
    if formdegree != element.get_reference_element().get_spatial_dimension(
    ) - 1:
        raise ValueError("Tried to use Hdiv on a non-(n-1)-form element")

    newelement = TensorProductElement(element.A,
                                      element.B)  # make a copy to return

    # redefine value_shape()
    def value_shape(self):
        "Return the value shape of the finite element functions."
        return (self.get_reference_element().get_spatial_dimension(), )

    newelement.value_shape = types.MethodType(value_shape, newelement)

    # store old _mapping
    newelement._oldmapping = newelement._mapping

    # redefine _mapping
    newelement._mapping = "contravariant piola"

    # store formdegree
    newelement.formdegree = formdegree

    # redefine tabulate
    newelement.old_tabulate = newelement.tabulate

    def tabulate(self, order, points, entity=None):
        """Return tabulated values of derivatives up to given order of
        basis functions at given points."""

        # don't duplicate what the old function does fine...
        old_result = self.old_tabulate(order, points, entity)
        new_result = {}
        sd = self.get_reference_element().get_spatial_dimension()
        for alpha in old_result.keys():
            temp_old = old_result[alpha]

            if self._oldmapping == "affine":
                temp = numpy.zeros((temp_old.shape[0], sd, temp_old.shape[1]),
                                   dtype=temp_old.dtype)
                # both constituents affine, i.e., they were 0 forms or n-forms.
                # to sum to n-1, we must have "0-form on an interval" crossed
                # with something discontinuous.
                # look for the (continuous) 0-form, and put the value there
                if self.A.get_formdegree() == 0:
                    # first element, so (-x, 0, ...)
                    # Sign flip to ensure that a positive value of the node
                    # means a vector field having a direction "to the left"
                    # relative to direction in which the nodes are placed on an
                    # edge in case of higher-order schemes.
                    # This is required for unstructured quadrilateral meshes.
                    temp[:, 0, :] = -temp_old[:, :]
                elif self.B.get_formdegree() == 0:
                    # second element, so (..., 0, x)
                    temp[:, -1, :] = temp_old[:, :]
                else:
                    raise Exception("Hdiv affine/affine form degrees broke")

            elif self._oldmapping == "contravariant piola":
                temp = numpy.zeros((temp_old.shape[0], sd, temp_old.shape[2]),
                                   dtype=temp_old.dtype)
                Asd = self.A.get_reference_element().get_spatial_dimension()
                # one component is affine, one is contravariant piola
                # the affine one must be an n-form, hence discontinuous
                # this component/these components get zeroed out
                if element.A.mapping()[0] == "contravariant piola":
                    # first element, so (x1, ..., xn, 0, ...)
                    temp[:, :Asd, :] = temp_old[:, :, :]
                elif element.B.mapping()[0] == "contravariant piola":
                    # second element, so (..., 0, x1, ..., xn)
                    temp[:, Asd:, :] = temp_old[:, :, :]
                else:
                    raise ValueError(
                        "Hdiv contravariant piola couldn't find an existing ConPi subelement"
                    )

            elif self._oldmapping == "covariant piola":
                temp = numpy.zeros((temp_old.shape[0], sd, temp_old.shape[2]),
                                   dtype=temp_old.dtype)
                # one component is affine, one is covariant piola
                # the affine one must be an n-form, hence discontinuous
                # this component/these components get zeroed out
                # the remaining part gets perped
                if element.A.mapping()[0] == "covariant piola":
                    Asd = self.A.get_reference_element().get_spatial_dimension(
                    )
                    if not Asd == 2:
                        raise ValueError(
                            "Must be 2d shape to automatically convert covariant to contravariant"
                        )
                    temp_perp = numpy.zeros(temp_old.shape,
                                            dtype=temp_old.dtype)
                    # first element, so (x2, -x1, 0, ...)
                    temp_perp[:, 0, :] = temp_old[:, 1, :]
                    temp_perp[:, 1, :] = -temp_old[:, 0, :]
                    temp[:, :Asd, :] = temp_perp[:, :, :]
                elif element.B.mapping()[0] == "covariant piola":
                    Bsd = self.B.get_reference_element().get_spatial_dimension(
                    )
                    if not Bsd == 2:
                        raise ValueError(
                            "Must be 2d shape to automatically convert covariant to contravariant"
                        )
                    temp_perp = numpy.zeros(temp_old.shape,
                                            dtype=temp_old.dtype)
                    # second element, so (..., 0, x2, -x1)
                    temp_perp[:, 0, :] = temp_old[:, 1, :]
                    temp_perp[:, 1, :] = -temp_old[:, 0, :]
                    temp[:, Asd:, :] = temp_old[:, :, :]
                else:
                    raise ValueError(
                        "Hdiv covariant piola couldn't find an existing CovPi subelement"
                    )
            new_result[alpha] = temp
        return new_result

    newelement.tabulate = types.MethodType(tabulate, newelement)

    # splat any PointEvaluation functionals.
    # they become a nasty mix of internal and external component DOFs
    if newelement._oldmapping == "affine":
        oldnodes = newelement.dual.nodes
        newnodes = []
        for node in oldnodes:
            if isinstance(node, functional.PointEvaluation):
                newnodes.append(
                    functional.Functional(None, None, None, {}, "Undefined"))
            else:
                newnodes.append(node)
        newelement.dual.nodes = newnodes

    return newelement
Ejemplo n.º 16
0
def Hdiv(element):
    if not isinstance(element, TensorProductElement):
        raise NotImplementedError

    if element.A.get_formdegree() is None or element.B.get_formdegree() is None:
        raise ValueError("form degree of sub-element was None (not set during initialisation), Hdiv cannot be done without this information")
    formdegree = element.A.get_formdegree() + element.B.get_formdegree()
    if formdegree != element.get_reference_element().get_spatial_dimension() - 1:
        raise ValueError("Tried to use Hdiv on a non-(n-1)-form element")

    newelement = TensorProductElement(element.A, element.B)  # make a copy to return

    # redefine value_shape()
    def value_shape(self):
        "Return the value shape of the finite element functions."
        return (self.get_reference_element().get_spatial_dimension(),)
    newelement.value_shape = types.MethodType(value_shape, newelement)

    # store old _mapping
    newelement._oldmapping = newelement._mapping

    # redefine _mapping
    newelement._mapping = "contravariant piola"

    # store formdegree
    newelement.formdegree = formdegree

    # redefine tabulate
    newelement.old_tabulate = newelement.tabulate

    def tabulate(self, order, points, entity=None):
        """Return tabulated values of derivatives up to given order of
        basis functions at given points."""

        # don't duplicate what the old function does fine...
        old_result = self.old_tabulate(order, points, entity)
        new_result = {}
        sd = self.get_reference_element().get_spatial_dimension()
        for alpha in old_result.keys():
            temp_old = old_result[alpha]

            if self._oldmapping == "affine":
                temp = numpy.zeros((temp_old.shape[0], sd, temp_old.shape[1]), dtype=temp_old.dtype)
                # both constituents affine, i.e., they were 0 forms or n-forms.
                # to sum to n-1, we must have "0-form on an interval" crossed
                # with something discontinuous.
                # look for the (continuous) 0-form, and put the value there
                if self.A.get_formdegree() == 0:
                    # first element, so (-x, 0, ...)
                    # Sign flip to ensure that a positive value of the node
                    # means a vector field having a direction "to the left"
                    # relative to direction in which the nodes are placed on an
                    # edge in case of higher-order schemes.
                    # This is required for unstructured quadrilateral meshes.
                    temp[:, 0, :] = -temp_old[:, :]
                elif self.B.get_formdegree() == 0:
                    # second element, so (..., 0, x)
                    temp[:, -1, :] = temp_old[:, :]
                else:
                    raise Exception("Hdiv affine/affine form degrees broke")

            elif self._oldmapping == "contravariant piola":
                temp = numpy.zeros((temp_old.shape[0], sd, temp_old.shape[2]), dtype=temp_old.dtype)
                Asd = self.A.get_reference_element().get_spatial_dimension()
                # one component is affine, one is contravariant piola
                # the affine one must be an n-form, hence discontinuous
                # this component/these components get zeroed out
                if element.A.mapping()[0] == "contravariant piola":
                    # first element, so (x1, ..., xn, 0, ...)
                    temp[:, :Asd, :] = temp_old[:, :, :]
                elif element.B.mapping()[0] == "contravariant piola":
                    # second element, so (..., 0, x1, ..., xn)
                    temp[:, Asd:, :] = temp_old[:, :, :]
                else:
                    raise ValueError("Hdiv contravariant piola couldn't find an existing ConPi subelement")

            elif self._oldmapping == "covariant piola":
                temp = numpy.zeros((temp_old.shape[0], sd, temp_old.shape[2]), dtype=temp_old.dtype)
                # one component is affine, one is covariant piola
                # the affine one must be an n-form, hence discontinuous
                # this component/these components get zeroed out
                # the remaining part gets perped
                if element.A.mapping()[0] == "covariant piola":
                    Asd = self.A.get_reference_element().get_spatial_dimension()
                    if not Asd == 2:
                        raise ValueError("Must be 2d shape to automatically convert covariant to contravariant")
                    temp_perp = numpy.zeros(temp_old.shape, dtype=temp_old.dtype)
                    # first element, so (x2, -x1, 0, ...)
                    temp_perp[:, 0, :] = temp_old[:, 1, :]
                    temp_perp[:, 1, :] = -temp_old[:, 0, :]
                    temp[:, :Asd, :] = temp_perp[:, :, :]
                elif element.B.mapping()[0] == "covariant piola":
                    Bsd = self.B.get_reference_element().get_spatial_dimension()
                    if not Bsd == 2:
                        raise ValueError("Must be 2d shape to automatically convert covariant to contravariant")
                    temp_perp = numpy.zeros(temp_old.shape, dtype=temp_old.dtype)
                    # second element, so (..., 0, x2, -x1)
                    temp_perp[:, 0, :] = temp_old[:, 1, :]
                    temp_perp[:, 1, :] = -temp_old[:, 0, :]
                    temp[:, Asd:, :] = temp_old[:, :, :]
                else:
                    raise ValueError("Hdiv covariant piola couldn't find an existing CovPi subelement")
            new_result[alpha] = temp
        return new_result

    newelement.tabulate = types.MethodType(tabulate, newelement)

    # splat any PointEvaluation functionals.
    # they become a nasty mix of internal and external component DOFs
    if newelement._oldmapping == "affine":
        oldnodes = newelement.dual.nodes
        newnodes = []
        for node in oldnodes:
            if isinstance(node, functional.PointEvaluation):
                newnodes.append(functional.Functional(None, None, None, {}, "Undefined"))
            else:
                newnodes.append(node)
        newelement.dual.nodes = newnodes

    return newelement