我试图用中心有限差分法求解波动方程。
我从一个基本的二维高斯函数开始作为我的初始条件u[x,y,t] = u[:,:,0] = init_fn(x,y)
这里是我对高斯波脉冲的初始化:
def init_fn(x,y):
return A*(np.exp(-1*((x**2)/stdx**2 + (y**2)/stdy**2)))
这是我的全部代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.animation as animation
dx=1 #space incrementB
dy=1
dt=.5 #time increment #Make sure time increment is smaller than space increment
tmin=0.0 #initial time
tmax=50.0 #simulate until
xmin=-50.0 #left bound
xmax=50.0 #right bound...assume packet never reaches boundary
ymin = -50
ymax = 50
c = 1.0 #speed of sound
rsq1=(c*dt/dx)**2 #appears in finite diff sol for damped and linear damped
rsq2=(c*dt/dy)**2
k = .1
z = 1/(1+ 2*k*dt) #appears in finite diff sol for linear damped
A = 10
nx = int((xmax-xmin)/dx)+1 #number of points on x grid
ny = int((ymax-ymin)/dy)+1
nt = int((tmax-tmin)/dt)+2 #number of points on t grid
u = np.zeros((nx,ny,nt)) #solution to WE
stdx = 20
stdy = 20
#set initial pulse shape
def init_fn(x,y):
return A*(np.exp(-1*((x**2)/stdx**2 + (y**2)/stdy**2)))
for j in range(0,nx):
for m in range (0,ny):
u[j,m,0]=init_fn(xmin + j*dx,ymin + m*dy)
u[j,m,1]=u[j,m,0]
for n in range (1,nt-1):
for j in range(1,nx-1):
for m in range (1,ny-1):
u[j,m,n+1] = rsq1*z*(u[j+1,m,n] + u[j-1,m,n]) + rsq2*z*(u[j,m+1,n]+u[j,m-1,n]) - 2*z* (rsq1+rsq2+1)*u[j,m,n] - z*(1-2*k*dt)*u[j,m,n-1]
x = np.linspace(xmin, xmax, nx)
y = np.linspace(ymin, ymax, ny)
xx, yy = np.meshgrid(x, y)
z = u[:,:,0] #init_fn(xx,yy)
fig, ax = plt.subplots()
p = ax.pcolor(xx, yy, z, cmap=cm.RdBu, vmin=abs(z).min(), vmax=abs(z).max())
cb = fig.colorbar(p, ax=ax)
plt.show()
print u[:,:,0], len(x)
从逻辑上讲,如果我将u[:,:,0]
和init_fn(x,y)
图形化,我应该能够生成相同的图形,因为我将它们设置为彼此相等。但是,输出是不同的。设置z = u[:,:,0]
我得到以下输出:
设置z = init_fn(xx,yy)
我得到以下输出:
我的代码在哪里犯了错误?谢谢。
答案 0 :(得分:0)
问题不在matplotlib
范围内,而是在循环中的某个地方
for j in range(0,nx):
for m in range (0,ny):
u[j,m,0]=init_fn(xmin + j*dx,ymin + m*dy)
u[j,m,1]=u[j,m,0]
您的函数init_fn
由numpy
个函数组成,因此您也可以使用numpy
数组作为输入。这也加快了计算速度:
# as init_fn is defined with numpy functions,
# you can directly call it with your meshgrid
# to initialize the array u[:,:,0] and u[:,:,1]
x = np.linspace(xmin, xmax, nx)
y = np.linspace(ymin, ymax, ny)
xx, yy = np.meshgrid(x, y)
u[:,:,0] = init_fn(xx,yy)
u[:,:,1] = init_fn(xx,yy)
这样做会产生预期的结果。
因此,您在使用init_fn()
函数的循环中遇到问题。我确实检查了你在循环中创建的x,y值是否与meshgrid中的值相同,所以我丢失了错误所在的位置,但是通过使用meshgrid调用init_fn(xx,yy)
来替换循环可以避免问题!