Coverage for pySDC/projects/FastWaveSlowWave/runmultiscale_acoustic.py: 99%
97 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
1import matplotlib
3matplotlib.use('Agg')
5import numpy as np
6from matplotlib import pyplot as plt
7from pylab import rcParams
9from pySDC.projects.FastWaveSlowWave.HookClass_acoustic import dump_energy
11from pySDC.implementations.sweeper_classes.imex_1st_order import imex_1st_order
12from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI
13from pySDC.implementations.problem_classes.acoustic_helpers.standard_integrators import bdf2, dirk, trapezoidal, rk_imex
15from pySDC.projects.FastWaveSlowWave.AcousticAdvection_1D_FD_imex_multiscale import acoustic_1d_imex_multiscale
18def compute_and_plot_solutions():
19 """
20 Routine to compute and plot the solutions of SDC(2), IMEX, BDF-2 and RK for a multiscale problem
21 """
23 num_procs = 1
25 t0 = 0.0
26 Tend = 3.0
27 nsteps = 154 # 154 is value in Vater et al.
28 dt = Tend / float(nsteps)
30 # initialize level parameters
31 level_params = dict()
32 level_params['restol'] = 1e-10
33 level_params['dt'] = dt
35 # This comes as read-in for the step class
36 step_params = dict()
37 step_params['maxiter'] = 2
39 # This comes as read-in for the problem class
40 problem_params = dict()
41 problem_params['cadv'] = 0.05
42 problem_params['cs'] = 1.0
43 problem_params['nvars'] = [(2, 512)]
44 problem_params['order_adv'] = 5
45 problem_params['waveno'] = 5
47 # This comes as read-in for the sweeper class
48 sweeper_params = dict()
49 sweeper_params['quad_type'] = 'RADAU-RIGHT'
50 sweeper_params['num_nodes'] = 2
52 # initialize controller parameters
53 controller_params = dict()
54 controller_params['logger_level'] = 30
55 controller_params['hook_class'] = dump_energy
57 # Fill description dictionary for easy hierarchy creation
58 description = dict()
59 description['problem_class'] = acoustic_1d_imex_multiscale
60 description['problem_params'] = problem_params
61 description['sweeper_class'] = imex_1st_order
62 description['sweeper_params'] = sweeper_params
63 description['step_params'] = step_params
64 description['level_params'] = level_params
66 # instantiate the controller
67 controller = controller_nonMPI(num_procs=num_procs, controller_params=controller_params, description=description)
69 # get initial values on finest level
70 P = controller.MS[0].levels[0].prob
71 uinit = P.u_exact(t0)
73 # call main function to get things done...
74 uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
76 # instantiate standard integrators to be run for comparison
77 trap = trapezoidal((P.A + P.Dx).astype('complex'), 0.5)
78 bdf2_m = bdf2(P.A + P.Dx)
79 dirk_m = dirk((P.A + P.Dx).astype('complex'), step_params['maxiter'])
80 rkimex = rk_imex(P.A.astype('complex'), P.Dx.astype('complex'), step_params['maxiter'])
82 y0_tp = np.concatenate((uinit[0, :], uinit[1, :]))
83 y0_bdf = y0_tp
84 y0_dirk = y0_tp.astype('complex')
85 y0_imex = y0_tp.astype('complex')
87 # Perform time steps with standard integrators
88 for i in range(0, nsteps):
89 # trapezoidal rule step
90 ynew_tp = trap.timestep(y0_tp, dt)
92 # BDF-2 scheme
93 if i == 0:
94 ynew_bdf = bdf2_m.firsttimestep(y0_bdf, dt)
95 ym1_bdf = y0_bdf
96 else:
97 ynew_bdf = bdf2_m.timestep(y0_bdf, ym1_bdf, dt)
99 # DIRK scheme
100 ynew_dirk = dirk_m.timestep(y0_dirk, dt)
102 # IMEX scheme
103 ynew_imex = rkimex.timestep(y0_imex, dt)
105 y0_tp = ynew_tp
106 ym1_bdf = y0_bdf
107 y0_bdf = ynew_bdf
108 y0_dirk = ynew_dirk
109 y0_imex = ynew_imex
111 # Finished running standard integrators
112 unew_tp, pnew_tp = np.split(ynew_tp, 2)
113 unew_bdf, pnew_bdf = np.split(ynew_bdf, 2)
114 unew_dirk, pnew_dirk = np.split(ynew_dirk, 2)
115 unew_imex, pnew_imex = np.split(ynew_imex, 2)
117 fs = 8
119 rcParams['figure.figsize'] = 2.5, 2.5
120 # rcParams['pgf.rcfonts'] = False
121 fig = plt.figure()
123 sigma_0 = 0.1
124 # k = 7.0 * 2.0 * np.pi
125 x_0 = 0.75
126 # x_1 = 0.25
128 assert np.isclose(np.linalg.norm(uend[1, :], np.inf), 8.489e-01, 1e-03)
129 assert np.isclose(np.linalg.norm(pnew_dirk, np.inf), 1.003e00, 1e-03)
130 assert np.isclose(np.linalg.norm(pnew_imex, np.inf), 2.762e21, 1e-03)
132 print('Maximum pressure in SDC: %5.3e' % np.linalg.norm(uend[1, :], np.inf))
133 print('Maximum pressure in DIRK: %5.3e' % np.linalg.norm(pnew_dirk, np.inf))
134 print('Maximum pressure in RK-IMEX: %5.3e' % np.linalg.norm(pnew_imex, np.inf))
136 if dirk_m.order == 2:
137 plt.plot(P.mesh, pnew_bdf, 'd-', color='c', label='BDF-2', markevery=(50, 75))
138 p_slow = np.exp(-np.square(np.mod(P.mesh - problem_params['cadv'] * Tend, 1.0) - x_0) / (sigma_0 * sigma_0))
139 plt.plot(P.mesh, p_slow, '--', color='k', markersize=fs - 2, label='Slow mode', dashes=(10, 2))
140 if np.linalg.norm(pnew_imex, np.inf) <= 2:
141 plt.plot(
142 P.mesh, pnew_imex, '+-', color='r', label='IMEX(' + str(rkimex.order) + ')', markevery=(1, 75), mew=1.0
143 )
144 plt.plot(P.mesh, uend[1, :], 'o-', color='b', label='SDC(' + str(step_params['maxiter']) + ')', markevery=(25, 75))
145 plt.plot(P.mesh, np.real(pnew_dirk), '-', color='g', label='DIRK(' + str(dirk_m.order) + ')')
147 plt.xlabel('x', fontsize=fs, labelpad=0)
148 plt.ylabel('Pressure', fontsize=fs, labelpad=0)
149 fig.gca().set_xlim([0, 1.0])
150 fig.gca().set_ylim([-0.5, 1.1])
151 fig.gca().tick_params(axis='both', labelsize=fs)
152 plt.legend(loc='upper left', fontsize=fs, prop={'size': fs}, handlelength=3)
153 fig.gca().grid()
154 filename = 'data/multiscale-K' + str(step_params['maxiter']) + '-M' + str(sweeper_params['num_nodes']) + '.png'
155 plt.gcf().savefig(filename, bbox_inches='tight')
158if __name__ == "__main__":
159 compute_and_plot_solutions()