Skip to content

Commit 1738313

Browse files
review fixes: re-factor cs algorithm
1 parent aee97c1 commit 1738313

2 files changed

Lines changed: 31 additions & 30 deletions

File tree

src/pyfmi/fmi3.pyx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3916,9 +3916,11 @@ cdef class FMUModelCS3(FMUModelBase3):
39163916
39173917
status --
39183918
The status of function which can be checked against
3919-
FMI_OK, FMI_WARNING. FMI_DISCARD, FMI_ERROR, FMI_FATAL
3919+
FMI_OK, FMI_WARNING, FMI_DISCARD, FMI_ERROR, FMI_FATAL.
39203920
3921-
Calls the underlying low-level function fmi3DoStep.
3921+
Calls the underlying low-level function fmi3DoStep.
3922+
The `do_step_terminated` class attribute tracks the fmi3DoStep return
3923+
for `terminateSimulation`.
39223924
"""
39233925
cdef FMIL3.fmi3_status_t status
39243926
cdef FMIL3.fmi3_boolean_t new_s

src/pyfmi/fmi_algorithm_drivers.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import numpy as np
2525
import scipy.optimize as spopt
2626

27-
from pyfmi.fmi1 import FMUModelME1, FMUModelCS1, FMI_ERROR, FMI_DISCARD, FMI1_LAST_SUCCESSFUL_TIME # TODO
27+
from pyfmi.fmi1 import FMUModelME1, FMUModelCS1, FMI_OK, FMI_ERROR, FMI_DISCARD, FMI1_LAST_SUCCESSFUL_TIME # TODO
2828
from pyfmi.fmi2 import FMUModelME2, FMUModelCS2, FMI2_INPUT, FMI2_LAST_SUCCESSFUL_TIME
2929
from pyfmi.fmi3 import FMUModelME3, FMUModelCS3
3030
from pyfmi.fmi_coupled import CoupledFMUModelME2
@@ -1015,6 +1015,26 @@ def _set_solver_options(self):
10151015
"""
10161016
pass #No solver options
10171017

1018+
def _check_do_step_status_and_terminated(self, status) -> tuple[bool, float]:
1019+
"""Return (true, <termination_time>) if terminated, (False, 0) else.
1020+
Raise exception in case of error returns."""
1021+
if status != FMI_OK:
1022+
if status == FMI_DISCARD and isinstance(self.model, (FMUModelCS1, FMUModelCS2)):
1023+
try:
1024+
if isinstance(self.model, FMUModelCS1):
1025+
last_time = self.model.get_real_status(FMI1_LAST_SUCCESSFUL_TIME)
1026+
else:
1027+
last_time = self.model.get_real_status(FMI2_LAST_SUCCESSFUL_TIME)
1028+
return True, last_time
1029+
except FMUException:
1030+
pass
1031+
else: # status = error || fatal || (discard && FMI3)
1032+
raise FMUException("The simulation failed. See the log for more information. Return flag %d."%status)
1033+
elif isinstance(self.model, FMUModelCS3):
1034+
if self.model.do_step_terminated:
1035+
return True, self.model.time
1036+
return False, 0
1037+
10181038
def solve(self):
10191039
"""
10201040
Runs the simulation.
@@ -1045,37 +1065,16 @@ def solve(self):
10451065
status = self.model.do_step(t,h)
10461066
self.status = status
10471067

1048-
if isinstance(self.model, FMUModelCS3):
1049-
if self.model.do_step_terminated:
1050-
final_time = self.model.time
1068+
terminated, terminated_time = self._check_do_step_status_and_terminated(status)
1069+
if terminated:
1070+
if terminated_time > t: # only store additional point if time advanced
1071+
self.model.time = terminated_time
1072+
final_time = terminated_time
10511073

10521074
start_time_point = timer()
10531075
result_handler.integration_point()
10541076
self.timings["storing_result"] += timer() - start_time_point
1055-
break
1056-
1057-
if status != 0:
1058-
1059-
if status == FMI_ERROR:
1060-
raise FMUException("The simulation failed. See the log for more information. Return flag %d."%status)
1061-
1062-
elif status == FMI_DISCARD and isinstance(self.model, (FMUModelCS1, FMUModelCS2)):
1063-
1064-
try:
1065-
if isinstance(self.model, FMUModelCS1):
1066-
last_time = self.model.get_real_status(FMI1_LAST_SUCCESSFUL_TIME)
1067-
else:
1068-
last_time = self.model.get_real_status(FMI2_LAST_SUCCESSFUL_TIME)
1069-
if last_time > t: #Solver succeeded in taken a step a little further than the last time
1070-
self.model.time = last_time
1071-
final_time = last_time
1072-
1073-
start_time_point = timer()
1074-
result_handler.integration_point()
1075-
self.timings["storing_result"] += timer() - start_time_point
1076-
except FMUException:
1077-
pass
1078-
break
1077+
break # stop integration loop
10791078

10801079
final_time = t+h
10811080

0 commit comments

Comments
 (0)