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: Argument)
- 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.lag module¶
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.has_nonlinear_time_derivative(F, u0)[source]¶
True iff
Fcontains a TimeDerivative of an expression that is nonlinear in u0 – i.e.Dt(g(u0))for some nonlinear g. These cases lose mass conservation when chain-ruled through the stage-derivative form, and require the conservative two-evaluation discretisation.For each
Dt(f)in the form, the Gateaux derivative offwith respect tou0is taken in a trial direction. If the derivative still depends onu0,fis nonlinear in u0. This delegates the classification of linear operators (Grad, Div, Indexed, restrictions, ListTensor, ComponentTensor, …) to UFL’s own derivative machinery rather than maintaining a parallel exemption list inside Irksome.Warning
The detection is syntactic: it checks whether
u0appears underDtafter differentiation. If a user creates an intermediateFunctionwhose values were interpolated from an expression in u0 and then writesDt(that_intermediate), the syntactic dependence on u0 is lost and this function will declare the form safe. The resulting discretisation is not mass-conservative. Always wrap the symbolic expression directly inDt(asDt(theta(u)), notDt(theta_function)).
- 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.