Example #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)
Example #2
0
def NedelecSpace2D(ref_el, k):
    """Constructs a basis for the 2d H(curl) space of the first kind
    which is (P_k)^2 + P_k rot( x )"""
    sd = ref_el.get_spatial_dimension()
    if sd != 2:
        raise Exception("NedelecSpace2D requires 2d reference element")

    vec_Pkp1 = ONPolynomialSet(ref_el, k + 1, (sd, ))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)

    vec_Pk_indices = list(
        chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk) for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = ONPolynomialSet(ref_el, k + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * k + 2)

    Qpts = np.array(Q.get_points())
    Qwts = np.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkH_crossx_coeffs = np.zeros(
        (PkH.get_num_members(), sd, Pkp1.get_num_members()), "d")

    def rot_x_foo(a):
        if a == 0:
            return 1, 1.0
        elif a == 1:
            return 0, -1.0

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            (ind, sign) = rot_x_foo(j)
            for k in range(Pkp1.get_num_members()):
                PkH_crossx_coeffs[i, j, k] = sign * sum(
                    Qwts * PkH_at_Qpts[i, :] * Qpts[:, ind] *
                    Pkp1_at_Qpts[k, :])


#                for l in range( len( Qpts ) ):
#                    PkH_crossx_coeffs[i,j,k] += Qwts[ l ] \
#                                                * PkH_at_Qpts[i,l] \
#                                                * Qpts[l][ind] \
#                                                * Pkp1_at_Qpts[k,l] \
#                                                * sign

    PkHcrossx = PolynomialSet(ref_el, k + 1, k + 1,
                              vec_Pkp1.get_expansion_set(), PkH_crossx_coeffs,
                              vec_Pkp1.get_dmats())

    return polynomial_set_union_normalized(vec_Pk_from_Pkp1, PkHcrossx)
    def _generate_cell_dofs(self, cell, degree, offset):
        """Generate degrees of freedoms (dofs) for entities of
        codimension d (cells)."""

        # Return empty info if not applicable
        d = cell.get_spatial_dimension()
        if (d == 2 and degree < 2) or (d == 3 and degree < 3):
            return ([], {0: []})

        # Create quadrature points
        Q = make_quadrature(cell, 2 * (degree + 1))
        qs = Q.get_points()

        # Create Raviart-Thomas nodal basis
        RT = RaviartThomas(cell, degree + 1 - d)
        phi = RT.get_nodal_basis()

        # Evaluate Raviart-Thomas basis at quadrature points
        phi_at_qs = phi.tabulate(qs)[(0,) * d]

        # Use (Frobenius) integral moments against RTs as dofs
        dofs = [IntegralMoment(cell, Q, phi_at_qs[i, :])
                for i in range(len(phi_at_qs))]

        # Associate these dofs with the interior
        ids = {0: list(range(offset, offset + len(dofs)))}
        return (dofs, ids)
Example #4
0
    def _generate_cell_dofs(self, cell, degree, offset, variant, quad_deg):
        """Generate degrees of freedoms (dofs) for entities of
        codimension d (cells)."""

        # Return empty info if not applicable
        d = cell.get_spatial_dimension()
        if (d == 2 and degree < 2) or (d == 3 and degree < 3):
            return ([], {0: []})

        # Create quadrature points
        Q = make_quadrature(cell, 2 * (degree + 1))
        qs = Q.get_points()

        # Create Raviart-Thomas nodal basis
        RT = RaviartThomas(cell, degree + 1 - d, variant)
        phi = RT.get_nodal_basis()

        # Evaluate Raviart-Thomas basis at quadrature points
        phi_at_qs = phi.tabulate(qs)[(0,) * d]

        # Use (Frobenius) integral moments against RTs as dofs
        dofs = [IntegralMoment(cell, Q, phi_at_qs[i, :])
                for i in range(len(phi_at_qs))]

        # Associate these dofs with the interior
        ids = {0: list(range(offset, offset + len(dofs)))}
        return (dofs, ids)
Example #5
0
    def _generate_edge_dofs(self, cell, degree, offset, variant, quad_deg):
        """Generate degrees of freedoms (dofs) for entities of
        codimension 1 (edges)."""

        # (degree+1) tangential component point evaluation degrees of
        # freedom per entity of codimension 1 (edges)
        dofs = []
        ids = {}

        if variant == "integral":
            edge = cell.construct_subelement(1)
            Q = quadrature.make_quadrature(edge, quad_deg)
            Pq = polynomial_set.ONPolynomialSet(edge, degree)
            Pq_at_qpts = Pq.tabulate(Q.get_points())[tuple([0]*(1))]
            for e in range(len(cell.get_topology()[1])):
                for i in range(Pq_at_qpts.shape[0]):
                    phi = Pq_at_qpts[i, :]
                    dofs.append(functional.IntegralMomentOfEdgeTangentEvaluation(cell, Q, phi, e))
                jj = Pq_at_qpts.shape[0] * e
                ids[e] = list(range(offset + jj, offset + jj + Pq_at_qpts.shape[0]))

        elif variant == "point":
            for edge in range(len(cell.get_topology()[1])):

                # Create points for evaluation of tangential components
                points = cell.make_points(1, edge, degree + 2)

                # A tangential component evaluation for each point
                dofs += [Tangent(cell, edge, point) for point in points]

                # Associate these dofs with this edge
                i = len(points) * edge
                ids[edge] = list(range(offset + i, offset + i + len(points)))

        return (dofs, ids)
Example #6
0
    def __init__(self, ref_el, degree):
        nodes = []
        dim = ref_el.get_spatial_dimension()

        Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))

        f_at_qpts = numpy.ones(len(Q.wts))
        nodes.append(functional.IntegralMoment(ref_el, Q, f_at_qpts))

        vertices = ref_el.get_vertices()
        midpoint = tuple(sum(numpy.array(vertices)) / len(vertices))
        for k in range(1, degree + 1):
            # Loop over all multi-indices of degree k.
            for alpha in mis(dim, k):
                nodes.append(
                    functional.PointDerivative(ref_el, midpoint, alpha))

        entity_ids = {
            d: {e: []
                for e in ref_el.sub_entities[d]}
            for d in range(dim + 1)
        }
        entity_ids[dim][0] = list(range(len(nodes)))

        super(DiscontinuousTaylorDualSet,
              self).__init__(nodes, ref_el, entity_ids)
Example #7
0
def _fiat_scheme(ref_el, degree):
    """Get quadrature scheme from FIAT interface"""

    # Number of points per axis for exact integration
    num_points_per_axis = (degree + 1 + 1) // 2

    # Create and return FIAT quadrature rule
    return make_quadrature(ref_el, num_points_per_axis)
Example #8
0
    def __init__(self, ref_el, degree):

        # Initialize containers for map: mesh_entity -> dof number and
        # dual basis
        entity_ids = {}
        nodes = []

        sd = ref_el.get_spatial_dimension()
        t = ref_el.get_topology()

        # Define each functional for the dual set
        # codimension 1 facets
        for i in range(len(t[sd - 1])):
            pts_cur = ref_el.make_points(sd - 1, i, sd + degree)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointScaledNormalEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        # internal nodes
        if degree > 1:
            Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
            qpts = Q.get_points()
            Nedel = nedelec.Nedelec(ref_el, degree - 1)
            Nedfs = Nedel.get_nodal_basis()
            zero_index = tuple([0 for i in range(sd)])
            Ned_at_qpts = Nedfs.tabulate(qpts)[zero_index]

            for i in range(len(Ned_at_qpts)):
                phi_cur = Ned_at_qpts[i, :]
                l_cur = functional.FrobeniusIntegralMoment(ref_el, Q, phi_cur)
                nodes.append(l_cur)

        # sets vertices (and in 3d, edges) to have no nodes
        for i in range(sd - 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # set codimension 1 (edges 2d, faces 3d) dof
        pts_facet_0 = ref_el.make_points(sd - 1, 0, sd + degree)
        pts_per_facet = len(pts_facet_0)

        entity_ids[sd - 1] = {}
        for i in range(len(t[sd - 1])):
            entity_ids[sd - 1][i] = list(range(cur, cur + pts_per_facet))
            cur += pts_per_facet

        # internal nodes, if applicable
        entity_ids[sd] = {0: []}

        if degree > 1:
            num_internal_nodes = len(Ned_at_qpts)
            entity_ids[sd][0] = list(range(cur, cur + num_internal_nodes))

        super().__init__(nodes, ref_el, entity_ids)
Example #9
0
    def __init__(self, ref_el, degree):

        # Initialize containers for map: mesh_entity -> dof number and
        # dual basis
        entity_ids = {}
        nodes = []

        sd = ref_el.get_spatial_dimension()
        t = ref_el.get_topology()

        # Define each functional for the dual set
        # codimension 1 facets
        for i in range(len(t[sd - 1])):
            pts_cur = ref_el.make_points(sd - 1, i, sd + degree)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointScaledNormalEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        # internal nodes
        if degree > 1:
            Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
            qpts = Q.get_points()
            Nedel = nedelec.Nedelec(ref_el, degree - 1)
            Nedfs = Nedel.get_nodal_basis()
            zero_index = tuple([0 for i in range(sd)])
            Ned_at_qpts = Nedfs.tabulate(qpts)[zero_index]

            for i in range(len(Ned_at_qpts)):
                phi_cur = Ned_at_qpts[i, :]
                l_cur = functional.FrobeniusIntegralMoment(ref_el, Q, phi_cur)
                nodes.append(l_cur)

        # sets vertices (and in 3d, edges) to have no nodes
        for i in range(sd - 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # set codimension 1 (edges 2d, faces 3d) dof
        pts_facet_0 = ref_el.make_points(sd - 1, 0, sd + degree)
        pts_per_facet = len(pts_facet_0)

        entity_ids[sd - 1] = {}
        for i in range(len(t[sd - 1])):
            entity_ids[sd - 1][i] = list(range(cur, cur + pts_per_facet))
            cur += pts_per_facet

        # internal nodes, if applicable
        entity_ids[sd] = {0: []}

        if degree > 1:
            num_internal_nodes = len(Ned_at_qpts)
            entity_ids[sd][0] = list(range(cur, cur + num_internal_nodes))

        super(BDMDualSet, self).__init__(nodes, ref_el, entity_ids)
Example #10
0
    def __init__(self, ref_el, degree):
        sd = ref_el.get_spatial_dimension()
        if sd != 2:
            raise Exception("Nedelec2D only works on triangles")

        nodes = []

        t = ref_el.get_topology()

        num_edges = len(t[1])

        # edge tangents
        for i in range(num_edges):
            pts_cur = ref_el.make_points(1, i, degree + 2)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointEdgeTangentEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        # internal moments
        if degree > 0:
            Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
            qpts = Q.get_points()
            Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
            zero_index = tuple([0 for i in range(sd)])
            Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

            for d in range(sd):
                for i in range(Pkm1_at_qpts.shape[0]):
                    phi_cur = Pkm1_at_qpts[i, :]
                    l_cur = functional.IntegralMoment(ref_el, Q, phi_cur,
                                                      (d, ))
                    nodes.append(l_cur)

        entity_ids = {}

        # set to empty
        for i in range(sd + 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # edges
        num_edge_pts = len(ref_el.make_points(1, 0, degree + 2))

        for i in range(len(t[1])):
            entity_ids[1][i] = list(range(cur, cur + num_edge_pts))
            cur += num_edge_pts

        # moments against P_{degree-1} internally, if degree > 0
        if degree > 0:
            num_internal_dof = sd * Pkm1_at_qpts.shape[0]
            entity_ids[2][0] = list(range(cur, cur + num_internal_dof))

        super(NedelecDual2D, self).__init__(nodes, ref_el, entity_ids)
Example #11
0
    def __init__(self, ref_el, degree):
        sd = ref_el.get_spatial_dimension()
        if sd != 2:
            raise Exception("Nedelec2D only works on triangles")

        nodes = []

        t = ref_el.get_topology()

        num_edges = len(t[1])

        # edge tangents
        for i in range(num_edges):
            pts_cur = ref_el.make_points(1, i, degree + 2)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointEdgeTangentEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        # internal moments
        if degree > 0:
            Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
            qpts = Q.get_points()
            Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
            zero_index = tuple([0 for i in range(sd)])
            Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

            for d in range(sd):
                for i in range(Pkm1_at_qpts.shape[0]):
                    phi_cur = Pkm1_at_qpts[i, :]
                    l_cur = functional.IntegralMoment(ref_el, Q, phi_cur, (d,))
                    nodes.append(l_cur)

        entity_ids = {}

        # set to empty
        for i in range(sd + 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # edges
        num_edge_pts = len(ref_el.make_points(1, 0, degree + 2))

        for i in range(len(t[1])):
            entity_ids[1][i] = list(range(cur, cur + num_edge_pts))
            cur += num_edge_pts

        # moments against P_{degree-1} internally, if degree > 0
        if degree > 0:
            num_internal_dof = sd * Pkm1_at_qpts.shape[0]
            entity_ids[2][0] = list(range(cur, cur + num_internal_dof))

        super(NedelecDual2D, self).__init__(nodes, ref_el, entity_ids)
 def __init__(self, cell, order):
     assert cell == UFCInterval() and order == 3
     entity_ids = {0: {0: [0], 1: [1]}, 1: {0: [2, 3]}}
     vertnodes = [PointEvaluation(cell, xx) for xx in cell.vertices]
     Q = make_quadrature(cell, 3)
     # 1st integral moment node is integral(1*f(x)*dx)
     ones = np.asarray([1.0 for x in Q.pts])
     # 2nd integral moment node is integral(x*f(x)*dx)
     xs = np.asarray([x for (x, ) in Q.pts])
     intnodes = [IntegralMoment(cell, Q, ones), IntegralMoment(cell, Q, xs)]
     nodes = vertnodes + intnodes
     super().__init__(nodes, cell, entity_ids)
Example #13
0
    def __init__(self, cell, degree):
        if not degree == 2:
            raise ValueError("Nonconforming Arnold-Winther elements are"
                             "only defined for degree 2.")
        dofs = []
        dof_ids = {}
        dof_ids[0] = {0: [], 1: [], 2: []}
        dof_ids[1] = {0: [], 1: [], 2: []}
        dof_ids[2] = {0: []}

        dof_cur = 0
        # no vertex dofs
        # proper edge dofs now (not the contraints)
        # moments of normal . sigma against constants and linears.
        for entity_id in range(3):  # a triangle has 3 edges
            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, 2)

        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 i, y in enumerate(v1v2t):
                for j, x in enumerate(y):
                    for k in range(len(Q.pts)):
                        fatqp[i, j, k] = x
            dofs.append(FIM(cell, Q, fatqp))
        dof_ids[2][0] = list(range(dof_cur, dof_cur + 3))
        dof_cur += 3

        # put the constraint dofs last.
        for entity_id in range(3):
            dof = IntegralLegendreNormalNormalMoment(cell, entity_id, 2, 6)
            dofs.append(dof)
            dof_ids[1][entity_id].append(dof_cur)
            dof_cur += 1

        super(ArnoldWintherNCDual, self).__init__(dofs, cell, dof_ids)
Example #14
0
    def _setupQuadrature(self):
        """
    Setup quadrature rule for reference cell.
    """
        from FIAT.reference_element import default_simplex
        from FIAT.quadrature import make_quadrature
        from FIATQuadrature import CollocatedQuadratureRule

        if not self.collocateQuad:
            q = make_quadrature(default_simplex(1), self.order)
        else:
            q = CollocatedQuadratureRule(default_simplex(1), self.order)

        return q
Example #15
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
Example #16
0
def _fiat_scheme(ref_el, degree):
    """Get quadrature scheme from FIAT interface"""

    # Number of points per axis for exact integration
    num_points_per_axis = (degree + 1 + 1) // 2

    # Check for excess
    if num_points_per_axis > 30:
        dim = ref_el.get_spatial_dimension()
        raise RuntimeError("Requested a quadrature rule with %d points per direction (%d points)" %
                           (num_points_per_axis, num_points_per_axis**dim))

    # Create and return FIAT quadrature rule
    return make_quadrature(ref_el, num_points_per_axis)
Example #17
0
  def _setupQuadrature(self):
    """
    Setup quadrature rule for reference cell.
    """
    from FIAT.reference_element import default_simplex
    from FIAT.quadrature import make_quadrature
    from FIATQuadrature import CollocatedQuadratureRule
      
    if not self.collocateQuad:
      q = make_quadrature(default_simplex(1), self.order)
    else:
      q = CollocatedQuadratureRule(default_simplex(1), self.order)

    return q
Example #18
0
def RTSpace(ref_el, deg):
    """Constructs a basis for the the Raviart-Thomas space
    (P_k)^d + P_k x"""
    sd = ref_el.get_spatial_dimension()

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, deg + 1)
    dimPk = expansions.polynomial_dimension(ref_el, deg)
    dimPkm1 = expansions.polynomial_dimension(ref_el, deg - 1)

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * deg + 2)

    # have to work on this through "tabulate" interface
    # first, tabulate PkH at quadrature points
    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkHx_coeffs = numpy.zeros((PkH.get_num_members(),
                               sd,
                               Pkp1.get_num_members()), "d")

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            fooij = PkH_at_Qpts[i, :] * Qpts[:, j] * Qwts
            PkHx_coeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, fooij)

    PkHx = polynomial_set.PolynomialSet(ref_el,
                                        deg,
                                        deg + 1,
                                        vec_Pkp1.get_expansion_set(),
                                        PkHx_coeffs,
                                        vec_Pkp1.get_dmats())

    return polynomial_set.polynomial_set_union_normalized(vec_Pk_from_Pkp1, PkHx)
Example #19
0
def RTSpace(ref_el, deg):
    """Constructs a basis for the the Raviart-Thomas space
    (P_k)^d + P_k x"""
    sd = ref_el.get_spatial_dimension()

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, deg + 1)
    dimPk = expansions.polynomial_dimension(ref_el, deg)
    dimPkm1 = expansions.polynomial_dimension(ref_el, deg - 1)

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * deg + 2)

    # have to work on this through "tabulate" interface
    # first, tabulate PkH at quadrature points
    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkHx_coeffs = numpy.zeros((PkH.get_num_members(),
                               sd,
                               Pkp1.get_num_members()), "d")

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            fooij = PkH_at_Qpts[i, :] * Qpts[:, j] * Qwts
            PkHx_coeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, fooij)

    PkHx = polynomial_set.PolynomialSet(ref_el,
                                        deg,
                                        deg + 1,
                                        vec_Pkp1.get_expansion_set(),
                                        PkHx_coeffs,
                                        vec_Pkp1.get_dmats())

    return polynomial_set.polynomial_set_union_normalized(vec_Pk_from_Pkp1, PkHx)
Example #20
0
    def __init__(self, ref_el, degree):
        nodes = []
        dim = ref_el.get_spatial_dimension()

        Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))

        f_at_qpts = numpy.ones(len(Q.wts))
        nodes.append(functional.IntegralMoment(ref_el, Q, f_at_qpts))

        vertices = ref_el.get_vertices()
        midpoint = tuple(sum(numpy.array(vertices)) / len(vertices))
        for k in range(1, degree + 1):
            # Loop over all multi-indices of degree k.
            for alpha in mis(dim, k):
                nodes.append(functional.PointDerivative(ref_el, midpoint, alpha))

        entity_ids = {d: {e: [] for e in ref_el.sub_entities[d]}
                      for d in range(dim + 1)}
        entity_ids[dim][0] = list(range(len(nodes)))

        super(DiscontinuousTaylorDualSet, self).__init__(nodes, ref_el, entity_ids)
Example #21
0
    def __init__(self, ref_el, degree, variant, quad_deg):

        # Initialize containers for map: mesh_entity -> dof number and
        # dual basis
        entity_ids = {}
        nodes = []

        sd = ref_el.get_spatial_dimension()
        t = ref_el.get_topology()

        if variant == "integral":
            facet = ref_el.get_facet_element()
            # Facet nodes are \int_F v\cdot n p ds where p \in P_{q-1}
            # degree is q - 1
            Q = quadrature.make_quadrature(facet, quad_deg)
            Pq = polynomial_set.ONPolynomialSet(facet, degree)
            Pq_at_qpts = Pq.tabulate(Q.get_points())[tuple([0] * (sd - 1))]
            for f in range(len(t[sd - 1])):
                for i in range(Pq_at_qpts.shape[0]):
                    phi = Pq_at_qpts[i, :]
                    nodes.append(
                        functional.IntegralMomentOfScaledNormalEvaluation(
                            ref_el, Q, phi, f))

            # internal nodes
            if degree > 1:
                Q = quadrature.make_quadrature(ref_el, quad_deg)
                qpts = Q.get_points()
                Nedel = nedelec.Nedelec(ref_el, degree - 1, variant)
                Nedfs = Nedel.get_nodal_basis()
                zero_index = tuple([0 for i in range(sd)])
                Ned_at_qpts = Nedfs.tabulate(qpts)[zero_index]

                for i in range(len(Ned_at_qpts)):
                    phi_cur = Ned_at_qpts[i, :]
                    l_cur = functional.FrobeniusIntegralMoment(
                        ref_el, Q, phi_cur)
                    nodes.append(l_cur)

        elif variant == "point":
            # Define each functional for the dual set
            # codimension 1 facets
            for i in range(len(t[sd - 1])):
                pts_cur = ref_el.make_points(sd - 1, i, sd + degree)
                for j in range(len(pts_cur)):
                    pt_cur = pts_cur[j]
                    f = functional.PointScaledNormalEvaluation(
                        ref_el, i, pt_cur)
                    nodes.append(f)

            # internal nodes
            if degree > 1:
                Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
                qpts = Q.get_points()
                Nedel = nedelec.Nedelec(ref_el, degree - 1, variant)
                Nedfs = Nedel.get_nodal_basis()
                zero_index = tuple([0 for i in range(sd)])
                Ned_at_qpts = Nedfs.tabulate(qpts)[zero_index]

                for i in range(len(Ned_at_qpts)):
                    phi_cur = Ned_at_qpts[i, :]
                    l_cur = functional.FrobeniusIntegralMoment(
                        ref_el, Q, phi_cur)
                    nodes.append(l_cur)

        # sets vertices (and in 3d, edges) to have no nodes
        for i in range(sd - 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # set codimension 1 (edges 2d, faces 3d) dof
        pts_facet_0 = ref_el.make_points(sd - 1, 0, sd + degree)
        pts_per_facet = len(pts_facet_0)

        entity_ids[sd - 1] = {}
        for i in range(len(t[sd - 1])):
            entity_ids[sd - 1][i] = list(range(cur, cur + pts_per_facet))
            cur += pts_per_facet

        # internal nodes, if applicable
        entity_ids[sd] = {0: []}

        if degree > 1:
            num_internal_nodes = len(Ned_at_qpts)
            entity_ids[sd][0] = list(range(cur, cur + num_internal_nodes))

        super(BDMDualSet, self).__init__(nodes, ref_el, entity_ids)
Example #22
0
    def __init__(self, ref_el, degree):
        sd = ref_el.get_spatial_dimension()
        if sd != 3:
            raise Exception("NedelecDual3D only works on tetrahedra")

        nodes = []

        t = ref_el.get_topology()

        # how many edges
        num_edges = len(t[1])

        for i in range(num_edges):
            # points to specify P_k on each edge
            pts_cur = ref_el.make_points(1, i, degree + 2)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointEdgeTangentEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        if degree > 0:  # face tangents
            num_faces = len(t[2])
            for i in range(num_faces):  # loop over faces
                pts_cur = ref_el.make_points(2, i, degree + 2)
                for j in range(len(pts_cur)):  # loop over points
                    pt_cur = pts_cur[j]
                    for k in range(2):  # loop over tangents
                        f = functional.PointFaceTangentEvaluation(ref_el, i, k, pt_cur)
                        nodes.append(f)

        if degree > 1:  # internal moments
            Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
            qpts = Q.get_points()
            Pkm2 = polynomial_set.ONPolynomialSet(ref_el, degree - 2)
            zero_index = tuple([0 for i in range(sd)])
            Pkm2_at_qpts = Pkm2.tabulate(qpts)[zero_index]

            for d in range(sd):
                for i in range(Pkm2_at_qpts.shape[0]):
                    phi_cur = Pkm2_at_qpts[i, :]
                    f = functional.IntegralMoment(ref_el, Q, phi_cur, (d,))
                    nodes.append(f)

        entity_ids = {}
        # set to empty
        for i in range(sd + 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # edge dof
        num_pts_per_edge = len(ref_el.make_points(1, 0, degree + 2))
        for i in range(len(t[1])):
            entity_ids[1][i] = list(range(cur, cur + num_pts_per_edge))
            cur += num_pts_per_edge

        # face dof
        if degree > 0:
            num_pts_per_face = len(ref_el.make_points(2, 0, degree + 2))
            for i in range(len(t[2])):
                entity_ids[2][i] = list(range(cur, cur + 2 * num_pts_per_face))
                cur += 2 * num_pts_per_face

        if degree > 1:
            num_internal_dof = Pkm2_at_qpts.shape[0] * sd
            entity_ids[3][0] = list(range(cur, cur + num_internal_dof))

        super(NedelecDual3D, self).__init__(nodes, ref_el, entity_ids)
Example #23
0
    def __init__(self, ref_el, degree, variant, quad_deg):
        entity_ids = {}
        nodes = []

        sd = ref_el.get_spatial_dimension()
        t = ref_el.get_topology()

        if variant == "integral":
            facet = ref_el.get_facet_element()
            # Facet nodes are \int_F v\cdot n p ds where p \in P_{q-1}
            # degree is q - 1
            Q = quadrature.make_quadrature(facet, quad_deg)
            Pq = polynomial_set.ONPolynomialSet(facet, degree)
            Pq_at_qpts = Pq.tabulate(Q.get_points())[tuple([0] * (sd - 1))]
            for f in range(len(t[sd - 1])):
                for i in range(Pq_at_qpts.shape[0]):
                    phi = Pq_at_qpts[i, :]
                    nodes.append(
                        functional.IntegralMomentOfScaledNormalEvaluation(
                            ref_el, Q, phi, f))

            # internal nodes. These are \int_T v \cdot p dx where p \in P_{q-2}^d
            if degree > 0:
                Q = quadrature.make_quadrature(ref_el, quad_deg)
                qpts = Q.get_points()
                Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
                zero_index = tuple([0 for i in range(sd)])
                Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

                for d in range(sd):
                    for i in range(Pkm1_at_qpts.shape[0]):
                        phi_cur = Pkm1_at_qpts[i, :]
                        l_cur = functional.IntegralMoment(
                            ref_el, Q, phi_cur, (d, ), (sd, ))
                        nodes.append(l_cur)

        elif variant == "point":
            # codimension 1 facets
            for i in range(len(t[sd - 1])):
                pts_cur = ref_el.make_points(sd - 1, i, sd + degree)
                for j in range(len(pts_cur)):
                    pt_cur = pts_cur[j]
                    f = functional.PointScaledNormalEvaluation(
                        ref_el, i, pt_cur)
                    nodes.append(f)

            # internal nodes.  Let's just use points at a lattice
            if degree > 0:
                cpe = functional.ComponentPointEvaluation
                pts = ref_el.make_points(sd, 0, degree + sd)
                for d in range(sd):
                    for i in range(len(pts)):
                        l_cur = cpe(ref_el, d, (sd, ), pts[i])
                        nodes.append(l_cur)

        # sets vertices (and in 3d, edges) to have no nodes
        for i in range(sd - 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # set codimension 1 (edges 2d, faces 3d) dof
        pts_facet_0 = ref_el.make_points(sd - 1, 0, sd + degree)
        pts_per_facet = len(pts_facet_0)
        entity_ids[sd - 1] = {}
        for i in range(len(t[sd - 1])):
            entity_ids[sd - 1][i] = list(range(cur, cur + pts_per_facet))
            cur += pts_per_facet

        # internal nodes, if applicable
        entity_ids[sd] = {0: []}
        if degree > 0:
            num_internal_nodes = expansions.polynomial_dimension(
                ref_el, degree - 1)
            entity_ids[sd][0] = list(range(cur, cur + num_internal_nodes * sd))

        super(RTDualSet, self).__init__(nodes, ref_el, entity_ids)
Example #24
0
            "text.usetex": True,
            "linewidth": 4,
            "figure.figsize": fig_size,
        }
    )
    # subplots_adjust(left=0.06,right=0.975,bottom=0.08,top=0.94)
    subplots_adjust(left=0.15, right=0.95, bottom=0.06, top=0.95)


set_sizes_talk()
rcParams.update({"backend": "png"})
m = 5
n = 100
u = Lagrange.Lagrange(1, m, shapes.line_point_family_lgl)
ufs = u.function_space()
q = quadrature.make_quadrature(1, n)
x = q.get_points()
t = ufs.tabulate_jet(1, x)
B = t[0][(0,)]
D = t[1][(1,)]
subplot(211)
p = [plot(x, B[i], linewidth=2) for i in range(m + 1)]
ylabel("Basis functions")
# xlabel('$\hat{x}$')
subplot(212)
p = [plot(x, D[i], linewidth=2) for i in range(m + 1)]
ylim(-10, 10)
ylabel("Derivatives")
xlabel("$\hat{x}$")
savefig("lgl.png")
Example #25
0
def NedelecSpace3D(ref_el, k):
    """Constructs a nodal basis for the 3d first-kind Nedelec space"""
    sd = ref_el.get_spatial_dimension()
    if sd != 3:
        raise Exception("NedelecSpace3D requires 3d reference element")

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1, (sd, ))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    if k > 0:
        dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)
    else:
        dimPkm1 = 0

    vec_Pk_indices = list(
        chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk) for i in range(sd))))
    vec_Pk = vec_Pkp1.take(vec_Pk_indices)

    vec_Pke_indices = list(
        chain(*(range(i * dimPkp1 + dimPkm1, i * dimPkp1 + dimPk)
                for i in range(sd))))

    vec_Pke = vec_Pkp1.take(vec_Pke_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1)

    Q = quadrature.make_quadrature(ref_el, 2 * (k + 1))

    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkCrossXcoeffs = numpy.zeros(
        (vec_Pke.get_num_members(), sd, Pkp1.get_num_members()), "d")

    Pke_qpts = vec_Pke.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    for i in range(vec_Pke.get_num_members()):
        for j in range(sd):  # vector components
            qwts_cur_bf_val = (
                Qpts[:, (j + 2) % 3] * Pke_qpts[i, (j + 1) % 3, :] -
                Qpts[:, (j + 1) % 3] * Pke_qpts[i, (j + 2) % 3, :]) * Qwts
            PkCrossXcoeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, qwts_cur_bf_val)


#            for k in range( Pkp1.get_num_members() ):
#                 PkCrossXcoeffs[i,j,k] = sum( Qwts * cur_bf_val * Pkp1_at_Qpts[k,:] )
#                for l in range( len( Qpts ) ):
#                    cur_bf_val = Qpts[l][(j+2)%3] \
#                                 * Pke_qpts[i,(j+1)%3,l] \
#                                 - Qpts[l][(j+1)%3] \
#                                 * Pke_qpts[i,(j+2)%3,l]
#                    PkCrossXcoeffs[i,j,k] += Qwts[l] \
#                                             * cur_bf_val \
#                                             * Pkp1_at_Qpts[k,l]

    PkCrossX = polynomial_set.PolynomialSet(ref_el, k + 1, k + 1,
                                            vec_Pkp1.get_expansion_set(),
                                            PkCrossXcoeffs,
                                            vec_Pkp1.get_dmats())
    return polynomial_set.polynomial_set_union_normalized(vec_Pk, PkCrossX)
Example #26
0
    def __init__(self, ref_el, degree):
        sd = ref_el.get_spatial_dimension()
        if sd != 3:
            raise Exception("NedelecDual3D only works on tetrahedra")

        nodes = []

        t = ref_el.get_topology()

        # how many edges
        num_edges = len(t[1])

        for i in range(num_edges):
            # points to specify P_k on each edge
            pts_cur = ref_el.make_points(1, i, degree + 2)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointEdgeTangentEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        if degree > 0:  # face tangents
            num_faces = len(t[2])
            for i in range(num_faces):  # loop over faces
                pts_cur = ref_el.make_points(2, i, degree + 2)
                for j in range(len(pts_cur)):  # loop over points
                    pt_cur = pts_cur[j]
                    for k in range(2):  # loop over tangents
                        f = functional.PointFaceTangentEvaluation(
                            ref_el, i, k, pt_cur)
                        nodes.append(f)

        if degree > 1:  # internal moments
            Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
            qpts = Q.get_points()
            Pkm2 = polynomial_set.ONPolynomialSet(ref_el, degree - 2)
            zero_index = tuple([0 for i in range(sd)])
            Pkm2_at_qpts = Pkm2.tabulate(qpts)[zero_index]

            for d in range(sd):
                for i in range(Pkm2_at_qpts.shape[0]):
                    phi_cur = Pkm2_at_qpts[i, :]
                    f = functional.IntegralMoment(ref_el, Q, phi_cur, (d, ))
                    nodes.append(f)

        entity_ids = {}
        # set to empty
        for i in range(sd + 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # edge dof
        num_pts_per_edge = len(ref_el.make_points(1, 0, degree + 2))
        for i in range(len(t[1])):
            entity_ids[1][i] = list(range(cur, cur + num_pts_per_edge))
            cur += num_pts_per_edge

        # face dof
        if degree > 0:
            num_pts_per_face = len(ref_el.make_points(2, 0, degree + 2))
            for i in range(len(t[2])):
                entity_ids[2][i] = list(range(cur, cur + 2 * num_pts_per_face))
                cur += 2 * num_pts_per_face

        if degree > 1:
            num_internal_dof = Pkm2_at_qpts.shape[0] * sd
            entity_ids[3][0] = list(range(cur, cur + num_internal_dof))

        super(NedelecDual3D, self).__init__(nodes, ref_el, entity_ids)
Example #27
0
    def __init__(self, ref_el, degree, variant, quad_deg):
        sd = ref_el.get_spatial_dimension()
        if sd != 3:
            raise Exception("NedelecDual3D only works on tetrahedra")

        nodes = []

        t = ref_el.get_topology()

        if variant == "integral":
            # edge nodes are \int_F v\cdot t p ds where p \in P_{q-1}(edge)
            # degree is q - 1
            edge = ref_el.get_facet_element().get_facet_element()
            Q = quadrature.make_quadrature(edge, quad_deg)
            Pq = polynomial_set.ONPolynomialSet(edge, degree)
            Pq_at_qpts = Pq.tabulate(Q.get_points())[tuple([0] * (1))]
            for e in range(len(t[1])):
                for i in range(Pq_at_qpts.shape[0]):
                    phi = Pq_at_qpts[i, :]
                    nodes.append(
                        functional.IntegralMomentOfEdgeTangentEvaluation(
                            ref_el, Q, phi, e))

            # face nodes are \int_F v\cdot p dA where p \in P_{q-2}(f)^3 with p \cdot n = 0 (cmp. Monk)
            # these are equivalent to dofs from Fenics book defined by
            # \int_F v\times n \cdot p ds where p \in P_{q-2}(f)^2
            if degree > 0:
                facet = ref_el.get_facet_element()
                Q = quadrature.make_quadrature(facet, quad_deg)
                Pq = polynomial_set.ONPolynomialSet(facet, degree - 1, (sd, ))
                Pq_at_qpts = Pq.tabulate(Q.get_points())[(0, 0)]

                for f in range(len(t[2])):
                    # R is used to map [1,0,0] to tangent1 and [0,1,0] to tangent2
                    R = ref_el.compute_face_tangents(f)

                    # Skip last functionals because we only want p with p \cdot n = 0
                    for i in range(2 * Pq.get_num_members() // 3):
                        phi = Pq_at_qpts[i, ...]
                        phi = numpy.matmul(phi[:-1, ...].T, R)
                        nodes.append(
                            functional.MonkIntegralMoment(ref_el, Q, phi, f))

            # internal nodes. These are \int_T v \cdot p dx where p \in P_{q-3}^3(T)
            if degree > 1:
                Q = quadrature.make_quadrature(ref_el, quad_deg)
                qpts = Q.get_points()
                Pkm2 = polynomial_set.ONPolynomialSet(ref_el, degree - 2)
                zero_index = tuple([0 for i in range(sd)])
                Pkm2_at_qpts = Pkm2.tabulate(qpts)[zero_index]

                for d in range(sd):
                    for i in range(Pkm2_at_qpts.shape[0]):
                        phi_cur = Pkm2_at_qpts[i, :]
                        l_cur = functional.IntegralMoment(
                            ref_el, Q, phi_cur, (d, ), (sd, ))
                        nodes.append(l_cur)

        elif variant == "point":
            num_edges = len(t[1])

            for i in range(num_edges):
                # points to specify P_k on each edge
                pts_cur = ref_el.make_points(1, i, degree + 2)
                for j in range(len(pts_cur)):
                    pt_cur = pts_cur[j]
                    f = functional.PointEdgeTangentEvaluation(
                        ref_el, i, pt_cur)
                    nodes.append(f)

            if degree > 0:  # face tangents
                num_faces = len(t[2])
                for i in range(num_faces):  # loop over faces
                    pts_cur = ref_el.make_points(2, i, degree + 2)
                    for j in range(len(pts_cur)):  # loop over points
                        pt_cur = pts_cur[j]
                        for k in range(2):  # loop over tangents
                            f = functional.PointFaceTangentEvaluation(
                                ref_el, i, k, pt_cur)
                            nodes.append(f)

            if degree > 1:  # internal moments
                Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
                qpts = Q.get_points()
                Pkm2 = polynomial_set.ONPolynomialSet(ref_el, degree - 2)
                zero_index = tuple([0 for i in range(sd)])
                Pkm2_at_qpts = Pkm2.tabulate(qpts)[zero_index]

                for d in range(sd):
                    for i in range(Pkm2_at_qpts.shape[0]):
                        phi_cur = Pkm2_at_qpts[i, :]
                        f = functional.IntegralMoment(ref_el, Q, phi_cur,
                                                      (d, ), (sd, ))
                        nodes.append(f)

        entity_ids = {}
        # set to empty
        for i in range(sd + 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # edge dof
        num_pts_per_edge = len(ref_el.make_points(1, 0, degree + 2))
        for i in range(len(t[1])):
            entity_ids[1][i] = list(range(cur, cur + num_pts_per_edge))
            cur += num_pts_per_edge

        # face dof
        if degree > 0:
            num_pts_per_face = len(ref_el.make_points(2, 0, degree + 2))
            for i in range(len(t[2])):
                entity_ids[2][i] = list(range(cur, cur + 2 * num_pts_per_face))
                cur += 2 * num_pts_per_face

        if degree > 1:
            num_internal_dof = Pkm2_at_qpts.shape[0] * sd
            entity_ids[3][0] = list(range(cur, cur + num_internal_dof))

        super(NedelecDual3D, self).__init__(nodes, ref_el, entity_ids)
Example #28
0
    def __init__(self, ref_el, degree, variant, quad_deg):
        sd = ref_el.get_spatial_dimension()
        if sd != 2:
            raise Exception("Nedelec2D only works on triangles")

        nodes = []

        t = ref_el.get_topology()

        if variant == "integral":
            # edge nodes are \int_F v\cdot t p ds where p \in P_{q-1}(edge)
            # degree is q - 1
            edge = ref_el.get_facet_element()
            Q = quadrature.make_quadrature(edge, quad_deg)
            Pq = polynomial_set.ONPolynomialSet(edge, degree)
            Pq_at_qpts = Pq.tabulate(Q.get_points())[tuple([0] * (sd - 1))]
            for e in range(len(t[sd - 1])):
                for i in range(Pq_at_qpts.shape[0]):
                    phi = Pq_at_qpts[i, :]
                    nodes.append(
                        functional.IntegralMomentOfEdgeTangentEvaluation(
                            ref_el, Q, phi, e))

            # internal nodes. These are \int_T v \cdot p dx where p \in P_{q-2}^2
            if degree > 0:
                Q = quadrature.make_quadrature(ref_el, quad_deg)
                qpts = Q.get_points()
                Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
                zero_index = tuple([0 for i in range(sd)])
                Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

                for d in range(sd):
                    for i in range(Pkm1_at_qpts.shape[0]):
                        phi_cur = Pkm1_at_qpts[i, :]
                        l_cur = functional.IntegralMoment(
                            ref_el, Q, phi_cur, (d, ), (sd, ))
                        nodes.append(l_cur)

        elif variant == "point":
            num_edges = len(t[1])

            # edge tangents
            for i in range(num_edges):
                pts_cur = ref_el.make_points(1, i, degree + 2)
                for j in range(len(pts_cur)):
                    pt_cur = pts_cur[j]
                    f = functional.PointEdgeTangentEvaluation(
                        ref_el, i, pt_cur)
                    nodes.append(f)

            # internal moments
            if degree > 0:
                Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))
                qpts = Q.get_points()
                Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
                zero_index = tuple([0 for i in range(sd)])
                Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

                for d in range(sd):
                    for i in range(Pkm1_at_qpts.shape[0]):
                        phi_cur = Pkm1_at_qpts[i, :]
                        l_cur = functional.IntegralMoment(
                            ref_el, Q, phi_cur, (d, ), (sd, ))
                        nodes.append(l_cur)

        entity_ids = {}

        # set to empty
        for i in range(sd + 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # edges
        num_edge_pts = len(ref_el.make_points(1, 0, degree + 2))

        for i in range(len(t[1])):
            entity_ids[1][i] = list(range(cur, cur + num_edge_pts))
            cur += num_edge_pts

        # moments against P_{degree-1} internally, if degree > 0
        if degree > 0:
            num_internal_dof = sd * Pkm1_at_qpts.shape[0]
            entity_ids[2][0] = list(range(cur, cur + num_internal_dof))

        super(NedelecDual2D, self).__init__(nodes, ref_el, entity_ids)
Example #29
0
import numpy
from FIAT.polynomial_set import mis
from FIAT.reference_element import default_simplex
from FIAT.quadrature import make_quadrature

order = 1
quadrature = make_quadrature(default_simplex(1), order)

from FIAT.lagrange import Lagrange

degree = 1
element = Lagrange(default_simplex(1), degree)

vertices = [n.get_point_dict().keys()[0] for n in element.dual.get_nodes()]

quadpts = numpy.array(quadrature.get_points(), dtype=numpy.float64)
quadwts = numpy.array(quadrature.get_weights(), dtype=numpy.float64)
numQuadPts = len(quadpts)
evals = element.get_nodal_basis().tabulate(quadrature.get_points(), 1)
basis = numpy.array(evals[mis(1, 0)[0]], dtype=numpy.float64).transpose()
numBasis = element.get_nodal_basis().get_num_members()
basisDeriv = numpy.array([evals[alpha] for alpha in mis(1, 1)], dtype=numpy.float64).transpose()

print "order: %d" % order
print "degree: %d" % degree
print "numQuadPts: %d" % numQuadPts
print "basis:" 
print basis
print "basisDeriv:"
print basisDeriv
Example #30
0
def NedelecSpace3D(ref_el, k):
    """Constructs a nodal basis for the 3d first-kind Nedelec space"""
    sd = ref_el.get_spatial_dimension()
    if sd != 3:
        raise Exception("NedelecSpace3D requires 3d reference element")

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    if k > 0:
        dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)
    else:
        dimPkm1 = 0

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk = vec_Pkp1.take(vec_Pk_indices)

    vec_Pke_indices = list(chain(*(range(i * dimPkp1 + dimPkm1, i * dimPkp1 + dimPk)
                                   for i in range(sd))))

    vec_Pke = vec_Pkp1.take(vec_Pke_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1)

    Q = quadrature.make_quadrature(ref_el, 2 * (k + 1))

    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkCrossXcoeffs = numpy.zeros((vec_Pke.get_num_members(),
                                  sd,
                                  Pkp1.get_num_members()), "d")

    Pke_qpts = vec_Pke.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    for i in range(vec_Pke.get_num_members()):
        for j in range(sd):  # vector components
            qwts_cur_bf_val = (
                Qpts[:, (j + 2) % 3] * Pke_qpts[i, (j + 1) % 3, :] -
                Qpts[:, (j + 1) % 3] * Pke_qpts[i, (j + 2) % 3, :]) * Qwts
            PkCrossXcoeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, qwts_cur_bf_val)
#            for k in range( Pkp1.get_num_members() ):
#                 PkCrossXcoeffs[i,j,k] = sum( Qwts * cur_bf_val * Pkp1_at_Qpts[k,:] )
#                for l in range( len( Qpts ) ):
#                    cur_bf_val = Qpts[l][(j+2)%3] \
#                                 * Pke_qpts[i,(j+1)%3,l] \
#                                 - Qpts[l][(j+1)%3] \
#                                 * Pke_qpts[i,(j+2)%3,l]
#                    PkCrossXcoeffs[i,j,k] += Qwts[l] \
#                                             * cur_bf_val \
#                                             * Pkp1_at_Qpts[k,l]

    PkCrossX = polynomial_set.PolynomialSet(ref_el,
                                            k + 1,
                                            k + 1,
                                            vec_Pkp1.get_expansion_set(),
                                            PkCrossXcoeffs,
                                            vec_Pkp1.get_dmats())
    return polynomial_set.polynomial_set_union_normalized(vec_Pk, PkCrossX)
Example #31
0
def NedelecSpace2D(ref_el, k):
    """Constructs a basis for the 2d H(curl) space of the first kind
    which is (P_k)^2 + P_k rot( x )"""
    sd = ref_el.get_spatial_dimension()
    if sd != 2:
        raise Exception("NedelecSpace2D requires 2d reference element")

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * k + 2)

    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkH_crossx_coeffs = numpy.zeros((PkH.get_num_members(),
                                     sd,
                                     Pkp1.get_num_members()), "d")

    def rot_x_foo(a):
        if a == 0:
            return 1, 1.0
        elif a == 1:
            return 0, -1.0

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            (ind, sign) = rot_x_foo(j)
            for k in range(Pkp1.get_num_members()):
                PkH_crossx_coeffs[i, j, k] = sign * sum(Qwts * PkH_at_Qpts[i, :] * Qpts[:, ind] * Pkp1_at_Qpts[k, :])
#                for l in range( len( Qpts ) ):
#                    PkH_crossx_coeffs[i,j,k] += Qwts[ l ] \
#                                                * PkH_at_Qpts[i,l] \
#                                                * Qpts[l][ind] \
#                                                * Pkp1_at_Qpts[k,l] \
#                                                * sign

    PkHcrossx = polynomial_set.PolynomialSet(ref_el,
                                             k + 1,
                                             k + 1,
                                             vec_Pkp1.get_expansion_set(),
                                             PkH_crossx_coeffs,
                                             vec_Pkp1.get_dmats())

    return polynomial_set.polynomial_set_union_normalized(vec_Pk_from_Pkp1,
                                                          PkHcrossx)
Example #32
0
        'ytick.labelsize': 16,
        'text.usetex': True,
        'linewidth': 4,
        'figure.figsize': fig_size
    })
    #subplots_adjust(left=0.06,right=0.975,bottom=0.08,top=0.94)
    subplots_adjust(left=0.15, right=0.95, bottom=0.06, top=0.95)


set_sizes_talk()
rcParams.update({'backend': 'png'})
m = 5
n = 100
u = Lagrange.Lagrange(1, m, shapes.line_point_family_lgl)
ufs = u.function_space()
q = quadrature.make_quadrature(1, n)
x = q.get_points()
t = ufs.tabulate_jet(1, x)
B = t[0][(0, )]
D = t[1][(1, )]
subplot(211)
p = [plot(x, B[i], linewidth=2) for i in range(m + 1)]
ylabel('Basis functions')
#xlabel('$\hat{x}$')
subplot(212)
p = [plot(x, D[i], linewidth=2) for i in range(m + 1)]
ylim(-10, 10)
ylabel('Derivatives')
xlabel('$\hat{x}$')
savefig('lgl.png')
Example #33
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)