Skip to content

Commit

Permalink
generate always SparsePattern for non-linear algebraic loops
Browse files Browse the repository at this point in the history
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed Nov 29, 2016
1 parent af8cd3e commit ff3d39d
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 34 deletions.
55 changes: 36 additions & 19 deletions Compiler/BackEnd/SymbolicJacobian.mo
Expand Up @@ -2390,16 +2390,20 @@ protected
Boolean b1, b2;
algorithm
if not Flags.isSet(Flags.FORCE_NLS_ANALYTIC_JACOBIAN) then
(b1, _) := BackendEquation.traverseExpsOfEquationList_WithStop(inResidualEqns, traverserhasEqnNonDiffParts, ({}, true, false));
(b2, _) := BackendEquation.traverseExpsOfEquationList_WithStop(inOtherEqns, traverserhasEqnNonDiffParts, ({}, true, false));
if not (b1 and b2) then
if Flags.isSet(Flags.FAILTRACE) then
Debug.traceln("Skip symbolic jacobian for non-linear system " + name + "\n");
end if;
try // might fail because of algorithms TODO: fix it!
(b1, _) := BackendEquation.traverseExpsOfEquationList_WithStop(inResidualEqns, traverserhasEqnNonDiffParts, ({}, true, false));
(b2, _) := BackendEquation.traverseExpsOfEquationList_WithStop(inOtherEqns, traverserhasEqnNonDiffParts, ({}, true, false));
if not (b1 and b2) then
if Flags.isSet(Flags.FAILTRACE) then
Debug.traceln("Skip symbolic jacobian for non-linear system " + name + "\n");
end if;
out := false;
else
out := true;
end if;
else
out := false;
else
out := true;
end if;
end try;
else
out := true;
end if;
Expand All @@ -2415,15 +2419,15 @@ protected function calculateTearingSetJacobian
output BackendDAE.Shared outShared;
protected
String name, prename;
Boolean debug = false;
Boolean debug = false, onlySparsePattern=false;

BackendDAE.Variables diffVars, oVars, resVars;
BackendDAE.EquationArray resEqns, oEqns;
algorithm
try
// check non-linear flag
if not isLinear and not Flags.isSet(Flags.NLS_ANALYTIC_JACOBIAN) then
fail();
onlySparsePattern := true;
end if;
// generate jacobian name
if isLinear then
Expand All @@ -2445,11 +2449,11 @@ algorithm

//check if we are able to calc symbolic jacobian
if not (isLinear or checkForSymbolicJacobian(BackendEquation.equationList(resEqns), BackendEquation.equationList(oEqns), name)) then
fail();
onlySparsePattern := true;
end if;

// generate generic jacobian backend dae
(outJacobian, outShared) := getSymbolicJacobian(diffVars, resEqns, resVars, oEqns, oVars, inShared, inVars, name);
(outJacobian, outShared) := getSymbolicJacobian(diffVars, resEqns, resVars, oEqns, oVars, inShared, inVars, name, onlySparsePattern);
else
fail();
end try;
Expand Down Expand Up @@ -2486,7 +2490,7 @@ algorithm
String name;
Boolean mixedSystem, linear;

Boolean debug = false;
Boolean debug = false, onlySparsePattern = true;
BackendDAE.TearingSet strictTearingset, causalTearingSet;
Option<BackendDAE.TearingSet> optCausalTearingSet;

Expand All @@ -2512,7 +2516,6 @@ algorithm

case (BackendDAE.EQUATIONSYSTEM(eqns=residualequations, vars=iterationvarsInts, mixedSystem=mixedSystem), _, _, _)
equation
true = Flags.isSet(Flags.NLS_ANALYTIC_JACOBIAN);
//generate jacobian name
name = "NLSJac" + intString(System.tmpTickIndex(Global.backendDAE_jacobianSeq));

Expand All @@ -2525,8 +2528,11 @@ algorithm
// get residual eqns
reqns = BackendEquation.getEqns(residualequations, inEqns);
reqns = BackendEquation.replaceDerOpInEquationList(reqns);

//check if we are able to calc symbolic jacobian
true = checkForSymbolicJacobian(reqns, {}, name);
if checkForSymbolicJacobian(reqns, {}, name) and Flags.isSet(Flags.NLS_ANALYTIC_JACOBIAN) then
onlySparsePattern = false;
end if;

eqns = BackendEquation.listEquation(reqns);
// create residual equations
Expand All @@ -2541,7 +2547,7 @@ algorithm
ovars = BackendVariable.emptyVars();

// generate generic jacobian backend dae
(jacobian, shared) = getSymbolicJacobian(diffVars, eqns, resVars, oeqns, ovars, inShared, inVars, name);
(jacobian, shared) = getSymbolicJacobian(diffVars, eqns, resVars, oeqns, ovars, inShared, inVars, name, onlySparsePattern);

then (BackendDAE.EQUATIONSYSTEM(residualequations, iterationvarsInts, jacobian, BackendDAE.JAC_GENERIC(), mixedSystem), shared);

Expand Down Expand Up @@ -2634,6 +2640,7 @@ protected function getSymbolicJacobian "author: wbraun
input BackendDAE.Shared inShared;
input BackendDAE.Variables inAllVars;
input String inName;
input Boolean inOnlySparsePattern;
output BackendDAE.Jacobian outJacobian;
output BackendDAE.Shared outShared;
algorithm
Expand Down Expand Up @@ -2740,7 +2747,7 @@ algorithm
inResVars,
dependentVarsLst,
inName,
false);
inOnlySparsePattern);

shared = BackendDAEUtil.setSharedFunctionTree(inShared, funcs);

Expand All @@ -2756,6 +2763,16 @@ algorithm
end matchcontinue;
end getSymbolicJacobian;

public function hasGenericSymbolicJacobian
input BackendDAE.Jacobian inJacobian;
output Boolean out;
algorithm
out := match(inJacobian)
case (BackendDAE.GENERIC_JACOBIAN(jacobian=SOME(_))) then true;
else false;
end match;
end hasGenericSymbolicJacobian;

protected function calculateEqSystemStateSetsJacobians
input BackendDAE.EqSystem inSyst;
input BackendDAE.Shared inShared;
Expand Down Expand Up @@ -2872,7 +2889,7 @@ algorithm
name = "StateSetJac" + intString(System.tmpTickIndex(Global.backendDAE_jacobianSeq));

// generate generic Jacobian back end dae
(jacobian, shared) = getSymbolicJacobian(diffVars, cEqns, resVars, oEqns, oVars, inShared, allvars, name);
(jacobian, shared) = getSymbolicJacobian(diffVars, cEqns, resVars, oEqns, oVars, inShared, allvars, name, false);

then (BackendDAE.STATESET(rang, state, crA, varA, statescandidates, ovars, eqns, oeqns, crJ, varJ, jacobian), shared);
end match;
Expand Down
78 changes: 69 additions & 9 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -1064,6 +1064,12 @@ algorithm
(res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, NONE(), homotopySupport, mixedSystem), NONE())::inEqnsAcc, inSymJacsAcc);
then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians);

case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, SOME(symJac as ({},_,_,_,_,_,_)), homotopySupport, mixedSystem), NONE())::rest, _, _, _, _, _, _, _)
equation
(eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {});
(res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, SOME(symJac), homotopySupport, mixedSystem), NONE())::inEqnsAcc, inSymJacsAcc);
then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians);

case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, SOME(symJac), homotopySupport, mixedSystem), NONE())::rest, _, _, _, _, _, _, _)
equation
(eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {});
Expand Down Expand Up @@ -1092,6 +1098,13 @@ algorithm
(res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, NONE(), homotopySupport, mixedSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, inNonLinSysIndex+1, NONE(), homotopySupport2, mixedSystem2)))::inEqnsAcc, inSymJacsAcc);
then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians);

case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, SOME(symJac as ({},_,_,_,_,_,_)), homotopySupport, mixedSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, _, SOME(symJac2 as ({},_,_,_,_,_,_)), homotopySupport2, mixedSystem2)))::rest, _, _, _, _, _, _, _)
equation
(eqs,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {});
(eqs2,_, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs2, {}, countLinearSys, countNonLinSys+1, countMixedSys, countJacobians, {}, {});
(res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(rest, inSymJacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians, SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, inNonLinSysIndex, SOME(symJac), homotopySupport, mixedSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, inNonLinSysIndex+1, SOME(symJac2), homotopySupport2, mixedSystem2)))::inEqnsAcc, inSymJacsAcc);
then (res, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians);

case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index, eqs, crefs, _, SOME(symJac), homotopySupport, mixedSystem), SOME(SimCode.NONLINEARSYSTEM(index2, eqs2, crefs2, _, SOME(symJac2), homotopySupport2, mixedSystem2)))::rest, _, _, _, _, _, _, _)
equation
(eqs, symjacs, countLinearSys, countNonLinSys, countMixedSys, countJacobians) = countandIndexAlgebraicLoopsWork(eqs, {}, inLinearSysIndex, inNonLinSysIndex+1, inMixedSysIndex, inJacobianIndex, {}, {});
Expand Down Expand Up @@ -4119,6 +4132,7 @@ algorithm
list<DAE.ComponentRef> independentComRefs, dependentVarsComRefs;

DAE.ComponentRef x;
BackendDAE.SparsePattern pattern;
BackendDAE.SparseColoring sparseColoring;
list<list<Integer>> coloring;
list<tuple<DAE.ComponentRef, list<DAE.ComponentRef>>> sparsepatternComRefs, sparsepatternComRefsT;
Expand All @@ -4130,7 +4144,7 @@ algorithm

list<SimCodeVar.SimVar> tempvars;
String name, s, dummyVar;
Integer maxColor, uniqueEqIndex;
Integer maxColor, uniqueEqIndex, nonZeroElements;

list<SimCode.SimEqSystem> columnEquations;
list<SimCodeVar.SimVar> columnVars;
Expand All @@ -4146,10 +4160,45 @@ algorithm

case (BackendDAE.FULL_JACOBIAN(_), _, _) then (NONE(), iuniqueEqIndex, itempvars);

case (BackendDAE.GENERIC_JACOBIAN(NONE(),pattern as (sparsepatternComRefs, sparsepatternComRefsT,
(independentComRefs, dependentVarsComRefs), nonZeroElements),
sparseColoring), _, _)
equation
if Flags.isSet(Flags.JAC_DUMP2) then
print("create sparse pattern for algebraic loop time: " + realString(clock()) + "\n");
BackendDump.dumpSparsityPattern(pattern, "---+++ SparsePattern +++---");
end if;
seedVars = list(makeTmpRealSimCodeVar(cr, BackendDAE.SEED_VAR()) for cr in independentComRefs);
indexVars = list(makeTmpRealSimCodeVar(cr, BackendDAE.VARIABLE()) for cr in dependentVarsComRefs);

seedVars = rewriteIndex(seedVars, 0);
indexVars = rewriteIndex(indexVars, 0);
if Flags.isSet(Flags.JAC_DUMP2) then
print("\n---+++ seedVars variables +++---\n");
print(Tpl.tplString(SimCodeDump.dumpVarsShort, seedVars));
print("\n---+++ indexVars variables +++---\n");
print(Tpl.tplString(SimCodeDump.dumpVarsShort, indexVars));
end if;
//sort sparse pattern
varsSeedIndex = listAppend(seedVars, indexVars);
//sort sparse pattern
sparseInts = sortSparsePattern(varsSeedIndex, sparsepatternComRefs, false);
sparseIntsT = sortSparsePattern(varsSeedIndex, sparsepatternComRefsT, false);

// set sparse pattern
coloring = sortColoring(seedVars, sparseColoring);
maxColor = listLength(sparseColoring);

if Flags.isSet(Flags.JAC_DUMP2) then
print("created sparse pattern for algebraic loop time: " + realString(clock()) + "\n");
end if;

then (SOME(({}, {}, "", (sparseInts, sparseIntsT), coloring, maxColor, -1)), iuniqueEqIndex, itempvars);

case (BackendDAE.GENERIC_JACOBIAN(SOME((BackendDAE.DAE(eqs={syst as BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(comps=comps))},
shared=shared), name,
independentVarsLst, residualVarsLst, dependentVarsLst)),
(sparsepatternComRefs, sparsepatternComRefsT, (_, _), _),
(sparsepatternComRefs, sparsepatternComRefsT, (_, _), nonZeroElements),
sparseColoring), _, _)
equation
if Flags.isSet(Flags.JAC_DUMP2) then
Expand Down Expand Up @@ -4208,17 +4257,16 @@ algorithm
print("analytical Jacobians -> transformed to SimCode for Matrix " + name + " time: " + realString(clock()) + "\n");
end if;

then (SOME(({(columnEquations, columnVars, s)}, seedVars, name, (sparseInts, sparseIntsT), coloring, maxColor, -1)), uniqueEqIndex, tempvars);
then (SOME(({(columnEquations, columnVars, s)}, seedVars, name, (sparseInts, sparseIntsT), coloring, maxColor, -1)), uniqueEqIndex, tempvars);

case(_, _, _)
else
equation
true = Flags.isSet(Flags.JAC_DUMP);
errorMessage = "function createSymbolicSimulationJacobian failed.";
Error.addInternalError(errorMessage, sourceInfo());
if Flags.isSet(Flags.JAC_DUMP) then
errorMessage = "function createSymbolicSimulationJacobian failed.";
Error.addInternalError(errorMessage, sourceInfo());
end if;
then (NONE(), iuniqueEqIndex, itempvars);

else (NONE(), iuniqueEqIndex, itempvars);

end matchcontinue;
end createSymbolicSimulationJacobian;

Expand Down Expand Up @@ -4672,6 +4720,17 @@ algorithm
simVar.varKind := varKind;
end setSimVarKind;

protected function makeTmpRealSimCodeVar
input DAE.ComponentRef inName;
input BackendDAE.VarKind inVarKind;
output SimCodeVar.SimVar outSimVar;
algorithm
outSimVar := SimCodeVar.SIMVAR(inName, inVarKind, "", "", "", -1 /* use -1 to get an error in simulation if something failed */,
NONE(), NONE(), NONE(), NONE(), false, DAE.T_REAL_DEFAULT,
false, NONE(), SimCodeVar.NOALIAS(), DAE.emptyElementSource,
SimCodeVar.NONECAUS(), NONE(), {}, false, false, false, NONE());
end makeTmpRealSimCodeVar;

protected function sortSparsePattern
input list<SimCodeVar.SimVar> inSimVars;
input list<tuple<DAE.ComponentRef, list<DAE.ComponentRef>>> inSparsePattern;
Expand Down Expand Up @@ -8724,6 +8783,7 @@ algorithm
a = List.map(a, addDivExpErrorMsgtoSimEqSystem);
then
(SOME(({(a, b, i)}, c, j, d, e, f, g)));
case (SOME(({},c,j,d,e,f,g))) then SOME(({},c,j,d,e,f,g));
case (NONE()) then NONE();
else
equation
Expand Down

0 comments on commit ff3d39d

Please sign in to comment.