Coverage for pySDC/projects/GPU/configs/RBC_configs.py: 31%

229 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-25 20:28 +0000

1from pySDC.projects.GPU.configs.base_config import Config 

2 

3 

4def get_config(args): 

5 name = args['config'] 

6 if name == 'RBC': 

7 return RayleighBenardRegular(args) 

8 elif name == 'RBC_dt': 

9 return RayleighBenard_dt_adaptivity(args) 

10 elif name == 'RBC_k': 

11 return RayleighBenard_k_adaptivity(args) 

12 elif name == 'RBC_dt_k': 

13 return RayleighBenard_dt_k_adaptivity(args) 

14 elif name == 'RBC_RK': 

15 return RayleighBenardRK(args) 

16 elif name == 'RBC_dedalus': 

17 return RayleighBenardDedalusComp(args) 

18 elif name == 'RBC_Tibo': 

19 return RayleighBenard_Thibaut(args) 

20 elif name == 'RBC_scaling': 

21 return RayleighBenard_scaling(args) 

22 elif name == 'RBC_large': 

23 return RayleighBenard_large(args) 

24 else: 

25 raise NotImplementedError(f'There is no configuration called {name!r}!') 

26 

27 

28class RayleighBenardRegular(Config): 

29 sweeper_type = 'IMEX' 

30 Tend = 50 

31 

32 def get_controller_params(self, *args, **kwargs): 

33 from pySDC.implementations.hooks.log_step_size import LogStepSize 

34 

35 controller_params = super().get_controller_params(*args, **kwargs) 

36 controller_params['hook_class'] += [LogStepSize] 

37 return controller_params 

38 

39 def get_description(self, *args, MPIsweeper=False, res=-1, **kwargs): 

40 from pySDC.implementations.problem_classes.RayleighBenard import ( 

41 RayleighBenard, 

42 CFLLimit, 

43 ) 

44 from pySDC.implementations.problem_classes.generic_spectral import ( 

45 compute_residual_DAE, 

46 compute_residual_DAE_MPI, 

47 ) 

48 from pySDC.implementations.convergence_controller_classes.step_size_limiter import StepSizeSlopeLimiter 

49 

50 desc = super().get_description(*args, MPIsweeper=MPIsweeper, **kwargs) 

51 

52 # subclass rather than patch: the sweeper class is shared with every other problem in the process 

53 sweeper_class = desc['sweeper_class'] 

54 desc['sweeper_class'] = type( 

55 sweeper_class.__name__, 

56 (sweeper_class,), 

57 {'compute_residual': compute_residual_DAE_MPI if MPIsweeper else compute_residual_DAE}, 

58 ) 

59 

60 desc['level_params']['dt'] = 0.1 

61 desc['level_params']['restol'] = 1e-7 

62 

63 desc['convergence_controllers'][CFLLimit] = {'dt_max': 0.1, 'dt_min': 1e-6, 'cfl': 0.8} 

64 desc['convergence_controllers'][StepSizeSlopeLimiter] = {'dt_rel_min_slope': 0.1} 

65 

66 desc['sweeper_params']['quad_type'] = 'RADAU-RIGHT' 

67 desc['sweeper_params']['num_nodes'] = 2 

68 desc['sweeper_params']['QI'] = 'MIN-SR-S' 

69 desc['sweeper_params']['QE'] = 'PIC' 

70 

71 desc['problem_params']['Rayleigh'] = 2e6 

72 desc['problem_params']['nx'] = 2**8 if res == -1 else res 

73 desc['problem_params']['nz'] = desc['problem_params']['nx'] // 4 

74 desc['problem_params']['dealiasing'] = 3 / 2 

75 

76 desc['step_params']['maxiter'] = 3 

77 

78 desc['problem_class'] = RayleighBenard 

79 

80 return desc 

81 

82 def get_initial_condition(self, P, *args, restart_idx=0, **kwargs): 

83 if restart_idx == 0: 

84 u0 = P.u_exact(t=0, seed=P.comm.rank, noise_level=1e-3) 

85 u0_with_pressure = P.solve_system(u0, 1e-9, u0) 

86 return u0_with_pressure, 0 

87 else: 

88 return super().get_initial_condition(P, *args, restart_idx=restart_idx, **kwargs) 

89 

90 def prepare_caches(self, prob): 

91 """ 

92 Cache the fft objects, which are expensive to create on GPU because graphs have to be initialized. 

93 """ 

94 prob.eval_f(prob.u_init) 

95 

96 def plot(self, P, idx, n_procs_list, quantitiy='T', quantitiy2='vorticity'): 

97 from pySDC.helpers.fieldsIO import FieldsIO 

98 import numpy as np 

99 

100 cmaps = {'vorticity': 'bwr', 'p': 'bwr'} 

101 

102 fig = P.get_fig() 

103 cax = P.cax 

104 axs = fig.get_axes() 

105 

106 outfile = FieldsIO.fromFile(self.get_file_name()) 

107 

108 x = outfile.header['coords'][0] 

109 z = outfile.header['coords'][1] 

110 X, Z = np.meshgrid(x, z, indexing='ij') 

111 

112 t, data = outfile.readField(idx) 

113 im = axs[0].pcolormesh( 

114 X, 

115 Z, 

116 data[P.index(quantitiy)].real, 

117 cmap=cmaps.get(quantitiy, 'plasma'), 

118 ) 

119 

120 im2 = axs[1].pcolormesh( 

121 X, 

122 Z, 

123 data[-1].real, 

124 cmap=cmaps.get(quantitiy2, None), 

125 ) 

126 

127 fig.colorbar(im2, cax[1]) 

128 fig.colorbar(im, cax[0]) 

129 axs[0].set_title(f't={t:.2f}') 

130 axs[1].set_xlabel('x') 

131 axs[1].set_ylabel('z') 

132 axs[0].set_aspect(1.0) 

133 axs[1].set_aspect(1.0) 

134 return fig 

135 

136 

137class RayleighBenard_k_adaptivity(RayleighBenardRegular): 

138 def get_description(self, *args, **kwargs): 

139 from pySDC.implementations.convergence_controller_classes.adaptivity import AdaptivityPolynomialError 

140 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

141 

142 desc = super().get_description(*args, **kwargs) 

143 

144 desc['convergence_controllers'][CFLLimit] = {'dt_max': 0.1, 'dt_min': 1e-6, 'cfl': 0.8} 

145 desc['level_params']['restol'] = 1e-7 

146 desc['sweeper_params']['num_nodes'] = 4 

147 desc['sweeper_params']['QI'] = 'MIN-SR-S' 

148 desc['step_params']['maxiter'] = 12 

149 

150 return desc 

151 

152 def get_controller_params(self, *args, **kwargs): 

153 from pySDC.implementations.problem_classes.RayleighBenard import ( 

154 LogAnalysisVariables, 

155 ) 

156 

157 controller_params = super().get_controller_params(*args, **kwargs) 

158 controller_params['hook_class'] = [ 

159 me for me in controller_params['hook_class'] if me is not LogAnalysisVariables 

160 ] 

161 return controller_params 

162 

163 

164class RayleighBenard_dt_k_adaptivity(RayleighBenardRegular): 

165 def get_description(self, *args, **kwargs): 

166 from pySDC.implementations.convergence_controller_classes.adaptivity import AdaptivityPolynomialError 

167 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

168 

169 desc = super().get_description(*args, **kwargs) 

170 

171 desc['convergence_controllers'][AdaptivityPolynomialError] = { 

172 'e_tol': 1e-3, 

173 'abort_at_growing_residual': False, 

174 'interpolate_between_restarts': False, 

175 'dt_min': 1e-3, 

176 'dt_rel_min_slope': 0.1, 

177 } 

178 desc['convergence_controllers'].pop(CFLLimit) 

179 desc['level_params']['restol'] = 1e-7 

180 desc['sweeper_params']['num_nodes'] = 3 

181 desc['sweeper_params']['QI'] = 'MIN-SR-S' 

182 desc['step_params']['maxiter'] = 16 

183 desc['problem_params']['nx'] *= 2 

184 desc['problem_params']['nz'] *= 2 

185 

186 return desc 

187 

188 def get_controller_params(self, *args, **kwargs): 

189 from pySDC.implementations.problem_classes.RayleighBenard import ( 

190 LogAnalysisVariables, 

191 ) 

192 

193 controller_params = super().get_controller_params(*args, **kwargs) 

194 controller_params['hook_class'] = [ 

195 me for me in controller_params['hook_class'] if me is not LogAnalysisVariables 

196 ] 

197 return controller_params 

198 

199 

200class RayleighBenard_dt_adaptivity(RayleighBenardRegular): 

201 def get_description(self, *args, **kwargs): 

202 from pySDC.implementations.convergence_controller_classes.adaptivity import Adaptivity 

203 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

204 

205 desc = super().get_description(*args, **kwargs) 

206 

207 desc['convergence_controllers'][Adaptivity] = {'e_tol': 1e-4, 'dt_rel_min_slope': 0.1} 

208 desc['convergence_controllers'].pop(CFLLimit) 

209 desc['level_params']['restol'] = -1 

210 desc['sweeper_params']['num_nodes'] = 3 

211 desc['sweeper_params']['skip_residual_computation'] = ('IT_CHECK', 'IT_DOWN', 'IT_UP', 'IT_FINE', 'IT_COARSE') 

212 desc['step_params']['maxiter'] = 5 

213 return desc 

214 

215 

216class RayleighBenard_Thibaut(RayleighBenardRegular): 

217 Tend = 1 

218 

219 def get_description(self, *args, **kwargs): 

220 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

221 

222 desc = super().get_description(*args, **kwargs) 

223 

224 desc['convergence_controllers'].pop(CFLLimit) 

225 desc['level_params']['restol'] = -1 

226 desc['level_params']['dt'] = 2e-2 / 4 

227 desc['sweeper_params']['num_nodes'] = 4 

228 desc['sweeper_params']['QI'] = 'MIN-SR-S' 

229 desc['sweeper_params']['node_type'] = 'LEGENDRE' 

230 desc['sweeper_params']['quad_type'] = 'RADAU-RIGHT' 

231 desc['sweeper_params']['skip_residual_computation'] = ('IT_CHECK', 'IT_DOWN', 'IT_UP', 'IT_FINE', 'IT_COARSE') 

232 desc['step_params']['maxiter'] = 4 

233 return desc 

234 

235 def get_controller_params(self, *args, **kwargs): 

236 controller_params = super().get_controller_params(*args, **kwargs) 

237 controller_params['hook_class'] = [] 

238 return controller_params 

239 

240 

241class RayleighBenardRK(RayleighBenardRegular): 

242 

243 def get_description(self, *args, **kwargs): 

244 from pySDC.implementations.sweeper_classes.Runge_Kutta import ARK3 

245 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

246 from pySDC.implementations.convergence_controller_classes.step_size_limiter import StepSizeSlopeLimiter 

247 

248 desc = super().get_description(*args, **kwargs) 

249 

250 desc['sweeper_class'] = ARK3 

251 

252 desc['step_params']['maxiter'] = 1 

253 

254 desc['convergence_controllers'][CFLLimit] = {'dt_max': 0.1, 'dt_min': 1e-6, 'cfl': 0.5} 

255 desc['convergence_controllers'][StepSizeSlopeLimiter] = {'dt_rel_min_slope': 0.1} 

256 return desc 

257 

258 def get_controller_params(self, *args, **kwargs): 

259 from pySDC.implementations.problem_classes.RayleighBenard import ( 

260 LogAnalysisVariables, 

261 ) 

262 

263 controller_params = super().get_controller_params(*args, **kwargs) 

264 controller_params['hook_class'] = [ 

265 me for me in controller_params['hook_class'] if me is not LogAnalysisVariables 

266 ] 

267 return controller_params 

268 

269 

270class RayleighBenardDedalusComp(RayleighBenardRK): 

271 Tend = 150 

272 

273 def get_description(self, *args, **kwargs): 

274 from pySDC.implementations.sweeper_classes.Runge_Kutta import ARK222 

275 

276 desc = super().get_description(*args, **kwargs) 

277 

278 desc['sweeper_class'] = ARK222 

279 

280 desc['step_params']['maxiter'] = 1 

281 desc['level_params']['dt'] = 5e-3 

282 

283 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

284 

285 desc['convergence_controllers'].pop(CFLLimit) 

286 return desc 

287 

288 

289class RayleighBenard_scaling(RayleighBenardRegular): 

290 Tend = 7 

291 

292 def get_description(self, *args, **kwargs): 

293 from pySDC.implementations.convergence_controller_classes.adaptivity import Adaptivity 

294 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

295 from pySDC.implementations.convergence_controller_classes.step_size_limiter import ( 

296 StepSizeRounding, 

297 StepSizeSlopeLimiter, 

298 ) 

299 

300 desc = super().get_description(*args, **kwargs) 

301 

302 desc['convergence_controllers'][Adaptivity] = {'e_tol': 1e-3, 'dt_rel_min_slope': 1.0, 'beta': 0.5} 

303 desc['convergence_controllers'][StepSizeRounding] = {} 

304 desc['convergence_controllers'][StepSizeSlopeLimiter] = {'dt_rel_min_slope': 1.0} 

305 desc['convergence_controllers'].pop(CFLLimit) 

306 desc['level_params']['restol'] = -1 

307 desc['level_params']['dt'] = 8e-2 

308 desc['sweeper_params']['num_nodes'] = 4 

309 desc['step_params']['maxiter'] = 4 

310 desc['problem_params']['max_cached_factorizations'] = 4 

311 return desc 

312 

313 def get_controller_params(self, *args, **kwargs): 

314 from pySDC.implementations.hooks.log_work import LogWork 

315 

316 params = super().get_controller_params(*args, **kwargs) 

317 params['hook_class'] = [LogWork] 

318 return params 

319 

320 

321class RayleighBenard_large(RayleighBenardRegular): 

322 Ra = 3.2e8 

323 relaxation_steps = 5 

324 

325 def get_description(self, *args, **kwargs): 

326 from pySDC.implementations.convergence_controller_classes.adaptivity import AdaptivityPolynomialError 

327 from pySDC.implementations.problem_classes.RayleighBenard import CFLLimit 

328 from pySDC.implementations.convergence_controller_classes.step_size_limiter import StepSizeRounding 

329 

330 desc = super().get_description(*args, **kwargs) 

331 

332 desc['convergence_controllers'][AdaptivityPolynomialError] = { 

333 'e_tol': 1e-5, 

334 'abort_at_growing_residual': False, 

335 'interpolate_between_restarts': False, 

336 'dt_min': 1e-5, 

337 'dt_rel_min_slope': 2, 

338 'beta': 0.5, 

339 } 

340 desc['convergence_controllers'][StepSizeRounding] = {} 

341 desc['convergence_controllers'].pop(CFLLimit) 

342 desc['level_params']['restol'] = 5e-6 

343 desc['level_params']['e_tol'] = 5e-6 

344 desc['level_params']['dt'] = 5e-3 

345 desc['sweeper_params']['num_nodes'] = 4 

346 desc['sweeper_params']['QI'] = 'MIN-SR-S' 

347 desc['sweeper_params']['QE'] = 'PIC' 

348 desc['step_params']['maxiter'] = 16 

349 

350 desc['problem_params']['Rayleigh'] = self.Ra 

351 desc['problem_params']['max_cached_factorizations'] = 4 

352 

353 return desc 

354 

355 def get_controller_params(self, *args, **kwargs): 

356 from pySDC.implementations.problem_classes.RayleighBenard import ( 

357 LogAnalysisVariables, 

358 ) 

359 

360 controller_params = super().get_controller_params(*args, **kwargs) 

361 controller_params['hook_class'] += [LogAnalysisVariables] 

362 return controller_params 

363 

364 def get_initial_condition(self, P, *args, restart_idx=0, **kwargs): 

365 if restart_idx > 0: 

366 return super().get_initial_condition(P, *args, restart_idx=restart_idx, **kwargs) 

367 else: 

368 u0 = P.u_exact(t=0, seed=P.comm.rank, noise_level=1e-3) 

369 for _ in range(self.relaxation_steps): 

370 u0 = P.solve_system(u0, 1e-1, u0) 

371 return u0, 0