Coverage for pySDC/projects/parallelSDC/preconditioner_playground_MPI.py: 97%
141 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-29 09:02 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-29 09:02 +0000
1import os
2import pickle
3from collections import namedtuple
5import numpy as np
6from mpi4py import MPI
8import pySDC.helpers.plot_helper as plt_helper
9from pySDC.helpers.stats_helper import get_sorted
11from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI
12from pySDC.implementations.problem_classes.AdvectionEquation_ND_FD import advectionNd
13from pySDC.implementations.problem_classes.GeneralizedFisher_1D_FD_implicit import generalized_fisher
14from pySDC.implementations.problem_classes.HeatEquation_ND_FD import heatNd_unforced
15from pySDC.implementations.problem_classes.Van_der_Pol_implicit import vanderpol
16from pySDC.implementations.sweeper_classes.generic_implicit_MPI import generic_implicit_MPI
18# from pySDC.projects.parallelSDC.BaseTransfer_MPI import base_transfer_mpi
20ID = namedtuple('ID', ['setup', 'qd_type', 'param'])
23def main(comm=None):
24 # initialize level parameters (part I)
25 level_params = dict()
26 level_params['restol'] = 1e-08
28 # initialize sweeper parameters (part I)
29 sweeper_params = dict()
30 sweeper_params['quad_type'] = 'RADAU-RIGHT'
31 sweeper_params['num_nodes'] = comm.Get_size()
32 sweeper_params['comm'] = comm
34 # initialize step parameters
35 step_params = dict()
36 step_params['maxiter'] = 100
38 # initialize controller parameters
39 controller_params = dict()
40 controller_params['logger_level'] = 30
42 # set up list of Q-delta types and setups
43 qd_list = ['IEpar', 'Qpar', 'MIN', 'MIN3', 'MIN_GT']
44 setup_list = [
45 ('heat', 63, [10.0**i for i in range(-3, 3)]),
46 ('advection', 64, [10.0**i for i in range(-3, 3)]),
47 ('vanderpol', 2, [0.1 * 2**i for i in range(0, 10)]),
48 ('fisher', 63, [2**i for i in range(-2, 3)]),
49 ]
50 # setup_list = [('fisher', 63, [2 * i for i in range(1, 6)])]
52 # pre-fill results with lists of setups
53 results = dict()
54 for setup, nvars, param_list in setup_list:
55 results[setup] = (nvars, param_list)
57 # loop over all Q-delta matrix types
58 for qd_type in qd_list:
59 # assign implicit Q-delta matrix
60 sweeper_params['QI'] = qd_type
62 # loop over all setups
63 for setup, nvars, param_list in setup_list:
64 # initialize problem parameters (part I)
65 problem_params = dict()
66 if setup != 'vanderpol':
67 problem_params['nvars'] = nvars # number of degrees of freedom for each level
69 # loop over all parameters
70 for param in param_list:
71 # fill description for the controller
72 description = dict()
73 description['sweeper_class'] = generic_implicit_MPI # pass sweeper
74 description['sweeper_params'] = sweeper_params # pass sweeper parameters
75 description['step_params'] = step_params # pass step parameters
76 # description['base_transfer_class'] = base_transfer_mpi
78 print('working on: %s - %s - %s' % (qd_type, setup, param))
80 # decide which setup to take
81 if setup == 'heat':
82 problem_params['nu'] = param
83 problem_params['freq'] = 2
84 problem_params['bc'] = 'dirichlet-zero' # boundary conditions
86 level_params['dt'] = 0.1
88 description['problem_class'] = heatNd_unforced
89 description['problem_params'] = problem_params
90 description['level_params'] = level_params # pass level parameters
92 elif setup == 'advection':
93 problem_params['c'] = param
94 problem_params['order'] = 2
95 problem_params['freq'] = 2
96 problem_params['stencil_type'] = 'center' # boundary conditions
97 problem_params['bc'] = 'periodic' # boundary conditions
99 level_params['dt'] = 0.1
101 description['problem_class'] = advectionNd
102 description['problem_params'] = problem_params
103 description['level_params'] = level_params # pass level parameters
105 elif setup == 'vanderpol':
106 problem_params['newton_tol'] = 1e-09
107 problem_params['newton_maxiter'] = 20
108 problem_params['mu'] = param
109 problem_params['u0'] = np.array([2.0, 0])
111 level_params['dt'] = 0.1
113 description['problem_class'] = vanderpol
114 description['problem_params'] = problem_params
115 description['level_params'] = level_params
117 elif setup == 'fisher':
118 problem_params['nu'] = 1
119 problem_params['lambda0'] = param
120 problem_params['newton_maxiter'] = 20
121 problem_params['newton_tol'] = 1e-10
122 problem_params['interval'] = (-5, 5)
124 level_params['dt'] = 0.01
126 description['problem_class'] = generalized_fisher
127 description['problem_params'] = problem_params
128 description['level_params'] = level_params
130 else:
131 print('Setup not implemented..', setup)
132 exit()
134 # instantiate controller
135 controller = controller_nonMPI(
136 num_procs=1, controller_params=controller_params, description=description
137 )
139 # get initial values on finest level
140 P = controller.MS[0].levels[0].prob
141 uinit = P.u_exact(0)
143 # call main function to get things done...
144 uend, stats = controller.run(u0=uinit, t0=0, Tend=level_params['dt'])
146 # filter statistics by type (number of iterations)
147 iter_counts = get_sorted(stats, type='niter', sortby='time')
149 # just one time-step, grep number of iteration and store
150 niter = iter_counts[0][1]
151 id = ID(setup=setup, qd_type=qd_type, param=param)
152 results[id] = niter
154 assert len(results) == (6 + 6 + 10 + 5) * 5 + 4, 'ERROR: did not get all results, got %s' % len(results)
156 if comm.Get_rank() == 0:
157 # write out for later visualization
158 file = open('data/parallelSDC_iterations_precond_MPI.pkl', 'wb')
159 pickle.dump(results, file)
161 assert os.path.isfile('data/parallelSDC_iterations_precond_MPI.pkl'), 'ERROR: pickle did not create file'
164def plot_iterations():
165 """
166 Helper routine to plot iteration counts
167 """
169 file = open('data/parallelSDC_iterations_precond_MPI.pkl', 'rb')
170 results = pickle.load(file)
172 # find the lists/header required for plotting
173 qd_type_list = []
174 setup_list = []
175 for key in results.keys():
176 if isinstance(key, ID):
177 if key.qd_type not in qd_type_list:
178 qd_type_list.append(key.qd_type)
179 elif isinstance(key, str):
180 setup_list.append(key)
181 print('Found these type of preconditioners:', qd_type_list)
182 print('Found these setups:', setup_list)
184 assert len(qd_type_list) == 5, 'ERROR did not find four preconditioners, got %s' % qd_type_list
185 assert len(setup_list) == 4, 'ERROR: did not find four setup, got %s' % setup_list
187 qd_type_list = ['IEpar', 'Qpar', 'MIN', 'MIN3', 'MIN_GT']
188 marker_list = ['s', 'o', '^', 'v', 'x']
189 color_list = ['r', 'g', 'b', 'c', 'm']
191 plt_helper.setup_mpl()
192 print('post setup')
193 # loop over setups and Q-delta types: one figure per setup, all Qds in one plot
194 for setup in setup_list:
195 print('setup')
196 plt_helper.newfig(textwidth=238.96, scale=0.89)
198 for qd_type, marker, color in zip(qd_type_list, marker_list, color_list):
199 niter = np.zeros(len(results[setup][1]))
200 for key in results.keys():
201 if isinstance(key, ID):
202 if key.setup == setup and key.qd_type == qd_type:
203 xvalue = results[setup][1].index(key.param)
204 niter[xvalue] = results[key]
205 ls = '-'
206 lw = 1
207 plt_helper.plt.semilogx(
208 results[setup][1],
209 niter,
210 label=qd_type,
211 lw=lw,
212 linestyle=ls,
213 color=color,
214 marker=marker,
215 markeredgecolor='k',
216 )
218 if setup == 'heat':
219 xlabel = r'$\nu$'
220 elif setup == 'advection':
221 xlabel = r'$c$'
222 elif setup == 'fisher':
223 xlabel = r'$\lambda_0$'
224 elif setup == 'vanderpol':
225 xlabel = r'$\mu$'
226 else:
227 print('Setup not implemented..', setup)
228 exit()
230 plt_helper.plt.ylim([0, 60])
231 plt_helper.plt.legend(loc=2, ncol=1)
232 plt_helper.plt.ylabel('number of iterations')
233 plt_helper.plt.xlabel(xlabel)
234 plt_helper.plt.grid()
236 # save plot as PDF and PGF
237 fname = 'data/parallelSDC_preconditioner_MPI_' + setup
238 plt_helper.savefig(fname)
240 assert os.path.isfile(fname + '.pdf'), 'ERROR: plotting did not create PDF file'
241 # assert os.path.isfile(fname + '.pgf'), 'ERROR: plotting did not create PGF file'
242 assert os.path.isfile(fname + '.png'), 'ERROR: plotting did not create PNG file'
245if __name__ == "__main__":
246 comm = MPI.COMM_WORLD
247 main(comm=comm)
248 if comm.Get_rank() == 0:
249 plot_iterations()