Skip to content

Commit

Permalink
Improve stream connector handling (#10541)
Browse files Browse the repository at this point in the history
- Remove connectors with zero flow when generating equations for a
  stream connector set.
  • Loading branch information
perost committed Apr 13, 2023
1 parent 1e295d1 commit cce0dbf
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 25 deletions.
65 changes: 43 additions & 22 deletions OMCompiler/Compiler/NFFrontEnd/NFConnectEquations.mo
Expand Up @@ -385,27 +385,28 @@ function generateStreamEquations
input Expression flowThreshold;
input UnorderedMap<ComponentRef, Variable> variables;
output list<Equation> equations;
protected
ComponentRef cr1, cr2;
DAE.ElementSource src, src1, src2;
Expression cref1, cref2, e1, e2;
list<Connector> inside, outside;
Variability var1, var2;
algorithm
equations := match elements
local
ComponentRef cr1, cr2;
DAE.ElementSource src, src1, src2;
Expression cref1, cref2, e1, e2;
list<Connector> 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);
Expand All @@ -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;
Expand All @@ -443,14 +440,22 @@ function streamEquationGeneral
input UnorderedMap<ComponentRef, Variable> variables;
output list<Equation> equations = {};
protected
list<Connector> outside = outsideElements;
list<Connector> 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;
Expand Down Expand Up @@ -834,6 +839,22 @@ algorithm
end if;
end isZeroFlowMinMax;

function isZeroFlowOutside
input Connector conn;
input UnorderedMap<ComponentRef, Variable> variables;
output Boolean isZero;
algorithm
isZero := isZeroFlow(conn, "max", variables);
end isZeroFlowOutside;

function isZeroFlowInside
input Connector conn;
input UnorderedMap<ComponentRef, Variable> 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;
Expand Down
54 changes: 54 additions & 0 deletions 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
6 changes: 3 additions & 3 deletions testsuite/flattening/modelica/scodeinst/InStreamArray.mo
Expand Up @@ -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";
Expand Down
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -297,6 +297,7 @@ ConnectNonConnector3.mo \
ConnectNonConnector4.mo \
ConnectNonConnector5.mo \
ConnectNonConnector6.mo \
ConnectStream1.mo \
ConstantConnector1.mo \
ConstantConnector2.mo \
ConstantConnector3.mo \
Expand Down

0 comments on commit cce0dbf

Please sign in to comment.