|
1 |
| -using ModelingToolkit |
2 | 1 | using Test
|
| 2 | +using ModelingToolkit, StructuralTransformations, OrdinaryDiffEq |
3 | 3 |
|
4 | 4 | # Basic electric components
|
5 |
| -@parameters t |
| 5 | +const t = Sym{ModelingToolkit.Parameter{Real}}(:t) |
6 | 6 | function Pin(name)
|
7 | 7 | @variables v(t) i(t)
|
8 | 8 | ODESystem(Equation[], t, [v, i], [], name=name, default_u0=[v=>1.0, i=>1.0])
|
9 | 9 | end
|
10 | 10 |
|
11 | 11 | 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) |
15 | 15 | end
|
16 | 16 |
|
17 |
| -function OnePort(name) |
| 17 | +function ConstantVoltage(name; V = 1.0) |
| 18 | + val = V |
18 | 19 | p = Pin(:p)
|
19 | 20 | n = Pin(:n)
|
20 |
| - @variables v(t) i(t) |
| 21 | + @parameters V |
21 | 22 | eqs = [
|
22 |
| - v ~ p.v - n.v |
| 23 | + V ~ p.v - n.v |
23 | 24 | 0 ~ p.i + n.i
|
24 |
| - i ~ p.i |
25 | 25 | ]
|
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) |
38 | 27 | end
|
39 | 28 |
|
40 | 29 | function Resistor(name; R = 1.0)
|
41 | 30 | val = R
|
42 |
| - v, i, op = OnePort(name) |
| 31 | + p = Pin(:p) |
| 32 | + n = Pin(:n) |
| 33 | + @variables v(t) |
43 | 34 | @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) |
49 | 41 | end
|
50 | 42 |
|
51 | 43 | function Capacitor(name; C = 1.0)
|
52 | 44 | val = C
|
53 |
| - v, i, op = OnePort(name) |
| 45 | + p = Pin(:p) |
| 46 | + n = Pin(:n) |
| 47 | + @variables v(t) |
54 | 48 | @parameters C
|
55 | 49 | 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) |
61 | 56 | end
|
62 | 57 |
|
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 |
73 | 76 | 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 | + ] |
74 | 82 |
|
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