Coverage for pySDC/tutorial/step_6/A_run_non_MPI_controller.py: 100%
13 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-02 12:30 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-02 12:30 +0000
1# ---
2# jupyter:
3# jupytext:
4# formats: py:percent
5# kernelspec:
6# display_name: Python 3
7# name: python3
8# ---
10# %% [markdown]
11# # Part A: The non-MPI controller
12#
13# pySDC comes with (at least) two controllers: the standard, non-MPI controller we have used so far, and the
14# MPI-parallel one. The non-MPI controller runs simulations without having to worry about parallelization and MPI
15# installations. By monitoring the convergence, it can already give a detailed idea of how PFASST will work for a
16# given problem.
17#
18# We run an unforced heat equation, on a smaller grid than in [Step 5](../step_5/B_my_first_PFASST_run), once on a
19# single level, as SDC, and then with two levels on 1, 2, 4 and 8 processes: MLSDC on one, PFASST on more. The setup is in `pfasst_setup.py` next to this tutorial, as
20# [Parts B](B_odd_temporal_distribution) and [C](C_MPI_parallelization) use it as well. The parameters of the
21# multi-level runs:
22#
23# :::{literalinclude} pfasst_setup.py
24# :pyobject: set_parameters_ml
25# :::
26#
27# The single-level ones, `set_parameters_sl`, are the same problem and sweeper on one level, without the transfer
28# class and without the controller options above. And this is the loop that runs the controller for each number of
29# processes, printing the error and the iterations of each step:
30#
31# :::{literalinclude} pfasst_setup.py
32# :pyobject: run_pfasst
33# :::
34#
35# The output also goes to a file in `data/`, for the comparison with the MPI controller in Part C.
37# %%
38import matplotlib.pyplot as plt
40from pySDC.tutorial.step_6.pfasst_setup import run_pfasst
42iterations_sl = run_pfasst(num_proc_list=[1], fname='step_6_A_sl_out.txt', multi_level=False)
44# %% [markdown]
45# And with two levels, PFASST:
47# %%
48iterations_ml = run_pfasst(num_proc_list=[1, 2, 4, 8], fname='step_6_A_ml_out.txt', multi_level=True)
50# %% tags=["hide-input"]
51fig, ax = plt.subplots(figsize=(8, 2.4), constrained_layout=True)
52rows = {'SDC, 1': iterations_sl[1]}
53rows.update({f'{"MLSDC" if n == 1 else "PFASST"}, {n}': counts for n, counts in iterations_ml.items()})
54image = ax.imshow(list(rows.values()), cmap='viridis', aspect='auto', vmin=0)
55ax.set_yticks(range(len(rows)))
56ax.set_yticklabels(list(rows))
57ax.set_ylabel('method, processes')
58ax.set_xlabel('time step')
59fig.colorbar(image, label='iterations')
61# %% [markdown]
62# :::{admonition} Important things to note
63# - If you don't want to deal with parallelization and/or are only interested in SDC, MLSDC or the convergence of
64# PFASST, use the non-MPI controller.
65# - If you care about parallelization, use the MPI controller, see [Part C](C_MPI_parallelization).
66# :::
67#
68# The check the tests run is inside `run_pfasst`: no step needs more than 8 iterations.