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.41k stars 204 forks source link

ParentScope() of parameters half works #1172

Open elbert5770 opened 3 years ago

elbert5770 commented 3 years ago

In composing a system of subsystems (U, etc.) of subsystems (Abeta38, etc.), using ParentScope works to promote state variables as expected. All the equations and the states end up being correct. However, when ParentScoping parameters, the parameters are promoted correctly in the equations but not in the parameter list. Example output from a composed and structural_simplified system below:

equations(simplified_sys) = ... Differential(t)(U₊Aβ38₊cbrain(t)) ~ kret*U₊Aβ38₊cex(t) + Qglym*(Vbr^-1)*(U₊Aβ38₊ccr(t) - U₊Aβ38₊cbrain(t))...  (Correct state variables and parameters)
states(simplified_sys) = Any[VSP1(t), VSP2(t), VSP3(t), U₊APP(t), U₊C83(t), U₊C99(t), U₊Aβ38₊cbrain(t), ... (Correct states)
parameters(simplified_sys) = ... U₊Aβ38₊Qglym ... U₊Aβ38₊kret ...  U₊Aβ38₊Vbr (unpromoted parameters)

Is there any downside to making the parameter list agree with the parameters in the equation?

YingboMa commented 3 years ago

Is there an MWE?

elbert5770 commented 3 years ago

Yes, indeed, and thank you for your work on this interesting project and your talk at JuliaCon.

The equations and states are promoted 'as requested'. The parameters are not. It would like to avoid eliminating the non-promoted parameters using 'defaults' and structural_simplify, as the actual number of parameters is much larger than what is shown here. Also please advise if this is not the intended function of ParentScope.

using ModelingToolkit, DifferentialEquations

function C99_factory(;name)
      ps = @parameters kf Vm1 Vm2 kgamma

      sts = @variables APP(t) C83(t) C99(t)
      kf = ParentScope(kf)
      kgamma = ParentScope(kgamma)
      Vm1 = ParentScope(Vm1)
      Vm2 = ParentScope(Vm2)

      D = Differential(t)
      # Define a nonlinear system
      eqs = [D(APP) ~ kf - Vm1*APP ,
      D(C83) ~ Vm1*APP  - Vm2*APP,
      D(C99) ~ Vm2*APP- kgamma*C99]

      @named Aβ38 = Abeta_factory()
      @named Aβ40 = Abeta_factory()
      compose(ODESystem(eqs,t,sts,ps;name=name),Aβ38,Aβ40)
end

function Abeta_factory(;name)
      ps = @parameters C99 C83 kgamma Vbr VCSF_cr Qglym
      sts = @variables  cbrain(t) ccr(t)
      C99 = ParentScope(C99)
      C83 = ParentScope(C83)
      kgamma = ParentScope(ParentScope(kgamma))
      Vbr = ParentScope(ParentScope(Vbr))
      VCSF_cr = ParentScope(ParentScope(VCSF_cr))
      Qglym = ParentScope(ParentScope(Qglym))

      D = Differential(t)

      eqs = [D(cbrain) ~ kgamma*C99 + Qglym/Vbr*(ccr-cbrain) ,
      D(ccr) ~ Qglym/VCSF_cr*(cbrain-ccr)]

      ODESystem(eqs,t,sts,ps;name=name)
end

@named U = C99_factory()
@named L = C99_factory()

ps = @parameters delta_VSP1 delta_VSP2
sts = @variables VSP1(t) VSP2(t)
D = Differential(t)

connections = [D(VSP1) ~ delta_VSP1,
            D(VSP2) ~ delta_VSP2
            ]

@named connected = compose(ODESystem(connections,t,sts,ps),U,L)
# @show equations(connected)
# @show states(connected)
# @show parameters(connected)

simplified_sys = structural_simplify(connected)
@show equations(simplified_sys)
@show states(simplified_sys)
@show parameters(simplified_sys)
ChrisRackauckas commented 7 months ago

@YingboMa was this fixed?