What's wrong with this system/circuit?

I’ve defined a system as follows:

using ModelingToolkit, ModelingToolkitStandardLibrary
using DifferentialEquations
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Blocks

function Component(; name, R)
    @named n = Pin()
    @named p1 = Pin()
    @named p2 = Pin()
    @named R = Resistor(R=R)
    @named C = Capacitor(C=R)
    eqs = [
        connect(p1, R.p)
        connect(p2, C.p)
        connect(n, R.n, C.n)
        ]
    return ODESystem(eqs, t, [], [] ; name, 
                systems=[p1, p2, n, R, C])
end

function S(;name, num)
    # construct the layers from the center out
    comps = Vector{Any}(undef, num)
    Ra_l = Vector{Any}(undef, num)
    Ra_r = Vector{Any}(undef, num)
    Rc_l = Vector{Any}(undef, num)
    Rc_r = Vector{Any}(undef, num)
    for i in 1:num
        comps[i] = Component(; name=Symbol(:L_, i),  R=1)
        Ra_l[i] = Resistor(name=Symbol(:Ra_, i, :l), R=2)
        Ra_r[i] = Resistor(name=Symbol(:Ra_, i, :r), R=3)
        Rc_l[i] = Resistor(name=Symbol(:Rc_, i, :l), R=4)
        Rc_r[i] = Resistor(name=Symbol(:Rc_, i, :r), R=5)
    end
    
    @named n = Pin()
    @named p = Pin()
    # connect everything
    eqs = [
        connect(Ra_l[1].p, Ra_r[1].p, p)
        connect(Rc_l[1].n, Rc_r[1].n, n)
        [connect(Ra_l[i].n, Ra_l[i+1].p) for i in 1:num-1]...
        [connect(Ra_r[i].n, Ra_r[i+1].p) for i in 1:num-1]...
        [connect(Rc_l[i].n, Rc_l[i+1].p) for i in 1:num-1]...
        [connect(Rc_r[i].n, Rc_r[i+1].p) for i in 1:num-1]...
        
        [connect(Ra_l[i].n, comps[i].p1) for i in 1:num]...
        [connect(Ra_r[i].n, comps[i].p2) for i in 1:num]...
        [connect(Rc_l[i].n, Rc_r[i].n, comps[i].n) for i in 1:num]...
        ]

    return ODESystem(eqs, t, [], [] ; name, 
                systems=[p, n, comps..., Ra_l..., Ra_r..., Rc_l..., Rc_r...])
end

@variables t
@named source = Voltage()
@named c = Constant(k=0.01)
@named ground = Ground()
@named s = S(num=2)

rc_eqs = [
        connect(c.output, source.V)
        connect(source.p, s.p)
        connect(s.n, source.n, ground.g)
        ]

@named rc_model = ODESystem(rc_eqs, t, systems=[s, c, source, ground])
sys = structural_simplify(rc_model)

No issues so far.

However, once I increase num to 3:

@named s = S(num=3)

I’m told the system is unbalanced:

ExtraEquationsSystemException: The system is unbalanced. There are 41 highest order derivative variables and 42 equations.
More equations than variables, here are the potential extra equation(s):
 0 ~ -s₊L_3₊n₊i(t) - s₊Ra_3l₊i(t) - s₊Ra_3r₊i(t)

I can’t really see what’s wrong here.
ModelingToolkit is v8.36.0 and ModelingToolkitStandardLibrary is v1.10.0

Thanks

Print out the list of equations, that would be an easier way to look at this. There’s likely just one redundancy in there.

Here are the equations:

julia> equations(rc_model)
connect(c.output, source.V)
connect(source.p, s.p)
connect(s.n, source.n, ground.g)
connect(Ra_1l.p, Ra_1r.p, p)
connect(Rc_1l.n, Rc_1r.n, n)
connect(Ra_1l.n, Ra_2l.p)
connect(Ra_2l.n, Ra_3l.p)
connect(Ra_1r.n, Ra_2r.p)
connect(Ra_2r.n, Ra_3r.p)
connect(Rc_1l.n, Rc_2l.p)
connect(Rc_2l.n, Rc_3l.p)
connect(Rc_1r.n, Rc_2r.p)
connect(Rc_2r.n, Rc_3r.p)
connect(Ra_1l.n, L_1.p1)
connect(Ra_2l.n, L_2.p1)
connect(Ra_3l.n, L_3.p1)
connect(Ra_1r.n, L_1.p2)
connect(Ra_2r.n, L_2.p2)
connect(Ra_3r.n, L_3.p2)
connect(Rc_1l.n, Rc_1r.n, L_1.n)
connect(Rc_2l.n, Rc_2r.n, L_2.n)
connect(Rc_3l.n, Rc_3r.n, L_3.n)
connect(p1, R.p)
connect(p2, C.p)
connect(n, R.n, C.n)
s₊L_1₊R₊v(t) ~ s₊L_1₊R₊p₊v(t) - s₊L_1₊R₊n₊v(t)
0 ~ s₊L_1₊R₊n₊i(t) + s₊L_1₊R₊p₊i(t)
s₊L_1₊R₊i(t) ~ s₊L_1₊R₊p₊i(t)
s₊L_1₊R₊v(t) ~ s₊L_1₊R₊R*s₊L_1₊R₊i(t)
s₊L_1₊C₊v(t) ~ s₊L_1₊C₊p₊v(t) - s₊L_1₊C₊n₊v(t)
0 ~ s₊L_1₊C₊n₊i(t) + s₊L_1₊C₊p₊i(t)
s₊L_1₊C₊i(t) ~ s₊L_1₊C₊p₊i(t)
Differential(t)(s₊L_1₊C₊v(t)) ~ s₊L_1₊C₊i(t) / s₊L_1₊C₊C
connect(p1, R.p)
connect(p2, C.p)
connect(n, R.n, C.n)
s₊L_2₊R₊v(t) ~ s₊L_2₊R₊p₊v(t) - s₊L_2₊R₊n₊v(t)
0 ~ s₊L_2₊R₊n₊i(t) + s₊L_2₊R₊p₊i(t)
s₊L_2₊R₊i(t) ~ s₊L_2₊R₊p₊i(t)
s₊L_2₊R₊v(t) ~ s₊L_2₊R₊R*s₊L_2₊R₊i(t)
s₊L_2₊C₊v(t) ~ s₊L_2₊C₊p₊v(t) - s₊L_2₊C₊n₊v(t)
0 ~ s₊L_2₊C₊n₊i(t) + s₊L_2₊C₊p₊i(t)
s₊L_2₊C₊i(t) ~ s₊L_2₊C₊p₊i(t)
Differential(t)(s₊L_2₊C₊v(t)) ~ s₊L_2₊C₊i(t) / s₊L_2₊C₊C
connect(p1, R.p)
connect(p2, C.p)
connect(n, R.n, C.n)
s₊L_3₊R₊v(t) ~ s₊L_3₊R₊p₊v(t) - s₊L_3₊R₊n₊v(t)
0 ~ s₊L_3₊R₊n₊i(t) + s₊L_3₊R₊p₊i(t)
s₊L_3₊R₊i(t) ~ s₊L_3₊R₊p₊i(t)
s₊L_3₊R₊v(t) ~ s₊L_3₊R₊R*s₊L_3₊R₊i(t)
s₊L_3₊C₊v(t) ~ s₊L_3₊C₊p₊v(t) - s₊L_3₊C₊n₊v(t)
0 ~ s₊L_3₊C₊n₊i(t) + s₊L_3₊C₊p₊i(t)
s₊L_3₊C₊i(t) ~ s₊L_3₊C₊p₊i(t)
Differential(t)(s₊L_3₊C₊v(t)) ~ s₊L_3₊C₊i(t) / s₊L_3₊C₊C
s₊Ra_1l₊v(t) ~ s₊Ra_1l₊p₊v(t) - s₊Ra_1l₊n₊v(t)
0 ~ s₊Ra_1l₊n₊i(t) + s₊Ra_1l₊p₊i(t)
s₊Ra_1l₊i(t) ~ s₊Ra_1l₊p₊i(t)
s₊Ra_1l₊v(t) ~ s₊Ra_1l₊R*s₊Ra_1l₊i(t)
s₊Ra_2l₊v(t) ~ s₊Ra_2l₊p₊v(t) - s₊Ra_2l₊n₊v(t)
0 ~ s₊Ra_2l₊n₊i(t) + s₊Ra_2l₊p₊i(t)
s₊Ra_2l₊i(t) ~ s₊Ra_2l₊p₊i(t)
s₊Ra_2l₊v(t) ~ s₊Ra_2l₊R*s₊Ra_2l₊i(t)
s₊Ra_3l₊v(t) ~ s₊Ra_3l₊p₊v(t) - s₊Ra_3l₊n₊v(t)
0 ~ s₊Ra_3l₊n₊i(t) + s₊Ra_3l₊p₊i(t)
s₊Ra_3l₊i(t) ~ s₊Ra_3l₊p₊i(t)
s₊Ra_3l₊v(t) ~ s₊Ra_3l₊R*s₊Ra_3l₊i(t)
s₊Ra_1r₊v(t) ~ s₊Ra_1r₊p₊v(t) - s₊Ra_1r₊n₊v(t)
0 ~ s₊Ra_1r₊n₊i(t) + s₊Ra_1r₊p₊i(t)
s₊Ra_1r₊i(t) ~ s₊Ra_1r₊p₊i(t)
s₊Ra_1r₊v(t) ~ s₊Ra_1r₊R*s₊Ra_1r₊i(t)
s₊Ra_2r₊v(t) ~ s₊Ra_2r₊p₊v(t) - s₊Ra_2r₊n₊v(t)
0 ~ s₊Ra_2r₊n₊i(t) + s₊Ra_2r₊p₊i(t)
s₊Ra_2r₊i(t) ~ s₊Ra_2r₊p₊i(t)
s₊Ra_2r₊v(t) ~ s₊Ra_2r₊R*s₊Ra_2r₊i(t)
s₊Ra_3r₊v(t) ~ s₊Ra_3r₊p₊v(t) - s₊Ra_3r₊n₊v(t)
0 ~ s₊Ra_3r₊n₊i(t) + s₊Ra_3r₊p₊i(t)
s₊Ra_3r₊i(t) ~ s₊Ra_3r₊p₊i(t)
s₊Ra_3r₊v(t) ~ s₊Ra_3r₊R*s₊Ra_3r₊i(t)
s₊Rc_1l₊v(t) ~ s₊Rc_1l₊p₊v(t) - s₊Rc_1l₊n₊v(t)
0 ~ s₊Rc_1l₊n₊i(t) + s₊Rc_1l₊p₊i(t)
s₊Rc_1l₊i(t) ~ s₊Rc_1l₊p₊i(t)
s₊Rc_1l₊v(t) ~ s₊Rc_1l₊R*s₊Rc_1l₊i(t)
s₊Rc_2l₊v(t) ~ s₊Rc_2l₊p₊v(t) - s₊Rc_2l₊n₊v(t)
0 ~ s₊Rc_2l₊n₊i(t) + s₊Rc_2l₊p₊i(t)
s₊Rc_2l₊i(t) ~ s₊Rc_2l₊p₊i(t)
s₊Rc_2l₊v(t) ~ s₊Rc_2l₊R*s₊Rc_2l₊i(t)
s₊Rc_3l₊v(t) ~ s₊Rc_3l₊p₊v(t) - s₊Rc_3l₊n₊v(t)
0 ~ s₊Rc_3l₊n₊i(t) + s₊Rc_3l₊p₊i(t)
s₊Rc_3l₊i(t) ~ s₊Rc_3l₊p₊i(t)
s₊Rc_3l₊v(t) ~ s₊Rc_3l₊R*s₊Rc_3l₊i(t)
s₊Rc_1r₊v(t) ~ s₊Rc_1r₊p₊v(t) - s₊Rc_1r₊n₊v(t)
0 ~ s₊Rc_1r₊n₊i(t) + s₊Rc_1r₊p₊i(t)
s₊Rc_1r₊i(t) ~ s₊Rc_1r₊p₊i(t)
s₊Rc_1r₊v(t) ~ s₊Rc_1r₊R*s₊Rc_1r₊i(t)
s₊Rc_2r₊v(t) ~ s₊Rc_2r₊p₊v(t) - s₊Rc_2r₊n₊v(t)
0 ~ s₊Rc_2r₊n₊i(t) + s₊Rc_2r₊p₊i(t)
s₊Rc_2r₊i(t) ~ s₊Rc_2r₊p₊i(t)
s₊Rc_2r₊v(t) ~ s₊Rc_2r₊R*s₊Rc_2r₊i(t)
s₊Rc_3r₊v(t) ~ s₊Rc_3r₊p₊v(t) - s₊Rc_3r₊n₊v(t)
0 ~ s₊Rc_3r₊n₊i(t) + s₊Rc_3r₊p₊i(t)
s₊Rc_3r₊i(t) ~ s₊Rc_3r₊p₊i(t)
s₊Rc_3r₊v(t) ~ s₊Rc_3r₊R*s₊Rc_3r₊i(t)
c₊output₊u(t) ~ c₊k
source₊v(t) ~ source₊p₊v(t) - source₊n₊v(t)
0 ~ source₊n₊i(t) + source₊p₊i(t)
source₊i(t) ~ source₊p₊i(t)
source₊v(t) ~ source₊V₊u(t)
ground₊g₊v(t) ~ 0

PNG of the Latex

states:

s₊p₊v(t)
s₊p₊i(t)
s₊n₊v(t)
s₊n₊i(t)
s₊L_1₊p1₊v(t)
s₊L_1₊p1₊i(t)
s₊L_1₊p2₊v(t)
s₊L_1₊p2₊i(t)
s₊L_1₊n₊v(t)
s₊L_1₊n₊i(t)
s₊L_1₊R₊v(t)
s₊L_1₊R₊i(t)
s₊L_1₊R₊p₊v(t)
s₊L_1₊R₊p₊i(t)
s₊L_1₊R₊n₊v(t)
s₊L_1₊R₊n₊i(t)
s₊L_1₊C₊v(t)
s₊L_1₊C₊i(t)
s₊L_1₊C₊p₊v(t)
s₊L_1₊C₊p₊i(t)
s₊L_1₊C₊n₊v(t)
s₊L_1₊C₊n₊i(t)
s₊L_2₊p1₊v(t)
s₊L_2₊p1₊i(t)
s₊L_2₊p2₊v(t)
s₊L_2₊p2₊i(t)
s₊L_2₊n₊v(t)
s₊L_2₊n₊i(t)
s₊L_2₊R₊v(t)
s₊L_2₊R₊i(t)
s₊L_2₊R₊p₊v(t)
s₊L_2₊R₊p₊i(t)
s₊L_2₊R₊n₊v(t)
s₊L_2₊R₊n₊i(t)
s₊L_2₊C₊v(t)
s₊L_2₊C₊i(t)
s₊L_2₊C₊p₊v(t)
s₊L_2₊C₊p₊i(t)
s₊L_2₊C₊n₊v(t)
s₊L_2₊C₊n₊i(t)
s₊L_3₊p1₊v(t)
s₊L_3₊p1₊i(t)
s₊L_3₊p2₊v(t)
s₊L_3₊p2₊i(t)
s₊L_3₊n₊v(t)
s₊L_3₊n₊i(t)
s₊L_3₊R₊v(t)
s₊L_3₊R₊i(t)
s₊L_3₊R₊p₊v(t)
s₊L_3₊R₊p₊i(t)
s₊L_3₊R₊n₊v(t)
s₊L_3₊R₊n₊i(t)
s₊L_3₊C₊v(t)
s₊L_3₊C₊i(t)
s₊L_3₊C₊p₊v(t)
s₊L_3₊C₊p₊i(t)
s₊L_3₊C₊n₊v(t)
s₊L_3₊C₊n₊i(t)
s₊Ra_1l₊v(t)
s₊Ra_1l₊i(t)
s₊Ra_1l₊p₊v(t)
s₊Ra_1l₊p₊i(t)
s₊Ra_1l₊n₊v(t)
s₊Ra_1l₊n₊i(t)
s₊Ra_2l₊v(t)
s₊Ra_2l₊i(t)
s₊Ra_2l₊p₊v(t)
s₊Ra_2l₊p₊i(t)
s₊Ra_2l₊n₊v(t)
s₊Ra_2l₊n₊i(t)
s₊Ra_3l₊v(t)
s₊Ra_3l₊i(t)
s₊Ra_3l₊p₊v(t)
s₊Ra_3l₊p₊i(t)
s₊Ra_3l₊n₊v(t)
s₊Ra_3l₊n₊i(t)
s₊Ra_1r₊v(t)
s₊Ra_1r₊i(t)
s₊Ra_1r₊p₊v(t)
s₊Ra_1r₊p₊i(t)
s₊Ra_1r₊n₊v(t)
s₊Ra_1r₊n₊i(t)
s₊Ra_2r₊v(t)
s₊Ra_2r₊i(t)
s₊Ra_2r₊p₊v(t)
s₊Ra_2r₊p₊i(t)
s₊Ra_2r₊n₊v(t)
s₊Ra_2r₊n₊i(t)
s₊Ra_3r₊v(t)
s₊Ra_3r₊i(t)
s₊Ra_3r₊p₊v(t)
s₊Ra_3r₊p₊i(t)
s₊Ra_3r₊n₊v(t)
s₊Ra_3r₊n₊i(t)
s₊Rc_1l₊v(t)
s₊Rc_1l₊i(t)
s₊Rc_1l₊p₊v(t)
s₊Rc_1l₊p₊i(t)
s₊Rc_1l₊n₊v(t)
s₊Rc_1l₊n₊i(t)
s₊Rc_2l₊v(t)
s₊Rc_2l₊i(t)
s₊Rc_2l₊p₊v(t)
s₊Rc_2l₊p₊i(t)
s₊Rc_2l₊n₊v(t)
s₊Rc_2l₊n₊i(t)
s₊Rc_3l₊v(t)
s₊Rc_3l₊i(t)
s₊Rc_3l₊p₊v(t)
s₊Rc_3l₊p₊i(t)
s₊Rc_3l₊n₊v(t)
s₊Rc_3l₊n₊i(t)
s₊Rc_1r₊v(t)
s₊Rc_1r₊i(t)
s₊Rc_1r₊p₊v(t)
s₊Rc_1r₊p₊i(t)
s₊Rc_1r₊n₊v(t)
s₊Rc_1r₊n₊i(t)
s₊Rc_2r₊v(t)
s₊Rc_2r₊i(t)
s₊Rc_2r₊p₊v(t)
s₊Rc_2r₊p₊i(t)
s₊Rc_2r₊n₊v(t)
s₊Rc_2r₊n₊i(t)
s₊Rc_3r₊v(t)
s₊Rc_3r₊i(t)
s₊Rc_3r₊p₊v(t)
s₊Rc_3r₊p₊i(t)
s₊Rc_3r₊n₊v(t)
s₊Rc_3r₊n₊i(t)
c₊output₊u(t)
source₊v(t)
source₊i(t)
source₊p₊v(t)
source₊p₊i(t)
source₊n₊v(t)
source₊n₊i(t)
source₊V₊u(t)
ground₊g₊v(t)
ground₊g₊i(t)

It hard for me to see what’s wrong without a diagram. But removing

makes the system balanced. Also, you are accidentally overwriting R. It should be

function Component(; name, R)
    @named n = Pin()
    @named p1 = Pin()
    @named p2 = Pin()
    vR = R
    @named R = Resistor(R=vR)
    @named C = Capacitor(C=vR)
    eqs = [
        connect(p1, R.p)
        connect(p2, C.p)
        connect(n, R.n, C.n)
        ]
    return ODESystem(eqs, t, [], [] ; name, 
                systems=[p1, p2, n, R, C])
end

Thanks!
Rc_l[1].n and Rc_r[1].n do appear both in

connect(Rc_l[1].n, Rc_r[1].n, n)

and in

[connect(Rc_l[i].n, Rc_r[i].n, comps[i].n) for i in 1:num]...

Replacing the first with:

connect(Rc_l[1].n, n)

seems to fix this issue.

This removes:

connect(Rc_l[1].n, Rc_r[1].n) 

which already appears in the 2nd line.

So, yes, there’s an extra equation. However, there isn’t any actual inconsistency here: the same equation appears twice. This seems like something ModelingToolkit can detect and ignore.

PS:
the line

prob = ODAEProblem(sys, Pair[], (0, 10))

fails

Open an issue. I do think a good default behavior would be to detect and warn, with options to detect and error or ignore, but of course that would need to be added.