Skip to content

Commit 6804af0

Browse files
author
Daniel Ruprecht
committed
Merge branch 'master' of github.com:Parallel-in-Time/pyParareal
2 parents 234b895 + c795cc7 commit 6804af0

14 files changed

+720
-87
lines changed

README.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,43 @@
1-
# pyParareal
2-
Python Parareal code for rapid protoyping
1+
pyParareal
2+
============
3+
4+
Python Parareal code to analyse Parareal's wave propagation characteristics.
5+
6+
Attribution
7+
-----------
8+
You can freely use and reuse this code in line with the BSD license.
9+
If you use it (or parts of it) for a publication, please cite
10+
11+
@unpublished{Ruprecht2017,
12+
author = {Ruprecht, Daniel},
13+
title = {{Wave propagation characteristics of Parareal}},
14+
year = {2017}
15+
}
16+
17+
(this will be updated once published).
18+
19+
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.228104.svg)](https://doi.org/10.5281/zenodo.228104)
20+
21+
How can I reproduce Figures from the publication?
22+
-----------------
23+
24+
- Fig. 1 --> scripts/plot_dispersion.py with different parameters
25+
- Fig. 2 --> example/run.py
26+
- Fig. 3 --> scripts/plot_ieuler_dispersion.py
27+
- Fig. 4 --> scripts/plot_dispersion.py with approx_symbol=True
28+
- Fig. 5 --> scripts/plot_dispersion.py with artificial_coarse=1 or 2
29+
- Fig. 6 --> example/run.py with artificial_coarse=2
30+
- Fig. 7 --> scripts/plot_svd_vs_waveno_different_G.py
31+
- Fig. 8 --> scripts/plot_dispersion.py with artifical_fine=1
32+
- Fig. 9 --> example/run.py with artifical_fine=1
33+
- Fig. 10 -> scripts/plot_dispersion.py with ncoarse=2
34+
- Fig. 11 -> scripts/plot_dispersion.py with Tend=64
35+
- Fig. 12 -> scripts/plot_svd_vs_P.py
36+
- Fig. 13 -> scripts/plot_conv_vs_waveno.py
37+
- Fig. 14 -> scripts/plot_svd_vs_waveno.py
38+
39+
40+
Who do I talk to?
41+
-----------------
42+
43+
This code is written by [Daniel Ruprecht](http://www.parallelintime.org/groups/leeds.html).

example/run.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# Parts of this code are taken from the PseudoSpectralPython tutorial.
2+
#
3+
# Author: D. Ketcheson
4+
# https://github.com/ketch/PseudoSpectralPython/blob/master/PSPython_01-linear-PDEs.ipynb
5+
#
6+
# The MIT License (MIT)
7+
#
8+
# Copyright (c) 2015 David Ketcheson
9+
#
10+
# Permission is hereby granted, free of charge, to any person obtaining a copy
11+
# of this software and associated documentation files (the "Software"), to deal
12+
# in the Software without restriction, including without limitation the rights
13+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
# copies of the Software, and to permit persons to whom the Software is
15+
# furnished to do so, subject to the following conditions:
16+
#
17+
# The above copyright notice and this permission notice shall be included in all
18+
# copies or substantial portions of the Software.
19+
#
20+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
# SOFTWARE.
27+
28+
import sys
29+
sys.path.append('../src')
30+
import numpy as np
31+
import scipy.sparse as sp
32+
import scipy.linalg as la
33+
34+
from parareal import parareal
35+
from impeuler import impeuler
36+
from intexact import intexact
37+
from trapezoidal import trapezoidal
38+
from special_integrator import special_integrator
39+
from solution_linear import solution_linear
40+
41+
import matplotlib.pyplot as plt
42+
from subprocess import call
43+
from pylab import rcParams
44+
45+
from joblib import Parallel, delayed
46+
47+
# advection speed
48+
uadv = 1.0
49+
50+
# diffusivity parameter
51+
nu = 0.0
52+
53+
# Spatial grid
54+
m = 64 # Number of grid points in space
55+
L = 4.0 # Width of spatial domain
56+
57+
# select coarse integrator:
58+
# 0 = normal backward Euler method
59+
# 1 = artificially constructed method with phase error from backward Euler and exact amplification factor
60+
# 2 = artificially constructed method with exact phase and amplification factor from backward Euler
61+
artificial_coarse = 0
62+
63+
artificial_fine = 0
64+
65+
# Grid points
66+
x = np.linspace(0, L, m, endpoint=False)
67+
# Grid spacing
68+
dx = x[1]-x[0]
69+
70+
# Temporal grid
71+
tmax = 16 # Final time
72+
#N = 100 # number grid points in time
73+
#dt = tmax/float(N)
74+
nproc = int(tmax)
75+
76+
Kiter_v = [5, 10, 15]
77+
78+
xi = np.fft.fftfreq(m)*m*2*np.pi/L # Wavenumber "grid"
79+
# (this is the order in which numpy's FFT gives the frequencies)
80+
81+
# define spatial operator matrix
82+
D = -1j*xi*uadv - nu*xi**2
83+
84+
# Initial data
85+
sig = 1.0
86+
u = np.exp(-(x-0.5*L)**2/sig**2)
87+
u = np.exp(2.0*np.pi*1j*x)
88+
uhat0 = np.fft.fft(u)
89+
90+
yend = np.zeros((3,m), dtype='complex')
91+
92+
### Because the exact integrator can only deal with scalar problems, we will need to solve
93+
### to initial value problem for each wave number independently
94+
### ...we use the JobLib module to speed up the computational
95+
def run_parareal(uhat, D, k):
96+
sol = solution_linear(np.asarray([[uhat]]), np.asarray([[D]]))
97+
para = parareal(tstart=0.0, tend=tmax, nslices=nproc, fine=intexact, coarse=impeuler, nsteps_fine=10, nsteps_coarse=1, tolerance=0.0, iter_max=k, u0 = sol)
98+
stab_coarse = para.timemesh.slices[0].get_coarse_update_matrix(sol)
99+
stab_ex = np.exp(D)
100+
101+
if artificial_coarse==2:
102+
stab_tailor = abs(stab_coarse[0,0])*np.exp(1j*np.angle(stab_ex)) # exact phase speed
103+
elif artificial_coarse==1:
104+
stab_tailor = abs(stab_ex)*np.exp(1j*np.angle(stab_coarse[0,0])) # exact amplification factor
105+
106+
if not artificial_coarse == 0:
107+
stab_tailor = sp.csc_matrix(np.array([stab_tailor], dtype='complex'))
108+
para = parareal(tstart=0.0, tend=tmax, nslices=nproc, fine=intexact, coarse=stab_tailor, nsteps_fine=10, nsteps_coarse=1, tolerance=0.0, iter_max=k, u0 = sol)
109+
110+
if artificial_fine==1:
111+
assert artificial_coarse==0, "Using artifical coarse and fine propagators together is not implemented and probably not working correctly"
112+
stab_fine = abs(stab_ex)*np.exp(1j*np.angle(stab_coarse[0,0]))
113+
stab_fine = sp.csc_matrix(np.array([stab_fine], dtype='complex'))
114+
# Must use nfine=1 in this case
115+
para = parareal(tstart=0.0, tend=tmax, nslices=nproc, fine=stab_fine, coarse=impeuler, nsteps_fine=1, nsteps_coarse=1, tolerance=0.0, iter_max=k, u0 = sol)
116+
117+
para.run()
118+
temp = para.get_last_end_value()
119+
return temp.y[0,0]
120+
121+
for k in range(0,3):
122+
temp = Parallel(n_jobs=2, verbose=5)(delayed(run_parareal)(uhat0[n],D[n], Kiter_v[k]) for n in range(m))
123+
yend[k,:] = temp
124+
125+
rcParams['figure.figsize'] = 2.5, 2.5
126+
fs = 8
127+
fig1 = plt.figure()
128+
plt.plot(x, np.fft.ifft(yend[0,:]).real, '-s', color='r', linewidth=1.5, label='Parareal k='+str(Kiter_v[0]), markevery=(1,6), mew=1.0, markersize=fs/2)
129+
plt.plot(x, np.fft.ifft(yend[1,:]).real, '-d', color='r', linewidth=1.5, label='Parareal k='+str(Kiter_v[1]), markevery=(3,6), mew=1.0, markersize=fs/2)
130+
plt.plot(x, np.fft.ifft(yend[2,:]).real, '-x', color='r', linewidth=1.5, label='Parareal k='+str(Kiter_v[2]), markevery=(5,6), mew=1.0, markersize=fs/2)
131+
plt.plot(x, np.fft.ifft(uhat0).real, '--', color='k', linewidth=1.5, label='Exact')
132+
plt.xlim([x[0], x[-1]])
133+
plt.ylim([-.2, 1.4])
134+
plt.xlabel('x', fontsize=fs, labelpad=0.25)
135+
plt.ylabel('u', fontsize=fs, labelpad=0.5)
136+
fig1.gca().tick_params(axis='both', labelsize=fs)
137+
plt.legend(loc='upper left', fontsize=fs, prop={'size':fs-2})
138+
#plt.show()
139+
filename = 'parareal-gauss-peak.pdf'
140+
plt.gcf().savefig(filename, bbox_inches='tight')
141+
call(["pdfcrop", filename, filename])
142+
143+
xi = np.fft.fftshift(xi)
144+
xi = xi[m/2:m]/m
145+
uhat0 = np.fft.fftshift(uhat0)
146+
yend[0,:] = np.around(np.fft.fftshift(yend[0,:]), 10)
147+
yend[1,:] = np.around(np.fft.fftshift(yend[1,:]), 10)
148+
yend[2,:] = np.around(np.fft.fftshift(yend[2,:]), 10)
149+
150+
fig2 = plt.figure()
151+
plt.semilogy(xi, np.absolute(uhat0[m/2:m])/m, '--', color='k', linewidth=1.5, label='Exact')
152+
plt.semilogy(xi, np.absolute(yend[0,m/2:m])/m, '-s', color='r', linewidth=1.5, label='Parareal k='+str(Kiter_v[0]), markevery=(1,3), mew=1.0, markersize=fs/2)
153+
plt.semilogy(xi, np.absolute(yend[1,m/2:m])/m, '-d', color='r', linewidth=1.5, label='Parareal k='+str(Kiter_v[1]), markevery=(2,3), mew=1.0, markersize=fs/2)
154+
plt.semilogy(xi, np.absolute(yend[2,m/2:m])/m, '-x', color='r', linewidth=1.5, label='Parareal k='+str(Kiter_v[2]), markevery=(3,3), mew=1.0, markersize=fs/2)
155+
plt.xlabel('Wave number', fontsize=fs, labelpad=0.25)
156+
plt.ylabel(r'abs($\hat{u}$)')
157+
plt.xticks([0.0, 0.1, 0.3], fontsize=fs)
158+
plt.xlim([0.0, 0.3])
159+
plt.yticks([1e0, 1e-3, 1e-6, 1e-9, 1e-12], fontsize=fs)
160+
plt.legend(loc='upper right', fontsize=fs, prop={'size':fs-2})
161+
filename = 'parareal-gauss-peak-spectrum.pdf'
162+
plt.gcf().savefig(filename, bbox_inches='tight')
163+
call(["pdfcrop", filename, filename])

scripts/plot_conv_vs_waveno.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def solve_omega(R):
2525
Tend = 16.0
2626
nslices = 16
2727
U_speed = 1.0
28-
nu = 0.0
28+
nu = 0.1
2929
ncoarse = 1
3030
nfine = 1
3131

@@ -78,7 +78,7 @@ def solve_omega(R):
7878
rcParams['figure.figsize'] = 2.5, 2.5
7979
fig = plt.figure()
8080
iter_v = range(1,nslices)
81-
assert np.max(err[:,-1])<1e-14, "For at least one wavenumber, Parareal did not fully converge for niter=nslices"
81+
assert np.max(err[:,-1])<1e-10, ("For at least one wavenumber, Parareal did not fully converge for niter=nslices. Error: %5.3e" % np.max(err[:,-1]))
8282
plt.semilogy(iter_v, err[0,0:-1], 'b-o', label=(r"$\kappa$=%4.2f" % k_vec[0]), markersize=fs/2)
8383
plt.semilogy(iter_v, err[0,0]*np.power(svds[0], iter_v), 'b--')
8484

0 commit comments

Comments
 (0)