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

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 

13 

14from pySDC.core.errors import ConvergenceError 

15 

16import numpy as np 

17 

18 

19def u_exact(self, t, u_init=None, t_init=None, recompute=False, _t0=None): 

20 import pickle 

21 import os 

22 

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 

30 

31 convergence_controllers = { 

32 Adaptivity: {'e_tol': 1e-8}, 

33 } 

34 desc = {'convergence_controllers': convergence_controllers} 

35 

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 

38 

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 

44 

45 stats, _, _ = run_GS(Tend=t, u0=u0, t0=_t0, custom_description=desc) 

46 

47 u = get_sorted(stats, type='u', recomputed=False)[-1] 

48 data = u[1] 

49 

50 if t0 == 0: 

51 with open(path, 'wb') as file: 

52 pickle.dump(data, file) 

53 

54 return data 

55 

56 

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""" 

59 

60 _u_exact = grayscott_imex_diffusion.u_exact 

61 u_exact = u_exact 

62 

63 

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 

87 

88 Returns: 

89 dict: The stats object 

90 controller: The controller 

91 bool: If the code crashed 

92 """ 

93 

94 level_params = {} 

95 level_params['dt'] = 1e0 

96 level_params['restol'] = -1 

97 

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' 

104 

105 from mpi4py import MPI 

106 

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 } 

117 

118 step_params = {} 

119 step_params['maxiter'] = 5 

120 

121 convergence_controllers = {} 

122 convergence_controllers[ReachTendExactly] = {'Tend': Tend} 

123 

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 

128 

129 if custom_controller_params is not None: 

130 controller_params = {**controller_params, **custom_controller_params} 

131 

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 

140 

141 if custom_description is not None: 

142 description = merge_descriptions(description, custom_description) 

143 

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 

151 

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 

158 

159 t0 = 0.0 if t0 is None else t0 

160 uinit = P.u_exact(t0) if u0 is None else u0 

161 

162 if fault_stuff is not None: 

163 from pySDC.projects.Resilience.fault_injection import prepare_controller_for_faults 

164 

165 prepare_controller_for_faults(controller, fault_stuff) 

166 

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 

175 

176 

177if __name__ == '__main__': 

178 stats, _, _ = run_GS()