Coverage for pySDC/implementations/convergence_controller_classes/inexactness.py: 92%

24 statements  

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

1from pySDC.core.ConvergenceController import ConvergenceController 

2 

3 

4class NewtonInexactness(ConvergenceController): 

5 """ 

6 Gradually refine Newton tolerance based on SDC residual. 

7 Be aware that the problem needs a parameter called "newton_tol" which controls the tolerance for the Newton solver for this to work! 

8 """ 

9 

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

11 """ 

12 Define default parameters here. 

13 

14 Args: 

15 controller (pySDC.Controller): The controller 

16 params (dict): The params passed for this specific convergence controller 

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

18 

19 Returns: 

20 (dict): The updated params dictionary 

21 """ 

22 defaults = { 

23 "control_order": 500, 

24 "ratio": 1e-2, 

25 "min_tol": 0, 

26 "max_tol": 1e99, 

27 "maxiter": None, 

28 "use_e_tol": 'e_tol' in description['level_params'].keys(), 

29 "initial_tol": 1e-3, 

30 **super().setup(controller, params, description, **kwargs), 

31 } 

32 if defaults['maxiter']: 

33 self.set_maxiter(description, defaults['maxiter']) 

34 return defaults 

35 

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

37 """ 

38 Load the embedded error estimator if needed. 

39 

40 Args: 

41 controller (pySDC.Controller): The controller 

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

43 

44 Returns: 

45 None 

46 """ 

47 super().dependencies(controller, description) 

48 

49 if self.params.use_e_tol: 

50 from pySDC.implementations.convergence_controller_classes.estimate_embedded_error import ( 

51 EstimateEmbeddedError, 

52 ) 

53 

54 controller.add_convergence_controller( 

55 EstimateEmbeddedError, 

56 description=description, 

57 ) 

58 

59 return None 

60 

61 def post_iteration_processing(self, controller, step, **kwargs): 

62 """ 

63 Change the Newton tolerance after every iteration. 

64 

65 Args: 

66 controller (pySDC.Controller.controller): The controller 

67 S (pySDC.Step): The current step 

68 

69 Returns: 

70 None 

71 """ 

72 for lvl in step.levels: 

73 SDC_accuracy = ( 

74 lvl.status.get('error_embedded_estimate', lvl.status.residual) 

75 if self.params.use_e_tol 

76 else lvl.status.residual 

77 ) 

78 SDC_accuracy = self.params.initial_tol if SDC_accuracy is None else SDC_accuracy 

79 tol = max([min([SDC_accuracy * self.params.ratio, self.params.max_tol]), self.params.min_tol]) 

80 self.set_tolerance(lvl, tol) 

81 self.log(f'Changed tolerance to {tol:.2e}', step) 

82 

83 def set_tolerance(self, lvl, tol): 

84 lvl.prob.newton_tol = tol 

85 

86 def set_maxiter(self, description, maxiter): 

87 description['problem_params']['newton_maxiter'] = maxiter