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

Separation of back end transformations for simulation and initialization #199

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Compiler/BackEnd/BackendDAE.mo
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ encapsulated package BackendDAE
" file: BackendDAE.mo
package: BackendDAE
description: BackendDAE contains the data-types used by the back end.

RCS: $Id$
"

public import Absyn;
Expand Down
14 changes: 2 additions & 12 deletions Compiler/BackEnd/BackendDAEOptimize.mo
Original file line number Diff line number Diff line change
Expand Up @@ -4340,7 +4340,8 @@ algorithm
functionTree := shared.functionTree;

simDAE := match shared
case BackendDAE.SHARED(backendDAEType = BackendDAE.SIMULATION()) then true;
case BackendDAE.SHARED(backendDAEType=BackendDAE.SIMULATION()) then true;
case BackendDAE.SHARED(backendDAEType=BackendDAE.INITIALSYSTEM()) then true;
else false;
end match;

Expand Down Expand Up @@ -4818,17 +4819,6 @@ public function symEuler
algorithm
outDAE := if Flags.getConfigBool(Flags.SYM_EULER) then symEulerWork(inDAE, true) else inDAE;
end symEuler;
public function symEulerInit
"
fix the difference quotient for initial equations[0/0]
ToDo: remove me
"
input BackendDAE.BackendDAE inDAE;
output BackendDAE.BackendDAE outDAE;
algorithm
outDAE := if Flags.getConfigBool(Flags.SYM_EULER) then symEulerWork(BackendDAEUtil.copyBackendDAE(inDAE), false) else inDAE;

end symEulerInit;

protected function symEulerWork
input BackendDAE.BackendDAE inDAE;
Expand Down
68 changes: 34 additions & 34 deletions Compiler/BackEnd/BackendDAEUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ encapsulated package BackendDAEUtil
package: BackendDAEUtil
description: BackendDAEUtil comprised functions for BackendDAE data types.

RCS: $Id$

This module is a lowered form of a DAE including equations
and simple equations in
two separate lists. The variables are split into known variables
Expand All @@ -62,8 +60,8 @@ protected import BackendDump;
protected import BackendEquation;
protected import BackendDAEEXT;
protected import BackendInline;
protected import BackendVariable;
protected import BackendVarTransform;
protected import BackendVariable;
protected import BinaryTree;
protected import Causalize;
protected import Ceval;
Expand Down Expand Up @@ -93,10 +91,12 @@ protected import HpcOmEqSystems;
protected import HpcOmTaskGraph;
protected import HpcOmSimCodeMain;
protected import IndexReduction;
protected import Initialization;
protected import Inline;
protected import InlineArrayEquations;
protected import List;
protected import Matching;
protected import MetaModelica.Dangerous.listReverseInPlace;
protected import OnRelaxation;
protected import RemoveSimpleEquations;
protected import ResolveLoops;
Expand All @@ -112,7 +112,6 @@ protected import Types;
protected import UnitCheck;
protected import Values;
protected import XMLDump;
protected import MetaModelica.Dangerous.listReverseInPlace;

protected
type Var = BackendDAE.Var;
Expand Down Expand Up @@ -6494,6 +6493,11 @@ public function getSolvedSystem "Run the equation system pipeline."
input Option<String> strdaeHandler = NONE();
input Option<list<String>> strPostOptModules = NONE();
output BackendDAE.BackendDAE outSODE;
output BackendDAE.BackendDAE outInitDAE;
output Boolean outUseHomotopy "true if homotopy(...) is used during initialization";
output list<BackendDAE.Equation> outRemovedInitialEquationLst;
output list<BackendDAE.Var> outPrimaryParameters "already sorted";
output list<BackendDAE.Var> outAllPrimaryParameters "already sorted";
protected
BackendDAE.BackendDAE optdae, sode, sode1, optsode;
list<tuple<BackendDAEFunc.preOptimizationDAEModule, String, Boolean>> preOptModules;
Expand Down Expand Up @@ -6533,6 +6537,9 @@ algorithm
sode := BackendDAEOptimize.evaluateOutputsOnly(sode);
end if;

// generate system for initialization
(outInitDAE, outUseHomotopy, outRemovedInitialEquationLst, outPrimaryParameters, outAllPrimaryParameters) := Initialization.solveInitialSystem(sode);

// post-optimization phase
optsode := postOptimizeDAE(sode, postOptModules, matchingAlgorithm, daeHandler);

Expand Down Expand Up @@ -7192,7 +7199,8 @@ algorithm
(CommonSubExpression.commonSubExpressionReplacement, "comSubExp", false),
(CommonSubExpression.CSE_EachCall, "CSE_EachCall", false),
(BackendDump.dumpDAE, "dumpDAE", false),
(XMLDump.dumpDAEXML, "dumpDAEXML", false)
(XMLDump.dumpDAEXML, "dumpDAEXML", false),
(FindZeroCrossings.encapsulateWhenConditions, "encapsulateWhenConditions", true)
};
strPreOptModules := getPreOptModulesString();
strPreOptModules := Util.getOptionOrDefault(ostrPreOptModules,strPreOptModules);
Expand All @@ -7210,10 +7218,10 @@ public function getPostOptModules
input Option<list<String>> ostrpostOptModules;
output list<tuple<BackendDAEFunc.postOptimizationDAEModule,String,Boolean>> postOptModules;
protected
list<tuple<BackendDAEFunc.postOptimizationDAEModule,String,Boolean>> allpostOptModules;
list<tuple<BackendDAEFunc.postOptimizationDAEModule,String,Boolean/*stopOnFailure*/>> allpostOptModules;
list<String> strpostOptModules;
algorithm
allpostOptModules := {(FindZeroCrossings.encapsulateWhenConditions, "encapsulateWhenConditions", true),
allpostOptModules := {(Initialization.removeInitializationStuff, "removeInitializationStuff", true),
(BackendInline.lateInlineFunction, "lateInlineFunction", false),
(RemoveSimpleEquations.removeSimpleEquations, "removeSimpleEquations", false),
(BackendDAEOptimize.removeEqualFunctionCalls, "removeEqualFunctionCalls", false),
Expand All @@ -7228,7 +7236,6 @@ algorithm
(BackendDAEOptimize.removeUnusedParameter, "removeUnusedParameter", false),
(BackendDAEOptimize.removeUnusedVariables, "removeUnusedVariables", false),
(BackendDAEOptimize.symEuler, "symEuler", false),
(BackendDAEOptimize.symEulerInit, "symEulerInit", false),
(SymbolicJacobian.constantLinearSystem, "constantLinearSystem", false),
(OnRelaxation.relaxSystem, "relaxSystem", false),
(BackendDAEOptimize.countOperations, "countOperations", false),
Expand Down Expand Up @@ -7654,34 +7661,33 @@ protected function getConditionList1 "author: lochel"
output list<DAE.ComponentRef> outConditionVarList;
output Boolean outInitialCall;
algorithm
(outConditionVarList, outInitialCall) := matchcontinue (inConditionList, inConditionVarList, inInitialCall)
(outConditionVarList, outInitialCall) := match inConditionList
local
list<DAE.Exp> conditionList;
list<DAE.ComponentRef> conditionVarList;
Boolean initialCall;
DAE.ComponentRef componentRef;
DAE.Exp exp;
String msg;

case ({}, _, _)
then (inConditionVarList, inInitialCall);
case {}
then (inConditionVarList, inInitialCall);

case (DAE.CALL(path = Absyn.IDENT(name = "initial"))::conditionList, _, _)
equation
(conditionVarList, initialCall) = getConditionList1(conditionList, inConditionVarList, true);
then (conditionVarList, initialCall);
case DAE.BCONST(false)::conditionList equation
(conditionVarList, initialCall) = getConditionList1(conditionList, inConditionVarList, inInitialCall);
then (conditionVarList, initialCall);

case (DAE.CREF(componentRef=componentRef)::conditionList, _, _)
equation
(conditionVarList, initialCall) = getConditionList1(conditionList, componentRef::inConditionVarList, inInitialCall);
then (conditionVarList, initialCall);
case DAE.CALL(path=Absyn.IDENT(name="initial"))::conditionList equation
(conditionVarList, initialCall) = getConditionList1(conditionList, inConditionVarList, true);
then (conditionVarList, initialCall);

case (exp::_, _ ,_)
equation
msg = "./Compiler/BackEnd/BackendDAEUtil.mo: function getConditionList1 failed for " + ExpressionDump.printExpStr(exp) + "\n";
Error.addMessage(Error.INTERNAL_ERROR, {msg});
then fail();
end matchcontinue;
case DAE.CREF(componentRef=componentRef)::conditionList equation
(conditionVarList, initialCall) = getConditionList1(conditionList, componentRef::inConditionVarList, inInitialCall);
then (conditionVarList, initialCall);

case exp::_ equation
Error.addInternalError("function getConditionList1 failed for " + ExpressionDump.printExpStr(exp), sourceInfo());
then fail();
end match;
end getConditionList1;

public function isArrayComp"outputs true if the strongComponent is an arrayEquation"
Expand Down Expand Up @@ -8093,15 +8099,9 @@ end setSharedEventInfo;
public function setSharedKnVars
input BackendDAE.Shared inShared;
input BackendDAE.Variables knownVars;
output BackendDAE.Shared outShared;
output BackendDAE.Shared outShared = inShared;
algorithm
outShared := match inShared
local
BackendDAE.Shared shared;
case shared as BackendDAE.SHARED()
algorithm shared.knownVars := knownVars;
then shared;
end match;
outShared.knownVars := knownVars;
end setSharedKnVars;

public function setSharedAliasVars
Expand Down
1 change: 1 addition & 0 deletions Compiler/BackEnd/BackendEquation.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2479,6 +2479,7 @@ algorithm
b := listEmpty(inputsKnVars);
end if;

b := false "hack";
if b then
if noPara then
oExp := ExpressionSimplify.simplify(iExp);
Expand Down
16 changes: 16 additions & 0 deletions Compiler/BackEnd/BackendVariable.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2449,6 +2449,22 @@ algorithm
end try;
end existsVar;

public function existsAnyVar
"author: PA
Return true if a variable exists in the vector"
input list<DAE.ComponentRef> inComponentRefs;
input BackendDAE.Variables inVariables;
input Boolean skipDiscrete = false;
output Boolean outExists = false;
algorithm
for cref in inComponentRefs loop
if existsVar(cref, inVariables, skipDiscrete) and not isState(cref, inVariables) then
outExists := true;
break;
end if;
end for;
end existsAnyVar;

public function makeVar
input DAE.ComponentRef cr;
output BackendDAE.Var v = BackendDAE.VAR(cr, BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false);
Expand Down
82 changes: 73 additions & 9 deletions Compiler/BackEnd/Initialization.mo
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ encapsulated package Initialization
package: Initialization
description: Initialization.mo contains everything needed to set up the
BackendDAE for the initial system.

RCS: $Id$"
"

public import Absyn;
public import BackendDAE;
Expand Down Expand Up @@ -99,15 +98,20 @@ protected
tuple<BackendDAEFunc.matchingAlgorithmFunc, String> matchingAlgorithm;
algorithm
try
// TODO: remove this once the initialization is moved before post-optimization
dae := BackendDAEOptimize.symEulerInit(inDAE);
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpBackendDAE(inDAE, "inDAE for initialization");
//end if;

// inline all when equations, if active with body else with lhs=pre(lhs)
dae := inlineWhenForInitialization(dae);
// fcall2(Flags.DUMP_INITIAL_SYSTEM, BackendDump.dumpBackendDAE, dae, "inlineWhenForInitialization");
dae := inlineWhenForInitialization(inDAE);
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpBackendDAE(dae, "inlineWhenForInitialization");
//end if;

(initVars, outPrimaryParameters, outAllPrimaryParameters) := selectInitializationVariablesDAE(dae);
// fcall2(Flags.DUMP_INITIAL_SYSTEM, BackendDump.dumpVariables, initVars, "selected initialization variables");
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpVariables(initVars, "selected initialization variables");
//end if;
hs := collectPreVariables(dae);

// collect vars and eqns for initial system
Expand All @@ -120,7 +124,9 @@ algorithm
((vars, fixvars, eqns, _)) := BackendVariable.traverseBackendDAEVars(dae.shared.knownVars, collectInitialVars, (vars, fixvars, eqns, hs));
((eqns, reeqns)) := BackendEquation.traverseEquationArray(dae.shared.initialEqs, collectInitialEqns, (eqns, reeqns));

// fcall2(Flags.DUMP_INITIAL_SYSTEM, BackendDump.dumpEquationArray, eqns, "initial equations");
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpEquationArray(eqns, "initial equations");
//end if;

((vars, fixvars, eqns, reeqns, _)) := List.fold(dae.eqs, collectInitialVarsEqnsSystem, ((vars, fixvars, eqns, reeqns, hs)));

Expand Down Expand Up @@ -172,7 +178,19 @@ algorithm
initdae := BackendDAEUtil.mapEqSystem(initdae, solveInitialSystemEqSystem);

// transform and optimize DAE
pastOptModules := BackendDAEUtil.getPostOptModules(SOME({"constantLinearSystem", "tearingSystem", "calculateStrongComponentJacobians", "solveSimpleEquations"}));
pastOptModules := BackendDAEUtil.getPostOptModules(SOME({
"constantLinearSystem",
"simplifyComplexFunction",
//"reduceDynamicOptimization", // before tearing
"tearingSystem",
"simplifyLoops",
"recursiveTearing",
"calculateStrongComponentJacobians",
"solveSimpleEquations"
//"inputDerivativesUsed",
//"extendDynamicOptimization"
}));

matchingAlgorithm := BackendDAEUtil.getMatchingAlgorithm(NONE());
daeHandler := BackendDAEUtil.getIndexReductionMethod(NONE());

Expand Down Expand Up @@ -2310,5 +2328,51 @@ algorithm
end match;
end collectInitialBindings;


// =============================================================================
// section for post-optimization module "removeInitializationStuff"
//
// =============================================================================

public function removeInitializationStuff
input BackendDAE.BackendDAE inDAE;
output BackendDAE.BackendDAE outDAE = inDAE;
algorithm
for eqs in outDAE.eqs loop
_ := BackendDAEUtil.traverseBackendDAEExpsEqnsWithUpdate(eqs.orderedEqs, removeInitializationStuff1, false);
end for;
end removeInitializationStuff;

protected function removeInitializationStuff1
input DAE.Exp inExp;
input Boolean inUseHomotopy;
output DAE.Exp outExp;
output Boolean outUseHomotopy;
algorithm
(outExp, outUseHomotopy) := Expression.traverseExpBottomUp(inExp, removeInitializationStuff2, inUseHomotopy);
end removeInitializationStuff1;

protected function removeInitializationStuff2
input DAE.Exp inExp;
input Boolean inUseHomotopy;
output DAE.Exp outExp;
output Boolean outUseHomotopy;
algorithm
(outExp, outUseHomotopy) := match (inExp, inUseHomotopy)
local
DAE.Exp e1, e2, e3, actual, simplified;

// replace initial() with false
case (DAE.CALL(path=Absyn.IDENT(name="initial")), _)
then (DAE.BCONST(false), inUseHomotopy);

// replace homotopy(actual, simplified) with actual
case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst=actual::simplified::_), _)
then (actual, true);

else (inExp, inUseHomotopy);
end match;
end removeInitializationStuff2;

annotation(__OpenModelica_Interface="backend");
end Initialization;
10 changes: 8 additions & 2 deletions Compiler/BackEnd/OpenTURNS.mo
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ public function generateOpenTURNSInterface "generates the dll and the python scr
list<String> libs;
BackendDAE.BackendDAE dae,strippedDae;
SimCode.SimulationSettings simSettings;
BackendDAE.BackendDAE initDAE;
Boolean useHomotopy "true if homotopy(...) is used during initialization";
list<BackendDAE.Equation> removedInitialEquationLst;
list<BackendDAE.Var> primaryParameters "already sorted";
list<BackendDAE.Var> allPrimaryParameters "already sorted";
algorithm
cname_str := Absyn.pathString(inPath);
cname_last_str := Absyn.pathLastIdent(inPath);
Expand All @@ -108,12 +113,13 @@ algorithm
// Strip correlation vector from dae to be able to compile (bug in OpenModelica with vectors of records )
strippedDae := stripCorrelationFromDae(inDaelow);

strippedDae := BackendDAEUtil.getSolvedSystem(strippedDae,"");
(strippedDae, initDAE, useHomotopy, removedInitialEquationLst, primaryParameters, allPrimaryParameters) := BackendDAEUtil.getSolvedSystem(strippedDae,"");

//print("strippedDae :");
//BackendDump.dump(strippedDae);
_ := System.realtimeTock(ClockIndexes.RT_CLOCK_BACKEND); // Is this necessary?
(libs, fileDir, _, _) := SimCodeMain.generateModelCode(strippedDae, inProgram, inPath, cname_str, SOME(simSettings), Absyn.FUNCTIONARGS({}, {}));

(libs, fileDir, _, _) := SimCodeMain.generateModelCode(strippedDae, initDAE, useHomotopy, removedInitialEquationLst, primaryParameters, allPrimaryParameters,inProgram, inPath, cname_str, SOME(simSettings), Absyn.FUNCTIONARGS({}, {}));

//print("..compiling, fileNamePrefix = "+fileNamePrefix+"\n");
CevalScript.compileModel(fileNamePrefix , libs);
Expand Down
Loading