Suppose that we have a differential-algebraic system of equations, with two variables f(t) and g(t) such that f(0) = g(0). Suppose moreover that g(t) is algebraic and g(0) could be explicitly calculated.
Is it possible to avoid the latter calculation and let MTK figure it out by itself?
Here is a MWE of what we are trying to do, which returns an error:
using ModelingToolkit, DifferentialEquations
@variables t
D = Differential(t)
function system_f(; name)
@variables f(t) g(t)
eqs = [D(f) ~ g - f]
ODESystem(eqs; name)
end
function system_g(; name)
@variables g(t)
eqs = [g ~ t]
ODESystem(eqs; name)
end
@named f = system_f()
@named g = system_g()
connected_eqs = [
f.g ~ g.g,
]
@named _model = ODESystem(connected_eqs, t)
@named model = compose(_model, [f, g])
model = structural_simplify(model)
prob = ODEProblem(model, [f.f => g.g], (0.0, 10.0))
sol = solve(prob)
In the above example, we have that g(t)=t, thus f(0)=g(0)=0.
When g(t) is much more complicated, is there a way to avoid having to provide g(0) to MTK explicitly?
Regarding your proposal, how can we set the parameter value to be dependent on g(t_0)?
The initial value of g is automatically computed and dependent on t_0 (from the timespan passed to ODEProblem), thus we cannot assign a constant value to it.
Since we don’t need to provide an initial value of g, we also don’t want to provide an initial value to f (or to a parameter p), because it can be clearly derived from the problem.
One -quite inelegant- way I’m managing to address the problem is to solve the system 2 times, where the first time is merely used to get the initial value of g, as follows:
first set both initial conditions equal to an arbitrary value
solve the system, getting the solution pre_sol,
solve again the system, this time with initial condition f(0)=\text{pre_sol}.g(0)
For example, here are the lines to substitute to the last two ones in the initial MWE: