From cc5d31eda800708747e29df976e9dac395fbb531 Mon Sep 17 00:00:00 2001 From: Ishaan Desai Date: Wed, 31 Jan 2024 12:45:49 +0100 Subject: [PATCH 1/2] Make initialize() a private method --- examples/python-dummy/run_micro_manager.py | 2 - micro_manager/micro_manager.py | 238 +++++++++--------- .../test_unit_cube/run_micro_manager.py | 2 - 3 files changed, 119 insertions(+), 123 deletions(-) diff --git a/examples/python-dummy/run_micro_manager.py b/examples/python-dummy/run_micro_manager.py index a3d0dd6c..3cffab3a 100644 --- a/examples/python-dummy/run_micro_manager.py +++ b/examples/python-dummy/run_micro_manager.py @@ -11,6 +11,4 @@ manager = MicroManager(args.config) -manager.initialize() - manager.solve() diff --git a/micro_manager/micro_manager.py b/micro_manager/micro_manager.py index 3b9ec38e..b2e6c0b6 100644 --- a/micro_manager/micro_manager.py +++ b/micro_manager/micro_manager.py @@ -119,11 +119,129 @@ def __init__(self, config_file: str) -> None: self._adaptivity_in_every_implicit_step = self._config.is_adaptivity_required_in_every_implicit_iteration() self._micro_sims_active_steps = None + self._initialize() + # ************** # Public methods # ************** - def initialize(self) -> None: + def solve(self) -> None: + """ + Solve the problem using preCICE. + - Handle checkpointing is implicit coupling is done. + - Read data from preCICE, solve micro simulations, and write data to preCICE + - If adaptivity is on, compute micro simulations adaptively. + """ + t, n = 0, 0 + t_checkpoint, n_checkpoint = 0, 0 + + if self._is_adaptivity_on: + similarity_dists = np.zeros( + (self._number_of_sims_for_adaptivity, + self._number_of_sims_for_adaptivity)) + + # Start adaptivity calculation with all sims inactive + is_sim_active = np.array([False] * self._number_of_sims_for_adaptivity) + + # Activate the first one (a random choice) + is_sim_active[0] = True + + # Associate all sims to the one active sim + sim_is_associated_to = np.zeros((self._number_of_sims_for_adaptivity), dtype=np.intc) + sim_is_associated_to[0] = -2 # An active sim does not have an associated sim + + similarity_dists_cp = None + is_sim_active_cp = None + sim_is_associated_to_cp = None + sim_states_cp = [None] * self._local_number_of_sims + + while self._participant.is_coupling_ongoing(): + # Write a checkpoint + if self._participant.requires_writing_checkpoint(): + for i in range(self._local_number_of_sims): + sim_states_cp[i] = self._micro_sims[i].get_state() + t_checkpoint = t + n_checkpoint = n + + if self._is_adaptivity_on: + if not self._adaptivity_in_every_implicit_step: + similarity_dists, is_sim_active, sim_is_associated_to = self._adaptivity_controller.compute_adaptivity( + self._dt, self._micro_sims, similarity_dists, is_sim_active, sim_is_associated_to, self._data_for_adaptivity) + + # Only checkpoint the adaptivity configuration if adaptivity is computed + # once in every time window + similarity_dists_cp = np.copy(similarity_dists) + is_sim_active_cp = np.copy(is_sim_active) + sim_is_associated_to_cp = np.copy(sim_is_associated_to) + + if self._adaptivity_type == "local": + active_sim_ids = np.where(is_sim_active)[0] + elif self._adaptivity_type == "global": + active_sim_ids = np.where( + is_sim_active[self._global_ids_of_local_sims[0]:self._global_ids_of_local_sims[-1] + 1])[0] + + for active_id in active_sim_ids: + self._micro_sims_active_steps[active_id] += 1 + + micro_sims_input = self._read_data_from_precice() + + if self._is_adaptivity_on: + if self._adaptivity_in_every_implicit_step: + similarity_dists, is_sim_active, sim_is_associated_to = self._adaptivity_controller.compute_adaptivity( + self._dt, self._micro_sims, similarity_dists, is_sim_active, sim_is_associated_to, self._data_for_adaptivity) + + if self._adaptivity_type == "local": + active_sim_ids = np.where(is_sim_active)[0] + elif self._adaptivity_type == "global": + active_sim_ids = np.where( + is_sim_active[self._global_ids_of_local_sims[0]:self._global_ids_of_local_sims[-1] + 1])[0] + + for active_id in active_sim_ids: + self._micro_sims_active_steps[active_id] += 1 + + micro_sims_output = self._solve_micro_simulations_with_adaptivity( + micro_sims_input, is_sim_active, sim_is_associated_to) + else: + micro_sims_output = self._solve_micro_simulations(micro_sims_input) + + self._write_data_to_precice(micro_sims_output) + + self._participant.advance(self._dt) + self._dt = self._participant.get_max_time_step_size() + + t += self._dt + n += 1 + + # Revert micro simulations to their last checkpoints if required + if self._participant.requires_reading_checkpoint(): + for i in range(self._local_number_of_sims): + self._micro_sims[i].set_state(sim_states_cp[i]) + n = n_checkpoint + t = t_checkpoint + + # If adaptivity is computed only once per time window, the states of sims need to be reset too + if self._is_adaptivity_on: + if not self._adaptivity_in_every_implicit_step: + similarity_dists = np.copy(similarity_dists_cp) + is_sim_active = np.copy(is_sim_active_cp) + sim_is_associated_to = np.copy(sim_is_associated_to_cp) + + else: # Time window has converged, now micro output can be generated + self._logger.info("Micro simulations {} - {} have converged at t = {}".format( + self._micro_sims[0].get_global_id(), self._micro_sims[-1].get_global_id(), t)) + + if self._micro_sims_have_output: + if n % self._micro_n_out == 0: + for sim in self._micro_sims: + sim.output() + + self._participant.finalize() + + # *************** + # Private methods + # *************** + + def _initialize(self) -> None: """ Initialize the Micro Manager by performing the following tasks: - Decompose the domain if the Micro Manager is executed in parallel. @@ -245,122 +363,6 @@ def initialize(self) -> None: self._dt = self._participant.get_max_time_step_size() - def solve(self) -> None: - """ - Solve the problem using preCICE. - - Handle checkpointing is implicit coupling is done. - - Read data from preCICE, solve micro simulations, and write data to preCICE - - If adaptivity is on, compute micro simulations adaptively. - """ - t, n = 0, 0 - t_checkpoint, n_checkpoint = 0, 0 - - if self._is_adaptivity_on: - similarity_dists = np.zeros( - (self._number_of_sims_for_adaptivity, - self._number_of_sims_for_adaptivity)) - - # Start adaptivity calculation with all sims inactive - is_sim_active = np.array([False] * self._number_of_sims_for_adaptivity) - - # Activate the first one (a random choice) - is_sim_active[0] = True - - # Associate all sims to the one active sim - sim_is_associated_to = np.zeros((self._number_of_sims_for_adaptivity), dtype=np.intc) - sim_is_associated_to[0] = -2 # An active sim does not have an associated sim - - similarity_dists_cp = None - is_sim_active_cp = None - sim_is_associated_to_cp = None - sim_states_cp = [None] * self._local_number_of_sims - - while self._participant.is_coupling_ongoing(): - # Write a checkpoint - if self._participant.requires_writing_checkpoint(): - for i in range(self._local_number_of_sims): - sim_states_cp[i] = self._micro_sims[i].get_state() - t_checkpoint = t - n_checkpoint = n - - if self._is_adaptivity_on: - if not self._adaptivity_in_every_implicit_step: - similarity_dists, is_sim_active, sim_is_associated_to = self._adaptivity_controller.compute_adaptivity( - self._dt, self._micro_sims, similarity_dists, is_sim_active, sim_is_associated_to, self._data_for_adaptivity) - - # Only checkpoint the adaptivity configuration if adaptivity is computed - # once in every time window - similarity_dists_cp = np.copy(similarity_dists) - is_sim_active_cp = np.copy(is_sim_active) - sim_is_associated_to_cp = np.copy(sim_is_associated_to) - - if self._adaptivity_type == "local": - active_sim_ids = np.where(is_sim_active)[0] - elif self._adaptivity_type == "global": - active_sim_ids = np.where( - is_sim_active[self._global_ids_of_local_sims[0]:self._global_ids_of_local_sims[-1] + 1])[0] - - for active_id in active_sim_ids: - self._micro_sims_active_steps[active_id] += 1 - - micro_sims_input = self._read_data_from_precice() - - if self._is_adaptivity_on: - if self._adaptivity_in_every_implicit_step: - similarity_dists, is_sim_active, sim_is_associated_to = self._adaptivity_controller.compute_adaptivity( - self._dt, self._micro_sims, similarity_dists, is_sim_active, sim_is_associated_to, self._data_for_adaptivity) - - if self._adaptivity_type == "local": - active_sim_ids = np.where(is_sim_active)[0] - elif self._adaptivity_type == "global": - active_sim_ids = np.where( - is_sim_active[self._global_ids_of_local_sims[0]:self._global_ids_of_local_sims[-1] + 1])[0] - - for active_id in active_sim_ids: - self._micro_sims_active_steps[active_id] += 1 - - micro_sims_output = self._solve_micro_simulations_with_adaptivity( - micro_sims_input, is_sim_active, sim_is_associated_to) - else: - micro_sims_output = self._solve_micro_simulations(micro_sims_input) - - self._write_data_to_precice(micro_sims_output) - - self._participant.advance(self._dt) - self._dt = self._participant.get_max_time_step_size() - - t += self._dt - n += 1 - - # Revert micro simulations to their last checkpoints if required - if self._participant.requires_reading_checkpoint(): - for i in range(self._local_number_of_sims): - self._micro_sims[i].set_state(sim_states_cp[i]) - n = n_checkpoint - t = t_checkpoint - - # If adaptivity is computed only once per time window, the states of sims need to be reset too - if self._is_adaptivity_on: - if not self._adaptivity_in_every_implicit_step: - similarity_dists = np.copy(similarity_dists_cp) - is_sim_active = np.copy(is_sim_active_cp) - sim_is_associated_to = np.copy(sim_is_associated_to_cp) - - else: # Time window has converged, now micro output can be generated - self._logger.info("Micro simulations {} - {} have converged at t = {}".format( - self._micro_sims[0].get_global_id(), self._micro_sims[-1].get_global_id(), t)) - - if self._micro_sims_have_output: - if n % self._micro_n_out == 0: - for sim in self._micro_sims: - sim.output() - - self._participant.finalize() - - # *************** - # Private methods - # *************** - def _read_data_from_precice(self) -> list: """ Read data from preCICE. @@ -523,8 +525,6 @@ def main(): manager = MicroManager(config_file_path) - manager.initialize() - manager.solve() diff --git a/tests/integration/test_unit_cube/run_micro_manager.py b/tests/integration/test_unit_cube/run_micro_manager.py index a3d0dd6c..3cffab3a 100644 --- a/tests/integration/test_unit_cube/run_micro_manager.py +++ b/tests/integration/test_unit_cube/run_micro_manager.py @@ -11,6 +11,4 @@ manager = MicroManager(args.config) -manager.initialize() - manager.solve() From f8ce800cb500903c0d088dc972de1d026cae0aaf Mon Sep 17 00:00:00 2001 From: Ishaan Desai Date: Wed, 31 Jan 2024 12:53:58 +0100 Subject: [PATCH 2/2] Remove calls to initialize() --- examples/cpp-dummy/run_micro_manager.py | 2 -- tests/unit/test_micro_manager.py | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/cpp-dummy/run_micro_manager.py b/examples/cpp-dummy/run_micro_manager.py index e6afd394..6c7336bd 100644 --- a/examples/cpp-dummy/run_micro_manager.py +++ b/examples/cpp-dummy/run_micro_manager.py @@ -11,6 +11,4 @@ manager = MicroManager(args.config) -manager.initialize() - manager.solve() diff --git a/tests/unit/test_micro_manager.py b/tests/unit/test_micro_manager.py index c020f09d..e0111d4a 100644 --- a/tests/unit/test_micro_manager.py +++ b/tests/unit/test_micro_manager.py @@ -46,14 +46,12 @@ def test_micromanager_constructor(self): self.assertDictEqual(self.fake_write_data_names, manager._write_data_names) self.assertEqual(manager._micro_n_out, 10) - def test_initialize(self): + def test_initialization(self): """ Test if the initialize function of the MicroManager class initializes member variables to correct values """ manager = micro_manager.MicroManager('micro-manager-config.json') - manager.initialize() - self.assertEqual(manager._dt, 0.1) # from Interface.initialize self.assertEqual(manager._global_number_of_sims, 4) self.assertListEqual(manager._macro_bounds, self.macro_bounds)