我正在尝试使用python numpy的Jacobi方法求解泊松方程:
# This function applies boundary conditions on the given array
def apply_bc(u):
u[0] = 0.0
if bc == 'Dirichlet':
u[num_mesh-1] = 0.0
else:
sys.exit('Set correct boundary condition at the right side boundary')
# ============== Program begins here ==================================
import numpy as np
import math as m
import matplotlib.pyplot as plt
import sys
# --------------- Set the following input parameters ------------------
num_mesh = 11 # number of mesh points
bc = 'Dirichlet' # Boundary condition at the right boundary; set either 'Dirichlet', 'Neumann' or 'Robin'
# ---------------------------------------------------------------------
del_x = 1.0/(num_mesh-1.0) # mesh size (Delta_x)
xmesh = np.zeros(num_mesh) # Mesh points
u_new = np.zeros(num_mesh)
u_old = np.zeros(num_mesh)
summation= np.zeros(num_mesh)
norm = 100.0 # measure of difference between values at two consequetive time steps
iter = 0
converged = False
# Elements of system matrix
A = np.zeros((num_mesh,num_mesh))
# RHS matrix
Q = np.zeros(num_mesh)
# Compute the location of mesh points
for i in range(0, len(xmesh)):
xmesh[i] = i * del_x
# apply boundary conditions on the initial field
apply_bc(u_new)
# construct the elements of discretized matrix
if bc == 'Dirichlet':
A[0,0] = 1.0
A[(num_mesh-1),(num_mesh-1)] = 1.0
Q[0] = 0.0
Q[num_mesh-1] = 0.0
for i in range(1, len(u_new)-1):
Q[i] = m.pi*m.pi*del_x*del_x*m.sin(m.pi*xmesh[i])
print("A="+str(A))
for i in range(0, len(u_new)):
for j in range(0, len(u_new)):
if i == j:
A[i][j] = 2
elif (j == (i + 1)):
A[i][j] = -1
elif (j == (i-1)):
A[i][j] = -1
else:
A[i][j] = 0
A[0,0] = 1.0
A[(num_mesh-1),(num_mesh-1)] = 1.0
A[(num_mesh-1),(num_mesh-2)] = -1
A[(num_mesh-2),(num_mesh-1)] = -1
print("A1="+str(A))
# Jacobi Method
# Iteration begins
while converged==False:
# RHS of the discretized equation
# On the left boundary, it is always Dirichlet BC
Q[0] = 0.0
if bc == 'Dirichlet':
Q[num_mesh-1] = 0.0
#iteration
for i in range(1, len(u_new)-1):
for j in range(1, len(u_new)-1):
if i!=j:
summation[i] = summation[i] + (A[i,j] * u_old[j])
u_new[i] = (Q[i]-summation[i])/A[i,i]
print("u_new=",u_new)
print("u_old=",u_old)
norm = abs(max(u_new-u_old, key=abs))/abs(max(u_new, key=abs)) # compute the difference between two solutions
print("norm=",str(norm))
iter = iter + 1
print(iter, norm)
import sys
# if iter == 100:
# sys.exit()
if norm <0.001:
converged = True
# Soution not converged -- copy current value into old
for i in range(0, len(u_new)):
u_old[i] = u_new[i]
# setting the x - coordinates
x = np.arange(0, 1, 0.0001)
# setting the corresponding y - coordinates
exac_sol = np.sin(m.pi*x)
# plot the converged results
plt.plot(xmesh,u_new,'r-o')
plt.plot(x,exac_sol)
plt.xlabel('x')
plt.ylabel('u')
plt.show()
#plt.savefig('Poisson_Eqn.pdf')
但是对于第1067次迭代,norm
的值为Nan
,但出现以下错误:
RuntimeWarning:在double_scalar中遇到无效值
该如何解决?