# ufl_legacy.algorithms package

## Submodules

## ufl_legacy.algorithms.ad module

Front-end for AD routines.

ufl_legacy.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_legacy.algorithms.analysis module

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

ufl_legacy.algorithms.analysis.extract_arguments(a)

  Build a sorted list of all arguments in a, which can be a Form, Integral or Expr.

ufl_legacy.algorithms.analysis.extract_arguments_and_coefficients(a)

  Build two sorted lists of all arguments and coefficients in a, which can be a Form, Integral or Expr.

ufl_legacy.algorithms.analysis.extract_coefficients(a)

  Build a sorted list of all coefficients in a, which can be a Form, Integral or Expr.

ufl_legacy.algorithms.analysis.extract_constants(a)

  Build a sorted list of all constants in a

ufl_legacy.algorithms.analysis.extract_elements(form)

  Build sorted tuple of all elements used in form.

ufl_legacy.algorithms.analysis.extract_sub_elements(elements)

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

ufl_legacy.algorithms.analysis.extract_type(a, ufl_type)

  Build a set of all objects of class ufl_type found in a. The argument a can be a Form, Integral or Expr.

ufl_legacy.algorithms.analysis.extract_unique_elements(form)

  Build sorted tuple of all unique elements used in form.

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

  Return if an object of class ufl_type can be found in a. The argument a can be a Form, Integral or Expr.

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

  Return if an object of class ufl_type can be found in a. The argument a can be a Form, Integral or Expr.

ufl_legacy.algorithms.analysis.sort_elements(elements)

  Sort elements 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_legacy.algorithms.analysis.unique_tuple(objects)

  Return tuple of unique objects, preserving initial ordering.

## ufl_legacy.algorithms.apply_algebra_lowering module

Algorithm for expanding compound expressions into equivalent representations using basic operators.

class ufl_legacy.algorithms.apply_algebra_lowering.LowerCompoundAlgebra

  Bases: `MultiFunction`

  Expands high level compound operators (e.g. inner) to equivalent representations using basic operators (e.g. index notation).

  altenative_dot(o, a, b)
  alternative_inner(o, a, b)
  cofactor(o, A)
  cross(o, a, b)
  curl(o, a)
  determinant(o, A)
  deviatoric(o, A)
  div(o, a)
  dot(o, a, b)
  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.

  inner(o, a, b)
  inverse(o, A)
  nabla_div(o, a)
  nabla_grad(o, a)
  outer(o, a, b)
  skew(o, A)
  sym(o, A)
  trace(o, A)
  transposed(o, A)

ufl_legacy.algorithms.apply_algebra_lowering.apply_algebra_lowering(expr)

  Expands high level compound operators (e.g. inner) to equivalent representations using basic operators (e.g. index notation).

## ufl_legacy.algorithms.apply_derivatives module

This module contains the apply_derivatives algorithm which computes the derivatives of a form of expression.

class ufl_legacy.algorithms.apply_derivatives.CoordinateDerivativeRuleDispatcher

  Bases: `MultiFunction`

  coefficient_derivative(o)
  coordinate_derivative(o, f, w, v, cd)
  derivative(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.

  grad(o)
  reference_grad(o)
  terminal(o)

class ufl_legacy.algorithms.apply_derivatives.CoordinateDerivativeRuleset(coefficients, arguments, coefficient_derivatives)

  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.

  argument(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  coefficient(o)
  geometric_quantity(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  grad(o)
  jacobian(o)
  reference_grad(g)
  reference_value(o)
  spatial_coordinate(o)

class ufl_legacy.algorithms.apply_derivatives.DerivativeRuleDispatcher

  Bases: `MultiFunction`

  coefficient_derivative(o, f, dummy_w, dummy_v, dummy_cd)
  coordinate_derivative(o, f, dummy_w, dummy_v, dummy_cd)
  derivative(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.

  grad(o, f)
  indexed(o, Ap, ii)
  reference_grad(o, f)
  terminal(o)
  variable_derivative(o, f, dummy_v)

class ufl_legacy.algorithms.apply_derivatives.GateauxDerivativeRuleset(coefficients, arguments, coefficient_derivatives)

  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

  argument(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  cell_avg(o, fp)
  coefficient(o)
  coordinate_derivative(o)
  facet_avg(o, fp)
  geometric_quantity(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  grad(g)
  reference_grad(o)
  reference_value(o)

class ufl_legacy.algorithms.apply_derivatives.GenericDerivativeRuleset(var_shape)

  Bases: `MultiFunction`

  abs(o, df)
  acos(o, fp)
  asin(o, fp)
  atan(o, fp)
  atan_2(o, fp, gp)
  bessel_i(o, nup, fp)
  bessel_j(o, nup, fp)
  bessel_k(o, nup, fp)
  bessel_y(o, nup, fp)
  binary_condition(o, dl, dr)
  cell_avg(o)
  component_tensor(o, Ap, ii)
  conditional(o, unused_dc, dt, df)
  conj(o, df)
  constant(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  constant_value(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  cos(o, fp)
  cosh(o, fp)
  derivative(o)
  division(o, fp, gp)
  erf(o, fp)
  exp(o, fp)
  expr(o)

    Trigger error for types with missing handlers.

  facet_avg(o)
  fixme(o)
  form_argument(o)
  geometric_quantity(o)
  grad(o)
  imag(o, df)
  independent_operator(o)

    Return a zero with the right shape and indices for operators independent of differentiation variable.

  independent_terminal(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  index_sum(o, Ap, i)
  indexed(o, Ap, ii)
  label(o)

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

  list_tensor(o, *dops)
  ln(o, fp)
  math_function(o, df)
  max_value(o, df, dg)
  min_value(o, df, dg)
  multi_index(o)

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

  non_differentiable_terminal(o)

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

  not_condition(o, c)
  override(o)
  power(o, fp, gp)
  product(o, da, db)
  real(o, df)
  restricted(o, fp)
  sin(o, fp)
  sinh(o, fp)
  sqrt(o, fp)
  sum(o, da, db)
  tan(o, fp)
  tanh(o, fp)
  unexpected(o)
  variable(o, df, unused_l)

class ufl_legacy.algorithms.apply_derivatives.GradRuleset(geometric_dimension)

  Bases: `GenericDerivativeRuleset`

  argument(o)
  cell_avg(o)

    Return a zero with the right shape and indices for operators independent of differentiation variable.

  cell_coordinate(o)

    dX/dx = inv(dx/dX) = inv(J) = K

  coefficient(o)
  facet_avg(o)

    Return a zero with the right shape and indices for operators independent of differentiation variable.

  geometric_quantity(o)

    Default for geometric quantities is do/dx = 0 if piecewise constant, otherwise transform derivatives to reference derivatives. Override for specific types if other behaviour is needed.

  grad(o)

    Represent grad(grad(f)) as Grad(Grad(f)).

  jacobian_inverse(o)
  reference_grad(o)
  reference_value(o)
  spatial_coordinate(o)

    dx/dx = I

class ufl_legacy.algorithms.apply_derivatives.ReferenceGradRuleset(topological_dimension)

  Bases: `GenericDerivativeRuleset`

  argument(o)
  cell_avg(o)

    Return a zero with the right shape and indices for operators independent of differentiation variable.

  cell_coordinate(o)

    dX/dX = I

  coefficient(o)
  facet_avg(o)

    Return a zero with the right shape and indices for operators independent of differentiation variable.

  geometric_quantity(o)

    dg/dX = 0 if piecewise constant, otherwise ReferenceGrad(g)

  grad(o)
  reference_grad(o)

    Represent ref_grad(ref_grad(f)) as RefGrad(RefGrad(f)).

  reference_value(o)
  spatial_coordinate(o)

    dx/dX = J

class ufl_legacy.algorithms.apply_derivatives.VariableRuleset(var)

  Bases: `GenericDerivativeRuleset`

  argument(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  cell_avg(o)

    Return a zero with the right shape and indices for operators independent of differentiation variable.

  coefficient(o)

    df/dv = Id if v is f else 0.

    Note that if v = variable(f), df/dv is still 0, but if v == f, i.e. isinstance(v, Coefficient) == True, then df/dv == df/df = Id.

  facet_avg(o)

    Return a zero with the right shape and indices for operators independent of differentiation variable.

  geometric_quantity(o)

    Return a zero with the right shape for terminals independent of differentiation variable.

  grad(o)

    Variable derivative of a gradient of a terminal must be 0.

  reference_grad(o)

    Variable derivative of a gradient of a terminal must be 0.

  reference_value(o)
  variable(o, df, l)

ufl_legacy.algorithms.apply_derivatives.apply_coordinate_derivatives(expression)

ufl_legacy.algorithms.apply_derivatives.apply_derivatives(expression)

ufl_legacy.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

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

## ufl_legacy.algorithms.apply_function_pullbacks module

Algorithm for replacing gradients in an expression with reference gradients and coordinate mappings.

class ufl_legacy.algorithms.apply_function_pullbacks.FunctionPullbackApplier

  Bases: `MultiFunction`

  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)

ufl_legacy.algorithms.apply_function_pullbacks.apply_function_pullbacks(expr)

  Change representation of coefficients and arguments in expression by applying Piola mappings where applicable and representing all form arguments in reference value.

  @param expr:

    An Expr.

ufl_legacy.algorithms.apply_function_pullbacks.apply_known_single_pullback(r, element)

  Apply pullback with given mapping.

  Parameters:

    - r – Expression wrapped in ReferenceValue

    - element – The element defining the mapping

ufl_legacy.algorithms.apply_function_pullbacks.apply_single_function_pullbacks(r, element)

  Apply an appropriate pullback to something in physical space

  Parameters:

    - r – An expression wrapped in ReferenceValue.

    - element – The element this expression lives in.

  Returns:

    a pulled back expression.

ufl_legacy.algorithms.apply_function_pullbacks.create_nested_lists(shape)

ufl_legacy.algorithms.apply_function_pullbacks.reshape_to_nested_list(components, shape)

ufl_legacy.algorithms.apply_function_pullbacks.sub_elements_with_mappings(element)

  Return an ordered list of the largest subelements that have a defined mapping.

## ufl_legacy.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_legacy.algorithms.apply_geometry_lowering.GeometryLoweringApplier(preserve_types=())

  Bases: `MultiFunction`

  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)
  spatial_coordinate(o)
  terminal(t)

ufl_legacy.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.

  @param form:

    An Expr or Form.

## ufl_legacy.algorithms.apply_integral_scaling module

Algorithm for replacing gradients in an expression with reference gradients and coordinate mappings.

ufl_legacy.algorithms.apply_integral_scaling.apply_integral_scaling(form)

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

ufl_legacy.algorithms.apply_integral_scaling.compute_integrand_scaling_factor(integral)

  Change integrand geometry to the right representations.

## ufl_legacy.algorithms.apply_restrictions module

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

class ufl_legacy.algorithms.apply_restrictions.DefaultRestrictionApplier(side=None)

  Bases: `MultiFunction`

  derivative(o)
  facet_area(o)

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

  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_origin(o)

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

  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.

  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.

  restricted(o)
  spatial_coordinate(o)

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

  terminal(o)

class ufl_legacy.algorithms.apply_restrictions.RestrictionPropagator(side=None)

  Bases: `MultiFunction`

  argument(o)

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

  coefficient(o)

    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_coordinate(o)

    Ignore current restriction, quantity is independent of side also from a computational point of view.

  facet_normal(o)
  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.

  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.

  terminal(o)
  variable(o, op, label)

    Strip variable.

ufl_legacy.algorithms.apply_restrictions.apply_default_restrictions(expression)

  Some terminals can be restricted from either side.

  This applies a default restriction to such terminals if unrestricted.

ufl_legacy.algorithms.apply_restrictions.apply_restrictions(expression)

  Propagate restriction nodes to wrap differential terminals directly.

## ufl_legacy.algorithms.balancing module

class ufl_legacy.algorithms.balancing.BalanceModifiers

  Bases: `MultiFunction`

  cell_avg(expr, *ops)
  expr(expr, *ops)

    Trigger error for types with missing handlers.

  facet_avg(expr, *ops)
  grad(expr, *ops)
  negative_restricted(expr, *ops)
  positive_restricted(expr, *ops)
  reference_grad(expr, *ops)
  reference_value(expr, *ops)
  terminal(expr)

ufl_legacy.algorithms.balancing.balance_modified_terminal(expr)

ufl_legacy.algorithms.balancing.balance_modifiers(expr)

## ufl_legacy.algorithms.change_to_reference module

Algorithm for replacing gradients in an expression with reference gradients and coordinate mappings.

class ufl_legacy.algorithms.change_to_reference.NEWChangeToReferenceGrad

  Bases: `MultiFunction`

  cell_avg(o, *dummy_ops)
  coefficient_derivative(o, *dummy_ops)
  expr(o, *ops)

    Trigger error for types with missing handlers.

  facet_avg(o, *dummy_ops)
  form_argument(t)
  geometric_quantity(t)
  grad(o, *dummy_ops)

    Store modifier state.

  reference_grad(o, *dummy_ops)
  restricted(o, *dummy_ops)

    Store modifier state.

  terminal(o)

class ufl_legacy.algorithms.change_to_reference.OLDChangeToReferenceGrad

  Bases: `MultiFunction`

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

  grad(o)
  reference_grad(o)
  terminal(o)

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

  Change integrand geometry to the right representations.

ufl_legacy.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.

  @param e:

    An Expr or Form.

## ufl_legacy.algorithms.check_arities module

class ufl_legacy.algorithms.check_arities.ArityChecker(arguments)

  Bases: `MultiFunction`

  argument(o)
  cell_avg(o, a)
  component_tensor(o, a, i)
  conditional(o, c, a, b)
  conj(o, a)
  division(o, a, b)
  dot(o, a, b)
  expr(o)

    Trigger error for types with missing handlers.

  facet_avg(o, a)
  grad(o, a)
  index_sum(o, a, i)
  indexed(o, a, i)
  inner(o, a, b)
  linear_indexed_type(o, a, i)
  linear_operator(o, a)
  list_tensor(o, *ops)
  negative_restricted(o, a)
  nonlinear_operator(o)
  outer(o, a, b)
  positive_restricted(o, a)
  product(o, a, b)
  reference_grad(o, a)
  reference_value(o, a)
  sum(o, a, b)
  terminal(o)
  variable(o, f, l)

exception ufl_legacy.algorithms.check_arities.ArityMismatch

  Bases: `UFLException`

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

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

## ufl_legacy.algorithms.check_restrictions module

Algorithms related to restrictions.

class ufl_legacy.algorithms.check_restrictions.RestrictionChecker(require_restriction)

  Bases: `MultiFunction`

  expr(o)

    Trigger error for types with missing handlers.

  facet_normal(o)
  form_argument(o)
  restricted(o)

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

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

## ufl_legacy.algorithms.checks module

Functions to check the validity of forms.

ufl_legacy.algorithms.checks.validate_form(form)

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

## ufl_legacy.algorithms.comparison_checker module

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

class ufl_legacy.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)
  compare(o, *ops)
  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)
  gt(o, *ops)
  imag(o, *ops)
  indexed(o, expr, multiindex)
  le(o, *ops)
  lt(o, *ops)
  max_value(o, *ops)
  min_value(o, *ops)
  power(o, base, exponent)
  real(o, *ops)
  sign(o, *ops)
  sqrt(o, *ops)
  terminal(term, *ops)

exception ufl_legacy.algorithms.comparison_checker.ComplexComparisonError

  Bases: `Exception`

ufl_legacy.algorithms.comparison_checker.do_comparison_check(form)

  Raises an error if invalid comparison nodes exist

## ufl_legacy.algorithms.compute_form_data module

This module provides the compute_form_data function which form compilers will typically call prior to code generation to preprocess/simplify a raw input form given by a user.

ufl_legacy.algorithms.compute_form_data.attach_estimated_degrees(form)

  Attach estimated polynomial degree to a form’s integrals.

  Parameters:

    form – The `Form` to inspect.

  Returns:

    A new Form with estimate degrees attached.

ufl_legacy.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, complex_mode=False)

## ufl_legacy.algorithms.coordinate_derivative_helpers module

This module provides the necessary tools to strip away and then reattach the coordinate derivatives at the right time point in compute_form_data.

class ufl_legacy.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, *_)
  expr(o, *operands)

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

  multi_index(o)
  terminal(o)

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

ufl_legacy.algorithms.coordinate_derivative_helpers.strip_coordinate_derivatives(integrals)

## ufl_legacy.algorithms.domain_analysis module

Algorithms for building canonical data structure for integrals over subdomains.

class ufl_legacy.algorithms.domain_analysis.ExprTupleKey(x)

  Bases: `object`

  x

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

  Bases: `object`

  Utility class with the 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_legacy.algorithms.domain_analysis.accumulate_integrands_with_same_metadata(integrals)
  Taking input on the form:

    integrals = [integral0, integral1, …]

  Return result on the form:
    integrands_by_id = [(integrand0, metadata0),

      (integrand1, metadata1), …]

  where integrand0 < integrand1 by the canonical ufl expression ordering criteria.

ufl_legacy.algorithms.domain_analysis.build_integral_data(integrals)

  Build integral data given a list of integrals.

  Parameters:

    integrals – An iterable of `Integral` objects.

  Returns:

    A tuple of `IntegralData` objects.

  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()`.

ufl_legacy.algorithms.domain_analysis.dicts_lt(a, b)

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

  Group integrals by domain and type, performing canonical simplification.

  Parameters:

    - form – the `Form` to group the integrals of.

    - domains – an iterable of :class:`~.Domain`s.

  Returns:

    A new `Form` with gathered integrands.

ufl_legacy.algorithms.domain_analysis.group_integrals_by_domain_and_type(integrals, domains)
  Input:

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

  Output:

    integrals_by_domain_and_type: dict: (domain, integral_type) -> list(Integral)

ufl_legacy.algorithms.domain_analysis.integral_subdomain_ids(integral)

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

ufl_legacy.algorithms.domain_analysis.rearrange_integrals_by_single_subdomains(integrals, do_append_everywhere_integrals)

  Rearrange integrals over multiple subdomains to single subdomain integrals.

  Input:

    integrals: list(Integral)

  Output:

    integrals: dict: subdomain_id -> list(Integral) (reconstructed with single subdomain_id)

ufl_legacy.algorithms.domain_analysis.reconstruct_form_from_integral_data(integral_data)

## ufl_legacy.algorithms.elementtransformations module

This module provides helper functions to - FFC/DOLFIN adaptive chain, - UFL algorithms taking care of underspecified DOLFIN expressions.

ufl_legacy.algorithms.elementtransformations.increase_order(element)

  Return element of same family, but a polynomial degree higher.

ufl_legacy.algorithms.elementtransformations.tear(element)

  For a finite element, return the corresponding discontinuous element.

## ufl_legacy.algorithms.estimate_degrees module

Algorithms for estimating polynomial degrees of expressions.

class ufl_legacy.algorithms.estimate_degrees.IrreducibleInt

  Bases: `int`

  Degree type used by quadrilaterals.

  Unlike int, values of this type are not decremeneted by _reduce_degree.

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

  Bases: `MultiFunction`

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

  abs(v, a)

    This is a heuristic, correct if there is no

  argument(v)

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

  atan_2(v, a, b)

    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)

    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)

    Cell average of a function is always cellwise constant.

  cell_coordinate(v)

    A coordinate provides one additional degree.

  coefficient(v)

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

  cofactor(v, *args)
  component_tensor(v, A, ii)
  compound_derivative(v, *args)
  compound_tensor_operator(v, *args)
  condition(v, *args)
  conditional(v, c, t, f)

    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)
  constant(v)
  constant_value(v)

    Constant values are constant.

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

    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)
  curl(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  derivative(v, *args)
  determinant(v, *args)
  deviatoric(v, *args)
  div(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  division(v, *ops)

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

  dot(v, *ops)
  expr(v, *ops)

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

  expr_list(v, *o)
  expr_mapping(v, *o)
  facet_avg(v, a)

    Facet average of a function is always cellwise constant.

  geometric_quantity(v)

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

  grad(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  imag(v, a)
  index_sum(v, A, ii)
  indexed(v, A, ii)
  inner(v, *ops)
  inverse(v, *args)
  label(v)
  list_tensor(v, *ops)
  math_function(v, a)

    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, l, r)

    Same as conditional.

  min_value(v, l, r)

    Same as conditional.

  multi_index(v)
  nabla_div(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  nabla_grad(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  negative_restricted(v, a)
  outer(v, *ops)
  positive_restricted(v, a)
  power(v, a, b)

    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)
  real(v, a)
  reference_curl(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  reference_div(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  reference_grad(v, f)

    Reduces the estimated degree by one; used when derivatives are taken. Does not reduce the degree when TensorProduct elements or quadrilateral elements are involved.

  reference_value(rv, f)
  skew(v, *args)
  spatial_coordinate(v)

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

  sum(v, *ops)
  sym(v, *args)
  trace(v, *args)
  transposed(v, A)
  variable(v, e, l)
  variable_derivative(v, *args)

ufl_legacy.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_legacy.algorithms.expand_compounds module

Algorithm for expanding compound expressions into equivalent representations using basic operators.

ufl_legacy.algorithms.expand_compounds.expand_compounds(e)

## ufl_legacy.algorithms.expand_indices module

This module defines expression transformation utilities, for expanding free indices in expressions to explicit fixed indices only.

class ufl_legacy.algorithms.expand_indices.IndexExpander

  Bases: `ReuseTransformer`

  …

  component()

    Return current component tuple.

  component_tensor(x)
  conditional(x)
  division(x)
  form_argument(x)
  grad(x)
  index_sum(x)
  indexed(x)
  list_tensor(x)
  multi_index(x)
  scalar_value(x)
  terminal(x)

    Always reuse Expr (ignore children)

  zero(x)

ufl_legacy.algorithms.expand_indices.expand_indices(e)

ufl_legacy.algorithms.expand_indices.purge_list_tensors(expr)

  Get rid of all ListTensor instances by expanding expressions to use their components directly. Will usually increase the size of the expression.

## ufl_legacy.algorithms.formdata module

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

class ufl_legacy.algorithms.formdata.ExprData

  Bases: `object`

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

class ufl_legacy.algorithms.formdata.FormData

  Bases: `object`

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

## ufl_legacy.algorithms.formfiles module

A collection of utility algorithms for handling UFL files.

class ufl_legacy.algorithms.formfiles.FileData

  Bases: `object`

ufl_legacy.algorithms.formfiles.execute_ufl_code(uflcode)

ufl_legacy.algorithms.formfiles.interpret_ufl_namespace(namespace)

  Takes a namespace dict from an executed ufl file and converts it to a FileData object.

ufl_legacy.algorithms.formfiles.load_forms(filename)

  Return a list of all forms in a file.

ufl_legacy.algorithms.formfiles.load_ufl_file(filename)

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

ufl_legacy.algorithms.formfiles.read_lines_decoded(fn)

ufl_legacy.algorithms.formfiles.read_ufl_file(filename)

  Read a UFL file.

## ufl_legacy.algorithms.formsplitter module

Extract part of a form in a mixed FunctionSpace.

class ufl_legacy.algorithms.formsplitter.FormSplitter

  Bases: `MultiFunction`

  argument(obj)
  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(obj)
  split(form, ix, iy=0)

ufl_legacy.algorithms.formsplitter.extract_blocks(form, i=None, j=None)

## ufl_legacy.algorithms.formtransformations module

This module defines utilities for transforming complete Forms into new related Forms.

class ufl_legacy.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)

    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)

    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)

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

  expr(x)

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

  facet_avg(x, arg)

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

  grad(x, arg)

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

  imag(x, arg)

    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)

    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)

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

  list_tensor(x, *ops)
  negative_restricted(x, arg)

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

  outer(x, *ops)

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

  positive_restricted(x, arg)

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

  product(x, *ops)

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

  real(x, arg)

    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)

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

  variable(x)

    Return relevant parts of this variable.

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

  Return set of arities of terms present in form.

ufl_legacy.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_legacy.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_legacy.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_legacy.algorithms.formtransformations.compute_form_with_arity(form, arity, arguments=None)

  Compute parts of form of given arity.

ufl_legacy.algorithms.formtransformations.zero_expr(e)

## ufl_legacy.algorithms.map_integrands module

Basic algorithms for applying functions to subexpressions.

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

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

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

## ufl_legacy.algorithms.multifunction module

## ufl_legacy.algorithms.preprocess_expression module

## ufl_legacy.algorithms.remove_complex_nodes module

Algorithm for removing conj, real, and imag nodes from a form for when the user is in ‘real mode’

class ufl_legacy.algorithms.remove_complex_nodes.ComplexNodeRemoval

  Bases: `MultiFunction`

  Replaces complex operator nodes with their children

  conj(o, a)
  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)
  real(o, a)
  terminal(t, *ops)

ufl_legacy.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_legacy.algorithms.renumbering module

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

class ufl_legacy.algorithms.renumbering.IndexRenumberingTransformer

  Bases: `VariableRenumberingTransformer`

  This is a poorly designed algorithm. It is used in some tests, please do not use for anything else.

  index(o)
  multi_index(o)
  zero(o)

class ufl_legacy.algorithms.renumbering.VariableRenumberingTransformer

  Bases: `ReuseTransformer`

  variable(o)

ufl_legacy.algorithms.renumbering.renumber_indices(expr)

## ufl_legacy.algorithms.replace module

Algorithm for replacing terminals in an expression.

class ufl_legacy.algorithms.replace.Replacer(mapping)

  Bases: `MultiFunction`

  coefficient_derivative(o)
  expr(o, *args)

    Trigger error for types with missing handlers.

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

  Replace subexpressions in expression.

  @param e:

    An Expr or Form.

  @param mapping:

    A dict with from:to replacements to perform.

## ufl_legacy.algorithms.signature module

Signature computation for forms.

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

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

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

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

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

## ufl_legacy.algorithms.strip_terminal_data module

Algorithm for replacing form arguments with ‘stripped’ versions where any data-carrying objects have been extracted to a mapping.

class ufl_legacy.algorithms.strip_terminal_data.TerminalStripper

  Bases: `MultiFunction`

  argument(o)
  coefficient(o)
  constant(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.

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

  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_legacy.algorithms.strip_terminal_data.strip_domain(domain)

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

ufl_legacy.algorithms.strip_terminal_data.strip_function_space(function_space)

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

ufl_legacy.algorithms.strip_terminal_data.strip_terminal_data(o)

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

  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()`.

  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.

## ufl_legacy.algorithms.transformer module

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_legacy.algorithms.transformer.CopyTransformer(variable_cache=None)

  Bases: `Transformer`

  expr(o, *operands)

    Always reconstruct expr.

  terminal(o)

    Always reuse Expr (ignore children)

  variable(o)

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

  Bases: `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)

    Always reuse Expr (ignore children)

  variable(o)

class ufl_legacy.algorithms.transformer.Transformer(variable_cache=None)

  Bases: `object`

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

  always_reconstruct(o, *operands)

    Always reconstruct expr.

  expr(o)

    Trigger error.

  print_visit_stack()
  reconstruct_variable(o)
  reuse(o)

    Always 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)
  terminal(o)

    Always reuse Expr (ignore children)

  undefined(o)

    Trigger error.

  visit(o)

class ufl_legacy.algorithms.transformer.VariableStripper

  Bases: `ReuseTransformer`

  variable(o)

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

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

ufl_legacy.algorithms.transformer.is_post_handler(function)

  Is this a handler that expects transformed children as input?

ufl_legacy.algorithms.transformer.strip_variables(e)

  Replace all Variable instances with the expression they represent.

ufl_legacy.algorithms.transformer.ufl2ufl(e)

  Convert an UFL expression to a new UFL expression, with no changes. This is used for testing that objects in the expression behave as expected.

ufl_legacy.algorithms.transformer.ufl2uflcopy(e)

  Convert an UFL expression to a new UFL expression. All nonterminal object instances are replaced with identical copies, while terminal objects are kept. This is used for testing that objects in the expression behave as expected.

## ufl_legacy.algorithms.traversal module

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

ufl_legacy.algorithms.traversal.iter_expressions(a)

  Utility function to 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

## Module contents

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

class ufl_legacy.algorithms.FormSplitter

  Bases: `MultiFunction`

  argument(obj)
  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(obj)
  split(form, ix, iy=0)

class ufl_legacy.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.

  expr(o, *args)

    Trigger error for types with missing handlers.

  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.

  undefined(o, *args)

    Trigger error for types with missing handlers.

class ufl_legacy.algorithms.ReuseTransformer(variable_cache=None)

  Bases: `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)

    Always reuse Expr (ignore children)

  variable(o)

class ufl_legacy.algorithms.Transformer(variable_cache=None)

  Bases: `object`

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

  always_reconstruct(o, *operands)

    Always reconstruct expr.

  expr(o)

    Trigger error.

  print_visit_stack()
  reconstruct_variable(o)
  reuse(o)

    Always 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)
  terminal(o)

    Always reuse Expr (ignore children)

  undefined(o)

    Trigger error.

  visit(o)

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

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

ufl_legacy.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.

  @param e:

    An Expr or Form.

ufl_legacy.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_legacy.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_legacy.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_legacy.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, complex_mode=False)

ufl_legacy.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_legacy.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_legacy.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_legacy.algorithms.compute_form_signature(form, renumbering)

ufl_legacy.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_legacy.algorithms.expand_compounds(e)

ufl_legacy.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_legacy.algorithms.expand_indices(e)

ufl_legacy.algorithms.extract_arguments(a)

  Build a sorted list of all arguments in a, which can be a Form, Integral or Expr.

ufl_legacy.algorithms.extract_coefficients(a)

  Build a sorted list of all coefficients in a, which can be a Form, Integral or Expr.

ufl_legacy.algorithms.extract_elements(form)

  Build sorted tuple of all elements used in form.

ufl_legacy.algorithms.extract_sub_elements(elements)

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

ufl_legacy.algorithms.extract_type(a, ufl_type)

  Build a set of all objects of class ufl_type found in a. The argument a can be a Form, Integral or Expr.

ufl_legacy.algorithms.extract_unique_elements(form)

  Build sorted tuple of all unique elements used in form.

ufl_legacy.algorithms.load_ufl_file(filename)

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

ufl_legacy.algorithms.post_traversal(expr)

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

ufl_legacy.algorithms.purge_list_tensors(expr)

  Get rid of all ListTensor instances by expanding expressions to use their components directly. Will usually increase the size of the expression.

ufl_legacy.algorithms.replace(e, mapping)

  Replace subexpressions in expression.

  @param e:

    An Expr or Form.

  @param mapping:

    A dict with from:to replacements to perform.

ufl_legacy.algorithms.replace_terminal_data(o, mapping)

  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_legacy.algorithms.sort_elements(elements)

  Sort elements 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_legacy.algorithms.strip_terminal_data(o)

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

  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()`.

  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.

ufl_legacy.algorithms.strip_variables(e)

  Replace all Variable instances with the expression they represent.

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

ufl_legacy.algorithms.validate_form(form)

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