Skip to content

Commit 33d5b5c

Browse files
committed
Better RC circuit example
1 parent 3bbe102 commit 33d5b5c

File tree

1 file changed

+67
-56
lines changed

1 file changed

+67
-56
lines changed

test/components.jl

Lines changed: 67 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,98 @@
1-
using ModelingToolkit
21
using Test
2+
using ModelingToolkit, StructuralTransformations, OrdinaryDiffEq
33

44
# Basic electric components
5-
@parameters t
5+
const t = Sym{ModelingToolkit.Parameter{Real}}(:t)
66
function Pin(name)
77
@variables v(t) i(t)
88
ODESystem(Equation[], t, [v, i], [], name=name, default_u0=[v=>1.0, i=>1.0])
99
end
1010

1111
function Ground(name)
12-
p = Pin(name)
13-
eqs = [p.v ~ 0]
14-
ODESystem(eqs, t, [], [], systems=[p], name=name)
12+
g = Pin(:g)
13+
eqs = [g.v ~ 0]
14+
ODESystem(eqs, t, [], [], systems=[g], name=name)
1515
end
1616

17-
function OnePort(name)
17+
function ConstantVoltage(name; V = 1.0)
18+
val = V
1819
p = Pin(:p)
1920
n = Pin(:n)
20-
@variables v(t) i(t)
21+
@parameters V
2122
eqs = [
22-
v ~ p.v - n.v
23+
V ~ p.v - n.v
2324
0 ~ p.i + n.i
24-
i ~ p.i
2525
]
26-
v, i, ODESystem(eqs, t, [v, i], [], systems=[p, n], name=name)
27-
end
28-
29-
function ConstantVoltage(name; V = 1.0)
30-
val = V
31-
v, i, op = OnePort(name)
32-
@parameters V
33-
push!(op.eqs, v ~ V)
34-
V = ModelingToolkit.value(V)
35-
push!(op.ps, V)
36-
op.default_p[V] = val
37-
op
26+
ODESystem(eqs, t, [], [V], systems=[p, n], default_p=Dict(V => val), name=name)
3827
end
3928

4029
function Resistor(name; R = 1.0)
4130
val = R
42-
v, i, op = OnePort(name)
31+
p = Pin(:p)
32+
n = Pin(:n)
33+
@variables v(t)
4334
@parameters R
44-
push!(op.eqs, v ~ R * i)
45-
R = ModelingToolkit.value(R)
46-
push!(op.ps, R)
47-
op.default_p[R] = val
48-
op
35+
eqs = [
36+
v ~ p.v - n.v
37+
0 ~ p.i + n.i
38+
v ~ p.i * R
39+
]
40+
ODESystem(eqs, t, [v], [R], systems=[p, n], default_p=Dict(R => val), name=name)
4941
end
5042

5143
function Capacitor(name; C = 1.0)
5244
val = C
53-
v, i, op = OnePort(name)
45+
p = Pin(:p)
46+
n = Pin(:n)
47+
@variables v(t)
5448
@parameters C
5549
D = Differential(t)
56-
push!(op.eqs, D(v) ~ i / C)
57-
C = ModelingToolkit.value(C)
58-
push!(op.ps, C)
59-
op.default_p[C] = val
60-
op
50+
eqs = [
51+
v ~ p.v - n.v
52+
0 ~ p.i + n.i
53+
D(v) ~ p.i / C
54+
]
55+
ODESystem(eqs, t, [v], [C], systems=[p, n], default_p=Dict(C => val), name=name)
6156
end
6257

63-
function Inductor(name; L = 1.0)
64-
val = L
65-
v, i, op = OnePort(name)
66-
@parameters L
67-
D = Differential(t)
68-
push!(op.eqs, D(i) ~ v / L)
69-
L = ModelingToolkit.value(L)
70-
push!(op.ps, L)
71-
op.default_p[L] = val
72-
op
58+
R = 1.0
59+
C = 1.0
60+
V = 1.0
61+
resistor = Resistor(:resistor, R=R)
62+
capacitor = Capacitor(:capacitor, C=C)
63+
source = ConstantVoltage(:source, V=V)
64+
ground = Ground(:ground)
65+
66+
function connect(ps...)
67+
eqs = [
68+
0 ~ sum(p->p.i, ps) # KCL
69+
]
70+
# KVL
71+
for i in 1:length(ps)-1
72+
push!(eqs, ps[i].v ~ ps[i+1].v)
73+
end
74+
75+
return eqs
7376
end
77+
rc_eqs = [
78+
connect(source.p, resistor.p)
79+
connect(resistor.n, capacitor.p)
80+
connect(capacitor.n, source.n, ground.g)
81+
]
7482

75-
R1 = Resistor(:R1)
76-
C1 = Capacitor(:C1)
77-
I1 = Inductor(:I1)
78-
@test isequal(R1.p.i, (@variables R1₊p₊i(t))[1])
79-
@parameters R
80-
@test ModelingToolkit.default_p(flatten(R1)) == Dict(R => 1.0)
81-
@variables n₊v(t) p₊v(t) n₊i(t) p₊i(t)
82-
@test ModelingToolkit.default_u0(flatten(R1)) == Dict(
83-
n₊v => 1.0,
84-
p₊v => 1.0,
85-
n₊i => 1.0,
86-
p₊i => 1.0,
87-
)
83+
rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, source, ground], name=:rc)
84+
sys = alias_elimination(rc_model)
85+
@test ModelingToolkit.default_p(sys) == Dict(
86+
capacitor.C => 1.0,
87+
source.V => 1.0,
88+
resistor.R => 1.0,
89+
)
90+
u0 = [
91+
capacitor.v => 0.0
92+
capacitor.p.i => 0.0
93+
resistor.v => 0.0
94+
]
95+
prob = ODEProblem(sys, u0, (0, 10.0))
96+
sol = solve(prob, Rodas5())
97+
#using Plot
98+
#plot(sol)

0 commit comments

Comments
 (0)