Source code for fridom.framework.modules.module_container
import fridom.framework as fr
[docs]
class ModuleContainer(fr.modules.Module):
"""
A module container that can hold multiple modules.
Description
-----------
A module container holds a list of modules and is a module itself. It can
start, stop, and update all the modules it contains.
Parameters
----------
`name` : `str`
Name of the module container.
`module_list` : `list`
A list of modules to be added to the container.
"""
[docs]
def __init__(self,
name: str = "Module Container",
module_list: list | None = None):
super().__init__()
self.name = name
self.module_list = module_list or []
[docs]
@fr.modules.module_method
def setup(self, mset: 'fr.ModelSettingsBase') -> None:
"""
Setup all modules.
"""
super().setup(mset)
for module in self.module_list:
module.setup(mset=mset)
return
[docs]
@fr.modules.module_method
def start(self) -> None:
"""
Start all modules.
"""
for module in self.module_list:
module.start()
return
[docs]
@fr.modules.module_method
def stop(self) -> None:
"""
Stop all modules.
"""
for module in self.module_list:
module.stop()
return
[docs]
def reset(self) -> None:
"""
Reset all modules.
"""
for module in self.module_list:
module.reset()
return
[docs]
@fr.modules.module_method
def update(self, mz: 'fr.ModelState') -> 'fr.ModelState':
"""
Update all modules.
"""
for module in self.module_list:
mz = module.update(mz=mz)
return mz
[docs]
def add_module(self, module) -> None:
"""
Add a module to the end of the module list.
Parameters
----------
`module` : `Module`
The module to be added to the list.
"""
self.module_list.append(module)
return
[docs]
def get(self, name) -> list:
"""
Get a module by name.
Parameters
----------
`name` : `str`
Name of the module.
Returns
-------
`list[Module]`
List of modules with the given name. If no module is found, an
empty list is returned. If multiple modules are found, all of them
are returned.
"""
matches = []
for module in self.module_list:
if module.name == name:
matches.append(module)
return matches
@property
def required_halo(self) -> int:
"""
The maximum required halo points of all modules.
"""
if self._required_halo is not None:
return self._required_halo
# check if module_list is empty
if not self.module_list:
return 0
return max([module.required_halo for module in self.module_list])
@property
def mpi_available(self) -> bool:
"""
Whether all modules are available in MPI mode.
"""
return all([module.mpi_available for module in self.module_list])
@mpi_available.setter
def mpi_available(self, value: bool) -> None:
pass # do nothing
def __repr__(self) -> str:
"""
String representation of the module.
"""
# format the title into a 48 character string of format
# "==================== TITLE ===================="
# title = self.name.upper()
# title = title.center(len(title)+2).center(48, "=")
res = f"{self.name}"
for module in self.module_list:
res += f"\n## {module}"
return res