Skip to content

Commit 840b3fc

Browse files
Avoid unnecessary solver resets on events in which nothing changes
refs #1516
1 parent d07ea53 commit 840b3fc

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
{
@@ -876,6 +877,15 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
876877
{
877878
logDebug("event found!!! " + std::to_string(time));
878879

880+
for (size_t i = 0; i < fmus.size(); ++i)
881+
{
882+
if (0 == nStates[i])
883+
continue;
884+
885+
status = fmus[i]->getDerivatives(states_der[i]);
886+
if (oms_status_ok != status) return status;
887+
}
888+
879889
// Enter event mode and handle discrete state updates for each FMU
880890
for (size_t i = 0; i < fmus.size(); ++i)
881891
{
@@ -913,21 +923,38 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
913923
if (isTopLevelSystem())
914924
getModel().emit(time, true);
915925

926+
bool resetSolver = false;
916927
for (size_t i = 0; i < fmus.size(); ++i)
917928
{
918929
if (0 == nStates[i])
919930
continue;
920931

921932
status = fmus[i]->getContinuousStates(states[i]);
922933
if (oms_status_ok != status) return status;
934+
935+
// Check whether dervative values have changed due to the event
936+
std::vector<double> prevDer;
937+
prevDer.reserve(nStates[i]);
938+
prevDer.assign(states_der[i], states_der[i] + nStates[i]);
939+
940+
status = fmus[i]->getDerivatives(states_der[i]);
941+
if (oms_status_ok != status) return status;
942+
943+
for (int k = 0; k < nStates[i]; k++) {
944+
double diff = states_der[i][k] - prevDer[k];
945+
if (fabs(diff) > absoluteTolerance && fabs(diff) > relativeTolerance * fabs(prevDer[k]))
946+
resetSolver = true;
947+
}
923948
}
924949

925950
for (size_t j=0, k=0; j < fmus.size(); ++j)
926951
for (size_t i=0; i < nStates[j]; ++i, ++k)
927952
NV_Ith_S(solverData.cvode.y, k) = states[j][i];
928953

929-
flag = CVodeReInit(solverData.cvode.mem, time, solverData.cvode.y);
930-
if (flag < 0) return logError("SUNDIALS_ERROR: CVodeReInit() failed with flag = " + std::to_string(flag));
954+
if (resetSolver) {
955+
flag = CVodeReInit(solverData.cvode.mem, time, solverData.cvode.y);
956+
if (flag < 0) return logError("SUNDIALS_ERROR: CVodeReInit() failed with flag = " + std::to_string(flag));
957+
}
931958

932959
return oms_status_ok;
933960
}

0 commit comments

Comments
 (0)