Coverage for pySDC/core/default_hook.py: 100%
15 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-02 12:30 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-02 12:30 +0000
1import time
2from pySDC.core.hooks import Hooks
5class DefaultHooks(Hooks):
6 """
7 Hook added to every controller, recording the residuals and the number of iterations of each step.
9 The residual is the one the convergence check reads, computed once per iteration after the new initial value has
10 come in. The residual after each sweep is not computed by default; add
11 :class:`~pySDC.implementations.hooks.log_residual.LogResidualPostSweep` to get it.
12 """
14 def post_iteration(self, step, level_number):
15 """
16 Default routine called after each iteration
18 Args:
19 step (pySDC.Step.step): the current step
20 level_number (int): the current level number
21 """
22 super().post_iteration(step, level_number)
24 L = step.levels[level_number]
26 self.logger.info(
27 'Process %2i on time %8.6f -- Iteration: %2i -- residual: %12.8e',
28 step.status.slot,
29 L.time,
30 step.status.iter,
31 L.status.residual,
32 )
34 self.add_to_stats(
35 process=step.status.slot,
36 process_sweeper=L.sweep.rank,
37 time=L.time,
38 level=-1,
39 iter=step.status.iter,
40 sweep=L.status.sweep,
41 type='residual_post_iteration',
42 value=L.status.residual,
43 )
45 def post_step(self, step, level_number):
46 """
47 Default routine called after each step or block
49 Args:
50 step (pySDC.Step.step): the current step
51 level_number (int): the current level number
52 """
53 super().post_step(step, level_number)
55 L = step.levels[level_number]
57 self.add_to_stats(
58 process=step.status.slot,
59 process_sweeper=L.sweep.rank,
60 time=L.time,
61 level=-1,
62 iter=step.status.iter,
63 sweep=L.status.sweep,
64 type='niter',
65 value=step.status.iter,
66 )
67 self.add_to_stats(
68 process=step.status.slot,
69 process_sweeper=L.sweep.rank,
70 time=L.time,
71 level=L.level_index,
72 iter=-1,
73 sweep=L.status.sweep,
74 type='residual_post_step',
75 value=L.status.residual,
76 )
78 # record the recomputed quantities at weird positions to make sure there is only one value for each step
79 for t in [L.time, L.time + L.dt]:
80 self.add_to_stats(
81 process=-1,
82 time=t,
83 level=-1,
84 iter=-1,
85 sweep=-1,
86 type='_recomputed',
87 value=step.status.get('restart'),
88 process_sweeper=-1,
89 )