Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 97e737e

Browse files
ptaeuberOpenModelica-Hudson
authored andcommitted
Improve Dynamic Tearing
... by adding constraints for the casual set
1 parent 56dc448 commit 97e737e

24 files changed

+764
-227
lines changed

Compiler/BackEnd/BackendDAE.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ uniontype Solvability
674674
end Solvability;
675675

676676
public
677-
type Constraints = list<.DAE.Constraint> "Constraints needed for proper Dynamic Tearing";
677+
type Constraints = list<.DAE.Constraint> "Constraints on the solvability of the (casual) tearing set; needed for proper Dynamic Tearing";
678678

679679
public
680680
uniontype IndexType

Compiler/BackEnd/BackendDAEUtil.mo

Lines changed: 130 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4803,20 +4803,56 @@ protected function tryToSolveOrDerive
48034803
input DAE.ComponentRef cr "x";
48044804
input BackendDAE.Variables vars;
48054805
input Option<DAE.FunctionTree> functions;
4806-
input Boolean trytosolve1 "if true, try to solve the expression for the variable, even if flag 'advanceTearing' is not set";
4806+
input Boolean trytosolve1 "if true, try to solve the expression for the variable, even if flag 'allowImpossibleAssignments' is not set";
48074807
output DAE.Exp f;
48084808
output Boolean solved=false "true if equation is solved for the variable with ExpressionSolve.solve2, false if equation is differentiated";
48094809
output Boolean derived=false;
48104810
output BackendDAE.Constraints outCons={};
48114811
protected
48124812
DAE.Type tp = Expression.typeof(e);
48134813
Boolean trytosolve2 = Flags.isSet(Flags.ALLOW_IMPOSSIBLE_ASSIGNMENTS);
4814-
DAE.Exp one,solvedExp;
4814+
Boolean localCon;
4815+
DAE.Exp one, tmpEqn, solvedExp, con;
4816+
list<BackendDAE.Equation> eqnForNewVars;
4817+
list<DAE.ComponentRef> newVarsCrefs;
4818+
DAE.ComponentRef tmpVar;
4819+
DAE.Constraint constraint;
4820+
BackendDAE.Constraints constraints;
48154821
algorithm
48164822
if trytosolve1 or trytosolve2 then
48174823
try // try to solve for x (1*x = f(y))
4818-
(solvedExp,_,_,_) := ExpressionSolve.solve2(e, Expression.makeConstZero(tp),Expression.crefExp(cr), functions, SOME(-1));
4819-
(_,(outCons,_)) := Expression.traverseExpTopDown(solvedExp, getConstraints, ({},vars));
4824+
(solvedExp,_,eqnForNewVars,newVarsCrefs) := ExpressionSolve.solve2(e, Expression.makeConstZero(tp),Expression.crefExp(cr), functions, SOME(1));
4825+
4826+
// print("Solve expression:\n" + ExpressionDump.printExpStr(e) + "\n");
4827+
// print("for variable: " + ExpressionDump.printExpStr(Expression.crefExp(cr)) + "\n");
4828+
// print("Solved expression:\n" + ExpressionDump.printExpStr(solvedExp) + "\n");
4829+
// ComponentReference.printComponentRefList(newVarsCrefs);
4830+
// BackendDump.dumpEquationList(eqnForNewVars, "eqnForNewVars");
4831+
// ExpressionDump.dumpExp(solvedExp);
4832+
// print("listLength(eqnForNewVars): " + intString(listLength(eqnForNewVars)) + "\n\n");
4833+
4834+
(_,(constraints,_)) := Expression.traverseExpTopDown(solvedExp, getConstraints, ({},vars));
4835+
4836+
for eqn in eqnForNewVars loop
4837+
BackendDAE.SOLVED_EQUATION(componentRef=tmpVar, exp=tmpEqn) := eqn;
4838+
(_,(constraints,_)) := Expression.traverseExpTopDown(tmpEqn, getConstraints, (constraints,vars));
4839+
end for;
4840+
4841+
// print("Constraints before substitution: " + ExpressionDump.constraintDTlistToString(constraints, "\n") + "\n\n");
4842+
4843+
for i in listLength(constraints):-1:1 loop
4844+
constraint := listGet(constraints, i);
4845+
DAE.CONSTRAINT_DT(constraint = con, localCon=localCon) := constraint;
4846+
for eqn in eqnForNewVars loop
4847+
BackendDAE.SOLVED_EQUATION(componentRef=tmpVar, exp=tmpEqn) := eqn;
4848+
con := Expression.replaceCrefBottomUp(con, tmpVar, tmpEqn);
4849+
end for;
4850+
outCons := DAE.CONSTRAINT_DT(con, localCon)::outCons;
4851+
end for;
4852+
4853+
// print("Substituted expression:\n" + ExpressionDump.printExpStr(solvedExp) + "\n");
4854+
// print("Constraints:" + ExpressionDump.constraintDTlistToString(outCons, "\n") + "\n\n");
4855+
48204856
solved := true;
48214857
else end try;
48224858
end if;
@@ -4849,29 +4885,86 @@ Function to find the constraints for Dynamic Tearing."
48494885
input DAE.Exp inExp;
48504886
input tuple<BackendDAE.Constraints,BackendDAE.Variables> inTpl;
48514887
output DAE.Exp outExp;
4852-
output Boolean cont;
4888+
output Boolean cont=true;
48534889
output tuple<BackendDAE.Constraints,BackendDAE.Variables> outTpl;
48544890
protected
48554891
BackendDAE.Constraints inCons;
48564892
BackendDAE.Variables vars;
48574893
algorithm
48584894
(inCons,vars) := inTpl;
4859-
(outExp,cont,outTpl) := match(inExp)
4895+
(outExp,outTpl) := match(inExp)
48604896
local
4861-
DAE.Exp e1, e2;
4897+
DAE.Exp e;
48624898
DAE.Exp rel;
48634899
DAE.Constraint con;
48644900
list<DAE.ComponentRef> crlst;
48654901
Boolean localCon;
4866-
case DAE.BINARY(operator=DAE.DIV(), exp2=e2)
4902+
case DAE.BINARY(operator=DAE.DIV(), exp2=e)
48674903
equation
4868-
rel = DAE.RELATION(e2,DAE.NEQUAL(DAE.T_UNKNOWN(DAE.emptyTypeSource)),DAE.RCONST(0.0),-1,NONE());
4904+
rel = DAE.RELATION(DAE.CALL(Absyn.IDENT("abs"), {e}, DAE.callAttrBuiltinOther), DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
48694905
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4870-
localCon = containAnyVar(crlst,vars);
4906+
localCon = containAnyVarWithoutStates(crlst,vars);
48714907
con = DAE.CONSTRAINT_DT(rel,localCon);
4872-
then (inExp,true,(con::inCons,vars));
4908+
then (inExp,(con::inCons,vars));
4909+
4910+
case DAE.CALL(path = Absyn.IDENT(name = "sqrt"), expLst = {e})
4911+
equation
4912+
rel = DAE.RELATION(e, DAE.GREATEREQ(DAE.T_REAL_DEFAULT), DAE.RCONST(0.0), -1, NONE());
4913+
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4914+
localCon = containAnyVarWithoutStates(crlst,vars);
4915+
con = DAE.CONSTRAINT_DT(rel,localCon);
4916+
then (inExp,(con::inCons,vars));
4917+
4918+
case DAE.BINARY(exp1=e, operator=DAE.POW(), exp2=DAE.RCONST(0.5))
4919+
equation
4920+
rel = DAE.RELATION(e, DAE.GREATEREQ(DAE.T_REAL_DEFAULT), DAE.RCONST(0.0), -1, NONE());
4921+
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4922+
localCon = containAnyVarWithoutStates(crlst,vars);
4923+
con = DAE.CONSTRAINT_DT(rel,localCon);
4924+
then (inExp,(con::inCons,vars));
4925+
4926+
case DAE.CALL(path = Absyn.IDENT(name = "log"), expLst = {e})
4927+
equation
4928+
rel = DAE.RELATION(e, DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
4929+
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4930+
localCon = containAnyVarWithoutStates(crlst,vars);
4931+
con = DAE.CONSTRAINT_DT(rel,localCon);
4932+
then (inExp,(con::inCons,vars));
4933+
4934+
case DAE.CALL(path = Absyn.IDENT(name = "log10"), expLst = {e})
4935+
equation
4936+
rel = DAE.RELATION(e, DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
4937+
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4938+
localCon = containAnyVarWithoutStates(crlst,vars);
4939+
con = DAE.CONSTRAINT_DT(rel,localCon);
4940+
then (inExp,(con::inCons,vars));
4941+
4942+
case DAE.CALL(path = Absyn.IDENT(name = "asin"), expLst = {e})
4943+
equation
4944+
rel = DAE.RELATION(DAE.CALL(Absyn.IDENT("abs"), {e}, DAE.callAttrBuiltinOther), DAE.LESSEQ(DAE.T_REAL_DEFAULT), DAE.RCONST(1.0), -1, NONE());
4945+
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4946+
localCon = containAnyVarWithoutStates(crlst,vars);
4947+
con = DAE.CONSTRAINT_DT(rel,localCon);
4948+
then (inExp,(con::inCons,vars));
4949+
4950+
case DAE.CALL(path = Absyn.IDENT(name = "acos"), expLst = {e})
4951+
equation
4952+
rel = DAE.RELATION(DAE.CALL(Absyn.IDENT("abs"), {e}, DAE.callAttrBuiltinOther), DAE.LESSEQ(DAE.T_REAL_DEFAULT), DAE.RCONST(1.0), -1, NONE());
4953+
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4954+
localCon = containAnyVarWithoutStates(crlst,vars);
4955+
con = DAE.CONSTRAINT_DT(rel,localCon);
4956+
then (inExp,(con::inCons,vars));
4957+
4958+
case DAE.CALL(path = Absyn.IDENT(name = "tan"), expLst = {e})
4959+
equation
4960+
rel = DAE.RELATION(DAE.BINARY(exp1=DAE.CALL(Absyn.IDENT("abs"), {DAE.BINARY(exp1=DAE.BINARY(exp1=e, operator=DAE.DIV(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(3.14159265358979)), operator=DAE.MUL(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(2.0))}, DAE.callAttrBuiltinOther), operator=DAE.SUB(ty=DAE.T_REAL_DEFAULT), exp2=DAE.CALL(Absyn.IDENT("floor"), {DAE.CALL(Absyn.IDENT("abs"), {DAE.BINARY(exp1=DAE.BINARY(exp1=e, operator=DAE.DIV(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(3.14159265358979)), operator=DAE.MUL(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(2.0))}, DAE.callAttrBuiltinOther)}, DAE.callAttrBuiltinOther)), DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
4961+
(_,crlst) = Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
4962+
localCon = containAnyVarWithoutStates(crlst,vars);
4963+
con = DAE.CONSTRAINT_DT(rel,localCon);
4964+
then (inExp,(con::inCons,vars));
4965+
48734966
else
4874-
then (inExp,true,inTpl);
4967+
then (inExp,inTpl);
48754968
end match;
48764969
end getConstraints;
48774970

@@ -5575,6 +5668,31 @@ algorithm
55755668
end matchcontinue;
55765669
end containAnyVar;
55775670

5671+
protected function containAnyVarWithoutStates
5672+
"Like containAnyVar but if var is state it is not counted."
5673+
input list<DAE.ComponentRef> inExpComponentRefLst;
5674+
input BackendDAE.Variables inVariables;
5675+
output Boolean outBoolean;
5676+
algorithm
5677+
outBoolean := matchcontinue (inExpComponentRefLst,inVariables)
5678+
local
5679+
DAE.ComponentRef cr;
5680+
list<DAE.ComponentRef> crefs;
5681+
BackendDAE.Variables vars;
5682+
BackendDAE.Var v;
5683+
case ({},_) then false;
5684+
case ((cr::_),vars)
5685+
equation
5686+
(v::_,_) = BackendVariable.getVar(cr, vars);
5687+
false = BackendVariable.isStateVar(v);
5688+
then
5689+
true;
5690+
case ((_::crefs),vars)
5691+
then
5692+
containAnyVarWithoutStates(crefs, vars);
5693+
end matchcontinue;
5694+
end containAnyVarWithoutStates;
5695+
55785696
public function getEqnSysRhs "author: Frenkel TUD 2013-02
55795697

55805698
Retrieve the right hand side of an equation system, given a set of variables.

Compiler/BackEnd/HpcOmScheduler.mo

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4141,6 +4141,7 @@ algorithm
41414141
Boolean homotopySupport;
41424142
Boolean mixedSystem;
41434143
list<BackendDAE.WhenOperator> whenStmtLst;
4144+
BackendDAE.Constraints cons;
41444145
case(SimCode.SES_RESIDUAL(index=idx,exp=exp,source=source),_)
41454146
equation
41464147
(exp,changed) = BackendVarTransform.replaceExp(exp,replIn,NONE());
@@ -4153,6 +4154,13 @@ algorithm
41534154
(exp,changed) = BackendVarTransform.replaceExp(exp,replIn,NONE());
41544155
simEqSys = SimCode.SES_SIMPLE_ASSIGN(idx,cref,exp,source);
41554156
then (simEqSys,changed or hasRepl);
4157+
case(SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(index=idx,cref=cref,exp=exp,source=source,cons=cons),_)
4158+
equation
4159+
hasRepl = BackendVarTransform.hasReplacement(replIn,cref);
4160+
DAE.CREF(componentRef=cref) = if hasRepl then BackendVarTransform.getReplacement(replIn,cref) else DAE.CREF(cref,DAE.T_UNKNOWN_DEFAULT);
4161+
(exp,changed) = BackendVarTransform.replaceExp(exp,replIn,NONE());
4162+
simEqSys = SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(idx,cref,exp,source,cons);
4163+
then (simEqSys,changed or hasRepl);
41564164
case(SimCode.SES_ARRAY_CALL_ASSIGN(index=idx,lhs=lhs,exp=exp,source=source),_)
41574165
equation
41584166
cref = Expression.expCref(lhs);

Compiler/BackEnd/HpcOmTaskGraph.mo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6874,6 +6874,7 @@ algorithm
68746874
(oIdx,oIdx2) := match(iEq)
68756875
case(SimCode.SES_RESIDUAL(index=index)) then (index,0);
68766876
case(SimCode.SES_SIMPLE_ASSIGN(index=index)) then (index,0);
6877+
case(SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(index=index)) then (index,0);
68776878
case(SimCode.SES_ARRAY_CALL_ASSIGN(index=index)) then (index,0);
68786879
case(SimCode.SES_IFEQUATION(index=index)) then (index,0);
68796880
case(SimCode.SES_ALGORITHM(index=index)) then (index,0);

Compiler/BackEnd/Tearing.mo

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,13 +1719,13 @@ algorithm
17191719
DAEtypeStr := BackendDump.printBackendDAEType2String(DAEtype);
17201720

17211721
// check if dynamic tearing is enabled for linear/nonlinear system
1722-
dynamicTearing := match (Config.dynamicTearing(),linear,noDynamicStateSelection,DAEtypeStr,Flags.getConfigBool(Flags.DYNAMIC_TEARING_FOR_INITIALIZATION))
1723-
case ("true",_,true,"simulation",_) then true;
1724-
case ("true",_,true,"initialization",true) then true;
1725-
case ("linear",true,true,"simulation",_) then true;
1726-
case ("linear",true,true,"initialization",true) then true;
1727-
case ("nonlinear",false,true,"simulation",_) then true;
1728-
case ("nonlinear",false,true,"initialization",true) then true;
1722+
dynamicTearing := match (Config.dynamicTearing(),linear,noDynamicStateSelection,DAEtypeStr,Flags.getConfigBool(Flags.DYNAMIC_TEARING_FOR_INITIALIZATION),Config.simCodeTarget())
1723+
case ("true",_,true,"simulation",_,"C") then true;
1724+
case ("true",_,true,"initialization",true,"C") then true;
1725+
case ("linear",true,true,"simulation",_,"C") then true;
1726+
case ("linear",true,true,"initialization",true,"C") then true;
1727+
case ("nonlinear",false,true,"simulation",_,"C") then true;
1728+
case ("nonlinear",false,true,"initialization",true,"C") then true;
17291729
else false;
17301730
end match;
17311731

@@ -1949,7 +1949,7 @@ algorithm
19491949

19501950
else
19511951
if Flags.isSet(Flags.TEARING_DUMP) or Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
1952-
print("Note:\n=====\nNo dynamic Tearing for this strong component. Check if\n- flag 'dynamicTearing' is set proper\n- strong component does not contain statesets\n- system belongs to simulation\n\n");
1952+
print("Note:\n=====\nNo dynamic Tearing for this strong component. Check if\n- flag 'dynamicTearing' is set proper\n- strong component does not contain statesets\n- system belongs to simulation\n- SimCode target is 'C'\n\n");
19531953
end if;
19541954
if not b and not Flags.getConfigBool(Flags.FORCE_TEARING) then
19551955
if Flags.isSet(Flags.TEARING_DUMP) or Flags.isSet(Flags.TEARING_DUMPVERBOSE) then

Compiler/SimCode/SerializeModelInfo.mo

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,26 @@ algorithm
480480
File.write(file, "}");
481481
then true;
482482

483+
case SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS() equation
484+
File.write(file, "\n{\"eqIndex\":");
485+
File.writeInt(file, eq.index);
486+
if parent <> 0 then
487+
File.write(file, ",\"parent\":");
488+
File.writeInt(file, parent);
489+
end if;
490+
File.write(file, ",\"section\":\"");
491+
File.write(file, section);
492+
File.write(file, "\",\"tag\":\"assign\",\"defines\":[\"");
493+
writeCref(file,eq.cref,escape=JSON);
494+
File.write(file, "\"],\"uses\":[");
495+
serializeUses(file,Expression.extractUniqueCrefsFromExp(eq.exp));
496+
File.write(file, "],\"equation\":[\"");
497+
File.writeEscape(file,expStr(eq.exp),escape=JSON);
498+
File.write(file, "\"],\"source\":");
499+
serializeSource(file,eq.source,withOperations);
500+
File.write(file, "}");
501+
then true;
502+
483503
case SimCode.SES_ARRAY_CALL_ASSIGN() equation
484504
File.write(file, "\n{\"eqIndex\":");
485505
File.writeInt(file, eq.index);

Compiler/SimCode/SimCode.mo

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,15 @@ uniontype SimEqSystem
281281
DAE.ElementSource source;
282282
end SES_SIMPLE_ASSIGN;
283283

284+
record SES_SIMPLE_ASSIGN_CONSTRAINTS
285+
"Solved inner equation of (casual) tearing set (Dynamic Tearing) with constraints on the solvability"
286+
Integer index;
287+
DAE.ComponentRef cref;
288+
DAE.Exp exp;
289+
DAE.ElementSource source;
290+
BackendDAE.Constraints cons;
291+
end SES_SIMPLE_ASSIGN_CONSTRAINTS;
292+
284293
record SES_ARRAY_CALL_ASSIGN
285294
Integer index;
286295
DAE.Exp lhs;

0 commit comments

Comments
 (0)