Skip to content

Commit 1daea97

Browse files
committed
- Fix initialization of dependent parameters
- Detect cyclically dependent parameters - except for some special cases, e.g. parameter Real p = 2p; git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23848 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 1bc9fc0 commit 1daea97

File tree

4 files changed

+244
-44
lines changed

4 files changed

+244
-44
lines changed

Compiler/BackEnd/BackendDAE.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ uniontype Var "variables"
199199
.DAE.InstDims arryDim "array dimensions of non-expanded var";
200200
.DAE.ElementSource source "origin of variable";
201201
Option< .DAE.VariableAttributes> values "values on built-in attributes";
202-
Option<TearingSelect> tearingSelectOption "value for TearingSelect";
202+
Option<TearingSelect> tearingSelectOption "value for TearingSelect";
203203
Option<SCode.Comment> comment "this contains the comment and annotation from Absyn";
204204
.DAE.ConnectorType connectorType "flow, stream, unspecified or not connector.";
205205
end VAR;

Compiler/BackEnd/BackendVariable.mo

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ public function varStartValue "author: PA
256256
protected
257257
Option<DAE.VariableAttributes> attr;
258258
algorithm
259-
BackendDAE.VAR(values = attr) := v;
259+
BackendDAE.VAR(values=attr) := v;
260260
sv := DAEUtil.getStartAttr(attr);
261261
end varStartValue;
262262

@@ -2341,8 +2341,7 @@ public function varsSize
23412341
input BackendDAE.Variables inVariables;
23422342
output Integer outNumVariables;
23432343
algorithm
2344-
BackendDAE.VARIABLES(varArr = BackendDAE.VARIABLE_ARRAY(numberOfElements =
2345-
outNumVariables)) := inVariables;
2344+
BackendDAE.VARIABLES(varArr=BackendDAE.VARIABLE_ARRAY(numberOfElements=outNumVariables)) := inVariables;
23462345
end varsSize;
23472346

23482347
protected function varsLoadFactor
@@ -2901,7 +2900,7 @@ public function getVarAt
29012900
protected
29022901
BackendDAE.VariableArray arr;
29032902
algorithm
2904-
BackendDAE.VARIABLES(varArr = arr) := inVariables;
2903+
BackendDAE.VARIABLES(varArr=arr) := inVariables;
29052904
outVar := vararrayNth(arr, inIndex);
29062905
end getVarAt;
29072906

Compiler/BackEnd/Initialization.mo

Lines changed: 202 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ end solveInitialSystemEqSystem;
316316
// section for inlining when-clauses
317317
//
318318
// This section contains all the helper functions to replace all when-clauses
319-
// from a given BackenDAE to get the initial equation system.
319+
// from a given BackendDAE to get the initial equation system.
320320
// =============================================================================
321321

322322
protected function inlineWhenForInitialization "author: lochel
@@ -836,7 +836,7 @@ end warnAboutEqns2;
836836
// section for selecting initialization variables
837837
//
838838
// - unfixed state
839-
// - unfixed parameter (TODO: change this to secondary parameter)
839+
// - secondary parameter
840840
// - unfixed discrete -> pre(vd)
841841
// =============================================================================
842842

@@ -846,14 +846,152 @@ protected function selectInitializationVariablesDAE "author: lochel
846846
output BackendDAE.Variables outVars;
847847
protected
848848
list<BackendDAE.EqSystem> systs;
849-
BackendDAE.Variables knownVars, alias;
849+
BackendDAE.Variables knownVars, alias, allParameters;
850+
BackendDAE.EquationArray allParameterEqns;
851+
BackendDAE.EqSystem paramSystem;
852+
BackendDAE.IncidenceMatrix m, mT;
853+
array<Integer> ass1 "vecVarsToEq";
854+
array<Integer> ass2 "vecEqsToVar";
855+
list<list<Integer>> comps;
856+
list<Integer> flatComps;
857+
Integer nParam;
858+
array<Integer> secondary;
859+
Integer i;
860+
BackendDAE.Var p;
850861
algorithm
851862
BackendDAE.DAE(systs, BackendDAE.SHARED(knownVars=knownVars, aliasVars=alias)) := inDAE;
852863
outVars := selectInitializationVariables(systs);
853864
outVars := BackendVariable.traverseBackendDAEVars(knownVars, selectInitializationVariables2, outVars);
854865
outVars := BackendVariable.traverseBackendDAEVars(alias, selectInitializationVariables2, outVars);
866+
867+
// select all parameters
868+
allParameters := BackendVariable.emptyVars();
869+
allParameterEqns := BackendEquation.emptyEqns();
870+
(allParameters, allParameterEqns) := BackendVariable.traverseBackendDAEVars(knownVars, selectParameter2, (allParameters, allParameterEqns));
871+
nParam := BackendVariable.varsSize(allParameters);
872+
873+
if nParam > 0 then
874+
// BackendDump.dumpVariables(allParameters, "all parameters");
875+
// BackendDump.dumpEquationArray(allParameterEqns, "all parameter equations");
876+
877+
paramSystem := BackendDAE.EQSYSTEM(allParameters, allParameterEqns, NONE(), NONE(), BackendDAE.NO_MATCHING(), {}, BackendDAE.UNKNOWN_PARTITION());
878+
(_, m, mT, _, _) := BackendDAEUtil.getIncidenceMatrixScalar(paramSystem, BackendDAE.SOLVABLE(), NONE());
879+
// BackendDump.dumpIncidenceMatrix(m);
880+
// BackendDump.dumpIncidenceMatrix(mT);
881+
882+
// match the system (nVars+nAddVars == nEqns+nAddEqs)
883+
ass1 := arrayCreate(nParam, -1);
884+
ass2 := arrayCreate(nParam, -1);
885+
Matching.matchingExternalsetIncidenceMatrix(nParam, nParam, m);
886+
BackendDAEEXT.matching(nParam, nParam, 5, 0, 0.0, 1);
887+
BackendDAEEXT.getAssignment(ass2, ass1);
888+
// BackendDump.dumpMatchingVars(ass1);
889+
// BackendDump.dumpMatchingEqns(ass2);
890+
891+
comps := BackendDAETransform.tarjanAlgorithm(mT, ass2);
892+
// BackendDump.dumpComponentsOLD(comps);
893+
comps := mapListIndices(comps, ass2) "map to var indices" ;
894+
// BackendDump.dumpComponentsOLD(comps);
895+
896+
// flattern list and look for cyclic dependencies
897+
flatComps := flatternParamComps(comps, {}, allParameters);
898+
// BackendDump.dumpComponentsOLD({flatComps});
899+
900+
// select secondary parameters
901+
secondary := arrayCreate(nParam, 0);
902+
secondary := selectSecondaryParameters(flatComps, allParameters, mT, secondary);
903+
// BackendDump.dumpMatchingVars(secondary);
904+
905+
// get secondary parameters
906+
for i in 1:nParam loop
907+
if 1 == secondary[i] then
908+
p := BackendVariable.getVarAt(allParameters, i);
909+
outVars := BackendVariable.addVar(p, outVars);
910+
end if;
911+
end for;
912+
end if;
855913
end selectInitializationVariablesDAE;
856914

915+
protected function markIndex
916+
input Integer inIndex;
917+
input array<Integer> inArray;
918+
output array<Integer> outArray := inArray;
919+
algorithm
920+
arrayUpdate(outArray, inIndex, 1);
921+
end markIndex;
922+
923+
protected function selectSecondaryParameters
924+
input list<Integer> inOrdering;
925+
input BackendDAE.Variables inParameters;
926+
input BackendDAE.IncidenceMatrix inM;
927+
input array<Integer> inSecondaryParams;
928+
output array<Integer> outSecondaryParams;
929+
algorithm
930+
outSecondaryParams := matchcontinue(inOrdering)
931+
local
932+
Integer i;
933+
array<Integer> secondaryParams;
934+
list<Integer> rest;
935+
BackendDAE.Var param;
936+
937+
case {}
938+
then inSecondaryParams;
939+
940+
// fixed=false
941+
case i::rest equation
942+
param = BackendVariable.getVarAt(inParameters, i);
943+
false = BackendVariable.varFixed(param);
944+
945+
secondaryParams = List.fold(inM[i], markIndex, inSecondaryParams);
946+
secondaryParams = selectSecondaryParameters(rest, inParameters, inM, secondaryParams);
947+
then secondaryParams;
948+
949+
// fixed=true, but dependent
950+
case i::rest equation
951+
1 = inSecondaryParams[i];
952+
953+
secondaryParams = List.fold(inM[i], markIndex, inSecondaryParams);
954+
secondaryParams = selectSecondaryParameters(rest, inParameters, inM, secondaryParams);
955+
then secondaryParams;
956+
957+
// primary
958+
else inSecondaryParams;
959+
end matchcontinue;
960+
end selectSecondaryParameters;
961+
962+
protected function flatternParamComps
963+
input list<list<Integer>> inComps;
964+
input list<Integer> inFlatComps;
965+
input BackendDAE.Variables inAllParameters;
966+
output list<Integer> outFlatComps;
967+
algorithm
968+
outFlatComps := match(inComps)
969+
local
970+
Integer i;
971+
list<list<Integer>> rest;
972+
list<Integer> rest2;
973+
list<Integer> paramIndices;
974+
list<BackendDAE.Var> paramLst;
975+
BackendDAE.Var param;
976+
977+
case {}
978+
then listReverse(inFlatComps);
979+
980+
case {i}::rest equation
981+
rest2 = flatternParamComps(rest, inFlatComps, inAllParameters);
982+
then i::rest2;
983+
984+
case paramIndices::rest algorithm
985+
paramLst := {};
986+
for i in paramIndices loop
987+
param := BackendVariable.getVarAt(inAllParameters, i);
988+
paramLst := param::paramLst;
989+
end for;
990+
Error.addCompilerError("Cyclically dependent parameters found:\n" + warnAboutVars2(paramLst));
991+
then fail();
992+
end match;
993+
end flatternParamComps;
994+
857995
protected function selectInitializationVariables "author: lochel"
858996
input list<BackendDAE.EqSystem> inEqSystems;
859997
output BackendDAE.Variables outVars;
@@ -873,6 +1011,44 @@ algorithm
8731011
outVars := BackendVariable.traverseBackendDAEVars(orderedVars, selectInitializationVariables2, inVars);
8741012
end selectInitializationVariables1;
8751013

1014+
protected function selectParameter2 "author: lochel"
1015+
input BackendDAE.Var inVar;
1016+
input tuple<BackendDAE.Variables, BackendDAE.EquationArray> inTpl;
1017+
output BackendDAE.Var outVar := inVar;
1018+
output tuple<BackendDAE.Variables, BackendDAE.EquationArray> outTpl;
1019+
algorithm
1020+
outTpl := match (inVar, inTpl)
1021+
local
1022+
BackendDAE.Variables vars;
1023+
BackendDAE.EquationArray eqns;
1024+
DAE.Exp bindExp, crefExp;
1025+
BackendDAE.Equation eqn;
1026+
DAE.ComponentRef cref;
1027+
1028+
// parameter without binding
1029+
case (BackendDAE.VAR(varKind=BackendDAE.PARAM(), bindExp=NONE()), (vars, eqns)) equation
1030+
vars = BackendVariable.addVar(inVar, vars);
1031+
1032+
cref = BackendVariable.varCref(inVar);
1033+
crefExp = Expression.crefExp(cref);
1034+
eqn = BackendDAE.EQUATION(crefExp, DAE.RCONST(0.0), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
1035+
eqns = BackendEquation.addEquation(eqn, eqns);
1036+
then ((vars, eqns));
1037+
1038+
// parameter with binding
1039+
case (BackendDAE.VAR(varKind=BackendDAE.PARAM(), bindExp=SOME(bindExp)), (vars, eqns)) equation
1040+
vars = BackendVariable.addVar(inVar, vars);
1041+
1042+
cref = BackendVariable.varCref(inVar);
1043+
crefExp = Expression.crefExp(cref);
1044+
eqn = BackendDAE.EQUATION(crefExp, bindExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
1045+
eqns = BackendEquation.addEquation(eqn, eqns);
1046+
then ((vars, eqns));
1047+
1048+
else inTpl;
1049+
end match;
1050+
end selectParameter2;
1051+
8761052
protected function selectInitializationVariables2 "author: lochel"
8771053
input BackendDAE.Var inVar;
8781054
input BackendDAE.Variables inVars;
@@ -893,12 +1069,6 @@ algorithm
8931069
vars = BackendVariable.addVar(inVar, vars);
8941070
then (inVar, vars);
8951071

896-
// unfixed parameter
897-
case (BackendDAE.VAR(varKind=BackendDAE.PARAM()), vars) equation
898-
false = BackendVariable.varFixed(inVar);
899-
vars = BackendVariable.addVar(inVar, vars);
900-
then (inVar, vars);
901-
9021072
// unfixed discrete -> pre(vd)
9031073
case (BackendDAE.VAR(varName=cr, varKind=BackendDAE.DISCRETE(), varType=ty, arryDim=arryDim), vars) equation
9041074
false = BackendVariable.varFixed(inVar);
@@ -1594,6 +1764,15 @@ algorithm
15941764
outIndices := List.map1(inIndices, mapIndex, inMapping);
15951765
end mapIndices;
15961766

1767+
protected function mapListIndices "author: lochel
1768+
This function applies 'inMapping' to the input index list list."
1769+
input list<list<Integer>> inListIndices;
1770+
input array<Integer> inMapping;
1771+
output list<list<Integer>> outListIndices;
1772+
algorithm
1773+
outListIndices := List.map1(inListIndices, mapIndices, inMapping);
1774+
end mapListIndices;
1775+
15971776
protected function compsMarker "author: mwenzler"
15981777
input Integer inUnassignedEqn;
15991778
input array<Integer> inVecVarToEq;
@@ -1815,7 +1994,7 @@ algorithm
18151994
nEqns = BackendDAEUtil.equationSize(inEqnsOrig);
18161995
true = intGt(counter, nEqns-nVars);
18171996

1818-
Error.addCompilerError("Initialization problem is structural singular. Please, check the initial conditions." );
1997+
Error.addCompilerError("Initialization problem is structural singular. Please, check the initial conditions.");
18191998
then ({}, true, {});
18201999

18212000
case (currID, _, _, _, _, _, _, _) equation
@@ -2055,7 +2234,7 @@ algorithm
20552234
DAE.InstDims arryDim;
20562235
Option<DAE.Exp> startValue;
20572236
DAE.Exp startValue_;
2058-
DAE.Exp startExp, bindExp, crefExp;
2237+
DAE.Exp startExp, bindExp, crefExp, e;
20592238
BackendDAE.VarKind varKind;
20602239
HashSet.HashSet hs;
20612240
String s, str, sv;
@@ -2071,7 +2250,9 @@ algorithm
20712250
//startExp = Expression.makePureBuiltinCall("$_start", {crefExp}, ty);
20722251
startExp = BackendVariable.varStartValue(var);
20732252
eqn = BackendDAE.EQUATION(crefExp, startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2074-
eqns = if isFixed then BackendEquation.addEquation(eqn, eqns) else eqns;
2253+
if isFixed then
2254+
eqns = BackendEquation.addEquation(eqn, eqns);
2255+
end if;
20752256

20762257
var = BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
20772258

@@ -2143,16 +2324,22 @@ algorithm
21432324
case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.PARAM(), bindExp=NONE()), (vars, fixvars, eqns, hs)) equation
21442325
true = BackendVariable.varFixed(var);
21452326
startExp = BackendVariable.varStartValueType(var);
2327+
2328+
s = ComponentReference.printComponentRefStr(cr);
2329+
str = ExpressionDump.printExpStr(startExp);
2330+
2331+
// e = Expression.crefExp(cr);
2332+
// ty = Expression.typeof(e);
2333+
// startExp = Expression.makePureBuiltinCall("$_start", {e}, ty);
2334+
21462335
var = BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
21472336
var = BackendVariable.setBindExp(var, SOME(startExp));
21482337
var = BackendVariable.setVarFixed(var, true);
21492338

2150-
s = ComponentReference.printComponentRefStr(cr);
2151-
str = ExpressionDump.printExpStr(startExp);
21522339
info = DAEUtil.getElementSourceFileInfo(BackendVariable.getVarSource(var));
21532340
Error.addSourceMessage(Error.UNBOUND_PARAMETER_WITH_START_VALUE_WARNING, {s, str}, info);
21542341

2155-
vars = BackendVariable.addVar(var, vars);
2342+
//vars = BackendVariable.addVar(var, vars);
21562343
then (var, (vars, fixvars, eqns, hs));
21572344

21582345
// parameter with binding and fixed=false

0 commit comments

Comments
 (0)