Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 2fa8c5e

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Evaluate actualStream.
- Add missing evaluation of actualStream to ConnectEquations. - Remove the associated flow cref stored in stream connectors, since it doesn't work for actualStream and we can just look it up in the type of the connector instead. Belonging to [master]: - #2642 - OpenModelica/OpenModelica-testsuite#1029
1 parent 661b595 commit 2fa8c5e

File tree

5 files changed

+126
-175
lines changed

5 files changed

+126
-175
lines changed

Compiler/NFFrontEnd/NFBuiltinFuncs.mo

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,5 +276,10 @@ constant Function FILL_FUNC = Function.FUNCTION(Path.IDENT("fill"),
276276
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
277277
Pointer.createImmutable(true), Pointer.createImmutable(0));
278278

279+
constant Function SMOOTH = Function.FUNCTION(Path.IDENT("smooth"),
280+
InstNode.EMPTY_NODE(), {}, {}, {}, {},
281+
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
282+
Pointer.createImmutable(true), Pointer.createImmutable(0));
283+
279284
annotation(__OpenModelica_Interface="frontend");
280285
end NFBuiltinFuncs;

Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,13 @@ public
175175
CREF(node = node) := cref;
176176
end node;
177177

178+
function nodeType
179+
input ComponentRef cref;
180+
output Type ty;
181+
algorithm
182+
CREF(ty = ty) := cref;
183+
end nodeType;
184+
178185
function firstName
179186
input ComponentRef cref;
180187
output String name;

Compiler/NFFrontEnd/NFConnectEquations.mo

Lines changed: 103 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import NFBinding.Binding;
6363
import NFFunction.Function;
6464
import Global;
6565
import BuiltinCall = NFBuiltinCall;
66+
import ComplexType = NFComplexType;
6667

6768
constant Expression EQ_ASSERT_STR =
6869
Expression.STRING("Connected constants/parameters must be equal");
@@ -429,11 +430,11 @@ function streamFlowExp
429430
output Expression streamExp;
430431
output Expression flowExp;
431432
protected
432-
ComponentRef flow_cr;
433+
ComponentRef stream_cr;
433434
algorithm
434-
Connector.CONNECTOR(associatedFlow = SOME(flow_cr)) := element;
435-
streamExp := Expression.fromCref(element.name);
436-
flowExp := Expression.fromCref(flow_cr);
435+
stream_cr := Connector.name(element);
436+
streamExp := Expression.fromCref(stream_cr);
437+
flowExp := Expression.fromCref(associatedFlowCref(stream_cr));
437438
end streamFlowExp;
438439

439440
function flowExp
@@ -443,7 +444,7 @@ function flowExp
443444
protected
444445
ComponentRef flow_cr;
445446
algorithm
446-
Connector.CONNECTOR(associatedFlow = SOME(flow_cr)) := element;
447+
flow_cr := associatedFlowCref(Connector.name(element));
447448
flowExp := Expression.fromCref(flow_cr);
448449
end flowExp;
449450

@@ -528,7 +529,7 @@ protected
528529
Option<Expression> nominal_oexp;
529530
Expression nominal_exp, flow_threshold;
530531
algorithm
531-
flow_node := ComponentRef.node(Connector.flowCref(element));
532+
flow_node := ComponentRef.node(associatedFlowCref(Connector.name(element)));
532533
nominal_oexp := Class.lookupAttributeValue("nominal", InstNode.getClass(flow_node));
533534

534535
if isSome(nominal_oexp) then
@@ -559,8 +560,8 @@ algorithm
559560
then match Function.name(call.fn)
560561
case Absyn.IDENT("inStream")
561562
then evaluateInStream(Expression.toCref(listHead(call.arguments)), sets, setsArray, ctable);
562-
//case Absyn.IDENT("actualStream")
563-
// then evaluateActualStream(Expression.toCref(listHead(call.arguments)), sets, setsArray);
563+
case Absyn.IDENT("actualStream")
564+
then evaluateActualStream(Expression.toCref(listHead(call.arguments)), sets, setsArray, ctable);
564565
case Absyn.IDENT("cardinality")
565566
then CardinalityTable.evaluateCardinality(listHead(call.arguments), ctable);
566567
else exp;
@@ -583,7 +584,7 @@ protected
583584
Integer set;
584585
algorithm
585586
c := Connector.CONNECTOR(cref, Type.UNKNOWN(), Face.INSIDE,
586-
ConnectorType.STREAM, NONE(), DAE.emptyElementSource);
587+
ConnectorType.STREAM, DAE.emptyElementSource);
587588

588589
try
589590
set := ConnectionSets.findSetArrayIndex(c, sets);
@@ -691,145 +692,78 @@ algorithm
691692
end if;
692693
end isZeroFlow;
693694

694-
//protected function evaluateActualStream
695-
// "This function evaluates the actualStream operator for a component reference,
696-
// given the connection sets."
697-
// input DAE.ComponentRef streamCref;
698-
// input ConnectionSets.Sets sets;
699-
// input array<list<Connector>> setsArray;
700-
// input Expression flowThreshold;
701-
// output DAE.Exp exp;
702-
//protected
703-
// DAE.ComponentRef flow_cr;
704-
// DAE.Exp e, flow_exp, stream_exp, instream_exp, rel_exp;
705-
// DAE.Type ety;
706-
// Integer flow_dir;
707-
//algorithm
708-
// //flow_cr := getStreamFlowAssociation(streamCref, sets);
709-
// //ety := ComponentReference.crefLastType(flow_cr);
710-
// //flow_dir := evaluateFlowDirection(ety);
711-
//
712-
// //// Select a branch if we know the flow direction, otherwise generate the whole
713-
// //// if-equation.
714-
// //if flow_dir == 1 then
715-
// // rel_exp := evaluateInStream(streamCref, sets, setsArray, flowThreshold);
716-
// //elseif flow_dir == -1 then
717-
// // rel_exp := Expression.crefExp(streamCref);
718-
// //else
719-
// // flow_exp := Expression.crefExp(flow_cr);
720-
// // stream_exp := Expression.crefExp(streamCref);
721-
// // instream_exp := evaluateInStream(streamCref, sets, setsArray, flowThreshold);
722-
// // rel_exp := DAE.IFEXP(
723-
// // DAE.RELATION(flow_exp, DAE.GREATER(ety), DAE.RCONST(0.0), -1, NONE()),
724-
// // instream_exp, stream_exp);
725-
// //end if;
726-
//
727-
// //// actualStream(stream_var) = smooth(0, if flow_var > 0 then inStream(stream_var)
728-
// //// else stream_var);
729-
// //exp := DAE.CALL(Absyn.IDENT("smooth"), {DAE.ICONST(0), rel_exp},
730-
// // DAE.callAttrBuiltinReal);
731-
//
732-
// exp := DAE.ICONST(0);
733-
//end evaluateActualStream;
734-
//
735-
//protected function evaluateFlowDirection
736-
// "Checks the min/max attributes of a flow variables type to try and determine
737-
// the flow direction. If the flow is positive 1 is returned, if it is negative
738-
// -1, otherwise 0 if the direction can't be decided."
739-
// input DAE.Type ty;
740-
// output Integer direction = 0;
741-
//protected
742-
// list<DAE.Var> attr;
743-
// Option<Values.Value> min_oval, max_oval;
744-
// Real min_val, max_val;
745-
//algorithm
746-
// attr := Types.getAttributes(ty);
747-
// if listEmpty(attr) then return; end if;
748-
//
749-
// min_oval := Types.lookupAttributeValue(attr, "min");
750-
// max_oval := Types.lookupAttributeValue(attr, "max");
751-
//
752-
// direction := match (min_oval, max_oval)
753-
// // No attributes, flow direction can't be decided.
754-
// case (NONE(), NONE()) then 0;
755-
// // Flow is positive if min is positive.
756-
// case (SOME(Values.REAL(min_val)), NONE())
757-
// then if min_val >= 0 then 1 else 0;
758-
// // Flow is negative if max is negative.
759-
// case (NONE(), SOME(Values.REAL(max_val)))
760-
// then if max_val <= 0 then -1 else 0;
761-
// // Flow is positive if both min and max are positive, negative if they are
762-
// // both negative, otherwise undecideable.
763-
// case (SOME(Values.REAL(min_val)), SOME(Values.REAL(max_val)))
764-
// then
765-
// if min_val >= 0 and max_val >= min_val then 1
766-
// elseif max_val <= 0 and min_val <= max_val then -1
767-
// else 0;
768-
// else 0;
769-
// end match;
770-
//end evaluateFlowDirection;
771-
//
772-
//function evaluateCardinality
773-
// input DAE.ComponentRef cref;
774-
// input ConnectionSets.Sets sets;
775-
// output DAE.Exp exp;
776-
//algorithm
777-
// // TODO: Implement this.
778-
// //exp := DAE.ICONST(getConnectCount(cref, sets.sets));
779-
// exp := DAE.Exp.ICONST(0);
780-
//end evaluateCardinality;
781-
//
782-
//function simplifyDAEElements
783-
//"run this only if we have cardinality"
784-
// input Boolean hasCardinality;
785-
// input output list<DAE.Element> daeElements;
786-
//protected
787-
// list<DAE.Element> accum = {};
788-
//algorithm
789-
// if not hasCardinality then
790-
// return;
791-
// end if;
792-
//
793-
// for e in daeElements loop
794-
// accum := matchcontinue e
795-
// case DAE.IF_EQUATION()
796-
// then listAppend(simplifyDAEIfEquation(e.condition1, e.equations2, e.equations3), accum);
797-
// case DAE.INITIAL_IF_EQUATION()
798-
// then listAppend(simplifyDAEIfEquation(e.condition1, e.equations2, e.equations3), accum);
799-
// case DAE.ASSERT(condition = DAE.BCONST(true)) then accum;
800-
// else e :: accum;
801-
// end matchcontinue;
802-
// end for;
803-
//
804-
// daeElements := listReverse(accum);
805-
//end simplifyDAEElements;
806-
//
807-
//protected function simplifyDAEIfEquation
808-
// input list<DAE.Exp> conditions;
809-
// input list<list<DAE.Element>> branches;
810-
// input list<DAE.Element> elseBranch;
811-
// output list<DAE.Element> elements;
812-
//protected
813-
// Boolean cond_value;
814-
// list<list<DAE.Element>> rest_branches = branches;
815-
//algorithm
816-
// for cond in conditions loop
817-
// DAE.BCONST(cond_value) := cond;
818-
//
819-
// // Condition is true, substitute the if-equation with the branch contents.
820-
// if cond_value == true then
821-
// elements := listReverse(listHead(rest_branches));
822-
// return;
823-
// end if;
824-
//
825-
// // Condition is false, discard the branch and continue with the other branches.
826-
// rest_branches := listRest(rest_branches);
827-
// end for;
828-
//
829-
// // All conditions were false, substitute if-equation with else-branch contents.
830-
// elements := listReverse(elseBranch);
831-
//end simplifyDAEIfEquation;
832-
//
695+
protected function evaluateActualStream
696+
"This function evaluates the actualStream operator for a component reference,
697+
given the connection sets."
698+
input ComponentRef streamCref;
699+
input ConnectionSets.Sets sets;
700+
input array<list<Connector>> setsArray;
701+
input CardinalityTable.Table ctable;
702+
output Expression exp;
703+
protected
704+
ComponentRef flow_cr;
705+
Integer flow_dir;
706+
Expression rel_exp, flow_exp, stream_exp, instream_exp;
707+
Operator op;
708+
algorithm
709+
flow_cr := associatedFlowCref(streamCref);
710+
flow_dir := evaluateFlowDirection(flow_cr);
711+
712+
// Select a branch if we know the flow direction, otherwise generate the whole
713+
// if-equation.
714+
if flow_dir == 1 then
715+
rel_exp := evaluateInStream(streamCref, sets, setsArray, ctable);
716+
elseif flow_dir == -1 then
717+
rel_exp := Expression.fromCref(streamCref);
718+
else
719+
flow_exp := Expression.fromCref(flow_cr);
720+
stream_exp := Expression.fromCref(streamCref);
721+
instream_exp := evaluateInStream(streamCref, sets, setsArray, ctable);
722+
op := Operator.makeGreater(ComponentRef.nodeType(flow_cr));
723+
rel_exp := Expression.IF(
724+
Expression.RELATION(flow_exp, op, Expression.REAL(0.0)),
725+
instream_exp, stream_exp);
726+
end if;
727+
728+
// actualStream(stream_var) = smooth(0, if flow_var > 0 then inStream(stream_var)
729+
// else stream_var);
730+
exp := Expression.CALL(Call.makeTypedCall(NFBuiltinFuncs.SMOOTH,
731+
{DAE.INTEGER(0), rel_exp}, Expression.variability(rel_exp)));
732+
end evaluateActualStream;
733+
734+
function evaluateFlowDirection
735+
input ComponentRef flowCref;
736+
output Integer direction = 0;
737+
protected
738+
Class flow_cls;
739+
Option<Expression> omin, omax;
740+
Real min_val, max_val;
741+
algorithm
742+
flow_cls := InstNode.getClass(ComponentRef.node(flowCref));
743+
omin := Class.lookupAttributeValue("min", flow_cls);
744+
omax := Class.lookupAttributeValue("max", flow_cls);
745+
746+
direction := match (omin, omax)
747+
// No attributes, flow direction can't be decided.
748+
case (NONE(), NONE()) then 0;
749+
// Flow is positive if min is positive.
750+
case (SOME(Expression.REAL(min_val)), NONE())
751+
then if min_val >= 0 then 1 else 0;
752+
// Flow is negative if max is negative.
753+
case (NONE(), SOME(Expression.REAL(max_val)))
754+
then if max_val <= 0 then -1 else 0;
755+
// Flow is positive if both min and max are positive, negative if they are
756+
// both negative, otherwise undecideable.
757+
case (SOME(Expression.REAL(min_val)), SOME(Expression.REAL(max_val)))
758+
then
759+
if min_val >= 0 and max_val >= min_val then 1
760+
elseif max_val <= 0 and min_val <= max_val then -1
761+
else 0;
762+
// Flow is undecideable if either attribute is not a constant Real value.
763+
else 0;
764+
end match;
765+
end evaluateFlowDirection;
766+
833767
protected function removeStreamSetElement
834768
"This function removes the given cref from a connection set."
835769
input ComponentRef cref;
@@ -848,5 +782,26 @@ algorithm
848782
matches := ComponentRef.isEqual(cref, element.name);
849783
end compareCrefStreamSet;
850784

785+
function associatedFlowCref
786+
"Returns the flow cref that's declared in the same connector as the given
787+
stream cref."
788+
input ComponentRef streamCref;
789+
output ComponentRef flowCref;
790+
algorithm
791+
flowCref := match streamCref
792+
local
793+
InstNode flow_node;
794+
795+
// A connector with a single flow, append the flow node to the cref and return it.
796+
case ComponentRef.CREF(ty = Type.COMPLEX(complexTy = ComplexType.CONNECTOR(flows = {flow_node})))
797+
then ComponentRef.prefixCref(flow_node, InstNode.getType(flow_node), {}, streamCref);
798+
799+
// Otherwise, remove the first part of the cref and try again.
800+
case ComponentRef.CREF()
801+
then associatedFlowCref(streamCref.restCref);
802+
803+
end match;
804+
end associatedFlowCref;
805+
851806
annotation(__OpenModelica_Interface="frontend");
852807
end NFConnectEquations;

0 commit comments

Comments
 (0)