Hello,
I would like to use the integrator interface of DifferentialEquations.jl for an ensemble, i.e. loop over the different ensemble members and advance forward in time by one time step each of them.
However, if I integrate multiple copies of the initial condition u0
stacked in an array ens
, it doesn’t give the same result.
using Test
using DifferentialEquations, OrdinaryDiffeq
function lorenz(du,u,p,t)
du[1] = 10.0*(u[2]-u[1])
du[2] = u[1]*(28.0-u[3]) - u[2]
du[3] = u[1]*u[2] - (8/3)*u[3]
end
u0 = [10.0; -5.0; 2.0]
tspan = (0.0,40.0)
Δt = 1e-2
T = tspan[1]:Δt:tspan[end]
prob = ODEProblem(lorenz,u0,tspan)
sol = solve(prob, RK4(), adaptive = false, dt = Δt);
# Integrator approach
integrator = init(prob, RK4(), adaptive =false, dt = Δt, save_everystep=false)
states = [deepcopy(u0)]
for t in T[1:end-1]
step!(integrator)
push!(states, deepcopy(integrator.u))
end
@test norm(states[end]-sol.u[end])<1e-15
Test Passed
Code if I integrate multiple copies of the initial condition u0
stacked in an array ens
, it doesn’t give the same result:
k = 3
Ne = 5
ens = zeros(k,Ne)
ens .= repeat(u0, 1, Ne)
#Define propagation operator
function Propagate(t::Float64, ens, integrator::OrdinaryDiffEq.ODEIntegrator)
Nx, Ne = size(ens)
for i=1:Ne
s = deepcopy(ens[:,i])
set_t!(integrator, deepcopy(t))
set_u!(integrator, deepcopy(s))
step!(integrator)
ens[:,i] .= deepcopy(integrator.u)
end
end
ens_hist = []
# Push the initial state
push!(ens_hist, deepcopy(ens))
# Propagate each ensemble member
for t in T[1:end-1]
Propagate(t, ens, integrator)
push!(ens_hist, deepcopy(ens))
end
@show sol.u[end]
@show ens_hist[end][:,1]
sol.u[end] = [-4.224313362730708, 0.6368037936621876, 28.848001043272014]
3-element Array{Float64,1}:
-4.224313362730708
0.6368037936621876
28.848001043272014
(ens_hist[end])[:, 1] = [-4.229515264992412, 0.6012730192194168, 28.81877934048208]
3-element Array{Float64,1}:
-4.229515264992412
0.6012730192194168
28.81877934048208