@@ -487,7 +487,7 @@ algorithm
487487
488488 // collect fmi partial derivative
489489 if FMI.isFMIVersion20(FMUVersion) then
490- (SymbolicJacsFMI, modelStructure, modelInfo, SymbolicJacsTemp, uniqueEqIndex) := createFMIModelStructure(inFMIDer, modelInfo, uniqueEqIndex);
490+ (SymbolicJacsFMI, modelStructure, modelInfo, SymbolicJacsTemp, uniqueEqIndex) := createFMIModelStructure(inFMIDer, modelInfo, uniqueEqIndex, inInitDAE );
491491 SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS);
492492 if debug then execStat("simCode: create FMI model structure"); end if;
493493 end if;
@@ -11947,6 +11947,7 @@ public function createFMIModelStructure
1194711947 input BackendDAE.SymbolicJacobians inSymjacs;
1194811948 input SimCode.ModelInfo inModelInfo;
1194911949 input Integer inUniqueEqIndex;
11950+ input BackendDAE.BackendDAE inInitDAE;
1195011951 output list<SimCode.JacobianMatrix> symJacFMI = {};
1195111952 output Option<SimCode.FmiModelStructure> outFmiModelStructure;
1195211953 output SimCode.ModelInfo outModelInfo = inModelInfo;
@@ -11970,16 +11971,19 @@ protected
1197011971 list<SimCodeVar.SimVar> tempvars;
1197111972 SimCodeVar.SimVars vars;
1197211973 SimCode.HashTableCrefToSimVar crefSimVarHT;
11973- list<Integer> intLst;
11974+ list<Integer> intLst, derivativesLst;
11975+ SimCode.FmiInitialUnknowns fmiInitUnknowns;
11976+ constant Boolean debug = false;
1197411977algorithm
1197511978 try
1197611979 //print("Start creating createFMIModelStructure\n");
1197711980 // combine the transposed sparse pattern of matrix A and B
11978- // to obtain dependencies for the derivativesq
11981+ // to obtain dependencies for the derivatives and outputs
1197911982 SOME((optcontPartDer, spPattern as (_, spTA, (diffCrefsA, diffedCrefsA),_), spColors)) := SymbolicJacobian.getJacobianMatrixbyName(inSymjacs, "FMIDER");
1198011983
1198111984 crefSimVarHT := createCrefToSimVarHT(inModelInfo);
1198211985 //print("-- Got matrixes\n");
11986+
1198311987 (spTA, derdiffCrefsA) := translateSparsePatterCref2DerCref(spTA, crefSimVarHT, {}, {});
1198411988 //print("-- translateSparsePatterCref2DerCref matrixes AB\n");
1198511989
@@ -11995,8 +11999,8 @@ algorithm
1199511999 allUnknowns := translateSparsePatterInts2FMIUnknown(sparseInts, {});
1199612000
1199712001 // get derivatives pattern
11998- intLst := list(getVariableIndex(v) for v in inModelInfo.vars.derivativeVars);
11999- derivatives := list(fmiUnknown for fmiUnknown guard(Util.boolOrList(list(isFmiUnknown(i, fmiUnknown) for i in intLst ))) in allUnknowns);
12002+ derivativesLst := list(getVariableIndex(v) for v in inModelInfo.vars.derivativeVars);
12003+ derivatives := list(fmiUnknown for fmiUnknown guard(Util.boolOrList(list(isFmiUnknown(i, fmiUnknown) for i in derivativesLst ))) in allUnknowns);
1200012004
1200112005 // get output pattern
1200212006 varsA := List.filterOnTrue(inModelInfo.vars.algVars, isOutputSimVar);
@@ -12021,6 +12025,11 @@ algorithm
1202112025 else
1202212026 contPartSimDer := NONE();
1202312027 end if;
12028+ if debug then print("-- FMI directional derivatives created\n"); end if;
12029+
12030+ // create initial unknonw dependencies
12031+ fmiInitUnknowns := getFMIInitialDep(inInitDAE, crefSimVarHT, derivativesLst);
12032+ if debug then print("-- FMI initial unknown created\n"); end if;
1202412033
1202512034 outFmiModelStructure :=
1202612035 SOME(
@@ -12029,7 +12038,7 @@ algorithm
1202912038 SimCode.FMIDERIVATIVES(derivatives),
1203012039 contPartSimDer,
1203112040 SimCode.FMIDISCRETESTATES(discreteStates),
12032- SimCode.FMIINITIALUNKNOWNS({}) ));
12041+ fmiInitUnknowns ));
1203312042else
1203412043 // create empty model structure
1203512044 try
@@ -12181,6 +12190,74 @@ algorithm
1218112190 end match;
1218212191end mergeSparsePatter;
1218312192
12193+ protected function getFMIInitialDep
12194+ input BackendDAE.BackendDAE initDAE;
12195+ input SimCode.HashTableCrefToSimVar crefSimVarHT;
12196+ input list<Integer> derivativesLst;
12197+ output SimCode.FmiInitialUnknowns fmiInitUnknowns;
12198+ protected
12199+ list<BackendDAE.Var> initUnknowns, states, tmpinitUnknowns;
12200+ list<DAE.ComponentRef> diffCrefs, diffedCrefs, derdiffCrefs, tmpOutputCref;
12201+ list<tuple<DAE.ComponentRef, list<DAE.ComponentRef>>> spT;
12202+ list<tuple<Integer, list<Integer>>> sparseInts;
12203+ list<SimCode.FmiUnknown> unknowns;
12204+ list<SimCodeVar.SimVar> vars1, vars2, outputvars;
12205+ BackendDAE.BackendDAE tmpBDAE;
12206+ list<Integer> intLst;
12207+ algorithm
12208+ try
12209+ //prepare initialUnknows
12210+ tmpBDAE := BackendDAEOptimize.collapseIndependentBlocks(initDAE);
12211+ tmpBDAE := BackendDAEUtil.transformBackendDAE(tmpBDAE, SOME((BackendDAE.NO_INDEX_REDUCTION(), BackendDAE.EXACT())), NONE(), NONE());
12212+
12213+ // TODO: filter the initUnknows for variables
12214+ // with causality = "output" and causality = "calculatedParameter"
12215+ // and all continuous-time states and all state derivatives
12216+ initUnknowns := BackendDAEUtil.getOrderedVarsLst(tmpBDAE);
12217+
12218+ // get the output patterns with causality = "output" and intial = "calculated"
12219+ (tmpinitUnknowns, _) := List.extractOnTrue(initUnknowns,isVarOutputandNotfixed);
12220+ tmpOutputCref:= List.filterMap(tmpinitUnknowns,getVarCref);
12221+ outputvars := getSimVars2Crefs(tmpOutputCref, crefSimVarHT);
12222+ intLst := list(getVariableIndex(v) for v in outputvars);
12223+
12224+ ((_, spT, (diffCrefs, diffedCrefs),_),_) := SymbolicJacobian.generateSparsePattern(tmpBDAE, initUnknowns, initUnknowns);
12225+
12226+ // collect all variable
12227+ vars1 := getSimVars2Crefs(diffedCrefs, crefSimVarHT);
12228+ vars2 := getSimVars2Crefs(diffCrefs, crefSimVarHT);
12229+ vars1 := listAppend(vars1, vars2);
12230+
12231+ sparseInts := sortSparsePattern(vars1, spT, true);
12232+ unknowns := translateSparsePatterInts2FMIUnknown(sparseInts, {});
12233+
12234+ // filter the initial unknowns with output and derivativelist index
12235+ unknowns := list(fmiUnknown for fmiUnknown guard(Util.boolOrList(list(isFmiUnknown(i, fmiUnknown) for i in listAppend(intLst,derivativesLst)))) in unknowns);
12236+
12237+ fmiInitUnknowns := SimCode.FMIINITIALUNKNOWNS(unknowns);
12238+ else
12239+ fmiInitUnknowns := SimCode.FMIINITIALUNKNOWNS({});
12240+ end try;
12241+ end getFMIInitialDep;
12242+
12243+ public function getVarCref
12244+ input BackendDAE.Var inVar;
12245+ output DAE.ComponentRef outComponentRef;
12246+ algorithm
12247+ outComponentRef := BackendVariable.varCref(inVar);
12248+ end getVarCref;
12249+
12250+ public function isVarOutputandNotfixed
12251+ input BackendDAE.Var inVar;
12252+ output Boolean outVar=false;
12253+ protected
12254+ Boolean direction;
12255+ algorithm
12256+ if (BackendVariable.isOutputVar(inVar) and not BackendVariable.varFixed(inVar)) then
12257+ outVar := true;
12258+ end if;
12259+ end isVarOutputandNotfixed;
12260+
1218412261public function getStateSimVarIndexFromIndex
1218512262 input list<SimCodeVar.SimVar> inStateVars;
1218612263 input Integer inIndex;
0 commit comments