Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helpful error for missing guesses has disappeared #2873

Closed
hersle opened this issue Jul 18, 2024 · 3 comments · Fixed by #2877
Closed

Helpful error for missing guesses has disappeared #2873

hersle opened this issue Jul 18, 2024 · 3 comments · Fixed by #2877
Labels
bug Something isn't working

Comments

@hersle
Copy link
Contributor

hersle commented Jul 18, 2024

Solving an ODE that needs a guess in initialization, like

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D

@variables x(t) y(t)
@named sys = ODESystem([x^2 + y^2 ~ 25, D(x) ~ 1], t)
ssys = structural_simplify(sys)
prob = ODEProblem(ssys, [x => 3], (0, 1), [] #=; guesses = [y => 5]=#)

gives the bad error

ERROR: LoadError: MethodError: no method matching AbstractFloat(::Type{SymbolicUtils.BasicSymbolic{Real}})

Closest candidates are:
  AbstractFloat(::Bool)
   @ Base float.jl:264
  AbstractFloat(::UInt32)
   @ Base float.jl:272
  AbstractFloat(::UInt8)
   @ Base float.jl:270
  ...

Stacktrace:
  [1] float(x::Type)
    @ Base .\float.jl:294
  [2] promote_to_concrete(vs::Vector{SymbolicUtils.BasicSymbolic{Real}}; tofloat::Bool, use_union::Bool)
    @ ModelingToolkit c:\Users\herma\.julia\dev\Symboltz\dev\ModelingToolkit\src\utils.jl:657
  [3] varmap_to_vars(varmap::Dict{…}, varlist::Vector{…}; defaults::Dict{…}, check::Bool, toterm::Function, promotetoconcrete::Nothing, tofloat::Bool, use_union::Bool)
    @ ModelingToolkit c:\Users\herma\.julia\dev\Symboltz\dev\ModelingToolkit\src\variables.jl:165
  [4] get_u0(sys::NonlinearSystem, u0map::Dict{Any, Any}, parammap::Vector{Pair{…}}; symbolic_u0::Bool, toterm::Function)
    @ ModelingToolkit c:\Users\herma\.julia\dev\Symboltz\dev\ModelingToolkit\src\systems\diffeqs\abstractodesystem.jl:742
  [5] get_u0
    @ c:\Users\herma\.julia\dev\Symboltz\dev\ModelingToolkit\src\systems\diffeqs\abstractodesystem.jl:719 [inlined]
  [6] process_NonlinearProblem(constructor::Type, sys::NonlinearSystem, u0map::Dict{…}, parammap::Vector{…}; version::Nothing, jac::Bool, checkbounds::Bool, sparse::Bool, simplify::Bool, linenumbers::Bool, parallel::Symbolics.SerialForm, eval_expression::Bool, eval_module::Module, use_union::Bool, tofloat::Bool, kwargs::@Kwargs{…})
    @ ModelingToolkit c:\Users\herma\.julia\dev\Symboltz\dev\ModelingToolkit\src\systems\nonlinear\nonlinearsystem.jl:391

I believe it used to give something much nicer saying which variables have missing guesses. What happened to that?

@hersle
Copy link
Contributor Author

hersle commented Jul 19, 2024

I think this is the core issue:

bilde

  • varmap_to_vars() calls _varmap_to_vars() to try to calculate an initial value of y using a varmap of x => 3 (from u0) and t => 0 (from tspan).
  • fixpoint_sub() (blue line) substitutes t => 0 into y(t), so it becomes y(0). The next line detects that y has changed, and adds it to the dictionary of "successfully changed" variables.
  • missingvars does not contain y (because it "successfully changed"), so the MissingVariablesError is not thrown.
  • promote_to_concrete() tries to promote y(0) to a concrete value, and rightfully throws up.

This can be reproduced with simply

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D

@variables x(t) y(t)
ModelingToolkit._varmap_to_vars(Dict(t => 0), [y]) # changes y(t) to y(0)

@ChrisRackauckas
Copy link
Member

fixpoint_sub() (blue line) substitutes t => 0 into y(t), so it becomes y(0). The next line detects that y has changed, and adds it to the dictionary of "successfully changed" variables.

Yeah I've noticed that in the error message. I have thought that should probably be removed, but it's a bit tricky. We do want t => 0 so that non-autonomous DAEs with algebraic equations that explicitly have t know how to handle it during initialization, i.e. x ~ 2t is a fine initialization equation since you know what t is, but the substitution to y(0) is an unintended side effect. It seems to only happen when you miss a variable so it's "okay" in the sense it doesn't make anything not work, but indeed you get the worst error message so I've wanted to fix this but haven't thought of a great way to do it.

At a high level, the fix is to just not substitute t=>0 into the dependent variables. But I'm not sure there's a symbolics utility that helps with that.

@hersle
Copy link
Contributor Author

hersle commented Jul 19, 2024

Indeed. ?fixpoint_sub() says that

The operator keyword can be specified to prevent substitution of expressions inside operators of the given type.

Can this be used to shield t from substitutions when it is an argument of a dependent variable (not in cos(t), for example)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants