Skip to content

Commit 6fd0847

Browse files
ChrisRackauckasAayushSabharwal
authored andcommitted
Run initialization on ODEs with superset initial conditions
InitializationProblem is not always built, however it missed a case. If you have an ODE and you define all of the initial conditions, then it does not need an initialization problem. But, if you simplify down to an ODE and give initial conditions for all of the original variables, including some simplified out, then you have defined initial conditions on some observed quantities and that needs to be accounted for by an initialization process. This fixes #2619
1 parent 38392d1 commit 6fd0847

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ function process_DEProblem(constructor, sys::AbstractODESystem, u0map, parammap;
797797
varmap = canonicalize_varmap(varmap)
798798
varlist = collect(map(unwrap, dvs))
799799
missingvars = setdiff(varlist, collect(keys(varmap)))
800+
setboserved = setdiff(collect(keys(varmap)), varlist)
800801

801802
if eltype(parammap) <: Pair
802803
parammap = Dict(unwrap(k) => v for (k, v) in todict(parammap))
@@ -810,7 +811,8 @@ function process_DEProblem(constructor, sys::AbstractODESystem, u0map, parammap;
810811

811812
# ModelingToolkit.get_tearing_state(sys) !== nothing => Requires structural_simplify first
812813
if sys isa ODESystem && build_initializeprob &&
813-
(((implicit_dae || !isempty(missingvars)) &&
814+
(((implicit_dae || !isempty(missingvars) || !isempty(setboserved)) &&
815+
all(isequal(Continuous()), ci.var_domain) &&
814816
ModelingToolkit.get_tearing_state(sys) !== nothing) ||
815817
!isempty(initialization_equations(sys))) && t !== nothing
816818
if eltype(u0map) <: Number

test/initializationsystem.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,3 +522,32 @@ end
522522
structural_simplify
523523
@test_nowarn ODEProblem(sys, [D(x) => 1.0], (0.0, 1.0), [])
524524
end
525+
526+
# https://github.com/SciML/ModelingToolkit.jl/issues/2619
527+
@parameters k1 k2 ω
528+
@variables X(t) Y(t)
529+
eqs_1st_order = [D(Y) + Y - ω ~ 0,
530+
X + k1 ~ Y + k2]
531+
eqs_2nd_order = [D(D(Y)) + 2ω*D(Y) +^2)*Y ~ 0,
532+
X + k1 ~ Y + k2]
533+
@mtkbuild sys_1st_order = ODESystem(eqs_1st_order, t)
534+
@mtkbuild sys_2nd_order = ODESystem(eqs_2nd_order, t)
535+
536+
u0_1st_order_1 = [X => 1.0, Y => 2.0]
537+
u0_1st_order_2 = [Y => 2.0]
538+
u0_2nd_order_1 = [X => 1.0, Y => 2.0, D(Y) => 0.5]
539+
u0_2nd_order_2 = [Y => 2.0, D(Y) => 0.5]
540+
tspan = (0.0, 10.)
541+
ps ==> 0.5, k1 => 2.0, k2 => 3.0]
542+
543+
oprob_1st_order_1 = ODEProblem(sys_1st_order, u0_1st_order_1, tspan, ps)
544+
oprob_1st_order_2 = ODEProblem(sys_1st_order, u0_1st_order_2, tspan, ps)
545+
oprob_2nd_order_1 = ODEProblem(sys_2nd_order, u0_2nd_order_1, tspan, ps) # gives sys_2nd_order
546+
oprob_2nd_order_2 = ODEProblem(sys_2nd_order, u0_2nd_order_2, tspan, ps)
547+
548+
@test solve(oprob_1st_order_1, Rosenbrock23()).retcode == SciMLBase.ReturnCode.InitialFailure
549+
@test solve(oprob_1st_order_2, Rosenbrock23())[Y][1] == 2.0
550+
@test solve(oprob_2nd_order_1, Rosenbrock23()).retcode == SciMLBase.ReturnCode.InitialFailure
551+
sol = solve(oprob_2nd_order_2, Rosenbrock23()) # retcode: Success
552+
@test sol[Y][1] == 2.0
553+
@test sol[1][2] == 0.5

0 commit comments

Comments
 (0)