Example #1
0
    def fiat_equivalent(self):
        ps = self._rule.point_set
        weights = getattr(self._rule, 'weights', None)
        if weights is None:
            # we need the weights.
            weights, = evaluate([self._rule.weight_expression])
            weights = weights.arr.flatten()
            self._rule.weights = weights

        return FIAT.QuadratureElement(self.cell, ps.points, weights)
Example #2
0
def convert_finiteelement(element, vector_is_mixed):
    if element.family() == "Real":
        # Real element is just DG0
        cell = element.cell()
        return create_element(ufl.FiniteElement("DG", cell, 0),
                              vector_is_mixed)
    cell = as_fiat_cell(element.cell())
    if element.family() == "Quadrature":
        degree = element.degree()
        scheme = element.quadrature_scheme()
        if degree is None or scheme is None:
            raise ValueError("Quadrature scheme and degree must be specified!")

        quad_rule = FIAT.create_quadrature(cell, degree, scheme)
        return FIAT.QuadratureElement(cell, quad_rule.get_points())
    lmbda = supported_elements[element.family()]
    if lmbda is None:
        if element.cell().cellname() == "quadrilateral":
            # Handle quadrilateral short names like RTCF and RTCE.
            element = element.reconstruct(cell=quadrilateral_tpc)
        elif element.cell().cellname() == "hexahedron":
            # Handle hexahedron short names like NCF and NCE.
            element = element.reconstruct(cell=hexahedron_tpc)
        else:
            raise ValueError("%s is supported, but handled incorrectly" %
                             element.family())
        return FlattenedDimensions(create_element(element, vector_is_mixed))

    kind = element.variant()
    if kind is None:
        kind = 'spectral' if element.cell().cellname(
        ) == 'interval' else 'equispaced'  # default variant

    if element.family() == "Lagrange":
        if kind == 'equispaced':
            lmbda = FIAT.Lagrange
        elif kind == 'spectral' and element.cell().cellname() == 'interval':
            lmbda = FIAT.GaussLobattoLegendre
        else:
            raise ValueError("Variant %r not supported on %s" %
                             (kind, element.cell()))
    elif element.family() in [
            "Discontinuous Lagrange", "Discontinuous Lagrange L2"
    ]:
        if kind == 'equispaced':
            lmbda = FIAT.DiscontinuousLagrange
        elif kind == 'spectral' and element.cell().cellname() == 'interval':
            lmbda = FIAT.GaussLegendre
        else:
            raise ValueError("Variant %r not supported on %s" %
                             (kind, element.cell()))
    return lmbda(cell, element.degree())
Example #3
0
    def fiat_equivalent(self):
        ps = self._rule.point_set
        if isinstance(ps, UnknownPointSet):
            raise ValueError(
                "A quadrature element with rule with runtime points has no fiat equivalent!"
            )
        weights = getattr(self._rule, 'weights', None)
        if weights is None:
            # we need the weights.
            weights, = evaluate([self._rule.weight_expression])
            weights = weights.arr.flatten()
            self._rule.weights = weights

        return FIAT.QuadratureElement(self.cell, ps.points, weights)
Example #4
0
def _create_finiteelement(element: ufl.FiniteElement) -> FIAT.FiniteElement:
    """Create FIAT element for UFL base type ufl.FiniteElement."""
    if element.family() == "Real":
        e = create_element(ufl.FiniteElement("DG", element.cell(), 0))
        e.__class__ = type('SpaceOfReals', (type(e), SpaceOfReals), {})
        return e

    if element.family() == "Quadrature":
        assert element.degree() is not None
        assert element.quadrature_scheme() is not None

        # 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.
        points, weights = create_quadrature(element.cell().cellname(),
                                            element.degree(),
                                            element.quadrature_scheme())
        return FIAT.QuadratureElement(FIAT.ufc_cell(element.cell().cellname()),
                                      points)

    # Handle tensor-product structured elements
    if element.cell().cellname() == "quadrilateral":
        e = _create_element(element.reconstruct(cell=_tpc_quadrilateral))
        return FIAT.tensor_product.FlattenedDimensions(e)
    elif element.cell().cellname() == "hexahedron":
        e = _create_element(element.reconstruct(cell=_tpc_hexahedron))
        return FIAT.tensor_product.FlattenedDimensions(e)

    if element.family() not in FIAT.supported_elements:
        raise ValueError(
            "Finite element of type \"{}\" is not supported by FIAT.".format(
                element.family()))

    # Handle Lagrange variants
    if element.family() == "Lagrange" and element.variant() == "spectral":
        assert element.cell().cellname() == "interval"
        element_class = FIAT.GaussLobattoLegendre
    else:
        element_class = FIAT.supported_elements[element.family()]

    assert element.degree() is not None
    return element_class(FIAT.ufc_cell(element.cell().cellname()),
                         element.degree())