Open
Description
This is in essence the same problem as #2045, except that differential variables are present but evolve far too slowly to provide indirect error control for algebraic variables.
using ModelingToolkit
@variables t
D = Differential(t)
@mtkmodel Foo begin
@parameters begin
ω₁
ω₂
l
end
@variables begin
x(t) # differential variable
y(t) # differential variable
z(t) # algebraic variable
end
@equations begin
D(x) ~ ω₁ * 2pi * y # solution: x(t) = sin(2πω₁t)
D(y) ~ -ω₁ * 2pi * x # solution: y(t) = cos(2πω₁t)
z^l ~ sin(ω₂ * 2pi * t) # solution: z(t) = sin(2πω₂t) when l == 1.0
end
end
@mtkbuild foo = Foo();
Solve and plot with a variety of solvers:
using DifferentialEquations: solve, Rosenbrock23, Rodas4, FBDF
prob = ODEProblem(foo,
[foo.x => 1.0, foo.y => 0.0, foo.z => 0.0],
(0.0, 1.0),
[foo.ω₁ => 1.0, foo.ω₂ => 1000.0, foo.l => 1.0])
sol0 = solve(prob, Rosenbrock23())
sol1 = solve(prob, Rodas4())
sol2 = solve(prob, FBDF())
plots = []
for (name, sol) in [
("Rosenbrock23", sol0),
("Rodas4", sol1),
("FBDF", sol2),
]
z = sol(sol.t, idxs=foo.z)
plt = plot(z, layout=(2,1), legend=:none, title="$(name) (t=0..1)")
plot!(plt[2], z[1:findfirst(sol.t .>= 2e-3)], xlim=(0,2.1e-3), legend=:none, title="$(name) (t=0..2e-3)")
push!(plots, plt)
end
plots
results in:
In summary:
- The FBDF() solution is correct.
- The Rodas4() solution is correct at each
sol.t
but is heavily under-sampled - The Rosenbrock23() is wildly incorrect, even at each
sol.t
Metadata
Metadata
Assignees
Labels
No labels