Exemplo n.º 1
0
    def _generate_edge_dofs(cell, degree):
        """Generate dofs on edges.
        On each edge, let n be its normal.  We need to integrate
        u.n and u.t against the first Legendre polynomial (constant)
        and u.n against the second (linear).
        """
        dofs = []
        dof_ids = {}
        offset = 0
        sd = 2

        facet = cell.get_facet_element()
        # Facet nodes are \int_F v\cdot n p ds where p \in P_{q-1}
        # degree is q - 1
        Q = make_quadrature(facet, 6)
        Pq = ONPolynomialSet(facet, 1)
        Pq_at_qpts = Pq.tabulate(Q.get_points())[tuple([0] * (sd - 1))]
        for f in range(3):
            phi0 = Pq_at_qpts[0, :]
            dofs.append(IntegralMomentOfNormalEvaluation(cell, Q, phi0, f))
            dofs.append(IntegralMomentOfTangentialEvaluation(cell, Q, phi0, f))
            phi1 = Pq_at_qpts[1, :]
            dofs.append(IntegralMomentOfNormalEvaluation(cell, Q, phi1, f))

            num_new_dofs = 3
            dof_ids[f] = list(range(offset, offset + num_new_dofs))
            offset += num_new_dofs

        return (dofs, dof_ids)
Exemplo n.º 2
0
def DivergenceDubinerMoments(cell, start_deg, stop_deg, comp_deg):
    onp = ONPolynomialSet(cell, stop_deg)
    Q = make_quadrature(cell, comp_deg)

    pts = Q.get_points()
    onp = onp.tabulate(pts, 0)[0, 0]

    ells = []

    for ii in range((start_deg) * (start_deg + 1) // 2,
                    (stop_deg + 1) * (stop_deg + 2) // 2):
        ells.append(IntegralMomentOfDivergence(cell, Q, onp[ii, :]))

    return ells
Exemplo n.º 3
0
    def __init__(self, cell, k, variant=None):

        (variant, quad_deg) = check_format_variant(variant, k)

        # Check degree
        assert k >= 1, "Second kind Nedelecs start at 1!"

        # Get dimension
        d = cell.get_spatial_dimension()

        # Construct polynomial basis for d-vector fields
        Ps = ONPolynomialSet(cell, k, (d, ))

        # Construct dual space
        Ls = NedelecSecondKindDual(cell, k, variant, quad_deg)

        # Set form degree
        formdegree = 1  # 1-form

        # Set mapping
        mapping = "covariant piola"

        # Call init of super-class
        super(NedelecSecondKind, self).__init__(Ps,
                                                Ls,
                                                k,
                                                formdegree,
                                                mapping=mapping)
Exemplo n.º 4
0
    def __init__(self, cell, degree=3):
        assert degree == 3, "Only defined for degree 3"
        assert cell.get_spatial_dimension(
        ) == 2, "Only defined for dimension 2"
        # polynomial space
        Ps = ONPolynomialSet(cell, degree, (2, ))

        # degrees of freedom
        Ls = MardalTaiWintherDual(cell, degree)

        # mapping under affine transformation
        mapping = "contravariant piola"

        super(MardalTaiWinther, self).__init__(Ps, Ls, degree, mapping=mapping)
Exemplo n.º 5
0
    def __init__(self, cell, degree):
        if not degree == 3:
            raise ValueError("Arnold-Winther elements are"
                             "only defined for degree 3.")
        dofs = []
        dof_ids = {}
        dof_ids[0] = {0: [], 1: [], 2: []}
        dof_ids[1] = {0: [], 1: [], 2: []}
        dof_ids[2] = {0: []}

        dof_cur = 0

        # vertex dofs
        vs = cell.get_vertices()
        e1 = numpy.array([1.0, 0.0])
        e2 = numpy.array([0.0, 1.0])
        basis = [(e1, e1), (e1, e2), (e2, e2)]

        dof_cur = 0

        for entity_id in range(3):
            node = tuple(vs[entity_id])
            for (v1, v2) in basis:
                dofs.append(InnerProduct(cell, v1, v2, node))
            dof_ids[0][entity_id] = list(range(dof_cur, dof_cur + 3))
            dof_cur += 3

        # edge dofs now
        # moments of normal . sigma against constants and linears.
        for entity_id in range(3):
            for order in (0, 1):
                dofs += [
                    IntegralLegendreNormalNormalMoment(cell, entity_id, order,
                                                       6),
                    IntegralLegendreNormalTangentialMoment(
                        cell, entity_id, order, 6)
                ]
            dof_ids[1][entity_id] = list(range(dof_cur, dof_cur + 4))
            dof_cur += 4

        # internal dofs: constant moments of three unique components
        Q = make_quadrature(cell, 3)

        e1 = numpy.array([1.0, 0.0])  # euclidean basis 1
        e2 = numpy.array([0.0, 1.0])  # euclidean basis 2
        basis = [(e1, e1), (e1, e2), (e2, e2)]  # basis for symmetric matrices
        for (v1, v2) in basis:
            v1v2t = numpy.outer(v1, v2)
            fatqp = numpy.zeros((2, 2, len(Q.pts)))
            for k in range(len(Q.pts)):
                fatqp[:, :, k] = v1v2t
            dofs.append(FIM(cell, Q, fatqp))
        dof_ids[2][0] = list(range(dof_cur, dof_cur + 3))
        dof_cur += 3

        # Constraint dofs

        Q = make_quadrature(cell, 5)

        onp = ONPolynomialSet(cell, 2, (2, ))
        pts = Q.get_points()
        onpvals = onp.tabulate(pts)[0, 0]

        for i in list(range(3, 6)) + list(range(9, 12)):
            dofs.append(
                IntegralMomentOfTensorDivergence(cell, Q, onpvals[i, :, :]))

        dof_ids[2][0] += list(range(dof_cur, dof_cur + 6))

        super(ArnoldWintherDual, self).__init__(dofs, cell, dof_ids)
 def __init__(self, cell, order):
     assert cell == UFCInterval() and order == 3
     poly_set = ONPolynomialSet(cell, 3)
     dual_set = P3IntMomentsDualSet(cell, 3)
     super().__init__(poly_set, dual_set, 3, 0)