June 10, 2026
NASA/JPL-Caltech
Unitful.jlA Julia package for handling measurements
Templated types
Unit checking reduced to type checking
Orbital mechanics ODE:
\(\dfrac{\mathrm{d}\mathbf{r}}{\mathrm{d}t} = \mathbf{v}\)
\(\dfrac{\mathrm{d}\mathbf{v}}{\mathrm{d}t} = - \frac{\mu\cdot \mathbf{r}}{\left\|\mathbf{v}\right\|_2^3}\)
\(\left[\mathbf{r}\right] = \mathrm{km}\) and \(\left[\mathbf{v}\right] = \mathrm{km/s}\), but what is \(\left[\begin{pmatrix}\mathbf{r} \\ \mathbf{v}\end{pmatrix}\right]\)?
DifferentialEquations supports Unitful for some ODE solversu_res[i] = k_1 * u_1[i] + k_2 * u_2[i]), but instead by broadcasting u .= k_1 .* u_1 .+ k_2 .* u_2zero()Unitful quantities. Examples:
RecursiveArrayTools.jlSupports both heterogeneous element types and type-stable broadcasting
using DifferentialEquations, Unitful
using RecursiveArrayTools
using LinearAlgebra
r0 = [1131.340, -2282.343, 6672.423]Unitful.u"km"
v0 = [-5.64305, 4.30333, 2.42879]Unitful.u"km/s"
Δt = 86400.0 * 365Unitful.u"s"
μ = 398600.4418Unitful.u"km^3/s^2"
rv0 = RecursiveArrayTools.ArrayPartition(r0, v0)
function f_orbital!(dy, y, μ, t)
r = norm(y.x[1])
dy.x[1] .= y.x[2]
dy.x[2] .= -μ .* y.x[1] / r^3
end
prob = ODEProblem(f_orbital!, rv0, (0.0Unitful.u"s", Δt), μ)
sol = solve(prob, Vern8())ArrayPartition is supposed to provide type-stable broadcasting, but sometimes the compiler gives up on inference, causing considerable slowdownsArrayPartition does not allow the components to have names, only a numeric indexHeterogeneousArrays.jlHeterogeneousVector which resolves the issues with ArrayPartitionConsider arrays y, x_1, x_2 with components u and v. We decompose the the heterogeneous broadcast y .= a .* x_1 .+ b .* x_2 into the homogeneous broadcasts y.u .= a .* x_1.u .+ b .* x_2.u and y.v .= a .* x_1.v .+ b .* x_2.v
Array as having Unitful components?Unitful: Can we construct a wrapper to make any solver work?