How to define a system of ODEs with @ode_def and update the value of a variable using a function that depends on time?

You need to @register_symbolic it so that way it’s kept as a node in the symbolic graph.

using DifferentialEquations
using ParameterizedFunctions

# Solve odeFB
odeFB = @ode_def begin 
    dGp = ((Vmax * Ge * Gp)/(Km + Gp)) - (k4 * Gp) - (k2 * A * Gp) + (km2 * A) + (km4 * Gi)
    dGi = (k4 * Gp) - (k5 * Gi) - (km4 * Gi) + (km5 * A)
    dA = - (k3 * A) + (k5 * Gi) - (km5 * A)
end Vmax Ge Km k2 k3 k4 k5 km2 km4 km5

x0 = ones(length(odeFB.syms))
p  = (1400, 24.15, 1100, 5.3, 4, 2, 2.3, 5.3, 2, 2.3)
solFB = solve(ODEProblem(odeFB,x0,1000,p); reltol = 1e-12);

# External function to calculate a constant of the equation du[2] of the second system 
function f(t, solFB)
    if t > 0
        i = findfirst(solFB.t .>= t)
        return ((((solFB[1,i] - solFB[1,i-1]) / (solFB.t[i] - solFB.t[i-1])) * (t .- solFB.t[i-1])) .+ solFB[1,i-1])
    else 
        return solFB[1,1]
    end
end
f2(t) = f(t, solFB)

using Symbolics
@register_symbolic f2(t)

# Solve odeNF
odeNF = @ode_def begin 
    dGp = ((Vmax * Ge * Gp)/(Km + Gp)) - (k4 * Gp) - (k2 * A * Gp) + (km2 * A) + (km4 * Gi)
    dGi = (k4 * f2(t)) - (k5 * Gi) - (km4 * Gi) + (km5 * A)
    dA = - (k3 * A) + (k5 * Gi) - (km5 * A)
end Vmax Ge Km k2 k3 k4 k5 km2 km4 km5
prob = ODEProblem(odeNF, x0, 1000, p); 
prob.f(x0,p,0.0)

solNF = solve(prob, reltol = 1e-12);

See Function Registration and Tracing · Symbolics.jl for more details.

This is because ParameterizedFunctions.jl is implemented using ModelingToolkit.jl/Symbolics.jl, and this is a property of the symbolic library. Generally I wouldn’t recommend ParameterizedFunctions.jl that much these days except for very simple cases, but you can use this to make it do crazy things just by registering more functions to it.

1 Like