def construct_modified_terminal(mt, terminal): """Construct a modified terminal given terminal modifiers from an analysed modified terminal and a terminal.""" expr = terminal if mt.reference_value: expr = ReferenceValue(expr) dim = expr.ufl_domain().topological_dimension() for n in range(mt.local_derivatives): # Return zero if expression is trivially constant. This has to # happen here because ReferenceGrad has no access to the # topological dimension of a literal zero. if is_cellwise_constant(expr): expr = Zero(expr.ufl_shape + (dim, ), expr.ufl_free_indices, expr.ufl_index_dimensions) else: expr = ReferenceGrad(expr) # No need to apply restrictions to ConstantValue terminals if not isinstance(expr, ConstantValue): if mt.restriction == '+': expr = PositiveRestricted(expr) elif mt.restriction == '-': expr = NegativeRestricted(expr) return expr
def physical_points(self, point_set, entity=None): """Converts point_set from reference to physical space""" expr = SpatialCoordinate(self.mt.terminal.ufl_domain()) point_shape, = point_set.expression.shape if entity is not None: e, _ = entity assert point_shape == e else: assert point_shape == expr.ufl_domain().topological_dimension() if self.mt.restriction == '+': expr = PositiveRestricted(expr) elif self.mt.restriction == '-': expr = NegativeRestricted(expr) config = {"point_set": point_set} config.update(self.config) if entity is not None: config.update({ name: getattr(self.interface, name) for name in ["integration_dim", "entity_ids"] }) context = PointSetContext(**config) expr = self.preprocess(expr, context) mapped = map_expr_dag(context.translator, expr) indices = tuple(gem.Index() for _ in mapped.shape) return gem.ComponentTensor(gem.Indexed(mapped, indices), point_set.indices + indices)
def detJ_at(self, point): expr = JacobianDeterminant(self.mt.terminal.ufl_domain()) if self.mt.restriction == '+': expr = PositiveRestricted(expr) elif self.mt.restriction == '-': expr = NegativeRestricted(expr) config = {"point_set": PointSingleton(point)} config.update(self.config) context = PointSetContext(**config) expr = self.preprocess(expr, context) return map_expr_dag(context.translator, expr)
def physical_edge_lengths(self): expr = ufl.classes.CellEdgeVectors(self.mt.terminal.ufl_domain()) if self.mt.restriction == '+': expr = PositiveRestricted(expr) elif self.mt.restriction == '-': expr = NegativeRestricted(expr) expr = ufl.as_vector([ufl.sqrt(ufl.dot(expr[i, :], expr[i, :])) for i in range(3)]) expr = preprocess_expression(expr) config = {"point_set": PointSingleton([1/3, 1/3])} config.update(self.config) context = PointSetContext(**config) return map_expr_dag(context.translator, expr)
def jacobian_at(self, point): ps = PointSingleton(point) expr = Jacobian(self.mt.terminal.ufl_domain()) assert ps.expression.shape == ( expr.ufl_domain().topological_dimension(), ) if self.mt.restriction == '+': expr = PositiveRestricted(expr) elif self.mt.restriction == '-': expr = NegativeRestricted(expr) config = {"point_set": PointSingleton(point)} config.update(self.config) context = PointSetContext(**config) expr = self.preprocess(expr, context) return map_expr_dag(context.translator, expr)
def construct_modified_terminal(mt, terminal): """Construct a modified terminal given terminal modifiers from an analysed modified terminal and a terminal.""" expr = terminal if mt.reference_value: expr = ReferenceValue(expr) for n in range(mt.local_derivatives): expr = ReferenceGrad(expr) if mt.averaged == "cell": expr = CellAvg(expr) elif mt.averaged == "facet": expr = FacetAvg(expr) # No need to apply restrictions to ConstantValue terminals if not isinstance(expr, ConstantValue): if mt.restriction == '+': expr = PositiveRestricted(expr) elif mt.restriction == '-': expr = NegativeRestricted(expr) return expr