Skip to content

Commit b5ebdb5

Browse files
committed
Merge branch 'master' of ssh://github.com:/zingale/hydro_examples
2 parents fd073d4 + 88a17eb commit b5ebdb5

17 files changed

Lines changed: 2096 additions & 1133 deletions

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,12 @@ https://github.com/zingale/pyro2
7575
- `conservative-interpolation.ipynb`: an IPython notebook that
7676
illustrates how to derive high-order conservative interpolants
7777
for finite-volume data.
78-
78+
79+
* `incompressible/`
80+
81+
- `project.py`: a simple example of using a projection to recover
82+
a divergence-free velocity field.
83+
7984
* `multigrid/`
8085

8186
- `mg_converge.py`: a convergence test of the multigrid solver. A
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
from __future__ import print_function
2+
3+
import matplotlib.pyplot as plt
4+
import matplotlib as mpl
5+
import numpy as np
6+
import math
7+
8+
mpl.rcParams['mathtext.fontset'] = 'cm'
9+
mpl.rcParams['mathtext.rm'] = 'serif'
10+
11+
12+
# see: http://glowingpython.blogspot.com/2011/08/how-to-plot-frequency-spectrum-with.html
13+
# and
14+
# http://docs.scipy.org/doc/numpy/reference/routines.fft.html
15+
16+
# Since our input data is real, the negative frequency components
17+
# don't include any new information, and are not interesting to us.
18+
# The rfft routines understand this, and rfft takes n real points and
19+
# returns n/2+1 complex output points. The corresponding inverse
20+
# knows this, and acts accordingly.
21+
#
22+
# these are the routines we want for real valued data
23+
#
24+
# note that the scipy version of rfft returns that data differently
25+
#
26+
# M. Zingale (2013-03-03)
27+
28+
29+
def single_freq_sine(npts, xmax, f_0):
30+
31+
# a pure sine with no phase shift will result in pure imaginary
32+
# signal
33+
34+
xx = np.linspace(0.0, xmax, npts, endpoint=False)
35+
return xx, np.sin(2.0*math.pi*f_0*xx)
36+
37+
def single_freq_sine_plus_shift(npts, xmax, f_0):
38+
39+
# a pure sine with no phase shift will result in pure imaginary
40+
# signal
41+
xx = np.linspace(0.0, xmax, npts, endpoint=False)
42+
return xx, np.sin(2.0*math.pi*f_0*xx + math.pi/4)
43+
44+
def two_freq_sine(npts, xmax, f_0, f_1):
45+
46+
# a pure sine with no phase shift will result in pure imaginary
47+
# signal
48+
xx = np.linspace(0.0, xmax, npts, endpoint=False)
49+
f = 0.5*(np.sin(2.0*math.pi*f_0*xx) + np.sin(2.0*math.pi*f_1*xx))
50+
return xx, f
51+
52+
def single_freq_cosine(npts, xmax, f_0):
53+
54+
# a pure cosine with no phase shift will result in pure real
55+
# signal
56+
xx = np.linspace(0.0, xmax, npts, endpoint=False)
57+
f = np.cos(2.0*math.pi*f_0*xx)
58+
return xx, f
59+
60+
def plot_FFT(xx, xmax, f, outfile):
61+
62+
plt.clf()
63+
64+
plt.rc("font", size=10)
65+
66+
npts = len(xx)
67+
68+
# Forward transform: f(x) -> F(k)
69+
fk = np.fft.rfft(f)
70+
71+
# Normalization -- the '2' here comes from the fact that we are
72+
# neglecting the negative portion of the frequency space, since
73+
# the FFT of a real function contains redundant information, so
74+
# we are only dealing with 1/2 of the frequency space.
75+
#
76+
# technically, we should only scale the 0 bin by N, since k=0 is
77+
# not duplicated -- we won't worry about that for these plots
78+
norm = 2.0/npts
79+
80+
fk = fk*norm
81+
82+
fk_r = fk.real
83+
fk_i = fk.imag
84+
85+
# the fftfreq returns the postive and negative (and 0) frequencies
86+
# the newer versions of numpy (>=1.8) have an rfftfreq() function
87+
# that really does what we want -- we'll use that here.
88+
k = np.fft.rfftfreq(npts)
89+
90+
# to make these dimensional, we need to divide by dx. Note that
91+
# max(xx) is not the true length, since we didn't have a point
92+
# at the endpoint of the domain.
93+
kfreq = k*npts/(max(xx) + xx[1])
94+
95+
# Inverse transform: F(k) -> f(x) -- without the normalization
96+
fkinv = np.fft.irfft(fk/norm)
97+
98+
plt.subplot(411)
99+
100+
plt.plot(xx, f)
101+
plt.xlabel("x")
102+
plt.ylabel("$f(x)$")
103+
104+
plt.xlim(0, xmax)
105+
106+
plt.subplot(412)
107+
108+
plt.plot(kfreq, fk_r, label=r"Re($\mathcal{F}$)")
109+
plt.plot(kfreq, fk_i, ls=":", label=r"Im($\mathcal{F}$)")
110+
plt.xlabel(r"$k$")
111+
plt.ylabel("$\mathcal{F}_k$")
112+
113+
plt.legend(fontsize="small", frameon=False, ncol=2, loc="upper right")
114+
115+
plt.subplot(413)
116+
117+
plt.plot(kfreq, np.abs(fk))
118+
plt.xlabel(r"$k$")
119+
plt.ylabel(r"$|\mathcal{F}_k|$")
120+
121+
122+
plt.subplot(414)
123+
124+
plt.plot(xx, fkinv.real)
125+
plt.xlabel(r"$x$")
126+
plt.ylabel(r"$\mathcal{F}^{-1}(\mathcal{F}_k)$")
127+
128+
plt.xlim(0, xmax)
129+
130+
plt.tight_layout()
131+
132+
plt.savefig(outfile)
133+
134+
135+
136+
#-----------------------------------------------------------------------------
137+
138+
npts = 256 #64 #256
139+
140+
f_0 = 0.2
141+
142+
xmax = 10.0/f_0
143+
144+
# FFT of sine
145+
xx, f = single_freq_sine(npts, xmax, f_0)
146+
plot_FFT(xx, xmax, f, "fft-sine.pdf")
147+
148+
149+
# FFT of cosine
150+
xx, f = single_freq_cosine(npts, xmax, f_0)
151+
plot_FFT(xx, xmax, f, "fft-cosine.pdf")
152+
153+
# FFT of sine with pi/4 phase
154+
xx, f = single_freq_sine_plus_shift(npts, xmax, f_0)
155+
plot_FFT(xx, xmax, f, "fft-sine-phase.pdf")
156+
157+
# FFT of two sines
158+
f_1 = 0.5
159+
xx, f = two_freq_sine(npts, xmax, f_0, f_1)
160+
plot_FFT(xx, xmax, f, "fft-two-sines.pdf")
161+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env python
2+
3+
import matplotlib.pyplot as plt
4+
import matplotlib as mpl
5+
import numpy as np
6+
7+
mpl.rcParams['mathtext.fontset'] = 'cm'
8+
mpl.rcParams['mathtext.rm'] = 'serif'
9+
10+
def f(x):
11+
return np.sin(x)
12+
13+
def fprime(x):
14+
return np.cos(x)
15+
16+
def dfdx(x, dx):
17+
return (f(x+dx) - f(x))/dx
18+
19+
dx = np.logspace(-16.0,-1.0,1000)
20+
21+
x0 = 1.0
22+
23+
eps = abs(dfdx(x0, dx) - fprime(x0))
24+
25+
plt.loglog(dx, eps)
26+
27+
plt.xlabel("$\delta x$")
28+
plt.ylabel("error in difference approximation")
29+
30+
plt.tight_layout()
31+
32+
plt.savefig("deriv_error.pdf")
33+
34+
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import numpy as np
2+
import matplotlib as mpl
3+
import matplotlib.pyplot as plt
4+
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
5+
6+
# old font defaults
7+
mpl.rcParams['mathtext.fontset'] = 'cm'
8+
mpl.rcParams['mathtext.rm'] = 'serif'
9+
10+
11+
x_smooth = np.linspace(0.0, np.pi, 500)
12+
f_smooth = np.sin(x_smooth)
13+
14+
15+
x = np.linspace(0.0, np.pi, 10)
16+
f = np.sin(x)
17+
18+
i = 5
19+
x_0 = x[i]
20+
f_0 = f[i]
21+
22+
plt.plot(x_smooth, f_smooth)
23+
plt.scatter(x, f)
24+
25+
plt.scatter(x_0, np.sin(x_0), color="r", zorder=10)
26+
27+
dx = x[1] - x[0]
28+
x_d = np.linspace(x[i]-1.5*dx, x[i]+1.5*dx, 2)
29+
30+
d_exact = np.cos(x_0)
31+
32+
d_l = (np.sin(x[i]) - np.sin(x[i-1]))/dx
33+
d_r = (np.sin(x[i+1]) - np.sin(x[i]))/dx
34+
d_c = 0.5*(np.sin(x[i+1]) - np.sin(x[i-1]))/dx
35+
36+
37+
# plot a line showing dx
38+
dx = x[2] - x[1]
39+
ann = plt.annotate('', xy=(x[1], f[1]-0.5*dx), xycoords='data',
40+
xytext=(x[2], f[1]-0.5*dx), textcoords='data',
41+
arrowprops=dict(arrowstyle="<->",
42+
connectionstyle="bar,fraction=-0.4",
43+
ec="k",
44+
shrinkA=5, shrinkB=5,
45+
))
46+
47+
plt.text(0.5*(x[1]+x[2]), f[1]-0.8*dx, "$\Delta x$",
48+
horizontalalignment="center")
49+
50+
plt.plot([x[1], x[1]], [f[1]-0.5*dx, f[2]+0.5*dx], ls=":", color="0.5")
51+
plt.plot([x[2], x[2]], [f[1]-0.5*dx, f[2]+0.5*dx], ls=":", color="0.5")
52+
53+
plt.plot(x_d, d_exact*(x_d - x_0) + f_0, color="0.5", lw=2, ls=":", label="exact")
54+
plt.plot(x_d, d_l*(x_d - x_0) + f_0, label="left-sided")
55+
plt.plot(x_d, d_r*(x_d - x_0) + f_0, label="right-sided")
56+
plt.plot(x_d, d_c*(x_d - x_0) + f_0, label="centered")
57+
58+
59+
ax = plt.gca()
60+
61+
62+
# origin of the axes through 0
63+
ax.spines['left'].set_position('zero')
64+
ax.spines['right'].set_color('none')
65+
ax.spines['bottom'].set_position('zero')
66+
ax.spines['top'].set_color('none')
67+
ax.spines['left'].set_smart_bounds(True)
68+
ax.spines['bottom'].set_smart_bounds(True)
69+
ax.xaxis.set_ticks_position('bottom')
70+
ax.yaxis.set_ticks_position('left')
71+
72+
plt.legend(frameon=False, loc="best")
73+
74+
plt.ylim(-0.1, 1.1)
75+
76+
plt.tight_layout()
77+
78+
79+
plt.savefig("derivs.pdf")
80+
81+
82+

0 commit comments

Comments
 (0)