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

1# --- 

2# jupyter: 

3# jupytext: 

4# formats: py:percent 

5# kernelspec: 

6# display_name: Python 3 

7# name: python3 

8# --- 

9 

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. 

36 

37# %% 

38import matplotlib.pyplot as plt 

39 

40from pySDC.tutorial.step_6.pfasst_setup import run_pfasst 

41 

42iterations_sl = run_pfasst(num_proc_list=[1], fname='step_6_A_sl_out.txt', multi_level=False) 

43 

44# %% [markdown] 

45# And with two levels, PFASST: 

46 

47# %% 

48iterations_ml = run_pfasst(num_proc_list=[1, 2, 4, 8], fname='step_6_A_ml_out.txt', multi_level=True) 

49 

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') 

60 

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.