UFL Algorithms#

This module collects algorithms and utility functions operating on UFL objects.

class ufl.algorithms.FormSplitter(replace_argument: bool = True)[source]#

Bases: MultiFunction

Form splitter.

Initialize form splitter.

Parameters:

replace_argument – If True, replace the argument by a new argument in the sub-function space. If False, keep the original argument. This is useful for instance when diagonalizing a form with a mixed-element form, where we want to keep the original argument.

argument(obj)[source]#

Apply to argument.

expr(o, *ops)#

Reuse object if operands are the same objects.

Use in your own subclass by setting e.g.

expr = MultiFunction.reuse_if_untouched

as a default rule.

indexed(o, child, multiindex)[source]#

Extract indexed entry if multindices are fixed.

This avoids tensors like (v_0, 0)[1] to be created.

multi_index(obj)[source]#

Apply to multi_index.

restricted(o)[source]#

Apply to a restricted function.

split(form, ix, iy=None)[source]#

Split form based on the argument part/number.

class ufl.algorithms.MultiFunction[source]#

Bases: object

Base class for collections of non-recursive expression node handlers.

Subclass this (remember to call the __init__ method of this class), and implement handler functions for each Expr type, using the lower case handler name of the type (exprtype._ufl_handler_name_).

This class is optimized for efficient type based dispatch in the __call__ operator via typecode based lookup of the handler function bound to the algorithm object. Of course Python’s function call overhead still applies.

Initialise.

reuse_if_untouched(o, *ops)[source]#

Reuse object if operands are the same objects.

Use in your own subclass by setting e.g.

expr = MultiFunction.reuse_if_untouched

as a default rule.

ufl_type(o, *args)#

Trigger error for types with missing handlers.

undefined(o, *args)[source]#

Trigger error for types with missing handlers.

class ufl.algorithms.ReuseTransformer(variable_cache=None)[source]#

Bases: Transformer

Reuse transformer.

Initialise.

expr(o, *ops)#

Reuse object if operands are the same objects.

Use in your own subclass by setting e.g. expr = MultiFunction.reuse_if_untouched as a default rule.

terminal(o)#

Reuse Expr (ignore children).

variable(o)#

Reuse variable.

class ufl.algorithms.Transformer(variable_cache=None)[source]#

Bases: object

Transformer.

Base class for a visitor-like algorithm design pattern used to transform expression trees from one representation to another.

Initialise.

always_reconstruct(o, *operands)[source]#

Reconstruct expr.

print_visit_stack()[source]#

Print visit stack.

reconstruct_variable(o)[source]#

Reconstruct variable.

reuse(o)[source]#

Reuse Expr (ignore children).

reuse_if_possible(o, *ops)#

Reuse object if operands are the same objects.

Use in your own subclass by setting e.g. expr = MultiFunction.reuse_if_untouched as a default rule.

reuse_if_untouched(o, *ops)[source]#

Reuse object if operands are the same objects.

Use in your own subclass by setting e.g. expr = MultiFunction.reuse_if_untouched as a default rule.

reuse_variable(o)[source]#

Reuse variable.

terminal(o)#

Reuse Expr (ignore children).

ufl_type(o)#

Trigger error.

undefined(o)[source]#

Trigger error.

visit(o)[source]#

Visit.

ufl.algorithms.apply_transformer(e, transformer, integral_type=None)[source]#

Apply transforms.

Apply transformer.visit(expression) to each integrand expression in form, or to form if it is an Expr.

ufl.algorithms.change_to_reference_grad(e)[source]#

Change Grad objects in expression to products of JacobianInverse and ReferenceGrad.

Assumes the expression is preprocessed or at least that derivatives have been expanded.

Parameters:

e – An Expr or Form.

ufl.algorithms.compute_energy_norm(form, coefficient)[source]#

Compute the a-norm of a Coefficient given a form a.

This works simply by replacing the two Arguments with a Coefficient on the same function space (element). The Form returned will thus be a functional with no Arguments, and one additional Coefficient at the end if no coefficient has been provided.

ufl.algorithms.compute_form_action(form, coefficient)[source]#

Compute the action of a form on a Coefficient.

This works simply by replacing the last Argument with a Coefficient on the same function space (element). The form returned will thus have one Argument less and one additional Coefficient at the end if no Coefficient has been provided.

ufl.algorithms.compute_form_adjoint(form, reordered_arguments=None)[source]#

Compute the adjoint of a bilinear form.

This works simply by swapping the number and part of the two arguments, but keeping their elements and places in the integrand expressions.

ufl.algorithms.compute_form_arities(form)[source]#

Return set of arities of terms present in form.

ufl.algorithms.compute_form_data(form, do_apply_function_pullbacks=False, do_apply_integral_scaling=False, do_apply_geometry_lowering=False, preserve_geometry_types=(), do_apply_default_restrictions=True, do_apply_restrictions=True, do_estimate_degrees=True, do_append_everywhere_integrals=True, do_replace_functions=False, coefficients_to_split=None, complex_mode=False, do_remove_component_tensors=False)[source]#

Compute form data.

The default arguments configured to behave the way old FFC expects.

ufl.algorithms.compute_form_functional(form)[source]#

Compute the functional part of a form, that is the terms independent of Arguments.

(Used for testing, not sure if it’s useful for anything?)

ufl.algorithms.compute_form_lhs(form)[source]#

Compute the left hand side of a form.

Example

a = u*v*dx + f*v*dx a = lhs(a) -> u*v*dx

ufl.algorithms.compute_form_rhs(form)[source]#

Compute the right hand side of a form.

Example

a = u*v*dx + f*v*dx L = rhs(a) -> -f*v*dx

ufl.algorithms.compute_form_signature(form, renumbering)[source]#

Compute form signature.

ufl.algorithms.estimate_total_polynomial_degree(e, default_degree=1, element_replace_map={})[source]#

Estimate total polynomial degree of integrand.

NB: Although some compound types are supported here, some derivatives and compounds must be preprocessed prior to degree estimation. In generic code, this algorithm should only be applied after preprocessing.

For coefficients defined on an element with unspecified degree (None), the degree is set to the given default degree.

ufl.algorithms.expand_derivatives(form, **kwargs)[source]#

Expand all derivatives of expr.

In the returned expression g which is mathematically equivalent to expr, there are no VariableDerivative or CoefficientDerivative objects left, and Grad objects have been propagated to Terminal nodes.

ufl.algorithms.expand_indices(e)[source]#

Expand indices.

ufl.algorithms.extract_arguments(a)[source]#

Build a sorted list of all arguments in a.

Parameters:

a – A BaseForm, Integral or Expr

ufl.algorithms.extract_base_form_operators(a)[source]#

Build a sorted list of all base form operators in a.

Parameters:

a – A BaseForm, Integral or Expr

ufl.algorithms.extract_coefficients(a)[source]#

Build a sorted list of all coefficients in a.

Parameters:

a – A BaseForm, Integral or Expr

ufl.algorithms.extract_elements(form)[source]#

Build sorted tuple of all elements used in form.

ufl.algorithms.extract_sub_elements(elements)[source]#

Build sorted tuple of all sub elements (including parent element).

ufl.algorithms.extract_type(a, ufl_types)[source]#

Build a set of all objects found in a whose class is in ufl_types.

Parameters:
  • a – A BaseForm, Integral or Expr

  • ufl_types – A list of UFL types

Returns:

All objects found in a whose class is in ufl_type

ufl.algorithms.extract_unique_elements(form)[source]#

Build sorted tuple of all unique elements used in form.

ufl.algorithms.load_forms(filename)[source]#

Return a list of all forms in a file.

ufl.algorithms.load_ufl_file(filename)[source]#

Load a UFL file with elements, coefficients, expressions and forms.

ufl.algorithms.post_traversal(expr)[source]#

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

ufl.algorithms.preprocess_form(form, complex_mode)[source]#

Preprocess a form.

ufl.algorithms.read_ufl_file(filename)[source]#

Read a UFL file.

ufl.algorithms.replace(e, mapping)[source]#

Replace subexpressions in expression.

Params:

e: An Expr or Form mapping: A dict with from:to replacements to perform

Returns:

The expression with replacements performed

ufl.algorithms.replace_terminal_data(o, mapping)[source]#

Return a new form where the terminals have been replaced using the provided mapping.

Parameters:
  • o – The object to have its terminals replaced. This must either be a Form or Integral.

  • mapping – A mapping suitable for reconstructing the form such as the one returned by strip_terminal_data.

Returns:

The new form.

ufl.algorithms.sort_elements(elements)[source]#

Sort elements.

A sort is performed so that any sub elements appear before the corresponding mixed elements. This is useful when sub elements need to be defined before the corresponding mixed elements.

The ordering is based on sorting a directed acyclic graph.

ufl.algorithms.strip_terminal_data(o)[source]#

Return a new form where all terminals have been replaced by UFL-only equivalents.

This function is useful for forms containing augmented UFL objects that hold references to large data structures. These objects are be extracted into the mapping allowing the form to be cached without leaking memory.

Parameters:

o – The object to be stripped. This must either be a Form or Integral

Returns:

A 2-tuple containing an equivalent UFL-only object and a mapping allowing the original form to be reconstructed using replace_terminal_data

ufl.algorithms.strip_variables(e)[source]#

Replace all Variable instances with the expression they represent.

ufl.algorithms.tree_format(expression, indentation=0, parentheses=True)[source]#

Tree format.

ufl.algorithms.validate_form(form)[source]#

Performs all implemented validations on a form. Raises exception if something fails.