irksome.ufl package¶
Submodules¶
irksome.ufl.deriv module¶
- irksome.ufl.deriv.Dt(f, order=1)[source]¶
Short-hand function to produce a
TimeDerivativeof a given order.
- class irksome.ufl.deriv.TimeDerivative(f)[source]¶
Bases:
DerivativeUFL 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:
DAGTraverserMapping 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:
UFL expression to start DAG traversal from.
- **kwargs:
Keyword arguments for the
processsingledispatchmethod.
- Returns:
Processed
Expr.
- class irksome.ufl.deriv.TimeDerivativeRuleset(t=None, timedep_coeffs=None)[source]¶
Bases:
GenericDerivativeRulesetApply AD rules to time derivative expressions.
Initialise.
- 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.
- irksome.ufl.deriv.check_irksome_import_order()[source]¶
Check that irksome has been imported early enough.
Due to the inadequacies of the UFL type system, it is not possible to define a new UFL type once any ufl MultiFunction has been used.
This restriction can be removed once all MultiFunctions have been transitioned to ufl.corealg.dag_traverser.DAGTraverser.
irksome.ufl.estimate_degrees module¶
- class irksome.ufl.estimate_degrees.TimeDegreeEstimator(degree_mapping=None, **kwargs)[source]¶
Bases:
DAGTraverserTime degree estimator.
This algorithm is exact for a few operators and heuristic for many.
Initialise.
- 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.
- 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:
UFL expression to start DAG traversal from.
- **kwargs:
Keyword arguments for the
processsingledispatchmethod.
- Returns:
Processed
Expr.
- 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.BaseFormorufl.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
ConstantorFunctionin the Real space.timedep_coeffs – a list of
Functionthat 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 split_time_derivative_terms).
- class irksome.ufl.manipulation.SplitTimeForm(time: BaseForm, remainder: BaseForm)[source]¶
Bases:
NamedTupleA container for a form split into time terms and a remainder.
Create new instance of SplitTimeForm(time, remainder)
- remainder: BaseForm¶
Alias for field number 1
- time: BaseForm¶
Alias for field number 0
- irksome.ufl.manipulation.check_integrals(integrals: Sequence[Integral], t: Expr = None, timedep_coeffs: Sequence[Coefficient] = (), expect_time_derivative: bool = True)[source]¶
Check a list of integrals for linearity in the time derivative.
- Parameters:
integrals – list of integrals.
timedep_coeffs – The time-dependent coefficients.
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.remove_time_derivatives(F: Form)[source]¶
Helper function to strip all time derivatives from a Form
- irksome.ufl.manipulation.split_time_derivative_terms(form: BaseForm, t: Expr = None, timedep_coeffs: Sequence[Coefficient] = ()) SplitTimeForm[source]¶
Split terms from a
Form.This splits a form (a sum of integrals) into those integrals which do contain a
TimeDerivativeacting on timedep_coeffs and those that don’t.- Parameters:
form – The form to split.
t – The time variable.
timedep_coeffs – The time-dependent coefficients.
- Returns:
a
SplitTimeFormtuple.- Raises:
ValueError – if the form does not apply anything other than first-order time derivatives to a single coefficient.