From cce0dbf536c7d4f54b694c2ffddc49402c995847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Thu, 13 Apr 2023 15:22:33 +0200 Subject: [PATCH] Improve stream connector handling (#10541) - Remove connectors with zero flow when generating equations for a stream connector set. --- .../Compiler/NFFrontEnd/NFConnectEquations.mo | 65 ++++++++++++------- .../modelica/scodeinst/ConnectStream1.mo | 54 +++++++++++++++ .../modelica/scodeinst/InStreamArray.mo | 6 +- .../flattening/modelica/scodeinst/Makefile | 1 + 4 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 testsuite/flattening/modelica/scodeinst/ConnectStream1.mo diff --git a/OMCompiler/Compiler/NFFrontEnd/NFConnectEquations.mo b/OMCompiler/Compiler/NFFrontEnd/NFConnectEquations.mo index 9e4375ca3d5..f9a3e52ae28 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFConnectEquations.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFConnectEquations.mo @@ -385,27 +385,28 @@ function generateStreamEquations input Expression flowThreshold; input UnorderedMap variables; output list equations; +protected + ComponentRef cr1, cr2; + DAE.ElementSource src, src1, src2; + Expression cref1, cref2, e1, e2; + list inside, outside; + Variability var1, var2; algorithm - equations := match elements - local - ComponentRef cr1, cr2; - DAE.ElementSource src, src1, src2; - Expression cref1, cref2, e1, e2; - list inside, outside; - Variability var1, var2; + (outside, inside) := List.splitOnTrue(elements, Connector.isOutside); + inside := list(s for s guard not isZeroFlowInside(s, variables) in inside); + equations := match (inside, outside) // Unconnected stream connector, do nothing. - case ({Connector.CONNECTOR(face = Face.INSIDE)}) then {}; + case ({_}, {}) then {}; // Both inside, do nothing. - case ({Connector.CONNECTOR(face = Face.INSIDE), - Connector.CONNECTOR(face = Face.INSIDE)}) then {}; + case ({_, _}, {}) then {}; // Both outside: // cr1 = inStream(cr2); // cr2 = inStream(cr1); - case ({Connector.CONNECTOR(name = cr1, face = Face.OUTSIDE, source = src1), - Connector.CONNECTOR(name = cr2, face = Face.OUTSIDE, source = src2)}) + case ({}, {Connector.CONNECTOR(name = cr1, source = src1), + Connector.CONNECTOR(name = cr2, source = src2)}) algorithm cref1 := Expression.fromCref(cr1); cref2 := Expression.fromCref(cr2); @@ -418,19 +419,15 @@ algorithm // One inside, one outside: // cr1 = cr2; - case ({Connector.CONNECTOR(name = cr1, source = src1), - Connector.CONNECTOR(name = cr2, source = src2)}) + case ({Connector.CONNECTOR(name = cr1, source = src1)}, + {Connector.CONNECTOR(name = cr2, source = src2)}) algorithm src := ElementSource.mergeSources(src1, src2); then {Equation.makeCrefEquality(cr1, cr2, InstNode.EMPTY_NODE(), src)}; // The general case with N inside connectors and M outside: - else - algorithm - (outside, inside) := List.splitOnTrue(elements, Connector.isOutside); - then - streamEquationGeneral(outside, inside, flowThreshold, variables); + else streamEquationGeneral(outside, inside, flowThreshold, variables); end match; end generateStreamEquations; @@ -443,14 +440,22 @@ function streamEquationGeneral input UnorderedMap variables; output list equations = {}; protected - list outside = outsideElements; + list reduced_outside, outside; Expression cref_exp, res; DAE.ElementSource src; algorithm + reduced_outside := list(s for s guard not isZeroFlowOutside(s, variables) in outsideElements); + for e in outsideElements loop cref_exp := Expression.fromCref(e.name); - outside := removeStreamSetElement(e.name, outsideElements); - res := streamSumEquationExp(outside, insideElements, flowThreshold, variables); + outside := removeStreamSetElement(e.name, reduced_outside); + + if listEmpty(outside) and listEmpty(insideElements) then + res := Expression.INTEGER(0); + else + res := streamSumEquationExp(outside, insideElements, flowThreshold, variables); + end if; + src := ElementSource.addAdditionalComment(e.source, " equation generated from stream connection"); equations := Equation.EQUALITY(cref_exp, res, Type.REAL(), InstNode.EMPTY_NODE(), src) :: equations; end for; @@ -834,6 +839,22 @@ algorithm end if; end isZeroFlowMinMax; +function isZeroFlowOutside + input Connector conn; + input UnorderedMap variables; + output Boolean isZero; +algorithm + isZero := isZeroFlow(conn, "max", variables); +end isZeroFlowOutside; + +function isZeroFlowInside + input Connector conn; + input UnorderedMap variables; + output Boolean isZero; +algorithm + isZero := isZeroFlow(conn, "min", variables); +end isZeroFlowInside; + function isZeroFlow "Returns true if the given flow attribute of a connector is zero." input Connector element; diff --git a/testsuite/flattening/modelica/scodeinst/ConnectStream1.mo b/testsuite/flattening/modelica/scodeinst/ConnectStream1.mo new file mode 100644 index 00000000000..6b005ab4c4e --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/ConnectStream1.mo @@ -0,0 +1,54 @@ +// name: ConnectStream1 +// keywords: +// status: correct +// cflags: -d=newInst +// +// + +type AbsolutePressure = Real(min = 0, max = 1.e8); +type SpecificEnthalpy = Real(min = -1.0e10, max = 1.e10); +type MassFlowRate = Real(min = -1.0e5, max = 1.e5); + +connector FluidPort + flow MassFlowRate m_flow; + AbsolutePressure p; + stream SpecificEnthalpy h_outflow; +end FluidPort; + +model IdealSource + FluidPort port_b(m_flow(max = 1e60)); +end IdealSource; + +model RelativePressure + FluidPort port_a(m_flow(min = 0)); +end RelativePressure; + +model ConnectStream1 + FluidPort port_b(m_flow(max = 1e60)); +protected + IdealSource preSou; + RelativePressure senRelPre; +equation + connect(preSou.port_b, port_b); + connect(senRelPre.port_a, preSou.port_b); +end ConnectStream1; + +// Result: +// class ConnectStream1 +// Real port_b.m_flow(min = -100000.0, max = 9.999999999999999e+59); +// Real port_b.p(min = 0.0, max = 100000000.0); +// Real port_b.h_outflow(min = -10000000000.0, max = 10000000000.0); +// protected Real preSou.port_b.m_flow(min = -100000.0, max = 9.999999999999999e+59); +// protected Real preSou.port_b.p(min = 0.0, max = 100000000.0); +// protected Real preSou.port_b.h_outflow(min = -10000000000.0, max = 10000000000.0); +// protected Real senRelPre.port_a.m_flow(min = 0.0, max = 100000.0); +// protected Real senRelPre.port_a.p(min = 0.0, max = 100000000.0); +// protected Real senRelPre.port_a.h_outflow(min = -10000000000.0, max = 10000000000.0); +// equation +// senRelPre.port_a.p = preSou.port_b.p; +// senRelPre.port_a.p = port_b.p; +// senRelPre.port_a.m_flow + preSou.port_b.m_flow - port_b.m_flow = 0.0; +// preSou.port_b.h_outflow = port_b.h_outflow; +// port_b.m_flow = 0.0; +// end ConnectStream1; +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/InStreamArray.mo b/testsuite/flattening/modelica/scodeinst/InStreamArray.mo index 18707e1f04e..8424a58d314 100644 --- a/testsuite/flattening/modelica/scodeinst/InStreamArray.mo +++ b/testsuite/flattening/modelica/scodeinst/InStreamArray.mo @@ -122,19 +122,19 @@ end InStreamArray; // equation // c[1].a.e = c[1].t.a.e; // c[1].t.a.f - c[1].a.f = 0.0; -// c[1].a.s = c[1].t.a.s; +// c[1].t.a.s = c[1].a.s; // c[1].b.e = c[1].v.p.e; // c[1].b.e = c[1].t.b.e; // c[1].b.s = ($OMC$PositiveMax(-c[1].t.b.f, 1e-07 * c[1].t.fnom) * c[1].t.b.s + $OMC$PositiveMax(-c[1].v.p.f, 1e-07 * c[1].v.fnom) * c[1].v.p.s) / ($OMC$PositiveMax(-c[1].t.b.f, 1e-07 * c[1].t.fnom) + $OMC$PositiveMax(-c[1].v.p.f, 1e-07 * c[1].v.fnom)) " equation generated from stream connection"; // c[2].a.e = c[2].t.a.e; // c[2].t.a.f - c[2].a.f = 0.0; -// c[2].a.s = c[2].t.a.s; +// c[2].t.a.s = c[2].a.s; // c[2].b.e = c[2].v.p.e; // c[2].b.e = c[2].t.b.e; // c[2].b.s = ($OMC$PositiveMax(-c[2].t.b.f, 1e-07 * c[2].t.fnom) * c[2].t.b.s + $OMC$PositiveMax(-c[2].v.p.f, 1e-07 * c[2].v.fnom) * c[2].v.p.s) / ($OMC$PositiveMax(-c[2].t.b.f, 1e-07 * c[2].t.fnom) + $OMC$PositiveMax(-c[2].v.p.f, 1e-07 * c[2].v.fnom)) " equation generated from stream connection"; // c[3].a.e = c[3].t.a.e; // c[3].t.a.f - c[3].a.f = 0.0; -// c[3].a.s = c[3].t.a.s; +// c[3].t.a.s = c[3].a.s; // c[3].b.e = c[3].v.p.e; // c[3].b.e = c[3].t.b.e; // c[3].b.s = ($OMC$PositiveMax(-c[3].t.b.f, 1e-07 * c[3].t.fnom) * c[3].t.b.s + $OMC$PositiveMax(-c[3].v.p.f, 1e-07 * c[3].v.fnom) * c[3].v.p.s) / ($OMC$PositiveMax(-c[3].t.b.f, 1e-07 * c[3].t.fnom) + $OMC$PositiveMax(-c[3].v.p.f, 1e-07 * c[3].v.fnom)) " equation generated from stream connection"; diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index 618e2c516ff..7df1cd3c2f5 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -297,6 +297,7 @@ ConnectNonConnector3.mo \ ConnectNonConnector4.mo \ ConnectNonConnector5.mo \ ConnectNonConnector6.mo \ +ConnectStream1.mo \ ConstantConnector1.mo \ ConstantConnector2.mo \ ConstantConnector3.mo \