UFL core algebra#

Base class for dag traversers.

class ufl.corealg.dag_traverser.DAGTraverser(compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)[source]#

Bases: object

Base class for DAG traversers.

Parameters:
  • compress – If True, result_cache will be used.

  • visited_cache – cache of intermediate results; expr -> r = self.process(expr, …).

  • result_cache – cache of result objects for memory reuse, r -> r.

Initialise.

static postorder(method)[source]#

Postorder decorator.

It is more natural for users to write a post-order singledispatchmethod whose arguments are (self, o, *processed_operands, **kwargs), while DAGTraverser expects one whose arguments are (self, o, **kwargs). This decorator takes the former and converts to the latter, processing o.ufl_operands behind the users.

static postorder_only_children(indices)[source]#

Postorder decorator with child indices.

This decorator is the same as DAGTraverser.postorder except that the decorated method is only to take processed operands corresponding to indices.

process(o: Expr, **kwargs) Expr[source]#

Process node by type.

Parameters:
  • o – UFL expression to start DAG traversal from.

  • **kwargs – Keyword arguments for the process singledispatchmethod.

Returns:

Processed Expr.

reuse_if_untouched(o: Expr, **kwargs) Expr[source]#
reuse_if_untouched(o: BaseForm, **kwargs) BaseForm

Reuse if untouched.

Parameters:
  • o – Expression to start DAG traversal from.

  • **kwargs – Keyword arguments for the process singledispatchmethod.

Returns:

Processed expression.

Basic algorithms for applying functions to subexpressions.

ufl.corealg.map_dag.map_expr_dag(function, expression, compress=True, vcache=None, rcache=None)[source]#

Apply a function to each subexpression node in an expression DAG.

If the same function is called multiple times in a transformation (as for example in apply_derivatives), then to reuse caches across the call, use the arguments vcache and rcache.

Parameters:
  • function – The function

  • expression – An expression

  • compress – If True (default), the output object from the function is cached in a dict and reused such that the resulting expression DAG does not contain duplicate objects

  • vcache – Optional dict for caching results of intermediate transformations

  • rcache – Optional dict for caching results for compression

Returns:

The result of the final function call

ufl.corealg.map_dag.map_expr_dags(function, expressions, compress=True, vcache=None, rcache=None)[source]#

Apply a function to each sub-expression node in an expression DAG.

If compress is True (default) the output object from the function is cached in a dict and reused such that the resulting expression DAG does not contain duplicate objects.

If the same function is called multiple times in a transformation (as for example in apply_derivatives), then to reuse caches across the call, use the arguments vcache and rcache.

Parameters:
  • function – The function

  • expressions – An expression

  • compress – If True (default), the output object from the function is cached in a dict and reused such that the resulting expression DAG does not contain duplicate objects

  • vcache – Optional dict for caching results of intermediate transformations

  • rcache – Optional dict for caching results for compression

Returns:

A list with the result of the final function call for each expression

Various expression traversal utilities.

The algorithms here are non-recursive, which is faster than recursion by a factor of 10 or so because of the function call overhead.

ufl.corealg.traversal.cutoff_post_traversal(expr, cutofftypes)[source]#

Cut-off post-tranversal.

Yield o for each node o in expr, child before parent, but skipping subtrees of the cutofftypes.

ufl.corealg.traversal.cutoff_unique_post_traversal(expr, cutofftypes, visited=None)[source]#

Yield o for each node o in expr, child before parent.

Never visit a node twice.

ufl.corealg.traversal.post_traversal(expr)[source]#

Yield o for each node o in expr, child before parent.

ufl.corealg.traversal.pre_traversal(expr)[source]#

Yield o for each tree node o in expr, parent before child.

ufl.corealg.traversal.traverse_terminals(expr)[source]#

Traverse terminals.

ufl.corealg.traversal.traverse_unique_terminals(expr, visited=None)[source]#

Traverse unique terminals.

ufl.corealg.traversal.unique_post_traversal(expr, visited=None)[source]#

Yield o for each node o in expr, child before parent.

Never visit a node twice.

ufl.corealg.traversal.unique_pre_traversal(expr, visited=None)[source]#

Yield o for each tree node o in expr, parent before child.

This version only visits each node once.