DiffEq-Specific Array Types
In many cases, a standard array may not be enough to fully hold the data for a model. Many of the solvers in DifferentialEquations.jl (only the native Julia methods) allow you to solve problems on AbstractArray
types which allow you to extend the meaning of an array. This page describes some of the AbstractArray
types which can be helpful for modeling differential equations problems.
ArrayPartitions
ArrayPartitions in DiffEq are used for heterogeneous arrays. For example, DynamicalODEProblem
solvers use them internally to turn the separate parts into a single array. You can construct an ArrayPartition
using RecursiveArrayTools.jl:
using RecursiveArrayTools
A = ArrayPartition(x::AbstractArray...)
where x
is an array of arrays. Then, A
will act like a single array, and its broadcast will be type stable, allowing for it to be used inside of the native Julia DiffEq solvers in an efficient way. This is a good way to generate an array which has different units for different parts, or different amounts of precision.
Usage
An ArrayPartition
acts like a single array. A[i]
indexes through the first array, then the second, etc. all linearly. But A.x
is where the arrays are stored. Thus for
using RecursiveArrayTools
A = ArrayPartition(y,z)
We would have A.x[1]==y
and A.x[2]==z
. Broadcasting like f.(A)
is efficient.
Example: Dynamics Equations
In this example we will show using heterogeneous units in dynamics equations. Our arrays will be:
using Unitful, RecursiveArrayTools, DiffEqBase, OrdinaryDiffEq
using LinearAlgebra
r0 = [1131.340, -2282.343, 6672.423]u"km"
v0 = [-5.64305, 4.30333, 2.42879]u"km/s"
Δt = 86400.0*365u"s"
μ = 398600.4418u"km^3/s^2"
rv0 = ArrayPartition(r0,v0)
Here, r0
is the initial positions, and v0
are the initial velocities. rv0
is the ArrayPartition
initial condition. We now write our update function in terms of the ArrayPartition
:
function f(dy, y, μ, t)
r = norm(y.x[1])
dy.x[1] .= y.x[2]
dy.x[2] .= -μ .* y.x[1] / r^3
end
Notice that y.x[1]
is the r
part of y
, and y.x[2]
is the v
part of y
. Using this kind of indexing is type stable, even though the array itself is heterogeneous. Note that one can also use things like 2y
or y.+x
and the broadcasting will be efficient.
Now to solve our equations, we do the same thing as always in DiffEq:
prob = ODEProblem(f, rv0, (0.0u"s", Δt), μ)
sol = solve(prob, Vern8())
MultiScaleArrays
The multi-scale modeling functionality is provided by MultiScaleArrays.jl. It allows for designing a multi-scale model as an extension of an array, which in turn can be directly used in the native Julia solvers of DifferentialEquations.jl.
For more information, please see the MultiScaleArrays.jl README.