Skip to content

Commit d313aef

Browse files
committed
Added test that ParaDiag converges within the bounds for Dahlquist
problem
1 parent bdfa5c9 commit d313aef

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

pySDC/tests/test_controllers/test_controller_ParaDiag_nonMPI.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ def get_composite_collocation_problem(L, M, N, alpha=0, dt=1e-1, problem='Dahlqu
66
from pySDC.implementations.hooks.log_errors import (
77
LogGlobalErrorPostRun,
88
LogGlobalErrorPostStep,
9+
LogGlobalErrorPostIter,
910
)
1011

1112
if ParaDiag:
@@ -74,7 +75,7 @@ def get_composite_collocation_problem(L, M, N, alpha=0, dt=1e-1, problem='Dahlqu
7475

7576
controller_params = {}
7677
controller_params['logger_level'] = 15
77-
controller_params['hook_class'] = [LogGlobalErrorPostRun, LogGlobalErrorPostStep]
78+
controller_params['hook_class'] = [LogGlobalErrorPostRun, LogGlobalErrorPostStep, LogGlobalErrorPostIter]
7879
controller_params['mssdc_jac'] = False
7980
controller_params['alpha'] = alpha
8081
controller_params['average_jacobian'] = average_jacobian
@@ -223,8 +224,45 @@ def test_ParaDiag_order(L, M, N, alpha):
223224
), f'Got unexpected numerical order {num_order} instead of {expected_order} in ParaDiag'
224225

225226

227+
@pytest.mark.base
228+
@pytest.mark.parametrize('L', [4, 12])
229+
@pytest.mark.parametrize('M', [2, 3])
230+
@pytest.mark.parametrize('N', [1])
231+
@pytest.mark.parametrize('alpha', [1e-4, 1e-2])
232+
def test_ParaDiag_convergence_rate(L, M, N, alpha):
233+
r"""
234+
Test that the error in ParaDiag contracts as fast as expected.
235+
236+
The upper bound is \|u^{k+1} - u^*\| / \|u^k - u^*\| < \alpha / (1-\alpha).
237+
Here, we compare to the exact solution to the continuous problem rather than the exact solution of the collocation
238+
problem, which means the error stalls at time-discretization level. Therefore, we only check the contraction in the
239+
first ParaDiag iteration.
240+
"""
241+
import numpy as np
242+
from pySDC.helpers.stats_helper import get_sorted
243+
244+
dt = 1e-2
245+
controller, prob = get_composite_collocation_problem(L, M, N, alpha, dt=dt, problem='Dahlquist')
246+
247+
# setup initial conditions
248+
u0 = prob.u_exact(0)
249+
250+
uend, stats = controller.run(u0=u0, t0=0, Tend=L * dt)
251+
252+
# test that the convergence rate in the first iteration is sufficiently small.
253+
errors = get_sorted(stats, type='e_global_post_iteration', sortby='iter', time=(L - 1) * dt)
254+
convergence_rates = [errors[i + 1][1] / errors[i][1] for i in range(len(errors) - 1)]
255+
convergence_rate = convergence_rates[0]
256+
convergence_bound = alpha / (1 - alpha)
257+
258+
assert (
259+
convergence_rate < convergence_bound
260+
), f'Convergence rate {convergence_rate} exceeds upper bound of {convergence_bound}!'
261+
262+
226263
if __name__ == '__main__':
227-
test_ParaDiag_vs_PFASST(4, 3, 2, 'Dahlquist')
264+
test_ParaDiag_convergence_rate(4, 3, 1, 1e-4)
265+
# test_ParaDiag_vs_PFASST(4, 3, 2, 'Dahlquist')
228266
# test_ParaDiag_convergence(4, 3, 1, 1e-4, 'vdp')
229267
# test_IMEX_ParaDiag_convergence(4, 3, 64, 1e-4)
230268
# test_ParaDiag_order(3, 3, 1, 1e-4)

0 commit comments

Comments
 (0)