# SPDX-License-Identifier: MIT
# Copyright (c) 2011–2026 Joris J.C. Remmers
"""
Base module for PyFEM.
This module provides the BaseModule class, which serves as the base class for
modules in the PyFEM framework. It handles initialization of module properties
and provides utility methods for logging and timing module execution.
The BaseModule automatically detects whether it's a solver module and provides
appropriate logging levels. It also manages nested property hierarchies from
configuration objects.
"""
import time
from typing import Any, Optional
from pyfem.util.logger import getLogger,separator
from pyfem.util.plotUtils import plotTime
logger = getLogger()
[docs]
class BaseModule:
"""
Base class for all PyFEM modules.
This class provides common functionality for modules including:
- Automatic detection of module type (solver vs. non-solver)
- Property management from configuration objects
- Consistent logging with timing information
- Support for hierarchical property organization
Attributes:
isSolver (bool): True if this module is a solver, False otherwise.
type (str): The class name of the module.
myProps: The properties dictionary for this module from the configuration.
Args:
props: A properties object containing configuration. Can have nested
attributes or a currentModule attribute specifying the module name.
"""
def __init__(self, props: Any) -> None:
"""
Initialize the base module with properties from configuration.
Attempts to load module-specific properties from the props object,
supporting both single-level and nested property hierarchies. Also
automatically detects if the module is a solver.
Args:
props (Any): Configuration object containing module properties.
Can have a currentModule attribute specifying the module name,
or will use the class name. Supports nested modules like
"parent.child" in addition to flat module names.
"""
self.isSolver = False
if "Solver" in self.__class__.__name__.lower():
self.isSolver = True
if hasattr(props, 'currentModule') and hasattr(props, props.currentModule):
currentModule = props.currentModule
if 'solver' in currentModule.lower():
self.isSolver = True
elif hasattr(props, 'currentModule'):
currentModule = props.currentModule
if 'solver' in currentModule.lower():
self.isSolver = True
else:
currentModule = self.__class__.__name__
print(currentModule)
if currentModule.endswith("olver") == "olver":
currentModule = "solver"
self.isSolver = True
c = currentModule.split('.')
if len(c) == 1:
if hasattr(props, currentModule):
self.myProps = getattr(props, currentModule)
for name, val in self.myProps:
setattr(self, name, val)
elif len(c) == 2:
if hasattr(props, c[0]):
p2 = getattr(props, c[0])
if hasattr(p2, c[1]):
self.myProps = getattr(p2, c[1])
for name, val in self.myProps:
setattr(self, name, val)
self.type = self.__class__.__name__