Hi,
I try to initialize an ODE system in a function and then assign initial conditions and parameters through any kind of named structure (dict, vector(tuples), or whatever). However, the only way to set parameters outside the function is then through arrays, which is a source of error when they get large…
I’m new to Julia and try to find a good way to solve this that scales well for ensembles of ODEs later.
I tried this:
using ModelingToolkit, DifferentialEquations
function init_ODE()
@parameters g
@variables t, x(t), y(t), c_gp(t)
D = Differential(t)
particle_equations = [
c_gp ~ - x./ g,
D(x) ~ c_gp ,
D(y) ~ x- u(t)
]
return particle_equations
end
@register_symbolic u(t)
@named fol_separate = ODESystem(init_ODE())
fs = structural_simplify(fol_separate)
# external forcing
u(t) = 7 + 2.0 .* sin.(t .* π ./(60*30))
z0 = [ x => 0.0, y => 0.0]
params = [ g => 9 ]
prob = ODEProblem(fs, z0, (0.0, 60*60*5) , params) #(0.0,60.0*60.0*10)
sol = solve(prob, saveat=60*5)
gives an UndevVarErr for x, y, and g, which makes sense, they were never defined outside the function.
If, alternatively, I do:
z0 = [ fs.x => 0.0, fs.y => 0.0]
params = [ fs.g => 9 ]
The ODEProblem returns:
ArgumentError: Term{Real, Base.ImmutableDict{DataType, Any}}[x(t), y(t)] are missing from the variable map.
The only way is to write z0, params as arrays since @variables are only defined in the function.
Does someone have an idea of how to initialize a generic ODE problem with the ModelingToolkit properly and then define the parameters in a named structure?
In the end, I want a large ensemble of ODE systems that only differ by parameters and forcing. containing the ODEs and algebraic expressions in a function would be very useful.