I tested a simple component-based electrical example with a resistor, capacitor and an inductor. An additional resistor is connected in parallel with the inductor.
using ModelingToolkit
using LinearAlgebra
@variables t
D = Differential(t)
@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
function ConstantVoltage(;name, V = 1.0)
@named oneport = OnePort()
@unpack v = oneport
ps = @parameters V=V
eqs = [ V ~ v ]
extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end
function Inductor(; name, L=1.0)
@named oneport = OnePort()
@unpack v, i = oneport
pars = @parameters L = L
eqs = [ v ~ L * D(i) ]
extend(ODESystem(eqs, t, [], pars; name = name), oneport)
end
R = 0.5; C = 0.2; L= 0.6; V = 1.0
@named resistor = Resistor(R=R)
@named resistor2 = Resistor(R=5.0)
@named capacitor = Capacitor(C=C)
@named inductor = Inductor(L=L)
@named source = ConstantVoltage(V=V)
@named ground = Ground()
connections2 = [
connect(source.p, resistor.p)
connect(resistor.n, inductor.p)
connect(inductor.n, capacitor.p)
connect(capacitor.n, source.n)
connect(capacitor.n, ground.g)
connect(inductor.p, resistor2.p) # resistor2 // inductor
connect(inductor.n, resistor2.n) # resistor2 // inductor
]
@named rlc_model2 = ODESystem(connections2, t, systems=[resistor, capacitor, source, ground, inductor, resistor2])
sys2 = structural_simplify(rlc_model2)
printstyled("\n********************\nR - C - L//R2\n********************\n", color=:red, bold=true)
@show states(sys2)
lsys2, ssys = linearize(rlc_model2, [], [])
printstyled("Linearization\n", underline=true)
show(IOContext(stdout, :compact => false), "text/plain", lsys2.A)
println()
printstyled("Eigenvalues\n", underline=true)
eigvals(lsys2.A)
I expected 2 states, but the result was different.
********************
R - C - L//R2
********************
states(sys2) = Any[capacitorâ‚Šv(t), inductorâ‚Ši(t), resistor2â‚Ši(t)]
Linearization
3Ă—3 Array{Float64, 2}:
0.0 5.0 5.0
-1.6666666666666667 -0.8333333333333334 -0.8333333333333334
0.15151515151515152 -0.8333333333333334 -0.8333333333333334
Eigenvalues
3-element Vector{ComplexF64}:
-0.8333333333333337 - 2.623225711087996im
-0.8333333333333337 + 2.623225711087996im
2.2624174687408427e-16 + 0.0im
remark: Test with MODIA
gave the correct result.
Thanks / Johann