Skip to content

Commit 4d10733

Browse files
committed
Added basic infrastructure for Rayleigh-Benard in resilience project
1 parent 5fccc9f commit 4d10733

File tree

2 files changed

+166
-1
lines changed

2 files changed

+166
-1
lines changed

pySDC/implementations/convergence_controller_classes/step_size_limiter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def get_new_step_size(self, controller, S, **kwargs):
146146
S,
147147
)
148148
L.status.dt_new = dt_new
149-
elif abs(L.status.dt_new / L.params.dt - 1) < self.params.dt_rel_min_slope:
149+
elif abs(L.status.dt_new / L.params.dt - 1) < self.params.dt_rel_min_slope and not S.status.restart:
150150
L.status.dt_new = L.params.dt
151151
self.log(
152152
f"Step size did not change sufficiently to warrant step size change, keeping {L.status.dt_new:.2e}",

pySDC/projects/Resilience/RBC.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# script to run a Rayleigh-Benard Convection problem
2+
from pySDC.implementations.problem_classes.generic_spectral import compute_residual_DAE
3+
from pySDC.implementations.problem_classes.RayleighBenard import RayleighBenard
4+
from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI
5+
from pySDC.projects.Resilience.hook import hook_collection, LogData
6+
from pySDC.projects.Resilience.strategies import merge_descriptions
7+
from pySDC.implementations.sweeper_classes.imex_1st_order import imex_1st_order
8+
from pySDC.core.convergence_controller import ConvergenceController
9+
10+
from pySDC.core.errors import ConvergenceError
11+
12+
13+
class ReachTendExactly(ConvergenceController):
14+
15+
def setup(self, controller, params, description, **kwargs):
16+
defaults = {
17+
"control_order": +50,
18+
"Tend": None,
19+
}
20+
return {**defaults, **super().setup(controller, params, description, **kwargs)}
21+
22+
def get_new_step_size(self, controller, step, **kwargs):
23+
L = step.levels[0]
24+
L.status.dt_new = min([L.params.dt, self.params.Tend - L.time - L.dt])
25+
26+
27+
def run_RBC(
28+
custom_description=None,
29+
num_procs=1,
30+
Tend=14.0,
31+
hook_class=LogData,
32+
fault_stuff=None,
33+
custom_controller_params=None,
34+
u0=None,
35+
t0=10,
36+
use_MPI=False,
37+
**kwargs,
38+
):
39+
"""
40+
Args:
41+
custom_description (dict): Overwrite presets
42+
num_procs (int): Number of steps for MSSDC
43+
Tend (float): Time to integrate to
44+
hook_class (pySDC.Hook): A hook to store data
45+
fault_stuff (dict): A dictionary with information on how to add faults
46+
custom_controller_params (dict): Overwrite presets
47+
u0 (dtype_u): Initial value
48+
t0 (float): Starting time
49+
use_MPI (bool): Whether or not to use MPI
50+
51+
Returns:
52+
dict: The stats object
53+
controller: The controller
54+
bool: If the code crashed
55+
"""
56+
level_params = {}
57+
level_params['dt'] = 5e-4
58+
level_params['restol'] = -1
59+
60+
sweeper_params = {}
61+
sweeper_params['quad_type'] = 'RADAU-RIGHT'
62+
sweeper_params['num_nodes'] = 3
63+
sweeper_params['QI'] = 'LU'
64+
sweeper_params['QE'] = 'PIC'
65+
66+
problem_params = {}
67+
68+
step_params = {}
69+
step_params['maxiter'] = 5
70+
71+
convergence_controllers = {}
72+
convergence_controllers[ReachTendExactly] = {'Tend': Tend}
73+
74+
controller_params = {}
75+
controller_params['logger_level'] = 30
76+
controller_params['hook_class'] = hook_collection + (hook_class if type(hook_class) == list else [hook_class])
77+
controller_params['mssdc_jac'] = False
78+
79+
if custom_controller_params is not None:
80+
controller_params = {**controller_params, **custom_controller_params}
81+
82+
imex_1st_order.compute_residual = compute_residual_DAE
83+
84+
RayleighBenard._u_exact = RayleighBenard.u_exact
85+
RayleighBenard.u_exact = u_exact
86+
87+
description = {}
88+
description['problem_class'] = RayleighBenard
89+
description['problem_params'] = problem_params
90+
description['sweeper_class'] = imex_1st_order
91+
description['sweeper_params'] = sweeper_params
92+
description['level_params'] = level_params
93+
description['step_params'] = step_params
94+
95+
if custom_description is not None:
96+
description = merge_descriptions(description, custom_description)
97+
98+
controller_args = {
99+
'controller_params': controller_params,
100+
'description': description,
101+
}
102+
if use_MPI:
103+
from mpi4py import MPI
104+
from pySDC.implementations.controller_classes.controller_MPI import controller_MPI
105+
106+
comm = kwargs.get('comm', MPI.COMM_WORLD)
107+
controller = controller_MPI(**controller_args, comm=comm)
108+
P = controller.S.levels[0].prob
109+
else:
110+
controller = controller_nonMPI(**controller_args, num_procs=num_procs)
111+
P = controller.MS[0].levels[0].prob
112+
113+
t0 = 0.0 if t0 is None else t0
114+
uinit = P.u_exact(t0) if u0 is None else u0
115+
116+
if fault_stuff is not None:
117+
from pySDC.projects.Resilience.fault_injection import prepare_controller_for_faults
118+
119+
prepare_controller_for_faults(controller, fault_stuff)
120+
121+
crash = False
122+
try:
123+
uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
124+
except ConvergenceError as e:
125+
print(f'Warning: Premature termination!: {e}')
126+
stats = controller.return_stats()
127+
crash = True
128+
return stats, controller, crash
129+
130+
131+
def u_exact(self, t, u_init=None, t_init=None, recompute=False):
132+
import pickle
133+
import os
134+
135+
path = f'data/stats/RBC-u_init-{t}.pickle'
136+
if os.path.exists(path) and not recompute and t_init is None:
137+
with open(path, 'rb') as file:
138+
data = pickle.load(file)
139+
else:
140+
from pySDC.helpers.stats_helper import get_sorted
141+
from pySDC.implementations.convergence_controller_classes.adaptivity import Adaptivity
142+
143+
convergence_controllers = {
144+
Adaptivity: {'e_tol': 1e-8, 'dt_rel_min_slope': 0.25},
145+
}
146+
desc = {'convergence_controllers': convergence_controllers}
147+
148+
u0 = RayleighBenard()._u_exact(0) if u_init is None else u_init
149+
t0 = 0 if t_init is None else t_init
150+
stats, _, _ = run_RBC(Tend=t, u0=u0, t0=t0, custom_description=desc)
151+
152+
u = get_sorted(stats, type='u', recomputed=False)[-1]
153+
data = u[1]
154+
155+
if t0 == 0:
156+
with open(path, 'wb') as file:
157+
pickle.dump(data, file)
158+
159+
return data
160+
161+
162+
if __name__ == '__main__':
163+
from pySDC.implementations.hooks.log_errors import LogLocalErrorPostStep
164+
165+
stats, _, _ = run_RBC(hook_class=LogLocalErrorPostStep)

0 commit comments

Comments
 (0)