I'm trying to create a three index matrix that contains 1 value (V) for every node of a numerical spatial mesh (xyz) (real world problem: the electrostatic potential created by finite-paralell- plates in a point of space). This matrix initially has to be filled with zeros except for some specific points (where the plates and space limits are) and then iteratively update the value at each node according to the following 7-point stencil method (j k and l indices of the x y z coordinates respectively):
V[j,k,l] = (V[j+1, k, l] + V[j-1, k, l] + V[j, k+1, l] + V[j, k-1, l] + V[j, k, l+1] +V[j, k, l-1])/6 (i. e., replace the value of a node with the average of the other 6 neighbouring nodes)
I've tried np.zeros and np.meshgrid but I think maybe I just simply have a serious conceptual and basic gap regarding arrays since nothing seems to do what I want. Any orientation would be really appreciated and sorry if I did not explain myself correctly. Here some code I've tried:
V1 = 10
V2 = -5
Mx = 101
My = 151
Mz = 301
V = np.zeros([Mx, My, Mz]).astype(int)
V[46, 51:101, 101:201] = V1 #the values of these nodes should stay fixed throughout iteration
V[56, 51:101, 101:201] = V2 #the values of these nodes should stay fixed throughout iteration
V[1,:,:] =V[100,:,:] =V[:,1,:] =V[:,150,:] =V[:,:,1] =V[:,:,300] = 0 #the values of these nodes should stay fixed throughout iteration
for j in V:
for k in j:
for l in k:
V[j, k, l] = (V[j+1, k, l] + V[j-1, k, l] + V[j, k+1, l] + V[j, k-1, l] + V[j, k, l+1] +V[j, k, l-1])/6
(Update after help from user kcw78)
Implementing the proposed code and trying to implement a while loop that keeps going until error falls below tolerance or the error in two consecutives cycles is the same. The statement of the assignment says more specifically:
"As many of these cycles will be completed as needed for the error to fall below a certain prescribed tolerance, rtol. And what is a good measure of the error here? We will use the maximum value of the local residual, defined as the (absolute value of the) difference between the potential value at the central node and the arithmetic average of the other values in the stencil. As a extra safeguard, we will also compare the errors of any two successive cycles and stop the relaxation if they become equal. A better solution is no longer possible."
Now trying the code below, but not sure if it's trapped in an infinite while loop or just takes a lot of time since I have to stop it after 20 minutes without producing any output (also not sure if maybe I should use .all() instead of .any()):
import numpy as np
V1 = 10
V2 = -5
Mx = 101
My = 151
Mz = 301
rtol = 10**-2
V1_set = { (46,k,l) for k in range(51,101,1) for l in range(101,201,1) }
V2_set = { (56,k,l) for k in range(51,101,1) for l in range(101,201,1) }
V = np.zeros((Mx, My, Mz))
Vnew = np.copy(V)
V[46, 51:101, 101:201] = V1
V[56, 51:101, 101:201] = V2
V[1,:,:] =V[100,:,:] =V[:,1,:] =V[:,150,:] =V[:,:,1] =V[:,:,300] = 0
check_set = set().union(V1_set,V2_set)
error = np.zeros((Mx, My, Mz))
errornew = np.zeros((Mx, My, Mz))
while float(errornew.any()) < rtol or error.any() != errornew.any():
V = Vnew
error = errornew
for j in range(1,V.shape[0]-1):
for k in range(1,V.shape[1]-1):
for l in range(1,V.shape[2]-1):
if (j,k,l) not in check_set:
Vnew[j, k, l] = (V[j+1, k, l] + V[j-1, k, l] + V[j, k+1, l] + V[j, k-1, l] + V[j, k, l+1] +V[j, k, l-1])/6
errornew[j, k, l] = abs(Vnew[j, k, l]-V[j, k, l])