diff --git a/Compiler/FrontEnd/ConnectUtil.mo b/Compiler/FrontEnd/ConnectUtil.mo index a6b1a1d3e71..99e16fe19dd 100644 --- a/Compiler/FrontEnd/ConnectUtil.mo +++ b/Compiler/FrontEnd/ConnectUtil.mo @@ -581,46 +581,40 @@ protected function daeVarToCrefs "Converts a DAE.Var to a list of crefs." input DAE.Var inVar; output list outCrefs; +protected + String name; + DAE.Type ty; + list crefs; + DAE.Dimensions dims; + DAE.ComponentRef cr; algorithm - outCrefs := match(inVar) - local - String name; - list vars; - list crefs; - DAE.Type ty; - DAE.Dimensions dims; - DAE.ComponentRef cr; + DAE.TYPES_VAR(name = name, ty = ty) := inVar; + ty := Types.derivedBasicType(ty); + outCrefs := match ty // Scalar - case (DAE.TYPES_VAR(name = name, ty = DAE.T_REAL())) - then {DAE.CREF_IDENT(name, DAE.T_REAL_DEFAULT, {})}; - case (DAE.TYPES_VAR(name = name, ty = DAE.T_SUBTYPE_BASIC(complexType = DAE.T_REAL()))) - then {DAE.CREF_IDENT(name, DAE.T_REAL_DEFAULT, {})}; + case DAE.T_REAL() then {DAE.CREF_IDENT(name, ty, {})}; // Complex type - case (DAE.TYPES_VAR(name = name, - ty = DAE.T_COMPLEX(varLst = vars))) - equation - crefs = List.mapFlat(vars, daeVarToCrefs); - cr = DAE.CREF_IDENT(name, DAE.T_REAL_DEFAULT, {}); - crefs = List.map1r(crefs, ComponentReference.joinCrefs, cr); + case DAE.T_COMPLEX() + algorithm + crefs := listAppend(daeVarToCrefs(v) for v in listReverse(ty.varLst)); + cr := DAE.CREF_IDENT(name, DAE.T_REAL_DEFAULT, {}); then - crefs; + list(ComponentReference.joinCrefs(cr, c) for c in crefs); // Array - case (DAE.TYPES_VAR(name = name, - ty = ty as DAE.T_ARRAY())) - equation - dims = Types.getDimensions(ty); - cr = DAE.CREF_IDENT(name, ty, {}); - crefs = expandArrayCref(cr, dims, {}); + case DAE.T_ARRAY() + algorithm + dims := Types.getDimensions(ty); + cr := DAE.CREF_IDENT(name, ty, {}); then - crefs; + expandArrayCref(cr, dims, {}); else - equation - name = Types.unparseVar(inVar); - Error.addInternalError("Unknown var " + name + " in ConnectUtil.daeVarToCrefs", sourceInfo()); + algorithm + Error.addInternalError("Unknown var " + name + + " in ConnectUtil.daeVarToCrefs", sourceInfo()); then fail(); @@ -3276,31 +3270,73 @@ public function evaluateActualStream input Connect.Sets inSets; input array inSetArray; output DAE.Exp outExp; -algorithm - outExp := match(inStreamCref, inSets, inSetArray) - local - DAE.ComponentRef flow_cr; - DAE.Exp e, flow_exp, stream_exp, instream_exp; - DAE.Type ety; - Connect.Sets sets; +protected + DAE.ComponentRef flow_cr; + DAE.Exp e, flow_exp, stream_exp, instream_exp, rel_exp; + DAE.Type ety; + Integer flow_dir; +algorithm + flow_cr := getStreamFlowAssociation(inStreamCref, inSets); + ety := ComponentReference.crefLastType(flow_cr); + flow_dir := evaluateFlowDirection(ety); + + // Select a branch if we know the flow direction, otherwise generate the whole + // if-equation. + if flow_dir == 1 then + rel_exp := evaluateInStream(inStreamCref, (true, false, inSets, inSetArray)); + elseif flow_dir == -1 then + rel_exp := Expression.crefExp(inStreamCref); + else + flow_exp := Expression.crefExp(flow_cr); + stream_exp := Expression.crefExp(inStreamCref); + instream_exp := evaluateInStream(inStreamCref, (true, false, inSets, inSetArray)); + rel_exp := DAE.IFEXP( + DAE.RELATION(flow_exp, DAE.GREATER(ety), DAE.RCONST(0.0), -1, NONE()), + instream_exp, stream_exp); + end if; + + // actualStream(stream_var) = smooth(0, if flow_var > 0 then inStream(stream_var) + // else stream_var); + outExp := DAE.CALL(Absyn.IDENT("smooth"), {DAE.ICONST(0), rel_exp}, + DAE.callAttrBuiltinReal); +end evaluateActualStream; - case (_, _, _) - equation - flow_cr = getStreamFlowAssociation(inStreamCref, inSets); - ety = ComponentReference.crefLastType(flow_cr); - flow_exp = Expression.crefExp(flow_cr); - stream_exp = Expression.crefExp(inStreamCref); - instream_exp = evaluateInStream(inStreamCref, (true, false, inSets, inSetArray)); - // actualStream(stream_var) = smooth(0, if flow_var > 0 then inStream(stream_var) - // else stream_var); - e = DAE.CALL(Absyn.IDENT("smooth"), { - DAE.ICONST(0), - DAE.IFEXP(DAE.RELATION(flow_exp, DAE.GREATER(ety), DAE.RCONST(0.0), -1, NONE()), - instream_exp, stream_exp)}, DAE.callAttrBuiltinReal); +protected function evaluateFlowDirection + "Checks the min/max attributes of a flow variables type to try and determine + the flow direction. If the flow is positive 1 is returned, if it is negative + -1, otherwise 0 if the direction can't be decided." + input DAE.Type inType; + output Integer outDirection = 0; +protected + list attr; + Option min_oval, max_oval; + Real min_val, max_val; +algorithm + attr := Types.getAttributes(inType); + if listEmpty(attr) then return; end if; + + min_oval := Types.lookupAttributeValue(attr, "min"); + max_oval := Types.lookupAttributeValue(attr, "max"); + + outDirection := match (min_oval, max_oval) + // No attributes, flow direction can't be decided. + case (NONE(), NONE()) then 0; + // Flow is positive if min is positive. + case (SOME(Values.REAL(min_val)), NONE()) + then if min_val >= 0 then 1 else 0; + // Flow is negative if max is negative. + case (NONE(), SOME(Values.REAL(max_val))) + then if max_val <= 0 then -1 else 0; + // Flow is positive if both min and max are positive, negative if they are + // both negative, otherwise undecideable. + case (SOME(Values.REAL(min_val)), SOME(Values.REAL(max_val))) then - e; + if min_val >= 0 and max_val >= min_val then 1 + elseif max_val <= 0 and min_val <= max_val then -1 + else 0; + else 0; end match; -end evaluateActualStream; +end evaluateFlowDirection; protected function evaluateCardinality input DAE.ComponentRef inCref; diff --git a/Compiler/FrontEnd/DAEUtil.mo b/Compiler/FrontEnd/DAEUtil.mo index eb119be77b5..63d340601c1 100644 --- a/Compiler/FrontEnd/DAEUtil.mo +++ b/Compiler/FrontEnd/DAEUtil.mo @@ -7174,5 +7174,16 @@ algorithm end match; end getSubscriptIndex; +public function bindingValue + input DAE.Binding inBinding; + output Option outValue; +algorithm + outValue := match inBinding + case DAE.EQBOUND() then inBinding.evaluatedExp; + case DAE.VALBOUND() then SOME(inBinding.valBound); + else NONE(); + end match; +end bindingValue; + annotation(__OpenModelica_Interface="frontend"); end DAEUtil; diff --git a/Compiler/FrontEnd/ModelicaBuiltin.mo b/Compiler/FrontEnd/ModelicaBuiltin.mo index 9ca20c6b8b1..de2be12c370 100644 --- a/Compiler/FrontEnd/ModelicaBuiltin.mo +++ b/Compiler/FrontEnd/ModelicaBuiltin.mo @@ -1365,7 +1365,7 @@ function getModelicaPath "Get the Modelica Library Path." external "builtin"; annotation(Documentation(info="

The MODELICAPATH is list of paths to search when trying to load a library. It is a string separated by colon (:) on all OSes except Windows, which uses semicolon (;).

-

To override the default path (getModelicaPath()/lib/omlibrary/:~/.openmodelica/libraries/), set the environment variable OPENMODELICALIBRARY=...

+

To override the default path (OPENMODELICAHOME/lib/omlibrary/:~/.openmodelica/libraries/), set the environment variable OPENMODELICALIBRARY=...

"), preferredView="text"); end getModelicaPath; diff --git a/Compiler/FrontEnd/Types.mo b/Compiler/FrontEnd/Types.mo index ba5186b4869..fa564dad3a2 100644 --- a/Compiler/FrontEnd/Types.mo +++ b/Compiler/FrontEnd/Types.mo @@ -260,11 +260,16 @@ Function for getting the name of a DAE.Var" input DAE.Var v; output String s; algorithm - s := match(v) - case(DAE.TYPES_VAR(name = s)) then s; - end match; + DAE.TYPES_VAR(name = s) := v; end varName; +public function varBinding + input DAE.Var inVar; + output DAE.Binding outBinding; +algorithm + DAE.TYPES_VAR(binding = outBinding) := inVar; +end varBinding; + public function varEqualName input DAE.Var inVar1; input DAE.Var inVar2; @@ -8805,5 +8810,33 @@ algorithm end match; end metaArrayElementType; +public function getAttributes + input DAE.Type inType; + output list outAttributes; +algorithm + outAttributes := match inType + case DAE.T_REAL() then inType.varLst; + case DAE.T_INTEGER() then inType.varLst; + case DAE.T_STRING() then inType.varLst; + case DAE.T_BOOL() then inType.varLst; + case DAE.T_ENUMERATION() then inType.attributeLst; + case DAE.T_SUBTYPE_BASIC() then getAttributes(inType.complexType); + else {}; + end match; +end getAttributes; + +public function lookupAttributeValue + input list inAttributes; + input String inName; + output Option outValue = NONE(); +algorithm + for attr in inAttributes loop + if inName == varName(attr) then + outValue := DAEUtil.bindingValue(varBinding(attr)); + break; + end if; + end for; +end lookupAttributeValue; + annotation(__OpenModelica_Interface="frontend"); end Types; diff --git a/Makefile.common b/Makefile.common index 8068a217bd6..129397ec10f 100644 --- a/Makefile.common +++ b/Makefile.common @@ -410,6 +410,8 @@ git-clean: git-sanity-check: git-clean test "./Compiler/boot/bootstrap-sources.tar.xz" = `find . -type f -size +684k | grep -v 3rdParty` + git rev-list origin/master..HEAD | grep -q ^ for commit in `git rev-list origin/master..HEAD`; do \ - (! git ls-tree --name-only -r $$commit | egrep "(.*[.](html|png|o|so|a|dll|exe|log|db|zip|DS_Store)$$)|SimulationRuntime/cpp/Doc" || exit 1) \ + (! git ls-tree --name-only -r $$commit | egrep "(.*[.](html|png|svg|o|so|la|stamp|a|dll|exe|cab|lnk|msi|log|class|jar|pyc|db|zip|DS_Store|pdf|tex|md5|dep)$$)|SimulationRuntime/cpp/Doc" || exit 1) \ done + ! (git rev-list origin/master..HEAD | xargs git grep "Generated by Susan" -- Compiler/Template)