Skip to content

Commit fb13739

Browse files
committed
Merge branch 'master' into v5
2 parents 559271c + 553e460 commit fb13739

File tree

9 files changed

+995
-38
lines changed

9 files changed

+995
-38
lines changed

pySDC/core/Controller.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ def __setup_custom_logger(level=None, log_to_file=None, fname=None):
100100
else:
101101
pass
102102

103+
def welcome_message(self):
104+
out = 'Welcome to the one and only, really very astonishing and 87.3% bug free' + \
105+
'\n _____ _____ _____ ' + \
106+
'\n / ____| __ \ / ____|' + \
107+
'\n _ __ _ _| (___ | | | | | ' + \
108+
'\n | \'_ \| | | |\___ \| | | | | ' + \
109+
'\n | |_) | |_| |____) | |__| | |____ ' + \
110+
'\n | .__/ \__, |_____/|_____/ \_____|' + \
111+
'\n | | __/ | ' + \
112+
'\n |_| |___/ ' + \
113+
'\n '
114+
self.logger.info(out)
115+
103116
def dump_setup(self, step, controller_params, description):
104117
"""
105118
Helper function to dump the setup used for this controller
@@ -110,6 +123,7 @@ def dump_setup(self, step, controller_params, description):
110123
description (dict): description of the problem
111124
"""
112125

126+
self.welcome_message()
113127
out = 'Setup overview (--> user-defined) -- BEGIN'
114128
self.logger.info(out)
115129
out = '----------------------------------------------------------------------------------------------------\n\n'

pySDC/implementations/convergence_controller_classes/adaptivity.py

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def get_new_step_size(self, controller, S):
6767
"""
6868
raise NotImplementedError('Please implement a rule for updating the step size!')
6969

70-
def compute_optimatal_step_size(self, beta, dt, e_tol, e_est, order):
70+
def compute_optimal_step_size(self, beta, dt, e_tol, e_est, order):
7171
"""
7272
Compute the optimal step size for the current step based on the order of the scheme.
7373
This function can be called from `get_new_step_size` for various implementations of adaptivity, but notably not
@@ -199,9 +199,8 @@ def get_new_step_size(self, controller, S):
199199
order = S.status.iter # embedded error estimate is same order as time marching
200200

201201
e_est = self.get_local_error_estimate(controller, S)
202-
L.status.dt_new = self.compute_optimatal_step_size(
203-
self.params.beta, L.params.dt, self.params.e_tol, e_est, order
204-
)
202+
L.status.dt_new = self.compute_optimal_step_size(self.params.beta, L.params.dt, self.params.e_tol, e_est,
203+
order)
205204
self.log(f'Adjusting step size from {L.params.dt:.2e} to {L.status.dt_new:.2e}', S)
206205

207206
return None
@@ -220,6 +219,55 @@ def get_local_error_estimate(self, controller, S, **kwargs):
220219
return S.levels[0].status.error_embedded_estimate
221220

222221

222+
class AdaptivityRK(Adaptivity):
223+
'''
224+
Adaptivity for Runge-Kutta methods. Basically, we need to change the order in the step size update
225+
'''
226+
def check_parameters(self, controller, params, description):
227+
'''
228+
Check whether parameters are compatible with whatever assumptions went into the step size functions etc.
229+
For adaptivity, we need to know the order of the scheme.
230+
231+
Args:
232+
controller (pySDC.Controller): The controller
233+
params (dict): The params passed for this specific convergence controller
234+
description (dict): The description object used to instantiate the controller
235+
236+
Returns:
237+
bool: Whether the parameters are compatible
238+
str: The error message
239+
'''
240+
if 'update_order' not in params.keys():
241+
return False, 'Adaptivity needs an order for the update rule! Please set some up in \
242+
description[\'convergence_control_params\'][\'update_order\']!'
243+
244+
return super(AdaptivityRK, self).check_parameters(controller, params, description)
245+
246+
def get_new_step_size(self, controller, S):
247+
'''
248+
Determine a step size for the next step from an embedded estimate of the local error of the current step.
249+
250+
Args:
251+
controller (pySDC.Controller): The controller
252+
S (pySDC.Step): The current step
253+
254+
Returns:
255+
None
256+
'''
257+
# check if we performed the desired amount of sweeps
258+
if S.status.iter == S.params.maxiter:
259+
L = S.levels[0]
260+
261+
# compute next step size
262+
order = self.params.update_order
263+
e_est = self.get_local_error_estimate(controller, S)
264+
L.status.dt_new = self.compute_optimal_step_size(self.params.beta, L.params.dt, self.params.e_tol, e_est,
265+
order)
266+
self.log(f'Adjusting step size from {L.params.dt:.2e} to {L.status.dt_new:.2e}', S)
267+
268+
return None
269+
270+
223271
class AdaptivityResidual(AdaptivityBase):
224272
"""
225273
Do adaptivity based on residual.

pySDC/implementations/convergence_controller_classes/estimate_embedded_error.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from pySDC.core.ConvergenceController import ConvergenceController, Pars
44
from pySDC.implementations.convergence_controller_classes.store_uold import StoreUOld
55

6+
from pySDC.implementations.sweeper_classes.Runge_Kutta import RungeKutta
7+
68

79
class EstimateEmbeddedError(ConvergenceController):
810
"""
@@ -14,7 +16,7 @@ class EstimateEmbeddedError(ConvergenceController):
1416

1517
def setup(self, controller, params, description):
1618
"""
17-
Add a default value for control order to the parameters
19+
Add a default value for control order to the parameters and check if we are using a Runge-Kutta sweeper
1820
1921
Args:
2022
controller (pySDC.Controller): The controller
@@ -24,11 +26,12 @@ def setup(self, controller, params, description):
2426
Returns:
2527
dict: Updated parameters
2628
"""
27-
return {'control_order': -80, **params}
29+
sweeper_type = 'RK' if RungeKutta in description['sweeper_class'].__bases__ else 'SDC'
30+
return {'control_order': -80, 'sweeper_type': sweeper_type, **params}
2831

2932
def dependencies(self, controller, description):
3033
"""
31-
Load the convergence controller that stores the solution of the last sweep
34+
Load the convergence controller that stores the solution of the last sweep unless we are doing Runge-Kutta
3235
3336
Args:
3437
controller (pySDC.Controller): The controller
@@ -37,9 +40,32 @@ def dependencies(self, controller, description):
3740
Returns:
3841
None
3942
"""
40-
controller.add_convergence_controller(StoreUOld, description=description)
43+
if RungeKutta not in description['sweeper_class'].__bases__:
44+
controller.add_convergence_controller(StoreUOld, description=description)
4145
return None
4246

47+
def estimate_embedded_error_serial(self, L):
48+
"""
49+
Estimate the serial embedded error, which may need to be modified for a parallel estimate.
50+
51+
Depending on the type of sweeper, the lower order solution is stored in a different place.
52+
53+
Args:
54+
L (pySDC.level): The level
55+
56+
Returns:
57+
dtype_u: The embedded error estimate
58+
"""
59+
if self.params.sweeper_type == 'RK':
60+
# lower order solution is stored in the second to last entry of L.u
61+
return abs(L.u[-2] - L.u[-1])
62+
elif self.params.sweeper_type == 'SDC':
63+
# order rises by one between sweeps, making this so ridiculously easy
64+
return abs(L.uold[-1] - L.u[-1])
65+
else:
66+
raise NotImplementedError(f'Don\'t know how to estimate embedded error for sweeper type \
67+
{self.params.sweeper_type}')
68+
4369

4470
class EstimateEmbeddedErrorNonMPI(EstimateEmbeddedError):
4571
def __init__(self, controller, params, description):
@@ -85,10 +111,9 @@ def post_iteration_processing(self, controller, S):
85111
level'
86112
)
87113

88-
if S.status.iter > 1:
114+
if S.status.iter > 1 or self.params.sweeper_type == 'RK':
89115
for L in S.levels:
90-
# order rises by one between sweeps, making this so ridiculously easy
91-
temp = abs(L.uold[-1] - L.u[-1])
116+
temp = self.estimate_embedded_error_serial(L)
92117
L.status.error_embedded_estimate = max([abs(temp - self.buffers.e_em_last), np.finfo(float).eps])
93118

94119
self.buffers.e_em_last = temp * 1.0

0 commit comments

Comments
 (0)