def modified_terminal(self, o): mt = analyse_modified_terminal(o) terminal = mt.terminal if not isinstance(terminal, Coefficient): # Only split coefficients return o if type(terminal.ufl_element()) != MixedElement: # Only split mixed coefficients return o # Reference value expected assert mt.reference_value # Derivative indices beta = indices(mt.local_derivatives) components = [] for subcoeff in self._split[terminal]: # Apply terminal modifiers onto the subcoefficient component = construct_modified_terminal(mt, subcoeff) # Collect components of the subcoefficient for alpha in numpy.ndindex(subcoeff.ufl_element().reference_value_shape()): # New modified terminal: component[alpha + beta] components.append(component[alpha + beta]) # Repack derivative indices to shape c, = indices(1) return ComponentTensor(as_tensor(components)[c], MultiIndex((c,) + beta))
def translate_spatialcoordinate(terminal, mt, ctx): # Replace terminal with a Coefficient terminal = ctx.coordinate(terminal.ufl_domain()) # Get back to reference space terminal = preprocess_expression(terminal) # Rebuild modified terminal expr = construct_modified_terminal(mt, terminal) # Translate replaced UFL snippet return ctx.translator(expr)
def translate_cellorigin(terminal, mt, ctx): domain = terminal.ufl_domain() coords = SpatialCoordinate(domain) expression = construct_modified_terminal(mt, coords) point_set = PointSingleton((0.0,) * domain.topological_dimension()) config = {name: getattr(ctx, name) for name in ["ufl_cell", "precision", "index_cache"]} config.update(interface=ctx, point_set=point_set) context = PointSetContext(**config) return context.translator(expression)
def translate_cell_vertices(terminal, mt, ctx): coords = SpatialCoordinate(terminal.ufl_domain()) ufl_expr = construct_modified_terminal(mt, coords) ps = PointSet(numpy.array(ctx.fiat_cell.get_vertices())) config = {name: getattr(ctx, name) for name in ["ufl_cell", "precision", "index_cache"]} config.update(interface=ctx, point_set=ps) context = PointSetContext(**config) expr = context.translator(ufl_expr) # Wrap up point (vertex) index c = gem.Index() return gem.ComponentTensor(gem.Indexed(expr, (c,)), ps.indices + (c,))
def translate_cell_edge_vectors(terminal, mt, ctx): # WARNING: Assumes straight edges! coords = CellVertices(terminal.ufl_domain()) ufl_expr = construct_modified_terminal(mt, coords) cell_vertices = ctx.translator(ufl_expr) e = gem.Index() c = gem.Index() expr = gem.ListTensor([ gem.Sum( gem.Indexed(cell_vertices, (u, c)), gem.Product(gem.Literal(-1), gem.Indexed(cell_vertices, (v, c)))) for _, (u, v) in sorted(ctx.fiat_cell.get_topology()[1].items()) ]) return gem.ComponentTensor(gem.Indexed(expr, (e, )), (e, c))
def translate_cell_edge_vectors(terminal, mt, ctx): # WARNING: Assumes straight edges! coords = CellVertices(terminal.ufl_domain()) ufl_expr = construct_modified_terminal(mt, coords) cell_vertices = ctx.translator(ufl_expr) e = gem.Index() c = gem.Index() expr = gem.ListTensor([ gem.Sum(gem.Indexed(cell_vertices, (u, c)), gem.Product(gem.Literal(-1), gem.Indexed(cell_vertices, (v, c)))) for _, (u, v) in sorted(ctx.fiat_cell.get_topology()[1].items()) ]) return gem.ComponentTensor(gem.Indexed(expr, (e,)), (e, c))