Possible to save Differential Equation interpolation solution to a file?

Hi again everyone, I’ve got another question…

Using the DifferentialEquations package, the solutions aren’t just discrete lists of numbers for the function and its derivative, but it’s also an INTERPOLATION scheme which can output the estimated value at ANY value of time. Some of my solutions will eventually take hours or days to complete, is there any way I could save the ENTIRE interpolation scheme to a file, for reading into Julia later?

For example, the (abbreviated) code below does the calc, and saves the discrete values only. Is there any way to save & read "sol" back in as an interpolatable function? (e.g., for getting sol.u(t)[2] for any t-value again, etc.)

using DifferentialEquations
using DelimitedFiles
prob = SecondOrderODEProblem(DiffEqToSolve!,vInit,xInit,tspan,Param)
sol = solve(prob, dense=true)

open(TimeSolnFileNm, "w") do file
    writedlm(TimeSolnFileNm, getindex.(sol.t, 1))
end
open(dfSolnFileNm, "w") do file
    writedlm(dfSolnFileNm, getindex.(sol.u, 1))
end
open(FnSolnFileNm, "w") do file
    writedlm(FnSolnFileNm, getindex.(sol.u, 2))
end

ReadSolnTime = readdlm(TimeSolnFileNm)
ReadSolndf = readdlm(dfSolnFileNm)
ReadSolnFn = readdlm(FnSolnFileNm)

All of this stuff works to save & read the DISCRETE values of the solution – so I can always calculate, e.g., sol.u[10] later – but how to save and read, e.g., sol(5.25)[2] in a later running of the program, without re-solving everything?

(I saw some mentions elsewhere of BSON.jl and JLD2.jl; but BSON didn’t work when I tried it, and JLD2 seems not to be maintained.)

Thanks for any suggestions!

You should be able to use BSON, the blessing and the curse of BSON is that it can restore and execute arbitrary code. This makes it unwise to load BSON from untrusted sources and it means that the environment in which the BSON is loaded must have all the functions defined and modules loaded needed to reconstruct the types saved. This worked for me:

using DifferentialEquations
using BSON

spring(du, u, p, t) = -9u

function solve()
    du0 = [0.0]
    u0 = [2.0]
    tspan = (0.0,30.0)
    prob = SecondOrderODEProblem(spring,du0,u0,tspan)
    solve(prob)
end

sol = solve()

BSON.@save "solution.bson" sol

Then, to restore (in a new Julia session to be sure)

using DifferentialEquations
using BSON
# BSON needs this to reconstruct sol, I got
# ERROR: UndefVarError: LinearAlgebra not defined
# without this
using LinearAlgebra

# The name of the integrated function is part of the type of the ODEProblem,
# and the type of the ODEProblem is part of the type of the ODESolution,
# so the function must be defined, although it does not need to be
# implemented since only its type is used, it is never called.
# The simplest way to do this is probably just to include your "load" function
# in the same module that solves and saves
spring(du, u, p, t) = 0

BSON.@load "solution.bson" sol

sol(5.25)
1 Like

Note that one thing you can use to accelerate the solution as well is to save less, so only get the interpolation scheme if you really need it, otherwise reduce the amount of saving with saveat and other similar commands.

That said, if you do want to save it all, the right way to do it is described here:

https://diffeq.sciml.ai/latest/features/io/#JLD2-and-BSON.jl-1

JLD2 and BSON will work, but see how it describes the loading and how it interacts with the function definitions.

For JLD2 however see the deprecation warning and this issue (fails on 1.5).

1 Like

BSON worked, thanks guys!

Contradict, I basically used your formulation (for some reason I didn’t have to redefine "spring(du, u, p, t)"), although I did have to add "using FiniteDiff" as well.
(Not sure why it didn’t ask for "FiniteDifferences"; though maybe it will when I try more precise DiffEq ODE solvers.)

Thanks again…

Would it be possible to save the data points (and not the interpolation functions), and then recreate the interpolation functions upon loading the data points? [I.e., which interpolation schemes should be used?]

Yes, you can save the sol.t, sol.u, sol.k and recreate the solution. That could be worth documenting, though BSON and JLD2 should be the go-to solutions IMO

Since you solved your problem, it’d be nice to mark one of the posts as the solution so other people with this problem can easily find the solution. :wink:

1 Like