Skip to content

Commit f162868

Browse files
authored
Improve and fix minimal tearing. (#733)
- Minimal tearing now handles algorithm equations. - It now uses a local subsystem to do the matching. This is not strictly needed but simplifies things. - It now uses the Enhanced Adjacency Matrix. - It does not scalarize the system anymore. TODO: - The inner equations of the torn system are NOT properly sorted right now.
1 parent b2ea29e commit f162868

21 files changed

+240
-397
lines changed

OMCompiler/Compiler/BackEnd/BackendDAEUtil.mo

Lines changed: 2 additions & 261 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,7 +2696,8 @@ algorithm
26962696
case BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS(statementLst = statementLst))
26972697
algorithm
26982698
res := traverseStmts(statementLst, function adjacencyRowAlgorithm(inVariables = vars,
2699-
functionTree = functionTree, inIndexType = inIndexType, isInitial = isInitial), iRow);
2699+
functionTree = functionTree, inIndexType = inIndexType, isInitial = isInitial), iRow);
2700+
27002701
/*
27012702
If looking for solvability add all discrete output variables, even if they don't occur in the algorithm.
27022703
Discrete output variables that do not occur get computed by pre().
@@ -4371,266 +4372,6 @@ algorithm
43714372
res := listArray(lst_1);
43724373
end adjacencyMatrixToSparsePattern;
43734374

4374-
/******************************************************************
4375-
Functions to calculate the solvability for minimal tearing
4376-
******************************************************************/
4377-
function findSolvabelVarInEquation
4378-
"Checks if equation is solvable for variable.
4379-
Returns true if input equation is solvable for input variable."
4380-
input Integer inVariable;
4381-
input Integer inEquation;
4382-
input array<Boolean> varArray;
4383-
input BackendDAE.EqSystem isyst;
4384-
input BackendDAE.Shared ishared;
4385-
output Boolean solvability;
4386-
protected
4387-
BackendDAE.Var v;
4388-
BackendDAE.Variables vars, globalKnownVars;
4389-
BackendDAE.EquationArray eqns;
4390-
BackendDAE.Equation eq;
4391-
BackendDAE.VarKind varKind;
4392-
DAE.ComponentRef cr;
4393-
constant Boolean debug = false;
4394-
algorithm
4395-
// Get equation and variable from integer index
4396-
try
4397-
BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) := isyst;
4398-
BackendDAE.SHARED(globalKnownVars=globalKnownVars) := ishared;
4399-
else
4400-
//Todo: Error
4401-
end try;
4402-
eq := BackendEquation.get(eqns, inEquation);
4403-
BackendDAE.VAR(varName = cr , varKind = varKind) := BackendVariable.getVarAt(vars, inVariable);
4404-
// Compute solvability
4405-
solvability := match(varKind)
4406-
// Case variable is a state
4407-
case(BackendDAE.STATE()) algorithm
4408-
v := BackendVariable.createAliasDerVar(cr);
4409-
cr := BackendVariable.varCref(v);
4410-
then testSolvabilityForEquation(cr, eq, varArray, vars, globalKnownVars);
4411-
else
4412-
then testSolvabilityForEquation(cr, eq, varArray, vars, globalKnownVars);
4413-
end match;
4414-
4415-
if debug then
4416-
print("\n solvability: " + boolString(solvability) + " \n");
4417-
end if;
4418-
end findSolvabelVarInEquation;
4419-
4420-
function testSolvabilityForEquation
4421-
"Helper function for findSolvabelVarInEquation."
4422-
input DAE.ComponentRef inCref;
4423-
input BackendDAE.Equation inEq;
4424-
input array<Boolean> varArray;
4425-
input BackendDAE.Variables inVariables "Unknowns of system";
4426-
input BackendDAE.Variables globalKnownVars;
4427-
output Boolean solvability;
4428-
protected
4429-
DAE.Exp detmp;
4430-
Boolean debug = false;
4431-
algorithm
4432-
4433-
if debug then
4434-
detmp := Expression.crefExp(inCref);
4435-
print("\n Equation Check: " + BackendDump.equationString(inEq) + "\n");
4436-
print("\n The Cref: " + ExpressionDump.printExpStr(detmp)+"\n");
4437-
end if;
4438-
4439-
solvability := match (inEq)
4440-
local
4441-
Integer size;
4442-
list<Integer> lst,ds, lstall, varsSolvedInWhenEqns;
4443-
DAE.Exp e1,e2,e,expCref,cond;
4444-
list<DAE.Exp> expl;
4445-
BackendDAE.WhenEquation we,elsewe;
4446-
String eqnstr;
4447-
DAE.Algorithm alg;
4448-
BackendDAE.AdjacencyMatrixElementEnhanced row, row1;
4449-
list<list<BackendDAE.Equation>> eqnslst;
4450-
list<BackendDAE.Equation> eqnselse;
4451-
list<DAE.ComponentRef> algoutCrefs;
4452-
DAE.Expand crefExpand;
4453-
DAE.ComponentRef cr;
4454-
Boolean try_b;
4455-
DAE.ElementSource source;
4456-
// EQUATION
4457-
case (BackendDAE.EQUATION(exp = e1,scalar = e2)) algorithm
4458-
then minimalTearingRowEnhanced(e1, e2, inCref, varArray, inVariables, globalKnownVars);
4459-
4460-
// COMPLEX_EQUATION
4461-
case (BackendDAE.COMPLEX_EQUATION(left=e1,right=e2)) algorithm
4462-
then minimalTearingRowEnhanced(e1, e2, inCref, varArray, inVariables, globalKnownVars);
4463-
4464-
// ARRAY_EQUATION
4465-
case (BackendDAE.ARRAY_EQUATION(dimSize=ds,left=e1,right=e2)) algorithm
4466-
then minimalTearingRowEnhanced(e1, e2, inCref, varArray, inVariables, globalKnownVars);
4467-
4468-
// SOLVED_EQUATION
4469-
case (BackendDAE.SOLVED_EQUATION(componentRef = cr,exp = e)) algorithm
4470-
if ComponentReference.crefEqualNoStringCompare(cr, inCref) then
4471-
solvability := true;
4472-
else
4473-
expCref := Expression.crefExp(cr);
4474-
solvability := minimalTearingRowEnhanced(expCref, e, inCref, varArray, inVariables, globalKnownVars);
4475-
end if;
4476-
then solvability;
4477-
4478-
// RESIDUAL_EQUATION
4479-
case (BackendDAE.RESIDUAL_EQUATION(exp = e)) algorithm
4480-
then minimalTearingRowEnhanced(e, DAE.RCONST(0.0), inCref, varArray, inVariables, globalKnownVars);
4481-
4482-
// WHEN_EQUATION
4483-
case (BackendDAE.WHEN_EQUATION(whenEquation = elsewe)) algorithm
4484-
print("\nWHEN_EQUATION are not supported now!\n");
4485-
fail();
4486-
// Todo Add Waring / Error
4487-
then false;
4488-
4489-
// IF_EQUATION
4490-
// TODO : how to handle this?
4491-
// Proposal:
4492-
// 1. vars in conditions are unsolvable
4493-
// 2. vars occur in all branches: check how they are occur
4494-
// 3. vars occur not in all branches: then unsolvable
4495-
case(BackendDAE.IF_EQUATION(conditions=expl,eqnstrue=eqnslst,eqnsfalse=eqnselse)) algorithm
4496-
try
4497-
//check condition?
4498-
try_b := tryToFindSolvableEqInBranch(inCref, eqnselse, varArray, inVariables, globalKnownVars);
4499-
true := try_b;
4500-
for eqns in eqnslst loop
4501-
try_b := tryToFindSolvableEqInBranch(inCref, eqns, varArray, inVariables, globalKnownVars);
4502-
true := try_b;
4503-
end for;
4504-
solvability := true;
4505-
else
4506-
solvability := false;
4507-
end try;
4508-
then solvability;
4509-
4510-
else
4511-
algorithm
4512-
eqnstr := BackendDump.equationString(inEq);
4513-
eqnstr := stringAppendList({"BackendDAE.adjacencyRowEnhanced failed for eqn:\n",eqnstr,"\n"});
4514-
Error.addMessage(Error.INTERNAL_ERROR,{eqnstr});
4515-
fail();
4516-
then false;
4517-
end match;
4518-
end testSolvabilityForEquation;
4519-
4520-
4521-
protected function tryToFindSolvableEqInBranch
4522-
input DAE.ComponentRef inCref;
4523-
input list<BackendDAE.Equation> iEqns;
4524-
input array<Boolean> varArray;
4525-
input BackendDAE.Variables inVariables;
4526-
input BackendDAE.Variables globalKnownVars;
4527-
output Boolean solvability = false;
4528-
protected
4529-
Boolean solvable;
4530-
algorithm
4531-
for eq in iEqns loop
4532-
solvable := testSolvabilityForEquation(inCref, eq, varArray, inVariables, globalKnownVars);
4533-
if solvable then
4534-
// Found a solvable equation, return solvability=true
4535-
solvability := true;
4536-
break;
4537-
end if;
4538-
end for;
4539-
end tryToFindSolvableEqInBranch;
4540-
4541-
4542-
protected function minimalTearingRowEnhanced
4543-
input DAE.Exp e1;
4544-
input DAE.Exp e2;
4545-
input DAE.ComponentRef inCref;
4546-
input array<Boolean> varArray;
4547-
input BackendDAE.Variables inVariables;
4548-
input BackendDAE.Variables globalKnownVars;
4549-
output Boolean solvability;
4550-
protected
4551-
Integer r,rabs;
4552-
list<Integer> rest;
4553-
DAE.Exp de,detmp, e, e_derAlias, e3, nominal;
4554-
DAE.ComponentRef cr,cr1,crarr;
4555-
BackendDAE.Solvability solvab;
4556-
list<DAE.ComponentRef> crlst;
4557-
Absyn.Path path,path1;
4558-
list<DAE.Exp> explst,crexplst, explst2;
4559-
Boolean b,solved,constOneorMOne, b1, b2, b_1;
4560-
BackendDAE.Constraints cons;
4561-
Boolean debug = false;
4562-
algorithm
4563-
try
4564-
try
4565-
e := Expression.expSub(e1,e2);
4566-
else
4567-
solvability := true;
4568-
return;
4569-
end try;
4570-
e_derAlias := Expression.traverseExpDummy(e, replaceDerCall);
4571-
(de,constOneorMOne) := minimalTearingTestSolvability(e_derAlias, inCref, inVariables,NONE());
4572-
(de,_) := ExpressionSimplify.simplify(de);
4573-
4574-
if debug then
4575-
detmp := Expression.crefExp(inCref);
4576-
print("\n The Cref: " + ExpressionDump.printExpStr(detmp)+"\n" + " the expression: " + ExpressionDump.printExpStr(e_derAlias));
4577-
print("\n Expressin after derive: " + ExpressionDump.printExpStr(de) + "\n");
4578-
end if ;
4579-
4580-
if not constOneorMOne then
4581-
solvability := Expression.isConst(de);
4582-
else
4583-
solvability := true;
4584-
end if;
4585-
else
4586-
solvability := false;
4587-
end try;
4588-
end minimalTearingRowEnhanced;
4589-
4590-
function minimalTearingTestSolvability
4591-
input DAE.Exp e;
4592-
input DAE.ComponentRef cr "x";
4593-
input BackendDAE.Variables vars;
4594-
input Option<DAE.FunctionTree> functions;
4595-
output DAE.Exp derivedFunction;
4596-
output Boolean constOneorMOne;
4597-
protected
4598-
DAE.Type tp = Expression.typeof(e);
4599-
Boolean trytosolve2 = stringEqual(Flags.getConfigString(Flags.TEARING_STRICTNESS), "casual");
4600-
Boolean localCon;
4601-
DAE.Exp one, tmpEqn, solvedExp, con;
4602-
list<BackendDAE.Equation> eqnForNewVars;
4603-
list<DAE.ComponentRef> newVarsCrefs;
4604-
DAE.ComponentRef tmpVar;
4605-
constant Boolean debug = false;
4606-
algorithm
4607-
try
4608-
derivedFunction := Differentiate.differentiateExpSolve(e, cr, functions);
4609-
//print("\n Expressin after derive: " + ExpressionDump.printExpStr(derivedFunction) + "\n");
4610-
(derivedFunction,constOneorMOne) := match(derivedFunction)
4611-
/* der(f(x)) = c/y => c*x = y*lhs */
4612-
case DAE.BINARY(one,DAE.DIV(), DAE.CREF()) /*Note: 1/x => ln(x) => Expression.solve will solve it */
4613-
guard (Expression.isConst(one) and not Expression.isZero(one))
4614-
then (one,true);
4615-
4616-
else (derivedFunction,false);
4617-
end match;
4618-
else
4619-
derivedFunction := Expression.makeConstOne(tp);
4620-
constOneorMOne:=true;
4621-
end try;
4622-
4623-
if Expression.isZero(derivedFunction) then
4624-
// see https://trac.openmodelica.org/OpenModelica/ticket/3742#comment:12
4625-
// ExpressionSolve will fail for derivedFunction == 0 --> internal loops inside tearing
4626-
Error.addInternalError("Expression is zero.", sourceInfo());
4627-
fail();
4628-
end if;
4629-
4630-
if debug then
4631-
print("minimalTearingTestSolvability" + ExpressionDump.printExpStr(e) + " -> " + ExpressionDump.printExpStr(derivedFunction) + " == " + ExpressionDump.printExpStr(Expression.crefExp(cr)) + "\n");
4632-
end if;
4633-
end minimalTearingTestSolvability;
46344375

46354376
/******************************************************************
46364377
stuff to calculate enhanced Adjacency matrix

0 commit comments

Comments
 (0)