diff --git a/README.md b/README.md index 56d5ad73..2ddc2e71 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,4 @@ The main documentation is rendered on the [preCICE website](https://precice.org/ Please report any [issues](https://github.com/precice/micro-manager/issues) and give us feedback through [one of our community channels](https://precice.org/community-channels.html). -The concept and initial design of the Micro Manager has been discussed in - -Desai, Ishaan, & Bringedal, Carina & Uekermann, Benjamin. A flexible software approach to simulate two-scale coupled problems. ECCOMAS Congress 2022. [10.23967/eccomas.2022.037](https://doi.org/10.23967/eccomas.2022.037). +The concept and initial design of the Micro Manager has been discussed in *Desai, Ishaan, & Bringedal, Carina & Uekermann, Benjamin. A flexible software approach to simulate two-scale coupled problems. ECCOMAS Congress 2022. [10.23967/eccomas.2022.037](https://doi.org/10.23967/eccomas.2022.037)*. diff --git a/micro_manager/config.py b/micro_manager/config.py index 6dcf9a1f..07b73f71 100644 --- a/micro_manager/config.py +++ b/micro_manager/config.py @@ -12,7 +12,7 @@ class Config: the config class in https://github.com/precice/fenics-adapter/tree/develop/fenicsadapter """ - def __init__(self, config_filename): + def __init__(self, logger, config_filename): """ Constructor of the Config class. @@ -21,6 +21,8 @@ def __init__(self, config_filename): config_filename : string Name of the JSON configuration file """ + self._logger = logger + self._micro_file_name = None self._config_file_name = None @@ -77,7 +79,7 @@ def read_json(self, config_filename): else: raise Exception("Write data dictionary as a value other than 'scalar' or 'vector'") except BaseException: - print("No write data names provided. Micro manager will only read data from preCICE.") + self._logger.info("No write data names provided. Micro manager will only read data from preCICE.") try: self._read_data_names = data["coupling_params"]["read_data_names"] @@ -90,14 +92,14 @@ def read_json(self, config_filename): else: raise Exception("Read data dictionary as a value other than 'scalar' or 'vector'") except BaseException: - print("No read data names provided. Micro manager will only write data to preCICE.") + self._logger.info("No read data names provided. Micro manager will only write data to preCICE.") self._macro_domain_bounds = data["simulation_params"]["macro_domain_bounds"] try: self._ranks_per_axis = data["simulation_params"]["decomposition"] except BaseException: - print("Domain decomposition is not specified, so the Micro Manager will expect to be run in serial.") + self._logger.info("Domain decomposition is not specified, so the Micro Manager will expect to be run in serial.") try: if data["simulation_params"]["adaptivity"]: @@ -105,7 +107,7 @@ def read_json(self, config_filename): else: self._adaptivity = False except BaseException: - print("Micro Manager will not adaptively run micro simulations, but instead will run all micro simulations in all time steps.") + self._logger.info("Micro Manager will not adaptively run micro simulations, but instead will run all micro simulations in all time steps.") if self._adaptivity: if data["simulation_params"]["adaptivity"]["type"] == "local": @@ -126,7 +128,7 @@ def read_json(self, config_filename): if "similarity_measure" in data["simulation_params"]["adaptivity"]: self._adaptivity_similarity_measure = data["simulation_params"]["adaptivity"]["similarity_measure"] else: - print("No similarity measure provided, using L1 norm as default") + self._logger.info("No similarity measure provided, using L1 norm as default") self._adaptivity_similarity_measure = "L1" adaptivity_every_implicit_iteration = data["simulation_params"]["adaptivity"]["every_implicit_iteration"] @@ -137,7 +139,7 @@ def read_json(self, config_filename): self._adaptivity_every_implicit_iteration = False if not self._adaptivity_every_implicit_iteration: - print("Micro Manager will compute adaptivity once at the start of every time window") + self._logger.info("Micro Manager will compute adaptivity once at the start of every time window") self._write_data_names["active_state"] = False self._write_data_names["active_steps"] = False @@ -153,12 +155,12 @@ def read_json(self, config_filename): else: raise Exception("Diagnostics data dictionary as a value other than 'scalar' or 'vector'") except BaseException: - print("No diagnostics data is defined. Micro Manager will not output any diagnostics data.") + self._logger.info("No diagnostics data is defined. Micro Manager will not output any diagnostics data.") try: self._micro_output_n = data["diagnostics"]["micro_output_n"] except BaseException: - print("Output interval of micro simulations not specified, if output is available then it will be called " + self._logger.info("Output interval of micro simulations not specified, if output is available then it will be called " "in every time window.") try: @@ -166,7 +168,7 @@ def read_json(self, config_filename): self._output_micro_sim_time = True self._write_data_names["micro_sim_time"] = False except BaseException: - print("Micro manager will not output time required to solve each micro simulation in each time step.") + self._logger.info("Micro manager will not output time required to solve each micro simulation in each time step.") def get_config_file_name(self): """ diff --git a/micro_manager/micro_manager.py b/micro_manager/micro_manager.py index e4eb9cd9..1858ff48 100644 --- a/micro_manager/micro_manager.py +++ b/micro_manager/micro_manager.py @@ -62,7 +62,7 @@ def __init__(self, config_file: str) -> None: self._micro_sims_have_output = False self._logger.info("Provided configuration file: {}".format(config_file)) - self._config = Config(config_file) + self._config = Config(self._logger, config_file) # Define the preCICE interface self._interface = precice.Interface( diff --git a/tests/unit/test_adaptivity_serial.py b/tests/unit/test_adaptivity_serial.py index 7334b203..c9dcc411 100644 --- a/tests/unit/test_adaptivity_serial.py +++ b/tests/unit/test_adaptivity_serial.py @@ -2,11 +2,9 @@ from unittest.mock import MagicMock from micro_manager.adaptivity.adaptivity import AdaptivityCalculator from micro_manager.adaptivity.local_adaptivity import LocalAdaptivityCalculator -from micro_manager.adaptivity.global_adaptivity import GlobalAdaptivityCalculator from micro_manager.config import Config import numpy as np from math import exp -from mpi4py import MPI class TestLocalAdaptivity(TestCase): diff --git a/tests/unit/test_domain_decomposition.py b/tests/unit/test_domain_decomposition.py index 9a813e5c..a07d996d 100644 --- a/tests/unit/test_domain_decomposition.py +++ b/tests/unit/test_domain_decomposition.py @@ -7,7 +7,7 @@ class TestDomainDecomposition(TestCase): def setUp(self) -> None: self._logger = MagicMock() - self._macro_bounds_3d = [-1, 1, -2, 2, -2, 8] + self._macro_bounds_3d = [-1, 1, -2, 2, -2, 8] # Cuboid which is not symmetric around origin def test_rank5_outof_10_3d(self): """ diff --git a/tests/unit/test_micro_manager.py b/tests/unit/test_micro_manager.py index 0199b92b..385119f4 100644 --- a/tests/unit/test_micro_manager.py +++ b/tests/unit/test_micro_manager.py @@ -1,5 +1,6 @@ import numpy as np from unittest import TestCase +from unittest.mock import MagicMock import micro_manager @@ -35,6 +36,9 @@ def setUp(self): self.macro_bounds = [0.0, 25.0, 0.0, 25.0, 0.0, 25.0] def test_micromanager_constructor(self): + """ + Test if the constructor of the MicroManager class passes correct values to member variables. + """ manager = micro_manager.MicroManager('micro-manager-config.json') self.assertListEqual(manager._macro_bounds, self.macro_bounds) @@ -43,6 +47,9 @@ def test_micromanager_constructor(self): self.assertEqual(manager._micro_n_out, 10) def test_initialize(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() @@ -57,6 +64,9 @@ def test_initialize(self): self.assertDictEqual(self.fake_write_data_names, manager._write_data_names) def test_read_write_data_from_precice(self): + """ + Test if the internal functions _read_data_from_precice and _write_data_to_precice work as expected. + """ manager = micro_manager.MicroManager('micro-manager-config.json') manager._write_data_to_precice(self.fake_write_data) @@ -68,6 +78,9 @@ def test_read_write_data_from_precice(self): fake_data["macro-vector-data"].tolist()) def test_solve_mico_sims(self): + """ + Test if the internal function _solve_micro_simulations works as expected. + """ manager = micro_manager.MicroManager('micro-manager-config.json') manager._local_number_of_sims = 4 manager._micro_sims = [MicroSimulation() for _ in range(4)] @@ -81,7 +94,10 @@ def test_solve_mico_sims(self): (fake_data["micro-vector-data"] + 1).tolist()) def test_config(self): - config = micro_manager.Config('micro-manager-config.json') + """ + Test if the functions in the Config class work. + """ + config = micro_manager.Config(MagicMock(), 'micro-manager-config.json') self.assertEqual(config._config_file_name.split("/")[-1], "dummy-config.xml") self.assertEqual(config._micro_file_name, "test_micro_manager")