Coverage for pySDC/implementations/convergence_controller_classes/inexactness.py: 92%
24 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
1from pySDC.core.convergence_controller import ConvergenceController
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 """
10 def setup(self, controller, params, description, **kwargs):
11 """
12 Define default parameters here.
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
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
36 def dependencies(self, controller, description, **kwargs):
37 """
38 Load the embedded error estimator if needed.
40 Args:
41 controller (pySDC.Controller): The controller
42 description (dict): The description object used to instantiate the controller
44 Returns:
45 None
46 """
47 super().dependencies(controller, description)
49 if self.params.use_e_tol:
50 from pySDC.implementations.convergence_controller_classes.estimate_embedded_error import (
51 EstimateEmbeddedError,
52 )
54 controller.add_convergence_controller(
55 EstimateEmbeddedError,
56 description=description,
57 )
59 return None
61 def post_iteration_processing(self, controller, step, **kwargs):
62 """
63 Change the Newton tolerance after every iteration.
65 Args:
66 controller (pySDC.Controller.controller): The controller
67 S (pySDC.Step): The current step
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)
83 def set_tolerance(self, lvl, tol):
84 lvl.prob.newton_tol = tol
86 def set_maxiter(self, description, maxiter):
87 description['problem_params']['newton_maxiter'] = maxiter