Skip to content

Commit 35ea997

Browse files
Avoid unnecessary solver resets on events in which nothing changes
refs #1516
1 parent c11f4ee commit 35ea997

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

src/OMSimulatorLib/SystemSC.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <algorithm>
4242
#include <cstring>
4343
#include <sstream>
44+
#include <cmath>
4445

4546
int oms::cvode_rhs(realtype t, N_Vector y, N_Vector ydot, void* user_data)
4647
{
@@ -860,6 +861,15 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
860861
{
861862
logDebug("event found!!! " + std::to_string(time));
862863

864+
for (size_t i = 0; i < fmus.size(); ++i)
865+
{
866+
if (0 == nStates[i])
867+
continue;
868+
869+
status = fmus[i]->getDerivatives(states_der[i]);
870+
if (oms_status_ok != status) return status;
871+
}
872+
863873
// Enter event mode and handle discrete state updates for each FMU
864874
for (size_t i = 0; i < fmus.size(); ++i)
865875
{
@@ -897,21 +907,38 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
897907
if (isTopLevelSystem())
898908
getModel().emit(time, true);
899909

910+
bool resetSolver = false;
900911
for (size_t i = 0; i < fmus.size(); ++i)
901912
{
902913
if (0 == nStates[i])
903914
continue;
904915

905916
status = fmus[i]->getContinuousStates(states[i]);
906917
if (oms_status_ok != status) return status;
918+
919+
// Check whether dervative values have changed due to the event
920+
std::vector<double> prevDer;
921+
prevDer.reserve(nStates[i]);
922+
prevDer.assign(states_der[i], states_der[i] + nStates[i]);
923+
924+
status = fmus[i]->getDerivatives(states_der[i]);
925+
if (oms_status_ok != status) return status;
926+
927+
for (int k = 0; k < nStates[i]; k++) {
928+
double diff = states_der[i][k] - prevDer[k];
929+
if (fabs(diff) > absoluteTolerance && fabs(diff) > relativeTolerance * fabs(prevDer[k]))
930+
resetSolver = true;
931+
}
907932
}
908933

909934
for (size_t j=0, k=0; j < fmus.size(); ++j)
910935
for (size_t i=0; i < nStates[j]; ++i, ++k)
911936
NV_Ith_S(solverData.cvode.y, k) = states[j][i];
912937

913-
flag = CVodeReInit(solverData.cvode.mem, time, solverData.cvode.y);
914-
if (flag < 0) return logError("SUNDIALS_ERROR: CVodeReInit() failed with flag = " + std::to_string(flag));
938+
if (resetSolver) {
939+
flag = CVodeReInit(solverData.cvode.mem, time, solverData.cvode.y);
940+
if (flag < 0) return logError("SUNDIALS_ERROR: CVodeReInit() failed with flag = " + std::to_string(flag));
941+
}
915942

916943
return oms_status_ok;
917944
}

0 commit comments

Comments
 (0)