Issues using a vector connector in ModelingToolkit for acausal modeling

Hi, I’m modeling a three-reactor system with two chemical species. I’d like to define the concentration of species as a vector so that I can add more species later. Here is the code:

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

@connector Port begin
    c(t)[1:2] 
    v(t), [connect = Flow]  # volumetric flow rate 
end

@mtkmodel Feed begin
    @parameters begin 
        c0[1:2] = [2,2]
        v      # dm³/min
    end
    @components begin
        s = Port()
    end
    @equations begin
        s.c ~ c0
        s.v ~ -v # flow is leaving
    end
end

@mtkmodel CSTR1 begin
    @parameters begin 
        V  # volume, dm³
        v1 # outlet flow rate, dm³/min
        k  # reaction constant
    end
    @variables begin 
        c(t)[1:2] 
        v(t)
    end
    @components begin 
        in₁ = Port()
        in₂ = Port()
        out = Port()
    end
    @equations begin
        V*D(c)[1] ~ in₁.v*in₁.c[1] - v*c[1] - k*V*c[1]*c[2]
        V*D(c)[2] ~ in₂.v*in₂.c[2] - v*c[2] - k*V*c[1]*c[2]
        out.c ~ c
        out.v ~ -v
        v ~ v1
    end
end

@mtkmodel CSTR2 begin
    @parameters begin 
        V  # volume, dm³
        v2 # outlet flow rate, dm³/min
        k  # reaction constant
    end
    @variables begin 
        c(t)[1:2] 
        v(t)
    end
    @components begin 
        in  = Port()
        out = Port()
    end
    @equations begin
        V*D(c)[1] ~ in.v*in.c[1] - v*c[1] - k*V*c[1]*c[2]
        V*D(c)[2] ~ in.v*in.c[2] - v*c[2] - k*V*c[1]*c[2]
        out.c ~ c
        out.v ~ -v
        v ~ v2
    end
end

@mtkmodel CSTR3 begin
    @parameters begin 
        V  # volume, dm³
        v3 # outlet flow rate, dm³/min
        k  # reaction constant
    end
    @variables begin 
        c(t)[1:2]
        v(t)
    end
    @components begin 
        in  = Port()
    end
    @equations begin
        V*D(c)[1] ~ in.v*in.c[1] - v*c[1] - k*V*c[1]*c[2]
        V*D(c)[2] ~ in.v*in.c[2] - v*c[2] - k*V*c[1]*c[2]
        v ~ v3
    end
end

@mtkmodel CSTRs begin
    @components begin
        feedA = Feed(c0=[2.0,0.0],v=6.0)
        feedB = Feed(c0=[0.0,2.0],v=6.0)
        cstr1 = CSTR1(V=200,k=0.5,v=12)
        cstr2 = CSTR2(V=200,k=0.5,v=12)
        cstr3 = CSTR3(V=200,k=0.5,v=12)
    end
    @equations begin
        connect(feedA.s,cstr1.in₁)
        connect(feedB.s,cstr1.in₂)
        connect(cstr1.out,cstr2.in)
        connect(cstr2.out,cstr3.in)
    end
end

@mtkbuild cstrs = CSTRs()

u0 = [cstrs.cstr1.c[1] => 2,
      cstrs.cstr1.c[2] => 2,
      cstrs.cstr2.c[1] => 0,
      cstrs.cstr2.c[2] => 0,
      cstrs.cstr3.c[1] => 0,
      cstrs.cstr3.c[2] => 0] 

prob  = ODEProblem(cstrs,u0,(0.0,20.0))

I get a Warning about the connectors and an Error that I have no idea where it comes from:

 Warning: in contains 1 flow variables, yet 2 regular (non-flow, non-stream, non-input, non-output) variables. This could lead to imbalanced model that are difficult to debug. Consider marking some of the regular variables as input/output variables.
└ @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/connectors.jl:54

ERROR: MethodError: no method matching -(::ModelingToolkit.NoValue, ::SymbolicUtils.BasicSymbolic{Real})
The function `-` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  -(::Num, ::SymbolicUtils.BasicSymbolic{<:Number})
   @ Symbolics ~/.julia/packages/SymbolicUtils/jf8aQ/src/methods.jl:65
  -(::MutableArithmetics.Zero, ::Any)
   @ MutableArithmetics ~/.julia/packages/MutableArithmetics/BLlgj/src/rewrite.jl:67
  -(::Any, ::MutableArithmetics.Zero)
   @ MutableArithmetics ~/.julia/packages/MutableArithmetics/BLlgj/src/rewrite.jl:68
  ...

Stacktrace:
  [1] (::ModelingToolkit.var"#713#717")(eq::Equation)
    @ ModelingToolkit ./none:0
  [2] iterate
    @ ./generator.jl:48 [inlined]
  [3] collect_to!(dest::Vector{…}, itr::Base.Generator{…}, offs::Int64, st::Int64)
    @ Base ./array.jl:838
  [4] collect_to_with_first!
    @ ./array.jl:816 [inlined]
  [5] collect(itr::Base.Generator{Vector{Equation}, ModelingToolkit.var"#713#717"})
    @ Base ./array.jl:790
  [6] NonlinearSystem(eqs::Vector{…}, unknowns::Vector{…}, ps::Vector{…}; observed::Vector{…}, name::Symbol, description::String, default_u0::Dict{…}, default_p::Dict{…}, defaults::Dict{…}, systems::Vector{…}, connector_type::Nothing, continuous_events::Nothing, discrete_events::Nothing, checks::Bool, parameter_dependencies::Vector{…}, metadata::ModelingToolkit.InitializationSystemMetadata, gui_metadata::Nothing)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/nonlinear/nonlinearsystem.jl:151
  [7] generate_initializesystem(sys::ODESystem; u0map::Dict{…}, pmap::Dict{…}, initialization_eqs::Vector{…}, guesses::Dict{…}, default_dd_guess::Float64, algebraic_only::Bool, check_units::Bool, check_defguess::Bool, name::Symbol, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/nonlinear/initializesystem.jl:182
  [8] generate_initializesystem
    @ ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/nonlinear/initializesystem.jl:6 [inlined]
  [9] ModelingToolkit.InitializationProblem{…}(sys::ODESystem, t::Float64, u0map::Dict{…}, parammap::Dict{…}; guesses::Dict{…}, check_length::Bool, warn_initialize_determined::Bool, initialization_eqs::Vector{…}, fully_determined::Nothing, check_units::Bool, kwargs::@Kwargs{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:1315
 [10] InitializationProblem
    @ ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:1295 [inlined]
 [11] #_#998
    @ ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:1273 [inlined]
 [12] InitializationProblem
    @ ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:1272 [inlined]
 [13] #InitializationProblem#996
    @ ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:1261 [inlined]
 [14] InitializationProblem
    @ ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:1260 [inlined]
 [15] process_SciMLProblem(constructor::Type, sys::ODESystem, u0map::Vector{…}, pmap::SciMLBase.NullParameters; build_initializeprob::Bool, implicit_dae::Bool, t::Float64, guesses::Dict{…}, warn_initialize_determined::Bool, initialization_eqs::Vector{…}, eval_expression::Bool, eval_module::Module, fully_determined::Nothing, check_initialization_units::Bool, tofloat::Bool, use_union::Bool, u0_constructor::typeof(identity), du0map::Nothing, check_length::Bool, symbolic_u0::Bool, warn_cyclic_dependency::Bool, circular_dependency_max_cycle_length::Int64, circular_dependency_max_cycles::Int64, substitution_limit::Int64, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/problem_utils.jl:554
 [16] (ODEProblem{…})(sys::ODESystem, u0map::Vector{…}, tspan::Tuple{…}, parammap::SciMLBase.NullParameters; callback::Nothing, check_length::Bool, warn_initialize_determined::Bool, eval_expression::Bool, eval_module::Module, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:840
 [17] ODEProblem
    @ ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:828 [inlined]
 [18] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Pair{…}}, tspan::Tuple{Float64, Float64})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:828
 [19] (ODEProblem{true})(::ODESystem, ::Vector{Pair{Num, Int64}}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:821
 [20] (ODEProblem{true})(::ODESystem, ::Vector{Pair{Num, Int64}}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:820
 [21] ODEProblem(::ODESystem, ::Vector{Pair{Num, Int64}}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:810
 [22] ODEProblem(::ODESystem, ::Vector{Pair{Num, Int64}}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/0O7FS/src/systems/diffeqs/abstractodesystem.jl:809
 [23] top-level scope
    @ ~/julia/MTK/mycodes/IsoCSTRb.jl:140
Some type information was truncated. Use `show(err)` to see complete types.

If I define scalars like ca(t) and cb(t) instead of c(t)[1:2] I still get the warning but not the Error, and I’m able to solve the system. Any help would be appreciated.

1 Like

This sounds very similar to the issue I am describing here:

…no solution yet.

1 Like