Я работаю над проблемой вычислительной физики, используя python. Ожидаемым выходным сигналом должен быть график с маленькими стрелками (с использованием колчана), показывающий направление поля электричества c в каждой точке внутри призмы из полого металла 1010 * с внутренним проводником solid metalli c. На внутреннем проводнике, напряжение = 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 находятся в диапазоне, например, когда я закомментирую уравнения для первого, если l oop внутри моих вычислений в поле electri c, и вместо этого приравниваю их к нулю, я получаю вывод. Я все еще очень плохо знаком с python и пытаюсь получить лучший результат asp. Любая помощь в этом вопросе очень ценится.