Skip to content

Commit 9fe15bd

Browse files
Fix order of operations in SystemSC (first writes, then reads)
refs #1326
1 parent fd10ddb commit 9fe15bd

1 file changed

Lines changed: 38 additions & 52 deletions

File tree

src/OMSimulatorLib/SystemSC.cpp

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,10 @@ oms_status_enu_t oms::SystemSC::doStepEuler(double stopTime)
613613
step_size_adjustment *= 0.5; // reduce the step size in each iteration
614614

615615
// a. Evaluate derivatives for each FMU
616+
// set time
617+
for (const auto& component : getComponents())
618+
component.second->setTime(time);
619+
616620
const fmi2Real step_size = event_time - time; // Substep size, do one step from current time to the event
617621
logDebug("step_size: " + std::to_string(step_size) + " | " + std::to_string(time) + " -> " + std::to_string(event_time));
618622
for (size_t i = 0; i < fmus.size(); ++i)
@@ -627,6 +631,8 @@ oms_status_enu_t oms::SystemSC::doStepEuler(double stopTime)
627631
if (oms_status_ok != status) return status;
628632
}
629633

634+
updateInputs(eventGraph);
635+
630636
// b. Event Detection
631637
event_detected = event_time == tnext;
632638
logDebug("Event detected: " + std::to_string(event_detected));
@@ -657,10 +663,6 @@ oms_status_enu_t oms::SystemSC::doStepEuler(double stopTime)
657663
time = event_time;
658664
step_size_adjustment = maximumStepSize;
659665

660-
// set time
661-
for (const auto& component : getComponents())
662-
component.second->setTime(time);
663-
664666
for (size_t i = 0; i < fmus.size(); ++i)
665667
{
666668
fmistatus = fmi2_completedIntegratorStep(fmus[i]->getFMU(), fmi2True, &callEventUpdate[i], &terminateSimulation[i]);
@@ -696,10 +698,6 @@ oms_status_enu_t oms::SystemSC::doStepEuler(double stopTime)
696698
if (isTopLevelSystem())
697699
getModel().emit(time, false);
698700

699-
// set time
700-
for (const auto& component : getComponents())
701-
component.second->setTime(time);
702-
703701
// Enter event mode and handle discrete state updates for each FMU
704702
for (size_t i = 0; i < fmus.size(); ++i)
705703
{
@@ -713,7 +711,16 @@ oms_status_enu_t oms::SystemSC::doStepEuler(double stopTime)
713711

714712
fmistatus = fmi2_enterContinuousTimeMode(fmus[i]->getFMU());
715713
if (fmi2OK != fmistatus) logError_FMUCall("fmi2_enterContinuousTimeMode", fmus[i]);
716-
714+
}
715+
716+
updateInputs(eventGraph);
717+
718+
// emit the right limit of the event
719+
if (isTopLevelSystem())
720+
getModel().emit(time, true);
721+
722+
for (size_t i = 0; i < fmus.size(); ++i)
723+
{
717724
if (nStates[i] > 0)
718725
{
719726
status = fmus[i]->getContinuousStates(states_backup[i]);
@@ -722,8 +729,11 @@ oms_status_enu_t oms::SystemSC::doStepEuler(double stopTime)
722729
if (oms_status_ok != status) return status;
723730
}
724731

725-
status = fmus[i]->getEventindicators(event_indicators_prev[i]);
726-
if (oms_status_ok != status) return status;
732+
if (nEventIndicators[i] > 0)
733+
{
734+
status = fmus[i]->getEventindicators(event_indicators_prev[i]);
735+
if (oms_status_ok != status) return status;
736+
}
727737
}
728738

729739
// find next time event
@@ -740,11 +750,6 @@ oms_status_enu_t oms::SystemSC::doStepEuler(double stopTime)
740750
terminated = true;
741751
}
742752
}
743-
744-
// emit the right limit of the event
745-
updateInputs(eventGraph);
746-
if (isTopLevelSystem())
747-
getModel().emit(time, true);
748753
}
749754
else
750755
{
@@ -835,8 +840,15 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
835840

836841
time = cvode_time;
837842

843+
// set time
844+
for (const auto& component : getComponents())
845+
component.second->setTime(time);
846+
838847
for (size_t i = 0, j=0; i < fmus.size(); ++i)
839848
{
849+
if (nStates[i] == 0)
850+
continue;
851+
840852
for (size_t k = 0; k < nStates[i]; k++, j++)
841853
states[i][k] = NV_Ith_S(solverData.cvode.y, j);
842854

@@ -845,24 +857,20 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
845857
if (oms_status_ok != status) return status;
846858
}
847859

860+
updateInputs(eventGraph);
861+
if (isTopLevelSystem())
862+
getModel().emit(time, false);
863+
864+
for (size_t i = 0; i < fmus.size(); ++i)
865+
{
866+
fmistatus = fmi2_completedIntegratorStep(fmus[i]->getFMU(), fmi2True, &callEventUpdate[i], &terminateSimulation[i]);
867+
if (fmi2OK != fmistatus) return logError_FMUCall("fmi2_completedIntegratorStep", fmus[i]);
868+
}
869+
848870
if (flag == CV_ROOT_RETURN || tnext_is_event && time == tnext)
849871
{
850872
logDebug("event found!!! " + std::to_string(time));
851873

852-
// set time
853-
for (const auto& component : getComponents())
854-
component.second->setTime(time);
855-
856-
for (size_t i = 0; i < fmus.size(); ++i)
857-
{
858-
fmistatus = fmi2_completedIntegratorStep(fmus[i]->getFMU(), fmi2True, &callEventUpdate[i], &terminateSimulation[i]);
859-
if (fmi2OK != fmistatus) return logError_FMUCall("fmi2_completedIntegratorStep", fmus[i]);
860-
}
861-
862-
updateInputs(eventGraph);
863-
if (isTopLevelSystem())
864-
getModel().emit(time, false);
865-
866874
// Enter event mode and handle discrete state updates for each FMU
867875
for (size_t i = 0; i < fmus.size(); ++i)
868876
{
@@ -920,29 +928,7 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
920928
}
921929

922930
if (flag >= 0) // Some kind of success
923-
{
924931
logDebug("CVode completed successfully at t = " + std::to_string(time));
925-
926-
// set time
927-
for (const auto& component : getComponents())
928-
component.second->setTime(time);
929-
930-
for (size_t i = 0; i < fmus.size(); ++i)
931-
{
932-
fmistatus = fmi2_completedIntegratorStep(fmus[i]->getFMU(), fmi2True, &callEventUpdate[i], &terminateSimulation[i]);
933-
if (fmi2OK != fmistatus) return logError_FMUCall("fmi2_completedIntegratorStep", fmus[i]);
934-
935-
if (0 == nStates[i])
936-
continue;
937-
938-
status = fmus[i]->getContinuousStates(states[i]);
939-
if (oms_status_ok != status) return status;
940-
}
941-
942-
updateInputs(eventGraph);
943-
if (isTopLevelSystem())
944-
getModel().emit(time, false);
945-
}
946932
else
947933
return logError("CVode failed with flag = " + std::to_string(flag));
948934
//}

0 commit comments

Comments
 (0)