Skip to content

Commit 67e8b79

Browse files
committed
added paper scripts to pySDC
1 parent 42ac113 commit 67e8b79

File tree

6 files changed

+353
-13
lines changed

6 files changed

+353
-13
lines changed

projects/AsympConv/PFASST_conv_tests.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import pickle
33
import os
44
import matplotlib
5-
# matplotlib.use('Agg')
5+
matplotlib.use('Agg')
66
import matplotlib.pyplot as plt
77

88
from pySDC.implementations.problem_classes.HeatEquation_1D_FD import heat1d
@@ -17,20 +17,28 @@
1717

1818

1919
def main():
20-
run_diffusion()
21-
run_advection()
20+
"""
21+
Main driver running diffusion and advection tests
22+
"""
23+
nsweeps = 3
24+
run_diffusion(nsweeps=nsweeps)
25+
run_advection(nsweeps=nsweeps)
26+
plot_results(nsweeps=nsweeps)
2227

2328

24-
def run_diffusion():
29+
def run_diffusion(nsweeps):
2530
"""
26-
A simple test program to test PFASST convergence for the periodic heat equation with random initial data
31+
A simple test program to test PFASST convergence for the heat equation with random initial data
32+
33+
Args:
34+
nsweeps: number of fine sweeps to perform
2735
"""
2836

2937
# initialize level parameters
3038
level_params = dict()
3139
level_params['restol'] = 1E-08
3240
level_params['dt'] = 0.25
33-
level_params['nsweeps'] = [3, 1]
41+
level_params['nsweeps'] = [nsweeps, 1]
3442

3543
# initialize sweeper parameters
3644
sweeper_params = dict()
@@ -114,6 +122,9 @@ def run_diffusion():
114122
out = ' Mean number of iterations: %4.2f' % np.mean(niters)
115123
print(out)
116124

125+
assert np.mean(niters) <= 6, "ERROR: number of iterations for diffusion tesst too high, got %s" \
126+
% np.mean(niters)
127+
117128
results[cfl] = np.mean(niters)
118129

119130
file = open('data/results_conv_diffusion.pkl', 'wb')
@@ -123,16 +134,19 @@ def run_diffusion():
123134
assert os.path.isfile('data/results_conv_diffusion.pkl'), 'ERROR: pickle did not create file'
124135

125136

126-
def run_advection():
137+
def run_advection(nsweeps):
127138
"""
128-
A simple test program to test PFASST convergence for the periodic heat equation with random initial data
139+
A simple test program to test PFASST convergence for the periodic advection equation
140+
141+
Args:
142+
nsweeps: number of fine sweeps to perform
129143
"""
130144

131145
# initialize level parameters
132146
level_params = dict()
133147
level_params['restol'] = 1E-08
134148
level_params['dt'] = 0.25
135-
level_params['nsweeps'] = [3, 1]
149+
level_params['nsweeps'] = [nsweeps, 1]
136150

137151
# initialize sweeper parameters
138152
sweeper_params = dict()
@@ -218,6 +232,9 @@ def run_advection():
218232
out = ' Mean number of iterations: %4.2f' % np.mean(niters)
219233
print(out)
220234

235+
assert np.mean(niters) <= 10, "ERROR: number of iterations for advection tesst too high, got %s" \
236+
% np.mean(niters)
237+
221238
results[cfl] = np.mean(niters)
222239

223240
file = open('data/results_conv_advection.pkl', 'wb')
@@ -227,7 +244,13 @@ def run_advection():
227244
assert os.path.isfile('data/results_conv_advection.pkl'), 'ERROR: pickle did not create file'
228245

229246

230-
def plot_results():
247+
def plot_results(nsweeps):
248+
"""
249+
Plotting routine for iteration counts
250+
251+
Args:
252+
nsweeps: number of fine sweeps used
253+
"""
231254

232255
file = open('data/results_conv_diffusion.pkl', 'rb')
233256
results_diff = pickle.load(file)
@@ -269,18 +292,16 @@ def plot_results():
269292
# plot
270293
plt.semilogx(xvalues_diff, niter_diff, 'r-', marker='s', markersize=10, label='diffusion')
271294
plt.semilogx(xvalues_adv, niter_adv, 'b-', marker='o', markersize=10, label='advection')
272-
# plt.plot()
273295

274296
plt.legend(loc=1, ncol=1, numpoints=1)
275297

276298
# plt.show()
277299
# save plot, beautify
278-
fname = 'data/conv_test_niter.png'
300+
fname = 'data/conv_test_niter_NS' + str(nsweeps) + '.png'
279301
plt.savefig(fname, rasterized=True, bbox_inches='tight')
280302

281303
assert os.path.isfile(fname), 'ERROR: plotting did not create file'
282304

283305

284306
if __name__ == "__main__":
285307
main()
286-
plot_results()
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import numpy as np
2+
import scipy.linalg as LA
3+
4+
import matplotlib
5+
matplotlib.use('Agg')
6+
import matplotlib.pylab as plt
7+
from matplotlib import rc
8+
9+
from pySDC.implementations.collocation_classes.gauss_radau_right import CollGaussRadau_Right
10+
11+
12+
def compute_and_plot_specrad(Nnodes, lam):
13+
"""
14+
Compute and plot the spectral radius of the smoother for different step-sizes
15+
16+
Args:
17+
Nnodes: number of collocation nodes
18+
lam: test parameter representing the spatial problem
19+
"""
20+
21+
coll = CollGaussRadau_Right(Nnodes, 0, 1)
22+
Qmat = coll.Qmat[1:, 1:]
23+
24+
# do LU decomposition of QT (St. Martin's trick)
25+
QT = coll.Qmat[1:, 1:].T
26+
[_, _, U] = LA.lu(QT, overwrite_a=True)
27+
QDmat = U.T
28+
29+
Nmat = np.zeros((Nnodes, Nnodes))
30+
Nmat[:, -1] = 1
31+
32+
Nsteps_list = [64, 256]
33+
color_list = ['red', 'blue']
34+
marker_list = ['s', 'o']
35+
36+
setup_list = zip(Nsteps_list, color_list, marker_list)
37+
38+
xlist = [0.1 ** i for i in range(11)]
39+
40+
plt.subplots(figsize=(15, 10))
41+
rc('font', **{"sans-serif": ["Arial"], "size": 24})
42+
rc('legend', fontsize='small')
43+
rc('xtick', labelsize='small')
44+
rc('ytick', labelsize='small')
45+
46+
for Nsteps, color, marker in setup_list:
47+
48+
Emat = np.zeros((Nsteps, Nsteps))
49+
np.fill_diagonal(Emat[1:, :], 1)
50+
51+
Prho_list = []
52+
predict_list = []
53+
for x in xlist:
54+
55+
mat = np.linalg.inv(np.eye(Nnodes * Nsteps) - x * lam * np.kron(np.eye(Nsteps), QDmat)).dot(
56+
x * lam * np.kron(np.eye(Nsteps), (Qmat - QDmat)) + np.kron(Emat, Nmat))
57+
58+
Prho_list.append(max(abs(np.linalg.eigvals(mat))))
59+
predict_list.append((1 + x) ** (1.0 - 1.0 / (Nnodes * Nsteps)) * x ** (1.0 / (Nnodes * Nsteps)))
60+
61+
if len(predict_list) > 1:
62+
print(x, predict_list[-1], Prho_list[-1], Prho_list[-2] / Prho_list[-1],
63+
predict_list[-2] / predict_list[-1])
64+
65+
plt.loglog(xlist, Prho_list, linestyle='-', linewidth=3, color=color, marker=marker, markersize=10,
66+
label='spectral radius, L=' + str(Nsteps))
67+
plt.loglog(xlist, [item for item in predict_list], linestyle='--', linewidth=2, color=color, marker=marker,
68+
markersize=10, label='estimate, L=' + str(Nsteps))
69+
70+
ax = plt.gca()
71+
ax.invert_xaxis()
72+
73+
plt.xlabel('time-step size')
74+
plt.ylabel('spectral radius')
75+
plt.legend(loc=3, numpoints=1)
76+
plt.grid()
77+
plt.ylim([1E-02, 1E01])
78+
79+
if type(lam) is complex:
80+
fname = 'data/smoother_specrad_to0_L64+256_M' + str(Nnodes) + 'LU_imag.png'
81+
else:
82+
fname = 'data/smoother_specrad_to0_L64+256_M' + str(Nnodes) + 'LU_real.png'
83+
plt.savefig(fname, rasterized=True, transparent=True, bbox_inches='tight')
84+
85+
86+
if __name__ == "__main__":
87+
compute_and_plot_specrad(Nnodes=3, lam=-1)
88+
compute_and_plot_specrad(Nnodes=3, lam=1j)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import numpy as np
2+
import scipy.linalg as LA
3+
4+
import matplotlib
5+
matplotlib.use('Agg')
6+
import matplotlib.pylab as plt
7+
from matplotlib import rc
8+
9+
from pySDC.implementations.collocation_classes.gauss_radau_right import CollGaussRadau_Right
10+
11+
12+
def compute_and_plot_specrad(Nnodes, lam):
13+
"""
14+
Compute and plot the spectral radius of the smoother for different step-sizes
15+
16+
Args:
17+
Nnodes: number of collocation nodes
18+
lam: test parameter representing the spatial problem
19+
"""
20+
21+
Nsteps = 1
22+
23+
coll = CollGaussRadau_Right(Nnodes, 0, 1)
24+
Qmat = coll.Qmat[1:, 1:]
25+
26+
# do LU decomposition of QT (St. Martin's trick)
27+
QT = coll.Qmat[1:, 1:].T
28+
[_, _, U] = LA.lu(QT, overwrite_a=True)
29+
QDmat = U.T
30+
31+
Nmat = np.zeros((Nnodes, Nnodes))
32+
Nmat[:, -1] = 1
33+
34+
Nsweep_list = [1, Nnodes - 1, Nnodes]
35+
color_list = ['red', 'blue', 'green']
36+
marker_list = ['s', 'o', 'd']
37+
38+
setup_list = zip(Nsweep_list, color_list, marker_list)
39+
40+
xlist = [10 ** i for i in range(11)]
41+
42+
plt.subplots(figsize=(15, 10))
43+
rc('font', **{"sans-serif": ["Arial"], "size": 24})
44+
rc('legend', fontsize='small')
45+
rc('xtick', labelsize='small')
46+
rc('ytick', labelsize='small')
47+
48+
for Nsweeps, color, marker in setup_list:
49+
50+
Emat = np.zeros((Nsteps, Nsteps))
51+
np.fill_diagonal(Emat[1:, :], 1)
52+
53+
Prho_list = []
54+
predict_list = []
55+
for x in xlist:
56+
57+
mat = np.linalg.inv(np.eye(Nnodes * Nsteps) - x * lam * np.kron(np.eye(Nsteps), QDmat)).dot(
58+
x * lam * np.kron(np.eye(Nsteps), (Qmat - QDmat)) + np.kron(Emat, Nmat))
59+
mat = np.linalg.matrix_power(mat, Nsweeps)
60+
61+
Prho_list.append(max(abs(np.linalg.eigvals(mat))))
62+
predict_list.append(1.0 / x)
63+
64+
if len(predict_list) > 1:
65+
print(x, predict_list[-1], Prho_list[-1], Prho_list[-2] / Prho_list[-1],
66+
predict_list[-2] / predict_list[-1])
67+
68+
plt.loglog(xlist, Prho_list, linestyle='-', linewidth=3, color=color, marker=marker, markersize=10,
69+
label='spectral radius, L=' + str(Nsteps))
70+
71+
plt.loglog(xlist, [item / predict_list[0] for item in predict_list], linestyle='--', linewidth=2, color='k',
72+
label='estimate')
73+
74+
plt.xlabel('time-step size')
75+
plt.ylabel('spectral radius')
76+
plt.legend(loc=3, numpoints=1)
77+
plt.grid()
78+
plt.ylim([1E-16, 1E00])
79+
80+
if type(lam) is complex:
81+
fname = 'data/smoother_specrad_toinf_M' + str(Nnodes) + '_LU_imag.png'
82+
else:
83+
fname = 'data/smoother_specrad_toinf_M' + str(Nnodes) + '_LU_real.png'
84+
plt.savefig(fname, rasterized=True, transparent=True, bbox_inches='tight')
85+
86+
87+
if __name__ == "__main__":
88+
89+
compute_and_plot_specrad(Nnodes=3, lam=-1)
90+
compute_and_plot_specrad(Nnodes=3, lam=1j)
91+
compute_and_plot_specrad(Nnodes=7, lam=-1)
92+
compute_and_plot_specrad(Nnodes=7, lam=1j)

0 commit comments

Comments
 (0)