# ModelingToolkit: (Transport) delay? Example: Inflow to one water reservoir is a delayed outflow from another

**URL:** <https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654>\
**Category:** Modelling & Simulations\
**Tags:** delay\
**Created:** [November 14, 2024, 9:56pm UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654 "2024-11-14T21:56:56Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)\
**Post date:** [November 14, 2024, 9:56pm UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654/1 "2024-11-14T21:56:56Z")

</div>

Referring to @baggepinnen 's past [response](https://discourse.julialang.org/t/model-a-first-order-plus-delay-system-in-modelingtoolkit/109695/2) to the question about the possibility to model a delay using ModelingToolkit, I was just wondering if there has been any progress in this direction. Something along the line of [delay(…)](https://specification.modelica.org/master/operators-and-expressions.html#modelica:delay) operator in Modelica.

Or what is the recommendation in the meantime? I am considering a cascade of water dams, wherein each dam is modelled (more or less as a plain hydraulic tank) using ModelingToolkit, but then a simple one-directional interaction between two neighbour dams is that the outflow from one constitutes an inflow to the other, surely with some (transport) delay.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [November 17, 2024, 1:19pm UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654/2 "2024-11-17T13:19:53Z")

</div>

DDEs are done via using the call at a different time:

```julia
using ModelingToolkit, DelayDiffEq
using ModelingToolkit: t_nounits as t, D_nounits as D

tau = 1;
@parameters p0=0.2 p1=0.2 q0=0.3 q1=0.3 v0=1 v1=1 d0=5 d1=1 d2=1 beta0=1 beta1=1
@variables x₀(t) x₁(t) x₂(..)
eqs = [D(x₀) ~ (v0 / (1 + beta0 * (x₂(t - tau)^2))) * (p0 - q0) * x₀ - d0 * x₀
       D(x₁) ~ (v0 / (1 + beta0 * (x₂(t - tau)^2))) * (1 - p0 + q0) * x₀ +
               (v1 / (1 + beta1 * (x₂(t - tau)^2))) * (p1 - q1) * x₁ - d1 * x₁
       D(x₂(t)) ~ (v1 / (1 + beta1 * (x₂(t - tau)^2))) * (1 - p1 + q1) * x₁ - d2 * x₂(t)]
@mtkbuild sys = System(eqs, t)

prob = DDEProblem(sys,
    [x₀ => 1.0, x₁ => 1.0, x₂(t) => 1.0],
    tspan,
    constant_lags = [tau])

```

---

<div class="post-metadata">

**Author:** ![filip.cerny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filip.cerny/32/213932_2.png) [@filip.cerny](https://discourse.julialang.org/u/filip.cerny)\
**Post date:** [December 12, 2024, 2:40pm UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654/3 "2024-12-12T14:40:29Z")

</div>

I was wondering if it was somehow possible to use transport delay inside of a ModelingToolkit component. I tried modifing the example from @ChrisRackauckas to

```julia
using ModelingToolkit, DelayDiffEq
using ModelingToolkit: t_nounits as t, D_nounits as D

using Plots

# this does not work
tau = 1 
@mtkmodel FOL begin
    @parameters begin
        p0=0.2 
        p1=0.2 
        q0=0.3 
        q1=0.3 
        v0=1 
        v1=1 
        d0=5 
        d1=1 
        d2=1 
        beta0=1 
        beta1=1
    end
    @variables begin
        x₀(t) 
        x₁(t) 
        x₂(..)
    end
    @equations begin
        D(x₀) ~ (v0 / (1 + beta0 * (x₂(t - tau)^2))) * (p0 - q0) * x₀ - d0 * x₀
        D(x₁) ~ (v0 / (1 + beta0 * (x₂(t - tau)^2))) * (1 - p0 + q0) * x₀ +
               (v1 / (1 + beta1 * (x₂(t - tau)^2))) * (p1 - q1) * x₁ - d1 * x₁
        D(x₂(t)) ~ (v1 / (1 + beta1 * (x₂(t - tau)^2))) * (1 - p1 + q1) * x₁ - d2 * x₂(t)
    end
end

tspan = (0.0, 10.0)
@mtkbuild sys = FOL()

prob = DDEProblem(sys,
    [x₀ => 1.0, x₁ => 1.0, x₂(t) => 1.0],
    tspan,
    constant_lags = [tau])

alg = MethodOfSteps(Tsit5())
sol = solve(prob, alg)

plot(sol)

```

, but unfortunately, I had no luck running it. This is the error stacktrace:

```julia
ERROR: LoadError: AssertionError: Multiple independent variables are used in the model Symbol Symbol
Stacktrace:
  [1] assert_unique_independent_var(dict::Dict{Symbol, Any}, iv::Symbol)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:485
  [2] assert_unique_independent_var(dict::Dict{Symbol, Any}, iv::Num)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:478
  [3] generate_var!(dict::Dict{…}, a::Symbol, b::Symbol, varclass::Symbol, mod::Module; indices::Nothing, type::Type)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:492
  [4] parse_variable_def!(dict::Dict{…}, mod::Module, arg::Expr, varclass::Symbol, kwargs::OrderedCollections.OrderedSet{…}, where_types::Vector{…}; def::Nothing, type::Type, meta::Dict{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:279
  [5] parse_variable_def!
    @ ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:247 [inlined]
  [6] parse_variable_arg(dict::Dict{…}, mod::Module, arg::Expr, varclass::Symbol, kwargs::OrderedCollections.OrderedSet{…}, where_types::Vector{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:878
  [7] parse_variable_arg!(exprs::Vector{…}, vs::Vector{…}, dict::Dict{…}, mod::Module, arg::Expr, varclass::Symbol, kwargs::OrderedCollections.OrderedSet{…}, where_types::Vector{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:845
  [8] parse_variables!(exprs::Vector{…}, vs::Vector{…}, dict::Dict{…}, mod::Module, body::Expr, varclass::Symbol, kwargs::OrderedCollections.OrderedSet{…}, where_types::Vector{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:1029
  [9] parse_model!(exprs::Vector{…}, comps::Vector{…}, ext::Base.RefValue{…}, eqs::Vector{…}, icon::Base.RefValue{…}, vs::Vector{…}, ps::Vector{…}, sps::Vector{…}, c_evts::Vector{…}, d_evts::Vector{…}, dict::Dict{…}, mod::Module, arg::Expr, kwargs::OrderedCollections.OrderedSet{…}, where_types::Vector{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:606
 [10] _model_macro(mod::Module, name::Symbol, expr::Expr, isconnector::Bool)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:71
 [11] var"@mtkmodel"( __source__ ::LineNumberNode, __module__ ::Module, name::Symbol, body::Any)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/zfOUk/src/systems/model_parsing.jl:33
 [12] eval
    @ ./boot.jl:385 [inlined]
 [13] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:2076

```

Am I making any obvious mistake? Do you have any recommendation?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 12, 2024, 2:47pm UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654/4 "2024-12-12T14:47:38Z")

</div>

The change is just to the macro?

---

<div class="post-metadata">

**Author:** ![filip.cerny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filip.cerny/32/213932_2.png) [@filip.cerny](https://discourse.julialang.org/u/filip.cerny)\
**Post date:** [December 16, 2024, 12:04am UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654/5 "2024-12-16T00:04:32Z")

</div>

Yes, the only change is the macro. Sorry for the late response, I did not get notified.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 16, 2024, 12:34am UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654/6 "2024-12-16T00:34:38Z")

</div>

I think we just don’t support it in the macro right now, but we should if we just lower to System instead of ODESystem. Can you open an issue?

---

<div class="post-metadata">

**Author:** ![filip.cerny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filip.cerny/32/213932_2.png) [@filip.cerny](https://discourse.julialang.org/u/filip.cerny)\
**Post date:** [December 16, 2024, 9:33am UTC](https://discourse.julialang.org/t/modelingtoolkit-transport-delay-example-inflow-to-one-water-reservoir-is-a-delayed-outflow-from-another/122654/7 "2024-12-16T09:33:32Z")

</div>

Yes, I will open an issue later today. Thank you.
