# ufl.algorithms package

## Submodules

## ufl.algorithms.ad module

Front-end for AD routines.

ufl.algorithms.ad.expand_derivatives(form, **kwargs)

  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.analysis module

Utility algorithms for inspection of and information extraction from UFL objects.

ufl.algorithms.analysis.extract_arguments(a)

  Build a sorted list of all arguments in a.

  Args:

    a: A BaseForm, Integral or Expr

ufl.algorithms.analysis.extract_base_form_operators(a)

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

  Args:

    a: A BaseForm, Integral or Expr

ufl.algorithms.analysis.extract_coefficients(a)

  Build a sorted list of all coefficients in a.

  Args:

    a: A BaseForm, Integral or Expr

ufl.algorithms.analysis.extract_constants(a)

  Build a sorted list of all constants in a.

  Args:

    a: A BaseForm, Integral or Expr

ufl.algorithms.analysis.extract_elements(form)

  Build sorted tuple of all elements used in form.

ufl.algorithms.analysis.extract_sub_elements(elements)

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

ufl.algorithms.analysis.extract_terminals_with_domain(a)

  Build three sorted lists of all arguments, coefficients, and geometric quantities in a.

  This function is faster than extracting each type of terminal separately for large forms, and has more validation built in.

  Args:

    a: A BaseForm, Integral or Expr

  Returns:

    Tuples of extracted `Argument`s, `Coefficient`s, and `GeometricQuantity`s.

ufl.algorithms.analysis.extract_type(a, ufl_types)

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

  Args:

    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.analysis.extract_unique_elements(form)

  Build sorted tuple of all unique elements used in form.

ufl.algorithms.analysis.has_exact_type(a, ufl_type)

  Return if an object of class ufl_type can be found in a.

  Args:

    a: A BaseForm, Integral or Expr ufl_type: A UFL type

  Returns:

    Whether an object of class ufl_type can be found in a

ufl.algorithms.analysis.has_type(a, ufl_type)

  Return if an object of class ufl_type or a subclass can be found in a.

  Args:

    a: A BaseForm, Integral or Expr ufl_type: A UFL type

  Returns:

    Whether an object of class ufl_type can be found in a

ufl.algorithms.analysis.sort_elements(elements)

  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.analysis.unique_tuple(objects)

  Return tuple of unique objects, preserving initial ordering.

## ufl.algorithms.apply_algebra_lowering module

Algorithm for expanding compound expressions.

class ufl.algorithms.apply_algebra_lowering.LowerCompoundAlgebra

  Bases: `MultiFunction`

  Expands high level compound operators to equivalent representations using basic operators.

  cofactor(o, A)

    Lower a cofactor.

  cross(o, a, b)

    Lower a cross.

  curl(o, a)

    Lower a curl.

  determinant(o, A)

    Lower a determinant.

  deviatoric(o, A)

    Lower a deviatoric.

  div(o, a)

    Lower a div.

  dot(o, a, b)

    Lower a dot.

  inner(o, a, b)

    Lower an inner.

  inverse(o, A)

    Lower an inverse.

  nabla_div(o, a)

    Lower a nabla_div.

  nabla_grad(o, a)

    Lower a nabla_grad.

  outer(o, a, b)

    Lower an outer.

  perp(o, a)

    Lower a perp.

  skew(o, A)

    Lower a skew.

  sym(o, A)

    Lower a sym.

  trace(o, A)

    Lower a trace.

  transposed(o, A)

    Lower a transposed.

  ufl_type(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.

ufl.algorithms.apply_algebra_lowering.apply_algebra_lowering(expr)

  Expands high level compound operators to equivalent representations using basic operators.

## ufl.algorithms.apply_coefficient_split module

Apply coefficient split.

This module contains the apply_coefficient_split function that decomposes mixed coefficients in the given Expr into components.

class ufl.algorithms.apply_coefficient_split.CoefficientSplitter(coefficient_split: dict, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `DAGTraverser`

  DAGTraverser to split mixed coefficients.

  process(o: Expr, reference_value: bool | None = False, reference_grad: int | None = 0, restricted: str | None = None) → Expr
  process(o: Expr, reference_value: bool | None = False, reference_grad: int | None = 0, restricted: str | None = None) → Expr
  process(o: Expr, reference_value: bool | None = False, reference_grad: int | None = 0, restricted: str | None = None) → Expr
  process(o: Expr, reference_value: bool = False, reference_grad: int = 0, restricted: str | None = None) → Expr
  process(o: Restricted, reference_value: bool | None = False, reference_grad: int | None = 0, restricted: str | None = None) → Expr
  process(o: Expr, reference_value: bool | None = False, reference_grad: int = 0, restricted: str | None = None) → Expr
  process(o: Expr, reference_value: bool | None = False, reference_grad: int = 0, restricted: str | None = None) → Expr

    Split mixed coefficients.

    Args:

      o: Expr to be processed. reference_value: Whether ReferenceValue has been applied or not. reference_grad: Number of `ReferenceGrad`s that have been applied. restricted: ‘+’, ‘-’, or None.

    Returns:

      This `o` wrapped with ReferenceValue (if `reference_value`), ReferenceGrad (`reference_grad` times), and Restricted (if `restricted` is ‘+’ or ‘-‘). The underlying terminal will be decomposed into components according to `self._coefficient_split`.

ufl.algorithms.apply_coefficient_split.apply_coefficient_split(expr: Expr, coefficient_split: dict) → Expr

  Split mixed coefficients.

  Args:

    expr: UFL expression. coefficient_split: dict that maps mixed coefficients to their components.

  Returns:

    `expr` with uderlying mixed coefficients split according to `coefficient_split`.

## ufl.algorithms.apply_derivatives module

Apply derivatives algorithm which computes the derivatives of a form of expression.

class ufl.algorithms.apply_derivatives.BaseFormOperatorDerivativeRecorder(var, **kwargs)

  Bases: `object`

  A derivative recorded for a base form operator.

class ufl.algorithms.apply_derivatives.BaseFormOperatorDerivativeRuleset(coefficients: ExprList, arguments: ExprList, coefficient_derivatives: ExprMapping, outer_base_form_op: Expr, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `GateauxDerivativeRuleset`

  Apply AFD (Automatic Functional Differentiation) to BaseFormOperator.

  Implements rules for the Gateaux derivative D_w[v](…) defined as D_w[v](B) = d/dtau B(w+tau v)|tau=0 where B is a ufl.BaseFormOperator.

  external_operator(base_form_op, *dfs)

    Decorate.

  static pending_operations_recording(base_form_operator_handler)

    Decorate a function to record pending operations.

  process(o: Expr) → Expr
  process(base_form_op: Interpolate, *dfs)
  process(base_form_op: ExternalOperator, *dfs)

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

class ufl.algorithms.apply_derivatives.CoordinateDerivativeRuleDispatcher(compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `DAGTraverser`

  Dispatcher.

  process(o: Expr) → Expr
  process(o: Expr | BaseForm) → Expr | BaseForm
  process(o: Expr | BaseForm) → Expr | BaseForm
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr, f: Expr) → Expr

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

class ufl.algorithms.apply_derivatives.CoordinateDerivativeRuleset(coefficients: ExprList, arguments: ExprList, coefficient_derivatives: ExprMapping, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `GenericDerivativeRuleset`

  Apply AFD (Automatic Functional Differentiation) to expression.

  Implements rules for the Gateaux derivative D_w[v](…) defined as D_w[v](e) = d/dtau e(w+tau v)|tau=0 where ‘e’ is a ufl form after pullback and w is a SpatialCoordinate.

  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(g: Expr) → Expr
  process(o: Expr) → Expr

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

class ufl.algorithms.apply_derivatives.DerivativeRuleDispatcher(compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `DAGTraverser`

  Dispatch a derivative rule.

  process(o: Expr) → Expr
  process(o: Expr | BaseForm) → Expr | BaseForm
  process(o: Expr | BaseForm) → Expr | BaseForm
  process(o: Terminal) → Terminal
  process(o: Derivative) → Expr
  process(o: Grad, f: Expr | BaseForm) → Expr
  process(o: ReferenceGrad, f: Expr | BaseForm) → Expr | BaseForm
  process(o: Expr, f: Expr | BaseForm) → Expr | BaseForm
  process(o: CoefficientDerivative, f: Expr | BaseForm) → Expr | BaseForm
  process(o: BaseFormOperatorDerivative, f: Expr | BaseForm) → Expr | BaseForm
  process(o: Expr, f: Expr | BaseForm) → CoordinateDerivative
  process(o: Expr, f: Expr | BaseForm) → BaseFormCoordinateDerivative
  process(o: Indexed, Ap: Expr, ii: MultiIndex) → Expr | BaseForm

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

class ufl.algorithms.apply_derivatives.GateauxDerivativeRuleset(coefficients: ExprList, arguments: ExprList, coefficient_derivatives: ExprMapping, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `GenericDerivativeRuleset`

  Apply AFD (Automatic Functional Differentiation) to expression.

  Implements rules for the Gateaux derivative D_w[v](…) defined as D_w[v](e) = d/dtau e(w+tau v)|tau=0.

  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Argument) → Expr
  process(o: Coefficient) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(g: Expr) → Expr
  process(o: Expr, o0: Expr) → Expr
  process(o: BaseFormOperator, *dfs) → Expr
  process(o: Cofunction) → Expr
  process(o: Coargument) → Expr
  process(M: Matrix) → BaseForm

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

class ufl.algorithms.apply_derivatives.GenericDerivativeRuleset(var_shape: tuple, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `DAGTraverser`

  A generic derivative.

  independent_operator(o)

    A zero with correct shape and indices for operators independent of diff. variable.

  independent_terminal(o)

    A zero with correct shape for terminals independent of diff. variable.

  non_differentiable_terminal(o)

    Return the non-differentiated object.

    Labels and indices are not differentiable: it’s convenient to return the non-differentiated object.

  override(o)

    Raise error about overriding.

  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Indexed, Ap: Expr, ii: MultiIndex) → Expr
  process(o: Expr) → Expr
  process(o: ComponentTensor, Ap: Expr, ii: MultiIndex) → Expr
  process(o: Expr, Ap: Expr, ii: Expr) → Expr
  process(o: Expr, da: Expr, db: Expr) → Expr
  process(o: Expr, da: Expr, db: Expr) → Expr
  process(o: Expr, fp: Expr, gp: Expr) → Expr
  process(o: Expr, fp: Expr, gp: Expr) → Expr
  process(o: Expr, df: Expr) → Expr
  process(o: Expr, df: Expr) → Expr
  process(o: Expr, df: Expr) → Expr
  process(o: Expr, df: Expr) → Expr
  process(o: Expr, df: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, fp: Expr, gp: Expr) → Expr
  process(o: Expr, fp: Expr) → Expr
  process(o: Expr, nup: Expr, fp: Expr) → Expr
  process(o: Expr, nup: Expr, fp: Expr) → Expr
  process(o: Expr, nup: Expr, fp: Expr) → Expr
  process(o: Expr, nup: Expr, fp: Expr) → Expr
  process(o: Restricted, fp: Expr) → Expr
  process(o: BinaryCondition) → Expr
  process(o: NotCondition) → Expr
  process(o: Expr, dt: Expr, df: Expr) → Expr
  process(o: Expr, df: Expr, dg: Expr) → Expr
  process(o: Expr, df: Expr, dg: Expr) → Expr

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

  unexpected(o)

    Raise error about unexpected type.

class ufl.algorithms.apply_derivatives.GradRuleset(geometric_dimension: int, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `GenericDerivativeRuleset`

  Take the grad derivative.

  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: JacobianInverse) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: ReferenceValue) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

class ufl.algorithms.apply_derivatives.ReferenceGradRuleset(topological_dimension: int, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `GenericDerivativeRuleset`

  Apply the reference grad derivative.

  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

class ufl.algorithms.apply_derivatives.VariableRuleset(var: Expr, compress: bool | None = True, visited_cache: dict[tuple, Expr] | None = None, result_cache: dict[Expr, Expr] | None = None)

  Bases: `GenericDerivativeRuleset`

  Differentiate with respect to a variable.

  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr, df: Expr, a: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr
  process(o: Expr) → Expr

    Process `o`.

    Args:

      o: Expr to be processed.

    Returns:

      Processed object.

ufl.algorithms.apply_derivatives.apply_coordinate_derivatives(expression)

  Apply coordinate derivatives to an expression.

ufl.algorithms.apply_derivatives.apply_derivatives(expression)

  Apply derivatives to an expression.

  Args:

    expression: A Form, an Expr or a BaseFormOperator to be differentiated

  Returns:

    A differentiated expression

ufl.algorithms.apply_derivatives.flatten_domain_element(domain, element)

  Return the flattened (domain, element) pairs for mixed domain problems.

  Args:

    domain: Mesh or MeshSequence. element: FiniteElement.

  Returns:

    Nested tuples of (domain, element) pairs; just ((domain, element),) if domain is a Mesh (and not a MeshSequence).

ufl.algorithms.apply_derivatives.grad_to_reference_grad(o, K)

  Relates grad(o) to reference_grad(o) using the Jacobian inverse.

  Args:

    o: Operand K: Jacobian inverse

  Returns:

    grad(o) written in terms of reference_grad(o) and K

## ufl.algorithms.apply_function_pullbacks module

Algorithm for replacing gradients in an expression.

class ufl.algorithms.apply_function_pullbacks.FunctionPullbackApplier

  Bases: `MultiFunction`

  A pull back applier.

  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.

  form_argument(o)
  terminal(t)

    Apply to a terminal.

ufl.algorithms.apply_function_pullbacks.apply_function_pullbacks(expr)

  Change representation of coefficients and arguments in an expression.

  Applies Piola mappings where applicable and represents all form arguments in reference value.

  Args:

    expr: An Expression

## ufl.algorithms.apply_geometry_lowering module

Algorithm for lowering abstractions of geometric types.

This means replacing high-level types with expressions of mostly the Jacobian and reference cell data.

class ufl.algorithms.apply_geometry_lowering.GeometryLoweringApplier(preserve_types=())

  Bases: `MultiFunction`

  Geometry lowering.

  cell_coordinate(o)
  cell_diameter(o)
  cell_normal(o)
  cell_volume(o)
  circumradius(o)
  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.

  facet_area(o)
  facet_cell_coordinate(o)
  facet_jacobian(o)
  facet_jacobian_determinant(o)
  facet_jacobian_inverse(o)
  facet_normal(o)
  jacobian(o)
  jacobian_determinant(o)
  jacobian_inverse(o)
  max_cell_edge_length(o)
  max_facet_edge_length(o)
  min_cell_edge_length(o)
  min_facet_edge_length(o)
  ridge_jacobian(o)
  ridge_jacobian_determinant(o)
  ridge_jacobian_inverse(o)
  spatial_coordinate(o)
  terminal(t)

    Apply to terminal.

ufl.algorithms.apply_geometry_lowering.apply_geometry_lowering(form, preserve_types=())

  Change GeometricQuantity objects in expression to the lowest level GeometricQuantity objects.

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

  Args:

    form: An Expr or Form. preserve_types: Preserved types

## ufl.algorithms.apply_integral_scaling module

Algorithm for replacing gradients in an expression.

ufl.algorithms.apply_integral_scaling.apply_integral_scaling(form)

  Multiply integrands by a factor to scale the integral to reference frame.

ufl.algorithms.apply_integral_scaling.compute_integrand_scaling_factor(integral)

  Change integrand geometry to the right representations.

## ufl.algorithms.apply_restrictions module

Apply restrictions.

This module contains the apply_restrictions algorithm which propagates restrictions in a form towards the terminals.

class ufl.algorithms.apply_restrictions.RestrictionPropagator(side=None, apply_default=True)

  Bases: `MultiFunction`

  Restriction propagator.

  argument(o)

    Restrict a discontinuous quantity to current side, require a side to be set.

  coefficient(o)

    Restrict a coefficient.

    Allow coefficients to be unrestricted (apply default if so) if the values are fully continuous across the facet.

  constant(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  constant_value(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  facet_area(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  facet_coordinate(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  facet_jacobian(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  facet_jacobian_determinant(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  facet_jacobian_inverse(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  facet_normal(o)

    Restrict a facet_normal.

  facet_origin(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  geometric_cell_quantity(o)

    Restrict a discontinuous quantity to current side, require a side to be set.

  geometric_facet_quantity(o)

    Restrict a discontinuous quantity to current side, require a side to be set.

  grad(o)

    Restrict a discontinuous quantity to current side, require a side to be set.

  label(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  max_facet_edge_length(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  min_facet_edge_length(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  multi_index(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  operator(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.

  quadrature_weight(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  reference_cell_volume(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  reference_facet_volume(o)

    Ignore current restriction.

    Quantity is independent of side also from a computational point of view.

  reference_value(o)

    Reference value of something follows same restriction rule as the underlying object.

  restricted(o)

    When hitting a restricted quantity, visit child with a separate restriction algorithm.

  spatial_coordinate(o)

    Restrict a continuous quantity to default side if no current restriction is set.

  terminal(o)

    Raise an error.

  variable(o, op, label)

    Strip variable.

ufl.algorithms.apply_restrictions.apply_restrictions(expression, apply_default=True)

  Propagate restriction nodes to wrap differential terminals directly.

## ufl.algorithms.balancing module

Balancing.

class ufl.algorithms.balancing.BalanceModifiers

  Bases: `MultiFunction`

  Balance modifiers.

  cell_avg(expr, *ops)

    Apply to _modifier.

  expr(expr, *ops)

    Apply to expr.

  facet_avg(expr, *ops)

    Apply to _modifier.

  grad(expr, *ops)

    Apply to _modifier.

  negative_restricted(expr, *ops)

    Apply to _modifier.

  positive_restricted(expr, *ops)

    Apply to _modifier.

  reference_grad(expr, *ops)

    Apply to _modifier.

  reference_value(expr, *ops)

    Apply to _modifier.

  terminal(expr)

    Apply to terminal.

ufl.algorithms.balancing.balance_modified_terminal(expr)

  Balance modified terminal.

ufl.algorithms.balancing.balance_modifiers(expr)

  Balance modifiers.

## ufl.algorithms.change_to_reference module

Algorithm for replacing gradients in an expression.

class ufl.algorithms.change_to_reference.ChangeToReferenceGrad

  Bases: `MultiFunction`

  Change to reference grad.

  coefficient_derivative(o)

    Apply to coefficient_derivative.

  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.

  grad(o)

    Apply to grad.

  reference_grad(o)

    Apply to reference_grad.

  terminal(o)

    Apply to terminal.

ufl.algorithms.change_to_reference.change_integrand_geometry_representation(integrand, scale, integral_type)

  Change integrand geometry to the right representations.

ufl.algorithms.change_to_reference.change_to_reference_grad(e)

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

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

  Args:

    e: An Expr or Form.

## ufl.algorithms.check_arities module

Check arities.

class ufl.algorithms.check_arities.ArityChecker(arguments)

  Bases: `MultiFunction`

  Arity checker.

  argument(o)

    Apply to argument.

  cell_avg(o, a)

    Apply to linear_operator.

  component_tensor(o, a, i)

    Apply to linear_indexed_type.

  conditional(o, c, a, b)

    Apply to conditional.

  conj(o, a)

    Apply to conj.

  division(o, a, b)

    Apply to division.

  dot(o, a, b)

    Apply to inner.

  expr(o)

    Apply to nonlinear_operator.

  facet_avg(o, a)

    Apply to linear_operator.

  grad(o, a)

    Apply to linear_operator.

  index_sum(o, a, i)

    Apply to linear_indexed_type.

  indexed(o, a, i)

    Apply to linear_indexed_type.

  inner(o, a, b)

    Apply to inner.

  linear_indexed_type(o, a, i)

    Apply to linear_indexed_type.

  linear_operator(o, a)

    Apply to linear_operator.

  list_tensor(o, *ops)

    Apply to list_tensor.

  negative_restricted(o, a)

    Apply to linear_operator.

  nonlinear_operator(o)

    Apply to nonlinear_operator.

  outer(o, a, b)

    Apply to outer.

  positive_restricted(o, a)

    Apply to linear_operator.

  product(o, a, b)

    Apply to product.

  reference_grad(o, a)

    Apply to linear_operator.

  reference_value(o, a)

    Apply to linear_operator.

  sum(o, a, b)

    Apply to sum.

  terminal(o)

    Apply to terminal.

  variable(o, f, a)

    Apply to variable.

exception ufl.algorithms.check_arities.ArityMismatch

  Bases: `BaseException`

  Arity mismatch exception.

ufl.algorithms.check_arities.check_form_arity(form, arguments, complex_mode=False)

  Check the arity of a form.

ufl.algorithms.check_arities.check_integrand_arity(expr, arguments, complex_mode=False)

  Check the arity of an integrand.

## ufl.algorithms.check_restrictions module

Algorithms related to restrictions.

class ufl.algorithms.check_restrictions.RestrictionChecker(require_restriction)

  Bases: `MultiFunction`

  Restiction checker.

  expr(o)

    Apply to expr.

  facet_normal(o)

    Apply to facet_normal.

  form_argument(o)

    Apply to form_argument.

  restricted(o)

    Apply to restricted.

ufl.algorithms.check_restrictions.check_restrictions(expression, require_restriction)

  Check that types that must be restricted are restricted in expression.

## ufl.algorithms.checks module

Functions to check the validity of forms.

ufl.algorithms.checks.validate_form(form)

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

## ufl.algorithms.comparison_checker module

Algorithm to check for ‘comparison’ nodes in a form when the user is in ‘complex mode’.

class ufl.algorithms.comparison_checker.CheckComparisons

  Bases: `MultiFunction`

  Raises an error if comparisons are done with complex quantities.

  If quantities are real, adds the Real operator to the compared quantities.

  Terminals that are real are RealValue, Zero, and Argument (even in complex FEM, the basis functions are real) Operations that produce reals are Abs, Real, Imag. Terminals default to complex, and Sqrt, Pow (defensively) imply complex. Otherwise, operators preserve the type of their operands.

  abs(o, *ops)

    Apply to abs.

  compare(o, *ops)

    Compare.

  expr(o, *ops)

    Defaults expressions to complex unless they only act on real quantities.

    Overridden for specific operators. Rebuilds objects if necessary.

  ge(o, *ops)

    Compare.

  gt(o, *ops)

    Compare.

  imag(o, *ops)

    Apply to imag.

  indexed(o, expr, multiindex)

    Apply to indexed.

  le(o, *ops)

    Compare.

  lt(o, *ops)

    Compare.

  max_value(o, *ops)

    Apply to max_value.

  min_value(o, *ops)

    Apply to min_value.

  power(o, base, exponent)

    Apply to power.

  real(o, *ops)

    Apply to real.

  sign(o, *ops)

    Compare.

  sqrt(o, *ops)

    Apply to sqrt.

  terminal(term, *ops)

    Apply to terminal.

exception ufl.algorithms.comparison_checker.ComplexComparisonError

  Bases: `BaseException`

  Complex compariseon exception.

ufl.algorithms.comparison_checker.do_comparison_check(form)

  Raises an error if invalid comparison nodes exist.

## ufl.algorithms.compute_form_data module

This module provides the compute_form_data function.

Form compilers will typically call compute_form_dataprior to code generation to preprocess/simplify a raw input form given by a user.

ufl.algorithms.compute_form_data.attach_estimated_degrees(form)

  Attach estimated polynomial degree to a form’s integrals.

  Args:

    form: The Form` to inspect.

  Returns:

    A new Form with estimate degrees attached.

ufl.algorithms.compute_form_data.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)

  Compute form data.

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

ufl.algorithms.compute_form_data.preprocess_form(form, complex_mode)

  Preprocess a form.

## ufl.algorithms.coordinate_derivative_helpers module

Tools to strip away and reattach coordinate derivatives.

This is used in compute_form_data.

class ufl.algorithms.coordinate_derivative_helpers.CoordinateDerivativeIsOutermostChecker

  Bases: `MultiFunction`

  Traverses the tree to make sure that CoordinateDerivatives are only on the outside.

  The visitor returns False as long as no CoordinateDerivative has been seen.

  coordinate_derivative(o, expr, *_)

    Apply to coordinate derivative.

  expr(o, *operands)

    Apply to expr.

    If we have already seen a CoordinateDerivative, then no other expressions apart from more CoordinateDerivatives are allowed to wrap around it.

  multi_index(o)

    Apply to multi_index.

  terminal(o)

    Apply to terminal.

ufl.algorithms.coordinate_derivative_helpers.attach_coordinate_derivatives(integral, coordinate_derivatives)

  Attach coordinate derivatives.

ufl.algorithms.coordinate_derivative_helpers.strip_coordinate_derivatives(integrals)

  Strip coordinate derivatives.

## ufl.algorithms.domain_analysis module

Algorithms for building canonical data structure for integrals over subdomains.

class ufl.algorithms.domain_analysis.ExprTupleKey(x)

  Bases: `object`

  Tuple comparison helper.

  x

class ufl.algorithms.domain_analysis.IntegralData(domain, integral_type, subdomain_id, integrals, metadata)

  Bases: `object`

  Utility class.

  This class has members (domain, integral_type, subdomain_id, integrals, metadata), where metadata is an empty dictionary that may be used for associating metadata with each object.

  domain
  enabled_coefficients
  integral_coefficients
  integral_type
  integrals
  metadata
  subdomain_id

ufl.algorithms.domain_analysis.accumulate_integrands_with_same_metadata(integrals)

  Accumulate integrands with the same metedata.

  Args:

    integrals: a list of integrals

  Returns:

    A list of the form [(integrand0, metadata0), (integrand1, metadata1), …] where integrand0 < integrand1 by the canonical ufl expression ordering criteria.

ufl.algorithms.domain_analysis.build_integral_data(integrals)

  Build integral data given a list of integrals.

  The integrals you pass in here must have been rearranged and gathered (removing the “everywhere” subdomain_id). To do this, you should call group_form_integrals.

  Args:

    integrals: An iterable of Integral objects.

  Returns:

    A tuple of IntegralData objects.

ufl.algorithms.domain_analysis.group_form_integrals(form, domains, do_append_everywhere_integrals=True)

  Group integrals by domain and type, performing canonical simplification.

  Args:
    form:

      the Form to group the integrals of.

    domains:

      an iterable of Domains.

    do_append_everywhere_integrals:

      Boolean indicating if integrals defined on the whole domain should just be restricted to the set of input subdomain ids.

  Returns:

    A new Form with gathered integrands.

ufl.algorithms.domain_analysis.group_integrals_by_domain_and_type(integrals, domains)

  Group integrals by domain and type.

  Args:

    integrals: list of Integral objects domains: list of AbstractDomain objects from the parent Form

  Returns:

    Dictionary mapping (domain, integral_type) to list(Integral)

ufl.algorithms.domain_analysis.integral_subdomain_ids(integral)

  Get a tuple of integer subdomains or a valid string subdomain from integral.

ufl.algorithms.domain_analysis.rearrange_integrals_by_single_subdomains(integrals: list[Integral], do_append_everywhere_integrals: bool) → dict[int, list[Integral]]

  Rearrange integrals over multiple subdomains to single subdomain integrals.

  Args:
    integrals:

      List of integrals

    do_append_everywhere_integrals:

      Boolean indicating if integrals defined on the whole domain should just be restricted to the set of input subdomain ids.

  Returns:

    The integrals reconstructed with single subdomain_id

ufl.algorithms.domain_analysis.reconstruct_form_from_integral_data(integral_data)

  Reconstruct a form from integral data.

## ufl.algorithms.estimate_degrees module

Algorithms for estimating polynomial degrees of expressions.

class ufl.algorithms.estimate_degrees.SumDegreeEstimator(default_degree, element_replace_map)

  Bases: `MultiFunction`

  Sum degree estimator.

  This algorithm is exact for a few operators and heuristic for many.

  abs(v, a)

    Apply to abs.

    This is a heuristic, correct if there is no.

  argument(v)

    Apply to argument.

    A form argument provides a degree depending on the element, or the default degree if the element has no degree.

  atan2(v, a, b)

    Apply to atan2.

    Using the heuristic: degree(atan2(const,const)) == 0 degree(atan2(a,b)) == max(degree(a),degree(b))+2 which can be wildly inaccurate but at least gives a somewhat high integration degree.

  bessel_function(v, nu, x)

    Apply to bessel_function.

    Using the heuristic degree(bessel_*(const)) == 0 degree(bessel_*(x)) == degree(x)+2 which can be wildly inaccurate but at least gives a somewhat high integration degree.

  cell_avg(v, a)

    Apply to cell_avg.

    Cell average of a function is always cellwise constant.

  cell_coordinate(v)

    Apply to cell_coordinate.

    A coordinate provides one additional degree.

  coefficient(v)

    Apply to coefficient.

    A form argument provides a degree depending on the element, or the default degree if the element has no degree.

  cofactor(v, *args)

    Apply to _not_handled.

  component_tensor(v, A, ii)

    Apply to component_tensor.

  compound_derivative(v, *args)

    Apply to _not_handled.

  compound_tensor_operator(v, *args)

    Apply to _not_handled.

  condition(v, *args)

    Apply to condition.

  conditional(v, c, t, f)

    Apply to conditional.

    Degree of condition does not influence degree of values which conditional takes. So heuristicaly taking max of true degree and false degree. This will be exact in cells where condition takes single value. For improving accuracy of quadrature near condition transition surface quadrature order must be adjusted manually.

  conj(v, a)

    Apply to conj.

  constant(v)

    Apply to constant.

  constant_value(v)

    Apply to constant_value.

    Constant values are constant.

  coordinate_derivative(v, integrand_degree, b, direction_degree, d)

    Apply to coordinate_derivative.

    We use the heuristic that a shape derivative in direction V introduces terms V and grad(V) into the integrand. Hence we add the degree of the deformation to the estimate.

  cross(v, *ops)

    Apply to _add_degrees.

  curl(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  derivative(v, *args)

    Apply to _not_handled.

  determinant(v, *args)

    Apply to _not_handled.

  deviatoric(v, *args)

    Apply to _not_handled.

  div(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  division(v, *ops)

    Apply to division.

    Using the sum here is a heuristic. Consider e.g. (x+1)/(x-1).

  dot(v, *ops)

    Apply to _add_degrees.

  expr(v, *ops)

    Apply to expr.

    For most operators we take the max degree of its operands.

  expr_list(v, *o)

    Apply to expr_list.

  expr_mapping(v, *o)

    Apply to expr_mapping.

  facet_avg(v, a)

    Apply to facet_avg.

    Facet average of a function is always cellwise constant.

  geometric_quantity(v)

    Apply to geometric_quantity.

    Some geometric quantities are cellwise constant. Others are nonpolynomial and thus hard to estimate.

  grad(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  imag(v, a)

    Apply to imag.

  index_sum(v, A, ii)

    Apply to index_sum.

  indexed(v, A, ii)

    Apply to indexed.

  inner(v, *ops)

    Apply to _add_degrees.

  inverse(v, *args)

    Apply to _not_handled.

  label(v)

    Apply to label.

  list_tensor(v, *ops)

    Apply to _max_degrees.

  math_function(v, a)

    Apply to math_function.

    Using the heuristic: degree(sin(const)) == 0 degree(sin(a)) == degree(a)+2 which can be wildly inaccurate but at least gives a somewhat high integration degree.

  max_value(v, a, r)

    Apply to min_value.

    Same as conditional.

  min_value(v, a, r)

    Apply to min_value.

    Same as conditional.

  multi_index(v)

    Apply to multi_index.

  nabla_div(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  nabla_grad(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  negative_restricted(v, a)

    Apply to negative_restricted.

  outer(v, *ops)

    Apply to _add_degrees.

  positive_restricted(v, a)

    Apply to positive_restricted.

  power(v, a, b)

    Apply to power.

    If b is a positive integer: degree(a**b) == degree(a)*b otherwise use the heuristic: degree(a**b) == degree(a) + 2.

  product(v, *ops)

    Apply to _add_degrees.

  real(v, a)

    Apply to real.

  reference_curl(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  reference_div(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  reference_grad(v, f)

    Reduce the estimated degree by one.

    This is used when derivatives are taken. It does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  reference_value(rv, f)

    Apply to reference_value.

  skew(v, *args)

    Apply to _not_handled.

  spatial_coordinate(v)

    Apply to spatial_coordinate.

    A coordinate provides additional degrees depending on coordinate field of domain.

  sum(v, *ops)

    Apply to _max_degrees.

  sym(v, *args)

    Apply to _not_handled.

  trace(v, *args)

    Apply to _not_handled.

  transposed(v, A)

    Apply to transposed.

  variable(v, e, a)

    Apply to variable.

  variable_derivative(v, *args)

    Apply to _not_handled.

ufl.algorithms.estimate_degrees.estimate_total_polynomial_degree(e, default_degree=1, element_replace_map={})

  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_indices module

This module defines expression transformation utilities.

These utilities are for expanding free indices in expressions to explicit fixed indices only.

class ufl.algorithms.expand_indices.IndexExpander

  Bases: `ReuseTransformer`

  Index expander.

  component()

    Return current component tuple.

  component_tensor(x)

    Apply to component_tensor.

  conditional(x)

    Apply to conditional.

  division(x)

    Apply to division.

  form_argument(x)

    Apply to form_argument.

  grad(x)

    Apply to grad.

  index_sum(x)

    Apply to index_sum.

  indexed(x)

    Apply to indexed.

  list_tensor(x)

    Apply to list_tensor.

  multi_index(x)

    Apply to multi_index.

  scalar_value(x)

    Apply to scalar_value.

  terminal(x)

    Apply to terminal.

  zero(x)

    Apply to zero.

ufl.algorithms.expand_indices.expand_indices(e)

  Expand indices.

## ufl.algorithms.formdata module

FormData class easy for collecting of various data about a form.

class ufl.algorithms.formdata.FormData

  Bases: `object`

  Class collecting various information extracted from a Form by calling preprocess.

## ufl.algorithms.formfiles module

A collection of utility algorithms for handling UFL files.

class ufl.algorithms.formfiles.FileData

  Bases: `object`

  File data.

ufl.algorithms.formfiles.execute_ufl_code(uflcode)

  Execute code.

ufl.algorithms.formfiles.interpret_ufl_namespace(namespace)

  Take a namespace dict from an executed ufl file and convert it to a FileData object.

ufl.algorithms.formfiles.load_forms(filename)

  Return a list of all forms in a file.

ufl.algorithms.formfiles.load_ufl_file(filename)

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

ufl.algorithms.formfiles.read_lines_decoded(fn)

  Read decoded lines of a UFL file.

ufl.algorithms.formfiles.read_ufl_file(filename)

  Read a UFL file.

## ufl.algorithms.formsplitter module

Extract part of a form in a mixed FunctionSpace.

class ufl.algorithms.formsplitter.FormSplitter(replace_argument: bool = True)

  Bases: `MultiFunction`

  Form splitter.

  argument(obj)

    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)

    Extract indexed entry if multindices are fixed.

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

  multi_index(obj)

    Apply to multi_index.

  restricted(o)

    Apply to a restricted function.

  split(form, ix, iy=None)

    Split form based on the argument part/number.

ufl.algorithms.formsplitter.extract_blocks(form, i: int | None = None, j: int | None = None, arity: int | None = None, replace_argument: bool = True) → Form | tuple[Form | None, ...] | tuple[tuple[Form | None, ...], ...]

  Extract blocks of a form.

  If arity is 0, returns the form. If arity is 1, return the ith block. If `i` is `None`, return all blocks. If arity is 2, return the `(i,j)` entry. If `j` is `None`, return the ith row.

  If neither i nor j are set, return all blocks (as a scalar, vector or tensor).

  Args:

    form: A form i: Index of the block to extract. If set to `None`, `j` must be None. j: Index of the block to extract. arity: Arity of the form. If not set, it will be inferred from the form. replace_argument: If True, replace the argument by a new argument

    > in the (collapsed) sub-function space. If False, keep the original argument.

## ufl.algorithms.formtransformations module

Utilities for transforming complete Forms into new related Forms.

class ufl.algorithms.formtransformations.PartExtracter(arguments)

  Bases: `Transformer`

  PartExtracter extracts those parts of a form that contain the given argument(s).

  argument(x)

    Return itself unless itself provides too much.

  cell_avg(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  component_tensor(x)

    Return parts of expression belonging to this indexed expression.

  conj(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  division(x)

    Return parts_of_numerator/denominator.

  dot(x, *ops)

    Apply to product.

    Note: Product is a visit-children-first handler. ops are the visited factors.

  expr(x)

    Apply to expr.

    The default is a nonlinear operator not accepting any Arguments among its children.

  facet_avg(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  grad(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  imag(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  index_sum(x)

    Return parts of expression belonging to this indexed expression.

  indexed(x)

    Return parts of expression belonging to this indexed expression.

  inner(x, *ops)

    Apply to product.

    Note: Product is a visit-children-first handler. ops are the visited factors.

  linear_indexed_type(x)

    Return parts of expression belonging to this indexed expression.

  linear_operator(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  list_tensor(x, *ops)

    Apply to list_tensor.

  negative_restricted(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  outer(x, *ops)

    Apply to product.

    Note: Product is a visit-children-first handler. ops are the visited factors.

  positive_restricted(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  product(x, *ops)

    Apply to product.

    Note: Product is a visit-children-first handler. ops are the visited factors.

  real(x, arg)

    Apply to linear_operator.

    A linear operator with a single operand accepting arity > 0, providing whatever Argument its operand does.

  sum(x)

    Return the terms that might eventually yield the correct parts(!).

    The logic required for sums is a bit elaborate:

    A sum may contain terms providing different arguments. We should return (a sum of) a suitable subset of these terms. Those should all provide the same arguments.

    For each term in a sum, there are 2 simple possibilities:

    1a) The relevant part of the term is zero -> skip. 1b) The term provides more arguments than we want -> skip

    2) If all terms fall into the above category, we can just return zero.

    Any remaining terms may provide exactly the arguments we want, or fewer. This is where things start getting interesting.

    3) Bottom-line: if there are terms with providing different arguments – provide terms that contain the most arguments. If there are terms providing different sets of same size -> throw error (e.g. Argument(-1) + Argument(-2)).

  terminal(x)

    Apply to expr.

    The default is a nonlinear operator not accepting any Arguments among its children.

  variable(x)

    Return relevant parts of this variable.

ufl.algorithms.formtransformations.compute_energy_norm(form, coefficient)

  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.formtransformations.compute_form_action(form, coefficient)

  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.formtransformations.compute_form_adjoint(form, reordered_arguments=None)

  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.formtransformations.compute_form_arities(form)

  Return set of arities of terms present in form.

ufl.algorithms.formtransformations.compute_form_functional(form)

  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.formtransformations.compute_form_lhs(form)

  Compute the left hand side of a form.

  Example:

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

ufl.algorithms.formtransformations.compute_form_rhs(form)

  Compute the right hand side of a form.

  Example:

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

ufl.algorithms.formtransformations.compute_form_with_arity(form, arity, arguments=None)

  Compute parts of form of given arity.

  Note:

    If the form has no parts of the specified arity, this will return 0*form.

ufl.algorithms.formtransformations.zero_expr(e)

  Create a zero expression.

## ufl.algorithms.map_integrands module

Basic algorithms for applying functions to sub-expressions.

ufl.algorithms.map_integrands.map_integrand_dags(function, form, only_integral_type=None, compress=True)

  Map integrand dags.

ufl.algorithms.map_integrands.map_integrands(function, form, only_integral_type=None)

  Map integrands.

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

## ufl.algorithms.remove_complex_nodes module

Remove conj, real, and imag nodes from a form.

class ufl.algorithms.remove_complex_nodes.ComplexNodeRemoval

  Bases: `MultiFunction`

  Replaces complex operator nodes with their children.

  conj(o, a)

    Apply to conj.

  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.

  imag(o, a)

    Apply to imag.

  real(o, a)

    Apply to real.

  terminal(t, *ops)

    Apply to terminal.

ufl.algorithms.remove_complex_nodes.remove_complex_nodes(expr)

  Replaces complex operator nodes with their children.

  This is called during compute_form_data if the compiler wishes to compile real-valued forms. In essence this strips all trace of complex support from the preprocessed form.

## ufl.algorithms.remove_component_tensors module

Remove component tensors.

This module contains classes and functions to remove component tensors.

class ufl.algorithms.remove_component_tensors.IndexRemover

  Bases: `MultiFunction`

  Remove Indexed.

  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, o1, i1)

    Simplify Indexed.

class ufl.algorithms.remove_component_tensors.IndexReplacer(fimap: dict)

  Bases: `MultiFunction`

  Replace Indices.

  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.

  multi_index(o)

    Handle MultiIndex.

  zero(o)

    Handle Zero.

ufl.algorithms.remove_component_tensors.remove_component_tensors(o)

  Remove component tensors.

## ufl.algorithms.renumbering module

Algorithms for renumbering of counted objects, currently variables and indices.

class ufl.algorithms.renumbering.IndexRelabeller

  Bases: `MultiFunction`

  Renumber indices to have a consistent index numbering starting from 0.

  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.

  multi_index(o)

    Apply to multi-indices.

  zero(o)

    Apply to zero.

ufl.algorithms.renumbering.renumber_indices(form)

  Renumber indices to have a consistent index numbering starting from 0.

  This is useful to avoid multiple kernels for the same integrand, but with different subdomain ids.

  Args:

    form: A UFL form, integral or expression.

  Returns:

    A new form, integral or expression with renumbered indices.

## ufl.algorithms.replace module

Algorithm for replacing terminals in an expression.

class ufl.algorithms.replace.Replacer(mapping)

  Bases: `MultiFunction`

  Replacer.

  coefficient_derivative(o)

    Replace a coefficient derivative.

  external_operator(o)

    Replace an external_operator.

  interpolate(o)

    Replace an interpolate.

  ufl_type(o, *args)

    Replace a ufl_type.

ufl.algorithms.replace.replace(e, mapping)

  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_derivative_nodes module

Algorithm for replacing derivative nodes in a BaseForm or Expr.

class ufl.algorithms.replace_derivative_nodes.DerivativeNodeReplacer(mapping, **derivative_kwargs)

  Bases: `MultiFunction`

  Replace derivative nodes with new derivative nodes.

  coefficient_derivative(cd, o, coefficients, arguments, coefficient_derivatives)

    Apply to coefficient_derivative.

  ufl_type(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.

ufl.algorithms.replace_derivative_nodes.replace_derivative_nodes(expr, mapping, **derivative_kwargs)

  Replaces derivative nodes.

  Replaces the variable with respect to which the derivative is taken. This is called during apply_derivatives to treat delayed derivatives.

  Example: Let u be a Coefficient, N an ExternalOperator independent

    of u (i.e. N’s operands don’t depend on u), and let uhat and Nhat be Arguments.

    F = u ** 2 * N * dx dFdu = derivative(F, u, uhat) dFdN = replace_derivative_nodes(dFdu, {u: N}, argument=Nhat)

    Then, by subsequently expanding the derivatives we have:

    dFdu -> 2 * u * uhat * N * dx dFdN -> u ** 2 * Nhat * dx

  Args:
    expr:

      An Expr or BaseForm.

    mapping:

      A dict with from:to replacements to perform.

    derivative_kwargs:

      A dict containing the keyword arguments for derivative (i.e. argument and coefficient_derivatives).

## ufl.algorithms.signature module

Signature computation for forms.

ufl.algorithms.signature.compute_expression_hashdata(expression, terminal_hashdata) → bytes

  Compute expression hashdata.

ufl.algorithms.signature.compute_expression_signature(expr, renumbering)

  Compute expression signature.

ufl.algorithms.signature.compute_form_signature(form, renumbering)

  Compute form signature.

ufl.algorithms.signature.compute_multiindex_hashdata(expr, index_numbering)

  Compute multiindex hashdata.

ufl.algorithms.signature.compute_terminal_hashdata(expressions, renumbering)

  Compute terminal hashdata.

## ufl.algorithms.strip_terminal_data module

Algorithm for replacing form arguments with ‘stripped’ versions.

In the stripped version, any data-carrying objects have been extracted to a mapping.

class ufl.algorithms.strip_terminal_data.TerminalStripper

  Bases: `MultiFunction`

  Terminal stripper.

  argument(o)

    Apply to argument.

  coefficient(o)

    Apply to coefficient.

  constant(o)

    Apply to constant.

  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.

ufl.algorithms.strip_terminal_data.replace_terminal_data(o, mapping)

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

  Args:
    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.strip_terminal_data.strip_domain(domain)

  Return a new domain with all non-UFL information removed.

ufl.algorithms.strip_terminal_data.strip_function_space(function_space)

  Return a new function space with all non-UFL information removed.

ufl.algorithms.strip_terminal_data.strip_terminal_data(o)

  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.

  Args:

    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.transformer module

Transformer.

This module defines the Transformer base class and some basic specializations to further base other algorithms upon, as well as some utilities for easier application of such algorithms.

class ufl.algorithms.transformer.CopyTransformer(variable_cache=None)

  Bases: `Transformer`

  Copy transformer.

  expr(o, *operands)

    Reconstruct expr.

  terminal(o)

    Reuse Expr (ignore children).

  variable(o)

    Reconstruct variable.

class ufl.algorithms.transformer.ReuseTransformer(variable_cache=None)

  Bases: `Transformer`

  Reuse transformer.

  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.Transformer(variable_cache=None)

  Bases: `object`

  Transformer.

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

  always_reconstruct(o, *operands)

    Reconstruct expr.

  print_visit_stack()

    Print visit stack.

  reconstruct_variable(o)

    Reconstruct variable.

  reuse(o)

    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)

    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)

    Reuse variable.

  terminal(o)

    Reuse Expr (ignore children).

  ufl_type(o)

    Trigger error.

  undefined(o)

    Trigger error.

  visit(o)

    Visit.

class ufl.algorithms.transformer.VariableStripper

  Bases: `ReuseTransformer`

  Variable stripper.

  variable(o)

    Visit a variable.

ufl.algorithms.transformer.apply_transformer(e, transformer, integral_type=None)

  Apply transforms.

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

ufl.algorithms.transformer.is_post_handler(function)

  Check if function is a handler that expects transformed children as input.

ufl.algorithms.transformer.strip_variables(e)

  Replace all Variable instances with the expression they represent.

## ufl.algorithms.traversal module

This module contains algorithms for traversing expression trees in different ways.

ufl.algorithms.traversal.iter_expressions(a)

  Handle Form, Integral and any Expr the same way when inspecting expressions.

  Returns an iterable over Expr instances: - a is an Expr: (a,) - a is an Integral: the integrand expression of a - a is a Form: all integrand expressions of all integrals - a is a FormSum: the components of a - a is an Action: the left and right component of a - a is an Adjoint: the underlying form of a

## Module contents

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

class ufl.algorithms.FormSplitter(replace_argument: bool = True)

  Bases: `MultiFunction`

  Form splitter.

  argument(obj)

    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)

    Extract indexed entry if multindices are fixed.

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

  multi_index(obj)

    Apply to multi_index.

  restricted(o)

    Apply to a restricted function.

  split(form, ix, iy=None)

    Split form based on the argument part/number.

class ufl.algorithms.MultiFunction

  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.

  reuse_if_untouched(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.

  ufl_type(o, *args)

    Trigger error for types with missing handlers.

  undefined(o, *args)

    Trigger error for types with missing handlers.

class ufl.algorithms.ReuseTransformer(variable_cache=None)

  Bases: `Transformer`

  Reuse transformer.

  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)

  Bases: `object`

  Transformer.

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

  always_reconstruct(o, *operands)

    Reconstruct expr.

  print_visit_stack()

    Print visit stack.

  reconstruct_variable(o)

    Reconstruct variable.

  reuse(o)

    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)

    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)

    Reuse variable.

  terminal(o)

    Reuse Expr (ignore children).

  ufl_type(o)

    Trigger error.

  undefined(o)

    Trigger error.

  visit(o)

    Visit.

ufl.algorithms.apply_transformer(e, transformer, integral_type=None)

  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)

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

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

  Args:

    e: An Expr or Form.

ufl.algorithms.compute_energy_norm(form, coefficient)

  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)

  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)

  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)

  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)

  Compute form data.

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

ufl.algorithms.compute_form_functional(form)

  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)

  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)

  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)

  Compute form signature.

ufl.algorithms.estimate_total_polynomial_degree(e, default_degree=1, element_replace_map={})

  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)

  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)

  Expand indices.

ufl.algorithms.extract_arguments(a)

  Build a sorted list of all arguments in a.

  Args:

    a: A BaseForm, Integral or Expr

ufl.algorithms.extract_base_form_operators(a)

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

  Args:

    a: A BaseForm, Integral or Expr

ufl.algorithms.extract_coefficients(a)

  Build a sorted list of all coefficients in a.

  Args:

    a: A BaseForm, Integral or Expr

ufl.algorithms.extract_elements(form)

  Build sorted tuple of all elements used in form.

ufl.algorithms.extract_sub_elements(elements)

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

ufl.algorithms.extract_type(a, ufl_types)

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

  Args:

    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)

  Build sorted tuple of all unique elements used in form.

ufl.algorithms.load_forms(filename)

  Return a list of all forms in a file.

ufl.algorithms.load_ufl_file(filename)

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

ufl.algorithms.post_traversal(expr)

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

ufl.algorithms.preprocess_form(form, complex_mode)

  Preprocess a form.

ufl.algorithms.read_ufl_file(filename)

  Read a UFL file.

ufl.algorithms.replace(e, mapping)

  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)

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

  Args:
    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)

  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)

  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.

  Args:

    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)

  Replace all Variable instances with the expression they represent.

ufl.algorithms.tree_format(expression, indentation=0, parentheses=True)

  Tree format.

ufl.algorithms.validate_form(form)

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