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)
Ejemplo n.º 2
0
    def __init__(self, ref_el, points):
        # Create entity dofs.
        entity_dofs = {dim: {entity: [] for entity in entities}
                       for dim, entities in ref_el.get_topology().items()}
        entity_dofs[ref_el.get_dimension()] = {0: list(range(len(points)))}

        # The dual nodes are PointEvaluations at the quadrature points.
        # FIXME: KBO: Check if this gives expected results for code like evaluate_dof.
        nodes = [PointEvaluation(ref_el, tuple(point)) for point in points]

        # Construct the dual set
        dual = DualSet(nodes, ref_el, entity_dofs)

        super(QuadratureElement, self).__init__(ref_el, dual, order=None)
        self._points = points  # save the quadrature points
Ejemplo n.º 3
0
    def __init__(self, ref_el, degree):
        sd = ref_el.get_spatial_dimension()
        if sd in (0, 1):
            raise ValueError(
                "Cannot use this trace class on a %d-dimensional cell." % sd)

        # Constructing facet element as a discontinuous Lagrange element
        dglagrange = DiscontinuousLagrange(ufc_simplex(sd - 1), degree)

        # Construct entity ids (assigning top. dim. and initializing as empty)
        entity_dofs = {}

        # Looping over dictionary of cell topology to construct the empty
        # dictionary for entity ids of the trace element
        topology = ref_el.get_topology()
        for top_dim, entities in topology.items():
            entity_dofs[top_dim] = {}
            for entity in entities:
                entity_dofs[top_dim][entity] = []

        # Filling in entity ids and generating points for dual basis
        nf = dglagrange.space_dimension()
        points = []
        num_facets = sd + 1
        for f in range(num_facets):
            entity_dofs[sd - 1][f] = range(f * nf, (f + 1) * nf)

            for dof in dglagrange.dual_basis():
                facet_point = list(dof.get_point_dict().keys())[0]
                transform = ref_el.get_entity_transform(sd - 1, f)
                points.append(tuple(transform(facet_point)))

        # Setting up dual basis - only point evaluations
        nodes = [PointEvaluation(ref_el, pt) for pt in points]
        dual = dual_set.DualSet(nodes, ref_el, entity_dofs)

        super(HDivTrace, self).__init__(ref_el, dual, dglagrange.get_order(),
                                        dglagrange.get_formdegree(),
                                        dglagrange.mapping()[0])
        # Set up facet element
        self.facet_element = dglagrange

        # degree for quadrature rule
        self.polydegree = degree
Ejemplo n.º 4
0
    def __init__(self, ufl_element):
        "Create QuadratureElement"

        # Compute number of points per axis from the degree of the element
        degree = ufl_element.degree()
        if degree is None:
            degree = default_quadrature_degree
        scheme = ufl_element.quadrature_scheme()
        if scheme is None:
            scheme = default_quadrature_scheme
        self._quad_scheme = scheme

        # Create quadrature (only interested in points)
        # TODO: KBO: What should we do about quadrature functions that live on ds, dS?
        # Get cell and facet names.
        domain, = ufl_element.domains()  # Assuming single domain
        cellname = domain.cell().cellname()
        #facet_cellname = domain.cell().facet_cellname()
        points, weights = create_quadrature(cellname, degree,
                                            self._quad_scheme)

        # Save the quadrature points
        self._points = points

        # Create entity dofs.
        ufc_cell = reference_cell(cellname)
        self._entity_dofs = _create_entity_dofs(ufc_cell, len(points))

        # The dual is a simply the PointEvaluation at the quadrature points
        # FIXME: KBO: Check if this gives expected results for code like evaluate_dof.
        self._dual = [
            PointEvaluation(ufc_cell, tuple(point)) for point in points
        ]

        # Save the geometric dimension.
        # FIXME: KBO: Do we need to change this in order to integrate on facets?
        #        MSA: Not the geometric dimension, but maybe the topological dimension somewhere?
        self._geometric_dimension = domain.geometric_dimension()
Ejemplo n.º 5
0
    def __init__(self, ref_el, degree):
        """Constructor for the HDivTrace element.

        :arg ref_el: A reference element, which may be a tensor product
                     cell.
        :arg degree: The degree of approximation. If on a tensor product
                     cell, then provide a tuple of degrees if you want
                     varying degrees.
        """
        sd = ref_el.get_spatial_dimension()
        if sd in (0, 1):
            raise ValueError("Cannot take the trace of a %d-dim cell." % sd)

        # Store the degrees if on a tensor product cell
        if ref_el.get_shape() == TENSORPRODUCT:
            try:
                degree = tuple(degree)
            except TypeError:
                degree = (degree,) * len(ref_el.cells)

            assert len(ref_el.cells) == len(degree), (
                "Number of specified degrees must be equal to the number of cells."
            )
        else:
            if ref_el.get_shape() not in [TRIANGLE, TETRAHEDRON, QUADRILATERAL]:
                raise NotImplementedError(
                    "Trace element on a %s not implemented" % type(ref_el)
                )
            # Cannot have varying degrees for these reference cells
            if isinstance(degree, tuple):
                raise ValueError("Must have a tensor product cell if providing multiple degrees")

        # Initialize entity dofs and construct the DG elements
        # for the facets
        facet_sd = sd - 1
        dg_elements = {}
        entity_dofs = {}
        topology = ref_el.get_topology()
        for top_dim, entities in topology.items():
            cell = ref_el.construct_subelement(top_dim)
            entity_dofs[top_dim] = {}

            # We have a facet entity!
            if cell.get_spatial_dimension() == facet_sd:
                dg_elements[top_dim] = construct_dg_element(cell, degree)
            # Initialize
            for entity in entities:
                entity_dofs[top_dim][entity] = []

        # Compute the dof numbering for all facet entities
        # and extract nodes
        offset = 0
        pts = []
        for facet_dim in sorted(dg_elements):
            element = dg_elements[facet_dim]
            nf = element.space_dimension()
            num_facets = len(topology[facet_dim])

            for i in range(num_facets):
                entity_dofs[facet_dim][i] = list(range(offset, offset + nf))
                offset += nf

                # Run over nodes and collect the points for point evaluations
                for dof in element.dual_basis():
                    facet_pt, = dof.get_point_dict()
                    transform = ref_el.get_entity_transform(facet_dim, i)
                    pts.append(tuple(transform(facet_pt)))

        # Setting up dual basis - only point evaluations
        nodes = [PointEvaluation(ref_el, pt) for pt in pts]
        dual = DualSet(nodes, ref_el, entity_dofs)

        # Degree of the element
        deg = max([e.degree() for e in dg_elements.values()])

        super(HDivTrace, self).__init__(ref_el, dual, order=deg,
                                        formdegree=facet_sd,
                                        mapping="affine")

        # Set up facet elements
        self.dg_elements = dg_elements

        # Degree for quadrature rule
        self.polydegree = deg