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

Commit 963b33e

Browse files
kabdelhakOpenModelica-Hudson
authored andcommitted
[BE] Add jacobian dependencies
- Preparation for initial state selection, used for matching - The dependencies of a jacobian are all unknowns contained in it Belonging to [master]: - OpenModelica/OpenModelica#136 - #3048
1 parent 3006b8a commit 963b33e

File tree

8 files changed

+218
-28
lines changed

8 files changed

+218
-28
lines changed

Compiler/BackEnd/BackendDAE.mo

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ public constant EvaluationStages defaultEvalStages = EVALUATION_STAGES(false,fal
333333

334334
public uniontype EquationAttributes
335335
record EQUATION_ATTRIBUTES
336-
Boolean differentiated "true if the equation was differentiated, and should not differentiated again to avoid equal equations";
336+
Boolean differentiated "true if the equation was differentiated, and should not be differentiated again to avoid equal equations";
337337
EquationKind kind;
338338
EvaluationStages evalStages;
339339
end EQUATION_ATTRIBUTES;
@@ -780,7 +780,8 @@ type SymbolicJacobian = tuple<BackendDAE, // symbolic equation sys
780780
String, // Matrix name
781781
list<Var>, // diff vars (independent vars)
782782
list<Var>, // diffed vars (residual vars)
783-
list<Var> // all diffed vars (residual vars + dependent vars)
783+
list<Var>, // all diffed vars (residual vars + dependent vars)
784+
list< .DAE.ComponentRef> // original dependent variables
784785
>;
785786

786787
public

Compiler/BackEnd/BackendDAEOptimize.mo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,7 +1463,7 @@ algorithm
14631463
DAE.FunctionTree usedfuncs;
14641464
BackendDAE.Shared shared;
14651465

1466-
case (SOME((bdae, _, _, _, _)), _, _)
1466+
case (SOME((bdae, _, _, _, _, _)), _, _)
14671467
equation
14681468
bdae = BackendDAEUtil.setFunctionTree(bdae, inFunctions);
14691469
shared = bdae.shared;
@@ -1930,7 +1930,7 @@ algorithm
19301930
/* TODO: implement/check for GENERIC_JACOBIAN */
19311931
case BackendDAE.GENERIC_JACOBIAN(jacobian=NONE())
19321932
then -1;
1933-
case BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((_,_,vars1,vars2,_)))
1933+
case BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((_,_,vars1,vars2,_,_)))
19341934
guard
19351935
listLength(vars1) == listLength(vars2)
19361936
then listLength(vars1);

Compiler/BackEnd/BackendDAEUtil.mo

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6267,9 +6267,9 @@ algorithm
62676267
BackendDAE.BackendDAE bdae;
62686268
case BackendDAE.EQUATIONSYSTEM(jac=BackendDAE.FULL_JACOBIAN(SOME(jac)))
62696269
then traverseBackendDAEExpsJacobianEqn(jac, inFunc, arg);
6270-
case BackendDAE.EQUATIONSYSTEM(jac=BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_))))
6270+
case BackendDAE.EQUATIONSYSTEM(jac=BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_,_))))
62716271
then traverseBackendDAEExps(bdae, inFunc, arg);
6272-
case BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(jac=BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_)))))
6272+
case BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(jac=BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_,_)))))
62736273
then traverseBackendDAEExps(bdae, inFunc, arg);
62746274
else arg;
62756275
end match;
@@ -6325,7 +6325,7 @@ algorithm
63256325
BackendDAE.BackendDAE bdae;
63266326
Type_a arg;
63276327
case ({}, _, _) then inTypeA;
6328-
case (BackendDAE.STATESET(jacobian = BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_))))::rest, _, _)
6328+
case (BackendDAE.STATESET(jacobian = BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_,_))))::rest, _, _)
63296329
equation
63306330
arg = traverseBackendDAEExps(bdae, inFunc, inTypeA);
63316331
then
@@ -7052,6 +7052,9 @@ algorithm
70527052
dae := BackendDAEOptimize.evaluateOutputsOnly(dae);
70537053
end if;
70547054

7055+
//generate Jacobian for StateSets for initial state selection
7056+
dae := SymbolicJacobian.calculateStateSetsJacobians(dae);
7057+
70557058
// generate system for initialization
70567059
(outInitDAE, outInitDAE_lambda0_option, outRemovedInitialEquationLst, globalKnownVars) := Initialization.solveInitialSystem(dae);
70577060
if Flags.isSet(Flags.WARN_NO_NOMINAL) then

Compiler/BackEnd/BackendDump.mo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,7 +2320,7 @@ algorithm
23202320
then s;
23212321
case(BackendDAE.GENERIC_JACOBIAN(jacobian=SOME(sJac),sparsePattern=sparsePattern))
23222322
equation
2323-
((dae,_,_,_,_)) = sJac;
2323+
((dae,_,_,_,_, _)) = sJac;
23242324
s = "GENERIC JACOBIAN:\n";
23252325
dumpBackendDAE(dae,"Directional Derivatives System");
23262326
dumpSparsityPattern(sparsePattern,"Sparse Pattern");
@@ -2351,7 +2351,7 @@ algorithm
23512351
String s;
23522352
case((SOME(sJac), sparsePattern, _))
23532353
equation
2354-
((dae,_,_,_,_)) = sJac;
2354+
((dae,_,_,_,_, _)) = sJac;
23552355
s = "GENERIC JACOBIAN:\n";
23562356
dumpBackendDAE(dae,"Directional Derivatives System");
23572357
dumpSparsityPattern(sparsePattern,"Sparse Pattern");

Compiler/BackEnd/BackendEquation.mo

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,28 @@ algorithm
609609
(_, (_,cr_lst)) := traverseExpsOfEquation(e, Expression.traverseSubexpressionsHelper, (Expression.traversingComponentRefFinder, cr_lst));
610610
end traversingEquationCrefFinder;
611611

612+
public function getCrefsFromEquations
613+
input BackendDAE.EquationArray inEqns;
614+
input BackendDAE.Variables inVars;
615+
input BackendDAE.Variables inKnVars;
616+
output list<DAE.ComponentRef> cr_lst;
617+
protected
618+
HashTable.HashTable ht;
619+
BackendDAE.Variables vars;
620+
BackendDAE.Variables knownVars;
621+
algorithm
622+
ht := HashTable.emptyHashTable();
623+
(_, _, ht) := traverseEquationArray(inEqns, findUnknownCrefs, (inVars, inKnVars, ht));
624+
cr_lst := BaseHashTable.hashTableKeyList(ht);
625+
end getCrefsFromEquations;
626+
627+
protected function findUnknownCrefs
628+
input output BackendDAE.Equation inEq;
629+
input output tuple<BackendDAE.Variables, BackendDAE.Variables, HashTable.HashTable> extraArgs;
630+
algorithm
631+
(_, ( _, extraArgs)) := traverseExpsOfEquation(inEq, Expression.traverseSubexpressionsHelper, (checkEquationsUnknownCrefsExp, extraArgs));
632+
end findUnknownCrefs;
633+
612634
public function equationUnknownCrefs "author: Frenkel TUD 2012-05
613635
From the equation and a variable array return all
614636
variables in the equation an not in the variable array."
@@ -3182,6 +3204,5 @@ algorithm
31823204
end match;
31833205
end scalarComplexEquations;
31843206

3185-
31863207
annotation(__OpenModelica_Interface="backend");
31873208
end BackendEquation;

Compiler/BackEnd/FindZeroCrossings.mo

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,10 +892,11 @@ protected
892892
BackendDAE.BackendDAE jacBDAE;
893893
String name;
894894
list<BackendDAE.Var> seedVars, tmpVars, resultVars;
895+
list<DAE.ComponentRef> depCrefs;
895896
algorithm
896-
(jacBDAE, name, seedVars, tmpVars, resultVars) := symJac;
897+
(jacBDAE, name, seedVars, tmpVars, resultVars, depCrefs) := symJac;
897898
jacBDAE := replaceZeroCrossingsJacBackend(jacBDAE, zeroCrossingLst, relationsLst, samplesLst, allVariables, globalKnownVars);
898-
outSymJac := (jacBDAE, name, seedVars, tmpVars, resultVars);
899+
outSymJac := (jacBDAE, name, seedVars, tmpVars, resultVars, depCrefs);
899900
end replaceZCExpinSymJacobian;
900901

901902
protected function replaceZeroCrossingsJacBackend

Compiler/BackEnd/SymbolicJacobian.mo

Lines changed: 156 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,7 +1744,7 @@ try
17441744
if Flags.isSet(Flags.JAC_DUMP2) then
17451745
BackendDump.dumpSparsityPattern(sparsePattern, "FMI sparsity");
17461746
end if;
1747-
outJacobianMatrixes := (SOME((emptyBDAE,"FMIDER",{},{},{})), sparsePattern, sparseColoring)::outJacobianMatrixes;
1747+
outJacobianMatrixes := (SOME((emptyBDAE,"FMIDER",{},{},{}, {})), sparsePattern, sparseColoring)::outJacobianMatrixes;
17481748
outFunctionTree := inBackendDAE.shared.functionTree;
17491749
else
17501750
// prepare more needed variables
@@ -2001,7 +2001,7 @@ algorithm
20012001
local
20022002
BackendDAE.BackendDAE backendDAE, reducedDAE;
20032003

2004-
list<DAE.ComponentRef> comref_vars, comref_differentiatedVars;
2004+
list<DAE.ComponentRef> comref_vars, comref_differentiatedVars, dependencies;
20052005

20062006
BackendDAE.Shared shared;
20072007
BackendDAE.Variables globalKnownVars, globalKnownVars1;
@@ -2043,9 +2043,10 @@ algorithm
20432043
if Flags.isSet(Flags.JAC_DUMP2) then
20442044
print("analytical Jacobians -> generated Jacobian DAE time: " + realString(clock()) + "\n");
20452045
end if;
2046+
dependencies = calcJacobianDependencies((backendDAE, "", {}, {}, {}, {}));
20462047

20472048
then
2048-
((backendDAE, inName, inDiffVars, diffedVars, inVars), funcs);
2049+
((backendDAE, inName, inDiffVars, diffedVars, inVars, dependencies), funcs);
20492050
else
20502051
equation
20512052
Error.addInternalError("function createJacobian failed", sourceInfo());
@@ -2382,7 +2383,7 @@ algorithm
23822383
BackendDAE.SymbolicJacobians rest;
23832384
String name;
23842385

2385-
case (matrix as (SOME((_,name,_,_,_)), _, _))::_ guard
2386+
case (matrix as (SOME((_,name,_,_,_,_)), _, _))::_ guard
23862387
stringEq(name, inJacobianName)
23872388
then SOME(matrix);
23882389

@@ -2393,6 +2394,36 @@ algorithm
23932394
end match;
23942395
end getJacobianMatrixbyName;
23952396

2397+
2398+
public function calcJacobianDependencies
2399+
input BackendDAE.SymbolicJacobian jacobian;
2400+
output list<DAE.ComponentRef> dependencies;
2401+
protected
2402+
BackendDAE.EqSystem syst;
2403+
BackendDAE.Shared shared;
2404+
algorithm
2405+
(BackendDAE.DAE({syst}, shared), _, _, _, _, _) := jacobian;
2406+
dependencies := BackendEquation.getCrefsFromEquations(syst.orderedEqs, syst.orderedVars, shared.globalKnownVars);
2407+
end calcJacobianDependencies;
2408+
2409+
public function getJacobianDependencies
2410+
input BackendDAE.Jacobian jacobian;
2411+
output list<DAE.ComponentRef> dependencies;
2412+
algorithm
2413+
dependencies := match(jacobian)
2414+
case (BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((_, _, _, _, _, dependencies))))
2415+
then dependencies;
2416+
2417+
case (BackendDAE.GENERIC_JACOBIAN(jacobian=NONE()))
2418+
then {};
2419+
2420+
else equation
2421+
Error.addInternalError("function getJacobianDependencies failed", sourceInfo());
2422+
then fail();
2423+
2424+
end match;
2425+
end getJacobianDependencies;
2426+
23962427
// =============================================================================
23972428
// Module for to calculate strong component Jacobains
23982429
//
@@ -2826,7 +2857,8 @@ algorithm
28262857

28272858
// create known variables
28282859
knvarLst1 := BackendEquation.equationsVars(eqns, globalKnownVars);
2829-
knvarLst2 := BackendEquation.equationsVars(eqns, inAllVars);
2860+
//knvarLst2 := BackendEquation.equationsVars(eqns, inAllVars);
2861+
knvarLst2 := {};
28302862
// Create a list of known variables true *only* for this shared system
28312863
globalKnownVars := BackendVariable.listVar2(knvarLst1,knvarLst2);
28322864
// Remove inputs for the jacobian
@@ -3716,7 +3748,7 @@ protected
37163748
BackendDAE.BackendDAE jacBDAE;
37173749
String name;
37183750
algorithm
3719-
(jacBDAE, name, _, _, _) := symbolicJacobian;
3751+
(jacBDAE, name, _, _, _, _) := symbolicJacobian;
37203752
try
37213753
_ := BackendDAEUtil.mapEqSystem(jacBDAE, checkForNonLinearStrongComponents_work);
37223754
result := true;
@@ -3754,5 +3786,123 @@ algorithm
37543786
end try;
37553787
end checkForNonLinearStrongComponents_work;
37563788

3789+
3790+
public function getFixedStatesForSelfdependentSets
3791+
" author: kabdelhak
3792+
Returns states to fix for initial problem in the case of selfdependent dynamic state sets"
3793+
input BackendDAE.StateSet stateSet;
3794+
input list<BackendDAE.Var> unfixedStates;
3795+
input Integer toFix;
3796+
output list<BackendDAE.Var> statesToFix;
3797+
protected
3798+
list<tuple<Integer,BackendDAE.Var>> nonlinearCountLst = {};
3799+
Integer nonlinearCount;
3800+
algorithm
3801+
_:= match(stateSet.jacobian)
3802+
local
3803+
BackendDAE.SymbolicJacobian sJac;
3804+
BackendDAE.BackendDAE dae;
3805+
list<BackendDAE.Var> diffVars;
3806+
String matrixName;
3807+
case (BackendDAE.GENERIC_JACOBIAN(jacobian=SOME(sJac))) algorithm
3808+
((dae,matrixName,diffVars, _, _,_)) := sJac;
3809+
for var in unfixedStates loop
3810+
nonlinearCountLst := getNonlinearStateCount(var,unfixedStates,dae,matrixName)::nonlinearCountLst;
3811+
end for;
3812+
then 0;
3813+
end match;
3814+
statesToFix := fixedVarsFromNonlinearCount(nonlinearCountLst, toFix);
3815+
end getFixedStatesForSelfdependentSets;
3816+
3817+
protected function getNonlinearStateCount
3818+
input BackendDAE.Var state;
3819+
input list<BackendDAE.Var> diffVars;
3820+
input BackendDAE.BackendDAE dae;
3821+
input String matrixName;
3822+
output tuple<Integer,BackendDAE.Var> outTpl;
3823+
protected
3824+
algorithm
3825+
outTpl:=match(dae)
3826+
local
3827+
BackendDAE.EqSystems systs;
3828+
tuple<BackendDAE.Var,list<BackendDAE.Var>,Integer,String> tpl;
3829+
BackendDAE.Var outState;
3830+
Integer nonlinearCount = 0;
3831+
case BackendDAE.DAE(eqs=systs) algorithm
3832+
tpl := (state,diffVars,nonlinearCount,matrixName);
3833+
for syst in systs loop
3834+
_:= match(syst)
3835+
local
3836+
BackendDAE.EquationArray eqnarray;
3837+
3838+
case BackendDAE.EQSYSTEM(_,eqnarray,_,_,_,_,_,_) algorithm
3839+
tpl := BackendEquation.traverseEquationArray(eqnarray,getNonlinearStateCount0,tpl);
3840+
then 0;
3841+
end match;
3842+
end for;
3843+
(outState,_,nonlinearCount,_) := tpl;
3844+
then (nonlinearCount,outState);
3845+
end match;
3846+
3847+
end getNonlinearStateCount;
3848+
3849+
protected function getNonlinearStateCount0
3850+
input BackendDAE.Equation inEq;
3851+
input tuple<BackendDAE.Var,list<BackendDAE.Var>,Integer,String> inTpl;
3852+
output BackendDAE.Equation outEq;
3853+
output tuple<BackendDAE.Var,list<BackendDAE.Var>,Integer,String> outTpl;
3854+
algorithm
3855+
outEq := inEq;
3856+
outTpl := match inEq
3857+
local
3858+
DAE.Exp exp, diffExp;
3859+
BackendDAE.Var state;
3860+
list<BackendDAE.Var> diffVars;
3861+
Integer nonlinearCount;
3862+
String matrixName;
3863+
DAE.ComponentRef seedVar;
3864+
list<DAE.Subscript> subs;
3865+
case BackendDAE.EQUATION(scalar=exp) algorithm
3866+
(state,diffVars,nonlinearCount,matrixName) := inTpl;
3867+
// Differentiate equation to look for nonlinear dependencies
3868+
seedVar := Differentiate.createSeedCrefName(BackendVariable.varCref(state),matrixName);
3869+
diffExp := Differentiate.differentiateExpSolve(exp,seedVar,NONE());
3870+
for var in diffVars loop
3871+
if not ComponentReference.crefEqual(var.varName, state.varName) and Expression.expContains(diffExp,Expression.crefExp(var.varName)) then
3872+
// Heuristic to punish fixed vars with a value of zero
3873+
if BackendVariable.varFixed(var) and Expression.isZero(BackendVariable.varStartValue(var)) then
3874+
nonlinearCount := nonlinearCount + 2;
3875+
else
3876+
nonlinearCount := nonlinearCount + 1;
3877+
end if;
3878+
end if;
3879+
end for;
3880+
then (state,diffVars,nonlinearCount,matrixName);
3881+
end match;
3882+
end getNonlinearStateCount0;
3883+
3884+
protected function fixedVarsFromNonlinearCount
3885+
input list<tuple<Integer,BackendDAE.Var>> tplLst;
3886+
input Integer toFix;
3887+
output list<BackendDAE.Var> fixedVars = {};
3888+
protected
3889+
list<tuple<Integer,BackendDAE.Var>> sortedTplLst, strippedTplLst;
3890+
BackendDAE.Var fixVar;
3891+
Integer fixInt;
3892+
algorithm
3893+
for tpl in tplLst loop
3894+
(fixInt,fixVar) := tpl;
3895+
end for;
3896+
// Sort by nonlinear count and take first N states to fix
3897+
sortedTplLst := List.sort(tplLst, Util.compareTupleIntGt);
3898+
strippedTplLst := List.firstN(sortedTplLst,toFix);
3899+
for tpl in strippedTplLst loop
3900+
(_,fixVar) := tpl;
3901+
fixVar.values := DAEUtil.setFixedAttr(fixVar.values,SOME(DAE.BCONST(true)));
3902+
fixedVars := fixVar::fixedVars;
3903+
end for;
3904+
end fixedVarsFromNonlinearCount;
3905+
3906+
37573907
annotation(__OpenModelica_Interface="backend");
37583908
end SymbolicJacobian;

0 commit comments

Comments
 (0)