Open
Description
Problem Description
When specifying time-dependent parameters in an ODEProblem
by specifying them as anonymous functions, modelingtoolkitize
fails to take the symbolic Jacobian.
Example
Using the example parameterized problem (Example 3) in https://docs.juliadiffeq.org/latest/tutorials/ode_example.html
using DifferentialEquations
using ModelingToolkit
l = 1.0 # length [m]
m = 1.0 # mass[m]
g = 9.81 # gravitational acceleration [m/s²]
function pendulum!(du,u,p,t)
du[1] = u[2] # θ'(t) = ω(t)
du[2] = -3g/(2l)*sin(u[1]) + 3/(m*l^2)*p(t) # ω'(t) = -3g/(2l) sin θ(t) + 3/(ml^2)M(t)
end
θ₀ = 0.01 # initial angular deflection [rad]
ω₀ = 0.0 # initial angular velocity [rad/s]
u₀ = [θ₀, ω₀] # initial state vector
tspan = (0.0,10.0) # time interval
M = t->0.1sin(t) # external torque [Nm]
prob = ODEProblem(pendulum!,u₀,tspan,M)
ODEProblem with uType Array{Float64,1} and tType Float64. In-place: true
timespan: (0.0, 10.0)
u0: [0.01, 0.0]
Attempting to modelingtoolkitize
this ODEProblem
results in an error:
de = modelingtoolkitize(prob)
MethodError: no method matching keys(::getfield(Main, Symbol("##3#4")))
Closest candidates are:
keys(!Matched::Core.SimpleVector) at essentials.jl:606
keys(!Matched::Cmd) at process.jl:963
keys(!Matched::Tuple) at tuple.jl:46
...
Stacktrace:
[1] eachindex(::Function) at .\abstractarray.jl:209
[2] modelingtoolkitize(::ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,getfield(Main, Symbol("##3#4")),ODEFunction{true,typeof(pendulum!),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}) at \.julia\packages\ModelingToolkit\czHtj\src\systems\diffeqs\diffeqsystem.jl:265
[3] top-level scope at In[4]:1
This is due to attempting to call keys
on the parameter function p
, which can only become a array/tuple after it is called with time as argument. modelingtoolkitize
should recognize the parameter passed in being a function and replicate this function call symbolically.