ExtraVariablesSystemException when using structural_simplify in Modelingtoolkit

Hi there, I’m new to julia (and Modelingtoolkit), and am trying to replicate a simple 2 element Windkessel model (capacitor and resistor in parallel). my code is as follows:

using ModelingToolkit
using Plots
using DifferentialEquations

@variables t
D = Differential(t)

# DEFINING COMPONENTS AND SYSTEMS
@connector function Pin(;name)
    sts = @variables v(t)=1.0 i(t)=1.0 [connect = Flow]
    ODESystem(Equation[], t, sts, []; name=name)
end

function Ground(;name)
    @named g = Pin()
    eqs = [g.v ~ 0]
    compose(ODESystem(eqs, t, [], []; name=name), g)
end

function OnePort(;name)
    @named p = Pin()
    @named n = Pin()
    sts = @variables v(t)=1.0 i(t)=1.0
    eqs = [
           v ~ p.v - n.v
           0 ~ p.i + n.i
           i ~ p.i  ]
    compose(ODESystem(eqs, t, sts, []; name=name), p, n)
end

function Resistor(;name, R = 1.0)
    @named oneport = OnePort()
    @unpack v, i = oneport
    ps = @parameters R=R
    eqs = [  v ~ i * R  ]
    extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end

function Capacitor(;name, C = 1.0)
    @named oneport = OnePort()
    @unpack v, i = oneport
    ps = @parameters C=C
    eqs = [   D(v) ~ i / C  ]
    extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end

@component function DrivenCurrent(; name, I=1.0, fun)
    @named oneport = OnePort()
    @unpack i = oneport
    ps = @parameters I = I
    eqs = [
            i ~ I * fun(t)
    ]
    extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end

@component function WK2(; name, Rp=1.0, C=1.0)
    @named in = Pin()
    @named out = Pin()

    sts = @variables Δv(t) = 0.0 i(t) = 0.0
    # Parameters are inherited from subcomponents
    ps = []

    # These are the components the subsystem is made of:
    @named Rp = Resistor(R=Rp)
    @named C = Capacitor(C=C)
    @named ground = Ground()

    eqs = [
            Δv ~ out.v - in.v
            0 ~ in.i + out.i
            i ~ in.i
            connect(in, Rp.p, C.p)
            connect(Rp.n, C.n, out)
    ]

    # and finaly compose the system
    compose(ODESystem(eqs, t, sts, ps; name=name), in, out, Rp, C)
end

# PROBLEM STARTS HERE (I THINK)
@named wk2 = WK2(Rp=1, C=1)
@named source = DrivenCurrent(I = 1.0,fun=sin)
eqs = [
    connect(source.n, wk2.in)
    connect(source.p, wk2.out)
]

@named _wk2model2 = ODESystem(eqs, t)
@named wk2model2 = compose(_wk2model2,[wk2,source])
wk2_sys = structural_simplify(wk2model2)

I am getting the following error (incl stacktrace):

ExtraVariablesSystemException: The system is unbalanced. There are 24 highest order derivative variables and 23 equations.
More variables than equations, here are the potential extra variable(s):
 wk2₊C₊v(t)
 source₊v(t)

Stacktrace:
  [1] error_reporting(state::TearingState{ODESystem}, bad_idxs::Vector{Int64}, n_highest_vars::Int64, iseqs::Bool, orig_inputs::Set{Any})
    @ ModelingToolkit.StructuralTransformations C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\structural_transformation\utils.jl:50
  [2] check_consistency(state::TearingState{ODESystem}, orig_inputs::Set{Any})
    @ ModelingToolkit.StructuralTransformations C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\structural_transformation\utils.jl:85
  [3] _structural_simplify!(state::TearingState{ODESystem}, io::Nothing; simplify::Bool, check_consistency::Bool, fully_determined::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ ModelingToolkit C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systemstructure.jl:609
  [4] _structural_simplify!
    @ C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systemstructure.jl:597 [inlined]
  [5] structural_simplify!(state::TearingState{ODESystem}, io::Nothing; simplify::Bool, check_consistency::Bool, fully_determined::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ ModelingToolkit C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systemstructure.jl:563
  [6] __structural_simplify(sys::ODESystem, io::Nothing; simplify::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ ModelingToolkit C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systems.jl:56
  [7] __structural_simplify
    @ C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systems.jl:36 [inlined]
  [8] structural_simplify(sys::ODESystem, io::Nothing; simplify::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ ModelingToolkit C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systems.jl:21
  [9] structural_simplify
    @ C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systems.jl:19 [inlined]
 [10] structural_simplify(sys::ODESystem)
    @ ModelingToolkit C:\Users\aoife\.julia\packages\ModelingToolkit\oIgbi\src\systems\systems.jl:19
 [11] top-level scope
    @ c:\Users\aoife\Desktop\School\5 yr\Thesis\Julia\electric_circuit.ipynb:3

Any guidance as to why this is not working would be appreciated! Thank you!!

I usually debug this by calling

wk2_sys = structural_simplify(wk2model2; check_consistency=false)

This returns the unbalanced system in a simplified sate, and you can do

julia> states(wk2_sys)
3-element Vector{Any}:
 wk2₊C₊v(t)
 wk2₊C₊n₊v(t)
 source₊v(t)

julia> equations(wk2_sys)
2-element Vector{Equation}:
 Differential(t)(wk2₊C₊v(t)) ~ wk2₊C₊i(t) / wk2₊C₊C
 0 ~ -wk2₊C₊p₊v(t) + wk2₊C₊n₊v(t) - source₊v(t)

3 unknowns and 2 equations. It would be nice if there were one more voltage equation, and looking through your system ground is defined, but never connected or composed.

Adding ground to a connect statement in WK2

connect(Rp.n, C.n, out, ground.g)

and to the compose at the end

compose(ODESystem(eqs, t, sts, ps; name = name), in, out, Rp, C, ground)

results in

julia> wk2_sys = structural_simplify(wk2model2)
Model wk2model2 with 1 equations
States (1):
  wk2₊C₊v(t) [defaults to 1.0]
Parameters (3):
  wk2₊Rp₊R [defaults to 1]
  wk2₊C₊C [defaults to 1]
  source₊I [defaults to 1.0]
Incidence matrix:1×2 SparseArrays.SparseMatrixCSC{Num, Int64} with 2 stored entries:
 ×  ×

That worked thank you!!