Coverage for pySDC/tutorial/step_5/B_my_first_PFASST_run.py: 100%
72 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
1from pathlib import Path
2import numpy as np
4from pySDC.helpers.stats_helper import get_sorted
6from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI
7from pySDC.implementations.problem_classes.HeatEquation_ND_FD import heatNd_forced
8from pySDC.implementations.sweeper_classes.imex_1st_order import imex_1st_order
9from pySDC.implementations.transfer_classes.TransferMesh import mesh_to_mesh
12def main():
13 """
14 A simple test program to do PFASST runs for the heat equation
15 """
17 # initialize level parameters
18 level_params = dict()
19 level_params['restol'] = 1e-10
20 level_params['dt'] = 0.25
22 # initialize sweeper parameters
23 sweeper_params = dict()
24 sweeper_params['quad_type'] = 'RADAU-RIGHT'
25 sweeper_params['num_nodes'] = [3]
26 sweeper_params['QI'] = 'LU' # For the IMEX sweeper, the LU-trick can be activated for the implicit part
28 # initialize problem parameters
29 problem_params = dict()
30 problem_params['nu'] = 0.1 # diffusion coefficient
31 problem_params['freq'] = 8 # frequency for the test value
32 problem_params['nvars'] = [511, 255] # number of degrees of freedom for each level
33 problem_params['bc'] = 'dirichlet-zero' # boundary conditions
35 # initialize step parameters
36 step_params = dict()
37 step_params['maxiter'] = 50
39 # initialize space transfer parameters
40 space_transfer_params = dict()
41 space_transfer_params['rorder'] = 2
42 space_transfer_params['iorder'] = 6
44 # initialize controller parameters
45 controller_params = dict()
46 controller_params['logger_level'] = 30
47 controller_params['predict_type'] = 'pfasst_burnin'
49 # fill description dictionary for easy step instantiation
50 description = dict()
51 description['problem_class'] = heatNd_forced # pass problem class
52 description['problem_params'] = problem_params # pass problem parameters
53 description['sweeper_class'] = imex_1st_order # pass sweeper (see part B)
54 description['sweeper_params'] = sweeper_params # pass sweeper parameters
55 description['level_params'] = level_params # pass level parameters
56 description['step_params'] = step_params # pass step parameters
57 description['space_transfer_class'] = mesh_to_mesh # pass spatial transfer class
58 description['space_transfer_params'] = space_transfer_params # pass parameters for spatial transfer
60 # set time parameters
61 t0 = 0.0
62 Tend = 4.0
64 # set up list of parallel time-steps to run PFASST with
65 nsteps = int(Tend / level_params['dt'])
66 num_proc_list = [2**i for i in range(int(np.log2(nsteps) + 1))]
68 Path("data").mkdir(parents=True, exist_ok=True)
69 f = open('data/step_5_B_out.txt', 'w')
70 # loop over different number of processes and check results
71 for num_proc in num_proc_list:
72 out = 'Working with %2i processes...' % num_proc
73 f.write(out + '\n')
74 print(out)
75 # instantiate controller
76 controller = controller_nonMPI(num_procs=num_proc, controller_params=controller_params, description=description)
78 # get initial values on finest level
79 P = controller.MS[0].levels[0].prob
80 uinit = P.u_exact(t0)
82 # call main function to get things done...
83 uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
85 # compute exact solution and compare
86 uex = P.u_exact(Tend)
87 err = abs(uex - uend)
89 # filter statistics by type (number of iterations)
90 iter_counts = get_sorted(stats, type='niter', sortby='time')
92 # compute and print statistics
93 for item in iter_counts:
94 out = 'Number of iterations for time %4.2f: %2i' % item
95 f.write(out + '\n')
96 print(out)
97 f.write('\n')
98 print()
99 niters = np.array([item[1] for item in iter_counts])
100 out = ' Mean number of iterations: %4.2f' % np.mean(niters)
101 f.write(out + '\n')
102 print(out)
103 out = ' Range of values for number of iterations: %2i ' % np.ptp(niters)
104 f.write(out + '\n')
105 print(out)
106 out = ' Position of max/min number of iterations: %2i -- %2i' % (
107 int(np.argmax(niters)),
108 int(np.argmin(niters)),
109 )
110 f.write(out + '\n')
111 print(out)
112 out = ' Std and var for number of iterations: %4.2f -- %4.2f' % (float(np.std(niters)), float(np.var(niters)))
113 f.write(out + '\n')
114 print(out)
116 f.write('\n\n')
117 print()
118 print()
120 assert err < 1.3505e-04, "ERROR: error is too high, got %s" % err
121 assert np.ptp(niters) <= 1, "ERROR: range of number of iterations is too high, got %s" % np.ptp(niters)
122 assert np.mean(niters) <= 5.0, "ERROR: mean number of iterations is too high, got %s" % np.mean(niters)
124 f.close()
127if __name__ == "__main__":
128 main()