controller#
- class Controller(controller_params: Dict[str, Any], description: Dict[str, Any], useMPI: bool | None = None)[source]#
Bases:
objectAbstract base class of the controllers, which set up hooks and convergence controllers and run the steps in time.
- add_convergence_controller(convergence_controller: Type[Any], description: Dict[str, Any], params: Dict[str, Any] | None = None, allow_double: bool = False) None[source]#
Add an individual convergence controller to the list of convergence controllers and instantiate it. Afterwards, the order of the convergence controllers is updated.
- Parameters:
convergence_controller (
pySDC.ConvergenceController) – The convergence controller to be addeddescription (
dict) – The description object used to instantiate the controllerparams (
dict) – Parameters for the convergence controllerallow_double (
bool) – Allow adding the same convergence controller multiple times
- Returns:
None
- add_hook(hook: Type[Any]) None[source]#
Add a hook to the controller which will be called in addition to all other hooks whenever something happens. The hook is only added if a hook of the same class is not already present.
- Parameters:
hook (
pySDC.Hook) – A hook class that is derived from the core hook class- Returns:
None
- check_variable_coefficients(num_procs: int) None[source]#
Reject k-dependent QDelta coefficients outside plain SDC.
MIN-SR-FLEX and the Jumper variants vary QDelta with the sweep index, and the nilpotency argument behind them is derived for SDC, where that index is the SDC iteration count. Anything needing more iterations (PFASST) or fewer (MLSDC) breaks that identity and would need its own analysis first.
They are also only refreshed by Sweeper.updateVariableCoeffs, which runs on the finest level of the Jacobi sweep alone, so on a coarse level or on the Gauss-Seidel path they silently degrade to a fixed preconditioner. Failing loudly beats either of those.
Note this gates parallelism across steps and the number of levels. Parallelism across collocation nodes (generic_implicit_MPI and friends) is still SDC and stays allowed.
- Parameters:
num_procs (
int) – number of parallel time steps- Raises:
ControllerError – if a k-dependent QDelta is combined with multiple levels or steps
- dump_setup(step: Any, controller_params: Dict[str, Any], description: Dict[str, Any]) None[source]#
Helper function to dump the setup used for this controller
- Parameters:
step (
pySDC.Step.step) – the step instance (will/should be the first one only)controller_params (
dict) – controller parametersdescription (
dict) – description of the problem
- get_convergence_controllers_as_table(description: Dict[str, Any]) str[source]#
This function is for debugging purposes to keep track of the different convergence controllers and their order.
- Parameters:
description (
dict) – Description of the problem- Returns:
str – Table of convergence controllers as a string
- return_stats() Dict[Any, Any][source]#
Return the merged stats from all hooks
- Returns:
dict – Merged stats from all hooks
- run(u0: Any, t0: float, Tend: float) Any[source]#
Abstract interface to the run() method
- Parameters:
u0 – initial values
t0 (
float) – starting timeTend (
float) – ending time
- setup_convergence_controllers(description: Dict[str, Any]) None[source]#
Setup variables needed for convergence controllers, notably a list containing all of them and a list containing their order. Also, we add the CheckConvergence convergence controller, which takes care of maximum iteration count or a residual based stopping criterion, as well as all convergence controllers added to the description.
- Parameters:
description (
dict) – The description object used to instantiate the controller- Returns:
None
- step_is_active(time: float, block_start: float, Tend: float) bool[source]#
Whether a step starting at time, in a block starting at block_start, still has work.
The default is that a step runs if it starts before the end of the interval, so a block may be run partially. An algorithm that couples its steps too tightly to drop one of them answers this from block_start instead and runs the block whole.
- Parameters:
time (
float) – when this step startsblock_start (
float) – when the first step of this step’s block startsTend (
float) – ending time
- Returns:
bool – whether this step takes part
- property steps: List[Any][source]#
Getter for the steps this controller owns.
Controllers that hold the whole block expose them as MS; MPI controllers hold a single step as S. Dispatch on which of those exists rather than on the class name, so that subclasses keep working.
- Returns:
list – the steps owned by this controller