irksome.ufl package

Submodules

irksome.ufl.deriv module

irksome.ufl.deriv.Dt(f, order=1)[source]

Short-hand function to produce a TimeDerivative of a given order.

class irksome.ufl.deriv.TimeDerivative(f)[source]

Bases: Derivative

UFL node representing a time derivative of some quantity/field. Note: Currently form compilers do not understand how to process these nodes. Instead, Irksome pre-processes forms containing TimeDerivative nodes.

Initalise.

property ufl_free_indices
property ufl_index_dimensions
property ufl_shape
class irksome.ufl.deriv.TimeDerivativeRuleDispatcher(t=None, timedep_coeffs=None, **kwargs)[source]

Bases: DAGTraverser

Mapping rules to splat out time derivatives so that replacement should work on more complex problems.

Initialise.

process(o)[source]
process(o: TimeDerivative)
process(o: BaseForm)
process(o: Expr)

Process node by type.

Args:

o: Expr to start DAG traversal from. **kwargs: keyword arguments for the process singledispatchmethod.

Returns:

Processed Expr.

time_derivative(o)[source]
class irksome.ufl.deriv.TimeDerivativeRuleset(t=None, timedep_coeffs=None)[source]

Bases: GenericDerivativeRuleset

Apply AD rules to time derivative expressions.

Initialise.

constant(o)[source]
process(o)[source]
process(o: ConstantValue)
process(o: SpatialCoordinate)
process(o: Coefficient)
process(o: TimeDerivative, f)
process(o: Variable, *operands)
process(o: ReferenceValue, *operands)
process(o: ReferenceGrad, *operands)
process(o: Indexed, *operands)
process(o: Grad, *operands)
process(o: Div, *operands)
process(o: Derivative, *operands)
process(o: Curl, *operands)
process(o: Conj, *operands)

Process o.

Args:

o: Expr to be processed.

Returns:

Processed object.

terminal(o)[source]
terminal_modifier(o, *operands)[source]
time_derivative(o, f)[source]
irksome.ufl.deriv.apply_time_derivatives(expression, t=None, timedep_coeffs=None)[source]
irksome.ufl.deriv.expand_time_derivatives(expression, t=None, timedep_coeffs=None)[source]

irksome.ufl.estimate_degrees module

class irksome.ufl.estimate_degrees.TimeDegreeEstimator(degree_mapping=None, **kwargs)[source]

Bases: DAGTraverser

Time degree estimator.

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

Initialise.

add_degrees(v, *ops)[source]
conditional(v, c, *ops)[source]
form(o)[source]
formsum(o)[source]
integral(o)[source]
interpolate(o)[source]
math_function(v, a)[source]

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_degree(v, *ops)[source]
minmax(v, *ops)[source]
non_numeric(v, *args)[source]
not_handled(v, *ops)[source]
power(v, a, b)[source]

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.

process(o)[source]
process(o: FormSum)
process(o: Interpolate)
process(o: Form)
process(o: Integral)
process(o: SpatialCoordinate)
process(o: ConstantValue)
process(o: Coefficient)
process(o: Cofunction)
process(o: Argument)
process(o: TimeDerivative, degree)
process(o: IndexSum, degree, *ops)
process(o: ComponentTensor, degree, *ops)
process(o: Variable, degree, *ops)
process(o: ReferenceValue, degree, *ops)
process(o: ReferenceGrad, degree, *ops)
process(o: Indexed, degree, *ops)
process(o: Grad, degree, *ops)
process(o: Div, degree, *ops)
process(o: Derivative, degree, *ops)
process(o: Curl, degree, *ops)
process(o: Conj, degree, *ops)
process(o: Abs, degree, *ops)
process(v: Inverse, *ops)
process(v: Determinant, *ops)
process(v: Transposed, *ops)
process(v: Trace, *ops)
process(v: Sym, *ops)
process(v: Skew, *ops)
process(v: Cofactor, *ops)
process(v: ExprMapping, *ops)
process(v: ExprList, *ops)
process(v: ListTensor, *ops)
process(v: Sum, *ops)
process(v: Cross, *ops)
process(v: Outer, *ops)
process(v: Dot, *ops)
process(v: Inner, *ops)
process(v: Product, *ops)
process(v: Division, *ops)
process(v: Power, a, b)
process(v: MathFunction, a)
process(v: Conditional, c, *ops)
process(v: MaxValue, *ops)
process(v: MinValue, *ops)
process(v: MultiIndex, *args)
process(v: Condition, *args)
process(v: Label, *args)

Process node by type.

Args:

o: Expr to start DAG traversal from. **kwargs: keyword arguments for the process singledispatchmethod.

Returns:

Processed Expr.

terminal(o)[source]
terminal_modifier(o, degree, *ops)[source]
time_derivative(o, degree)[source]
irksome.ufl.estimate_degrees.estimate_time_degree(expression, test_degree, trial_degree, t=None, timedep_coeffs=None)[source]
irksome.ufl.estimate_degrees.get_degree_mapping(expression, test_degree, trial_degree, t=None, timedep_coeffs=None)[source]

Map time-dependent terminals to their polynomial degree.

Parameters:
  • expression – a ufl.BaseForm or ufl.Expr.

  • test_degree – the temporal polynomial degree of the test space.

  • trial_degree – the temporal polynomial degree of the trial space.

  • t – the time variable as a Constant or Function in the Real space.

  • timedep_coeffs – a list of Function that depend on time.

Returns:

a dict mapping time-dependent terminals to their degree in time.

irksome.ufl.manipulation module

Manipulation of expressions containing TimeDerivative terms.

These can be used to do some basic checking of the suitability of a Form for use in Irksome (via check_integrals), and splitting out terms in the Form that contain a time derivative from those that don’t (via extract_terms).

class irksome.ufl.manipulation.SplitTimeForm(time: Form, remainder: Form)[source]

Bases: NamedTuple

A container for a form split into time terms and a remainder.

Create new instance of SplitTimeForm(time, remainder)

remainder: Form

Alias for field number 1

time: Form

Alias for field number 0

irksome.ufl.manipulation.check_integrals(integrals: List[Integral], expect_time_derivative: bool = True) List[Integral][source]

Check a list of integrals for linearity in the time derivative.

Parameters:
  • integrals – list of integrals.

  • expect_time_derivative – Are we expecting to see a time derivative?

Raises:

ValueError – if we are expecting a time derivative and don’t see one, or time derivatives are applied nonlinearly, to more than one coefficient, or more than first order.

irksome.ufl.manipulation.extract_terms(form: Form) SplitTimeForm[source]

Extract terms from a Form.

This splits a form (a sum of integrals) into those integrals which do contain a TimeDerivative and those that don’t.

Parameters:

form – The form to split.

Returns:

a SplitTimeForm tuple.

Raises:

ValueError – if the form does not apply anything other than first-order time derivatives to a single coefficient.

Module contents