from IPython.core.display import HTML
css_file = './example.css'
HTML(open(css_file, "r").read())
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from clawpack.visclaw.JSAnimation import IPython_display
m=2**8-1 # Number of grid points
h=1./(m+1) # Mesh width
x=np.linspace(0,1,m+2); x=x[1:-1] # grid
alpha=1.; beta=3. # boundary values
phi = lambda x: 20.* np.pi * x**3
f = lambda x: -20 + 0.5*120*np.pi*x * np.cos(phi(x)) - \
0.5*(60*np.pi*x**2)**2 * np.sin(phi(x)) # RHS
plt.plot(x,f(x)); plt.xlabel('x'); plt.ylabel('f(x)')
U=np.linspace(alpha,beta,m) # Just use a straight line as initial guess
UU=[U]
F=0.5*h**2*f(x) # Construct the RHS
F[0]-=alpha/2.; F[-1]-=beta/2. # boundary conditions
e=np.ones(m-1)
G=0.5*(np.diag(e,-1)+np.diag(e,1)) # Jacobi matrix (average neighbors)
for i in range(100):
U=np.dot(G,U) - F
UU.append(U)
xf = np.linspace(0,1,1000);
uf = 1.+12.*xf-10.*xf**2 + 0.5*np.sin(phi(xf)) # Exact solution on fine grid
u = 1.+12.*x-10.*x**2 + 0.5*np.sin(phi(x)) # Exact solution on computational grid
fig = plt.figure()
ax = plt.axes(xlim=(0, 1), ylim=(-3, 6))
ax.plot(xf,uf)
line1, = ax.plot([],[],'-')
line2, = ax.plot([],[],'-o')
plt.legend(['Exact','Jacobi','Error'],loc=2)
def fplot(i):
line1.set_data(x,UU[i])
line2.set_data(x,UU[i]-u)
ax.set_title('# of iterations: '+str(i))
return line1,
animation.FuncAnimation(fig, fplot, frames=range(len(UU)))
M=30; H=1./(M+1)
omegas=np.linspace(0.,1.)
p=np.arange(1,M+1)
fig = plt.figure()
ax = plt.axes(xlim=(0, M), ylim=(0,1))
ax.set_xlabel('p', fontsize=20)
ax.set_ylabel('$\widehat{\gamma}_p$', fontsize=20)
line1, = ax.plot([],[],'o')
def fplot(i):
omega = omegas[i]
gamma = abs(1.+omega*(np.cos(p*np.pi*H)-1))
line1.set_data(p,gamma)
ax.set_title('$\omega = %02.2f $' % omega, fontsize=20)
return line1,
animation.FuncAnimation(fig, fplot, frames=range(50))
omega = 2./3.
U=np.linspace(alpha,beta,m) # Just use a straight line as initial guess
UU=[U]
F=0.5*h**2*f(x)
F[0]-=alpha/2.; F[-1]-=beta/2. # Construct the RHS, including boundary conditions
e=np.ones(m-1)
G=0.5*(np.diag(e,-1)+np.diag(e,1))
niter=100
for i in range(niter):
U=(1.-omega)*U+omega*(np.dot(G,U)-F)
UU.append(U)
xf = np.linspace(0,1,1000);
uf = 1.+12.*xf-10.*xf**2 + 0.5*np.sin(phi(xf)) # Exact solution on fine grid
u = 1.+12.*x-10.*x**2 + 0.5*np.sin(phi(x)) # Exact solution on computational grid
fig = plt.figure()
ax = plt.axes(xlim=(0, 1), ylim=(-3, 6))
ax.plot(xf,uf)
line1, = ax.plot([],[],'-')
line2, = ax.plot([],[],'-o')
plt.legend(['Exact','Jacobi','Error'],loc=2)
def fplot(i):
line1.set_data(x,UU[i])
line2.set_data(x,UU[i]-u)
ax.set_title('# of iterations: '+str(i))
return line1,
animation.FuncAnimation(fig, fplot, frames=range(niter))
from matplotlib import animation
import matplotlib.pyplot as plt
from clawpack.visclaw.JSAnimation import IPython_display
fig = plt.figure()
ax = plt.axes(xlim=(0, 1), ylim=(-1.2, 1.2))
p=5
xf=np.linspace(0,1,1000) # fine grid
line1, = ax.plot(xf, np.sin(p*np.pi*xf), '-r', lw=2)
line2, = ax.plot([],[],'o-',lw=2)
def fplot(m):
x=np.linspace(0,1,m+2); # grid
line2.set_data(x,np.sin(p*np.pi*x))
ax.set_title('m='+str(m))
return line2,
animation.FuncAnimation(fig, fplot, frames=(63,31,15,7,3,1))
def coarsen(f):
return f[1::2] # This slicing just takes the odd-numbered points
def interpolate(f,alpha,beta):
m_coarse=len(f)
m_fine =2*m_coarse+1
f_interp = np.zeros(m_fine)
f_interp[1::2]=f #Set the values of the odd numbered points
f_interp[2:-1:2]=0.5*(f[:-1]+f[1:]) #Set the values of the (interior) even numbered points
f_interp[0]=0.5*(f_interp[1]+alpha) #Set the values of the endpoints
f_interp[-1]=0.5*(f_interp[-2]+beta)
return f_interp
#compute the residual
A=2./h**2*(G-np.eye(m))
F=f(x); F[0]-=alpha/h**2; F[-1]-=beta/h**2
r=F-np.dot(A,U)
print max(abs(r))
omega=2./3.
m2=(m-1)/2. # Number of points in coarse grid
h2=1./(m2+1) # coarse mesh width
x2=coarsen(x) # coarse grid points
r2=coarsen(r) # residual restricted to coarse grid
err2=np.zeros(m2) # initial guess for the error
e2=np.ones(m2-1); G2=0.5*(np.diag(e2,-1)+np.diag(e2,1))
for i in range(3): #Solve Ae=-r by Jacobi iteration
err2=(1.-omega)*err2+omega*(np.dot(G2,err2)+0.5*h2**2*r2)
err=interpolate(err2,0,0) # interpolate the error
print err[0]
U=U-err # and use it to correct our solution
plt.clf()
plt.plot(x,u,x,U,x,U-u)
plt.legend(['Exact','Jacobi','Error'],loc='best')
def Jacobi(U,f,alpha,beta,m,nu):
"""Perform nu Jacobi iterations on a grid with m points, with initial guess U, right hand side function f and
Dirichlet boundary conditions with values alpha and beta. The function returns both the approximate
solution and the residual."""
omega=2./3.
h=1./(m+1)
F=0.5*h**2*f.copy()
F[0]-=alpha/2.; F[-1]-=beta/2.
e=np.ones(m-1)
G=0.5*(np.diag(e,-1)+np.diag(e,1))
for i in range(nu):
U=(1.-omega)*U + omega*(np.dot(G,U)-F)
A=2./h**2*(G-np.eye(m))
FF=f.copy(); FF[0]-=alpha/h**2; FF[-1]-=beta/h**2
rr=FF-np.dot(A,U)
return U,rr
k=8;
m=2**k-1
rdep=k-1 # Recursion depth; this is how many grids down we want to go
# rdep=k-1 gives a full V-cycle
nu=3 # Number of Jacobi iterations to take at each step
U=np.linspace(alpha,beta,m) # Initial guess
x=np.linspace(0,1,m+2); x=x[1:-1] # grid
phi = lambda x: 20.* np.pi * x**3
u = 1.+12.*x-10.*x**2 + 0.5*np.sin(phi(x))
f = lambda x: -20 + 0.5*120*np.pi*x * np.cos(phi(x)) - 0.5*(60*np.pi*x**2)**2 * np.sin(phi(x))
alpha=1.; beta=3.
F=f(x)
r=[None]*(rdep+1); error=[None]*(rdep+1) # This just initializes these lists to have the right length
U,rr=Jacobi(U,F,alpha,beta,m,nu) # Initial iteration on fine grid
for i in range(1,rdep+1): # Going down
m=(m-1)/2 # = 2**(k-i) - 1
r[i]=coarsen(rr) # residual restricted to next coarser grid
error[i],rr=Jacobi(np.zeros(m),-r[i],0.,0.,m,nu)
for i in range(1,rdep): # Coming up
m=2*m+1
err=error[rdep-i]-interpolate(error[rdep+1-i],0,0) # Interpolate and subtract the correction
error[-i-1],rr=Jacobi(err,-r[rdep-i],0.,0.,m,nu)
m=2*m+1
U=U-interpolate(error[1],0,0) # final solution correction
U,rr=Jacobi(U,F,alpha,beta,m,nu) #Final iterations on original grid
plt.clf()
plt.plot(x,u,x,U,'o-',x,U-u)
plt.legend(['Exact','Jacobi','Error'],loc='best')
fig = plt.figure()
ax = plt.axes(xlim=(0, 1), ylim=(-5,5))
line1, = ax.plot([],[],'-ok',lw=2)
def fplot(i):
y = error[-i]
m = len(y)
x=np.linspace(0,1,m+2); x=x[1:-1]
line1.set_data(x,y)
return line1,
animation.FuncAnimation(fig, fplot, frames=range(1,len(error)))
from IPython.display import display, HTML
from IPython.html import widgets
from IPython.html.widgets import interact, interactive
def Jacobi(U,f,alpha,beta,m,nu,omega=2./3):
"""Perform nu Jacobi iterations on a grid with m points, with initial guess U, right hand side function f and
Dirichlet boundary conditions with values alpha and beta. The function returns both the approximate
solution and the residual."""
h=1./(m+1)
F=0.5*h**2*f.copy()
F[0]-=alpha/2.; F[-1]-=beta/2.
e=np.ones(m-1)
G=0.5*(np.diag(e,-1)+np.diag(e,1))
for i in range(nu):
U=(1.-omega)*U + omega*(np.dot(G,U)-F)
A=2./h**2*(G-np.eye(m))
FF=f.copy(); FF[0]-=alpha/h**2; FF[-1]-=beta/h**2
rr=FF-np.dot(A,U)
return U,rr
def Vcycle(k=8,nu=3,omega=2./3,smooth_after_interp=True):
m=2**k-1
rdep=k-1 # Recursion depth; this is how many grids down we want to go
# rdep=k-1 gives a full V-cycle
alpha=1.; beta=3.
U=np.linspace(alpha,beta,m) # Initial guess
x=np.linspace(0,1,m+2); x=x[1:-1] # grid
u = 1.+12.*x-10.*x**2 + 0.5*np.sin(phi(x))
F=f(x)
r=[None]*(rdep+1); error=[None]*(rdep+1) # This just initializes these lists to have the right length
U,rr=Jacobi(U,F,alpha,beta,m,nu,omega) # Initial iteration on fine grid
for i in range(1,rdep+1): # Going down
m=(m-1)/2 # = 2**(k-i) - 1
r[i]=coarsen(rr) # residual restricted to next coarser grid
error[i],rr=Jacobi(np.zeros(m),-r[i],0.,0.,m,nu,omega)
for i in range(1,rdep): # Coming up
m=2*m+1
err=error[rdep-i]-interpolate(error[rdep+1-i],0,0) # Interpolate and subtract the correction
if smooth_after_interp:
error[-i-1],rr=Jacobi(err,-r[rdep-i],0.,0.,m,nu,omega)
else:
error[-i-1] = err
m=2*m+1
U=U-interpolate(error[1],0,0) # final solution correction
U,rr=Jacobi(U,F,alpha,beta,m,nu,omega) #Final iterations on original grid
fig, ax = plt.subplots(figsize=(8,6),subplot_kw={'axisbg':'#EEEEEE',
'axisbelow':True})
ax = plt.axes(xlim=(0, 1), ylim=(-5,6))
ax.plot(x,u,x,U,'o-',x,U-u)
plt.legend(['Exact','Jacobi','Error'],loc='best')
interact(Vcycle, k=(4,10,1), nu=(1,4,1), omega=(0,2,1./6))