Skip to content

Commit

Permalink
[BE] implement sanity check for artificial states
Browse files Browse the repository at this point in the history
- ticket 5459
- revert some stateSelect.prefer based on partial derivatives
- revert stateSelect.prefer if contained in smooth(0, cr)
- force in stateSelect.never more rigorously
- make function tree more accessible when stuff gets differentiated
- add some convenience functions
  • Loading branch information
kabdelhak authored and adrpo committed Sep 25, 2019
1 parent 33ce6e1 commit ad95e1a
Show file tree
Hide file tree
Showing 15 changed files with 642 additions and 195 deletions.
12 changes: 12 additions & 0 deletions OMCompiler/Compiler/BackEnd/AdjacencyMatrix.mo
Expand Up @@ -284,5 +284,17 @@ algorithm
end for;
end absAdjacencyMatrix;

public function isEmpty
input BackendDAE.AdjacencyMatrix m;
output Boolean b = true;
algorithm
for element in m loop
if not listEmpty(element) then
b := false;
return;
end if;
end for;
end isEmpty;

annotation(__OpenModelica_Interface="backend");
end AdjacencyMatrix;
10 changes: 6 additions & 4 deletions OMCompiler/Compiler/BackEnd/BackendDAECreate.mo
Expand Up @@ -1096,12 +1096,14 @@ protected function lowerVarkind
output BackendDAE.VarKind outVarKind;
algorithm
outVarKind := match(inVarKind, daeAttr)
// variable -> state if have stateSelect = StateSelect.always
// variable -> artificial state if have stateSelect = StateSelect.always
case (DAE.VARIABLE(), SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.ALWAYS()))))
guard(not Types.isDiscreteType(inType))
then BackendDAE.STATE(1, NONE(), false);

// variable -> state if have stateSelect = StateSelect.prefer
// variable -> artificial state if have stateSelect = StateSelect.prefer
case (DAE.VARIABLE(), SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.PREFER()))))
guard(not Types.isDiscreteType(inType))
then BackendDAE.STATE(1, NONE(), false);

else
Expand Down Expand Up @@ -2022,7 +2024,7 @@ algorithm

case DAE.DEFINE(componentRef = cr, exp = e, source = source)::xs
equation
(e, _) = ExpressionSolve.solve(Expression.crefExp(cr), e, Expression.crefExp(cr));
(e, _) = ExpressionSolve.solve(Expression.crefExp(cr), e, Expression.crefExp(cr), NONE());
(DAE.PARTIAL_EQUATION(e), source) = ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(e),source);
whenOp = BackendDAE.ASSIGN(Expression.crefExp(cr), e, source);
whenEq = BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
Expand Down Expand Up @@ -2052,7 +2054,7 @@ algorithm

case (el as DAE.EQUATION(exp = (cre as DAE.CREF()), scalar = e, source = source))::xs algorithm
try
e := ExpressionSolve.solve(cre, e, cre);
e := ExpressionSolve.solve(cre, e, cre, NONE());
else
Error.addCompilerError("Failed to solve " + DAEDump.dumpElementsStr({el}));
fail();
Expand Down
6 changes: 3 additions & 3 deletions OMCompiler/Compiler/BackEnd/BackendDAEOptimize.mo
Expand Up @@ -600,7 +600,7 @@ algorithm
(_,(false,_,_,_,_)) = Expression.traverseExpTopDown(e2, traversingTimeEqnsFinder, (false,vars,globalKnownVars,true,false));
cr = BackendVariable.varCref(var);
cre = Expression.crefExp(cr);
(_,{}) = ExpressionSolve.solve(e1,e2,cre);
(_,{}) = ExpressionSolve.solve(e1,e2,cre, NONE());
then ();
// a = const
case ({i},_,_,_,_)
Expand All @@ -619,7 +619,7 @@ algorithm
(_,(false,_,_,_,_)) = Expression.traverseExpTopDown(e2, traversingTimeEqnsFinder, (false,vars,globalKnownVars,false,false));
cr = BackendVariable.varCref(var);
cre = Expression.crefExp(cr);
(_,{}) = ExpressionSolve.solve(e1,e2,cre);
(_,{}) = ExpressionSolve.solve(e1,e2,cre, NONE());
then ();
// a = der(b)
case ({_,_},_,_,_,_)
Expand Down Expand Up @@ -3654,7 +3654,7 @@ algorithm
try
BackendDAE.EQUATION(exp = lhs, scalar = rhs) := potentialGlobalKnownEquation;
crefExp := BackendVariable.varExp(potentialLocalKnownVar);
(binding,_) := ExpressionSolve.solve(lhs,rhs,crefExp);
(binding,_) := ExpressionSolve.solve(lhs,rhs,crefExp, NONE());
potentialLocalKnownVar := BackendVariable.setBindExp(potentialLocalKnownVar, SOME(binding));
localKnownVars := vindex::localKnownVars;
localKnownEqns := eindex::localKnownEqns;
Expand Down
117 changes: 49 additions & 68 deletions OMCompiler/Compiler/BackEnd/BackendDAEUtil.mo

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions OMCompiler/Compiler/BackEnd/BackendDump.mo
Expand Up @@ -454,6 +454,40 @@ algorithm
outTpl := (varNo + 1, buffer);
end var1String;

public function varListStringShort
input list<BackendDAE.Var> inVars;
input String heading;
output String outString;
algorithm
outString := match(inVars, heading)
local
String buffer;

case (_, "") equation
((_, buffer)) = List.fold(inVars, varNameString, (1, ""));
then buffer;

else equation
((_, buffer)) = List.fold(inVars, varNameString, (1, ""));
buffer = heading + "\n" + UNDERLINE + "\n" + buffer;
then buffer;
end match;
end varListStringShort;

protected function varNameString
input BackendDAE.Var inVar;
input tuple<Integer /*inVarNo*/, String /*buffer*/> inTpl;
output tuple<Integer /*outVarNo*/, String /*buffer*/> outTpl;
protected
Integer varNo;
String buffer;
algorithm
(varNo, buffer) := inTpl;
buffer := buffer + intString(varNo) + ": ";
buffer := buffer + ComponentReference.printComponentRefStr(inVar.varName) + "\n";
outTpl := (varNo + 1, buffer);
end varNameString;

public function varListStringIndented
input list<BackendDAE.Var> inVars;
input String heading;
Expand Down
11 changes: 11 additions & 0 deletions OMCompiler/Compiler/BackEnd/BackendVariable.mo
Expand Up @@ -460,6 +460,17 @@ algorithm
end match;
end varStateSelect;

public function varStateSelectNever "author: kabdelhak
Returns true, if the state select attribute is DAE.NEVER()"
input BackendDAE.Var inVar;
output Boolean isNever;
algorithm
isNever := match(varStateSelect(inVar))
case DAE.NEVER() then true;
else false;
end match;
end varStateSelectNever;

public function setVarStateSelect "Sets the state select attribute of a variable."
input BackendDAE.Var inVar;
input DAE.StateSelect stateSelect;
Expand Down
3 changes: 2 additions & 1 deletion OMCompiler/Compiler/BackEnd/ExpressionSolve.mo
Expand Up @@ -193,6 +193,7 @@ public function solve
input DAE.Exp inExp1 "lhs";
input DAE.Exp inExp2 "rhs";
input DAE.Exp inExp3 "DAE.CREF or 'der(DAE.CREF())'";
input Option<DAE.FunctionTree> functions = NONE() "need for solve modelica functions";
output DAE.Exp outExp;
output list<DAE.Statement> outAsserts;
protected
Expand All @@ -209,7 +210,7 @@ algorithm
(outExp,outAsserts,dummy1, dummy2, dummyI) := matchcontinue inExp1
case _ then solveSimple(inExp1, inExp2, inExp3, 0);
case _ then solveSimple(inExp2, inExp1, inExp3, 0);
case _ then solveWork(inExp1, inExp2, inExp3, NONE(), NONE(), 0, false, false);
case _ then solveWork(inExp1, inExp2, inExp3, functions, NONE(), 0, false, false);
else equation
if Flags.isSet(Flags.FAILTRACE) then
Error.addInternalError("Failed to solve \"" + ExpressionDump.printExpStr(inExp1) + " = " + ExpressionDump.printExpStr(inExp2) + "\" w.r.t. \"" + ExpressionDump.printExpStr(inExp3) + "\"", sourceInfo());
Expand Down
10 changes: 6 additions & 4 deletions OMCompiler/Compiler/BackEnd/HpcOmEqSystems.mo
Expand Up @@ -505,7 +505,7 @@ algorithm
resEqsOut := hs;

// some optimization
(eqsNewOut,varsNewOut,resEqsOut) := simplifyNewEquations(eqsNewOut,varsNewOut,resEqsOut,listLength(List.flatten(arrayList(xa_iArr))),2);
(eqsNewOut,varsNewOut,resEqsOut) := simplifyNewEquations(eqsNewOut,varsNewOut,resEqsOut,listLength(List.flatten(arrayList(xa_iArr))),2,ishared);

// handle the strongComponent (system of equations) to solve the tearing vars
(compsEqSys,resEqsOut,tVarsOut,addEqLst,addVarLst) := buildEqSystemComponent(resEqIdcs0,tVarIdcs0,resEqsOut,tVarsOut,a_iArr,ishared);
Expand Down Expand Up @@ -559,6 +559,7 @@ protected function simplifyNewEquations
input list<BackendDAE.Equation> resEqsIn;
input Integer numAuxiliaryVars; // to prevent replacement of coefficients
input Integer numIter;
input BackendDAE.Shared shared;
output list<BackendDAE.Equation> eqsOut;
output list<BackendDAE.Var> varsOut;
output list<BackendDAE.Equation> resEqsOut;
Expand All @@ -578,7 +579,7 @@ algorithm
eqSys := BackendDAEUtil.createEqSystem(varArr, eqArr);
(m,mT) := BackendDAEUtil.incidenceMatrix(eqSys,BackendDAE.ABSOLUTE(),NONE());
size := listLength(eqsIn);
(eqIdcs,varIdcs,resEqsOut) := List.fold(List.intRange(size),function simplifyNewEquations1(eqArr=eqArr,varArr=varArr,m=m,mt=mT,numAuxiliaryVars=numAuxiliaryVars),({},{},resEqsIn));
(eqIdcs,varIdcs,resEqsOut) := List.fold(List.intRange(size),function simplifyNewEquations1(eqArr=eqArr,varArr=varArr,m=m,mt=mT,numAuxiliaryVars=numAuxiliaryVars,shared=shared),({},{},resEqsIn));
numAux := numAuxiliaryVars-listLength(varIdcs);
if listEmpty(varIdcs) then numIterNew:=0;
else numIterNew := numIter;
Expand All @@ -588,7 +589,7 @@ algorithm
(_,eqIdcs,_) := List.intersection1OnTrue(List.intRange(size),eqIdcs,intEq);
eqsOut := BackendEquation.getList(eqIdcs,eqArr);
varsOut := List.map1(varIdcs,BackendVariable.getVarAtIndexFirst,varArr);
if numIterNew<>0 then (eqsOut,varsOut,resEqsOut) := simplifyNewEquations(eqsOut,varsOut,resEqsOut,numAux,numIterNew-1);
if numIterNew<>0 then (eqsOut,varsOut,resEqsOut) := simplifyNewEquations(eqsOut,varsOut,resEqsOut,numAux,numIterNew-1,shared);
else (eqsOut,varsOut,resEqsOut) := (eqsOut,varsOut,resEqsOut);
end if;
end simplifyNewEquations;
Expand All @@ -600,6 +601,7 @@ protected function simplifyNewEquations1
input BackendDAE.IncidenceMatrix m;
input BackendDAE.IncidenceMatrix mt;
input Integer numAuxiliaryVars;
input BackendDAE.Shared shared;
input tuple<list<Integer>,list<Integer>,list<BackendDAE.Equation>> tplIn; //these can be removed afterwards (eqIdcs,varIdcs,_)
output tuple<list<Integer>,list<Integer>,list<BackendDAE.Equation>> tplOut;
algorithm
Expand Down Expand Up @@ -628,7 +630,7 @@ algorithm
varExp := Expression.crefExp(varCref);
rhs := BackendEquation.getEquationRHS(eq);
lhs := BackendEquation.getEquationLHS(eq);
(rhs,_) := ExpressionSolve.solve(lhs,rhs,varExp);
(rhs,_) := ExpressionSolve.solve(lhs,rhs,varExp,NONE());
if Expression.isAsubExp(rhs) then
rhs := List.fold1(Expression.allTerms(rhs),Expression.makeBinaryExp,DAE.ADD(Expression.typeof(varExp)),DAE.RCONST(0.0)); //in case ({a,0,b}+funcCall(1,2,3,4,5))[2] I need to get 0+funcCAll(1,2,3,4,5)[2]
end if;
Expand Down

0 comments on commit ad95e1a

Please sign in to comment.