@@ -63,6 +63,7 @@ import NFBinding.Binding;
6363import NFFunction.Function ;
6464import Global ;
6565import BuiltinCall = NFBuiltinCall ;
66+ import ComplexType = NFComplexType ;
6667
6768constant 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;
431432protected
432- ComponentRef flow_cr ;
433+ ComponentRef stream_cr ;
433434algorithm
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) );
437438end streamFlowExp;
438439
439440function flowExp
@@ -443,7 +444,7 @@ function flowExp
443444protected
444445 ComponentRef flow_cr;
445446algorithm
446- Connector . CONNECTOR (associatedFlow = SOME ( flow_cr)) := element;
447+ flow_cr := associatedFlowCref( Connector . name( element)) ;
447448 flowExp := Expression . fromCref(flow_cr);
448449end flowExp;
449450
@@ -528,7 +529,7 @@ protected
528529 Option < Expression > nominal_oexp;
529530 Expression nominal_exp, flow_threshold;
530531algorithm
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;
584585algorithm
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 ;
692693end 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+
833767protected 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);
849783end 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+
851806annotation(__OpenModelica_Interface= "frontend" );
852807end NFConnectEquations ;
0 commit comments