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

Commit 368ac8c

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Refactor SimCode.createEquation
Belonging to [master]: - #2360
1 parent 7a3a58f commit 368ac8c

File tree

1 file changed

+84
-112
lines changed

1 file changed

+84
-112
lines changed

Compiler/SimCode/SimCodeUtil.mo

Lines changed: 84 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,16 +2017,19 @@ protected function createEquation
20172017
output list<SimCode.SimEqSystem> equation_;
20182018
output Integer ouniqueEqIndex;
20192019
output list<SimCodeVar.SimVar> otempvars;
2020+
protected
2021+
BackendDAE.Variables vars;
2022+
BackendDAE.EquationArray eqns;
2023+
BackendDAE.Equation eqn;
20202024
algorithm
2021-
(equation_, ouniqueEqIndex, otempvars) := matchcontinue (eqNum, varNum, syst, shared, skipDiscInAlgorithm, iuniqueEqIndex, itempvars)
2025+
BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) := syst;
2026+
eqn := BackendEquation.get(eqns, eqNum);
2027+
(equation_, ouniqueEqIndex, otempvars) := match eqn
20222028
local
20232029
DAE.ComponentRef cr;
20242030
BackendDAE.VarKind kind;
20252031
Option<DAE.VariableAttributes> values;
20262032
BackendDAE.Var v;
2027-
BackendDAE.Variables vars;
2028-
BackendDAE.EquationArray eqns;
2029-
BackendDAE.Equation eqn;
20302033
Integer uniqueEqIndex;
20312034
list<DAE.Statement> algStatements;
20322035
list<DAE.ComponentRef> conditions, solveCr;
@@ -2050,21 +2053,20 @@ algorithm
20502053
list<BackendDAE.WhenOperator> whenStmtLst;
20512054
Option<SimCode.SimEqSystem> oelseWhenSimEq;
20522055
BackendDAE.EquationAttributes eqAttr;
2056+
Boolean b;
20532057

20542058
// solved equation
2055-
case (_, _, BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns), _, _, _, _)
2059+
case BackendDAE.SOLVED_EQUATION(exp=e2, source=source, attr=eqAttr)
20562060
equation
2057-
BackendDAE.SOLVED_EQUATION(exp=e2, source=source, attr=eqAttr) = BackendEquation.get(eqns, eqNum);
20582061
(v as BackendDAE.VAR(varName = cr)) = BackendVariable.getVarAt(vars, varNum);
20592062
varexp = Expression.crefExp(cr);
20602063
varexp = if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
20612064
then
20622065
({SimCode.SES_SIMPLE_ASSIGN(iuniqueEqIndex, cr, e2, source, eqAttr)}, iuniqueEqIndex+1, itempvars);
20632066

20642067
// when eq
2065-
case (_, _, BackendDAE.EQSYSTEM(orderedEqs=eqns), BackendDAE.SHARED(), _, _, _)
2068+
case BackendDAE.WHEN_EQUATION(whenEquation=whenEquation, source=source, attr=eqAttr)
20662069
equation
2067-
BackendDAE.WHEN_EQUATION(whenEquation=whenEquation, source=source, attr=eqAttr) = BackendEquation.get(eqns, eqNum);
20682070
BackendDAE.WHEN_STMTS(cond, whenStmtLst, oelseWhen) = whenEquation;
20692071
if isSome(oelseWhen) then
20702072
SOME(elseWhen) = oelseWhen;
@@ -2079,120 +2081,90 @@ algorithm
20792081
({SimCode.SES_WHEN(iuniqueEqIndex, conditions, initialCall, whenStmtLst, oelseWhenSimEq, source, eqAttr)}, uniqueEqIndex+1, itempvars);
20802082

20812083
// single equation
2082-
case (_, _, BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns), _, _, _, _)
2083-
equation
2084-
eqn = BackendEquation.get(eqns, eqNum);
2085-
BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr) = eqn;
2086-
(v as BackendDAE.VAR(varName = cr)) = BackendVariable.getVarAt(vars, varNum);
2087-
varexp = Expression.crefExp(cr);
2088-
varexp = if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
2089-
BackendDAE.SHARED(functionTree = funcs) = shared;
2090-
(exp_, asserts, solveEqns, solveCr) = ExpressionSolve.solve2(e1, e2, varexp, SOME(funcs), SOME(iuniqueEqIndex), true, BackendDAEUtil.isSimulationDAE(shared));
2091-
solveEqns = listReverse(solveEqns);
2092-
solveCr = listReverse(solveCr);
2093-
cr = if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
2094-
source = ElementSource.addSymbolicTransformationSolve(true, source, cr, e1, e2, exp_, asserts);
2095-
(eqSystlst, uniqueEqIndex) = List.mapFold(solveEqns, makeSolved_SES_SIMPLE_ASSIGN, iuniqueEqIndex);
2096-
if listEmpty(cons) then
2097-
(resEqs, uniqueEqIndex) = addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN(uniqueEqIndex, cr, exp_, source, eqAttr)}, uniqueEqIndex+1);
2084+
case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr)
2085+
algorithm
2086+
(v as BackendDAE.VAR(varName = cr)) := BackendVariable.getVarAt(vars, varNum);
2087+
varexp := Expression.crefExp(cr);
2088+
varexp := if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
2089+
BackendDAE.SHARED(functionTree = funcs) := shared;
2090+
b := true;
2091+
try
2092+
(exp_, asserts, solveEqns, solveCr) := ExpressionSolve.solve2(e1, e2, varexp, SOME(funcs), SOME(iuniqueEqIndex), true, BackendDAEUtil.isSimulationDAE(shared));
20982093
else
2099-
(resEqs, uniqueEqIndex) = addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(uniqueEqIndex, cr, exp_, source, cons, eqAttr)}, uniqueEqIndex+1);
2094+
b := false;
2095+
end try;
2096+
if b then
2097+
solveEqns := listReverse(solveEqns);
2098+
solveCr := listReverse(solveCr);
2099+
cr := if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
2100+
source := ElementSource.addSymbolicTransformationSolve(true, source, cr, e1, e2, exp_, asserts);
2101+
(eqSystlst, uniqueEqIndex) := List.mapFold(solveEqns, makeSolved_SES_SIMPLE_ASSIGN, iuniqueEqIndex);
2102+
if listEmpty(cons) then
2103+
(resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN(uniqueEqIndex, cr, exp_, source, eqAttr)}, uniqueEqIndex+1);
2104+
else
2105+
(resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(uniqueEqIndex, cr, exp_, source, cons, eqAttr)}, uniqueEqIndex+1);
2106+
end if;
2107+
eqSystlst := listAppend(eqSystlst,resEqs);
2108+
tempvars := createTempVarsforCrefs(List.map(solveCr, Expression.crefExp),itempvars);
2109+
else
2110+
if match (e1,e2) case (DAE.RCONST(),DAE.IFEXP()) then true; else false; end match then
2111+
try
2112+
// single equation from if-equation -> 0.0 = if .. then bla else lbu and var is not in all branches
2113+
// change branches without variable to var - pre(var)
2114+
prevarexp := Expression.makePureBuiltinCall("pre", {varexp}, Expression.typeof(varexp));
2115+
prevarexp := Expression.expSub(varexp, prevarexp);
2116+
(e2, _) := Expression.traverseExpBottomUp(e2, replaceIFBrancheswithoutVar, (varexp, prevarexp));
2117+
eqn := BackendDAE.EQUATION(e1, e2, source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN);
2118+
(resEqs, uniqueEqIndex, tempvars) := createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars);
2119+
cr := if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
2120+
(_, homotopySupport) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
2121+
eqSystlst := {SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, {cr}, 0, 1, NONE(), homotopySupport, false, false), NONE(), eqAttr)};
2122+
uniqueEqIndex := uniqueEqIndex + 1;
2123+
else
2124+
b := false;
2125+
end try;
2126+
else
2127+
b := false;
2128+
end if;
2129+
if not b then
2130+
// non-linear
2131+
(resEqs, uniqueEqIndex, tempvars) := createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars);
2132+
cr := if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
2133+
(_, homotopySupport) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
2134+
eqSystlst := {SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, {cr}, 0, 1, NONE(), homotopySupport, false, false), NONE(), eqAttr)};
2135+
uniqueEqIndex := uniqueEqIndex+1;
2136+
end if;
21002137
end if;
2101-
eqSystlst = listAppend(eqSystlst,resEqs);
2102-
tempvars = createTempVarsforCrefs(List.map(solveCr, Expression.crefExp),itempvars);
2103-
then
2104-
(eqSystlst, uniqueEqIndex,tempvars);
2105-
2106-
// single equation from if-equation -> 0.0 = if .. then bla else lbu and var is not in all branches
2107-
// change branches without variable to var - pre(var)
2108-
case (_, _, BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns), _, _, _, _)
2109-
equation
2110-
BackendDAE.EQUATION(exp=e1 as DAE.RCONST(_), scalar=e2 as DAE.IFEXP(), source=source, attr=eqAttr) = BackendEquation.get(eqns, eqNum);
2111-
(v as BackendDAE.VAR(varName = cr)) = BackendVariable.getVarAt(vars, varNum);
2112-
varexp = Expression.crefExp(cr);
2113-
varexp = if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
2114-
failure((_, _) = ExpressionSolve.solve(e1, e2, varexp));
2115-
prevarexp = Expression.makePureBuiltinCall("pre", {varexp}, Expression.typeof(varexp));
2116-
prevarexp = Expression.expSub(varexp, prevarexp);
2117-
(e2, _) = Expression.traverseExpBottomUp(e2, replaceIFBrancheswithoutVar, (varexp, prevarexp));
2118-
eqn = BackendDAE.EQUATION(e1, e2, source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN);
2119-
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars);
2120-
cr = if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
2121-
(_, homotopySupport) = BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
2122-
then
2123-
({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, {cr}, 0, 1, NONE(), homotopySupport, false, false), NONE(), eqAttr)}, uniqueEqIndex+1, tempvars);
2124-
2125-
// non-linear
2126-
case (_, _, BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns), _, _, _, _)
2127-
equation
2128-
(eqn as BackendDAE.EQUATION(exp=e1, scalar=e2, attr=eqAttr)) = BackendEquation.get(eqns, eqNum);
2129-
(v as BackendDAE.VAR(varName = cr)) = BackendVariable.getVarAt(vars, varNum);
2130-
varexp = Expression.crefExp(cr);
2131-
varexp = if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
2132-
failure((_, _) = ExpressionSolve.solve(e1, e2, varexp));
2133-
// index = System.tmpTick();
2134-
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations({eqn}, iuniqueEqIndex, itempvars);
2135-
cr = if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
2136-
(_, homotopySupport) = BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
2137-
then
2138-
({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, {cr}, 0, 1, NONE(), homotopySupport, false, false), NONE(), eqAttr)}, uniqueEqIndex+1, tempvars);
2138+
then (eqSystlst, uniqueEqIndex,tempvars);
21392139

21402140
// Algorithm for single variable.
2141-
case (_, _, BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns), _, true, _, _)
2142-
equation
2143-
BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand, attr=eqAttr) = BackendEquation.get(eqns, eqNum);
2144-
varOutput::{} = CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
2145-
v = BackendVariable.getVarAt(vars, varNum);
2146-
// The output variable of the algorithm must be the variable solved
2147-
// for, otherwise we need to solve an inverse problem of an algorithm
2148-
// section.
2149-
true = ComponentReference.crefEqualNoStringCompare(BackendVariable.varCref(v), varOutput);
2150-
DAE.ALGORITHM_STMTS(algStatements) = BackendDAEUtil.collateAlgorithm(alg, NONE());
2151-
algStatements = BackendDAEUtil.removeDiscreteAssignments(algStatements, vars);
2152-
then
2153-
({SimCode.SES_ALGORITHM(iuniqueEqIndex, algStatements, eqAttr)}, iuniqueEqIndex+1, itempvars);
2154-
2155-
// algorithm for single variable
2156-
case (_, _, BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns), _,false, _, _)
2157-
equation
2158-
BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand, attr=eqAttr) = BackendEquation.get(eqns, eqNum);
2159-
varOutput::{} = CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
2160-
v = BackendVariable.getVarAt(vars, varNum);
2141+
case BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand, attr=eqAttr)
2142+
algorithm
2143+
varOutput::{} := CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
2144+
v := BackendVariable.getVarAt(vars, varNum);
21612145
// The output variable of the algorithm must be the variable solved
21622146
// for, otherwise we need to solve an inverse problem of an algorithm
21632147
// section.
2164-
true = ComponentReference.crefEqualNoStringCompare(BackendVariable.varCref(v), varOutput);
2165-
DAE.ALGORITHM_STMTS(algStatements) = BackendDAEUtil.collateAlgorithm(alg, NONE());
2166-
then
2167-
({SimCode.SES_ALGORITHM(iuniqueEqIndex, algStatements, eqAttr)}, iuniqueEqIndex+1, itempvars);
2168-
2169-
// inverse Algorithm for single variable
2170-
case (_, _, BackendDAE.EQSYSTEM(orderedVars = vars, orderedEqs = eqns), _, _, _, _)
2171-
equation
2172-
BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand, attr=eqAttr) = BackendEquation.get(eqns, eqNum);
2173-
varOutput::{} = CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
2174-
v = BackendVariable.getVarAt(vars, varNum);
2175-
// We need to solve an inverse problem of an algorithm section.
2176-
false = ComponentReference.crefEqualNoStringCompare(BackendVariable.varCref(v), varOutput);
2177-
DAE.ALGORITHM_STMTS(algStatements) = BackendDAEUtil.collateAlgorithm(alg, NONE());
2178-
algStatements = solveAlgorithmInverse(algStatements, {v});
2148+
DAE.ALGORITHM_STMTS(algStatements) := BackendDAEUtil.collateAlgorithm(alg, NONE());
2149+
if ComponentReference.crefEqualNoStringCompare(BackendVariable.varCref(v), varOutput) then
2150+
if skipDiscInAlgorithm then
2151+
algStatements := BackendDAEUtil.removeDiscreteAssignments(algStatements, vars);
2152+
end if;
2153+
else
2154+
try
2155+
algStatements := solveAlgorithmInverse(algStatements, {v});
2156+
else
2157+
algStr := DAEDump.dumpAlgorithmsStr({DAE.ALGORITHM(alg, source)});
2158+
message := ComponentReference.printComponentRefStr(BackendVariable.varCref(v));
2159+
message := stringAppendList({"Inverse Algorithm needs to be solved for ", message, " in \n", algStr, "This has not been implemented yet.\n"});
2160+
Error.addInternalError(message, sourceInfo());
2161+
fail();
2162+
end try;
2163+
end if;
21792164
then
21802165
({SimCode.SES_ALGORITHM(iuniqueEqIndex, algStatements, eqAttr)}, iuniqueEqIndex+1, itempvars);
21812166

2182-
// inverse Algorithm for single variable failed
2183-
case (_, _, BackendDAE.EQSYSTEM(orderedVars = vars, orderedEqs = eqns), _, _, _, _)
2184-
equation
2185-
BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand, attr=eqAttr) = BackendEquation.get(eqns, eqNum);
2186-
varOutput::{} = CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
2187-
v = BackendVariable.getVarAt(vars, varNum);
2188-
// We need to solve an inverse problem of an algorithm section.
2189-
false = ComponentReference.crefEqualNoStringCompare(BackendVariable.varCref(v), varOutput);
2190-
algStr = DAEDump.dumpAlgorithmsStr({DAE.ALGORITHM(alg, source)});
2191-
message = ComponentReference.printComponentRefStr(BackendVariable.varCref(v));
2192-
message = stringAppendList({"Inverse Algorithm needs to be solved for ", message, " in \n", algStr, "This has not been implemented yet.\n"});
2193-
Error.addInternalError(message, sourceInfo());
2194-
then fail();
2195-
end matchcontinue;
2167+
end match;
21962168
end createEquation;
21972169

21982170
protected function replaceIFBrancheswithoutVar

0 commit comments

Comments
 (0)