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

1import time 

2from pySDC.core.hooks import Hooks 

3 

4 

5class DefaultHooks(Hooks): 

6 """ 

7 Hook added to every controller, recording the residuals and the number of iterations of each step. 

8 

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 """ 

13 

14 def post_iteration(self, step, level_number): 

15 """ 

16 Default routine called after each iteration 

17 

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) 

23 

24 L = step.levels[level_number] 

25 

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 ) 

33 

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 ) 

44 

45 def post_step(self, step, level_number): 

46 """ 

47 Default routine called after each step or block 

48 

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) 

54 

55 L = step.levels[level_number] 

56 

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 ) 

77 

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 )