# Split ODE Problems

`SciMLBase.SplitODEProblem`

— TypeDefines a split ordinary differential equation (ODE) problem. Documentation Page: https://diffeq.sciml.ai/stable/types/split*ode*types/

**Mathematical Specification of a Split ODE Problem**

To define a `SplitODEProblem`

, you simply need to give a two functions $f_1$ and $f_2$ along with an initial condition $u_0$ which define an ODE:

\[\frac{du}{dt} = f_1(u,p,t) + f_2(u,p,t)\]

`f`

should be specified as `f(u,p,t)`

(or in-place as `f(du,u,p,t)`

), and `u₀`

should be an AbstractArray (or number) whose geometry matches the desired geometry of `u`

. Note that we are not limited to numbers or vectors for `u₀`

; one is allowed to provide `u₀`

as arbitrary matrices / higher dimension tensors as well.

Many splits are at least partially linear. That is the equation:

\[\frac{du}{dt} = Au + f_2(u,p,t)\]

For how to define a linear function `A`

, see the documentation for the DiffEqOperators.

**Constructors**

```
SplitODEProblem(f::SplitFunction,u0,tspan,p=NullParameters();kwargs...)
SplitODEProblem{isinplace}(f1,f2,u0,tspan,p=NullParameters();kwargs...)
```

The `isinplace`

parameter can be omitted and will be determined using the signature of `f2`

. Note that both `f1`

and `f2`

should support the in-place style if `isinplace`

is `true`

or they should both support the out-of-place style if `isinplace`

is `false`

. You cannot mix up the two styles.

Parameters are optional, and if not given then a `NullParameters()`

singleton will be used which will throw nice errors if you try to index non-existent parameters. Any extra keyword arguments are passed on to the solvers. For example, if you set a `callback`

in the problem, then that `callback`

will be added in every solve call.

Under the hood, a `SplitODEProblem`

is just a regular `ODEProblem`

whose `f`

is a `SplitFunction`

. Therefore you can solve a `SplitODEProblem`

using the same solvers for `ODEProblem`

. For solvers dedicated to split problems, see Split ODE Solvers.

For specifying Jacobians and mass matrices, see the DiffEqFunctions page.

**Fields**

`f1`

,`f2`

: The functions in the ODE.`u0`

: The initial condition.`tspan`

: The timespan for the problem.`p`

: The parameters for the problem. Defaults to`NullParameters`

`kwargs`

: The keyword arguments passed onto the solves.

`SciMLBase.SplitFunction`

— Type`SplitFunction{iip,F1,F2,TMM,C,Ta,Tt,TJ,JVP,VJP,JP,SP,TW,TWt,TPJ,S,O,TCV} <: AbstractODEFunction{iip}`

A representation of a split ODE function `f`

, defined by:

\[M \frac{du}{dt} = f_1(u,p,t) + f_2(u,p,t)\]

and all of its related functions, such as the Jacobian of `f`

, its gradient with respect to time, and more. For all cases, `u0`

is the initial condition, `p`

are the parameters, and `t`

is the independent variable.

Generally, for ODE integrators the `f_1`

portion should be considered the "stiff portion of the model" with larger time scale separation, while the `f_2`

portion should be considered the "non-stiff portion". This interpretation is directly used in integrators like IMEX (implicit-explicit integrators) and exponential integrators.

**Constructor**

```
SplitFunction{iip,recompile}(f1,f2;
mass_matrix = __has_mass_matrix(f) ? f.mass_matrix : I,
analytic = __has_analytic(f) ? f.analytic : nothing,
tgrad= __has_tgrad(f) ? f.tgrad : nothing,
jac = __has_jac(f) ? f.jac : nothing,
jvp = __has_jvp(f) ? f.jvp : nothing,
vjp = __has_vjp(f) ? f.vjp : nothing,
jac_prototype = __has_jac_prototype(f) ? f.jac_prototype : nothing,
sparsity = __has_sparsity(f) ? f.sparsity : jac_prototype,
paramjac = __has_paramjac(f) ? f.paramjac : nothing,
syms = __has_syms(f) ? f.syms : nothing,
indepsym= __has_indepsym(f) ? f.indepsym : nothing,
colorvec = __has_colorvec(f) ? f.colorvec : nothing,
sys = __has_sys(f) ? f.sys : nothing)
```

Note that only the functions `f_i`

themselves are required. These functions should be given as `f_i!(du,u,p,t)`

or `du = f_i(u,p,t)`

. See the section on `iip`

for more details on in-place vs out-of-place handling.

All of the remaining functions are optional for improving or accelerating the usage of `f`

. These include:

`mass_matrix`

: the mass matrix`M`

represented in the ODE function. Can be used to determine that the equation is actually a differential-algebraic equation (DAE) if`M`

is singular. Note that in this case special solvers are required, see the DAE solver page for more details: https://diffeq.sciml.ai/stable/solvers/dae_solve/. Must be an AbstractArray or an AbstractSciMLOperator.`analytic(u0,p,t)`

: used to pass an analytical solution function for the analytical solution of the ODE. Generally only used for testing and development of the solvers.`tgrad(dT,u,p,t)`

or dT=tgrad(u,p,t): returns $\frac{\partial f_1(u,p,t)}{\partial t}$`jac(J,u,p,t)`

or`J=jac(u,p,t)`

: returns $\frac{df_1}{du}$`jvp(Jv,v,u,p,t)`

or`Jv=jvp(v,u,p,t)`

: returns the directional derivative$\frac{df_1}{du} v$`vjp(Jv,v,u,p,t)`

or`Jv=vjp(v,u,p,t)`

: returns the adjoint derivative$\frac{df_1}{du}^\ast v$`jac_prototype`

: a prototype matrix matching the type that matches the Jacobian. For example, if the Jacobian is tridiagonal, then an appropriately sized`Tridiagonal`

matrix can be used as the prototype and integrators will specialize on this structure where possible. Non-structured sparsity patterns should use a`SparseMatrixCSC`

with a correct sparsity pattern for the Jacobian. The default is`nothing`

, which means a dense Jacobian.`paramjac(pJ,u,p,t)`

: returns the parameter Jacobian $\frac{df_1}{dp}$.`syms`

: the symbol names for the elements of the equation. This should match`u0`

in size. For example, if`u0 = [0.0,1.0]`

and`syms = [:x, :y]`

, this will apply a canonical naming to the values, allowing`sol[:x]`

in the solution and automatically naming values in plots.`indepsym`

: the canonical naming for the independent variable. Defaults to nothing, which internally uses`t`

as the representation in any plots.`colorvec`

: a color vector according to the SparseDiffTools.jl definition for the sparsity pattern of the`jac_prototype`

. This specializes the Jacobian construction when using finite differences and automatic differentiation to be computed in an accelerated manner based on the sparsity pattern. Defaults to`nothing`

, which means a color vector will be internally computed on demand when required. The cost of this operation is highly dependent on the sparsity pattern.

**Note on the Derivative Definition**

The derivatives, such as the Jacobian, are only defined on the `f1`

portion of the split ODE. This is used to treat the `f1`

implicit while keeping the `f2`

portion explicit.

**iip: In-Place vs Out-Of-Place**

For more details on this argument, see the ODEFunction documentation.

**recompile: Controlling Compilation and Specialization**

For more details on this argument, see the ODEFunction documentation.

**Fields**

The fields of the SplitFunction type directly match the names of the inputs.

**Symbolically Generating the Functions**

See the `modelingtoolkitize`

function from ModelingToolkit.jl for automatically symbolically generating the Jacobian and more from the numerically-defined functions. See `ModelingToolkit.SplitODEProblem`

for information on generating the SplitFunction from this symbolic engine.

## Solution Type

`SplitODEProblem`

solutions return an `ODESolution`

. For more information, see the ODE problem definition page for the `ODESolution`

docstring.