Skip to content

Commit

Permalink
Revised implementation of analyzeInitialSystem
Browse files Browse the repository at this point in the history
* Removed unnecessary matchcontinue statement
* Added new flag +maxMixedDeterminedIndex
  • Loading branch information
lochel authored and OpenModelica-Hudson committed Oct 5, 2015
1 parent a030088 commit 7c88a18
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 148 deletions.
246 changes: 99 additions & 147 deletions Compiler/BackEnd/Initialization.mo
Expand Up @@ -1103,7 +1103,7 @@ algorithm
end for;
dae := BackendDAE.DAE(eqs, initDAE.shared);

(outDAE, (_, _, outDumpVars, outRemovedEqns)) := BackendDAEUtil.mapEqSystemAndFold(dae, analyzeInitialSystem2, (inDAE, inInitVars, {}, outRemovedEqns));
(outDAE, (_, _, outDumpVars, outRemovedEqns)) := BackendDAEUtil.mapEqSystemAndFold(dae, fixInitialSystem, (inDAE, inInitVars, {}, outRemovedEqns));
end analyzeInitialSystem;

protected function getInitEqIndex
Expand All @@ -1119,85 +1119,20 @@ algorithm
outTpl := (pos+1, lst);
end getInitEqIndex;

protected function analyzeInitialSystem2 "author: lochel"
protected function fixInitialSystem "author: lochel
This function handles under-, over-, and mixed-determined systems with a given index."
input BackendDAE.EqSystem inEqSystem;
input BackendDAE.Shared inShared;
input tuple<BackendDAE.BackendDAE, BackendDAE.Variables, list<BackendDAE.Var>, list<BackendDAE.Equation>> inTpl;
output BackendDAE.EqSystem outEqSystem;
output BackendDAE.Shared outShared = inShared;
output tuple<BackendDAE.BackendDAE, BackendDAE.Variables, list<BackendDAE.Var>, list<BackendDAE.Equation>> outTpl;
algorithm
outTpl := matchcontinue inTpl
local
BackendDAE.BackendDAE inDAE;
BackendDAE.EquationArray eqns2;
BackendDAE.Variables initVars;
list<BackendDAE.Var> dumpVars, dumpVars2;
list<BackendDAE.Equation> removedEqns, removedEqns2;

// (regular) determined system
case ((inDAE, initVars, dumpVars, removedEqns)) equation
// print("index-0 start\n");
(eqns2, dumpVars2, removedEqns2) = fixInitialSystem(inEqSystem.orderedVars, inEqSystem.orderedEqs, initVars, inShared, 0);
// print("index-0 ende\n");

// add dummy var + dummy eqn
dumpVars = listAppend(dumpVars, dumpVars2);
removedEqns = listAppend(removedEqns, removedEqns2);
outEqSystem = BackendDAEUtil.setEqSystEqs(inEqSystem, eqns2);
then ((inDAE, initVars, dumpVars, removedEqns));

// (index-1) mixed-determined system
case ((inDAE, initVars, dumpVars, removedEqns)) equation
// print("index-1 start\n");
(eqns2, dumpVars2, removedEqns2) = fixInitialSystem(inEqSystem.orderedVars, inEqSystem.orderedEqs, initVars, inShared, 1);
// print("index-1 ende\n");

// add dummy var + dummy eqn
dumpVars = listAppend(dumpVars, dumpVars2);
removedEqns = listAppend(removedEqns, removedEqns2);
outEqSystem = BackendDAEUtil.setEqSystEqs(inEqSystem, eqns2);
then ((inDAE, initVars, dumpVars, removedEqns));

// (index-2) mixed-determined system
case ((inDAE, initVars, dumpVars, removedEqns)) equation
// print("index-2 start\n");
(eqns2, dumpVars2, removedEqns2) = fixInitialSystem(inEqSystem.orderedVars, inEqSystem.orderedEqs, initVars, inShared, 2);
// print("index-2 ende\n");

// add dummy var + dummy eqn
dumpVars = listAppend(dumpVars, dumpVars2);
removedEqns = listAppend(removedEqns, removedEqns2);
outEqSystem = BackendDAEUtil.setEqSystEqs(inEqSystem, eqns2);
then ((inDAE, initVars, dumpVars, removedEqns));

// (index-3) mixed-determined system
case ((inDAE, initVars, dumpVars, removedEqns)) equation
// print("index-3 start\n");
(eqns2, dumpVars2, removedEqns2) = fixInitialSystem(inEqSystem.orderedVars, inEqSystem.orderedEqs, initVars, inShared, 3);
// print("index-3 ende\n");

// add dummy var + dummy eqn
dumpVars = listAppend(dumpVars, dumpVars2);
removedEqns = listAppend(removedEqns, removedEqns2);
outEqSystem = BackendDAEUtil.setEqSystEqs(inEqSystem, eqns2);
then ((inDAE, initVars, dumpVars, removedEqns));

else fail();
end matchcontinue;
end analyzeInitialSystem2;

protected function fixInitialSystem "author: lochel
This function handles under-, over-, and mixed-determined systems with a given index."
input BackendDAE.Variables inVars;
input BackendDAE.EquationArray inEqns;
input BackendDAE.Variables inInitVars;
input BackendDAE.Shared inShared;
input Integer inIndex "index of the system (0 is regular)";
output BackendDAE.EquationArray outEqns;
output list<BackendDAE.Var> outDumpVars;
output list<BackendDAE.Equation> outRemovedEqns;
protected
BackendDAE.BackendDAE inDAE;
BackendDAE.EquationArray eqns2;
BackendDAE.Variables initVars;
list<BackendDAE.Var> dumpVars, dumpVars2;
list<BackendDAE.Equation> removedEqns, removedEqns2;
Integer nVars, nEqns, nInitEqs, nAddEqs, nAddVars;
list<Integer> stateIndices, range, initEqsIndices, redundantEqns;
list<BackendDAE.Var> initVarList;
Expand All @@ -1209,81 +1144,98 @@ protected
BackendDAE.AdjacencyMatrixEnhanced me;
array<Integer> mapIncRowEqn;
Boolean perfectMatching;
algorithm
// nVars = nEqns
nVars := BackendVariable.varsSize(inVars);
nEqns := BackendDAEUtil.equationSize(inEqns);
syst := BackendDAEUtil.createEqSystem(inVars, inEqns);
funcs := BackendDAEUtil.getFunctions(inShared);
(m_, _, _, mapIncRowEqn) := BackendDAEUtil.incidenceMatrixScalar(syst, BackendDAE.SOLVABLE(), SOME(funcs));
//BackendDump.dumpEqSystem(syst, "fixInitialSystem");
//BackendDump.dumpVariables(inInitVars, "selected initialization variables");
//BackendDump.dumpIncidenceMatrix(m_);

// get state-index list
stateIndices := BackendVariable.getVarIndexFromVariables(inInitVars, inVars);
//print("{" + stringDelimitList(List.map(stateIndices, intString), ",") + "}\n");

// get initial equation-index list
//(initEqs, _) := List.extractOnTrue(BackendEquation.equationList(inEqns), BackendEquation.isInitialEquation);
//nInitEqs := BackendDAEUtil.equationSize(BackendEquation.listEquation(initEqs));
((_, initEqsIndices)) := List.fold(BackendEquation.equationList(inEqns), getInitEqIndex, (1, {}));
nInitEqs := listLength(initEqsIndices);
//print("{" + stringDelimitList(List.map(initEqsIndices, intString), ",") + "}\n");

// modify incidence matrix for under-determined systems
nAddEqs := intMax(nVars-nEqns + inIndex, inIndex);
//print("nAddEqs: " + intString(nAddEqs) + "\n");
m_ := fixUnderDeterminedSystem(m_, stateIndices, nEqns, nAddEqs);
m := arrayCopy(m_) "deep copy";

// modify incidence matrix for over-determined systems
nAddVars := intMax(nEqns-nVars + inIndex, inIndex);
//print("nAddVars: " + intString(nAddVars) + "\n");
m := fixOverDeterminedSystem(m, initEqsIndices, nVars, nAddVars);

// match the system (nVars+nAddVars == nEqns+nAddEqs)
ass1 := arrayCreate(nVars+nAddVars, -1);
ass2 := arrayCreate(nEqns+nAddEqs, -1);
Matching.matchingExternalsetIncidenceMatrix(nVars+nAddVars, nEqns+nAddEqs, m);
BackendDAEEXT.matching(nVars+nAddVars, nEqns+nAddEqs, 5, 0, 0.0, 1);
BackendDAEEXT.getAssignment(ass2, ass1);
perfectMatching := listEmpty(Matching.getUnassigned(nVars+nAddVars, ass1, {}));
// (ass1, ass2, perfectMatching) := Matching.RegularMatching(m, nVars+nAddVars, nEqns+nAddEqs);
//BackendDump.dumpMatchingVars(ass1);
//BackendDump.dumpMatchingEqns(ass2);

// check whether or not a complete matching was found
if not perfectMatching then
Error.addCompilerNotification("The given system is mixed-determined. [index > " + intString(inIndex) + "]");
//BackendDump.dumpEqSystem(syst, "The given system is mixed-determined. [index > " + intString(inIndex) + "]");
fail();
end if;
Integer maxMixedDeterminedIndex = intMax(0, Flags.getConfigInt(Flags.MAX_MIXED_DETERMINED_INDEX));
algorithm
for index in 0:maxMixedDeterminedIndex loop
//print("index-" + intString(index) + " start\n");

((inDAE, initVars, dumpVars, removedEqns)) := inTpl;

// nVars = nEqns
nVars := BackendVariable.varsSize(inEqSystem.orderedVars);
nEqns := BackendDAEUtil.equationSize(inEqSystem.orderedEqs);
syst := BackendDAEUtil.createEqSystem(inEqSystem.orderedVars, inEqSystem.orderedEqs);
funcs := BackendDAEUtil.getFunctions(inShared);
(m_, _, _, mapIncRowEqn) := BackendDAEUtil.incidenceMatrixScalar(syst, BackendDAE.SOLVABLE(), SOME(funcs));
//BackendDump.dumpEqSystem(syst, "fixInitialSystem");
//BackendDump.dumpVariables(initVars, "selected initialization variables");
//BackendDump.dumpIncidenceMatrix(m_);

// get state-index list
stateIndices := BackendVariable.getVarIndexFromVariables(initVars, inEqSystem.orderedVars);
//print("{" + stringDelimitList(List.map(stateIndices, intString), ",") + "}\n");

// get initial equation-index list
//(initEqs, _) := List.extractOnTrue(BackendEquation.equationList(inEqSystem.orderedEqs), BackendEquation.isInitialEquation);
//nInitEqs := BackendDAEUtil.equationSize(BackendEquation.listEquation(initEqs));
((_, initEqsIndices)) := List.fold(BackendEquation.equationList(inEqSystem.orderedEqs), getInitEqIndex, (1, {}));
nInitEqs := listLength(initEqsIndices);
//print("{" + stringDelimitList(List.map(initEqsIndices, intString), ",") + "}\n");

// modify incidence matrix for under-determined systems
nAddEqs := intMax(nVars-nEqns + index, index);
//print("nAddEqs: " + intString(nAddEqs) + "\n");
m_ := fixUnderDeterminedSystem(m_, stateIndices, nEqns, nAddEqs);
m := arrayCopy(m_) "deep copy";

// modify incidence matrix for over-determined systems
nAddVars := intMax(nEqns-nVars + index, index);
//print("nAddVars: " + intString(nAddVars) + "\n");
m := fixOverDeterminedSystem(m, initEqsIndices, nVars, nAddVars);

// match the system (nVars+nAddVars == nEqns+nAddEqs)
ass1 := arrayCreate(nVars+nAddVars, -1);
ass2 := arrayCreate(nEqns+nAddEqs, -1);
Matching.matchingExternalsetIncidenceMatrix(nVars+nAddVars, nEqns+nAddEqs, m);
BackendDAEEXT.matching(nVars+nAddVars, nEqns+nAddEqs, 5, 0, 0.0, 1);
BackendDAEEXT.getAssignment(ass2, ass1);
perfectMatching := listEmpty(Matching.getUnassigned(nVars+nAddVars, ass1, {}));
// (ass1, ass2, perfectMatching) := Matching.RegularMatching(m, nVars+nAddVars, nEqns+nAddEqs);
//BackendDump.dumpMatchingVars(ass1);
//BackendDump.dumpMatchingEqns(ass2);

// check whether or not a complete matching was found
if perfectMatching then
if index > 0 then
Error.addCompilerNotification("The given system is mixed-determined. [index = " + intString(index) + "]");
end if;
// map artificial variables to redundant equations
range := if nAddVars > 0 then List.intRange2(nVars+1, nVars+nAddVars) else {};
redundantEqns := mapIndices(range, ass1);
//print("{" + stringDelimitList(List.map(redundantEqns, intString), ",") + "}\n");

// symbolic consistency check
(me, _, _, _) := BackendDAEUtil.getAdjacencyMatrixEnhancedScalar(syst, inShared, false);
(_, _, _) := consistencyCheck(redundantEqns, inEqSystem.orderedEqs, inEqSystem.orderedVars, inShared, nAddVars, m_, me, ass1, ass2, mapIncRowEqn);

// remove redundant equations
removedEqns2 := BackendEquation.getEqns(redundantEqns, inEqSystem.orderedEqs);
//BackendDump.dumpEquationList(removedEqns2, "removed equations");
eqns2 := BackendEquation.equationDelete(inEqSystem.orderedEqs, redundantEqns);
//BackendDump.dumpEquationArray(eqns2, "remaining equations");

// map artificial equations to unfixed states
range := if nAddEqs > 0 then List.intRange2(nEqns+1, nEqns+nAddEqs) else {};
range := mapIndices(range, ass2);
//print("{" + stringDelimitList(List.map(range, intString), ",") + "}\n");

// introduce additional initial equations
initVarList := List.map1r(range, BackendVariable.getVarAt, inEqSystem.orderedVars);
(eqns2, dumpVars2) := addStartValueEquations(initVarList, eqns2, {});
//BackendDump.dumpEquationArray(eqns2, "remaining equations");

// map artificial variables to redundant equations
range := if nAddVars > 0 then List.intRange2(nVars+1, nVars+nAddVars) else {};
redundantEqns := mapIndices(range, ass1);
//print("{" + stringDelimitList(List.map(redundantEqns, intString), ",") + "}\n");

// symbolic consistency check
(me, _, _, _) := BackendDAEUtil.getAdjacencyMatrixEnhancedScalar(syst, inShared, false);
(_, _, _) := consistencyCheck(redundantEqns, inEqns, inVars, inShared, nAddVars, m_, me, ass1, ass2, mapIncRowEqn);

// remove redundant equations
outRemovedEqns := BackendEquation.getEqns(redundantEqns, inEqns);
//BackendDump.dumpEquationList(outRemovedEqns, "removed equations");
outEqns := BackendEquation.equationDelete(inEqns, redundantEqns);
//BackendDump.dumpEquationArray(outEqns, "remaining equations");

// map artificial equations to unfixed states
range := if nAddEqs > 0 then List.intRange2(nEqns+1, nEqns+nAddEqs) else {};
range := mapIndices(range, ass2);
//print("{" + stringDelimitList(List.map(range, intString), ",") + "}\n");

// introduce additional initial equations
initVarList := List.map1r(range, BackendVariable.getVarAt, inVars);
(outEqns, outDumpVars) := addStartValueEquations(initVarList, outEqns, {});
//BackendDump.dumpEquationArray(outEqns, "remaining equations");
// add dummy var + dummy eqn
dumpVars := listAppend(dumpVars, dumpVars2);
removedEqns := listAppend(removedEqns, removedEqns2);
outEqSystem := BackendDAEUtil.setEqSystEqs(inEqSystem, eqns2);
//print("index-" + intString(index) + " ende\n");
outTpl := ((inDAE, initVars, dumpVars, removedEqns));
return;
end if;
//print("index-" + intString(index) + " ende\n");
end for;
Error.addCompilerError("The given system is mixed-determined. [index > " + intString(maxMixedDeterminedIndex) + "]\nPlease checkout the option \"+maxMixedDeterminedIndex\".");
fail();
end fixInitialSystem;

protected function fixUnderDeterminedSystem "author: lochel"
Expand Down
7 changes: 6 additions & 1 deletion Compiler/Util/Flags.mo
Expand Up @@ -1177,6 +1177,10 @@ constant ConfigFlag INIT_OPT_MODULES = CONFIG_FLAG(78, "initOptModules",
})),
Util.gettext("Sets the initialization optimization modules to use in the back end. See --help=optmodules for more info."));

constant ConfigFlag MAX_MIXED_DETERMINED_INDEX = CONFIG_FLAG(79, "maxMixedDeterminedIndex",
NONE(), EXTERNAL(), INT_FLAG(3), NONE(),
Util.gettext("Sets the maximum mixed-determined index that is handled by the initialization."));

protected
// This is a list of all configuration flags. A flag can not be used unless it's
// in this list, and the list is checked at initialization so that all flags are
Expand Down Expand Up @@ -1259,7 +1263,8 @@ constant list<ConfigFlag> allConfigFlags = {
FLOW_THRESHOLD,
MATRIX_FORMAT,
PARTLINTORN,
INIT_OPT_MODULES
INIT_OPT_MODULES,
MAX_MIXED_DETERMINED_INDEX
};

public function new
Expand Down

0 comments on commit 7c88a18

Please sign in to comment.