8000 ENH: Parallel mode for monte-carlo simulations 2 by Gui-FernandesBR · Pull Request #768 · RocketPy-Team/RocketPy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Parallel mode for monte-carlo simulations 2 #768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 14, 2025
Prev Previous commit
Next Next commit
MNT: implementing back the last version of MonteCarlo class prior to …
…conflict solving
  • Loading branch information
Lucas-Prates committed Feb 11, 2025
commit fc38e3a730c9d053d575f4f19ba0ade4021643a8
38 changes: 0 additions & 38 deletions rocketpy/simulation/monte_carlo.py
A389
Original file line number Diff line number Diff line change
Expand Up @@ -218,50 +218,19 @@
running the simulation again with `append=False`.
"""
self._export_config = kwargs
# Create data files for inputs, outputs and error logging
open_mode = "a" if append else "w"
input_file = open(self._input_file, open_mode, encoding="utf-8")
output_file = open(self._output_file, open_mode, encoding="utf-8")
error_file = open(self._error_file, open_mode, encoding="utf-8")

# initialize counters
self.number_of_simulations = number_of_simulations
self._initial_sim_idx = self.num_of_loaded_sims if append else 0

Check warning on line 222 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L222

Added line #L222 was not covered by tests

_SimMonitor.reprint("Starting Monte Carlo analysis")

Check warning on line 224 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L224

Added line #L224 was not covered by tests

self.__setup_files(append)

Check warning on line 226 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L226

Added line #L226 was not covered by tests
try:
while self.__iteration_count < self.number_of_simulations:
self.__run_single_simulation(input_file, output_file)
except KeyboardInterrupt:
print("Keyboard Interrupt, files saved.")
error_file.write(
json.dumps(
self._inputs_dict, cls=RocketPyEncoder, **self._export_config
)
+ "\n"
)
self.__close_files(input_file, output_file, error_file)
except Exception as error:
print(f"Error on iteration {self.__iteration_count}: {error}")
error_file.write(
json.dumps(
self._inputs_dict, cls=RocketPyEncoder, **self._export_config
)
+ "\n"
)
self.__close_files(input_file, output_file, error_file)
raise error
finally:
self.total_wall_time = time() - self.__start_time

if parallel:
self.__run_in_parallel(n_workers)

Check warning on line 229 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L228-L229

Added lines #L228 - L229 were not covered by tests
else:
self.__run_in_serial()

Check warning on line 231 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L231

Added line #L231 was not covered by tests

self.__terminate_simulation()

Check warning on line 233 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L233

Added line #L233 was not covered by tests

def __setup_files(self, append):
"""
Expand All @@ -278,23 +247,23 @@
None
"""
# Create data files for inputs, outputs and error logging
open_mode = "r+" if append else "w+"

Check warning on line 250 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L250

Added line #L250 was not covered by tests

try:
with open(self._input_file, open_mode, encoding="utf-8") as input_file:
idx_i = len(input_file.readlines())
with open(self._output_file, open_mode, encoding="utf-8") as output_file:
idx_o = len(output_file.readlines())
with open(self._error_file, open_mode, encoding="utf-8"):
pass

Check warning on line 258 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L252-L258

Added lines #L252 - L258 were not covered by tests

if idx_i != idx_o and not append:

Check warning on line 260 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L260

Added line #L260 was not covered by tests
warnings.warn(
"Input and output files are not synchronized", UserWarning
)

except OSError as error:
raise OSError(f"Error creating files: {error}") from error

Check warning on line 266 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L265-L266

Added lines #L265 - L266 were not covered by tests

def __run_in_serial(self):
"""
Expand All @@ -304,38 +273,38 @@
-------
None
"""
sim_monitor = _SimMonitor(

Check warning on line 276 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L276

Added line #L276 was not covered by tests
initial_count=self._initial_sim_idx,
n_simulations=self.number_of_simulations,
start_time=time(),
)
try:
while sim_monitor.keep_simulating():
sim_monitor.increment()

Check warning on line 283 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L281-L283

Added lines #L281 - L283 were not covered by tests

flight = self.__run_single_simulation()
inputs_json = self.__evaluate_flight_inputs(sim_monitor.count)
outputs_json = self.__evaluate_flight_outputs(flight, sim_monitor.count)

Check warning on line 287 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L285-L287

Added lines #L285 - L287 were not covered by tests

with open(self.input_file, "a", encoding="utf-8") as f:
f.write(inputs_json)
with open(self.output_file, "a", encoding="utf-8") as f:
f.write(outputs_json)

Check warning on line 292 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L289-L292

Added lines #L289 - L292 were not covered by tests

sim_monitor.print_update_status(sim_monitor.count)

Check warning on line 294 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L294

Added line #L294 was not covered by tests

sim_monitor.print_final_status()

Check warning on line 296 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L296

Added line #L296 was not covered by tests

except KeyboardInterrupt:
_SimMonitor.reprint("Keyboard Interrupt, files saved.")
with open(self._error_file, "a", encoding="utf-8") as f:
f.write(inputs_json)

Check warning on line 301 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L298-L301

Added lines #L298 - L301 were not covered by tests

except Exception as error:
_SimMonitor.reprint(f"Error on iteration {sim_monitor.count}: {error}")
with open(self._error_file, "a", encoding="utf-8") as f:
f.write(inputs_json)
raise error

Check warning on line 307 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L303-L307

Added lines #L303 - L307 were not covered by tests

# pylint: disable=too-many-statements
def __run_in_parallel(self, n_workers=None):
Expand All @@ -352,30 +321,30 @@
-------
None
"""
if n_workers is None or n_workers > os.cpu_count():
n_workers = os.cpu_count()

Check warning on line 325 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L324-L325

Added lines #L324 - L325 were not covered by tests

if n_workers < 2:
raise ValueError("Number of workers must be at least 2 for parallel mode.")

Check warning on line 328 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L327-L328

Added lines #L327 - L328 were not covered by tests

_SimMonitor.reprint(f"Running Monte Carlo simulation with {n_workers} workers.")

Check warning on line 330 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L330

Added line #L330 was not covered by tests

multiprocess, managers = _import_multiprocess()

Check warning on line 332 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L332

Added line #L332 was not covered by tests

with _create_multiprocess_manager(multiprocess, managers) as manager:
mutex = manager.Lock()
simulation_error_event = manager.Event()
sim_monitor = manager._SimMonitor(

Check warning on line 337 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L334-L337

Added lines #L334 - L337 were not covered by tests
initial_count=self._initial_sim_idx,
n_simulations=self.number_of_simulations,
start_time=time(),
)

processes = []
seeds = np.random.SeedSequence().spawn(n_workers)

Check warning on line 344 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L343-L344

Added lines #L343 - L344 were not covered by tests

for seed in seeds:
sim_producer = multiprocess.Process(

Check warning on line 347 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L346-L347

Added lines #L346 - L347 were not covered by tests
target=self.__sim_producer,
args=(
seed,
Expand All @@ -384,33 +353,33 @@
simulation_error_event,
),
)
processes.append(sim_producer)
sim_producer.start()

Check warning on line 357 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L356-L357

Added lines #L356 - L357 were not covered by tests

try:
for sim_producer in processes:
sim_producer.join()

Check warning on line 361 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L359-L361

Added lines #L359 - L361 were not covered by tests

# Handle error from the child processes
if simulation_error_event.is_set():
raise RuntimeError(

Check warning on line 365 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L364-L365

Added lines #L364 - L365 were not covered by tests
"An error occurred during the simulation. \n"
f"Check the logs and error file {self.error_file} "
"for more information."
)

sim_monitor.print_final_status()

Check warning on line 371 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L371

Added line #L371 was not covered by tests

# Handle error from the main process
# pylint: disable=broad-except
except (Exception, KeyboardInterrupt) as error:
simulation_error_event.set()

Check warning on line 376 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L375-L376

Added lines #L375 - L376 were not covered by tests

for sim_producer in processes:
sim_producer.join()

Check warning on line 379 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L378-L379

Added lines #L378 - L379 were not covered by tests

if not isinstance(error, KeyboardInterrupt):
raise error

Check warning on line 382 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L381-L382

Added lines #L381 - L382 were not covered by tests

def __sim_producer(self, seed, sim_monitor, mutex, error_event):
"""Simulation producer to be used in parallel by multiprocessing.
Expand All @@ -426,49 +395,49 @@
error_event : multiprocess.Event
Event signaling an error occurred during the simulation.
"""
try:

Check warning on line 398 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L398

Added line #L398 was not covered by tests
# Ensure Processes generate different random numbers
self.environment._set_stochastic(seed)
self.rocket._set_stochastic(seed)
self.flight._set_stochastic(seed)

Check warning on line 402 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L400-L402

Added lines #L400 - L402 were not covered by tests

while sim_monitor.keep_simulating():
sim_idx = sim_monitor.increment() - 1

Check warning on line 405 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L404-L405

Added lines #L404 - L405 were not covered by tests

flight = self.__run_single_simulation()
inputs_json = self.__evaluate_flight_inputs(sim_idx)
outputs_json = self.__evaluate_flight_outputs(flight, sim_idx)

Check warning on line 409 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L407-L409

Added lines #L407 - L409 were not covered by tests

try:
mutex.acquire()
if error_event.is_set():
sim_monitor.reprint(

Check warning on line 414 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L411-L414

Added lines #L411 - L414 were not covered by tests
"Simulation Interrupt, files from simulation "
f"{sim_idx} saved."
)
with open(self.error_file, "a", encoding="utf-8") as f:
f.write(inputs_json)

Check warning on line 419 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L418-L419

Added lines #L418 - L419 were not covered by tests

break

Check warning on line 421 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L421

Added line #L421 was not covered by tests

with open(self.input_file, "a", encoding="utf-8") as f:
f.write(inputs_json)
with open(self.output_file, "a", encoding="utf-8") as f:
f.write(outputs_json)

Check warning on line 426 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L423-L426

Added lines #L423 - L426 were not covered by tests

sim_monitor.print_update_status(sim_idx)

Check warning on line 428 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L428

Added line #L428 was not covered by tests
finally:
mutex.release()

Check warning on line 430 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L430

Added line #L430 was not covered by tests

except Exception: # pylint: disable=broad-except
mutex.acquire()
with open(self.error_file, "a", encoding="utf-8") as f:
f.write(inputs_json)

Check warning on line 435 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L432-L435

Added lines #L432 - L435 were not covered by tests

sim_monitor.reprint(f"Error on iteration {sim_idx}:")
sim_monitor.reprint(traceback.format_exc())
error_event.set()
mutex.release()

Check warning on line 440 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L437-L440

Added lines #L437 - L440 were not covered by tests

def __run_single_simulation(self):
"""Runs a single simulation and returns the inputs and outputs.
Expand All @@ -478,7 +447,7 @@
Flight
The flight object of the simulation.
"""
return Flight(

Check warning on line 450 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L450

Added line #L450 was not covered by tests
rocket=self.rocket.create_object(),
environment=self.environment.create_object(),
rail_length=self.flight._randomize_rail_length(),
Expand All @@ -501,7 +470,7 @@
str
A JSON compatible dictionary with the inputs of the simulation.
"""
inputs_dict = dict(

Check warning on line 473 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L473

Added line #L473 was not covered by tests
item
for d in [
self.environment.last_rnd_dict,
Expand All @@ -510,8 +479,8 @@
]
for item in d.items()
)
inputs_dict["index"] = sim_idx
return json.dumps(inputs_dict, cls=RocketPyEncoder) + "\n"

Check warning on line 483 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L482-L483

Added lines #L482 - L483 were not covered by tests

def __evaluate_flight_outputs(self, flight, sim_idx):
"""Evaluates the outputs of a single flight simulation.
Expand All @@ -528,11 +497,11 @@
str
A JSON compatible dictionary with the outputs of the simulation.
"""
outputs_dict = {

Check warning on line 500 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L500

Added line #L500 was not covered by tests
export_item: getattr(flight, export_item)
for export_item in self.export_list
}
outputs_dict["index"] = sim_idx

Check warning on line 504 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L504

Added line #L504 was not covered by tests

if self.data_collector is not None:
additional_exports = {}
Expand All @@ -543,9 +512,9 @@
raise ValueError(
f"An error was encountered running 'data_collector' callback {key}. "
) from e
outputs_dict = outputs_dict | additional_exports

Check warning on line 515 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L515

Added line #L515 was not covered by tests

return json.dumps(outputs_dict, cls=RocketPyEncoder) + "\n"

Check warning on line 517 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L517

Added line #L517 was not covered by tests

def __terminate_simulation(self):
"""
Expand All @@ -556,18 +525,11 @@
None
"""
# resave the files on self and calculate post simulation attributes
self.input_file = self._input_file
self.output_file = self._output_file
self.error_file = self._error_file

Check warning on line 530 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L528-L530

Added lines #L528 - L530 were not covered by tests

_SimMonitor.reprint(f"Results saved to {self._output_file}")

Check warning on line 532 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L532

Added line #L532 was not covered by tests
self.input_file.write(
json.dumps(self.inputs_dict, cls=RocketPyEncoder, **self._export_config)
+ "\n"
)
self.output_file.write(
json.dumps(self.results, cls=RocketPyEncoder, **self._export_config) + "\n"
)

def __check_export_list(self, export_list):
"""
Expand Down Expand Up @@ -1149,10 +1111,10 @@
tuple
Tuple containing the imported modules.
"""
multiprocess = import_optional_dependency("multiprocess")
managers = import_optional_dependency("multiprocess.managers")

Check warning on line 1115 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1114-L1115

Added lines #L1114 - L1115 were not covered by tests

return multiprocess, managers

Check warning on line 1117 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1117

Added line #L1117 was not covered by tests


def _create_multiprocess_manager(multiprocess, managers):
Expand All @@ -1172,17 +1134,17 @@
Subclass of BaseManager with the necessary classes registered.
"""

class MonteCarloManager(managers.BaseManager):

Check warning on line 1137 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1137

Added line #L1137 was not covered by tests
"""Custom manager for shared objects in the Monte Carlo simulation."""

def __init__(self):
super().__init__()
self.register('Lock', multiprocess.Lock)
self.register('Queue', multiprocess.Queue)
self.register('Event', multiprocess.Event)
self.register('_SimMonitor', _SimMonitor)

Check warning on line 1145 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1140-L1145

Added lines #L1140 - L1145 were not covered by tests

return MonteCarloManager()

Check warning on line 1147 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1147

Added line #L1147 was not covered by tests


class _SimMonitor:
Expand All @@ -1191,17 +1153,17 @@
_last_print_len = 0

def __init__(self, initial_count, n_simulations, start_time):
self.initial_count = initial_count
self.count = initial_count
self.n_simulations = n_simulations
self.start_time = start_time

Check warning on line 1159 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1156-L1159

Added lines #L1156 - L1159 were not covered by tests

def keep_simulating(self):
return self.count < self.n_simulations

Check warning on line 1162 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1162

Added line #L1162 was not covered by tests

def increment(self):
self.count += 1
return self.count

Check warning on line 1166 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1165-L1166

Added lines #L1165 - L1166 were not covered by tests

def print_update_status(self, sim_idx):
"""Prints a message on the same line as the previous one and replaces
Expand All @@ -1217,23 +1179,23 @@
-------
None
"""
average_time = (time() - self.start_time) / (self.count - self.initial_count)
estimated_time = int((self.n_simulations - self.count) * average_time)

Check warning on line 1183 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1182-L1183

Added lines #L1182 - L1183 were not covered by tests

msg = f"Current iteration: {sim_idx:06d}"
msg += f" | Average Time per Iteration: {average_time:.3f} s"
msg += f" | Estimated time left: {estimated_time} s"

Check warning on line 1187 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1185-L1187

Added lines #L1185 - L1187 were not covered by tests

_SimMonitor.reprint(msg, end="\r", flush=True)

Check warning on line 1189 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1189

Added line #L1189 was not covered by tests

def print_final_status(self):
"""Prints the final status of the simulation."""
print()
msg = f"Completed {self.count - self.initial_count} iterations."
msg += f" In total, {self.count} simulations are exported.\n"
msg += f"Total wall time: {time() - self.start_time:.1f} s"

Check warning on line 1196 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1193-L1196

Added lines #L1193 - L1196 were not covered by tests

_SimMonitor.reprint(msg, end="\n", flush=True)

Check warning on line 1198 in rocketpy/simulation/monte_carlo.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/simulation/monte_carlo.py#L1198

Added line #L1198 was not covered by tests

@staticmethod
def reprint(msg, end="\n", flush=True):
Expand Down
Loading
0