SciML / ModelingToolkit.jl

An acausal modeling framework for automatically parallelized scientific machine learning (SciML) in Julia. A computer algebra system for integrated symbolics for physics-informed machine learning and automated transformations of differential equations
https://mtk.sciml.ai/dev/
Other
1.38k stars 196 forks source link

Initialization is incomplete without a `u0`, despite passing `guesses` #2788

Closed ven-k closed 2 weeks ago

ven-k commented 3 weeks ago

Describe the bug 🐞

Despite setting the ~initialization_eqs (or~ guesses, initialization fails during the construction of ODEProblem; passing a u0 with same values works.

Expected behavior

Whenever guesses are in the model, and u0 doesn't override its values, it should be used to complete the initialization.

Minimal Reproducible Example 👇

using ModelingToolkitStandardLibrary.Blocks: Constant, SecondOrder
using ModelingToolkit: t_nounits as t, D_nounits as D
using ModelingToolkit

@component function SecondOrderTest(; name)
    systems = @named begin
        c = Constant(k=1)
        pt2 = SecondOrder(k=1, w=1, d=0.5)
    end
    eqs = [c.output.u ~ pt2.u]
    guesses = [pt2.xd => 0.0]

    return ODESystem(eqs, t, [], []; systems, name, guesses)
end

@mtkbuild model = SecondOrderTest()
prob = ODEProblem(model, [], (0, 10))
#  prob = ODEProblem(model, [model.pt2.xd => 0.0], (0, 10)) works

Error & Stacktrace ⚠️

ERROR: Initialization incomplete. Not all of the state variables of the
DAE system can be determined by the initialization. Missing
variables:

Any[pt2₊xd(t)]

Stacktrace:
  [1] ModelingToolkit.InitializationProblem{…}(sys::ODESystem, t::Int64, u0map::Dict{…}, parammap::SciMLBase.NullParameters; guesses::Dict{…}, check_length::Bool, warn_initialize_determined::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1619
  [2] InitializationProblem
    @ ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1595 [inlined]
  [3] #_#822
    @ ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1573 [inlined]
  [4] InitializationProblem
    @ ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1572 [inlined]
  [5] #InitializationProblem#820
    @ ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1561 [inlined]
  [6] InitializationProblem
    @ ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1560 [inlined]
  [7] process_DEProblem(constructor::Type, sys::ODESystem, u0map::Vector{…}, parammap::SciMLBase.NullParameters; implicit_dae::Bool, du0map::Nothing, version::Nothing, tgrad::Bool, jac::Bool, checkbounds::Bool, sparse::Bool, simplify::Bool, linenumbers::Bool, parallel::Symbolics.SerialForm, eval_expression::Bool, use_union::Bool, tofloat::Bool, symbolic_u0::Bool, u0_constructor::typeof(identity), guesses::Dict{…}, t::Int64, warn_initialize_determined::Bool, build_initializeprob::Bool, kwargs::@Kwargs{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:922
  [8] process_DEProblem
    @ ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:835 [inlined]
  [9] (ODEProblem{…})(sys::ODESystem, u0map::Vector{…}, tspan::Tuple{…}, parammap::SciMLBase.NullParameters; callback::Nothing, check_length::Bool, warn_initialize_determined::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1086
 [10] ODEProblem
    @ ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1076 [inlined]
 [11] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Any}, tspan::Tuple{Int64, Int64})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1076
 [12] (ODEProblem{true})(::ODESystem, ::Vector{Any}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1063
 [13] (ODEProblem{true})(::ODESystem, ::Vector{Any}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1062
 [14] ODEProblem(::ODESystem, ::Vector{Any}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1052
 [15] ODEProblem(::ODESystem, ::Vector{Any}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/3Suzf/src/systems/diffeqs/abstractodesystem.jl:1051
 [16] top-level scope
    @ REPL[6]:1
Some type information was truncated. Use `show(err)` to see complete types.

Environment (please complete the following information):

(mtkmsl) pkg> status
Status `~/.julia/dev/mtkmsl/Project.toml`
  [0c46a032] DifferentialEquations v7.13.0
  [961ee093] ModelingToolkit v9.16.0
  [16a59e39] ModelingToolkitStandardLibrary v2.7.1
  [1dea7af3] OrdinaryDiffEq v6.82.0
julia> versioninfo()
Julia Version 1.10.4
Commit 48d4fd48430 (2024-06-04 10:41 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 16 × AMD Ryzen 9 5900HS with Radeon Graphics
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, znver3)
Threads: 16 default, 0 interactive, 8 GC (on 16 virtual cores)
mtiller-jh commented 3 weeks ago

@ChrisRackauckas My understanding from our discussion this morning is that you don't think this is actually a bug. But can you explain in this issue why you think this isn't a valid bug and what the remedy is? I'm just the middle man here.

ven-k commented 3 weeks ago

I think the answer to the initialization_eqs is:

Comment by Chris in this issue:

Yes, the equations are not satisfiable. Note that it's not (x=>1, y=>1, x^2 + y^2 ~ 1), it's (x=>1, y ~ 1, x^2 + y^2 ~ 1). That's different. initialization_eqs can have any nonlinear function. You cannot assume it's always analytically solvable. There is an issue of asking why this one isn't actually simplified out, which may be related to the unsatisfiabiltiy, but you should expect that if you can put in a nonlinear system then you need a guess.

But also, x = 1, y = 1, x^2 + y^2 != 1, so this test case is erroring for good reasons.

But I wonder if guesses can be promoted as u0 whenever available.

mtiller-jh commented 3 weeks ago

But I wonder if guesses can be promoted as u0 whenever available.

There is already so much confusion about the relationship between guesses and initial conditions, I don't want to do anything to reinforce that.

I need to revisit the tests I had previously reviewed to understand why this is even coming up. I don't understand why we are adding initialization equations that cannot be satisfied.

ChrisRackauckas commented 3 weeks ago

There is already so much confusion about the relationship between guesses and initial conditions, I don't want to do anything to reinforce that.

There is no confusion between guesses and initial conditions. They are separate. And we want to keep it that way. "But I wonder if guesses can be promoted as u0 whenever available." is exactly the kind of thing that would confuse them which is why we won't do it.

ChrisRackauckas commented 3 weeks ago

@ChrisRackauckas My understanding from our discussion this morning is that you don't think this is actually a bug. But can you explain in this issue why you think this isn't a valid bug and what the remedy is? I'm just the middle man here.

No, I was talking about the other issue that @ven-k opened at the same time https://github.com/SciML/ModelingToolkit.jl/issues/2787. This one seems to have opened after our discussion.

But I agree with the error message:

isys = generate_initializesystem(model)

julia> equations(isys)
3-element Vector{Equation}:
 0 ~ c₊k - c₊output₊u(t)
 0 ~ -pt2₊y(t) + pt2₊x(t)
 0 ~ c₊output₊u(t) - pt2₊u(t)

julia> unknowns(isys)
5-element Vector{SymbolicUtils.BasicSymbolic{Real}}:
 pt2₊x(t)
 pt2₊xd(t)
 c₊output₊u(t)
 pt2₊y(t)
 pt2₊u(t)

that pt2₊xd(t) is not in the system. Though I think you are hitting a bug here about underdetermined systems that are fully solvable.

julia> sys = structural_simplify(isys; fully_determined = false)
Model model with 0 equations
Unknowns (0):
Parameters (5):
  c₊k [defaults to 1]: Constant output value of block
  pt2₊k [defaults to 1]: Gain

There should be 2 unknowns in here after simplifying 3 equations to 0. It's another instance of https://github.com/SciML/ModelingToolkit.jl/issues/2515. @YingboMa can you take a look at that?