I am trying to solve a ODE using a DEDataVector to pass and store parameters that come from evaluating functions taking the state vector as argument. After reading the documentation I expected to obtain the value of the fields in SimData
at the same times as the solution for the state vector. However, the following example shows that this is not always true:
using StaticArrays
using OrdinaryDiffEq
mutable struct SimData{T, N} <: DEDataVector{T}
x::SVector{N, T}
t::T
α::T
end
foo(x) = cos(x) - 1
function fun(x, p, t)
α = foo(x[1])
xd1 = α * x[1] + 0.5 * x[2]
xd2 = x[1]
xd = @SVector [xd1, xd2]
return SimData(xd, t, α)
end
x0_arr = @SVector [1.0, 0.0]
x0 = SimData(x0_arr, 0.0, foo(x0_arr[1]))
prob = ODEProblem{false}(fun, x0, (0.0, 1.0))
Case working as expected:
julia> sol = solve(prob, Tsit5());
julia> [sol[ii].t for ii in 1:length(sol)] - sol.t
9-element Vector{Float64}:
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
However:
julia> sol = solve(prob, RK4());
julia> [sol[ii].t for ii in 1:length(sol)] - sol.t
13-element Vector{Float64}:
0.0
-0.0004995004468281904
-0.004303836649044169
-0.011007355182091345
-0.017836652779592538
-0.025106222288033136
-0.03475184792175873
-0.04537449406429234
-0.05776887934747188
-0.07134099643887737
-0.08652208123574157
-0.10318679719026902
-0.04230133645599987
I also tried:
sol = solve(prob, RK4(), saveat=0:0.1:1)
sol = solve(prob, RK4(), dt=0.1)
but I couldn’t obtain the same result as with Tsit5
. As it seems to me that this is related to automatic timestep determination, I finally arrived to:
julia> sol = solve(prob, RK4(), dt=0.1, adaptive=false);
julia> [sol[ii].t for ii in 1:length(sol)] - sol.t
11-element Vector{Float64}:
0.0
-0.05
-0.04999999999999999
-0.050000000000000044
-0.04999999999999999
-0.04999999999999999
-0.04999999999999993
-0.04999999999999993
-0.04999999999999993
-0.04999999999999993
-0.050000000000000044
which makes sense to me (t at which f is called is the one from the previous solution point).
At this point, my question is: is there a way to obtain a result equivalent to Tsit5()
example where sol[ii].t is evaluated at the same time as sol.u[ii]?