Copyright (C) 2010-2020 Luke Olson
Copyright (C) 2020 Andreas Kloeckner
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
Consider $$ u_t + a u_x = 0$$ with periodic BC on the interval $[0,1]$.
a = 1.0
T = 4.0 / a # end time for four cycles
dx
will be the grid spacing in the $x$-directionx
will be the grid coordinatesxx
will be really fine grid coordinatesnx = 90
k = 1
x = np.linspace(0, 2*np.pi, nx, endpoint=False)
dx = x[1] - x[0]
xx = np.linspace(0, 2*np.pi, 1000, endpoint=False)
Now define an initial condition:
def f(x):
u = np.sin(k * x)
return u
plt.plot(xx, f(xx), lw=3, clip_on=False)
[<matplotlib.lines.Line2D at 0x7f5845513130>]
Now we need a time step. Let $$ \Delta t = \Delta x \frac{\lambda}{a}$$ with CFL number $\lambda$.
lmbda = 0.9
dt = dx * lmbda / a
nt = int(T/dt)
print('T = %g' % T)
print('tsteps = %d' % nt)
print(' dx = %g' % dx)
print(' dt = %g' % dt)
print('lambda = %g' % lmbda)
T = 4 tsteps = 63 dx = 0.0698132 dt = 0.0628319 lambda = 0.9
Make an index list, called $J$, so that we can access $J+1$ and $J-1$ easily.
J = np.arange(0, nx) # all vertices
Jm1 = np.roll(J, 1)
Jp1 = np.roll(J, -1)
plotit = True
uETBS = f(x)
uLW = f(x)
if plotit:
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
ax.set_title('u vs x')
for n in range(0, nt):
uETBS[J] = uETBS[J] - lmbda * (uETBS[J] - uETBS[Jm1])
uLW[J] = uLW[J] - lmbda * (1.0 / 2.0) * (uLW[Jp1] - uLW[Jm1]) \
+ (lmbda**2 / 2.0) * (uLW[Jp1] - 2 * uLW[J] + uLW[Jm1])
uex = f((xx - a * (n+1) * dt) % (2*np.pi))
if plotit:
ax.plot(x, uETBS, '-', clip_on=False, label="ETBS")
#ax.plot(x, uLW, '-', clip_on=False, label="Lax-Wendroff")
ax.plot(xx, uex, 'k-', clip_on=False, label='exact')
ax.legend(frameon=False)
plt.show()