Skip to content

Commit

Permalink
- rewrote the generation of the analytical jacobian -> gain the perfo…
Browse files Browse the repository at this point in the history
…rmace a lot

- fixed bug in solver_main
- added "dassljac" as solvername that use the analytical jacobian for simulation


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@8262 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Willi Braun committed Mar 16, 2011
1 parent 71df6bc commit 76eb523
Show file tree
Hide file tree
Showing 9 changed files with 1,538 additions and 657 deletions.
1,682 changes: 1,059 additions & 623 deletions Compiler/BackEnd/BackendDAEOptimize.mo

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Compiler/BackEnd/BackendDAETransform.mo
Expand Up @@ -2449,7 +2449,7 @@ algorithm
// print("\n");
Debug.fprint("bltdump", BackendDump.equationStr(eqn_1)) " print \" to \" & print str & print \"\\n\" &" ;
Debug.fprint("bltdump", "\n");
eqns_1 = BackendEquation.equationAdd(eqns, eqn_1);
eqns_1 = BackendEquation.equationAdd(eqn_1,eqns);
leneqns = BackendDAEUtil.equationSize(eqns_1);
BackendDAEEXT.markDifferentiated(e) "length gives index of new equation Mark equation as differentiated so it won\'t be differentiated again" ;
(dae,m,mt,nv,nf,reqns,derivedAlgs1,derivedMultiEqn1) = differentiateEqns(BackendDAE.DAE(v,kv,ev,av,eqns_1,seqns,ie,ae1,al1,wc,eoc), m, mt, nv, nf, es, inFunctions,derivedAlgs,derivedMultiEqn);
Expand Down
9 changes: 3 additions & 6 deletions Compiler/BackEnd/BackendDAEUtil.mo
Expand Up @@ -1469,11 +1469,10 @@ algorithm
equation
((BackendDAE.VAR(varKind = kind) :: _),_) = BackendVariable.getVar(cr, vars);
res = isKindDiscrete(kind);
b = Util.getOptionOrDefault(blst,res);
then
((e,false,(vars,knvars,SOME(b))));
((e,false,(vars,knvars,SOME(res))));
// builtin variable time is not discrete
case (((e as DAE.CREF(componentRef = DAE.CREF_IDENT("time",_,_)),(vars,knvars,blst)))) then ((e,false,(vars,knvars,SOME(false))));
case (((e as DAE.CREF(componentRef = DAE.CREF_IDENT("time",_,_)),(vars,knvars,blst)))) then ((e,false,(vars,knvars,SOME(false))));
// Known variables that are input are continous
case (((e as DAE.CREF(componentRef = cr),(vars,knvars,blst))))
equation
Expand All @@ -1488,8 +1487,7 @@ algorithm
equation
failure((_,_) = BackendVariable.getVar(cr, vars));
((BackendDAE.VAR(varKind = kind) :: _),_) = BackendVariable.getVar(cr, knvars);
res = isKindDiscrete(kind);
b = Util.getOptionOrDefault(blst,res);
b = isKindDiscrete(kind);
then
((e,false,(vars,knvars,SOME(b))));

Expand All @@ -1498,7 +1496,6 @@ algorithm
b1 = isDiscreteExp(e1,vars,knvars);
b2 = isDiscreteExp(e2,vars,knvars);
b = Util.boolOrList({b1,b2});
b = Util.getOptionOrDefault(blst,b);
then ((e,false,(vars,knvars,SOME(b))));
case (((e as DAE.CALL(path = Absyn.IDENT(name = "pre")),(vars,knvars,blst))))
equation
Expand Down
8 changes: 4 additions & 4 deletions Compiler/BackEnd/BackendDump.mo
Expand Up @@ -133,17 +133,17 @@ algorithm
end printCallFunction2StrDIVISION;

public function printTuple
input list<tuple<String,Integer>> outTuple;
input list<tuple<DAE.ComponentRef,Integer>> outTuple;
algorithm
_ := matchcontinue(outTuple)
local
String currVar;
DAE.ComponentRef currVar;
Integer currInd;
list<tuple<String,Integer>> restTuple;
list<tuple<DAE.ComponentRef,Integer>> restTuple;
case ({}) then ();
case ((currVar,currInd)::restTuple)
equation
Debug.fcall("varIndex",print, currVar);
Debug.fcall("varIndex",print, ComponentReference.printComponentRefStr(currVar)) ;
Debug.fcall("varIndex",print,": ");
Debug.fcall("varIndex",print,intString(currInd));
Debug.fcall("varIndex",print,"\n");
Expand Down
20 changes: 15 additions & 5 deletions Compiler/BackEnd/BackendEquation.mo
Expand Up @@ -759,30 +759,40 @@ algorithm
end matchcontinue;
end equationEqual;

public function addEquations "function: addEquations
author: wbraun
Adds a list of BackendDAE.Equation to BackendDAE.EquationArray"
input list<BackendDAE.Equation> eqnlst;
input BackendDAE.EquationArray eqns;
output BackendDAE.EquationArray eqns_1;
algorithm
eqns_1 := Util.listFold(eqnlst, equationAdd, eqns);
end addEquations;

public function equationAdd "function: equationAdd
author: PA

Adds an equation to an EquationArray.
"
input BackendDAE.EquationArray inEquationArray;
input BackendDAE.Equation inEquation;
input BackendDAE.EquationArray inEquationArray;
output BackendDAE.EquationArray outEquationArray;
algorithm
outEquationArray:=
matchcontinue (inEquationArray,inEquation)
matchcontinue (inEquation,inEquationArray)
local
BackendDAE.Value n_1,n,size,expandsize,expandsize_1,newsize;
array<Option<BackendDAE.Equation>> arr_1,arr,arr_2;
BackendDAE.Equation e;
Real rsize,rexpandsize;
case (BackendDAE.EQUATION_ARRAY(numberOfElement = n,arrSize = size,equOptArr = arr),e)
case (e,BackendDAE.EQUATION_ARRAY(numberOfElement = n,arrSize = size,equOptArr = arr))
equation
(n < size) = true "Have space to add array elt." ;
n_1 = n + 1;
arr_1 = arrayUpdate(arr, n + 1, SOME(e));
then
BackendDAE.EQUATION_ARRAY(n_1,size,arr_1);
case (BackendDAE.EQUATION_ARRAY(numberOfElement = n,arrSize = size,equOptArr = arr),e) /* Do NOT Have space to add array elt. Expand array 1.4 times */
case (e,BackendDAE.EQUATION_ARRAY(numberOfElement = n,arrSize = size,equOptArr = arr)) /* Do NOT Have space to add array elt. Expand array 1.4 times */
equation
(n < size) = false;
rsize = intReal(size);
Expand All @@ -795,7 +805,7 @@ algorithm
arr_2 = arrayUpdate(arr_1, n + 1, SOME(e));
then
BackendDAE.EQUATION_ARRAY(n_1,newsize,arr_2);
case (BackendDAE.EQUATION_ARRAY(numberOfElement = n,arrSize = size,equOptArr = arr),e)
case (e,BackendDAE.EQUATION_ARRAY(numberOfElement = n,arrSize = size,equOptArr = arr))
equation
print("- BackendEquation.equationAdd failed\n");
then
Expand Down
144 changes: 127 additions & 17 deletions Compiler/BackEnd/SimCode.mo
Expand Up @@ -910,6 +910,7 @@ algorithm
Debug.fcall("execstat",print, "*** SimCode -> generateFunctions: " +& realString(clock()) +& "\n" );
(libs, includes, recordDecls, functions, outIndexedBackendDAE, _) :=
createFunctions(dae, inBackendDAE, functionTree, className);
Debug.fcall("execstat",print, "*** SimCode -> generateSimCode: " +& realString(clock()) +& "\n" );
simCode := createSimCode(functionTree, outIndexedBackendDAE, equationIndices,
variableIndices, incidenceMatrix, incidenceMatrixT, strongComponents,
className, filenamePrefix, fileDir, functions, includes, libs, simSettingsOpt, recordDecls);
Expand Down Expand Up @@ -1041,6 +1042,7 @@ algorithm
Debug.fcall("execstat",print, "*** SimCode -> generateFunctions: " +& realString(clock()) +& "\n" );
(libs, includes, recordDecls, functions, outIndexedBackendDAE, _) :=
createFunctions(dae, inBackendDAE, functionTree, className);
Debug.fcall("execstat",print, "*** SimCode -> generateSimCode: " +& realString(clock()) +& "\n" );
simCode := createSimCode(functionTree, outIndexedBackendDAE, equationIndices,
variableIndices, incidenceMatrix, incidenceMatrixT, strongComponents,
className, filenamePrefix, fileDir, functions, includes, libs, simSettingsOpt, recordDecls);
Expand Down Expand Up @@ -2014,11 +2016,12 @@ algorithm
// Replace variables in nonlinear equation systems with xloc[index]
// variables.
allEquations = applyResidualReplacements(allEquations);

LinearMats = createLinearModelMatrixes(functionTree,dlow,ass1,ass2);
Debug.fcall("execJacstat",print, "*** SimCode -> generate analytical Jacobians: " +& realString(clock()) +& "\n" );
LinearMats = createJacobianMatrix(functionTree,dlow,ass1,ass2,comps,m,mt);
LinearMats = createLinearModelMatrixes(functionTree,dlow,ass1,ass2,LinearMats);

modelInfo = expandModelInfoVars(LinearMats,modelInfo);

Debug.fcall("execJacstat",print, "*** SimCode -> generate analytical Jacobians done!: " +& realString(clock()) +& "\n" );
crefToSimVarHT = createCrefToSimVarHT(modelInfo);

simCode = SIMCODE(modelInfo,
Expand Down Expand Up @@ -2091,18 +2094,23 @@ algorithm
end expandModelInfoVars;


protected function createLinearModelMatrixes
protected function createJacobianMatrix
input DAE.FunctionTree functions;
input BackendDAE.BackendDAE inBackendDAE2;
input array<Integer> inIntegerArray3;
input array<Integer> inIntegerArray4;
input list<list<Integer>> inComps;
input BackendDAE.IncidenceMatrix inIncidenceMatrix5;
input BackendDAE.IncidenceMatrixT inIncidenceMatrixT6;
output list<JacobianMatrix> JacobianMatrixes;
algorithm
JacobianMatrixes :=
matchcontinue (functions,inBackendDAE2,inIntegerArray3,inIntegerArray4)
matchcontinue (functions,inBackendDAE2,inIntegerArray3,inIntegerArray4,inComps,inIncidenceMatrix5,inIncidenceMatrixT6)
local
BackendDAE.BackendDAE dlow,deriveddlow1,deriveddlow2;
array<Integer> ass1,ass2;
list<list<Integer>> blt_states,comps;
array<list<Integer>> m,mt;

//BackendDAE.Variables v,kv;
list<BackendDAE.Var> varlst,varlst1, states, inputvars,inputvars2, outputvars, paramvars;
Expand All @@ -2126,7 +2134,100 @@ algorithm

list<JacobianMatrix> LinearMats;

case (functions,dlow as BackendDAE.DAE(v,kv,exv,av,e,re,ie,ae,al,ev,eoc),ass1,ass2)
case (functions,dlow as BackendDAE.DAE(v,kv,exv,av,e,re,ie,ae,al,ev,eoc),ass1,ass2,comps,m,mt)
equation
true = RTOpts.debugFlag("jacobian");

(blt_states, _) = BackendDAEUtil.generateStatePartition(comps, dlow, ass1, ass2, m, mt);

// Prepare all needed variables
varlst = BackendDAEUtil.varList(v);
varlst1 = BackendDAEUtil.varList(kv);
states = BackendVariable.getAllStateVarFromVariables(v);
states = Util.sort(states, BackendVariable.varIndexComparer);
inputvars = Util.listSelect(varlst1,BackendDAEUtil.isInput);
inputvars = Util.sort(inputvars, BackendVariable.varIndexComparer);
paramvars = Util.listSelect(varlst1, BackendVariable.isParam);
paramvars = Util.sort(paramvars, BackendVariable.varIndexComparer);
inputvars2 = Util.listSelect(varlst1,BackendVariable.isVarOnTopLevelAndInput);
inputvars2 = Util.sort(inputvars2, BackendVariable.varIndexComparer);
outputvars = Util.listSelect(varlst,BackendVariable.isVarOnTopLevelAndOutput);
outputvars = Util.sort(outputvars, BackendVariable.varIndexComparer);

comref_states = Util.listMap(states,BackendVariable.varCref);
comref_inputvars = Util.listMap(inputvars2,BackendVariable.varCref);
comref_outputvars = Util.listMap(outputvars,BackendVariable.varCref);

// Differentiate the ODE system w.r.t states for jacobian
Debug.fcall("linmodel",print,"Differentiate System w.r.t. states.\n");
deriveddlow1 = BackendDAEOptimize.generateSymbolicJacobian(dlow, functions, comref_states, BackendDAEUtil.listVar(states), BackendDAEUtil.listVar(inputvars), BackendDAEUtil.listVar(paramvars));
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> generated system for ODE-Block : " +& realString(clock()) +& "\n" );

// create Matrix A and variables
Debug.fcall("jacdump2", print, "Dump of daelow for Matrix A.\n");
(deriveddlow2, v1, v2, comps1) = BackendDAEOptimize.generateLinearMatrix(deriveddlow1,functions,comref_states,comref_states,varlst);
JacAEquations = createEquations(false, false, false, false, true, deriveddlow2, v1, v2, comps1, {});
Debug.fcall("jacdump2", print, "Equations created for Matrix A!\n");
v = BackendVariable.daeVars(deriveddlow2);
((JacAVars,_)) = BackendVariable.traverseBackendDAEVars(v,traversingdlowvarToSimvar,({},kv));
JacAVars = listReverse(JacAVars);
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> created system A: " +& realString(clock()) +& "\n" );

LinearMats = {(JacAEquations,JacAVars,"A"),({},{},"B"),({},{},"C"),({},{},"D")};

then
LinearMats;
case (_,dlow,ass1,ass2,_,_,_)
equation
false = RTOpts.debugFlag("jacobian");
LinearMats = {({},{},"A"),({},{},"B"),({},{},"C"),({},{},"D")};
then
LinearMats;
case (_,_,_,_,_,_,_)
equation
Error.addMessage(Error.INTERNAL_ERROR, {"Generation of Jacobian Matrxi code using templates failed"});
then
fail();
end matchcontinue;
end createJacobianMatrix;

protected function createLinearModelMatrixes
input DAE.FunctionTree functions;
input BackendDAE.BackendDAE inBackendDAE2;
input array<Integer> inIntegerArray3;
input array<Integer> inIntegerArray4;
input list<JacobianMatrix> JacobianMatrixes;
output list<JacobianMatrix> outJacobianMatrixes;
algorithm
outJacobianMatrixes :=
matchcontinue (functions,inBackendDAE2,inIntegerArray3,inIntegerArray4,JacobianMatrixes)
local
BackendDAE.BackendDAE dlow,deriveddlow1,deriveddlow2;
array<Integer> ass1,ass2;

//BackendDAE.Variables v,kv;
list<BackendDAE.Var> varlst,varlst1, states, inputvars,inputvars2, outputvars, paramvars;
list<DAE.ComponentRef> comref_states, comref_inputvars, comref_outputvars;

array<Integer> v1,v2;
list<list<Integer>> comps1;
list<SimEqSystem> JacAEquations;
list<SimEqSystem> JacBEquations;
list<SimEqSystem> JacCEquations;
list<SimEqSystem> JacDEquations;
list<SimVar> JacAVars, JacBVars, JacCVars, JacDVars;

BackendDAE.Variables v,kv,exv;
BackendDAE.AliasVariables av;
BackendDAE.EquationArray e,re,ie;
array<BackendDAE.MultiDimEquation> ae;
array<DAE.Algorithm> al;
BackendDAE.EventInfo ev;
BackendDAE.ExternalObjectClasses eoc;

list<JacobianMatrix> LinearMats;

case (functions,dlow as BackendDAE.DAE(v,kv,exv,av,e,re,ie,ae,al,ev,eoc),ass1,ass2,_)
equation
true = RTOpts.debugFlag("linearization");
Debug.fcall("linmodel",print,"Generate Linear Model Matrices\n");
Expand All @@ -2151,8 +2252,9 @@ algorithm

// Differentiate the System w.r.t states for matrices A and C
Debug.fcall("linmodel",print,"Differentiate System w.r.t. states.\n");
deriveddlow1 = BackendDAEOptimize.generateSymbolicJacobian(dlow, functions, comref_states, states, inputvars, paramvars);
deriveddlow1 = BackendDAEOptimize.generateSymbolicJacobian(dlow, functions, comref_states, BackendDAEUtil.listVar(states), BackendDAEUtil.listVar(inputvars), BackendDAEUtil.listVar(paramvars));
Debug.fcall("linmodel",print,"Done! Create now Matrixes A and C for linear model.\n");
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> generated system for A and C : " +& realString(clock()) +& "\n" );

// create Matrix A and variables
Debug.fcall("jacdump2", print, "Dump of daelow for Matrix A.\n");
Expand All @@ -2162,6 +2264,7 @@ algorithm
v = BackendVariable.daeVars(deriveddlow2);
((JacAVars,_)) = BackendVariable.traverseBackendDAEVars(v,traversingdlowvarToSimvar,({},kv));
JacAVars = listReverse(JacAVars);
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> created system A: " +& realString(clock()) +& "\n" );
// create Matrix C and variables
Debug.fcall("jacdump2", print, "Dump of daelow for Matrix C.\n");
(deriveddlow2, v1, v2, comps1) = BackendDAEOptimize.generateLinearMatrix(deriveddlow1,functions,comref_outputvars,comref_states,varlst);
Expand All @@ -2170,10 +2273,12 @@ algorithm
v = BackendVariable.daeVars(deriveddlow2);
((JacCVars,_)) = BackendVariable.traverseBackendDAEVars(v,traversingdlowvarToSimvar,({},kv));
JacAVars = listReverse(JacAVars);
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> created system C: " +& realString(clock()) +& "\n" );
// Differentiate the System w.r.t states for matrices B and D
Debug.fcall("linmodel",print,"Differentiate System w.r.t. inputs.\n");
deriveddlow1 = BackendDAEOptimize.generateSymbolicJacobian(dlow, functions, comref_inputvars, states, inputvars, paramvars);
deriveddlow1 = BackendDAEOptimize.generateSymbolicJacobian(dlow, functions, comref_inputvars, BackendDAEUtil.listVar(states), BackendDAEUtil.listVar(inputvars), BackendDAEUtil.listVar(paramvars));
Debug.fcall("linmodel",print,"Done! Create now Matrixes B and D for linear model.\n");
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> generated system for B and D : " +& realString(clock()) +& "\n" );

// create Matrix B and variables
Debug.fcall("jacdump2", print, "Dump of daelow for Matrix B.\n");
Expand All @@ -2182,24 +2287,34 @@ algorithm
v = BackendVariable.daeVars(deriveddlow2);
((JacBVars,_)) = BackendVariable.traverseBackendDAEVars(v,traversingdlowvarToSimvar,({},kv));
JacBVars = listReverse(JacBVars);
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> created system B: " +& realString(clock()) +& "\n" );
// create Matrix D and variables
Debug.fcall("jacdump2", print, "Dump of daelow for Matrix D.\n");
(deriveddlow2, v1, v2, comps1) = BackendDAEOptimize.generateLinearMatrix(deriveddlow1,functions,comref_outputvars,comref_inputvars,varlst);
JacDEquations = createEquations(false, false, false, false, true, deriveddlow2, v1, v2, comps1, {});
v = BackendVariable.daeVars(deriveddlow2);
((JacDVars,_)) = BackendVariable.traverseBackendDAEVars(v,traversingdlowvarToSimvar,({},kv));
JacDVars = listReverse(JacDVars);
Debug.fcall("execJacstat",print, "*** analytical Jacobians -> created system D: " +& realString(clock()) +& "\n" );
LinearMats = {(JacAEquations,JacAVars,"A"),(JacBEquations,JacBVars,"B"),(JacCEquations,JacCVars,"C"),(JacDEquations,JacDVars,"D")};

then
LinearMats;
case (_,dlow,ass1,ass2)
case (_,dlow,ass1,ass2,JacobianMatrixes)
equation
false = RTOpts.debugFlag("linearization");
true = RTOpts.debugFlag("jacobian");
then
JacobianMatrixes;

case (_,dlow,ass1,ass2,_)
equation
false = RTOpts.debugFlag("linearization");
false = RTOpts.debugFlag("jacobian");
LinearMats = {({},{},"A"),({},{},"B"),({},{},"C"),({},{},"D")};
then
LinearMats;
case (_,_,_,_)
LinearMats;
case (_,_,_,_,_)
equation
Error.addMessage(Error.INTERNAL_ERROR, {"Generation of LinearModel Matrixes code using templates failed"});
then
Expand Down Expand Up @@ -3857,13 +3972,8 @@ algorithm
outJactype := match(inJactype)
local
BackendDAE.JacobianType jacType;
case (jacType as BackendDAE.JAC_TIME_VARYING()) then jacType;
case (jacType as BackendDAE.JAC_CONSTANT()) then jacType;
case (jacType as BackendDAE.JAC_NONLINEAR()) then BackendDAE.JAC_TIME_VARYING();
case (jacType as BackendDAE.JAC_NO_ANALYTIC())
equation
Debug.fprint("failtrace", "- failed to calculate a Jacobian a system of equation \n");
then fail();
case (jacType) then jacType;
end match;
end changeJactype;

Expand Down

0 comments on commit 76eb523

Please sign in to comment.