我用下面的代码得到了四极势的电场。
for n in range (nx-1):
for m in range (ny-1):
for k in range (nz-1):
Ex[n,m,k] =-( (T[n+1,m,k]-T[n,m,k]) )/((x[n+1]-x[n]));
Ey[n,m,k] =-( (T[n,m+1,k]-T[n,m,k]) )/((y[m+1]-y[m]));
Ez[n,m,k] =-( (T[n,m,k+1]-T[n,m,k]) )/((z[k+1]-z[k]));
return Ex,Ey,Ez, T

这里T是通过数值求解Laplace方程得到的三维势,从图中可以看出红色电极(正)有错误的电场矢量方向(顶部电极的右上、右下),在其他电极中也存在同样的错误。也就是说,负极具有外向电场矢量,该矢量必须是相反的方向。
我也使用了中心差分法,但我得到了相同的数字。你能告诉我我的差异化有什么问题吗?
发布于 2015-05-13 15:24:15
您的问题在于matplotlib解释方向的方式,它本身起源于传统的矩阵索引方式,这与许多人(比如我)的想法相反。具体来说,第一个索引是垂直索引,而第二个索引是水平索引。如果您使用了一个非方形数组,这将清楚地表明您的x和y是向后的。下面的示例说明了渐变(只稍微修改一下)如何给出正确的结果。第一个图显示了实际绘制的内容,它交换了渐变的x和y分量。这个数字(您可以通过运行这个)表明,梯度不是正交的等高线(这是必须的),有时走错方向。
第二个图和第三个图都显示了一种正确的方法来绘制梯度,使用的方法很好,在这种方法中,我们为坐标和正在绘制的东西(无论是quiver还是contour)都有二维数组。在使用meshgrid生成X和Y时,我遵循您的代码,但需要将参数交换给meshgrid以获得正确的维度。一种更简洁的方法是使用相同的编码风格来生成与所绘制的物体相同的坐标,在这种情况下,带有显式索引的while循环是最优的。
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-3,3,0.2)
y = np.arange(-5,5,0.2)
z = np.arange(-5,5,0.2)
def grad(f):
gx = np.zeros_like(f)
gy = np.zeros_like(f)
gz = np.zeros_like(f)
for n in range(1,len(x)-1):
for m in range(1,len(y)-1):
for k in range(1,len(z)-1):
gx[n,m,k] = (T[n+1,m,k]-T[n-1,m,k])/(x[n+1]-x[n-1]);
gy[n,m,k] = (T[n,m+1,k]-T[n,m-1,k])/(y[m+1]-y[m-1]);
gz[n,m,k] = (T[n,m,k+1]-T[n,m,k-1])/(z[k+1]-z[k-1]);
return gx, gy, gz
T = np.zeros((len(x), len(y), len(z)))
for n in range(len(x)):
for m in range(len(y)):
for k in range(len(z)):
T[n,m,k] = np.sin((x[n] - y[m])/3.0) + 0.3*np.cos(y[m]) + z[k]**2
gx,gy,gz = grad(T)
Y, X= np.meshgrid(y,x)
plt.figure('WRONG with x and y')
plt.contour(y, x, T[:,:,round(len(z)/2)], 64)
plt.colorbar()
plt.quiver(y, x, 10*gx[:,:,round(len(z)/2)], 10*gy[:,:,round(len(z)/2)])
plt.xlabel("x")
plt.ylabel("y")
plt.axes().set_aspect('equal')
plt.figure('with X and Y')
plt.contour(X, Y, T[:,:,round(len(z)/2)], 64)
plt.colorbar()
plt.quiver(X, Y, 10*gx[:,:,round(len(z)/2)], 10*gy[:,:,round(len(z)/2)])
plt.xlabel("X")
plt.ylabel("Y")
plt.axes().set_aspect('equal')
plt.figure('with Y and X')
plt.contour(Y, X, T[:,:,round(len(z)/2)], 64)
plt.colorbar()
plt.quiver(Y, X, 10*gy[:,:,round(len(z)/2)], 10*gx[:,:,round(len(z)/2)])
plt.xlabel("Y")
plt.ylabel("X")
plt.axes().set_aspect('equal')
plt.show()最后,我将再次指出,暴露这个bug的最干净的方法是使用nx != ny运行您的程序。如果出现错误消息表示数组尺寸不匹配,代码就会失败,这将导致您以正确的方式交换周围的东西(希望如此)。
https://stackoverflow.com/questions/30216146
复制相似问题