def expand_compounds_postdiff(e, dim=None): """Expand compound objects into basic operators. Requires e to have a well defined geometric dimension.""" if dim is None: cell = e.cell() dim = None if cell is None else cell.geometric_dimension() return apply_transformer(e, CompoundExpanderPostDiff(dim))
def flatten( e ): # TODO: Fix or remove! Maybe this works better now with IndexSum marking implicit summations. """Convert an UFL expression to a new UFL expression, with sums and products flattened from binary tree nodes to n-ary tree nodes.""" warning( "flatten doesn't work correctly for some indexed products, like (u[i]*v[i])*(q[i]*r[i])" ) return apply_transformer(e, TreeFlattener())
def renumber_indices(expr): if isinstance(expr, Expr): num_free_indices = len(expr.ufl_free_indices) result = apply_transformer(expr, IndexRenumberingTransformer()) if isinstance(expr, Expr): if num_free_indices != len(result.ufl_free_indices): error("The number of free indices left in expression should be invariant w.r.t. renumbering.") return result
def replace(e, mapping): """Replace terminal objects in expression. @param e: An Expr or Form. @param mapping: A dict with from:to replacements to perform. """ mapping2 = dict((k, as_ufl(v)) for (k,v) in mapping.iteritems()) # TODO: Should this be sorted? # Workaround for problem with delayed derivative evaluation if extract_type(e, CoefficientDerivative): # Hack to avoid circular dependencies from ufl.algorithms.ad import expand_derivatives e = expand_derivatives(e) return apply_transformer(e, Replacer(mapping2))
def replace(e, mapping): """Replace terminal objects in expression. @param e: An Expr or Form. @param mapping: A dict with from:to replacements to perform. """ mapping2 = dict( (k, as_ufl(v)) for (k, v) in mapping.iteritems()) # TODO: Should this be sorted? # Workaround for problem with delayed derivative evaluation if extract_type(e, CoefficientDerivative): # Hack to avoid circular dependencies from ufl.algorithms.ad import expand_derivatives e = expand_derivatives(e) return apply_transformer(e, Replacer(mapping2))
def purge_duplications(e): """Replace any subexpressions in expression that occur more than once with a single instance.""" return apply_transformer(e, DuplicationPurger())
def mark_duplications(e): """Wrap subexpressions that are equal (completely equal, not mathematically equivalent) in Variable objects to facilitate subexpression reuse.""" duplications = extract_duplications(e) return apply_transformer(e, DuplicationMarker(duplications))
def expand_indices(e): return apply_transformer(e, IndexExpander())
def renumber_variables(expr): if isinstance(expr, Expr) and expr.free_indices(): error("Not expecting any free indices left in expression.") return apply_transformer(expr, VariableRenumberingTransformer())
def flatten(e): # TODO: Fix or remove! Maybe this works better now with IndexSum marking implicit summations. """Convert an UFL expression to a new UFL expression, with sums and products flattened from binary tree nodes to n-ary tree nodes.""" warning("flatten doesn't work correctly for some indexed products, like (u[i]*v[i])*(q[i]*r[i])") return apply_transformer(e, TreeFlattener())
def propagate_restrictions(expression): "Propagate restriction nodes to wrap terminal objects directly." return apply_transformer(expression, RestrictionPropagator(), domain_type=Measure.INTERIOR_FACET)