Coverage for pySDC/tutorial/step_8/HookClass_error_output.py: 100%
30 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
1from pySDC.core.hooks import Hooks
2from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI
3from pySDC.implementations.problem_classes.Auzinger_implicit import auzinger
6class error_output(Hooks):
7 """
8 Hook class to add output of error
9 """
11 def __init__(self):
12 super(error_output, self).__init__()
13 self.uex = None
15 def pre_step(self, step, level_number):
16 """
17 Default routine called before each step
18 Args:
19 step: the current step
20 level_number: the current level number
21 """
22 super(error_output, self).pre_step(step, level_number)
24 L = step.levels[level_number]
26 # This is a bit black magic: we are going to run pySDC within the hook to check the error against the "exact"
27 # solution of the collocation problem
28 # copies: this hook runs in every step, and the outer run's parameters must stay as they are
29 description = dict(step.params.description)
30 description['level_params'] = {**description['level_params'], 'restol': 1e-14}
31 if type(L.prob) != auzinger:
32 description['problem_params'] = {**description['problem_params'], 'solver_type': 'direct'}
33 # without this, the iteration estimator would stop the "exact" solve as early as the run it is checking
34 description['convergence_controllers'] = {}
36 controller_params = dict(step.params.controller_params)
37 del controller_params['hook_class'] # get rid of the hook, otherwise this will be an endless recursion..
38 controller_params['logger_level'] = 90
40 controller = controller_nonMPI(num_procs=1, description=description, controller_params=controller_params)
41 self.uex, _ = controller.run(u0=L.u[0], t0=L.time, Tend=L.time + L.dt)
43 def post_step(self, step, level_number):
44 """
45 Default routine called after each step
46 Args:
47 step: the current step
48 level_number: the current level number
49 """
51 super(error_output, self).post_step(step, level_number)
53 # some abbreviations
54 L = step.levels[level_number]
55 P = L.prob
57 L.sweep.compute_end_point()
59 # compute and save errors
60 upde = P.u_exact(step.time + step.dt)
61 pde_err = abs(upde - L.uend)
62 coll_err = abs(self.uex - L.uend)
64 self.add_to_stats(
65 process=step.status.slot,
66 time=L.time + L.dt,
67 level=L.level_index,
68 iter=step.status.iter,
69 sweep=L.status.sweep,
70 type='PDE_error_after_step',
71 value=pde_err,
72 )
73 self.add_to_stats(
74 process=step.status.slot,
75 time=L.time + L.dt,
76 level=L.level_index,
77 iter=step.status.iter,
78 sweep=L.status.sweep,
79 type='coll_error_after_step',
80 value=coll_err,
81 )