@@ -173,14 +173,39 @@ function collect_instream!(set, expr, occurs=false)
173
173
return occurs
174
174
end
175
175
176
- positivemax (m, :: Any ; tol= nothing )= max (m, something (tol, 1e-8 ))
176
+ # positivemax(m, ::Any; tol=nothing)= max(m, something(tol, 1e-8))
177
+ # _positivemax(m, tol) = ifelse((-tol <= m) & (m <= tol), ((3 * tol - m) * (tol + m)^3)/(16 * tol^3) + tol, max(m, tol))
178
+ function _positivemax (m, si)
179
+ T = typeof (m)
180
+ relativeTolerance = 1e-4
181
+ nominal = one (T)
182
+ eps = relativeTolerance * nominal
183
+ alpha = if si > eps
184
+ one (T)
185
+ else
186
+ if si > 0
187
+ (si/ eps)^ 2 * (3 - 2 * si/ eps)
188
+ else
189
+ zero (T)
190
+ end
191
+ end
192
+ alpha * max (m, 0 ) + (1 - alpha)* eps
193
+ end
194
+ @register _positivemax (m, tol)
195
+ positivemax (m, :: Any ; tol= nothing ) = _positivemax (m, tol)
196
+ mydiv (num, den) = if den == 0
197
+ error ()
198
+ else
199
+ num / den
200
+ end
201
+ @register mydiv (n, d)
177
202
178
203
function expand_connections (sys:: AbstractSystem ; debug= false , tol= 1e-10 )
179
204
subsys = get_systems (sys)
180
205
isempty (subsys) && return sys
181
206
182
207
# post order traversal
183
- @set! sys. systems = map (s-> expand_connections (s, debug= debug), subsys)
208
+ @set! sys. systems = map (s-> expand_connections (s, debug= debug, tol = tol ), subsys)
184
209
185
210
outer_connectors = Symbol[]
186
211
for s in subsys
@@ -288,6 +313,67 @@ function expand_connections(sys::AbstractSystem; debug=false, tol=1e-10)
288
313
return sys
289
314
end
290
315
316
+ @generated function _instream_split (:: Val{inner_n} , :: Val{outer_n} , vars:: NTuple{N} ) where {inner_n, outer_n, N}
317
+ # instream_rt(innerfvs..., innersvs..., outerfvs..., outersvs...)
318
+ ret = Expr (:tuple )
319
+ # mj.c.m_flow
320
+ inner_f = :(Base. @ntuple $ inner_n i -> vars[i])
321
+ offset = inner_n
322
+ inner_s = :(Base. @ntuple $ inner_n i -> vars[$ offset+ i])
323
+ offset += inner_n
324
+ # ck.m_flow
325
+ outer_f = :(Base. @ntuple $ outer_n i -> vars[$ offset+ i])
326
+ offset += outer_n
327
+ outer_s = :(Base. @ntuple $ outer_n i -> vars[$ offset+ i])
328
+ Expr (:tuple , inner_f, inner_s, outer_f, outer_s)
329
+ end
330
+
331
+ function instream_rt (ins:: Val{inner_n} , outs:: Val{outer_n} , vars:: Vararg{Any,N} ) where {inner_n, outer_n, N}
332
+ @assert N == 2 * (inner_n + outer_n)
333
+
334
+ # inner: mj.c.m_flow
335
+ # outer: ck.m_flow
336
+ inner_f, inner_s, outer_f, outer_s = _instream_split (ins, outs, vars)
337
+
338
+ T = float (first (inner_f))
339
+ si = zero (T)
340
+ num = den = zero (T)
341
+ for f in inner_f
342
+ si += max (- f, 0 )
343
+ end
344
+ for f in outer_f
345
+ si += max (f, 0 )
346
+ end
347
+ # for (f, s) in zip(inner_f, inner_s)
348
+ for j in 1 : inner_n
349
+ @inbounds f = inner_f[j]
350
+ @inbounds s = inner_s[j]
351
+ num += _positivemax (- f, si) * s
352
+ den += _positivemax (- f, si)
353
+ end
354
+ # for (f, s) in zip(outer_f, outer_s)
355
+ for j in 1 : outer_n
356
+ @inbounds f = outer_f[j]
357
+ @inbounds s = outer_s[j]
358
+ num += _positivemax (- f, si) * s
359
+ den += _positivemax (- f, si)
360
+ end
361
+ return num / den
362
+ #=
363
+ si = sum(max(-mj.c.m_flow,0) for j in cat(1,1:i-1, i+1:N)) +
364
+ sum(max(ck.m_flow ,0) for k in 1:M)
365
+
366
+ inStream(mi.c.h_outflow) =
367
+ (sum(positiveMax(-mj.c.m_flow,si)*mj.c.h_outflow)
368
+ + sum(positiveMax(ck.m_flow,s_i)*inStream(ck.h_outflow)))/
369
+ (sum(positiveMax(-mj.c.m_flow,s_i))
370
+ + sum(positiveMax(ck.m_flow,s_i)))
371
+ for j in 1:N and i <> j and mj.c.m_flow.min < 0,
372
+ for k in 1:M and ck.m_flow.max > 0
373
+ =#
374
+ end
375
+ SymbolicUtils. promote_symtype (:: typeof (instream_rt), :: Vararg ) = Real
376
+
291
377
function expand_instream (instream_eqs, instream_exprs, connects; debug= false , tol)
292
378
sub = Dict ()
293
379
seen = Set ()
@@ -339,6 +425,15 @@ function expand_instream(instream_eqs, instream_exprs, connects; debug=false, to
339
425
fv = flowvar (first (connectors))
340
426
i = findfirst (c-> nameof (c) === connector_name, inner_sc)
341
427
if i != = nothing
428
+ # mj.c.m_flow
429
+ innerfvs = [unwrap (states (s, fv)) for (j, s) in enumerate (inner_sc) if j != i]
430
+ innersvs = [unwrap (states (s, sv)) for (j, s) in enumerate (inner_sc) if j != i]
431
+ # ck.m_flow
432
+ outerfvs = [unwrap (states (s, fv)) for s in outer_sc]
433
+ outersvs = [instream (states (s, fv)) for s in outer_sc]
434
+
435
+ sub[ex] = term (instream_rt, Val (length (innerfvs)), Val (length (outerfvs)), innerfvs... , innersvs... , outerfvs... , outersvs... )
436
+ #=
342
437
si = isempty(outer_sc) ? 0 : sum(s->max(states(s, fv), 0), outer_sc)
343
438
for j in 1:n_inners; j == i && continue
344
439
f = states(inner_sc[j], fv)
@@ -359,9 +454,9 @@ function expand_instream(instream_eqs, instream_exprs, connects; debug=false, to
359
454
den += tmp
360
455
num += tmp * instream(states(outer_sc[k], sv))
361
456
end
362
- sub[ex] = num / den
457
+ sub[ex] = mydiv(num, den)
458
+ =#
363
459
end
364
-
365
460
end
366
461
end
367
462
0 commit comments