def _interpolate_vertex_values(ufl_element, fiat_element): "Compute intermediate representation of interpolate_vertex_values." # Check for QuadratureElement for e in all_elements(fiat_element): if isinstance(e, QuadratureElement): return "Function is not supported/implemented for QuadratureElement." if isinstance(e, HDivTrace): return "Function is not implemented for HDivTrace." cell = ufl_element.cell() cellname = cell.cellname() tdim = cell.topological_dimension() gdim = cell.geometric_dimension() ir = {} ir["geometric_dimension"] = gdim ir["topological_dimension"] = tdim # Check whether computing the Jacobian is necessary mappings = fiat_element.mapping() ir["needs_jacobian"] = any("piola" in m for m in mappings) ir["needs_oriented"] = needs_oriented_jacobian(fiat_element) # See note in _evaluate_dofs ir["reference_value_size"] = ufl_element.reference_value_size() ir["physical_value_size"] = ufl_element.value_size() # Get vertices of reference cell fiat_cell = reference_cell(cellname) vertices = fiat_cell.get_vertices() # Compute data for each constituent element all_fiat_elm = all_elements(fiat_element) ir["element_data"] = [ { # NB! value_shape of fiat element e means reference_value_shape "reference_value_size": product(e.value_shape()), # FIXME: THIS IS A BUG: "physical_value_size": product(e.value_shape()), # FIXME: Get from corresponding ufl element? "basis_values": e.tabulate(0, vertices)[(0,) * tdim].transpose(), "mapping": e.mapping()[0], "space_dim": e.space_dimension(), } for e in all_fiat_elm] # FIXME: Temporary hack! if len(ir["element_data"]) == 1: ir["element_data"][0]["physical_value_size"] = ir["physical_value_size"] # Consistency check, related to note in _evaluate_dofs # This will fail for e.g. (RT1 x DG0) on a manifold because of the above bug if sum(data["physical_value_size"] for data in ir["element_data"]) != ir["physical_value_size"]: ir = "Failed to set physical value size correctly for subelements." elif sum(data["reference_value_size"] for data in ir["element_data"]) != ir["reference_value_size"]: ir = "Failed to set reference value size correctly for subelements." return ir
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. cellname = ufl_element.cell().cellname() #facet_cellname = ufl_element.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(ufl_element.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? self._geometric_dimension = ufl_element.cell().geometric_dimension()
def _interpolate_vertex_values(ufl_element, element): "Compute intermediate representation of interpolate_vertex_values." # Check for QuadratureElement for e in all_elements(element): if isinstance(e, QuadratureElement): return "Function is not supported/implemented for QuadratureElement." domain, = ufl_element.domains() # Assuming single domain cellname = domain.cell().cellname() ir = {} ir["geometric_dimension"] = domain.geometric_dimension() ir["topological_dimension"] = domain.topological_dimension() # Check whether computing the Jacobian is necessary mappings = element.mapping() ir["needs_jacobian"] = any("piola" in m for m in mappings) ir["needs_oriented"] = needs_oriented_jacobian(element) # See note in _evaluate_dofs ir["reference_value_size"] = _value_size(element) ir["physical_value_size"] = _value_size(ufl_element) # Get vertices of reference cell fiat_cell = reference_cell(cellname) vertices = fiat_cell.get_vertices() # Compute data for each constituent element extract = lambda values: values[sorted(values.keys())[0]].transpose() all_fiat_elm = all_elements(element) ir["element_data"] = [ { # See note in _evaluate_dofs "reference_value_size": _value_size(e), "physical_value_size": _value_size(e), # FIXME: Get from corresponding ufl element "basis_values": extract(e.tabulate(0, vertices)), "mapping": e.mapping()[0], "space_dim": e.space_dimension() } for e in all_fiat_elm ] # FIXME: Temporary hack! if len(ir["element_data"]) == 1: ir["element_data"][0]["physical_value_size"] = ir[ "physical_value_size"] # Consistency check, related to note in _evaluate_dofs # This will fail for e.g. (RT1 x DG0) on a manifold if sum(data["physical_value_size"] for data in ir["element_data"]) != ir["physical_value_size"]: ir = "Failed to set physical value size correctly for subelements." elif sum(data["reference_value_size"] for data in ir["element_data"]) != ir["reference_value_size"]: ir = "Failed to set reference value size correctly for subelements." return ir
def _map_entity_points(cell, points, entity_dim, entity, integral_type): # Not sure if this is useful anywhere else than in _tabulate_psi_table! tdim = cell.topological_dimension() if entity_dim == tdim: return points elif entity_dim == tdim-1: # Special case, don't need to map coordinates on vertices if len(points[0]) == 0: return [[(0.0,), (1.0,)][entity]] # Get mapping from facet to cell coordinates if integral_type in ("exterior_facet_top", "exterior_facet_bottom", "interior_facet_horiz"): t = reference_cell(cell).get_horiz_facet_transform(entity) elif integral_type in ("exterior_facet_vert", "interior_facet_vert"): t = reference_cell(cell).get_vert_facet_transform(entity) else: t = reference_cell(cell).get_facet_transform(entity) # Apply mapping for all points return numpy.asarray(map(t, points)) elif entity_dim == 0: return (reference_cell_vertices(cell.cellname())[entity],)
def _interpolate_vertex_values(ufl_element, element, cell): "Compute intermediate representation of interpolate_vertex_values." # Check for QuadratureElement for e in all_elements(element): if isinstance(e, QuadratureElement): return "Function is not supported/implemented for QuadratureElement." ir = {} ir["geometric_dimension"] = cell.geometric_dimension() ir["topological_dimension"] = cell.topological_dimension() # Check whether computing the Jacobian is necessary mappings = element.mapping() ir["needs_jacobian"] = any("piola" in m for m in mappings) ir["needs_oriented"] = needs_oriented_jacobian(element) # See note in _evaluate_dofs ir["reference_value_size"] = _value_size(element) ir["physical_value_size"] = _value_size(ufl_element) # Get vertices of reference cell cell = reference_cell(cell.cellname()) vertices = cell.get_vertices() # Compute data for each constituent element extract = lambda values: values[values.keys()[0]].transpose() all_fiat_elm = all_elements(element) ir["element_data"] = [{ # See note in _evaluate_dofs "reference_value_size": _value_size(e), "physical_value_size": _value_size(e), # FIXME: Get from corresponding ufl element "basis_values": extract(e.tabulate(0, vertices)), "mapping": e.mapping()[0], "space_dim": e.space_dimension()} for e in all_fiat_elm] # FIXME: Temporary hack! if len(ir["element_data"]) == 1: ir["element_data"][0]["physical_value_size"] = ir["physical_value_size"] # Consistency check, related to note in _evaluate_dofs # This will fail for e.g. (RT1 x DG0) on a manifold if sum(data["physical_value_size"] for data in ir["element_data"]) != ir["physical_value_size"]: ir = "Failed to set physical value size correctly for subelements." elif sum(data["reference_value_size"] for data in ir["element_data"]) != ir["reference_value_size"]: ir = "Failed to set reference value size correctly for subelements." return ir
def _map_entity_points(cell, points, entity_dim, entity, integral_type): # Not sure if this is useful anywhere else than in _tabulate_psi_table! tdim = cell.topological_dimension() if entity_dim == tdim: return points elif entity_dim == tdim - 1: # Special case, don't need to map coordinates on vertices if len(points[0]) == 0: return [[(0.0, ), (1.0, )][entity]] # Get mapping from facet to cell coordinates if integral_type in ("exterior_facet_top", "exterior_facet_bottom", "interior_facet_horiz"): t = reference_cell(cell).get_horiz_facet_transform(entity) elif integral_type in ("exterior_facet_vert", "interior_facet_vert"): t = reference_cell(cell).get_vert_facet_transform(entity) else: t = reference_cell(cell).get_facet_transform(entity) # Apply mapping for all points return numpy.asarray(map(t, points)) elif entity_dim == 0: return (reference_cell_vertices(cell.cellname())[entity], )
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()
def get_data(ufl_element): "Get needed data to run tests." # Create fiat element. element = create_element(ufl_element) # The derivative order that we are interested in is the degree of the element. if isinstance(element, FFCMixedElement): deriv_order = max([e.degree() for e in element.elements()]) else: deriv_order = element.degree() # Get coordinates of the reference cell. cell = ufl_element.cell() ref_coords = reference_cell(cell.cellname()).get_vertices() # Get the locations of the fiat element dofs. elem_points = [list(L.pt_dict.keys())[0] for L in element.dual_basis()] # Add some random points. geo_dim = cell.geometric_dimension() points = elem_points + random_points[geo_dim] return (element, points, geo_dim, ref_coords, deriv_order)
def _interpolate_vertex_values(ufl_element, fiat_element): "Compute intermediate representation of interpolate_vertex_values." # Check for QuadratureElement for e in all_elements(fiat_element): if isinstance(e, QuadratureElement): return "Function is not supported/implemented for QuadratureElement." if isinstance(e, HDivTrace): return "Function is not implemented for HDivTrace." cell = ufl_element.cell() cellname = cell.cellname() tdim = cell.topological_dimension() gdim = cell.geometric_dimension() ir = {} ir["geometric_dimension"] = gdim ir["topological_dimension"] = tdim # Check whether computing the Jacobian is necessary mappings = fiat_element.mapping() ir["needs_jacobian"] = any("piola" in m for m in mappings) ir["needs_oriented"] = needs_oriented_jacobian(fiat_element) # See note in _evaluate_dofs ir["reference_value_size"] = ufl_element.reference_value_size() ir["physical_value_size"] = ufl_element.value_size() # Get vertices of reference cell fiat_cell = reference_cell(cellname) vertices = fiat_cell.get_vertices() # Compute data for each constituent element all_fiat_elm = all_elements(fiat_element) ir["element_data"] = [ { # NB! value_shape of fiat element e means reference_value_shape "reference_value_size": product(e.value_shape()), # FIXME: THIS IS A BUG: "physical_value_size": product( e.value_shape()), # FIXME: Get from corresponding ufl element? "basis_values": e.tabulate(0, vertices)[(0, ) * tdim].transpose(), "mapping": e.mapping()[0], "space_dim": e.space_dimension(), } for e in all_fiat_elm ] # FIXME: Temporary hack! if len(ir["element_data"]) == 1: ir["element_data"][0]["physical_value_size"] = ir[ "physical_value_size"] # Consistency check, related to note in _evaluate_dofs # This will fail for e.g. (RT1 x DG0) on a manifold because of the above bug if sum(data["physical_value_size"] for data in ir["element_data"]) != ir["physical_value_size"]: ir = "Failed to set physical value size correctly for subelements." elif sum(data["reference_value_size"] for data in ir["element_data"]) != ir["reference_value_size"]: ir = "Failed to set reference value size correctly for subelements." return ir