Skip to content

Commit

Permalink
Improve Error.STRUCT_SINGULAR_SYSTEM
Browse files Browse the repository at this point in the history
  • Loading branch information
lochel committed Jul 19, 2019
1 parent 00048f4 commit 363c1e2
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 119 deletions.
67 changes: 32 additions & 35 deletions OMCompiler/Compiler/BackEnd/BackendDAEUtil.mo
Expand Up @@ -7339,49 +7339,46 @@ protected function causalizeDAEWork "
output Option<BackendDAE.StructurallySingularSystemHandlerArg> oArg;
output Boolean oCausalized;
algorithm
(osyst,oshared,oArg,oCausalized) := matchcontinue (isyst,ishared,inMatchingOptions,matchingAlgorithm,stateDeselection,iCausalized)
(osyst,oshared,oArg,oCausalized) := matchcontinue (isyst,matchingAlgorithm,stateDeselection)
local
String str,mAmethodstr,str1;
BackendDAE.MatchingOptions match_opts;
BackendDAEFunc.matchingAlgorithmFunc matchingAlgorithmfunc;
array<Integer> mapIncRowEqn;
array<list<Integer>> mapEqnIncRow;
BackendDAE.EqSystem syst;
BackendDAE.MatchingOptions match_opts;
BackendDAE.Shared shared;
BackendDAE.StructurallySingularSystemHandlerArg arg;
BackendDAEFunc.matchingAlgorithmFunc matchingAlgorithmfunc;
BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler;
array<list<Integer>> mapEqnIncRow;
array<Integer> mapIncRowEqn;
DAE.FunctionTree funcs;
Integer nvars,neqns;
String str,mAmethodstr,str1;

case (BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING()),_,_,_,_,_)
then
(isyst,ishared,NONE(),iCausalized);

case (BackendDAE.EQSYSTEM(matching=BackendDAE.NO_MATCHING()),_,_,(matchingAlgorithmfunc,_),(sssHandler,_,_,_),_)
equation
// print("SystemSize: " + intString(systemSize(isyst)) + "\n");
funcs = getFunctions(ishared);
(syst,_,_,mapEqnIncRow,mapIncRowEqn) = getIncidenceMatrixScalar(isyst,BackendDAE.SOLVABLE(), SOME(funcs));
match_opts = Util.getOptionOrDefault(inMatchingOptions,(BackendDAE.INDEX_REDUCTION(), BackendDAE.EXACT()));
arg = IndexReduction.getStructurallySingularSystemHandlerArg(syst,ishared,mapEqnIncRow,mapIncRowEqn);
// check singular system
nvars = BackendVariable.daenumVariables(syst);
neqns = systemSize(syst);
syst = Causalize.singularSystemCheck(nvars,neqns,syst,match_opts,matchingAlgorithm,arg,ishared);
// execStat("transformDAE -> singularSystemCheck " + mAmethodstr);
// match the system and reduce index if neccessary
(syst,shared,arg) = matchingAlgorithmfunc(syst, ishared, false, match_opts, sssHandler, arg);
// execStat("transformDAE -> matchingAlgorithm " + mAmethodstr + " index Reduction Method " + str1);
then (syst,shared,SOME(arg),true);

case (_,_,_,(_,mAmethodstr),(_,str1,_,_),_)
equation
str = "Transformation Module " + mAmethodstr + " index Reduction Method " + str1 + " failed!";
if not isInitializationDAE(ishared) then
Error.addMessage(Error.INTERNAL_ERROR, {str});
end if;
then
fail();
case (BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING()), _, _)
then (isyst, ishared,NONE(), iCausalized);

case (BackendDAE.EQSYSTEM(matching=BackendDAE.NO_MATCHING()), (matchingAlgorithmfunc,_), (sssHandler,_,_,_)) equation
//BackendDump.dumpEqSystem(isyst, "causalizeDAEWork");
//print("SystemSize: " + intString(systemSize(isyst)));
funcs = getFunctions(ishared);
(syst,_,_,mapEqnIncRow,mapIncRowEqn) = getIncidenceMatrixScalar(isyst,BackendDAE.SOLVABLE(), SOME(funcs));
match_opts = Util.getOptionOrDefault(inMatchingOptions,(BackendDAE.INDEX_REDUCTION(), BackendDAE.EXACT()));
arg = IndexReduction.getStructurallySingularSystemHandlerArg(syst,ishared,mapEqnIncRow,mapIncRowEqn);
// check singular system
nvars = BackendVariable.daenumVariables(syst);
neqns = systemSize(syst);
syst = Causalize.singularSystemCheck(nvars,neqns,syst,match_opts,matchingAlgorithm,arg,ishared);
// execStat("transformDAE -> singularSystemCheck " + mAmethodstr);
// match the system and reduce index if neccessary
(syst,shared,arg) = matchingAlgorithmfunc(syst, ishared, false, match_opts, sssHandler, arg);
// execStat("transformDAE -> matchingAlgorithm " + mAmethodstr + " index Reduction Method " + str1);
then (syst, shared,SOME(arg), true);

case (_, (_,mAmethodstr), (_,str1,_,_)) equation
str = "Transformation Module " + mAmethodstr + " index Reduction Method " + str1 + " failed!";
if not isInitializationDAE(ishared) then
Error.addMessage(Error.INTERNAL_ERROR, {str});
end if;
then fail();
end matchcontinue;
end causalizeDAEWork;

Expand Down
34 changes: 14 additions & 20 deletions OMCompiler/Compiler/BackEnd/BackendDump.mo
Expand Up @@ -3188,25 +3188,23 @@ public function dumpMarkedEqns
output String outString;
protected
BackendDAE.EquationArray eqns;
list<Integer> sortedeqns;
list<String> slst;
algorithm
BackendDAE.EQSYSTEM(orderedEqs = eqns) := syst;
outString := List.fold1(inIntegerLst,dumpMarkedEqns1,eqns,"");
BackendDAE.EQSYSTEM(orderedEqs=eqns) := syst;
slst := List.map1(inIntegerLst, dumpMarkedEqns1, eqns);
outString := stringDelimitList(slst, "\n");
end dumpMarkedEqns;

protected function dumpMarkedEqns1
input Integer e;
input Integer index;
input BackendDAE.EquationArray eqns;
input String inS;
output String outS;
protected
String s1,s2,s3;
BackendDAE.Equation eqn;
algorithm
eqn := BackendEquation.get(eqns, e);
s2 := equationString(eqn);
s3 := intString(e);
outS := stringAppendList({inS,s3,": ",s2,";\n"});
eqn := BackendEquation.get(eqns, index);
outS := " " + intString(index) + ": " + equationString(eqn);
end dumpMarkedEqns1;

public function dumpMarkedVarsLsts
Expand All @@ -3228,24 +3226,20 @@ protected
BackendDAE.Variables vars;
list<String> slst;
algorithm
BackendDAE.EQSYSTEM(orderedVars = vars) := syst;
slst := List.map1(inIntegerLst,dumpMarkedVars1,vars);
outString := stringDelimitList(slst,", ");
BackendDAE.EQSYSTEM(orderedVars=vars) := syst;
slst := List.map1(inIntegerLst, dumpMarkedVars1, vars);
outString := stringDelimitList(slst, "\n");
end dumpMarkedVars;

protected function dumpMarkedVars1
"Dumps only the variable names given as list of indexes to a string."
input Integer v;
input Integer index;
input BackendDAE.Variables vars;
output String outS;
protected
String s1,s2,s3;
DAE.ComponentRef cr;
BackendDAE.Var var;
algorithm
BackendDAE.VAR(varName = cr) := BackendVariable.getVarAt(vars, v);
s2 := ComponentReference.printComponentRefStr(cr);
s3 := intString(v);
outS := stringAppendList({s2,"(",s3,")"});
var := BackendVariable.getVarAt(vars, index);
outS := " " + intString(index) + ": " + varString(var);
end dumpMarkedVars1;

public function dumpMarkedVarList
Expand Down
102 changes: 39 additions & 63 deletions OMCompiler/Compiler/BackEnd/Causalize.mo
Expand Up @@ -191,74 +191,50 @@ algorithm
end match;
end freeStateAssignments;

protected function foundSingularSystem
"author: Frenkel TUD 2012-12
check if the system is singular"
input list<list<Integer>> eqns;
input Integer actualEqn;
input BackendDAE.EqSystem isyst;
input BackendDAE.Shared ishared;
input array<Integer> inAssignments1;
input array<Integer> inAssignments2;
input BackendDAE.StructurallySingularSystemHandlerArg inArg;
output list<Integer> changedEqns;
output Integer continueEqn;
output BackendDAE.EqSystem osyst;
output BackendDAE.Shared oshared;
output array<Integer> outAssignments1;
output array<Integer> outAssignments2;
output BackendDAE.StructurallySingularSystemHandlerArg outArg;
algorithm
(changedEqns,continueEqn,osyst,oshared,outAssignments1,outAssignments2,outArg) :=
match(eqns,actualEqn,isyst,ishared,inAssignments1,inAssignments2,inArg)
case ({},_,_,_,_,_,_) then ({},actualEqn,isyst,ishared,inAssignments1,inAssignments2,inArg);
case (_::_,_,_,_,_,_,_)
equation
singularSystemError(eqns,actualEqn,isyst,ishared,inAssignments1,inAssignments2,inArg);
then
fail();
end match;
end foundSingularSystem;

protected function singularSystemError
protected function foundSingularSystem "print error message if the system contains equations"
input list<list<Integer>> eqns;
input Integer actualEqn;
input BackendDAE.EqSystem isyst;
input BackendDAE.Shared ishared;
input array<Integer> inAssignments1;
input array<Integer> inAssignments2;
input BackendDAE.StructurallySingularSystemHandlerArg inArg;
output list<Integer> changedEqns = {};
input output Integer actualEqn;
input output BackendDAE.EqSystem isyst;
input output BackendDAE.Shared ishared;
input output array<Integer> inAssignments1;
input output array<Integer> inAssignments2;
input output BackendDAE.StructurallySingularSystemHandlerArg inArg;
protected
Integer n;
list<Integer> unmatched,unmatched1,vars;
String eqn_str,var_str;
DAE.ElementSource source;
SourceInfo info;
array<Integer> mapIncRowEqn;
BackendDAE.EqSystem syst;
DAE.ElementSource source;
Integer n;
list<Integer> unmatched, unmatched1, vars;
SourceInfo info;
String eqn_str, var_str;
algorithm
(_,_,_,mapIncRowEqn,_) := inArg;
n := BackendDAEUtil.systemSize(isyst);
/* for debugging
BackendDump.printEqSystem(isyst);
BackendDump.dumpMatching(inAssignments1);
BackendDump.dumpMatching(inAssignments2);
syst := BackendDAEUtil.setEqSystMatching(isyst, BackendDAE.MATCHING(inAssignments1,inAssignments2,{}));
// DumpGraphML.dumpSystem(syst,ishared,NONE(),"SingularSystem" + intString(n) + ".graphml",false);
*/
// get from scalar eqns indexes the indexes in the equation array
unmatched := List.flatten(eqns);
unmatched1 := List.map1r(unmatched,arrayGet,mapIncRowEqn);
unmatched1 := List.uniqueIntN(unmatched1,arrayLength(mapIncRowEqn));
eqn_str := BackendDump.dumpMarkedEqns(isyst, unmatched1);
vars := Matching.getUnassigned(n, inAssignments2, {});
vars := List.fold1(unmatched,getAssignedVars,inAssignments1,vars);
var_str := BackendDump.dumpMarkedVars(isyst, vars);
source := BackendEquation.markedEquationSource(isyst, listHead(unmatched1));
info := ElementSource.getElementSourceFileInfo(source);

Error.addSourceMessage(if BackendDAEUtil.isInitializationDAE(ishared) then Error.STRUCTURAL_SINGULAR_INITIAL_SYSTEM else Error.STRUCT_SINGULAR_SYSTEM, {eqn_str,var_str}, info);
end singularSystemError;
if not listEmpty(eqns) then
(_,_,_,mapIncRowEqn,_) := inArg;
n := BackendDAEUtil.systemSize(isyst);

// for debugging
// BackendDump.printEqSystem(isyst);
// BackendDump.dumpMatching(inAssignments1);
// BackendDump.dumpMatching(inAssignments2);
// syst := BackendDAEUtil.setEqSystMatching(isyst, BackendDAE.MATCHING(inAssignments1,inAssignments2,{}));
// //DumpGraphML.dumpSystem(syst,ishared,NONE(),"SingularSystem" + intString(n) + ".graphml",false);

// get from scalar eqns indexes the indexes in the equation array
unmatched := List.flatten(eqns);
unmatched1 := List.map1r(unmatched,arrayGet,mapIncRowEqn);
unmatched1 := List.uniqueIntN(unmatched1,arrayLength(mapIncRowEqn));
eqn_str := BackendDump.dumpMarkedEqns(isyst, List.sort(unmatched1, intGt));
vars := Matching.getUnassigned(n, inAssignments2, {});
vars := List.fold1(unmatched,getAssignedVars,inAssignments1,vars);
var_str := BackendDump.dumpMarkedVars(isyst, List.sort(vars, intGt));
source := BackendEquation.markedEquationSource(isyst, listHead(unmatched1));
info := ElementSource.getElementSourceFileInfo(source);

Error.addSourceMessage(if BackendDAEUtil.isInitializationDAE(ishared) then Error.STRUCTURAL_SINGULAR_INITIAL_SYSTEM else Error.STRUCT_SINGULAR_SYSTEM, {eqn_str,var_str}, info);
fail();
end if;
end foundSingularSystem;

protected function getAssignedVars
input Integer e;
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/Util/Error.mo
Expand Up @@ -196,7 +196,7 @@ public constant Message UNDERDET_EQN_SYSTEM = MESSAGE(32, SYMBOLIC(), ERROR(),
public constant Message OVERDET_EQN_SYSTEM = MESSAGE(33, SYMBOLIC(), ERROR(),
Util.gettext("Too many equations, over-determined system. The model has %s equation(s) and %s variable(s)."));
public constant Message STRUCT_SINGULAR_SYSTEM = MESSAGE(34, SYMBOLIC(), ERROR(),
Util.gettext("Model is structurally singular, error found sorting equations \n %s for variables \n %s"));
Util.gettext("Model is structurally singular, error found sorting equations\n%s\nfor variables\n%s"));
public constant Message UNSUPPORTED_LANGUAGE_FEATURE = MESSAGE(35, TRANSLATION(), ERROR(),
Util.gettext("The language feature %s is not supported. Suggested workaround: %s"));
public constant Message NON_EXISTING_DERIVATIVE = MESSAGE(36, SYMBOLIC(), ERROR(),
Expand Down

0 comments on commit 363c1e2

Please sign in to comment.