@@ -3248,125 +3248,118 @@ algorithm
32483248 end match;
32493249end createTempVars;
32503250
3251+ // no matchcontinue needed -> try/catch around whole
3252+ // loops the eqs list -> no recursion needed
32513253protected function createNonlinearResidualEquations
32523254 input list<BackendDAE.Equation> eqs;
32533255 input Integer iuniqueEqIndex;
32543256 input list<SimCodeVar.SimVar> itempvars;
3255- output list<SimCode.SimEqSystem> eqSystems;
3256- output Integer ouniqueEqIndex;
3257- output list<SimCodeVar.SimVar> otempvars;
3257+ output list<SimCode.SimEqSystem> eqSystems = {} ;
3258+ output Integer ouniqueEqIndex = iuniqueEqIndex ;
3259+ output list<SimCodeVar.SimVar> otempvars = itempvars ;
32583260algorithm
3259- (eqSystems, ouniqueEqIndex, otempvars) := matchcontinue (eqs)
3260- local
3261- Integer size, uniqueEqIndex;
3262- DAE.Exp res_exp, e1, e2, e, lhse;
3263- list<DAE.Exp> explst, explst1;
3264- list<BackendDAE.Equation> rest;
3265- BackendDAE.Equation eq;
3266- list<SimCode.SimEqSystem> eqSystemsRest, eqSystlst;
3267- list<Integer> ds;
3268- DAE.ComponentRef left;
3269- list<DAE.Statement> algStatements;
3270- DAE.ElementSource source;
3271- list<tuple<DAE.Exp, DAE.Exp>> exptl;
3272- list<DAE.ComponentRef> crefs, crefstmp;
3273- list<SimCodeVar.SimVar> tempvars;
3274- BackendVarTransform.VariableReplacements repl;
3275- DAE.Type ty;
3276- String errorMessage;
3277- DAE.Expand crefExpand;
3278-
3279- case ({})
3280- then ({}, iuniqueEqIndex, itempvars);
3281-
3282- case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source)::rest) equation
3283- res_exp = Expression.createResidualExp(e1, e2);
3284- res_exp = Expression.replaceDerOpInExp(res_exp);
3285- (eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, iuniqueEqIndex, itempvars);
3286- then (SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source)::eqSystemsRest, uniqueEqIndex+1, tempvars);
3287-
3288- case (BackendDAE.RESIDUAL_EQUATION(exp=e, source=source)::rest) equation
3289- (res_exp, _) = ExpressionSimplify.simplify(e);
3290- res_exp = Expression.replaceDerOpInExp(res_exp);
3291- (eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, iuniqueEqIndex, itempvars);
3292- then (SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source) :: eqSystemsRest, uniqueEqIndex+1, tempvars);
3293-
3294- // An array equation
3295- case (BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source)::rest) equation
3296- ty = Expression.typeof(e1);
3297- left = ComponentReference.makeCrefIdent("$TMP_" + intString(iuniqueEqIndex), ty, {});
3298- lhse = DAE.CREF(left,ty);
3299-
3300- res_exp = Expression.createResidualExp(e1, e2);
3301- res_exp = Expression.replaceDerOpInExp(res_exp);
3302- crefstmp = ComponentReference.expandCref(left, false);
3303- explst1 = List.map(crefstmp, Expression.crefExp);
3304- (eqSystlst, uniqueEqIndex) = List.map1Fold(explst1, makeSES_RESIDUAL, source, iuniqueEqIndex);
3305- eqSystlst = SimCode.SES_ARRAY_CALL_ASSIGN(uniqueEqIndex, lhse, res_exp, source)::eqSystlst;
3306- tempvars = createArrayTempVar(left, ds, explst1, itempvars);
3307- (eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, uniqueEqIndex+1, tempvars);
3308- eqSystemsRest = listAppend(eqSystlst, eqSystemsRest);
3309- then (eqSystemsRest, uniqueEqIndex, tempvars);
3310-
3311- // A complex equation
3312- case (BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source)::rest) equation
3313- (e1, _) = ExpressionSimplify.simplify(e1);
3314- e1 = Expression.replaceDerOpInExp(e1);
3315- (e2, _) = ExpressionSimplify.simplify(e2);
3316- e2 = Expression.replaceDerOpInExp(e2);
3317- (eqSystlst, uniqueEqIndex, tempvars) = createNonlinearResidualEquationsComplex(e1, e2, source, iuniqueEqIndex, itempvars);
3318- (eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, uniqueEqIndex, tempvars);
3319- eqSystemsRest = listAppend(eqSystlst, eqSystemsRest);
3320- then (eqSystemsRest, uniqueEqIndex, tempvars);
3321-
3322- case ((eq as BackendDAE.WHEN_EQUATION(whenEquation=BackendDAE.WHEN_STMTS()))::_) equation
3323- // This following does not work. It does not take index or elseWhen into account.
3324- // The generated code for the when-equation also does not solve a linear system; it uses the variables directly.
3325- /*
3326- tp = Expression.typeof(e2);
3327- e1 = Expression.makeCrefExp(left, tp);
3328- res_exp = DAE.BINARY(e1, DAE.SUB(tp), e2);
3329- res_exp = ExpressionSimplify.simplify(res_exp);
3330- res_exp = Expression.replaceDerOpInExp(res_exp);
3331- (eqSystemsRest) = createNonlinearResidualEquations(rest, repl, uniqueEqIndex );
3332- then
3333- (SimCode.SES_RESIDUAL(0, res_exp) :: eqSystemsRest, entrylst1);
3334- */
3335- Error.addSourceMessage(Error.UNSUPPORTED_LANGUAGE_FEATURE, {"non-linear equations within when-equations", "Perform non-linear operations outside the when-equation (this is slower, but works)"}, BackendEquation.equationInfo(eq));
3336- then fail();
3337-
3338- case (BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(algStatements), source=source, expand=crefExpand)::rest) equation
3339- crefs = CheckModel.checkAndGetAlgorithmOutputs(DAE.ALGORITHM_STMTS(algStatements), source, crefExpand);
3340- // BackendDump.debugStrCrefLstStr(("Crefs : ", crefs, ", ", "\n"));
3341- (crefstmp, repl) = createTmpCrefs(crefs, iuniqueEqIndex, {}, BackendVarTransform.emptyReplacements());
3342- // BackendDump.debugStrCrefLstStr(("Crefs : ", crefstmp, ", ", "\n"));
3343- explst = List.map(crefs, Expression.crefExp);
3344- explst = List.map(explst, Expression.replaceDerOpInExp);
3261+ try
3262+ for eq in listReverse(eqs) loop
3263+ eqSystems := match (eq, ouniqueEqIndex)
3264+ local
3265+ DAE.Exp res_exp, e1, e2, e, lhse;
3266+ list<DAE.Exp> explst, explst1;
3267+ list<SimCode.SimEqSystem> eqSystlst;
3268+ list<Integer> ds;
3269+ DAE.ComponentRef left;
3270+ list<DAE.Statement> algStatements;
3271+ DAE.ElementSource source;
3272+ list<tuple<DAE.Exp, DAE.Exp>> exptl;
3273+ list<DAE.ComponentRef> crefs, crefstmp;
3274+ BackendVarTransform.VariableReplacements repl;
3275+ DAE.Type ty;
3276+ DAE.Expand crefExpand;
3277+ Integer uniqueEqIndex;
3278+
3279+ case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source), uniqueEqIndex) equation
3280+ res_exp = Expression.createResidualExp(e1, e2);
3281+ res_exp = Expression.replaceDerOpInExp(res_exp);
3282+ ouniqueEqIndex = uniqueEqIndex + 1;
3283+ then SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source)::eqSystems;
3284+
3285+ case (BackendDAE.RESIDUAL_EQUATION(exp=e, source=source), uniqueEqIndex) equation
3286+ (res_exp, _) = ExpressionSimplify.simplify(e);
3287+ res_exp = Expression.replaceDerOpInExp(res_exp);
3288+ ouniqueEqIndex = uniqueEqIndex + 1;
3289+ then SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source) :: eqSystems;
3290+
3291+ // An array equation
3292+ case (BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source), uniqueEqIndex) equation
3293+ ty = Expression.typeof(e1);
3294+ left = ComponentReference.makeCrefIdent("$TMP_" + intString(uniqueEqIndex), ty, {});
3295+ lhse = DAE.CREF(left,ty);
3296+
3297+ res_exp = Expression.createResidualExp(e1, e2);
3298+ res_exp = Expression.replaceDerOpInExp(res_exp);
3299+ crefstmp = ComponentReference.expandCref(left, false);
3300+ explst1 = List.map(crefstmp, Expression.crefExp);
3301+ (eqSystlst, uniqueEqIndex) = List.map1Fold(explst1, makeSES_RESIDUAL, source, uniqueEqIndex);
3302+ eqSystlst = SimCode.SES_ARRAY_CALL_ASSIGN(uniqueEqIndex, lhse, res_exp, source)::eqSystlst;
3303+ otempvars = createArrayTempVar(left, ds, explst1, otempvars);
3304+ ouniqueEqIndex = uniqueEqIndex + 1;
3305+ then listAppend(eqSystlst, eqSystems);
3306+
3307+ // A complex equation
3308+ case (BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source), uniqueEqIndex) equation
3309+ (e1, _) = ExpressionSimplify.simplify(e1);
3310+ e1 = Expression.replaceDerOpInExp(e1);
3311+ (e2, _) = ExpressionSimplify.simplify(e2);
3312+ e2 = Expression.replaceDerOpInExp(e2);
3313+ (eqSystlst, ouniqueEqIndex, otempvars) = createNonlinearResidualEquationsComplex(e1, e2, source, uniqueEqIndex, otempvars);
3314+ then listAppend(eqSystlst, eqSystems);
3315+
3316+ case (BackendDAE.WHEN_EQUATION(whenEquation=BackendDAE.WHEN_STMTS()), _) equation
3317+ // This following does not work. It does not take index or elseWhen into account.
3318+ // The generated code for the when-equation also does not solve a linear system; it uses the variables directly.
3319+ /*
3320+ tp = Expression.typeof(e2);
3321+ e1 = Expression.makeCrefExp(left, tp);
3322+ res_exp = DAE.BINARY(e1, DAE.SUB(tp), e2);
3323+ res_exp = ExpressionSimplify.simplify(res_exp);
3324+ res_exp = Expression.replaceDerOpInExp(res_exp);
3325+ (eqSystemsRest) = createNonlinearResidualEquations(rest, repl, uniqueEqIndex );
3326+ then
3327+ (SimCode.SES_RESIDUAL(0, res_exp) :: eqSystemsRest, entrylst1);
3328+ */
3329+ Error.addSourceMessage(Error.UNSUPPORTED_LANGUAGE_FEATURE, {"non-linear equations within when-equations", "Perform non-linear operations outside the when-equation (this is slower, but works)"}, BackendEquation.equationInfo(eq));
3330+ then fail();
33453331
3346- // BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0);
3347- (algStatements, _) = BackendVarTransform.replaceStatementLst(algStatements, repl, SOME(BackendVarTransform.skipPreOperator), {}, false);
3348- // BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0);
3332+ case (BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(algStatements), source=source, expand=crefExpand), uniqueEqIndex) equation
3333+ crefs = CheckModel.checkAndGetAlgorithmOutputs(DAE.ALGORITHM_STMTS(algStatements), source, crefExpand);
3334+ // BackendDump.debugStrCrefLstStr(("Crefs : ", crefs, ", ", "\n"));
3335+ (crefstmp, repl) = createTmpCrefs(crefs, uniqueEqIndex, {}, BackendVarTransform.emptyReplacements());
3336+ // BackendDump.debugStrCrefLstStr(("Crefs : ", crefstmp, ", ", "\n"));
3337+ explst = List.map(crefs, Expression.crefExp);
3338+ explst = List.map(explst, Expression.replaceDerOpInExp);
33493339
3350- explst1 = List.map(crefstmp, Expression.crefExp );
3351- explst1 = List.map(explst1, Expression.replaceDerOpInExp );
3352- tempvars = createTempVarsforCrefs(explst1, itempvars );
3340+ // BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0 );
3341+ (algStatements, _) = BackendVarTransform.replaceStatementLst(algStatements, repl, SOME(BackendVarTransform.skipPreOperator), {}, false );
3342+ // BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0 );
33533343
3354- // 0 = a - tmp
3355- exptl = List.threadTuple(explst, explst1 );
3356- (eqSystlst, uniqueEqIndex) = List.map1Fold(exptl, makeSES_RESIDUAL1, source, iuniqueEqIndex );
3344+ explst1 = List.map(crefstmp, Expression.crefExp);
3345+ explst1 = List.map(explst1, Expression.replaceDerOpInExp );
3346+ otempvars = createTempVarsforCrefs(explst1, otempvars );
33573347
3358- eqSystlst = SimCode.SES_ALGORITHM(uniqueEqIndex, algStatements)::eqSystlst;
3359- // Tpl.tplPrint(SimCodeDump.dumpEqs, eqSystlst);
3348+ // 0 = a - tmp
3349+ exptl = List.threadTuple(explst, explst1);
3350+ (eqSystlst, uniqueEqIndex) = List.map1Fold(exptl, makeSES_RESIDUAL1, source, uniqueEqIndex);
33603351
3361- (eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, uniqueEqIndex+1, tempvars);
3362- eqSystemsRest = listAppend(eqSystlst, eqSystemsRest);
3363- then (eqSystemsRest, uniqueEqIndex, tempvars);
3352+ eqSystlst = SimCode.SES_ALGORITHM(uniqueEqIndex, algStatements)::eqSystlst;
3353+ // Tpl.tplPrint(SimCodeDump.dumpEqs, eqSystlst);
33643354
3365- case (eq::_) equation
3366- errorMessage = "function createNonlinearResidualEquations failed for equation: " + BackendDump.equationString(eq);
3367- Error.addSourceMessage(Error.INTERNAL_ERROR, {errorMessage}, BackendEquation.equationInfo(eq));
3368- then fail();
3369- end matchcontinue;
3355+ ouniqueEqIndex = uniqueEqIndex + 1;
3356+ then listAppend(eqSystlst, eqSystems);
3357+ end match;
3358+ end for;
3359+ else
3360+ Error.addMessage(Error.INTERNAL_ERROR, {"function createNonlinearResidualEquations failed"});
3361+ fail();
3362+ end try;
33703363end createNonlinearResidualEquations;
33713364
33723365public function dimsToAllIndexes
@@ -5865,7 +5858,7 @@ algorithm
58655858 // wbraun:
58665859 // TODO: Fix createNonlinearResidualEquations support cases where
58675860 // solved variables are on rhs and also lhs. This is not
5868- // cosidered yet there.
5861+ // considered yet there.
58695862 (resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations({inEquation}, iuniqueEqIndex, itempvars);
58705863 (_, homotopySupport) = BackendEquation.traverseExpsOfEquation(inEquation, BackendDAEUtil.containsHomotopyCall, false);
58715864 then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, crefs, 0, listLength(inVars)+listLength(tempvars)-listLength(itempvars), NONE(), homotopySupport, false, false), NONE())}, uniqueEqIndex+1, tempvars);
0 commit comments