Skip to content

Commit ec9a51f

Browse files
committed
Implement draft inner/outer criterion for instream
1 parent fb791eb commit ec9a51f

File tree

1 file changed

+71
-66
lines changed

1 file changed

+71
-66
lines changed

src/systems/connectors.jl

Lines changed: 71 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ end
5151
Connection(syss) = Connection(inners=syss)
5252
get_systems(c::Connection) = c.inners
5353
function Base.in(e::Symbol, c::Connection)
54-
f = isequal(e)
55-
any(f, c.inners) || any(f, c.outers)
54+
any(k->nameof(k) === e, c.inners) || any(k->nameof(k) === e, c.outers)
5655
end
5756

5857
const EMPTY_VEC = []
@@ -166,11 +165,10 @@ function get_sys_var(sys::AbstractSystem, var; inclusive=true)
166165
newsys, lvs[end]
167166
end
168167

169-
function split_stream_var(var)
168+
function split_sys_var(var)
170169
var_name = string(getname(var))
171-
@show var_name
172170
sidx = findlast(isequal(''), var_name)
173-
sidx === nothing && error("$var is not a stream variable")
171+
sidx === nothing && error("$var is not a namespaced variable")
174172
connector_name = Symbol(var_name[1:prevind(var_name, sidx)])
175173
streamvar_name = Symbol(var_name[nextind(var_name, sidx):end])
176174
connector_name, streamvar_name
@@ -179,15 +177,15 @@ end
179177
function find_connection(connector_name, ogsys, names)
180178
cs = get_connections(ogsys)
181179
cs === nothing || for c in cs
182-
@show renamespace(names, connector_name)
183-
renamespace(names, connector_name) in c && return c
180+
renamespace(names, connector_name) in c && return ogsys, c
184181
end
185182
innersys = ogsys
186-
for n in names
183+
for (i, n) in enumerate(names)
187184
innersys = getproperty(innersys, n)
188185
cs = get_connections(innersys)
189186
cs === nothing || for c in cs
190-
connector_name in c && return c
187+
nn = @view names[i+1:end]
188+
renamespace(nn, connector_name) in c && return innersys, c
191189
end
192190
end
193191
error("$connector_name cannot be found in $(nameof(ogsys)) with levels $(names)")
@@ -218,68 +216,75 @@ function expand_instream(ogsys, sys::AbstractSystem=ogsys, names=[]; debug=false
218216

219217
for ex in instream_exprs
220218
var = only(arguments(ex))
221-
connector_name, streamvar_name = split_stream_var(var)
222-
223-
n_inners = 0
224-
n_outers = 0
225-
outer_names = Symbol[]
226-
inner_names = Symbol[]
227-
outer_sc = Symbol[]
228-
inner_sc = Symbol[]
219+
connector_name, streamvar_name = split_sys_var(var)
220+
221+
outer_sc = []
222+
inner_sc = []
229223
# find the connect
230-
connect = find_connection(connector_name, ogsys, names)
231-
@show connect
232-
end
233-
return sys
234-
#=
235-
236-
#splitting_idx
237-
238-
#n_inners + n_outers <= 0 && error("Model $(nameof(sys)) has no stream connectors, yet there are equations with `instream` functions: $(instream_eqs)")
239-
240-
# expand `instream`s
241-
sub = Dict()
242-
additional_eqs = Equation[]
243-
seen = Set()
244-
# https://specification.modelica.org/v3.4/Ch15.html
245-
# Based on the above requirements, the following implementation is
246-
# recommended:
247-
if n_inners == 1 && n_outers == 0
248-
for ex in instream_exprs
249-
var = only(arguments(ex))
250-
connector_name, streamvar_name = split_stream_var(var)
251-
idx = findfirst(isequal(connector_name), inner_names)
252-
idx === nothing || error("$stream_name is not in any stream connector of $(nameof(sys))")
253-
sub[ex] = var #getproperty(inner_sc[idx], streamvar_name)
254-
end
255-
elseif n_inners == 2 && n_outers == 0
256-
for ex in instream_exprs
257-
var = only(arguments(ex))
258-
connector_name, streamvar_name = split_stream_var(var)
259-
idx = findfirst(isequal(connector_name), inner_names)
260-
idx === nothing || error("$stream_name is not in any stream connector of $(nameof(sys))")
261-
other = idx == 1 ? 2 : 1
262-
sub[ex] = getproperty(inner_sc[other], streamvar_name)
224+
parentsys, connect = find_connection(connector_name, ogsys, names)
225+
if nameof(parentsys) != nameof(sys)
226+
# everything is a inner connector w.r.t. `sys`
227+
for s in Iterators.flatten((connect.inners, connect.outers))
228+
push!(inner_sc, s)
229+
end
230+
else
231+
for s in Iterators.flatten((connect.inners, connect.outers))
232+
if connector_name == split_var(nameof(s))[1]
233+
push!(inner_sc, s)
234+
else
235+
push!(outer_sc, s)
236+
end
237+
end
263238
end
264-
elseif n_inners == 1 && n_outers == 1
265-
for ex in instream_exprs
266-
var = only(arguments(ex)) # m_1.c.h_outflow
267-
connector_name, streamvar_name = split_stream_var(var)
268-
idx = findfirst(isequal(connector_name), inner_names)
269-
idx === nothing || error("$stream_name is not in any stream connector of $(nameof(sys))")
270-
outerinstream = getproperty(only(outer_sc), streamvar_name) # c_1.h_outflow
271-
sub[ex] = outerinstream
272-
if var in seen
273-
push!(additional_eqs, outerinstream ~ var)
274-
push!(seen, var)
239+
240+
n_inners = length(outer_sc)
241+
n_outers = length(inner_sc)
242+
@show n_inners n_outers
243+
244+
# expand `instream`s
245+
sub = Dict()
246+
additional_eqs = Equation[]
247+
seen = Set()
248+
# https://specification.modelica.org/v3.4/Ch15.html
249+
# Based on the above requirements, the following implementation is
250+
# recommended:
251+
if n_inners == 1 && n_outers == 0
252+
for ex in instream_exprs
253+
var = only(arguments(ex))
254+
connector_name, streamvar_name = split_stream_var(var)
255+
idx = findfirst(isequal(connector_name), inner_names)
256+
idx === nothing || error("$stream_name is not in any stream connector of $(nameof(sys))")
257+
sub[ex] = var #getproperty(inner_sc[idx], streamvar_name)
258+
end
259+
elseif n_inners == 2 && n_outers == 0
260+
for ex in instream_exprs
261+
var = only(arguments(ex))
262+
connector_name, streamvar_name = split_stream_var(var)
263+
idx = findfirst(isequal(connector_name), inner_names)
264+
idx === nothing || error("$stream_name is not in any stream connector of $(nameof(sys))")
265+
other = idx == 1 ? 2 : 1
266+
sub[ex] = getproperty(inner_sc[other], streamvar_name)
267+
end
268+
elseif n_inners == 1 && n_outers == 1
269+
for ex in instream_exprs
270+
var = only(arguments(ex)) # m_1.c.h_outflow
271+
connector_name, streamvar_name = split_stream_var(var)
272+
idx = findfirst(isequal(connector_name), inner_names)
273+
idx === nothing || error("$stream_name is not in any stream connector of $(nameof(sys))")
274+
outerinstream = getproperty(only(outer_sc), streamvar_name) # c_1.h_outflow
275+
sub[ex] = outerinstream
276+
if var in seen
277+
push!(additional_eqs, outerinstream ~ var)
278+
push!(seen, var)
279+
end
275280
end
281+
elseif n_inners == 0 && n_outers == 2
282+
push!(additional_eqs, outerinstream ~ var)
283+
else
276284
end
277-
elseif n_inners == 0 && n_outers == 2
278-
push!(additional_eqs, outerinstream ~ var)
279-
else
280285
end
281286
instream_eqs = map(Base.Fix2(substitute, sub), instream_eqs)
282-
=#
287+
return sys
283288
end
284289

285290
function expand_connections(sys::AbstractSystem; debug=false)
@@ -305,7 +310,7 @@ function collect_connections(sys::AbstractSystem; debug=false)
305310
s = string(nameof(sys))
306311
isconnector(sys) || error("$s is not a connector!")
307312
idx = findfirst(isequal(''), s)
308-
parent_name = Symbol(idx === nothing ? s : s[1:idx])
313+
parent_name = Symbol(idx === nothing ? s : s[1:prevind(s, idx)])
309314
parent_name in outer_connectors
310315
end
311316
end

0 commit comments

Comments
 (0)