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

Commit

Permalink
[BE] add support for if equations as residual equations
Browse files Browse the repository at this point in the history
Belonging to [master]:
  - #2774
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed Nov 7, 2018
1 parent 19ec6d1 commit 5c46636
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 17 deletions.
48 changes: 44 additions & 4 deletions Compiler/BackEnd/BackendEquation.mo
Expand Up @@ -1345,18 +1345,20 @@ algorithm

outEquations := match (inEquation)
local
DAE.Exp e, e1, e2, exp;
DAE.Exp e, e1, e2, exp, cond;
DAE.ComponentRef cr;
DAE.ElementSource source;
BackendDAE.Equation backendEq;
list<Integer> ds;
Integer size;
list<DAE.Exp> explst, explst2;
list<BackendDAE.Equation> eqns;
Integer size, i, branches;
list<DAE.Exp> explst, explst2, condExps;
list<BackendDAE.Equation> eqns, eqnsfalse;
list<list<BackendDAE.Equation>> eqnstrue;
list<list<DAE.Subscript>> subslst;
Real r;
BackendDAE.EquationAttributes attr;
list<DAE.ComponentRef> crlst, crlst2;
array<list<DAE.Exp>> expA;

case (BackendDAE.EQUATION(exp=DAE.TUPLE(explst), scalar=e2, source=source, attr=attr)) equation
((_, eqns)) = List.fold3(explst,equationTupleToScalarResidualForm, e2, source, attr, (1, {}));
Expand Down Expand Up @@ -1425,6 +1427,42 @@ algorithm
exp = Expression.createResidualExp(e1, e2);
then {BackendDAE.RESIDUAL_EQUATION(exp, source, attr)};

case (BackendDAE.IF_EQUATION(conditions=condExps, eqnstrue=eqnstrue, eqnsfalse=eqnsfalse, source=source, attr=attr))
algorithm
branches := listLength(condExps);
expA := arrayCreate(branches, {});
// create array<list<exp>> with true branches
for eqLst in eqnstrue loop
i := 1;
for eq in eqLst loop
{BackendDAE.RESIDUAL_EQUATION(e1, _, _)} := equationToScalarResidualForm(eq, funcTree);
expA := Array.consToElement(i, e1, expA);
i := i + 1;
end for;
end for;
// add also else branches
i := 1;
for eq in eqnsfalse loop
{BackendDAE.RESIDUAL_EQUATION(e1, _, _)} := equationToScalarResidualForm(eq, funcTree);
expA := Array.consToElement(i, e1, expA);
i := i + 1;
end for;

eqns := {};
for i in 1:branches loop
explst := arrayGet(expA, i);
//get else branch
e2::explst := explst;
explst2 := condExps;
for e1 in explst loop
cond::explst2 := explst2;
e2 := DAE.IFEXP(cond, e1, e2);
end for;
eqns := BackendDAE.RESIDUAL_EQUATION(e2, source, attr)::eqns;
//BackendDump.printEquationList(eqns);
end for;
then eqns;

case (backendEq as BackendDAE.RESIDUAL_EQUATION())
then {backendEq};

Expand Down Expand Up @@ -1499,6 +1537,8 @@ algorithm
DAE.ElementSource source;
BackendDAE.Equation backendEq;
BackendDAE.EquationAttributes eqAttr;
list<list<BackendDAE.Equation>> eqnstrue;
list<BackendDAE.Equation> eqnsfalse;

case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr)) equation
//ExpressionDump.dumpExpWithTitle("equationToResidualForm 1\n", e2);
Expand Down
2 changes: 1 addition & 1 deletion Compiler/SimCode/SimCodeMain.mo
Expand Up @@ -1146,7 +1146,7 @@ algorithm
//initialEquations := listReverse(initialEquations);

// generate equations for removed initial equations
(removedInitialEquations, uniqueEqIndex, tempVars) := SimCodeUtil.createNonlinearResidualEquations(inRemovedInitialEquationLst, uniqueEqIndex, tempVars);
(removedInitialEquations, uniqueEqIndex, tempVars) := SimCodeUtil.createNonlinearResidualEquations(inRemovedInitialEquationLst, uniqueEqIndex, tempVars, inBackendDAE.shared.functionTree);
//removedInitialEquations := listReverse(removedInitialEquations);

ExecStat.execStat("simCode: created initialization part");
Expand Down
34 changes: 22 additions & 12 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -310,7 +310,7 @@ algorithm
end if;

// generate equations for removed initial equations
(removedInitialEquations, uniqueEqIndex, tempvars) := createNonlinearResidualEquations(inRemovedInitialEquationLst, uniqueEqIndex, tempvars);
(removedInitialEquations, uniqueEqIndex, tempvars) := createNonlinearResidualEquations(inRemovedInitialEquationLst, uniqueEqIndex, tempvars, dlow.shared.functionTree);

execStat("simCode: created initialization part");

Expand Down Expand Up @@ -1626,7 +1626,7 @@ algorithm
(eqnlst, varlst,_) = BackendDAETransform.getEquationAndSolvedVar(comp, syst.orderedEqs, syst.orderedVars);
// States are solved for der(x) not x.
varlst = List.map(varlst, BackendVariable.transformXToXd);
(equations1, uniqueEqIndex1, tempvars) = createSingleComplexEqnCode(listHead(eqnlst), varlst, uniqueEqIndex, tempvars, shared.info, true);
(equations1, uniqueEqIndex1, tempvars) = createSingleComplexEqnCode(listHead(eqnlst), varlst, uniqueEqIndex, tempvars, shared.info, true, shared.functionTree);

eqSccMapping = appendSccIdx(uniqueEqIndex1-1, sccIndex, eqSccMapping);
eqBackendSimCodeMapping = appendSccIdxRange(uniqueEqIndex, uniqueEqIndex1 - 1, e, eqBackendSimCodeMapping);
Expand Down Expand Up @@ -1850,7 +1850,7 @@ algorithm
(eqnlst, varlst,_) = BackendDAETransform.getEquationAndSolvedVar(comp, eqns, vars);
// States are solved for der(x) not x.
varlst = List.map(varlst, BackendVariable.transformXToXd);
(equations1, uniqueEqIndex, tempvars) = createSingleComplexEqnCode(listHead(eqnlst), varlst, iuniqueEqIndex, itempvars, ei, genDiscrete);
(equations1, uniqueEqIndex, tempvars) = createSingleComplexEqnCode(listHead(eqnlst), varlst, iuniqueEqIndex, itempvars, ei, genDiscrete, shared.functionTree);
then (equations1, equations1, uniqueEqIndex, tempvars);

// A single when equation
Expand Down Expand Up @@ -2189,7 +2189,7 @@ algorithm
prevarexp := Expression.expSub(varexp, prevarexp);
(e2, _) := Expression.traverseExpBottomUp(e2, replaceIFBrancheswithoutVar, (varexp, prevarexp));
eqn := BackendDAE.EQUATION(e1, e2, source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN);
(resEqs, uniqueEqIndex, tempvars) := createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars);
(resEqs, uniqueEqIndex, tempvars) := createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars, shared.functionTree);
cr := if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
(_, homotopySupport) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
eqSystlst := {SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, {cr}, 0, 1, NONE(), homotopySupport, false, false), NONE(), eqAttr)};
Expand All @@ -2202,7 +2202,7 @@ algorithm
end if;
if not b then
// non-linear
(resEqs, uniqueEqIndex, tempvars) := createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars);
(resEqs, uniqueEqIndex, tempvars) := createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars, shared.functionTree);
cr := if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
(_, homotopySupport) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
eqSystlst := {SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, {cr}, 0, 1, NONE(), homotopySupport, false, false), NONE(), eqAttr)};
Expand Down Expand Up @@ -2817,6 +2817,7 @@ public function createNonlinearResidualEquations
input list<BackendDAE.Equation> eqs;
input Integer iuniqueEqIndex;
input list<SimCodeVar.SimVar> itempvars;
input DAE.FunctionTree funcTree;
output list<SimCode.SimEqSystem> eqSystems = {};
output Integer ouniqueEqIndex = iuniqueEqIndex;
output list<SimCodeVar.SimVar> otempvars = itempvars;
Expand All @@ -2839,6 +2840,8 @@ algorithm
DAE.Expand crefExpand;
Integer uniqueEqIndex;
BackendDAE.EquationAttributes eqAttr;
BackendDAE.Equation ifEq;
list<BackendDAE.Equation> resEqs;

case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr), uniqueEqIndex) equation
res_exp = Expression.createResidualExp(e1, e2);
Expand All @@ -2851,6 +2854,11 @@ algorithm
res_exp = Expression.replaceDerOpInExp(res_exp);
ouniqueEqIndex = uniqueEqIndex + 1;
then SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source, eqAttr) :: eqSystems;
// if equations
case (ifEq as BackendDAE.IF_EQUATION(), uniqueEqIndex) equation
resEqs = BackendEquation.equationToScalarResidualForm(ifEq, funcTree);
(eqSystlst,ouniqueEqIndex,otempvars) = createNonlinearResidualEquations(resEqs, uniqueEqIndex-1, otempvars, funcTree);
then eqSystlst;

// An array equation
case (BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source, attr=eqAttr), uniqueEqIndex) equation
Expand Down Expand Up @@ -3265,7 +3273,8 @@ algorithm
end if;
eqn_lst = BackendEquation.equationList(inEquationArray);
crefs = BackendVariable.getAllCrefFromVariables(inVars);
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(eqn_lst, iuniqueEqIndex, itempvars);

(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(eqn_lst, iuniqueEqIndex, itempvars, inFuncs);
// create symbolic jacobian for simulation
(jacobianMatrix, uniqueEqIndex, tempvars) = createSymbolicSimulationJacobian(inJacobian, uniqueEqIndex, tempvars);
(_, homotopySupport) = BackendEquation.traverseExpsOfEquationList(eqn_lst, BackendDAEUtil.containsHomotopyCall, false);
Expand All @@ -3278,7 +3287,7 @@ algorithm
end if;
eqn_lst = BackendEquation.equationList(inEquationArray);
crefs = BackendVariable.getAllCrefFromVariables(inVars);
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(eqn_lst, iuniqueEqIndex, itempvars);
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(eqn_lst, iuniqueEqIndex, itempvars, inFuncs);
(_, homotopySupport) = BackendEquation.traverseExpsOfEquationList(eqn_lst, BackendDAEUtil.containsHomotopyCall, false);
then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, crefs, 0, inVars.numberOfVars+listLength(tempvars)-listLength(itempvars), NONE(), homotopySupport, mixedSystem, false), NONE(), BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)}, uniqueEqIndex+1, tempvars);

Expand Down Expand Up @@ -3394,7 +3403,7 @@ algorithm
reqns = BackendEquation.replaceDerOpInEquationList(reqns);
// generate other equations
(simequations, uniqueEqIndex, tempvars, nInnerVars, _) = createTornSystemInnerEqns(innerEquations, skipDiscInAlgorithm, genDiscrete, isyst, ishared, iuniqueEqIndex, itempvars, {});
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars);
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars, ishared.functionTree);
simequations = listAppend(simequations, resEqs);

(jacobianMatrix, uniqueEqIndex, tempvars) = createSymbolicSimulationJacobian(inJacobian, uniqueEqIndex, tempvars);
Expand All @@ -3415,7 +3424,7 @@ algorithm
reqns = BackendEquation.replaceDerOpInEquationList(reqns);
// generate other equations
(simequations, uniqueEqIndex, tempvars2, nInnerVars, _) = createTornSystemInnerEqns(innerEquations, skipDiscInAlgorithm, genDiscrete, isyst, ishared, uniqueEqIndex+1, tempvars, {});
(resEqs, uniqueEqIndex, tempvars2) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars2);
(resEqs, uniqueEqIndex, tempvars2) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars2, ishared.functionTree);
simequations = listAppend(simequations, resEqs);

(jacobianMatrix, uniqueEqIndex, tempvars2) = createSymbolicSimulationJacobian(inJacobian, uniqueEqIndex, tempvars2);
Expand All @@ -3440,7 +3449,7 @@ algorithm
tcrs = List.map(tvars, BackendVariable.varCref);
// generate other equations
(simequations, uniqueEqIndex, tempvars, nInnerVars, homotopySupport) = createTornSystemInnerEqns(innerEquations, skipDiscInAlgorithm, genDiscrete, isyst, ishared, iuniqueEqIndex, itempvars, {});
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars);
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars, ishared.functionTree);
simequations = listAppend(simequations, resEqs);

(jacobianMatrix, uniqueEqIndex, tempvars) = createSymbolicSimulationJacobian(inJacobian, uniqueEqIndex, tempvars);
Expand All @@ -3465,7 +3474,7 @@ algorithm
tcrs = List.map(tvars, BackendVariable.varCref);
// generate other equations
(simequations, uniqueEqIndex, tempvars2, nInnerVars, homotopySupport) = createTornSystemInnerEqns(innerEquations, skipDiscInAlgorithm, genDiscrete, isyst, ishared, uniqueEqIndex+1, tempvars, {});
(resEqs, uniqueEqIndex, tempvars2) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars2);
(resEqs, uniqueEqIndex, tempvars2) = createNonlinearResidualEquations(reqns, uniqueEqIndex, tempvars2, ishared.functionTree);
simequations = listAppend(simequations, resEqs);

(jacobianMatrix, uniqueEqIndex, tempvars2) = createSymbolicSimulationJacobian(inJacobian, uniqueEqIndex, tempvars2);
Expand Down Expand Up @@ -5122,6 +5131,7 @@ protected function createSingleComplexEqnCode
input list<SimCodeVar.SimVar> itempvars;
input BackendDAE.ExtraInfo iextra;
input Boolean genDiscrete;
input DAE.FunctionTree funcTree;
output list<SimCode.SimEqSystem> equations_;
output Integer ouniqueEqIndex;
output list<SimCodeVar.SimVar> otempvars;
Expand Down Expand Up @@ -5174,7 +5184,7 @@ algorithm
// TODO: Fix createNonlinearResidualEquations support cases where
// solved variables are on rhs and also lhs. This is not
// considered yet there.
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations({inEquation}, iuniqueEqIndex, itempvars);
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations({inEquation}, iuniqueEqIndex, itempvars, funcTree);
(_, homotopySupport) = BackendEquation.traverseExpsOfEquation(inEquation, BackendDAEUtil.containsHomotopyCall, false);
then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, crefs, 0, listLength(inVars)+listLength(tempvars)-listLength(itempvars), NONE(), homotopySupport, false, false), NONE(), eqAttr)}, uniqueEqIndex+1, tempvars);

Expand Down

0 comments on commit 5c46636

Please sign in to comment.