with initial conditions: $$ u(x,y,0)=f(x,y), u_t(x,y,0)=g(x,y)$$ and homogeneous Neumann boundary condition: $$\vec n\cdot \nabla u|_{\partial \Omega}=0$$
discretization: $u(t_m,x_i,y_j)= U^m_{i,j}$
Equations \begin{eqnarray} \frac{\partial^2 u}{\partial t^2} &\sim& \frac{U^{k+1}_{i,j}-2U^k_{i,j}+U^{k-1}_{i,j}}{\triangle t^2}\\ \frac{\partial^2 u}{\partial x^2} &\sim& \frac{ U^k_{i+1,j}-2U^k_{i,j}+U^k_{i-1,j}}{\triangle x^2}\\ \frac{\partial^2 u}{\partial y^2} &\sim& \frac{ U^k_{i,j+1}-2U^k_{i,j}+U^k{i,j-1}}{\triangle y^2}\\ \frac{U^{k+1}_{i,j}-2U^k_{i,j}+U^{k-1}_{i,j}}{\triangle t^2} &=& c^2\left( \frac{ U^k_{i+1,j}-2U^k_{i,j}+U^k_{i-1,j}}{\triangle x^2}+ \frac{ U^k_{i,j+1}-2U^k_{i,j}+U^k_{i,j-1}}{\triangle y^2} \right) \end{eqnarray}
scheme (main steps): \begin{eqnarray} \gamma_x,\gamma_y,\gamma &=& \frac{c\Delta t}{\Delta x}, \frac{c\Delta t}{\Delta y}, 2(1-\gamma_x^2-\gamma_y^2)\\ U_{i,j}^{k+1} &=& \gamma U_{i,j}^k+\gamma_x^2[U^k_{i,j+1}+U^k_{i,j-1}]+\gamma_y^2[U_{i+1,j}^k+U_{i-1,j}^k]-U_{i,j}^{k-1} \end{eqnarray}
Initial Condition, $ u(x,y,0)=f(x,y), u_t(x,y,0)=g(x,y)$: \begin{eqnarray} U_{i,j}^0 &=& f_{i,j},\quad \frac{U_{ij}^1-U_{i,j}^{-1}}{2\Delta t}=g_{i,j}\\ \to U_{i,j}^{-1} &=& U_{i,j}^1 - 2\Delta t g_{i,j} \\ \frac{2 U_{i,j}^{1}-2f_{i,j}-2\Delta t g_{i,j}}{\Delta t^2} &=& c^2\left( \frac{f_{i,j+1}-2f_{i,j}+f_{i,j-1}}{\Delta x^2} +\frac{f_{i+1,j}-2f_{i,j}+f_{i-1,j}}{\Delta y^2}\right) \\ U_{i,j}^1 &=& \frac{\gamma}{2}f_{i,j}+\frac{\gamma_x^2}{2}(f_{i,j+1}+f_{i,j-1}) +\frac{\gamma_y^2}{2}(f_{i+1,j} +f_{i-1,j})+\Delta t g_{i,j} \\ \end{eqnarray}
In [ ]:
In [24]:
from sympy import Symbol,symbols,solve,simplify,init_printing
from sympy.physics.mechanics import dynamicsymbols
In [2]:
def WaveScheme():
ut0,ut1,ut2=symbols("ut0 ut1 ut2")
ux=symbols('ux:' + str(3))
uy=symbols('uy:' + str(3))
dt,dx,dy,u,s=symbols("dt dx dy u s")
i,j,k=symbols("i j k", type=int)
EqS=(ut0-2*u+ut2)/dt**2.-((ux[0]-2*u+ux[2])/dx**2.+(uy[0]-2*u+uy[2])/dy**2.)
result=solve(EqS,ut2)
result1=result[0].subs({ut0:str('U(i,j,k-1)'),u:str('U(i,j,k)'),ux[0]:str('U(i-1,j,k)'),ux[2]:str('U(i+1,j,k)'), \
uy[0]:str('U(i,j-1,k)'),uy[2]:str('U(i,j+1,k)')})
#result=solve(EqS1,ut2)
return result1
In [22]:
def WaveScheme2(c):
ut0,ut1,ut2=symbols("ut0 ut1 ut2")
ux=symbols('ux:' + str(3))
uy=symbols('uy:' + str(3))
dt,dx,dy,u,s=symbols("dt dx dy u s")
i,j,k=symbols("i j k")
dudt2=(ut0-2*u+ut2)/dt**2.
dudx2=(ux[0]-2*u+ux[2])/dx**2.+(uy[0]-2*u+uy[2])/dy**2.
EqS=dudt2-c**2*dudx2
result=solve(EqS,ut2)
result1=result[0].subs({ut0:str('U(i,j,k-1)'),u:str('U(i,j,k)'),ux[0]:str('U(i-1,j,k)'),ux[2]:str('U(i+1,j,k)'), \
uy[0]:str('U(i,j-1,k)'),uy[2]:str('U(i,j+1,k)')})
#result=solve(EqS1,ut2)
return result1
In [18]:
init_printing(True)
scheme1=WaveScheme();scheme1
Out[18]:
In [25]:
init_printing(True)
c=Symbol("c")
scheme1=WaveScheme2(c);scheme1
Out[25]:
In [21]:
In [ ]:
In [3]:
%pylab inline
import numpy as np
import matplotlib.pyplot as plt
from numpy import exp,sin,pi
from matplotlib import animation
from JSAnimation import IPython_display
import time
In [2]:
def MainScheme(uk,ukm1,dt,dx,c):
gx2 = c*dt/dx
gy2 = c*dt/dy
gamma = 2*(1 - gx2 - gy2)
u[:,:,1] = 0.5*gamma*uk-dt-ulm1
u[1:-1,1:-1,1] += 0.5*gx2*(uk[1:-1,2:]+uk[1:-1,:-2])
u[1:-1,1:-1,1] += 0.5*gy2*(uk[:-2,1:-1]+uk[2:,1:-1])
return u
In [2]:
class wave2d(object):
def __init__(self,height,width,T,nx,ny,nt,c):
self.x = np.linspace(-0.5*width,0.5*width,nx+1)
self.y = np.linspace(-0.5*height,0.5*height,ny+1)
self.t = np.linspace(0,T,nt+1)
self.dx = self.x[1]-self.x[0]
self.dy = self.y[1]-self.y[0]
self.dt = self.t[1]-self.t[0]
self.xx,self.yy = np.meshgrid(self.x,self.y)
# Gamma_x squared
self.gx2 = c*self.dt/self.dx
# Gamma_y squared
self.gy2 = c*self.dt/self.dy
# 2*(1-gamma_x^2-gamma_y^2)
self.gamma = 2*(1 - self.gx2 - self.gy2)
def solve(self,ffun,gfun):
#f = ffun(self.xx,self.yy)
f = ffun(self.xx,self.yy)
g = gfun(self.xx,self.yy)
u = np.zeros((ny+1,nx+1,nt+1))
# Set initial condition
u[:,:,0] = f
U= np.copy( u[:,:,0])
""" Compute first time step """
u[:,:,1] = 0.5*self.gamma*f+self.dt*g
u[1:-1,1:-1,1] += 0.5*self.gx2*(f[1:-1,2:]+f[1:-1,:-2])
u[1:-1,1:-1,1] += 0.5*self.gy2*(f[:-2,1:-1]+f[2:,1:-1])
for k in range(1,nt):
# Every point contains these terms
u[:,:,k+1] = self.gamma*u[:,:,k] - u[:,:,k-1]
# Interior points
u[1:-1,1:-1,k+1] += self.gx2*(u[1:-1,2:,k]+u[1:-1,:-2,k]) + \
self.gy2*(u[2:,1:-1,k]+u[:-2,1:-1,k])
# Top boundary
u[0,1:-1,k+1] += 2*self.gy2*u[1,1:-1,k] + \
self.gx2*(u[0,2:,k]+u[0,:-2,k])
# Right boundary
u[1:-1,-1,k+1] += 2*self.gx2*u[1:-1,-2,k] + \
self.gy2*(u[2:,-1,k]+u[:-2,-1,k])
# Bottom boundary
u[-1,1:-1,k+1] += 2*self.gy2*u[-2,1:-1,k] + \
self.gx2*(u[-1,2:,k]+u[-1,:-2,k])
# Left boundary
u[1:-1,0,k+1] += 2*self.gx2*u[1:-1,1,k] + \
self.gy2*(u[2:,0,k]+u[:-2,0,k])
# Top right corner
u[0,-1,k+1] += 2*self.gx2*u[0,-2,k] + \
2*self.gy2*u[1,-1,k]
# Bottom right corner
u[-1,-1,k+1] += 2*self.gx2*u[-1,-2,k] + \
2*self.gy2*u[-2,-1,k]
# Bottom left corner
u[-1,0,k+1] += 2*self.gx2*u[-1,1,k] + \
2*self.gy2*u[-2,0,k]
# Top left corner
u[0,0,k+1] += 2*self.gx2*u[0,1,k] + \
2*self.gy2*u[1,0,k]
return u
In [3]:
class wave2dR(object):
def __init__(self,height,width,T,nx,ny,nt,c):
self.x = np.linspace(-0.5*width,0.5*width,nx+1)
self.y = np.linspace(-0.5*height,0.5*height,ny+1)
self.t = np.linspace(0,T,nt+1)
self.dx = self.x[1]-self.x[0]
self.dy = self.y[1]-self.y[0]
self.dt = self.t[1]-self.t[0]
self.xx,self.yy = np.meshgrid(self.x,self.y)
# Gamma_x squared
self.gx2 = c*self.dt/self.dx
# Gamma_y squared
self.gy2 = c*self.dt/self.dy
# 2*(1-gamma_x^2-gamma_y^2)
self.gamma = 2*(1 - self.gx2 - self.gy2)
def solve(self,ffun,gfun):
#f = ffun(self.xx,self.yy)
f = ffun(self.xx,self.yy)
g = gfun(self.xx,self.yy)
u = np.zeros((ny+1,nx+1,nt+1))
# Set initial condition
u[:,:,0] = f
""" Compute first time step """
u[:,:,1] = 0.5*self.gamma*f+self.dt*g
u[1:-1,1:-1,1] += 0.5*self.gx2*(f[1:-1,2:]+f[1:-1,:-2])
u[1:-1,1:-1,1] += 0.5*self.gy2*(f[:-2,1:-1]+f[2:,1:-1])
yo,xo = np.ogrid[-ny/2:ny-ny/2+1, -nx/2:nx-nx/2+1]
mask = xo**2 + yo**2 >= nx*nx/4
array = u[:,:,1]
array[mask] = 0.
u[:,:,1] = array
print(len(u[:,:,1]))
for k in range(1,nt):
# Every point contains these terms
u[:,:,k+1] = self.gamma*u[:,:,k] - u[:,:,k-1]
# Interior points
u[1:-1,1:-1,k+1] += self.gx2*(u[1:-1,2:,k]+u[1:-1,:-2,k]) + \
self.gy2*(u[2:,1:-1,k]+u[:-2,1:-1,k])
#UU= u[:,:,k+1]
#UU[mask]=0.
#u[:,:,k+1]=UU
u[mask,k+1]=0.
return u
In [16]:
T = 4
height = 2
width = 4
c = 1
nt = 800
nx = 250
ny = 125
In [18]:
nt=800
wave_eq = wave2d(height,width,T,nx,ny,nt,c)
# Initial value functions
f = lambda x,y: np.exp(-10*(x**2+y**2))
g = lambda x,y: 0
u = wave_eq.solve(f,g)
In [19]:
x = wave_eq.x
y = wave_eq.y
plt.imshow(u[:,:,-1],extent=[x[0],x[-1],y[0],y[-1]])
Out[19]:
In [28]:
dx=width/float(nx)
dy=height/float(ny)
sqrt(1/c**2*dx**2*dy**2/(dx**2+dy**2)/2.)
Out[28]:
In [26]:
4/800.
Out[26]:
In [ ]:
In [20]:
anim = plt.figure(figsize=(16,8))
ax = anim.add_subplot(111)
#ax = anim.add_subplot(111)
#ax.set_title("2D Wave Equation",fontsize=14)
T = 4
height = 2
width = 4
c = 1
nt = 800
nx = 250
ny = 125
wave_eq = wave2d(height,width,T,nx,ny,nt,c)
# Initial value functions
f = lambda x,y: np.exp(-10*(x**2+y**2))
g = lambda x,y: 0
u = wave_eq.solve(f,g)
x = wave_eq.x
y = wave_eq.y
def init():
return ax.imshow(u[:,:,0],vmin=0,vmax=1,extent=[x[0],x[-1],y[0],y[-1]])
def animate(i):
return ax.imshow(u[:,:,10*i],vmin=0,vmax=1,extent=[x[0],x[-1],y[0],y[-1]])
animation.FuncAnimation(anim, animate, init_func=init, frames=nt/10, interval=5)
Out[20]:
In [167]:
In [ ]:
In [10]:
T = 1
height = 4
width = 4
c = 1
nt = 200
nx = 250
ny = 250
In [11]:
#wave_eq = wave2dR(height,width,T,nx,ny,nt,c)
# Initial value functions
#f = lambda x,y: np.exp(-x**2.-y**2.)-1. if x**2.+y**2.<=4. else 0;
#"""
"""
def f(x,y):
U=0*x
if (np.any((x)**2+(y)**2)<=4):
U=np.exp(-(x)**2.-(y)**2.)-exp(-4)
return U
"""
def f(x,y):
R=x**2+y**2
U=np.cos(np.pi*np.sqrt((x)**2.+(y)**2.)/4.)
U[R>=2.]=0
return U
g = lambda x,y: 0
#def g(x,y): return 0.
wave_eq = wave2dR(height,width,T,nx,ny,nt,c)
u = wave_eq.solve(f,g)
In [17]:
x = wave_eq.x
y = wave_eq.y
plt.imshow(u[:,:,50],extent=[x[0],x[-1],y[0],y[-1]])
plt.colorbar()
Out[17]:
In [49]:
13952/251
Out[49]:
In [3]:
xx=np.linspace(-0.5*width,0.5*width,nx+1)
yy=np.linspace(-0.5*width,0.5*width,nx+1)
xm,ym = np.meshgrid(xx,yy)
mask= xm**2+ym**2
mask=np.meshgrid(xx,yy)
In [6]:
n=7
r=3
y,x = np.ogrid[-r:n-r, -r:n-r]
mask = x*x + y*y <= r*r
arr=array*5
array = np.ones((n, n))
array[mask] = 255
array
Out[6]:
In [23]:
nx=12
r=3
y,x = np.ogrid[-nx/2:nx-nx/2+1, -nx/2:nx-nx/2+1]
mask = x*x + y*y >= nx/2*nx/2
array = np.ones((nx+1, nx+1))
array[mask] = 0
array
Out[23]:
In [24]:
x*x
Out[24]:
In [9]:
anim = plt.figure(figsize=(16,8))
ax = anim.add_subplot(111)
#ax = anim.add_subplot(111)
#ax.set_title("2D Wave Equation",fontsize=14)
T=8
nt=int(T/0.005)
height = 4
width = 4
c = 1
nx = 400
ny = 400
wave_eq = wave2dR(height,width,T,nx,ny,nt,c)
# Initial value functions
def f(x,y):
R=x**2+y**2
U=np.cos(np.pi*np.sqrt((x)**2.+(y)**2.)/4.)
U[R>=2.]=0
return U
g = lambda x,y: 0
#def g(x,y): return 0.
u = wave_eq.solve(f,g)
x = wave_eq.x
y = wave_eq.y
frate=nt/40
def init():
#return ax.imshow(u[:,:,0],vmin=-2,vmax=2,extent=[x[0],x[-1],y[0],y[-1]])
return ax.imshow(u[:,:,0],vmin=-1,vmax=1,extent=[x[0],x[-1],y[0],y[-1]])
def animate(i):
return ax.imshow(u[:,:,i*frate],vmin=-1,vmax=1,extent=[x[0],x[-1],y[0],y[-1]])
animation.FuncAnimation(anim, animate, init_func=init, frames=nt/frate, interval=100)
Out[9]: