Skip to content

Commit ff79484

Browse files
authored
Merge pull request #1534 from SciML/myb/param
Add but_ordered_incidence
2 parents 752be46 + 7e286e7 commit ff79484

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

examples/electrical_components.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,41 @@ function Inductor(; name, L = 1.0)
6666
]
6767
extend(ODESystem(eqs, t, [], ps; name=name), oneport)
6868
end
69+
70+
@connector function HeatPort(;name)
71+
@variables T(t)=293.15 Q_flow(t)=0.0 [connect = Flow]
72+
ODESystem(Equation[], t, [T, Q_flow], [], name=name)
73+
end
74+
75+
function HeatingResistor(;name, R=1.0, TAmbient=293.15, alpha=1.0)
76+
@named p = Pin()
77+
@named n = Pin()
78+
@named h = HeatPort()
79+
@variables v(t) RTherm(t)
80+
@parameters R=R TAmbient=TAmbient alpha=alpha
81+
eqs = [
82+
RTherm ~ R*(1 + alpha*(h.T - TAmbient))
83+
v ~ p.i * RTherm
84+
h.Q_flow ~ -v * p.i # -LossPower
85+
v ~ p.v - n.v
86+
0 ~ p.i + n.i
87+
]
88+
compose(ODESystem(
89+
eqs, t, [v, RTherm], [R, TAmbient, alpha],
90+
name=name,
91+
), p, n, h)
92+
end
93+
94+
function HeatCapacitor(;name, rho=8050, V=1, cp=460, TAmbient=293.15)
95+
@parameters rho=rho V=V cp=cp
96+
C = rho*V*cp
97+
@named h = HeatPort()
98+
D = Differential(t)
99+
eqs = [
100+
D(h.T) ~ h.Q_flow / C
101+
]
102+
compose(ODESystem(
103+
eqs, t, [], [rho, V, cp],
104+
name=name,
105+
), h)
106+
end

src/structural_transformation/StructuralTransformations.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export sorted_incidence_matrix, pantelides!, tearing_reassemble, find_solvables!
4545
export tearing_assignments, tearing_substitution
4646
export torn_system_jacobian_sparsity
4747
export full_equations
48+
export but_ordered_incidence, lowest_order_variable_mask, highest_order_variable_mask
4849

4950
include("utils.jl")
5051
include("pantelides.jl")

src/structural_transformation/utils.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,38 @@ function find_solvables!(state::TearingState; kwargs...)
208208
return nothing
209209
end
210210

211+
highest_order_variable_mask(ts) = let v2d = ts.structure.var_to_diff
212+
v->isempty(outneighbors(v2d, v))
213+
end
214+
215+
lowest_order_variable_mask(ts) = let v2d = ts.structure.var_to_diff
216+
v->isempty(outneighbors(v2d, v))
217+
end
218+
219+
function but_ordered_incidence(ts::TearingState, varmask=highest_order_variable_mask(ts))
220+
graph = complete(ts.structure.graph)
221+
var_eq_matching = complete(maximal_matching(graph, _->true, varmask))
222+
scc = find_var_sccs(graph, var_eq_matching)
223+
vordering = Vector{Int}(undef, 0)
224+
bb = Int[1]
225+
sizehint!(vordering, ndsts(graph))
226+
sizehint!(bb, ndsts(graph))
227+
l = 1
228+
for c in scc
229+
isemptyc = true
230+
for v in c
231+
if varmask(v)
232+
push!(vordering, v)
233+
l += 1
234+
isemptyc = false
235+
end
236+
end
237+
isemptyc || push!(bb, l)
238+
end
239+
mm = incidence_matrix(graph)
240+
mm[[var_eq_matching[v] for v in vordering if var_eq_matching[v] isa Int], vordering], bb
241+
end
242+
211243
# debugging use
212244
function reordered_matrix(sys, torn_matching)
213245
s = TearingState(sys)

test/components.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,38 @@ end
212212

213213
@named foo = Circuit()
214214
@test structural_simplify(foo) isa ModelingToolkit.AbstractSystem
215+
216+
# BLT tests
217+
using LinearAlgebra
218+
function parallel_rc_model(i; name, source, ground, R, C)
219+
resistor = HeatingResistor(name=Symbol(:resistor, i), R=R)
220+
capacitor = Capacitor(name=Symbol(:capacitor, i), C=C)
221+
heat_capacitor = HeatCapacitor(name=Symbol(:heat_capacitor, i))
222+
223+
rc_eqs = [
224+
connect(source.p, resistor.p)
225+
connect(resistor.n, capacitor.p)
226+
connect(capacitor.n, source.n, ground.g)
227+
connect(resistor.h, heat_capacitor.h)
228+
]
229+
230+
compose(ODESystem(rc_eqs, t, name=Symbol(name, i)),
231+
[resistor, capacitor, source, ground, heat_capacitor])
232+
end
233+
V = 2.0
234+
@named source = ConstantVoltage(V=V)
235+
@named ground = Ground()
236+
N = 50
237+
Rs = 10 .^range(0, stop=-4, length=N)
238+
Cs = 10 .^range(-3, stop=0, length=N)
239+
rc_systems = map(1:N) do i
240+
parallel_rc_model(i; name=:rc, source=source, ground=ground, R=Rs[i], C=Cs[i])
241+
end;
242+
@variables E(t)=0.0
243+
eqs = [
244+
D(E) ~ sum(((i, sys),)->getproperty(sys, Symbol(:resistor, i)).h.Q_flow, enumerate(rc_systems))
245+
]
246+
@named _big_rc = ODESystem(eqs, t, [E], [])
247+
@named big_rc = compose(_big_rc, rc_systems)
248+
ts = TearingState(expand_connections(big_rc))
249+
@test istriu(but_ordered_incidence(ts)[1])

0 commit comments

Comments
 (0)