Commit 40073b6
committed
Fix hierarchical modeling with DDEs
Fixes #2232
The issue before was that the namespace handling was not recursing into variables, meaning that when namespace was applied, states and parameters used in the delay definition were not namespaced. This was the output before:
```julia
using ModelingToolkit, DifferentialEquations
@variables t
D = Differential(t)
@parameters x(..) a
function oscillator(;name, k=1.0, τ=0.01)
@parameters k=k τ=τ
@variables x(..)=0.1 y(t)=0.1 jcn(t)=0.0 delx(t)
eqs = [D(x(t)) ~ y,
D(y) ~ -k*x(t-τ)+jcn,
delx ~ x(t-τ)]
return System(eqs; name=name)
end
@nAmed osc1 = oscillator(k=1.0, τ=0.01)
@nAmed osc2 = oscillator(k=2.0, τ=0.04)
eqs = [osc1.jcn ~ osc2.delx,
osc2.jcn ~ osc1.delx]
@nAmed coupledOsc = compose(System(eqs, t; name=:connected), [osc1, osc2])
julia> equations(coupledOsc)
8-element Vector{Equation}:
osc1₊jcn(t) ~ osc2₊delx(t)
osc2₊jcn(t) ~ osc1₊delx(t)
Differential(t)(osc1₊x(t)) ~ osc1₊y(t)
Differential(t)(osc1₊y(t)) ~ osc1₊jcn(t) - osc1₊k*osc1₊x(t - τ)
osc1₊delx(t) ~ osc1₊x(t - τ)
Differential(t)(osc2₊x(t)) ~ osc2₊y(t)
Differential(t)(osc2₊y(t)) ~ osc2₊jcn(t) - osc2₊k*osc2₊x(t - τ)
osc2₊delx(t) ~ osc2₊x(t - τ)
```
You can see the issue is that it's using `τ` instead of a namespaced `tau`. With this PR:
```julia
julia> equations(coupledOsc)
8-element Vector{Equation}:
osc1₊jcn(t) ~ osc2₊delx(t)
osc2₊jcn(t) ~ osc1₊delx(t)
Differential(t)(osc1₊x(t)) ~ osc1₊y(t)
Differential(t)(osc1₊y(t)) ~ osc1₊jcn(t) - osc1₊k*osc1₊x(t - osc1₊τ)
osc1₊delx(t) ~ osc1₊x(t - osc1₊τ)
Differential(t)(osc2₊x(t)) ~ osc2₊y(t)
Differential(t)(osc2₊y(t)) ~ osc2₊jcn(t) - osc2₊k*osc2₊x(t - osc2₊τ)
osc2₊delx(t) ~ osc2₊x(t - osc2₊τ)
```
However, something is going on with structural_simplify here:
```julia
simpsys = structural_simplify(coupledOsc)
equations(simpsys)
6-element Vector{Equation}:
Differential(t)(osc1₊x(t)) ~ osc1₊y(t)
Differential(t)(osc1₊y(t)) ~ osc1₊jcn(t) - osc1₊k*osc1₊x(t - osc1₊τ)
Differential(t)(osc2₊x(t)) ~ osc2₊y(t)
Differential(t)(osc2₊y(t)) ~ osc2₊jcn(t) - osc2₊k*osc2₊x(t - osc2₊τ)
0 ~ osc1₊x(t - osc1₊τ) - osc1₊delx(t)
0 ~ osc2₊x(t - osc2₊τ) - osc2₊delx(t)
```
This errors:
```julia
julia> prob = DDEProblem(structural_simplify(coupledOsc), [0.1,0.1,0.1,0.1], (0, 50), constant_lags=[osc1.τ, osc2.τ])
ERROR: ArgumentError: Equations (6), states (4), and initial conditions (4) are of different lengths. To allow a different number of equations than states use kwarg check_length=false.
Stacktrace:
[1] check_eqs_u0(eqs::Vector{Equation}, dvs::Vector{Any}, u0::Vector{Float64}; check_length::Bool, kwargs::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:t, :has_difference, :constant_lags), Tuple{Int64, Bool, Vector{Num}}}})
@ ModelingToolkit C:\Users\accou\.julia\packages\ModelingToolkit\ua9Sp\src\systems\abstractsystem.jl:1714
[2] process_DEProblem(constructor::Type, sys::ODESystem, u0map::Vector{Float64}, 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, kwargs::Base.Pairs{Symbol, Any, NTuple{4, Symbol}, NamedTuple{(:t, :has_difference, :check_length, :constant_lags), Tuple{Int64, Bool, Bool, Vector{Num}}}})
@ ModelingToolkit C:\Users\accou\.julia\packages\ModelingToolkit\ua9Sp\src\systems\diffeqs\abstractodesystem.jl:736
[3] (DDEProblem{true})(sys::ODESystem, u0map::Vector{Float64}, tspan::Tuple{Int64, Int64}, parammap::SciMLBase.NullParameters; callback::Nothing, check_length::Bool, kwargs::Base.Pairs{Symbol, Vector{Num}, Tuple{Symbol}, NamedTuple{(:constant_lags,), Tuple{Vector{Num}}}})
@ ModelingToolkit C:\Users\accou\.julia\packages\ModelingToolkit\ua9Sp\src\systems\diffeqs\abstractodesystem.jl:930
[4] DDEProblem
@ C:\Users\accou\.julia\packages\ModelingToolkit\ua9Sp\src\systems\diffeqs\abstractodesystem.jl:923 [inlined]
[5] DDEProblem(::ODESystem, ::Vector{Float64}, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Vector{Num}, Tuple{Symbol}, NamedTuple{(:constant_lags,), Tuple{Vector{Num}}}})
@ ModelingToolkit C:\Users\accou\.julia\packages\ModelingToolkit\ua9Sp\src\systems\diffeqs\abstractodesystem.jl:921
[6] top-level scope
@ REPL[2]:1
```
The reason is because the last two equations are not deleted.
```julia
julia> states(simpsys)
4-element Vector{Any}:
osc1₊x(t)
osc1₊y(t)
osc2₊x(t)
osc2₊y(t)
```
```julia
julia> states(simpsys)
4-element Vector{Any}:
osc1₊x(t)
osc1₊y(t)
osc2₊x(t)
osc2₊y(t)
julia> observed(simpsys)
4-element Vector{Equation}:
osc2₊delx(t) ~ -0.0
osc1₊delx(t) ~ -0.0
osc1₊jcn(t) ~ osc2₊delx(t)
osc2₊jcn(t) ~ osc1₊delx(t)
```
These last two equations
```
0 ~ osc1₊x(t - osc1₊τ) - osc1₊delx(t)
0 ~ osc2₊x(t - osc2₊τ) - osc2₊delx(t)
```
should be observed equations in terms of the constant value (via delay):
```
osc1₊delx(t) ~ osc1₊x(t - osc1₊τ)
osc2₊delx(t) ~ osc2₊x(t - osc2₊τ)
```
and removed from the equations, but instead they are still in there so it things there's 6 equations and errors. Is some value matching thing missing the deletion of these equations?1 parent 74fb734 commit 40073b6
1 file changed
+9
-9
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
425 | 425 | | |
426 | 426 | | |
427 | 427 | | |
428 | | - | |
| 428 | + | |
429 | 429 | | |
430 | 430 | | |
431 | 431 | | |
| |||
434 | 434 | | |
435 | 435 | | |
436 | 436 | | |
437 | | - | |
| 437 | + | |
438 | 438 | | |
439 | 439 | | |
440 | 440 | | |
| |||
495 | 495 | | |
496 | 496 | | |
497 | 497 | | |
498 | | - | |
499 | | - | |
500 | 498 | | |
501 | 499 | | |
502 | | - | |
503 | | - | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
504 | 505 | | |
505 | | - | |
506 | | - | |
507 | | - | |
508 | 506 | | |
509 | 507 | | |
| 508 | + | |
| 509 | + | |
510 | 510 | | |
511 | 511 | | |
512 | 512 | | |
| |||
0 commit comments