def __init__(self, element): """ Constructs a FlattenToQuad element. :arg element: a fiat element """ nodes = element.dual.nodes ref_el = FiredrakeQuadrilateral() entity_ids = element.dual.entity_ids flat_entity_ids = {} flat_entity_ids[0] = entity_ids[(0, 0)] flat_entity_ids[1] = dict( enumerate([v for k, v in sorted(entity_ids[(0, 1)].items())] + [v for k, v in sorted(entity_ids[(1, 0)].items())])) flat_entity_ids[2] = entity_ids[(1, 1)] dual = DualSet(nodes, ref_el, flat_entity_ids) super(FlattenToQuad, self).__init__(ref_el, dual, element.get_order(), element.get_formdegree(), element._mapping) self.element = element
from __future__ import absolute_import, print_function, division import pytest import numpy as np from FIAT.reference_element import UFCInterval, UFCTriangle, UFCTetrahedron from FIAT.reference_element import FiredrakeQuadrilateral, TensorProductCell from tsfc.fem import make_cell_facet_jacobian interval = UFCInterval() triangle = UFCTriangle() quadrilateral = FiredrakeQuadrilateral() tetrahedron = UFCTetrahedron() interval_x_interval = TensorProductCell(interval, interval) triangle_x_interval = TensorProductCell(triangle, interval) quadrilateral_x_interval = TensorProductCell(quadrilateral, interval) @pytest.mark.parametrize( ('cell', 'cell_facet_jacobian'), [(interval, [[], []]), (triangle, [[-1, 1], [0, 1], [1, 0]]), (quadrilateral, [[0, 1], [0, 1], [1, 0], [1, 0]]), (tetrahedron, [[-1, -1, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0]])]) def test_cell_facet_jacobian(cell, cell_facet_jacobian): facet_dim = cell.get_spatial_dimension() - 1 for facet_number in range(len(cell.get_topology()[facet_dim])): actual = make_cell_facet_jacobian(cell, facet_dim, facet_number) expected = np.reshape(cell_facet_jacobian[facet_number], actual.shape) assert np.allclose(expected, actual)
def create_actual_fiat_element(ufl_element): fiat_element = None # Check if finite element family is supported by FIAT family = ufl_element.family() if not family in FIAT.supported_elements: # We support RTCE and RTCF elements on quadrilaterals, # even though they are not supported by FIAT. if ufl_element.cell().cellname() == "quadrilateral": fiat_element = create_actual_fiat_element( reconstruct_element(ufl_element, ufl_element.family(), _quad_opc, ufl_element.degree())) else: if family in ("FacetElement", "InteriorElement"): # rescue these pass else: error( "Sorry, finite element of type \"%s\" are not supported by FIAT.", family) # Skip all cases if FIAT element is ready already if fiat_element is not None: pass # HDiv and HCurl elements have family "OuterProductElement", # so get matching FIAT element directly rather than via lookup elif isinstance(ufl_element, ufl.HDivElement): fiat_element = FIAT.Hdiv(create_element(ufl_element._element)) elif isinstance(ufl_element, ufl.HCurlElement): fiat_element = FIAT.Hcurl(create_element(ufl_element._element)) elif isinstance(ufl_element, ufl.FacetElement): fiat_element = FIAT.RestrictedElement(create_element( ufl_element._element), restriction_domain="facet") elif isinstance(ufl_element, ufl.InteriorElement): fiat_element = FIAT.RestrictedElement(create_element( ufl_element._element), restriction_domain="interior") else: # Look up FIAT element ElementClass = FIAT.supported_elements[family] if isinstance(ufl_element, ufl.EnrichedElement): A = create_element(ufl_element._elements[0]) B = create_element(ufl_element._elements[1]) fiat_element = ElementClass(A, B) # OPVE is only here to satisfy calls from Firedrake elif isinstance( ufl_element, (ufl.OuterProductElement, ufl.OuterProductVectorElement, ufl.OuterProductTensorElement)): cell = ufl_element.cell() if not isinstance(cell, ufl.OuterProductCell): error( "An OuterProductElement must have an OuterProductCell as domain, sorry." ) A = create_element(ufl_element._A) B = create_element(ufl_element._B) fiat_element = ElementClass(A, B) elif isinstance(ufl_element, (ufl.BrokenElement, ufl.TraceElement)): fiat_element = ElementClass(create_element(ufl_element._element)) elif ufl_element.cell().cellname() == "quadrilateral": fiat_element = create_actual_fiat_element( ufl_element.reconstruct(domain=_quad_opc)) else: # "Normal element" case cell = ufl_element.cell() degree = ufl_element.degree() fiat_cell = reference_cell(cell) fiat_element = ElementClass(fiat_cell, degree) if fiat_element is None: raise Exception( "Something strange happened: reached end of function without returning an element" ) if ufl_element.cell().cellname() == "quadrilateral" and \ isinstance(fiat_element.get_reference_element(), FIAT.reference_element.two_product_cell): # Flatten tensor product element from FIAT.reference_element import FiredrakeQuadrilateral from FIAT.dual_set import DualSet nodes = fiat_element.dual.nodes ref_el = FiredrakeQuadrilateral() entity_ids = fiat_element.dual.entity_ids flat_entity_ids = {} flat_entity_ids[0] = entity_ids[(0, 0)] flat_entity_ids[1] = dict( enumerate(entity_ids[(0, 1)].values() + entity_ids[(1, 0)].values())) flat_entity_ids[2] = entity_ids[(1, 1)] fiat_element.dual = DualSet(nodes, ref_el, flat_entity_ids) fiat_element.ref_el = ref_el return fiat_element
def cell(self): return FiredrakeQuadrilateral()
def extr_quadrilateral(): """Extruded quadrilateral = quadrilateral x interval""" return TensorProductCell(FiredrakeQuadrilateral(), UFCInterval())
def quadrilateral(): return FiredrakeQuadrilateral()