import scipy as sp
import numpy as np
import scipy.sparse as sparse
import scipy.sparse.linalg as sla
import matplotlib.pyplot as plt
%matplotlib inline
import stencil
import diffusion
def hnorm(r):
"""define ||r||_h = h ||r||_2"""
n = len(r)
h = 1.0 / (n+1)
hrnorm = h * np.linalg.norm(r)
return hrnorm
def interpolation1d(nc, nf):
d = np.repeat([[1, 2, 1]], nc, axis=0).T
I = np.zeros((3,nc))
for i in range(nc):
I[:,i] = [2*i, 2*i+1, 2*i+2]
J = np.repeat([np.arange(nc)], 3, axis=0)
P = sparse.coo_matrix(
(d.ravel(), (I.ravel(), J.ravel()))
).tocsr()
return 0.5 * P
def relax(A, u, f, nu):
DE = sparse.tril(A).tocsc()
for i in range(nu):
u = u + sla.spsolve(DE, f - A * u, permc_spec='NATURAL')
return u
def create_operator(n, sten):
A = stencil.stencil_grid(sten, (n,n), format='csr')
return A
sten = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
A = create_operator(2**3-1, sten)
#print(A.toarray())
#plt.figure(figsize=(8,8))
#plt.spy(A, marker='s', markersize=6)
k = 5
n = 2**k - 1
u = np.random.rand(n*n)
f = np.zeros(n*n)
sten = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
A = create_operator(n, sten)
plt.figure()
plt.pcolor(u.reshape(n,n))
plt.colorbar()
u = relax(A, u, f, 100)
plt.figure()
plt.pcolor(u.reshape(n,n))
plt.colorbar()
k = 5
nc= 2**(k-1) - 1
n = 2**k - 1
x1d = np.linspace(0,1,nc+2)[1:-1]
X, Y = np.meshgrid(x1d, x1d)
uc = np.sin(np.pi * X) * np.sin(np.pi * Y)
uc = uc.ravel()
plt.figure()
plt.pcolor(uc.reshape(nc, nc))
plt.colorbar()
P1d = interpolation1d(nc, n)
P = sparse.kron(P1d, P1d)
u = P * uc
plt.figure()
plt.pcolor(u.reshape(n,n))
plt.colorbar()
k = 5
nc= 2**(k-1) - 1
n = 2**k - 1
x1d = np.linspace(0,1,n+2)[1:-1]
X, Y = np.meshgrid(x1d, x1d)
u = np.sin(np.pi * X) * np.sin(np.pi * Y)
plt.figure()
plt.pcolor(u)
plt.colorbar()
P = interpolation1d(nc, n)
uc = 0.5 * P.T * u
plt.figure()
plt.pcolor(uc)
plt.colorbar()
k = 5
n = 2**k - 1
nc = 2**(k-1) - 1
sten = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
A = create_operator(n, sten)
P1d = interpolation1d(nc, n)
P = sparse.kron(P1d, P1d).tocsr()
u = np.random.rand(n*n)
f = np.zeros((n*n,))
print(hnorm(f - A * u))
u = relax(A, u, f, 1)
fc = P.T * (f - A * u)
Ac = P.T * A * P
uc = sla.spsolve(Ac, fc)
u = u + P * uc
u = relax(A, u, f, 1)
print(hnorm(f - A * u))
u = relax(A, u, f, 1)
fc = P.T * (f - A * u)
Ac = P.T * A * P
uc = sla.spsolve(Ac, fc)
u = u + P * uc
u = relax(A, u, f, 1)
print(hnorm(f - A * u))
def twogrid(A, P, Ac, u, f, nu):
u = relax(A, u, f, nu)
fc = P.T * (f - A * u)
uc = sla.spsolve(Ac, fc)
u = u + P * uc
u = relax(A, u, f, nu)
return u
k = 6
n = 2**k - 1
nc = 2**(k-1) - 1
#sten = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
sten = diffusion.diffusion_stencil_2d(epsilon=0.00001, theta=0, type='FD')
A = (n+1)**2 * create_operator(n, sten)
P1d = interpolation1d(nc, n)
P = sparse.kron(P1d, P1d).tocsr()
u = np.random.rand(n*n)
f = np.zeros((n*n,))
A1 = P.T * A * P
res = [hnorm(f - A * u)]
for i in range(10):
u = twogrid(A, P, A1, u, f, 2)
res.append(hnorm(f - A * u))
res = np.array(res)
print(res[1:] / res[:-1])
res
k = 8
n = 2**k - 1
nc = 2**(k-1) - 1
sten = diffusion.diffusion_stencil_2d(epsilon=0.001, theta=0, type='FD')
print(sten)
A = (n+1)**2 * create_operator(n, sten)
P1d = interpolation1d(nc, n)
P = sparse.kron(P1d, P1d).tocsr()
u = np.random.rand(n*n)
f = np.zeros((n*n,))
plt.figure()
plt.pcolormesh(u.reshape(n,n))
plt.colorbar()
u = relax(A, u, f, 15)
plt.figure()
plt.pcolormesh(u.reshape(n,n))
plt.colorbar()