@@ -483,13 +483,13 @@ fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2Str
483483#endif
484484
485485 /* allocate memory for Jacobian */
486+ comp -> _has_jacobian = 0 ;
487+ comp -> fmiDerJac = NULL ;
486488 if (comp -> fmuData -> callback -> initialPartialFMIDER != NULL ){
487- comp -> _has_jacobian = 1 ;
488- comp -> fmiDerJac = & (comp -> fmuData -> simulationInfo -> analyticJacobians [comp -> fmuData -> callback -> INDEX_JAC_FMIDER ]);
489- }
490- else {
491- comp -> _has_jacobian = 0 ;
492- comp -> fmiDerJac = NULL ;
489+ if (! comp -> fmuData -> callback -> initialPartialFMIDER (comp -> fmuData , comp -> threadData )) {
490+ comp -> _has_jacobian = 1 ;
491+ comp -> fmiDerJac = & (comp -> fmuData -> simulationInfo -> analyticJacobians [comp -> fmuData -> callback -> INDEX_JAC_FMIDER ]);
492+ }
493493 }
494494
495495 FILTERED_LOG (comp , fmi2OK , LOG_FMI2_CALL , "fmi2Instantiate: GUID=%s" , fmuGUID )
@@ -960,7 +960,9 @@ fmi2Status fmi2DeSerializeFMUstate(fmi2Component c, const fmi2Byte serializedSta
960960 return unsupportedFunction (c , "fmi2DeSerializeFMUstate" , modelInstantiated |modelInitializationMode |modelEventMode |modelContinuousTimeMode |modelTerminated |modelError );
961961}
962962
963- fmi2Status fmi2GetDirectionalDerivative (fmi2Component c , const fmi2ValueReference vUnknown_ref [], size_t nUnknown , const fmi2ValueReference vKnown_ref [] , size_t nKnown ,
963+ fmi2Status fmi2GetDirectionalDerivative (fmi2Component c ,
964+ const fmi2ValueReference vUnknown_ref [], size_t nUnknown ,
965+ const fmi2ValueReference vKnown_ref [] , size_t nKnown ,
964966 const fmi2Real dvKnown [], fmi2Real dvUnknown [])
965967{
966968 ModelInstance * comp = (ModelInstance * )c ;
@@ -980,20 +982,27 @@ fmi2Status fmi2GetDirectionalDerivative(fmi2Component c, const fmi2ValueReferenc
980982 if (!comp -> _has_jacobian )
981983 return unsupportedFunction (c , "fmi2GetDirectionalDerivative" , modelInitializationMode |modelEventMode |modelContinuousTimeMode |modelTerminated |modelError );
982984 /***************************************/
983- // This code assumes that the FMU variables are always sorted,
984- // states first and then derivatives.
985- // This is true for the actual OMC FMUs.
986-
987- /* TODO: Use the literal names instead of the data-> structure
988- * Beware! This code assumes that the FMI variables are sorted putting
989- * states first (0 to nStates-1) and state derivatives (nStates to 2*nStates-1) second. */
985+ /* This code assumes that the FMU variables are always sorted,
986+ states first and then derivatives.
987+ This is true for the actual OMC FMUs.
988+ The input values references are mapped with mapInputReference2InputNumber
989+ and mapOutputReference2OutputNumber functions
990+ */
991+ /* clear out the seeds */
990992 for (i = 0 ;i < independent ; i ++ ) {
991- // Clear out the seeds
992993 comp -> fmiDerJac -> seedVars [i ]= 0 ;
993994 }
994- for (i = 0 ;i < nUnknown ; i ++ ) {
995+ for (i = 0 ;i < nKnown ; i ++ ) {
996+ int idx = vKnown_ref [i ];
997+ /* if idx is > nStates it's an input so we need a mapping */
998+ if (idx >= modelData -> nStates ){
999+ idx = mapInputReference2InputNumber (vKnown_ref [i ]);
1000+ idx = modelData -> nStates + idx ;
1001+ }
1002+ if (vrOutOfRange (comp , "fmi2GetDirectionalDerivative input index" , idx , independent ))
1003+ return fmi2Error ;
9951004 /* Put the supplied value in the seeds */
996- comp -> fmiDerJac -> seedVars [vUnknown_ref [ i ] ]= dvKnown [i ];
1005+ comp -> fmiDerJac -> seedVars [idx ]= dvKnown [i ];
9971006 }
9981007 /* Call the Jacobian evaluation function. This function evaluates the whole column of the Jacobian.
9991008 * More efficient code could only evaluate the equations needed for the
@@ -1002,9 +1011,18 @@ fmi2Status fmi2GetDirectionalDerivative(fmi2Component c, const fmi2ValueReferenc
10021011 fmudata -> callback -> functionJacFMIDER_column (fmudata , td );
10031012 resetThreadData (comp );
10041013
1005- // Write the results back to the array
1006- for (i = 0 ;i < nKnown ; i ++ ) {
1007- dvUnknown [vKnown_ref [i ]- dependent ] = comp -> fmiDerJac -> resultVars [vKnown_ref [i ]- dependent ];
1014+ /* Write the results to dvUnknown array */
1015+ for (i = 0 ;i < nUnknown ; i ++ ) {
1016+ /* derivatives are behind the states */
1017+ int idx = vUnknown_ref [i ] - modelData -> nStates ;
1018+ /* if idx is > nStates it's an output so we need a mapping */
1019+ if (idx >= modelData -> nStates ){
1020+ idx = mapOutputReference2OutputNumber (vUnknown_ref [i ]);
1021+ idx = modelData -> nStates + idx ;
1022+ }
1023+ if (vrOutOfRange (comp , "fmi2GetDirectionalDerivative output index" , idx , dependent ))
1024+ return fmi2Error ;
1025+ dvUnknown [i ] = comp -> fmiDerJac -> resultVars [idx ];
10081026 }
10091027 /***************************************/
10101028 return fmi2OK ;
0 commit comments