예제 #1
0
def test_quad_trace(degree):
    """Test the trace element defined on a quadrilateral cell"""
    from FIAT import ufc_simplex, HDivTrace, make_quadrature
    from FIAT.reference_element import TensorProductCell

    tpc = TensorProductCell(ufc_simplex(1), ufc_simplex(1))
    fiat_element = HDivTrace(tpc, (degree, degree))
    facet_elements = fiat_element.dg_elements
    quadrule = make_quadrature(ufc_simplex(1), degree + 1)

    for i, entity in enumerate([((0, 1), 0), ((0, 1), 1), ((1, 0), 0),
                                ((1, 0), 1)]):
        entity_dim, _ = entity
        element = facet_elements[entity_dim]
        nf = element.space_dimension()

        tab = fiat_element.tabulate(0, quadrule.pts,
                                    entity)[(0, 0)][nf * i:nf * (i + 1)]

        for test_degree in range(degree + 1):
            coeffs = [
                n(lambda x: x[0]**test_degree) for n in element.dual.nodes
            ]

            integral = np.dot(coeffs, np.dot(tab, quadrule.wts))

            reference = np.dot([x[0]**test_degree for x in quadrule.pts],
                               quadrule.wts)
            assert np.allclose(integral, reference, rtol=1e-14)
예제 #2
0
def test_quad_trace(degree):
    """Test the trace element defined on a quadrilateral cell"""
    from FIAT import ufc_simplex, HDivTrace, make_quadrature
    from FIAT.reference_element import TensorProductCell

    tpc = TensorProductCell(ufc_simplex(1), ufc_simplex(1))
    fiat_element = HDivTrace(tpc, (degree, degree))
    facet_elements = fiat_element.dg_elements
    quadrule = make_quadrature(ufc_simplex(1), degree + 1)

    for i, entity in enumerate([((0, 1), 0), ((0, 1), 1),
                                ((1, 0), 0), ((1, 0), 1)]):
        entity_dim, _ = entity
        element = facet_elements[entity_dim]
        nf = element.space_dimension()

        tab = fiat_element.tabulate(0, quadrule.pts,
                                    entity)[(0, 0)][nf*i:nf*(i+1)]

        for test_degree in range(degree + 1):
            coeffs = [n(lambda x: x[0]**test_degree)
                      for n in element.dual.nodes]

            integral = np.dot(coeffs, np.dot(tab, quadrule.wts))

            reference = np.dot([x[0]**test_degree
                                for x in quadrule.pts], quadrule.wts)
            assert np.allclose(integral, reference, rtol=1e-14)
예제 #3
0
파일: test_awc.py 프로젝트: vsujeesh/fiat
def test_projection():
    T = ufc_simplex(2)
    T.vertices = np.asarray([(0.0, 0.0), (1.0, 0.0), (0.5, 2.1)])

    AW = ArnoldWinther(T, 3)

    Q = make_quadrature(T, 4)
    qpts = np.asarray(Q.pts)
    qwts = np.asarray(Q.wts)
    nqp = len(Q.wts)

    nbf = 24
    m = np.zeros((nbf, nbf))
    b = np.zeros((24,))
    rhs_vals = np.zeros((2, 2, nqp))

    bfvals = AW.tabulate(0, qpts)[(0, 0)][:nbf, :, :, :]

    for i in range(nbf):
        for j in range(nbf):
            for k in range(nqp):
                m[i, j] += qwts[k] * frob(bfvals[i, :, :, k],
                                          bfvals[j, :, :, k])

    assert np.linalg.cond(m) < 1.e12

    comps = [(0, 0), (0, 1), (0, 0)]

    # loop over monomials up to degree 2
    for deg in range(3):
        for jj in range(deg+1):
            ii = deg-jj
            for comp in comps:
                b[:] = 0.0
                # set RHS (symmetrically) to be the monomial in
                # the proper component.
                rhs_vals[comp] = qpts[:, 0]**ii * qpts[:, 1]**jj
                rhs_vals[tuple(reversed(comp))] = rhs_vals[comp]
                for i in range(nbf):
                    for k in range(nqp):
                        b[i] += qwts[k] * frob(bfvals[i, :, :, k],
                                               rhs_vals[:, :, k])
                x = np.linalg.solve(m, b)

                sol_at_qpts = np.zeros(rhs_vals.shape)
                for i in range(nbf):
                    for k in range(nqp):
                        sol_at_qpts[:, :, k] += x[i] * bfvals[i, :, :, k]

                diff = sol_at_qpts - rhs_vals
                err = 0.0
                for k in range(nqp):
                    err += qwts[k] * frob(diff[:, :, k], diff[:, :, k])

                assert np.sqrt(err) < 1.e-12
예제 #4
0
def test_cell_traceerror(dim, degree):
    """Ensure that the TraceError appears in all dict entries when deliberately
    attempting to tabulate the cell of a trace element."""
    from FIAT import ufc_simplex, HDivTrace, make_quadrature
    from FIAT.hdiv_trace import TraceError

    fiat_element = HDivTrace(ufc_simplex(dim), degree)
    pts = make_quadrature(ufc_simplex(dim), 1).pts
    tab = fiat_element.tabulate(0, pts, entity=(dim, 0))

    for key in tab.keys():
        assert isinstance(tab[key], TraceError)
예제 #5
0
def test_cell_traceerror(dim, degree):
    """Ensure that the TraceError appears in all dict entries when deliberately
    attempting to tabulate the cell of a trace element."""
    from FIAT import ufc_simplex, HDivTrace, make_quadrature
    from FIAT.hdiv_trace import TraceError

    fiat_element = HDivTrace(ufc_simplex(dim), degree)
    pts = make_quadrature(ufc_simplex(dim), 1).pts
    tab = fiat_element.tabulate(0, pts, entity=(dim, 0))

    for key in tab.keys():
        assert isinstance(tab[key], TraceError)
예제 #6
0
 def create_data(family, dim, degree):
     '''Create the reference data.
     '''
     # Get domain and element class
     domain = ufc_simplex(dim)
     ElementClass = supported_elements[family]
     # Create element
     element = ElementClass(domain, degree)
     # Create quadrature points
     quad_rule = make_quadrature(domain, num_points)
     points = quad_rule.get_points()
     # Tabulate at quadrature points
     table = element.tabulate(max_derivative, points)
     return table
예제 #7
0
 def create_data(family, dim, degree):
     '''Create the reference data.
     '''
     # Get domain and element class
     domain = ufc_simplex(dim)
     ElementClass = supported_elements[family]
     # Create element
     element = ElementClass(domain, degree)
     # Create quadrature points
     quad_rule = make_quadrature(domain, num_points)
     points = quad_rule.get_points()
     # Tabulate at quadrature points
     table = element.tabulate(max_derivative, points)
     return table
예제 #8
0
def test_basis_values(dim, degree):
    """Ensure that integrating a simple monomial produces the expected results."""
    from FIAT import ufc_simplex, DiscontinuousTaylor, make_quadrature

    s = ufc_simplex(dim)
    q = make_quadrature(s, degree + 1)

    fe = DiscontinuousTaylor(s, degree)
    tab = fe.tabulate(0, q.pts)[(0, ) * dim]

    for test_degree in range(degree + 1):
        coefs = [n(lambda x: x[0]**test_degree) for n in fe.dual.nodes]
        integral = np.float(np.dot(coefs, np.dot(tab, q.wts)))
        reference = np.dot([x[0]**test_degree for x in q.pts], q.wts)
        assert np.isclose(integral, reference, rtol=1e-14)
예제 #9
0
def test_gradient_traceerror(dim, order, degree):
    """Ensure that the TraceError appears in the appropriate dict entries when
    attempting to tabulate certain orders of derivatives."""
    from FIAT import ufc_simplex, HDivTrace, make_quadrature
    from FIAT.hdiv_trace import TraceError

    fiat_element = HDivTrace(ufc_simplex(dim), degree)
    pts = make_quadrature(ufc_simplex(dim - 1), degree + 1).pts

    for facet_id in range(dim + 1):
        tab = fiat_element.tabulate(order, pts, entity=(dim - 1, facet_id))

        for key in tab.keys():
            if key != (0,)*dim:
                assert isinstance(tab[key], TraceError)
예제 #10
0
def test_gll_basis_values(degree):
    """Ensure that integrating a simple monomial produces the expected results."""
    from FIAT import ufc_simplex, GaussLobattoLegendre, make_quadrature

    s = ufc_simplex(1)
    q = make_quadrature(s, degree + 1)

    fe = GaussLobattoLegendre(s, degree)
    tab = fe.tabulate(0, q.pts)[(0, )]

    for test_degree in range(degree + 1):
        coefs = [n(lambda x: x[0]**test_degree) for n in fe.dual.nodes]
        integral = np.dot(coefs, np.dot(tab, q.wts))
        reference = np.dot([x[0]**test_degree for x in q.pts], q.wts)
        assert np.allclose(integral, reference, rtol=1e-14)
예제 #11
0
def test_gradient_traceerror(dim, order, degree):
    """Ensure that the TraceError appears in the appropriate dict entries when
    attempting to tabulate certain orders of derivatives."""
    from FIAT import ufc_simplex, HDivTrace, make_quadrature
    from FIAT.hdiv_trace import TraceError

    fiat_element = HDivTrace(ufc_simplex(dim), degree)
    pts = make_quadrature(ufc_simplex(dim - 1), degree + 1).pts

    for facet_id in range(dim + 1):
        tab = fiat_element.tabulate(order, pts, entity=(dim - 1, facet_id))

        for key in tab.keys():
            if key != (0, ) * dim:
                assert isinstance(tab[key], TraceError)
예제 #12
0
def test_sparsity(degree):
    from FIAT import ufc_simplex, FDMLagrange, make_quadrature
    cell = ufc_simplex(1)
    fe = FDMLagrange(cell, degree)

    rule = make_quadrature(cell, degree + 1)
    basis = fe.tabulate(1, rule.get_points())
    Jhat = basis[(0, )]
    Dhat = basis[(1, )]
    what = rule.get_weights()
    Ahat = np.dot(np.multiply(Dhat, what), Dhat.T)
    Bhat = np.dot(np.multiply(Jhat, what), Jhat.T)
    nnz = lambda A: A.size - np.sum(np.isclose(A, 0.0E0, rtol=1E-14))
    ndof = fe.space_dimension()
    assert nnz(Ahat) == 5 * ndof - 6
    assert nnz(Bhat) == ndof + 2
예제 #13
0
def test_basis_values(dim, degree):
    """Ensure that integrating a simple monomial produces the expected results."""
    from FIAT import ufc_simplex, DiscontinuousTaylor, make_quadrature

    s = ufc_simplex(dim)
    q = make_quadrature(s, degree + 1)

    fe = DiscontinuousTaylor(s, degree)
    tab = fe.tabulate(0, q.pts)[(0,) * dim]

    for test_degree in range(degree + 1):
        coefs = [n(lambda x: x[0]**test_degree) for n in fe.dual.nodes]
        integral = np.float(np.dot(coefs, np.dot(tab, q.wts)))
        reference = np.dot([x[0]**test_degree
                            for x in q.pts], q.wts)
        assert np.isclose(integral, reference, rtol=1e-14)
예제 #14
0
def test_gl_basis_values(degree):
    """Ensure that integrating a simple monomial produces the expected results."""
    from FIAT import ufc_simplex, GaussLegendre, make_quadrature

    s = ufc_simplex(1)
    q = make_quadrature(s, degree + 1)

    fe = GaussLegendre(s, degree)
    tab = fe.tabulate(0, q.pts)[(0,)]

    for test_degree in range(degree + 1):
        coefs = [n(lambda x: x[0]**test_degree) for n in fe.dual.nodes]
        integral = np.dot(coefs, np.dot(tab, q.wts))
        reference = np.dot([x[0]**test_degree
                            for x in q.pts], q.wts)
        assert np.allclose(integral, reference, rtol=1e-14)
예제 #15
0
def test_basis_values(dim, degree):
    """Ensure that integrating a simple monomial produces the expected results."""
    from FIAT import ufc_cell, make_quadrature
    from FIAT import DPC

    cell = np.array([None, 'interval', 'quadrilateral', 'hexahedron'])
    s = ufc_cell(cell[dim])
    q = make_quadrature(s, degree + 1)

    fe = DPC(s, degree)
    tab = fe.tabulate(0, q.pts)[(0, ) * dim]

    for test_degree in range(degree + 1):
        coefs = [n(lambda x: x[0]**test_degree) for n in fe.dual.nodes]
        integral = np.float(np.dot(coefs, np.dot(tab, q.wts)))
        reference = np.dot([x[0]**test_degree for x in q.pts], q.wts)
        assert np.isclose(integral, reference, rtol=1e-14)
예제 #16
0
def test_basis_values(dim, degree):
    """Ensure that integrating simple monomials produces the expected results
    for each facet entity of the reference triangle and tetrahedron.

    This test performs the trace tabulation in two ways:
    (1) The entity is not specified, in which case the element uses
        numerical tolerance to determine the facet id;
    (2) The entity pair (dim, id) is provided, and the trace element
        tabulates accordingly using the new tabulate API.
    """
    from FIAT import ufc_simplex, HDivTrace, make_quadrature

    ref_el = ufc_simplex(dim)
    quadrule = make_quadrature(ufc_simplex(dim - 1), degree + 1)
    fiat_element = HDivTrace(ref_el, degree)
    facet_element = fiat_element.dg_elements[dim - 1]
    nf = facet_element.space_dimension()

    for facet_id in range(dim + 1):
        # Tabulate without an entity pair given --- need to map to cell coordinates
        cell_transform = ref_el.get_entity_transform(dim - 1, facet_id)
        cell_points = np.array(list(map(cell_transform, quadrule.pts)))
        ctab = fiat_element.tabulate(
            0, cell_points)[(0, ) * dim][nf * facet_id:nf * (facet_id + 1)]

        # Tabulate with entity pair provided
        entity = (ref_el.get_spatial_dimension() - 1, facet_id)
        etab = fiat_element.tabulate(0, quadrule.pts,
                                     entity)[(0, ) * dim][nf * facet_id:nf *
                                                          (facet_id + 1)]

        for test_degree in range(degree + 1):
            coeffs = [
                n(lambda x: x[0]**test_degree)
                for n in facet_element.dual.nodes
            ]

            cintegral = np.dot(coeffs, np.dot(ctab, quadrule.wts))
            eintegral = np.dot(coeffs, np.dot(etab, quadrule.wts))
            assert np.allclose(cintegral, eintegral, rtol=1e-14)

            reference = np.dot([x[0]**test_degree for x in quadrule.pts],
                               quadrule.wts)
            assert np.allclose(cintegral, reference, rtol=1e-14)
            assert np.allclose(eintegral, reference, rtol=1e-14)
예제 #17
0
def test_basis_values(dim, degree):
    """Ensure that integrating a simple monomial produces the expected results."""
    from FIAT import ufc_cell, make_quadrature
    from FIAT.discontinuous_pc import DPC

    cell = np.array([None, 'interval', 'quadrilateral', 'hexahedron'])
    s = ufc_cell(cell[dim])
    q = make_quadrature(s, degree + 1)

    fe = DPC(s, degree)
    tab = fe.tabulate(0, q.pts)[(0,) * dim]

    for test_degree in range(degree + 1):
        coefs = [n(lambda x: x[0]**test_degree) for n in fe.dual.nodes]
        integral = np.float(np.dot(coefs, np.dot(tab, q.wts)))
        reference = np.dot([x[0]**test_degree
                            for x in q.pts], q.wts)
        assert np.isclose(integral, reference, rtol=1e-14)
예제 #18
0
def test_interpolate_monomials_tris(element_degree):
    element, degree = element_degree

    # ordered the same way as KMV nodes
    pts = create_quadrature(T, degree, "KMV").pts

    Q = make_quadrature(T, 2 * degree)
    phis = element.tabulate(0, Q.pts)[0, 0]
    print("deg", degree)
    for i in range(degree + 1):
        for j in range(degree + 1 - i):
            m = lambda x: x[0]**i * x[1]**j
            dofs = np.array([m(pt) for pt in pts])
            interp = phis.T @ dofs
            matqp = np.array([m(pt) for pt in Q.pts])
            err = 0.0
            for k in range(phis.shape[1]):
                err += Q.wts[k] * (interp[k] - matqp[k])**2
            assert np.sqrt(err) <= 1.0e-12
예제 #19
0
def test_basis_values(dim, degree):
    """Ensure that integrating simple monomials produces the expected results
    for each facet entity of the reference triangle and tetrahedron.

    This test performs the trace tabulation in two ways:
    (1) The entity is not specified, in which case the element uses
        numerical tolerance to determine the facet id;
    (2) The entity pair (dim, id) is provided, and the trace element
        tabulates accordingly using the new tabulate API.
    """
    from FIAT import ufc_simplex, HDivTrace, make_quadrature

    ref_el = ufc_simplex(dim)
    quadrule = make_quadrature(ufc_simplex(dim - 1), degree + 1)
    fiat_element = HDivTrace(ref_el, degree)
    facet_element = fiat_element.dg_elements[dim - 1]
    nf = facet_element.space_dimension()

    for facet_id in range(dim + 1):
        # Tabulate without an entity pair given --- need to map to cell coordinates
        cell_transform = ref_el.get_entity_transform(dim - 1, facet_id)
        cell_points = np.array(list(map(cell_transform, quadrule.pts)))
        ctab = fiat_element.tabulate(0, cell_points)[(0,) * dim][nf*facet_id:nf*(facet_id + 1)]

        # Tabulate with entity pair provided
        entity = (ref_el.get_spatial_dimension() - 1, facet_id)
        etab = fiat_element.tabulate(0, quadrule.pts,
                                     entity)[(0,) * dim][nf*facet_id:nf*(facet_id + 1)]

        for test_degree in range(degree + 1):
            coeffs = [n(lambda x: x[0]**test_degree)
                      for n in facet_element.dual.nodes]

            cintegral = np.dot(coeffs, np.dot(ctab, quadrule.wts))
            eintegral = np.dot(coeffs, np.dot(etab, quadrule.wts))
            assert np.allclose(cintegral, eintegral, rtol=1e-14)

            reference = np.dot([x[0]**test_degree
                                for x in quadrule.pts], quadrule.wts)
            assert np.allclose(cintegral, reference, rtol=1e-14)
            assert np.allclose(eintegral, reference, rtol=1e-14)
예제 #20
0
def test_dofs():
    line = ufc_simplex(1)
    T = ufc_simplex(2)
    T.vertices = np.asarray([(0.0, 0.0), (1.0, 0.25), (-0.75, 1.1)])
    MTW = MardalTaiWinther(T, 3)

    Qline = make_quadrature(line, 6)

    linebfs = expansions.LineExpansionSet(line)
    linevals = linebfs.tabulate(1, Qline.pts)

    for ed in range(3):
        n = T.compute_scaled_normal(ed)
        wts = np.asarray(Qline.wts)

        vals = MTW.tabulate(0, Qline.pts, (1, ed))[(0, 0)]
        nvals = np.dot(np.transpose(vals, (0, 2, 1)), n)
        normal_moments = np.zeros((9, 2))
        for bf in range(9):
            for k in range(len(Qline.wts)):
                for m in (0, 1):
                    normal_moments[bf,
                                   m] += wts[k] * nvals[bf, k] * linevals[m, k]
        right = np.zeros((9, 2))
        right[3 * ed, 0] = 1.0
        right[3 * ed + 2, 1] = 1.0
        assert np.allclose(normal_moments, right)
    for ed in range(3):
        t = T.compute_edge_tangent(ed)
        wts = np.asarray(Qline.wts)

        vals = MTW.tabulate(0, Qline.pts, (1, ed))[(0, 0)]
        tvals = np.dot(np.transpose(vals, (0, 2, 1)), t)
        tangent_moments = np.zeros(9)
        for bf in range(9):
            for k in range(len(Qline.wts)):
                tangent_moments[bf] += wts[k] * tvals[bf, k] * linevals[0, k]
        right = np.zeros(9)
        right[3 * ed + 1] = 1.0
        assert np.allclose(tangent_moments, right)
예제 #21
0
def test_edge_degree(degree):
    """Verify that the outer edges of a degree KMV element
       are indeed of degree and the interior is of degree+1"""
    # create a degree+1 polynomial
    I = UFCInterval()
    # an exact quad. rule for a degree+1 polynomial on the UFCinterval
    qr = make_quadrature(I, degree + 1)
    W = np.diag(qr.wts)
    sd = I.get_spatial_dimension()
    pset = polynomial_set.ONPolynomialSet(I, degree + 1, (sd, ))
    pset = pset.take([degree + 1])
    # tabulate at the quadrature points
    interval_vals = pset.tabulate(qr.get_points())[(0, )]
    interval_vals = np.squeeze(interval_vals)
    # create degree KMV element (should have degree outer edges and degree+1 edge in center)
    T = UFCTriangle()
    element = KMV(T, degree)
    # tabulate values on an edge of the KMV element
    for e in range(3):
        edge_values = element.tabulate(0, qr.get_points(), (1, e))[(0, 0)]
        # degree edge should be orthogonal to degree+1 ONpoly edge values
        result = edge_values @ W @ interval_vals.T
        assert np.allclose(np.sum(result), 0.0)
예제 #22
0
파일: test_awc.py 프로젝트: vsujeesh/fiat
def test_dofs():
    line = ufc_simplex(1)
    T = ufc_simplex(2)
    T.vertices = np.random.rand(3, 2)
    AW = ArnoldWinther(T, 3)

    # check Kronecker property at vertices

    bases = [[[1, 0], [0, 0]], [[0, 1], [1, 0]], [[0, 0], [0, 1]]]

    vert_vals = AW.tabulate(0, T.vertices)[(0, 0)]
    for i in range(3):
        for j in range(3):
            assert np.allclose(vert_vals[3*i+j, :, :, i], bases[j])
            for k in (1, 2):
                assert np.allclose(vert_vals[3*i+j, :, :, (i+k) % 3], np.zeros((2, 2)))

    # check edge moments
    Qline = make_quadrature(line, 6)

    linebfs = expansions.LineExpansionSet(line)
    linevals = linebfs.tabulate(1, Qline.pts)

    # n, n moments
    for ed in range(3):
        n = T.compute_scaled_normal(ed)
        wts = np.asarray(Qline.wts)
        nqpline = len(wts)

        vals = AW.tabulate(0, Qline.pts, (1, ed))[(0, 0)]
        nnvals = np.zeros((30, nqpline))
        for i in range(30):
            for j in range(len(wts)):
                nnvals[i, j] = n @ vals[i, :, :, j] @ n

        nnmoments = np.zeros((30, 2))

        for bf in range(30):
            for k in range(nqpline):
                for m in (0, 1):
                    nnmoments[bf, m] += wts[k] * nnvals[bf, k] * linevals[m, k]

        for bf in range(30):
            if bf != AW.dual.entity_ids[1][ed][0] and bf != AW.dual.entity_ids[1][ed][2]:
                assert np.allclose(nnmoments[bf, :], np.zeros(2))

    # n, t moments
    for ed in range(3):
        n = T.compute_scaled_normal(ed)
        t = T.compute_edge_tangent(ed)
        wts = np.asarray(Qline.wts)
        nqpline = len(wts)

        vals = AW.tabulate(0, Qline.pts, (1, ed))[(0, 0)]
        ntvals = np.zeros((30, nqpline))
        for i in range(30):
            for j in range(len(wts)):
                ntvals[i, j] = n @ vals[i, :, :, j] @ t

        ntmoments = np.zeros((30, 2))

        for bf in range(30):
            for k in range(nqpline):
                for m in (0, 1):
                    ntmoments[bf, m] += wts[k] * ntvals[bf, k] * linevals[m, k]

        for bf in range(30):
            if bf != AW.dual.entity_ids[1][ed][1] and bf != AW.dual.entity_ids[1][ed][3]:
                assert np.allclose(ntmoments[bf, :], np.zeros(2))

    # check internal dofs
    Q = make_quadrature(T, 6)
    qpvals = AW.tabulate(0, Q.pts)[(0, 0)]
    const_moms = qpvals @ Q.wts
    assert np.allclose(const_moms[:21], np.zeros((21, 2, 2)))
    assert np.allclose(const_moms[24:], np.zeros((6, 2, 2)))
    assert np.allclose(const_moms[21:24, 0, 0], np.asarray([1, 0, 0]))
    assert np.allclose(const_moms[21:24, 0, 1], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[21:24, 1, 0], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[21:24, 1, 1], np.asarray([0, 0, 1]))
예제 #23
0
def test_entity(element, quadrature):
    dim = element.get_reference_element().get_spatial_dimension()
    points = make_quadrature(ufc_simplex(dim - 1), 2).get_points()
    with pytest.raises(ValueError):
        element.tabulate(0, points, entity=(dim - 1, 1))
예제 #24
0
def quadrature(cell):
    return make_quadrature(cell, 2)
예제 #25
0
def test_dofs():
    line = ufc_simplex(1)
    T = ufc_simplex(2)
    T.vertices = np.asarray([(0.0, 0.0), (1.0, 0.25), (-0.75, 1.1)])
    AW = ArnoldWintherNC(T, 2)

    Qline = make_quadrature(line, 6)

    linebfs = expansions.LineExpansionSet(line)
    linevals = linebfs.tabulate(1, Qline.pts)

    # n, n moments
    for ed in range(3):
        n = T.compute_scaled_normal(ed)
        wts = np.asarray(Qline.wts)
        nqpline = len(wts)

        vals = AW.tabulate(0, Qline.pts, (1, ed))[(0, 0)]
        nnvals = np.zeros((18, nqpline))
        for i in range(18):
            for j in range(len(wts)):
                nnvals[i, j] = n @ vals[i, :, :, j] @ n

        nnmoments = np.zeros((18, 2))

        for bf in range(18):
            for k in range(nqpline):
                for m in (0, 1):
                    nnmoments[bf, m] += wts[k] * nnvals[bf, k] * linevals[m, k]

        for bf in range(18):
            if bf != AW.dual.entity_ids[1][ed][0] and bf != AW.dual.entity_ids[
                    1][ed][2]:
                assert np.allclose(nnmoments[bf, :], np.zeros(2))

    # n, t moments
    for ed in range(3):
        n = T.compute_scaled_normal(ed)
        t = T.compute_edge_tangent(ed)
        wts = np.asarray(Qline.wts)
        nqpline = len(wts)

        vals = AW.tabulate(0, Qline.pts, (1, ed))[(0, 0)]
        ntvals = np.zeros((18, nqpline))
        for i in range(18):
            for j in range(len(wts)):
                ntvals[i, j] = n @ vals[i, :, :, j] @ t

        ntmoments = np.zeros((18, 2))

        for bf in range(18):
            for k in range(nqpline):
                for m in (0, 1):
                    ntmoments[bf, m] += wts[k] * ntvals[bf, k] * linevals[m, k]

        for bf in range(18):
            if bf != AW.dual.entity_ids[1][ed][1] and bf != AW.dual.entity_ids[
                    1][ed][3]:
                assert np.allclose(ntmoments[bf, :], np.zeros(2), atol=1.e-7)

    # check internal dofs
    Q = make_quadrature(T, 6)
    qpvals = AW.tabulate(0, Q.pts)[(0, 0)]
    const_moms = qpvals @ Q.wts
    assert np.allclose(const_moms[:12], np.zeros((12, 2, 2)))
    assert np.allclose(const_moms[15:], np.zeros((3, 2, 2)))
    assert np.allclose(const_moms[12:15, 0, 0], np.asarray([1, 0, 0]))
    assert np.allclose(const_moms[12:15, 0, 1], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[12:15, 1, 0], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[12:15, 1, 1], np.asarray([0, 0, 1]))