Skip to content

Commit 4c3fe79

Browse files
Fix order of operations in SystemSC (first writes, then reads)
refs #1326
1 parent 25e1a2b commit 4c3fe79

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
{
@@ -819,8 +824,15 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
819824

820825
time = cvode_time;
821826

827+
// set time
828+
for (const auto& component : getComponents())
829+
component.second->setTime(time);
830+
822831
for (size_t i = 0, j=0; i < fmus.size(); ++i)
823832
{
833+
if (nStates[i] == 0)
834+
continue;
835+
824836
for (size_t k = 0; k < nStates[i]; k++, j++)
825837
states[i][k] = NV_Ith_S(solverData.cvode.y, j);
826838

@@ -829,24 +841,20 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
829841
if (oms_status_ok != status) return status;
830842
}
831843

844+
updateInputs(eventGraph);
845+
if (isTopLevelSystem())
846+
getModel().emit(time, false);
847+
848+
for (size_t i = 0; i < fmus.size(); ++i)
849+
{
850+
fmistatus = fmi2_completedIntegratorStep(fmus[i]->getFMU(), fmi2True, &callEventUpdate[i], &terminateSimulation[i]);
851+
if (fmi2OK != fmistatus) return logError_FMUCall("fmi2_completedIntegratorStep", fmus[i]);
852+
}
853+
832854
if (flag == CV_ROOT_RETURN || tnext_is_event && time == tnext)
833855
{
834856
logDebug("event found!!! " + std::to_string(time));
835857

836-
// set time
837-
for (const auto& component : getComponents())
838-
component.second->setTime(time);
839-
840-
for (size_t i = 0; i < fmus.size(); ++i)
841-
{
842-
fmistatus = fmi2_completedIntegratorStep(fmus[i]->getFMU(), fmi2True, &callEventUpdate[i], &terminateSimulation[i]);
843-
if (fmi2OK != fmistatus) return logError_FMUCall("fmi2_completedIntegratorStep", fmus[i]);
844-
}
845-
846-
updateInputs(eventGraph);
847-
if (isTopLevelSystem())
848-
getModel().emit(time, false);
849-
850858
// Enter event mode and handle discrete state updates for each FMU
851859
for (size_t i = 0; i < fmus.size(); ++i)
852860
{
@@ -904,29 +912,7 @@ oms_status_enu_t oms::SystemSC::doStepCVODE(double stopTime)
904912
}
905913

906914
if (flag >= 0) // Some kind of success
907-
{
908915
logDebug("CVode completed successfully at t = " + std::to_string(time));
909-
910-
// set time
911-
for (const auto& component : getComponents())
912-
component.second->setTime(time);
913-
914-
for (size_t i = 0; i < fmus.size(); ++i)
915-
{
916-
fmistatus = fmi2_completedIntegratorStep(fmus[i]->getFMU(), fmi2True, &callEventUpdate[i], &terminateSimulation[i]);
917-
if (fmi2OK != fmistatus) return logError_FMUCall("fmi2_completedIntegratorStep", fmus[i]);
918-
919-
if (0 == nStates[i])
920-
continue;
921-
922-
status = fmus[i]->getContinuousStates(states[i]);
923-
if (oms_status_ok != status) return status;
924-
}
925-
926-
updateInputs(eventGraph);
927-
if (isTopLevelSystem())
928-
getModel().emit(time, false);
929-
}
930916
else
931917
return logError("CVode failed with flag = " + std::to_string(flag));
932918
//}

0 commit comments

Comments
 (0)