Coverage for pySDC/projects/Resilience/GS.py: 76%
92 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
1# script to run a Gray-Scott problem
2from pySDC.implementations.problem_classes.GrayScott_MPIFFT import grayscott_imex_diffusion
3from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI
4from pySDC.projects.Resilience.hook import hook_collection, LogData
5from pySDC.projects.Resilience.strategies import merge_descriptions
6from pySDC.projects.Resilience.sweepers import imex_1st_order_efficient
7from pySDC.core.convergence_controller import ConvergenceController
8from pySDC.implementations.convergence_controller_classes.estimate_extrapolation_error import (
9 EstimateExtrapolationErrorNonMPI,
10)
11from pySDC.core.check_convergence import CheckConvergence
12from pySDC.projects.Resilience.reachTendExactly import ReachTendExactly
14from pySDC.core.errors import ConvergenceError
16import numpy as np
19def u_exact(self, t, u_init=None, t_init=None, recompute=False, _t0=None):
20 import pickle
21 import os
23 path = f'data/stats/GS-u_init-{t:.8f}.pickle'
24 if os.path.exists(path) and not recompute and t_init is None:
25 with open(path, 'rb') as file:
26 data = pickle.load(file)
27 else:
28 from pySDC.helpers.stats_helper import get_sorted
29 from pySDC.implementations.convergence_controller_classes.adaptivity import Adaptivity
31 convergence_controllers = {
32 Adaptivity: {'e_tol': 1e-8},
33 }
34 desc = {'convergence_controllers': convergence_controllers}
36 u0 = self._u_exact(0) if u_init is None else u_init
37 t0 = 0 if t_init is None else t_init
39 if t == t0:
40 return u0
41 else:
42 u0 = u0 if _t0 is None else self.u_exact(_t0)
43 _t0 = t0 if _t0 is None else _t0
45 stats, _, _ = run_GS(Tend=t, u0=u0, t0=_t0, custom_description=desc)
47 u = get_sorted(stats, type='u', recomputed=False)[-1]
48 data = u[1]
50 if t0 == 0:
51 with open(path, 'wb') as file:
52 pickle.dump(data, file)
54 return data
57class grayscott_imex_diffusion_reference(grayscott_imex_diffusion):
58 """Gray-Scott whose solution at t > 0 is a reference solution computed with `run_GS` and cached on disk"""
60 _u_exact = grayscott_imex_diffusion.u_exact
61 u_exact = u_exact
64def run_GS(
65 custom_description=None,
66 num_procs=1,
67 Tend=1e2,
68 hook_class=LogData,
69 fault_stuff=None,
70 custom_controller_params=None,
71 u0=None,
72 t0=0,
73 use_MPI=False,
74 **kwargs,
75):
76 """
77 Args:
78 custom_description (dict): Overwrite presets
79 num_procs (int): Number of steps for MSSDC
80 Tend (float): Time to integrate to
81 hook_class (pySDC.Hook): A hook to store data
82 fault_stuff (dict): A dictionary with information on how to add faults
83 custom_controller_params (dict): Overwrite presets
84 u0 (dtype_u): Initial value
85 t0 (float): Starting time
86 use_MPI (bool): Whether or not to use MPI
88 Returns:
89 dict: The stats object
90 controller: The controller
91 bool: If the code crashed
92 """
94 level_params = {}
95 level_params['dt'] = 1e0
96 level_params['restol'] = -1
98 sweeper_params = {}
99 sweeper_params['quad_type'] = 'RADAU-RIGHT'
100 sweeper_params['num_nodes'] = 3
101 sweeper_params['QI'] = 'MIN-SR-S'
102 sweeper_params['QE'] = 'PIC'
103 sweeper_params['initial_guess'] = 'copy'
105 from mpi4py import MPI
107 problem_params = {
108 'comm': MPI.COMM_SELF,
109 'num_blobs': -48,
110 'L': 2,
111 'nvars': (128,) * 2,
112 'A': 0.062,
113 'B': 0.1229,
114 'Du': 2e-5,
115 'Dv': 1e-5,
116 }
118 step_params = {}
119 step_params['maxiter'] = 5
121 convergence_controllers = {}
122 convergence_controllers[ReachTendExactly] = {'Tend': Tend}
124 controller_params = {}
125 controller_params['logger_level'] = 15
126 controller_params['hook_class'] = hook_collection + (hook_class if type(hook_class) == list else [hook_class])
127 controller_params['mssdc_jac'] = False
129 if custom_controller_params is not None:
130 controller_params = {**controller_params, **custom_controller_params}
132 description = {}
133 description['problem_class'] = grayscott_imex_diffusion_reference
134 description['problem_params'] = problem_params
135 description['sweeper_class'] = imex_1st_order_efficient
136 description['sweeper_params'] = sweeper_params
137 description['level_params'] = level_params
138 description['step_params'] = step_params
139 description['convergence_controllers'] = convergence_controllers
141 if custom_description is not None:
142 description = merge_descriptions(description, custom_description)
144 controller_args = {
145 'controller_params': controller_params,
146 'description': description,
147 }
148 if use_MPI:
149 from mpi4py import MPI
150 from pySDC.implementations.controller_classes.controller_MPI import controller_MPI
152 comm = kwargs.get('comm', MPI.COMM_WORLD)
153 controller = controller_MPI(**controller_args, comm=comm)
154 P = controller.S.levels[0].prob
155 else:
156 controller = controller_nonMPI(**controller_args, num_procs=num_procs)
157 P = controller.MS[0].levels[0].prob
159 t0 = 0.0 if t0 is None else t0
160 uinit = P.u_exact(t0) if u0 is None else u0
162 if fault_stuff is not None:
163 from pySDC.projects.Resilience.fault_injection import prepare_controller_for_faults
165 prepare_controller_for_faults(controller, fault_stuff)
167 crash = False
168 try:
169 uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
170 except ConvergenceError as e:
171 print(f'Warning: Premature termination!: {e}')
172 stats = controller.return_stats()
173 crash = True
174 return stats, controller, crash
177if __name__ == '__main__':
178 stats, _, _ = run_GS()