The AbstractDiffEqOperator interface is an interface for declaring parts of a differential equation as linear or affine. This then allows the solvers to exploit linearity to achieve maximal performance.

Note: this functionality is under heavy development. Interfaces may change. Treat this as experimental until the end of Summer 2019.

Using DiffEqOperators

AbstractDiffEqOperators act like functions. When defined, A has function calls A(u,p,t) and A(du,u,p,t) that act like A*u. These operators update via a function update_coefficients!(A,u,p,t).


Wrapping an Array: DiffEqArrayOperator

DiffEqArrayOperator is for defining an operator directly from an array. The operator is of the form


for some scalar α and time plus possibly state dependent A. The constructor is:

                             update_func = DEFAULT_UPDATE_FUNC)

A is the operator array. α is the scalar coefficient. If α is a function α(t), then it will update the coefficient as necessary. update_func(A,u,p,t) is the function called by update_coefficients!(A,u,p,t) (along with α if it's a function). If left as its default, then update_func is trivial which signifies A is a constant.


For As = (A1,A2,...,An) and Bs = (B1,B2,...,Bn) where each of the Ai and Bi are DiffEqLinearOperators, the following constructor:

function AffineDiffEqOperator{T}(As,Bs,u_cache=nothing)

builds an operator L = (A1 + A2 + ... An)*u + B1 + B2 + ... + Bn. u_cache is for designating a type of internal cache for non-allocating evaluation of L(du,u,p,t). If not given, the function L(du,u,p,t) is not available. Note that in solves which exploit this structure, this function call is not necessary. It's only used as the fallback in ODE solvers which were not developed for this structure.

Formal Properties of DiffEqOperators

These are the formal properties that an AbstractDiffEqOperator should obey for it to work in the solvers.

AbstractDiffEqOperator Interface Description

  1. Function call and multiplication: L(du,u,p,t) for inplace and du = L(u,p,t) for out-of-place, meaning L*u and A_mul_B!.
  2. If the operator is not a constant, update it with (u,p,t). A mutating form, i.e. update_coefficients!(A,u,p,t) that changes the internal coefficients, and a out-of-place form B = update_coefficients(A,u,p,t).
  3. is_constant(A) trait for whether the operator is constant or not.

AbstractDiffEqLinearOpeartor Interface Description

  1. AbstractDiffEqLinearOperator <: AbstractDiffEqOperator
  2. Can absorb under multiplication by a scalar. In all algorithms things like dt*L show up all the time, so the linear operator must be able to absorb such constants.
  3. is_constant(A) trait for whether the operator is constant or not.
  4. Optional: diagonal, symmetric, etc traits from LinearMaps.jl.
  5. Optional: expm(A). Required for simple exponential integration.
  6. Optional: expmv(A,u,t) = expm(t*A)*u and expmv!(v,A::DiffEqOperator,u,t) Required for sparse-saving exponential integration.
  7. Optional: factorizations. A_ldiv_B, factorize et. al. This is only required for algorithms which use the factorization of the operator (Crank-Nicholson), and only for when the default linear solve is used.