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

Initializing unknowns with parameter fails when using `remake` #2832

Open bradcarman opened 2 days ago

bradcarman commented 2 days ago

MWE...

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

@parameters g x0
@variables x(t)=x0 y(t) [state_priority = 10] λ(t)
eqs = [D(D(x)) ~ λ * x
       D(D(y)) ~ λ * y - g
       x^2 + y^2 ~ 1]
@mtkbuild pend = ODESystem(eqs, t)
prb = ODEProblem(pend, [y => 0], (0.0, 1.5), [g => 1, x0 => 1], guesses = [λ => 1])
@test prb.u0[4] == prb.ps[x0]

prb2 = remake(prb; p=[x0=>10])
@test prb2.u0[4] == prb2.ps[x0]  # ERROR!!
hersle commented 2 days ago

Does it work if you add use_defaults = true to remake()?

bradcarman commented 2 days ago

use_defaults = true doesn't work unfortunately, I still get...

julia> @test prb2.u0[4] == prb2.ps[x0]  # ERROR!!
Test Failed at c:\Work\Packages\ActiveSuspension\ActiveSuspensionModel.jl\test\mwe.jl:16
  Expression: prb2.u0[4] == prb2.ps[x0]
   Evaluated: 1.0 == 10.0

Which means prb2 just takes the u0 value from prb

hersle commented 1 day ago

It works if you also pass u0 = Dict():

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

@parameters g x0
@variables x(t)=x0 y(t) [state_priority = 10] λ(t)
eqs = [D(D(x)) ~ λ * x
       D(D(y)) ~ λ * y - g
       x^2 + y^2 ~ 1]
@mtkbuild pend = ODESystem(eqs, t)
prb = ODEProblem(pend, [y => 0], (0.0, 1.5), [g => 1, x0 => 1], guesses = [λ => 1])
@test prb.u0[4] == prb.ps[x0]

prb2 = remake(prb; u0=Dict(), p=[x0=>10], use_defaults=true)
@test prb2.u0[4] == prb2.ps[x0]
bradcarman commented 1 day ago

Interesting, thanks for finding that! I think this should still stay open as a bug.

Also, use_defaults is not needed here.

prb2 = remake(prb; u0=Dict(), p=[x0=>10])
@test prb2.u0[4] == prb2.ps[x0]  # OK
ChrisRackauckas commented 1 day ago

@AayushSabharwal why would the Dict be required?

AayushSabharwal commented 1 day ago

If either u0 or p is not specified, it keeps its original value. This is to avoid updating based on dependent defaults when the user doesn't want to

AayushSabharwal commented 1 day ago

I'm a little more concerned that defaults are used when use_defaults = false 😅