Coverage for pySDC/implementations/convergence_controller_classes/estimate_contraction_factor.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-04-29 09:02 +0000

1import numpy as np 

2 

3from pySDC.core.ConvergenceController import ConvergenceController 

4from pySDC.implementations.convergence_controller_classes.estimate_embedded_error import EstimateEmbeddedError 

5 

6 

7class EstimateContractionFactor(ConvergenceController): 

8 """ 

9 Estimate the contraction factor by using the evolution of the embedded error estimate across iterations. 

10 """ 

11 

12 def setup(self, controller, params, description, **kwargs): 

13 """ 

14 Add a default value for control order to the parameters. 

15 

16 Args: 

17 controller (pySDC.Controller): The controller 

18 params (dict): Parameters for the convergence controller 

19 description (dict): The description object used to instantiate the controller 

20 

21 Returns: 

22 dict: Updated parameters 

23 """ 

24 return {"control_order": -75, "e_tol": None, **super().setup(controller, params, description, **kwargs)} 

25 

26 def dependencies(self, controller, description, **kwargs): 

27 """ 

28 Load estimator of embedded error. 

29 

30 Args: 

31 controller (pySDC.Controller): The controller 

32 description (dict): The description object used to instantiate the controller 

33 

34 Returns: 

35 None 

36 """ 

37 controller.add_convergence_controller( 

38 EstimateEmbeddedError, 

39 description=description, 

40 ) 

41 

42 def setup_status_variables(self, controller, **kwargs): 

43 """ 

44 Add the embedded error, contraction factor and iterations to convergence variable to the status of the levels. 

45 

46 Args: 

47 controller (pySDC.Controller): The controller 

48 

49 Returns: 

50 None 

51 """ 

52 if 'comm' in kwargs.keys(): 

53 steps = [controller.S] 

54 else: 

55 if 'active_slots' in kwargs.keys(): 

56 steps = [controller.MS[i] for i in kwargs['active_slots']] 

57 else: 

58 steps = controller.MS 

59 where = ["levels", "status"] 

60 for S in steps: 

61 self.add_variable(S, name='error_embedded_estimate_last_iter', where=where, init=None) 

62 self.add_variable(S, name='contraction_factor', where=where, init=None) 

63 if self.params.e_tol is not None: 

64 self.add_variable(S, name='iter_to_convergence', where=where, init=None) 

65 

66 def reset_status_variables(self, controller, **kwargs): 

67 """ 

68 Reinitialize new status variables for the levels. 

69 

70 Args: 

71 controller (pySDC.controller): The controller 

72 

73 Returns: 

74 None 

75 """ 

76 self.setup_status_variables(controller, **kwargs) 

77 

78 def post_iteration_processing(self, controller, S, **kwargs): 

79 """ 

80 Estimate contraction factor here as the ratio of error estimates between iterations and estimate how many more 

81 iterations we need. 

82 

83 Args: 

84 controller (pySDC.controller): The controller 

85 S (pySDC.step): The current step 

86 

87 Returns: 

88 None 

89 """ 

90 for L in S.levels: 

91 if L.status.error_embedded_estimate_last_iter is not None: 

92 L.status.contraction_factor = ( 

93 L.status.error_embedded_estimate / L.status.error_embedded_estimate_last_iter 

94 ) 

95 if self.params.e_tol is not None: 

96 L.status.iter_to_convergence = max( 

97 [ 

98 0, 

99 np.ceil( 

100 np.log(self.params.e_tol / L.status.error_embedded_estimate) 

101 / np.log(L.status.contraction_factor) 

102 ), 

103 ] 

104 ) 

105 

106 def pre_iteration_processing(self, controller, S, **kwargs): 

107 """ 

108 Store the embedded error estimate of the current iteration in a different place so it doesn't get overwritten. 

109 

110 Args: 

111 controller (pySDC.controller): The controller 

112 S (pySDC.Step): The current step 

113 

114 Returns: 

115 None 

116 """ 

117 for L in S.levels: 

118 if L.status.error_embedded_estimate is not None: 

119 L.status.error_embedded_estimate_last_iter = L.status.error_embedded_estimate * 1.0