diff --git a/BouncingBall/config.h b/BouncingBall/config.h index e4d8f85f..c655ac7d 100644 --- a/BouncingBall/config.h +++ b/BouncingBall/config.h @@ -8,9 +8,8 @@ #define CO_SIMULATION #define MODEL_EXCHANGE -// define model size -#define NX 2 -#define NZ 1 +#define HAS_CONTINUOUS_STATES +#define HAS_EVENT_INDICATORS #define SET_FLOAT64 #define GET_OUTPUT_DERIVATIVE diff --git a/BouncingBall/model.c b/BouncingBall/model.c index de96867b..969ae1d8 100644 --- a/BouncingBall/model.c +++ b/BouncingBall/model.c @@ -133,9 +133,6 @@ void eventUpdate(ModelInstance *comp) { M(g) = 0; } - // reset previous event indicators - getEventIndicators(comp, comp->z, NZ); - comp->valuesOfContinuousStatesChanged = true; } else { comp->valuesOfContinuousStatesChanged = false; @@ -146,6 +143,16 @@ void eventUpdate(ModelInstance *comp) { comp->nextEventTimeDefined = false; } +size_t getNumberOfEventIndicators(ModelInstance* comp) { + UNUSED(comp); + return 1; +} + +size_t getNumberOfContinuousStates(ModelInstance* comp) { + UNUSED(comp); + return 2; +} + void getContinuousStates(ModelInstance *comp, double x[], size_t nx) { UNUSED(nx); x[0] = M(h); diff --git a/Clocks/config.h b/Clocks/config.h index 69b92335..3fdc4183 100644 --- a/Clocks/config.h +++ b/Clocks/config.h @@ -13,10 +13,6 @@ #define DEFAULT_STOP_TIME 3 -// define model size -#define NX 0 -#define NZ 0 - #define EVENT_UPDATE #define ACTIVATE_CLOCK #define GET_INT32 diff --git a/Dahlquist/config.h b/Dahlquist/config.h index 62e14b00..decc9c94 100644 --- a/Dahlquist/config.h +++ b/Dahlquist/config.h @@ -8,9 +8,7 @@ #define CO_SIMULATION #define MODEL_EXCHANGE -// define model size -#define NX 1 -#define NZ 0 +#define HAS_CONTINUOUS_STATES #define SET_FLOAT64 diff --git a/Dahlquist/model.c b/Dahlquist/model.c index 0c7adaff..624e3249 100644 --- a/Dahlquist/model.c +++ b/Dahlquist/model.c @@ -62,6 +62,11 @@ Status setFloat64(ModelInstance* comp, ValueReference vr, const double values[], } } +size_t getNumberOfContinuousStates(ModelInstance* comp) { + UNUSED(comp); + return 1; +} + void getContinuousStates(ModelInstance *comp, double x[], size_t nx) { UNUSED(nx); x[0] = M(x); diff --git a/Feedthrough/config.h b/Feedthrough/config.h index 978441d2..9fd4f50c 100644 --- a/Feedthrough/config.h +++ b/Feedthrough/config.h @@ -12,9 +12,6 @@ #define CO_SIMULATION #define MODEL_EXCHANGE -#define NX 0 -#define NZ 0 - #define GET_FLOAT32 #define GET_FLOAT64 #define GET_INT8 diff --git a/Feedthrough/model.c b/Feedthrough/model.c index 8e435c54..20c89616 100644 --- a/Feedthrough/model.c +++ b/Feedthrough/model.c @@ -530,7 +530,6 @@ Status setUInt16(ModelInstance* comp, ValueReference vr, const uint16_t values[] return OK; } - Status setInt32(ModelInstance* comp, ValueReference vr, const int32_t values[], size_t nValues, size_t* index) { ASSERT_NVALUES(1); diff --git a/LinearTransform/config.h b/LinearTransform/config.h index 9256310a..d2867414 100644 --- a/LinearTransform/config.h +++ b/LinearTransform/config.h @@ -7,10 +7,6 @@ #define MODEL_IDENTIFIER LinearTransform #define INSTANTIATION_TOKEN "{D773325B-AB94-4630-BF85-643EB24FCB78}" -// define model size -#define NX 0 -#define NZ 0 - #define CO_SIMULATION #define MODEL_EXCHANGE diff --git a/Resource/config.h b/Resource/config.h index 9ffe48ff..386ef160 100644 --- a/Resource/config.h +++ b/Resource/config.h @@ -8,10 +8,6 @@ #define CO_SIMULATION #define MODEL_EXCHANGE -// define model size -#define NX 0 -#define NZ 0 - #define GET_INT32 #define FIXED_SOLVER_STEP 1 diff --git a/Stair/config.h b/Stair/config.h index c8b3720d..b18fd89a 100644 --- a/Stair/config.h +++ b/Stair/config.h @@ -8,10 +8,6 @@ #define CO_SIMULATION #define MODEL_EXCHANGE -// define model size -#define NX 0 -#define NZ 0 - #define GET_INT32 #define EVENT_UPDATE diff --git a/VanDerPol/config.h b/VanDerPol/config.h index 8383f02a..bdacc385 100644 --- a/VanDerPol/config.h +++ b/VanDerPol/config.h @@ -8,9 +8,7 @@ #define CO_SIMULATION #define MODEL_EXCHANGE -// define model size -#define NX 2 -#define NZ 0 +#define HAS_CONTINUOUS_STATES #define SET_FLOAT64 diff --git a/VanDerPol/model.c b/VanDerPol/model.c index 4dc2cf32..781ead97 100644 --- a/VanDerPol/model.c +++ b/VanDerPol/model.c @@ -74,6 +74,11 @@ Status setFloat64(ModelInstance* comp, ValueReference vr, const double values[], } } +size_t getNumberOfContinuousStates(ModelInstance* comp) { + UNUSED(comp); + return 2; +} + void getContinuousStates(ModelInstance *comp, double x[], size_t nx) { UNUSED(nx); x[0] = M(x0); diff --git a/examples/jacobian.c b/examples/jacobian.c index 76256cfb..4b86c0cd 100644 --- a/examples/jacobian.c +++ b/examples/jacobian.c @@ -4,6 +4,7 @@ #include "util.h" +#define NX 2 int main(int argc, char* argv[]) { @@ -12,9 +13,8 @@ int main(int argc, char* argv[]) { size_t i, j; fmi3Float64 time = 0; - size_t nx = NX; - fmi3ValueReference vr_x[] = { vr_x0, vr_x1 }; - fmi3ValueReference vr_dx[] = { vr_der_x0, vr_der_x1 }; + fmi3ValueReference vr_x[NX] = { vr_x0, vr_x1 }; + fmi3ValueReference vr_dx[NX] = { vr_der_x0, vr_der_x1 }; // variables: fmi3Float64 x[NX]; @@ -34,7 +34,7 @@ int main(int argc, char* argv[]) { CALL(FMI3EnterContinuousTimeMode(S)); - CALL(FMI3GetContinuousStates(S, x, nx)); + CALL(FMI3GetContinuousStates(S, x, NX)); // tag::JacobianVariables[] // from the XML file: @@ -54,14 +54,14 @@ int main(int argc, char* argv[]) { // set time, states and inputs CALL(FMI3SetTime(S, time)); - CALL(FMI3SetContinuousStates(S, x, nx)); + CALL(FMI3SetContinuousStates(S, x, NX)); // fmi3Set{VariableType}(s, ...) // if required at this step, compute the Jacobian as a dense matrix - for (i = 0; i < nx; i++) { + for (i = 0; i < NX; i++) { // construct the Jacobian matrix column wise - CALL(FMI3GetDirectionalDerivative(S, vr_dx, nx, &vr_x[i], 1, &dk, 1, c, nx)); - for (j = 0; j < nx; j++) { + CALL(FMI3GetDirectionalDerivative(S, vr_dx, NX, &vr_x[i], 1, &dk, 1, c, NX)); + for (j = 0; j < NX; j++) { J[j][i] = c[j]; } } @@ -73,9 +73,9 @@ int main(int argc, char* argv[]) { assert(J[1][1] == -3); // tag::GetJacobianAdjoint[] - for (i = 0; i < nx; i++) { + for (i = 0; i < NX; i++) { // construct the Jacobian matrix column wise - CALL(FMI3GetAdjointDerivative(S, &vr_dx[i], 1, vr_x, nx, &dk, 1, &J[i][0], nx)); + CALL(FMI3GetAdjointDerivative(S, &vr_dx[i], 1, vr_x, NX, &dk, 1, &J[i][0], NX)); } // end::GetJacobianAdjoint[] diff --git a/fmusim/FMICVode.c b/fmusim/FMICVode.c index 32e4afd0..9a9bc987 100644 --- a/fmusim/FMICVode.c +++ b/fmusim/FMICVode.c @@ -213,7 +213,11 @@ Solver* FMICVodeCreate(FMIInstance* S, const FMIModelDescription* modelDescripti solver->abstol = N_VNew_Serial(NV_LENGTH_S(solver->x), solver->sunctx); ASSERT_NOT_NULL(solver->abstol); - CALL_FMI(solver->get_nominals(solver->S, NV_DATA_S(solver->abstol), solver->nx)); + if (solver->nx > 0) { + CALL_FMI(solver->get_nominals(solver->S, NV_DATA_S(solver->abstol), solver->nx)); + } else { + NV_DATA_S(solver->abstol)[0] = 1; + } for (size_t i = 0; i < NV_LENGTH_S(solver->x); i++) { NV_DATA_S(solver->abstol)[i] *= tolerance; diff --git a/include/model.h b/include/model.h index 11b4be65..8cbb4be6 100644 --- a/include/model.h +++ b/include/model.h @@ -140,11 +140,6 @@ typedef struct { ModelData modelData; -#if NZ > 0 - // event indicators - double z[NZ]; -#endif - // internal solver steps uint64_t nSteps; @@ -152,6 +147,15 @@ typedef struct { bool earlyReturnAllowed; bool eventModeUsed; + // solver + size_t nz; + double* z; + double* prez; + + size_t nx; + double* x; + double* dx; + } ModelInstance; ModelInstance *createModelInstance( @@ -166,6 +170,8 @@ ModelInstance *createModelInstance( void freeModelInstance(ModelInstance *comp); +void exitInitializationMode(ModelInstance* comp); + void reset(ModelInstance* comp); void setStartValues(ModelInstance* comp); @@ -208,6 +214,8 @@ Status getInterval(ModelInstance* comp, ValueReference vr, double* interval, int Status activateModelPartition(ModelInstance* comp, ValueReference vr, double activationTime); +size_t getNumberOfEventIndicators(ModelInstance* comp); +size_t getNumberOfContinuousStates(ModelInstance* comp); void getContinuousStates(ModelInstance *comp, double x[], size_t nx); void setContinuousStates(ModelInstance *comp, const double x[], size_t nx); void getDerivatives(ModelInstance *comp, double dx[], size_t nx); diff --git a/src/cosimulation.c b/src/cosimulation.c index 689851a4..72c72f16 100644 --- a/src/cosimulation.c +++ b/src/cosimulation.c @@ -111,9 +111,44 @@ void freeModelInstance(ModelInstance *comp) { if (comp->resourceLocation) free((void*)comp->resourceLocation); + if (comp->prez) free(comp->prez); + + if (comp->z) free(comp->z); + + if (comp->x) free(comp->x); + + if (comp->dx) free(comp->dx); + free(comp); } +void exitInitializationMode(ModelInstance* comp) { + +#if !defined(HAS_EVENT_INDICATORS) && !defined(HAS_CONTINUOUS_STATES) + UNUSED(comp); +#endif + +#ifdef HAS_EVENT_INDICATORS + comp->nz = getNumberOfEventIndicators(comp); + + if (comp->nz > 0) { + comp->prez = calloc(comp->nz, sizeof(double)); + comp->z = calloc(comp->nz, sizeof(double)); + } + + getEventIndicators(comp, comp->prez, comp->nz); +#endif + +#ifdef HAS_CONTINUOUS_STATES + comp->nx = getNumberOfContinuousStates(comp); + + if (comp->nx > 0) { + comp->x = calloc(comp->nx, sizeof(double)); + comp->dx = calloc(comp->nx, sizeof(double)); + } +#endif +} + void reset(ModelInstance* comp) { comp->state = Instantiated; comp->startTime = 0.0; @@ -256,16 +291,6 @@ void logError(ModelInstance *comp, const char *message, ...) { va_end(args); } -// default implementations -#if NZ < 1 -void getEventIndicators(ModelInstance *comp, double z[], size_t nz) { - UNUSED(comp); - UNUSED(z); - UNUSED(nz); - // do nothing -} -#endif - #define GET_NOT_ALLOWED(t) do { \ UNUSED(vr); \ UNUSED(values); \ @@ -473,26 +498,6 @@ Status activateModelPartition(ModelInstance* comp, ValueReference vr, double act } #endif -#if NX < 1 -void getContinuousStates(ModelInstance *comp, double x[], size_t nx) { - UNUSED(comp); - UNUSED(x); - UNUSED(nx); -} - -void setContinuousStates(ModelInstance *comp, const double x[], size_t nx) { - UNUSED(comp); - UNUSED(x); - UNUSED(nx); -} - -void getDerivatives(ModelInstance *comp, double dx[], size_t nx) { - UNUSED(comp); - UNUSED(dx); - UNUSED(nx); -} -#endif - #ifndef GET_PARTIAL_DERIVATIVE Status getPartialDerivative(ModelInstance *comp, ValueReference unknown, ValueReference known, double *partialDerivative) { UNUSED(comp); @@ -533,27 +538,27 @@ void setFMUState(ModelInstance* comp, void* FMUState) { comp->clocksTicked = s->clocksTicked; comp->isDirtyValues = s->isDirtyValues; comp->modelData = s->modelData; -#if NZ > 0 - memcpy(comp->z, s->z, NZ * sizeof(double)); -#endif + if (comp->nz) { + memcpy(comp->z, s->z, s->nz * sizeof(double)); + } comp->nSteps = s->nSteps; } void doFixedStep(ModelInstance *comp, bool* stateEvent, bool* timeEvent) { -#if NX > 0 - double x[NX] = { 0 }; - double dx[NX] = { 0 }; +#ifdef HAS_CONTINUOUS_STATES + if (comp->nx > 0) { - getContinuousStates(comp, x, NX); - getDerivatives(comp, dx, NX); + getContinuousStates(comp, comp->x, comp->nx); + getDerivatives(comp, comp->dx, comp->nx); - // forward Euler step - for (int i = 0; i < NX; i++) { - x[i] += FIXED_SOLVER_STEP * dx[i]; - } + // forward Euler step + for (size_t i = 0; i < comp->nx; i++) { + comp->x[i] += FIXED_SOLVER_STEP * comp->dx[i]; + } - setContinuousStates(comp, x, NX); + setContinuousStates(comp, comp->x, comp->nx); + } #endif comp->nSteps++; @@ -563,18 +568,23 @@ void doFixedStep(ModelInstance *comp, bool* stateEvent, bool* timeEvent) { // state event *stateEvent = false; -#if NZ > 0 - double z[NZ] = { 0.0 }; +#ifdef HAS_EVENT_INDICATORS + if (comp->nz > 0) { - getEventIndicators(comp, z, NZ); + getEventIndicators(comp, comp->z, comp->nz); - // check for zero-crossings - for (int i = 0; i < NZ; i++) { - *stateEvent |= (comp->z[i] <= 0 && z[i] > 0) || (comp->z[i] > 0 && z[i] <= 0); - } + // check for zero-crossings + for (size_t i = 0; i < comp->nz; i++) { + *stateEvent |= + (comp->prez[i] <= 0 && comp->z[i] > 0) || + (comp->prez[i] > 0 && comp->z[i] <= 0); + } - // remember the current event indicators - memcpy(comp->z, z, sizeof(double) * NZ); + // remember the current event indicators + double* temp = comp->prez; + comp->prez = comp->z; + comp->z = temp; + } #endif // time event diff --git a/src/fmi1Functions.c b/src/fmi1Functions.c index 3f7d8006..9e8fa3df 100644 --- a/src/fmi1Functions.c +++ b/src/fmi1Functions.c @@ -447,16 +447,23 @@ fmiStatus fmiSetContinuousStates(fmiComponent c, const fmiReal x[], size_t nx) { ModelInstance* instance = (ModelInstance *)c; +#ifdef HAS_CONTINUOUS_STATES if (invalidState(instance, "fmiSetContinuousStates", Initialized)) return fmiError; - if (invalidNumber(instance, "fmiSetContinuousStates", "nx", nx, NX)) + if (invalidNumber(instance, "fmiSetContinuousStates", "nx", nx, getNumberOfContinuousStates(instance))) return fmiError; if (nullPointer(instance, "fmiSetContinuousStates", "x[]", x)) return fmiError; setContinuousStates(instance, x, nx); +#else + UNUSED(x); + + if (invalidNumber(instance, "fmiSetContinuousStates", "nx", nx, 0)) + return fmiError; +#endif return fmiOK; } @@ -515,16 +522,23 @@ fmiStatus fmiGetContinuousStates(fmiComponent c, fmiReal states[], size_t nx){ ModelInstance* instance = (ModelInstance *)c; +#ifdef HAS_CONTINUOUS_STATES if (invalidState(instance, "fmiGetContinuousStates", not_modelError)) return fmiError; - if (invalidNumber(instance, "fmiGetContinuousStates", "nx", nx, NX)) + if (invalidNumber(instance, "fmiGetContinuousStates", "nx", nx, getNumberOfContinuousStates(instance))) return fmiError; if (nullPointer(instance, "fmiGetContinuousStates", "states[]", states)) return fmiError; getContinuousStates(instance, states, nx); +#else + UNUSED(states); + + if (invalidNumber(instance, "fmiGetContinuousStates", "nx", nx, 0)) + return fmiError; +#endif return fmiOK; } @@ -533,10 +547,11 @@ fmiStatus fmiGetNominalContinuousStates(fmiComponent c, fmiReal x_nominal[], siz ModelInstance* instance = (ModelInstance *)c; +#ifdef HAS_CONTINUOUS_STATES if (invalidState(instance, "fmiGetNominalContinuousStates", not_modelError)) return fmiError; - if (invalidNumber(instance, "fmiGetNominalContinuousStates", "nx", nx, NX)) + if (invalidNumber(instance, "fmiGetNominalContinuousStates", "nx", nx, getNumberOfContinuousStates(instance))) return fmiError; if (nullPointer(instance, "fmiGetNominalContinuousStates", "x_nominal[]", x_nominal)) @@ -545,6 +560,12 @@ fmiStatus fmiGetNominalContinuousStates(fmiComponent c, fmiReal x_nominal[], siz for (size_t i = 0; i < nx; i++) { x_nominal[i] = 1; } +#else + UNUSED(x_nominal); + + if (invalidNumber(instance, "fmiGetNominalContinuousStates", "nx", nx, 0)) + return fmiError; +#endif return fmiOK; } @@ -553,16 +574,23 @@ fmiStatus fmiGetDerivatives(fmiComponent c, fmiReal derivatives[], size_t nx) { ModelInstance* instance = (ModelInstance *)c; +#ifdef HAS_CONTINUOUS_STATES if (invalidState(instance, "fmiGetDerivatives", not_modelError)) return fmiError; - if (invalidNumber(instance, "fmiGetDerivatives", "nx", nx, NX)) + if (invalidNumber(instance, "fmiGetDerivatives", "nx", nx, getNumberOfContinuousStates(instance))) return fmiError; if (nullPointer(instance, "fmiGetDerivatives", "derivatives[]", derivatives)) return fmiError; getDerivatives(instance, derivatives, nx); +#else + UNUSED(derivatives); + + if (invalidNumber(instance, "fmiGetDerivatives", "nx", nx, 0)) + return fmiError; +#endif return fmiOK; } @@ -571,13 +599,20 @@ fmiStatus fmiGetEventIndicators(fmiComponent c, fmiReal eventIndicators[], size_ ModelInstance* instance = (ModelInstance *)c; +#ifdef HAS_EVENT_INDICATORS if (invalidState(instance, "fmiGetEventIndicators", not_modelError)) return fmiError; - if (invalidNumber(instance, "fmiGetEventIndicators", "ni", ni, NZ)) + if (invalidNumber(instance, "fmiGetEventIndicators", "ni", ni, getNumberOfEventIndicators(instance))) return fmiError; getEventIndicators(instance, eventIndicators, ni); +#else + UNUSED(eventIndicators); + + if (invalidNumber(instance, "fmiGetEventIndicators", "ni", ni, 0)) + return fmiError; +#endif return fmiOK; } diff --git a/src/fmi2Functions.c b/src/fmi2Functions.c index 98c4a5f6..014f601d 100644 --- a/src/fmi2Functions.c +++ b/src/fmi2Functions.c @@ -807,13 +807,20 @@ fmi2Status fmi2SetContinuousStates(fmi2Component c, const fmi2Real x[], size_t n ASSERT_STATE(SetContinuousStates); - if (invalidNumber(S, "fmi2SetContinuousStates", "nx", nx, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi2SetContinuousStates", "nx", nx, getNumberOfContinuousStates(S))) return fmi2Error; if (nullPointer(S, "fmi2SetContinuousStates", "x[]", x)) return fmi2Error; setContinuousStates(S, x, nx); +#else + UNUSED(x); + + if (invalidNumber(S, "fmi2SetContinuousStates", "nx", nx, 0)) + return fmi2Error; +#endif return fmi2OK; } @@ -823,13 +830,20 @@ fmi2Status fmi2GetDerivatives(fmi2Component c, fmi2Real derivatives[], size_t nx ASSERT_STATE(GetDerivatives); - if (invalidNumber(S, "fmi2GetDerivatives", "nx", nx, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi2GetDerivatives", "nx", nx, getNumberOfContinuousStates(S))) return fmi2Error; if (nullPointer(S, "fmi2GetDerivatives", "derivatives[]", derivatives)) return fmi2Error; getDerivatives(S, derivatives, nx); +#else + UNUSED(derivatives); + + if (invalidNumber(S, "fmi2GetDerivatives", "nx", nx, 0)) + return fmi2Error; +#endif return fmi2OK; } @@ -838,17 +852,18 @@ fmi2Status fmi2GetEventIndicators(fmi2Component c, fmi2Real eventIndicators[], s ASSERT_STATE(GetEventIndicators); -#if NZ > 0 - - if (invalidNumber(S, "fmi2GetEventIndicators", "ni", ni, NZ)) +#ifdef HAS_EVENT_INDICATORS + if (invalidNumber(S, "fmi2GetEventIndicators", "ni", ni, getNumberOfEventIndicators(S))) return fmi2Error; getEventIndicators(S, eventIndicators, ni); #else - UNUSED(c); UNUSED(eventIndicators); - if (ni > 0) return fmi2Error; + + if (invalidNumber(S, "fmi2GetEventIndicators", "ni", ni, 0)) + return fmi2Error; #endif + return fmi2OK; } @@ -856,13 +871,20 @@ fmi2Status fmi2GetContinuousStates(fmi2Component c, fmi2Real states[], size_t nx ASSERT_STATE(GetContinuousStates); - if (invalidNumber(S, "fmi2GetContinuousStates", "nx", nx, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi2GetContinuousStates", "nx", nx, getNumberOfContinuousStates(S))) return fmi2Error; if (nullPointer(S, "fmi2GetContinuousStates", "states[]", states)) return fmi2Error; getContinuousStates(S, states, nx); +#else + UNUSED(states); + + if (invalidNumber(S, "fmi2GetContinuousStates", "nx", nx, 0)) + return fmi2Error; +#endif return fmi2OK; } @@ -871,7 +893,8 @@ fmi2Status fmi2GetNominalsOfContinuousStates(fmi2Component c, fmi2Real x_nominal ASSERT_STATE(GetNominalsOfContinuousStates); - if (invalidNumber(S, "fmi2GetNominalContinuousStates", "nx", nx, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi2GetNominalContinuousStates", "nx", nx, getNumberOfContinuousStates(S))) return fmi2Error; if (nullPointer(S, "fmi2GetNominalContinuousStates", "x_nominal[]", x_nominal)) @@ -879,6 +902,12 @@ fmi2Status fmi2GetNominalsOfContinuousStates(fmi2Component c, fmi2Real x_nominal for (size_t i = 0; i < nx; i++) x_nominal[i] = 1; +#else + UNUSED(x_nominal); + + if (invalidNumber(S, "fmi2GetNominalContinuousStates", "nx", nx, 0)) + return fmi2Error; +#endif return fmi2OK; } diff --git a/src/fmi3Functions.c b/src/fmi3Functions.c index 364bd49c..e6fb2a50 100644 --- a/src/fmi3Functions.c +++ b/src/fmi3Functions.c @@ -429,10 +429,7 @@ fmi3Status fmi3ExitInitializationMode(fmi3Instance instance) { break; } -#if NZ > 0 - // initialize event indicators - getEventIndicators(S, S->z, NZ); -#endif + exitInitializationMode(S); return status; } @@ -1212,11 +1209,12 @@ fmi3Status fmi3SetTime(fmi3Instance instance, fmi3Float64 time) { fmi3Status fmi3SetContinuousStates(fmi3Instance instance, const fmi3Float64 continuousStates[], - size_t nContinuousStates){ + size_t nContinuousStates) { ASSERT_STATE(SetContinuousStates); - if (invalidNumber(S, "fmi3SetContinuousStates", "nContinuousStates", nContinuousStates, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi3SetContinuousStates", "nContinuousStates", nContinuousStates, getNumberOfContinuousStates(S))) return fmi3Error; ASSERT_NOT_NULL(continuousStates); @@ -1224,6 +1222,11 @@ fmi3Status fmi3SetContinuousStates(fmi3Instance instance, setContinuousStates(S, continuousStates, nContinuousStates); return fmi3OK; +#else + UNUSED(continuousStates); + UNUSED(nContinuousStates); + return fmi3Error; +#endif } /* Evaluation of the model equations */ @@ -1233,7 +1236,8 @@ fmi3Status fmi3GetContinuousStateDerivatives(fmi3Instance instance, ASSERT_STATE(GetContinuousStateDerivatives); - if (invalidNumber(S, "fmi3GetContinuousStateDerivatives", "nContinuousStates", nContinuousStates, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi3GetContinuousStateDerivatives", "nContinuousStates", nContinuousStates, getNumberOfContinuousStates(S))) return fmi3Error; if (nullPointer(S, "fmi3GetContinuousStateDerivatives", "derivatives[]", derivatives)) @@ -1242,6 +1246,11 @@ fmi3Status fmi3GetContinuousStateDerivatives(fmi3Instance instance, getDerivatives(S, derivatives, nContinuousStates); return fmi3OK; +#else + UNUSED(derivatives); + UNUSED(nContinuousStates); + return fmi3Error; +#endif } fmi3Status fmi3GetEventIndicators(fmi3Instance instance, @@ -1250,8 +1259,8 @@ fmi3Status fmi3GetEventIndicators(fmi3Instance instance, ASSERT_STATE(GetEventIndicators); -#if NZ > 0 - if (invalidNumber(S, "fmi3GetEventIndicators", "nEventIndicators", nEventIndicators, NZ)) { +#ifdef HAS_EVENT_INDICATORS + if (invalidNumber(S, "fmi3GetEventIndicators", "nEventIndicators", nEventIndicators, getNumberOfEventIndicators(S))) { return fmi3Error; } @@ -1275,7 +1284,8 @@ fmi3Status fmi3GetContinuousStates(fmi3Instance instance, ASSERT_STATE(GetContinuousStates); - if (invalidNumber(S, "fmi3GetContinuousStates", "nContinuousStates", nContinuousStates, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi3GetContinuousStates", "nContinuousStates", nContinuousStates, getNumberOfContinuousStates(S))) return fmi3Error; if (nullPointer(S, "fmi3GetContinuousStates", "continuousStates[]", continuousStates)) @@ -1284,6 +1294,11 @@ fmi3Status fmi3GetContinuousStates(fmi3Instance instance, getContinuousStates(S, continuousStates, nContinuousStates); return fmi3OK; +#else + UNUSED(continuousStates); + UNUSED(nContinuousStates); + return fmi3Error; +#endif } fmi3Status fmi3GetNominalsOfContinuousStates(fmi3Instance instance, @@ -1292,7 +1307,8 @@ fmi3Status fmi3GetNominalsOfContinuousStates(fmi3Instance instance, ASSERT_STATE(GetNominalsOfContinuousStates); - if (invalidNumber(S, "fmi3GetNominalContinuousStates", "nContinuousStates", nContinuousStates, NX)) +#ifdef HAS_CONTINUOUS_STATES + if (invalidNumber(S, "fmi3GetNominalContinuousStates", "nContinuousStates", nContinuousStates, getNumberOfContinuousStates(instance))) return fmi3Error; if (nullPointer(S, "fmi3GetNominalContinuousStates", "nominals[]", nominals)) @@ -1303,6 +1319,11 @@ fmi3Status fmi3GetNominalsOfContinuousStates(fmi3Instance instance, } return fmi3OK; +#else + UNUSED(nominals); + UNUSED(nContinuousStates); + return fmi3Error; +#endif } fmi3Status fmi3GetNumberOfEventIndicators(fmi3Instance instance, @@ -1312,7 +1333,11 @@ fmi3Status fmi3GetNumberOfEventIndicators(fmi3Instance instance, ASSERT_NOT_NULL(nEventIndicators); - *nEventIndicators = NZ; +#ifdef HAS_ENVENT_INDICATORS + *nEventIndicators = nz(instance); +#else + *nEventIndicators = 0; +#endif return fmi3OK; } @@ -1324,8 +1349,11 @@ fmi3Status fmi3GetNumberOfContinuousStates(fmi3Instance instance, ASSERT_NOT_NULL(nContinuousStates); - *nContinuousStates = NX; - +#ifdef HAS_CONTINUOUS_STATES + *nContinuousStates = getNumberOfContinuousStates(instance); +#else + *nContinuousStates = 0; +#endif return fmi3OK; } @@ -1409,6 +1437,7 @@ fmi3Status fmi3DoStep(fmi3Instance instance, fmi3Boolean nextCommunicationPointReached; *eventHandlingNeeded = fmi3False; + *terminateSimulation = fmi3False; while (true) { @@ -1425,14 +1454,15 @@ fmi3Status fmi3DoStep(fmi3Instance instance, #ifdef EVENT_UPDATE if (stateEvent || timeEvent) { - *eventHandlingNeeded = fmi3True; - if (S->eventModeUsed) { - break; + *eventHandlingNeeded = fmi3True; + } else { + eventUpdate(S); +#ifdef HAS_EVENT_INDICATORS + getEventIndicators(S, S->prez, S->nz); +#endif } - eventUpdate(S); - if (S->earlyReturnAllowed) { break; } @@ -1442,8 +1472,6 @@ fmi3Status fmi3DoStep(fmi3Instance instance, *earlyReturn = !nextCommunicationPointReached; - *terminateSimulation = fmi3False; - *lastSuccessfulTime = S->time; return fmi3OK;