You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Stream connectors: positivemax drops sq, so outer-connector stream mixing is unweighted #5218
positivemax(m, sq; tol) = _positivemax(m, tol) discards sq and passes tol (1e-10 from expand_connections) as the regularisation scale si. The generated equations for an outer connector's stream variable therefore use weights that saturate almost immediately. For any real flow, both weights are effectively equal, so the "flow-weighted" mix is an unweighted average.
Reproducer (ModelingToolkit + SciMLBase only)
# positivemax(m, sq; tol) drops sq and passes expand_connections' tol (1e-10)# as si. Outer-connector stream mixing is then an unweighted average.using InteractiveUtils
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
using SciMLBase
@connectorfunctionSPort(; name)
@variablesp(t) m(t) [connect = Flow] h(t) [connect = Stream]
System(Equation[], t, [p, m, h], []; name)
endfunctionSrc(; name, rate, h0)
@named port =SPort()
@variablesx(t) = h0
System([port.m ~-rate, port.h ~ x, D(x) ~0], t; name, systems = [port])
endfunctionRecv(; name)
@named port =SPort()
@variablesz(t) =0.0System([port.p ~1.0, port.h ~ z, D(z) ~instream(port.h) - z], t;
name, systems = [port])
end# Two inner sources with unequal flows; one outer port. The generated# outer-stream equation is gp.h ~ mix(s1.h, s2.h).functionGroup(; name)
@named gp =SPort()
@named s1 =Src(rate =1.0, h0 =2.0)
@named s2 =Src(rate =2.0, h0 =8.0)
System([connect(gp, s1.port, s2.port)], t; name, systems = [gp, s1, s2])
end@named g =Group()
@named c =Recv()
sys =mtkcompile(System([connect(g.gp, c.port)], t; name =:hier, systems = [g, c]))
prob =ODEProblem(sys, [], (0.0, 1.0))
got = SciMLBase.getsym(prob, sys.g.gp.h)(prob)
# Modelica §15.2 outer connection equation (si = 1+2 = 3 ≫ 1e-4):# gp.h = (1*2 + 2*8) / (1+2) = 18/3 = 6
expected =6.0# Bug: _positivemax(m, 1e-10) ≈ 1e-4 for every positive m, so# gp.h ≈ (2+8)/2 = 5 (unweighted).println("bug2: positivemax drops sq; outer stream mix is unweighted")
println("ModelingToolkit ", pkgversion(ModelingToolkit))
println("observed gp.h equation:")
for eq inobserved(sys)
s =string(eq)
ifoccursin("gp", s) &&occursin("h", s) &&occursin("positivemax", s)
println("", s)
endendprintln("got g.gp.h = ", got)
println("expected g.gp.h = ", expected, " (flow-weighted (1*2 + 2*8)/3 )")
println("unweighted average would be ", (2.0+8.0) /2)
versioninfo()
Output (ModelingToolkit 11.45.1, rerun in a fresh process)
bug2: positivemax drops sq; outer stream mix is unweighted
ModelingToolkit 11.45.1
observed gp.h equation:
g₊gp₊h(t) ~ (ModelingToolkitBase._positivemax(-g₊s1₊port₊m(t), 1.0e-10)*g₊s1₊x(t) + ModelingToolkitBase._positivemax(-g₊s2₊port₊m(t), 1.0e-10)*g₊s2₊x(t)) / (ModelingToolkitBase._positivemax(-g₊s1₊port₊m(t), 1.0e-10) + ModelingToolkitBase._positivemax(-g₊s2₊port₊m(t), 1.0e-10))
got g.gp.h = 5.000000044999968
expected g.gp.h = 6.0 (flow-weighted (1*2 + 2*8)/3 )
unweighted average would be 5.0
Julia Version 1.12.4
Two sources with flows 1 and 2 and stream values 2 and 8 should mix to the flow-weighted value (1·2 + 2·8)/3 = 6.0. The generated equation gives 5.0, the unweighted average. The expected value follows directly from the Modelica stream-connector semantics (§15.2): outflowing connectors are weighted by their flow.
🤖 Filed by an AI agent (Claude Code, model claude-opus-5-5) on behalf of Chris Rackauckas. The reproducer was prepared by Cursor Agent (auto) and independently rerun by the filing agent. Found during an Opus 5.5 review of #5213. https://claude.ai/code/session_01VJtEvCkHe9XafoMbYvR9No
Activity