Coverage for pySDC/tutorial/step_4/C_SDC_vs_MLSDC.py: 100%
80 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
3from pySDC.helpers.stats_helper import get_sorted
5from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI
6from pySDC.implementations.problem_classes.HeatEquation_ND_FD import heatNd_unforced
7from pySDC.implementations.sweeper_classes.generic_implicit import generic_implicit
8from pySDC.implementations.transfer_classes.TransferMesh import mesh_to_mesh
11def main():
12 """
13 A simple test program to compare SDC and MLSDC
14 """
16 # initialize level parameters
17 level_params = dict()
18 level_params['restol'] = 1e-09
19 level_params['dt'] = 0.1
21 # initialize sweeper parameters
22 sweeper_params_sdc = dict()
23 sweeper_params_sdc['node_type'] = 'LEGENDRE'
24 sweeper_params_sdc['quad_type'] = 'RADAU-RIGHT'
25 sweeper_params_sdc['num_nodes'] = 5
26 sweeper_params_sdc['QI'] = 'LU'
28 sweeper_params_mlsdc = dict()
29 sweeper_params_mlsdc['node_type'] = 'LEGENDRE'
30 sweeper_params_mlsdc['quad_type'] = 'RADAU-RIGHT'
31 sweeper_params_mlsdc['num_nodes'] = [5, 3, 2]
32 sweeper_params_mlsdc['QI'] = 'LU'
34 # initialize problem parameters
35 problem_params_sdc = dict()
36 problem_params_sdc['nu'] = 0.1 # diffusion coefficient
37 problem_params_sdc['freq'] = 4 # frequency for the test value
38 problem_params_sdc['nvars'] = 1023 # number of degrees of freedom for each level
39 problem_params_sdc['bc'] = 'dirichlet-zero' # boundary conditions
41 problem_params_mlsdc = dict()
42 problem_params_mlsdc['nu'] = 0.1 # diffusion coefficient
43 problem_params_mlsdc['freq'] = 4 # frequency for the test value
44 problem_params_mlsdc['nvars'] = [1023, 511, 255] # number of degrees of freedom for each level
45 problem_params_mlsdc['bc'] = 'dirichlet-zero' # boundary conditions
47 # initialize step parameters
48 step_params = dict()
49 step_params['maxiter'] = 20
51 # initialize space transfer parameters
52 space_transfer_params = dict()
53 space_transfer_params['rorder'] = 2
54 space_transfer_params['iorder'] = 6
56 # initialize controller parameters
57 controller_params = dict()
58 controller_params['logger_level'] = 30
60 # fill description dictionary for SDC
61 description_sdc = dict()
62 description_sdc['problem_class'] = heatNd_unforced
63 description_sdc['problem_params'] = problem_params_sdc
64 description_sdc['sweeper_class'] = generic_implicit
65 description_sdc['sweeper_params'] = sweeper_params_sdc
66 description_sdc['level_params'] = level_params
67 description_sdc['step_params'] = step_params
69 # fill description dictionary for MLSDC
70 description_mlsdc = dict()
71 description_mlsdc['problem_class'] = heatNd_unforced
72 description_mlsdc['problem_params'] = problem_params_mlsdc
73 description_mlsdc['sweeper_class'] = generic_implicit
74 description_mlsdc['sweeper_params'] = sweeper_params_mlsdc
75 description_mlsdc['level_params'] = level_params
76 description_mlsdc['step_params'] = step_params
77 description_mlsdc['space_transfer_class'] = mesh_to_mesh
78 description_mlsdc['space_transfer_params'] = space_transfer_params
80 # instantiate the controller (no controller parameters used here)
81 controller_sdc = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description_sdc)
82 controller_mlsdc = controller_nonMPI(
83 num_procs=1, controller_params=controller_params, description=description_mlsdc
84 )
86 # set time parameters
87 t0 = 0.0
88 Tend = 0.1
90 # get initial values on finest level
91 P = controller_sdc.MS[0].levels[0].prob
92 uinit = P.u_exact(t0)
94 # call main functions to get things done...
95 uend_sdc, stats_sdc = controller_sdc.run(u0=uinit, t0=t0, Tend=Tend)
96 uend_mlsdc, stats_mlsdc = controller_mlsdc.run(u0=uinit, t0=t0, Tend=Tend)
98 # get number of iterations for both
99 niter_sdc = get_sorted(stats_sdc, type='niter', sortby='time')[0][1]
100 niter_mlsdc = get_sorted(stats_mlsdc, type='niter', sortby='time')[0][1]
102 # compute exact solution and compare both
103 uex = P.u_exact(Tend)
104 err_sdc = abs(uex - uend_sdc)
105 err_mlsdc = abs(uex - uend_mlsdc)
106 diff = abs(uend_mlsdc - uend_sdc)
108 # print out and check
109 Path("data").mkdir(parents=True, exist_ok=True)
110 f = open('data/step_4_C_out.txt', 'a')
111 out = 'Error SDC and MLSDC: %12.8e -- %12.8e' % (err_sdc, err_mlsdc)
112 f.write(out + '\n')
113 print(out)
114 out = 'Difference SDC vs. MLSDC: %12.8e' % diff
115 f.write(out + '\n')
116 print(out)
117 out = 'Number of iterations SDC and MLSDC: %2i -- %2i' % (niter_sdc, niter_mlsdc)
118 f.write(out + '\n')
119 print(out)
121 assert diff < 6e-10, "ERROR: difference between MLSDC and SDC is higher than expected, got %s" % diff
122 assert niter_sdc - niter_mlsdc <= 6, "ERROR: MLSDC required more iterations than expected, got %s" % niter_mlsdc
125if __name__ == "__main__":
126 main()