繁体   English   中英

用python计算电场:不断得到索引错误(Python)

[英]Electric field calculation with python: keep getting index error (Python)

我正在使用 python 解决计算物理问题。 预期的输出应该是一个带有小箭头(使用箭袋)的图形,显示带有实心金属内导体的空心金属棱柱内部每个点的电场方向。 在内导体处,电压 = 1,在空心棱柱边界处,电压 = 0。这是我的(有点长)代码:

import matplotlib #plotting libraries
import numpy as np #numerical routines
import matplotlib.mlab as mlab #bridge from python to matlab that lets matlab look like a normal python library
import matplotlib.pyplot as plt #plotting libraries
from mpl_toolkits.mplot3d import Axes3D #3D axes 
from copy import deepcopy #deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original
from pylab import * #plotting and numerical routines 

v = [] #creates list for values of v(i,j)
dx = 0.01
dy = 0.01

#initializing boundary conditions:
for i in range(101): 
    row_i = [] #list to store initial values of i and j in
    for j in range(101):
        #i in [35,65] b/c my range is 0-100 for a graph from (-1,1). Thus, each step (in 0-100) has a value of 0.02 (in(-1,1))
        #so since in the graph, the inner conductor is from -0.3,0.3, in time step numbers that is 35 to 65
        if 35<=i<=65 and 35<=j<=65: #boundary for inner conductor
            volt = 1

        #inside (65,99] is all of the space between conductor and prism 
        elif 65<i<=99 or 65<j<=99: #outside of conductor inside prism
            volt = 0
        elif i==0 or i==100 or j==0 or j==100: #metallic prism boundary
            volt = 0
        else:
            volt = 0
        row_i.append(volt) #stores initial values of v in row_i list
    v.append(row_i) #stores the initial values of v in 2d array like list

def update_V(v): #uses initialized values to compute improved estimate for v(i,j)
    dv = 0
    #looping through all points (i,j) except for the boundary
    for i in range(101):
        for j in range(101):
            #pass at boundary:
            if i==0 or i==100 or j==0 or j==100: 
                pass
            #pass at boundary:
            elif 35<=i<=65 and 35<=j<=65:
                pass
            else:
                v_new = (v[i+1][j]+v[i-1][j]+v[i][j+1]+v[i][j-1])/4
                v_old = v[i][j] #assigns value of v(i,j) from previous step as v-old
                dv += abs(v_old - v_new)
                v[i][j] = v_new #after loop goes through calculation for v-new, stores it as the current value for v(i,j)
                #v[i][j] is the value stored in v at the index i and j
    return v, dv

#calls update-v and tests for convergence of dv
def laplace_calculate(v):
    #10^-5 times N for checking 10^-5 at each site
    epsilon = 10**(-5)*100**2

    #initializing dv and N
    dv = 0
    N = 0

    while dv >= epsilon or N <= 10:
        v1, dv = update_V(v) #calling update-v so v creates improved guess of v1
        v2, dv = update_V(v1) #calling update-v again so v1 creates further improved guess of v2
        v = v2
        N += 1

    return v2

Z = laplace_calculate(v)
Ex = deepcopy(Z) #copies the function laplace-calculate
Ey = deepcopy(Z)
Ez = deepcopy(Z)
E = deepcopy(Z)

#electric field values calculation
for i in range(101):
    for j in range(101):
        if i==0 or j==0: #prism boundary on left
            #one sided difference equation for Ex and Ey
            Ex_value = -(v[i+1][j])/dx
            Ey_value = -(v[i][j+1])/dy
            Ex[i][j] = Ex_value #updates Ex-value to Ex list 
            Ey[i][j] = Ey_value #updates Ey-value to Ey list
        elif i==100 or j==100:
            #one sided difference equation for Ex and Ey
            Ex_value = -(v[i-1][j])/dx
            Ey_value = -(v[i][j-1])/dy
            Ex[i][j] = Ex_value
            Ey[i][j] = Ey_value
        elif 35<=i<=65 and 35<=j<=65:
            Ex_value = 0
            Ey_value = 0
            Ex[i][j] = Ex_value
            Ey[i][j] = Ey_value
        else:
            Ex_value = -(v[i+1][j] - v[i-1][j])/(2*dx) 
            Ey_value = -(v[i][j+1] - v[i][j-1])/(2*dy)
            Ex[i][j] = Ex_value
            Ey[i][j] = Ey_value

for i in range(101):
    for j in range(101):
        #just calculates the actual electric field value taken from the x and y values above 
        E_value = np.sqrt(Ex[i][j]**2 + Ey[i][j]**2)
        E[i][j] = E_value

x = np.linspace(-1,1,100)
y = np.linspace(-1,1,100)
X, Y = np.meshgrid(x,y)

fig, ax = plt.subplots()
ax.quiver(X, Y, Ey, Ex)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Electric Field')
plt.xticks([-1.5,-1,-0.5,0,0.5,1,1.5],['','-1','','0','','1',''])
plt.yticks([-1.5,-1,-0.5,0,0.5,1,1.5],['','-1','','0','','1',''])
plt.show()

但是,它一直在第 80 行抛出错误:

IndexError                                Traceback (most recent call last)
<ipython-input-8-f2be5562450c> in <module>
     78             #one sided difference equation for Ex and Ey
     79             Ex_value = -(v[i+1][j])/dx
---> 80             Ey_value = -(v[i][j+1])/dy
     81             Ex[i][j] = Ex_value #updates Ex-value to Ex list
     82             Ey[i][j] = Ey_value #updates Ey-value to Ey list

IndexError: list index out of range

我了解什么是索引错误,但在这里,我看不到我的索引如何超出我的列表范围。 我错过了什么? 所有其他 if/elif 循环都在范围内,因为当我在电场计算中注释掉第一个 if 循环的方程并将它们等同于零时,我得到输出。 我对 python 还是很陌生,并试图更好地掌握这一切。 非常感谢在此问题上的任何帮助。

您的ij循环超出range(101) ,因此最小值为 0,最大值为 100。

在有问题的线路上

Ey_value = -(v[i][j+1])/dy

j+1可以达到 101。

如果v[i]是一个len 100 的列表,那么这个索引,100 或 101 就太大了。 这种大小的列表的有效索引是 0 到 99(范围(99))。 对于形状为 (100,100) 的 numpy 数组也是如此(但它会给出不同的错误消息)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM