我的代码遇到了二阶耦合 PDE 问题的问题。为了澄清,我正在用有限差分解决这个问题,即使它不需要它,因为我有一个与这个类似的更普遍的问题,我想检查代码是否合理。
\begin{equation}
-\partial^2_r u_{\uparrow}(r) -\frac{1}{r} \partial_r u_{\uparrow}(r) + u_{\uparrow}(r)
+ \partial_r u_{\downarrow}(r)
+\frac{u_{\downarrow}(r)}{r}
- \Delta (r) u_{\downarrow}(r) = 0
\end{equation}
\begin{equation}
-\partial_r u_{\uparrow}(r)
+ \Delta (r) u_{\uparrow}(r)
-\partial^2_r u_{\downarrow}(r) -\frac{1}{r} \partial_r u_{\downarrow}(r) + \frac{u_{\downarrow}(r)}{r^2} - u_{\downarrow}(r) = 0
\end{equation}
因为 up(r) 和 down(r) 是耦合的,它最初没有给我一个三对角矩阵,这使得很难施加边界条件 (up(0) =1, down(0) = up(40) = down (40) = 0) 在 RHS 中。我知道答案将是振幅减小的振荡,但我的解决方案会增加振幅。我试图重新排列行和列以使其有点对角线。它仍然给我同样的错误答案。
def sol_fin(ran):
r = np.linspace(0, 40, ran)
Δ = 0.1*np.heaviside(r-1,1)
Δr = np.abs(r[2]-r[1])
M = np.zeros([2*ran,2*ran])
for i in range(1, ran-1):
M[i-1,i] = -1/(Δr**2) + 1/(2*r[i]*Δr) #up_i_eq1
M[i,i] = 2/(Δr**2) + 1 #up_i+1_eq1
M[i+1,i] = -1/(Δr**2) - 1/(2*r[i]*Δr) #up_i+1_eq1
M[i-1,i+ran] = 0 - 1/(2*Δr)#down_i_eq1
M[i,i+ran] = -Δ[i] + 1/r[i] #down_i+1_eq1
M[i+1,i+ran] = 1/(2*Δr) #10**-15 #down_i+2_eq1
M[i+ran-1,i] = 0 + 1/(2*Δr)#up_i_eq2
M[i+ran,i] = Δ[i] #up_i+1_eq2
M[i+1+ran,i] = -1/(2*Δr) #up_i+2_eq2
M[ran+i-1,i+ran] = -1/(Δr**2) + 1/(2*r[i]*Δr)#down_i_eq2
M[ran+i,i+ran] = 2/(Δr**2) +1/(r[i]**2) - 1 #down_i+1_eq2
M[ran+i+1,i+ran] = -1/(Δr**2) - 1/(2*r[i]*Δr)#down_i+2_eq2
#16 ghost points
#up1
##initials
M[0,0] = M[1,1] #exact
M[1,0] = -1/(Δr**2) - 1/(2*r[1]*Δr) #approx
##finals
M[ran-1,ran-1] = 2/(Δr**2) + 1 #approx
M[ran-2,ran-1] = -1/(Δr**2) + 1/(2*r[i-1]*Δr) #approx
#down1
##initials
M[0,ran] = -Δ[1] + 1/r[1] #approx
M[1,ran] = M[2,ran+1] #exact
##finals
M[ran-2,2*ran-1] = M[ran-3,2*ran-2] #exact
M[ran-1,2*ran-1] = -Δ[ran-1] + 1/r[ran-1] #approx
#up2
##initials
M[ran,0] = 0.1 # exact
M[ran+1,0] = M[ran+2,1] # exact
##finals
M[2*ran-1,ran-1] = 0.1 # exact
M[2*ran-2,ran-1] = M[2*ran-3,ran-2] # exact
#down2
##initials
M[ran,ran] = 2/(Δr**2) +1/(r[1]**2) - 1 #approx
M[ran+1,ran] = -1/(Δr**2) - 1/(2*r[1]*Δr)#approx
##finals
M[2*ran-1,2*ran-1] = 2/(Δr**2) +1/(r[ran-1]**2) - 1 #approx
M[2*ran-2,2*ran-1] = -1/(Δr**2) + 1/(2*r[ran-1]*Δr) #approx
#reorganizing lines and columns to make it somewhat tridiagonal
N = np.zeros([2*ran,2*ran])
for i in range(0, ran): #change lines
N[2*i,:] = M[i,:]
N[2*i+1,:] = M[ran+i,:]
N[2*ran-1,:] = M[2*ran-1,:]
N1 = np.zeros([2*ran,2*ran])
for i in range(0, ran): #change columns - adding regular order in pairs and the rest in the other
N1[:,2*i] = N[:,i]
N1[:,2*i+1] = N[:,ran+i]
N1[:,2*ran-1] = N[:,2*ran-1]
# b
b = np.zeros([2*ran])
b[0] = 1 #I guess??
# solution:
solA = np.linalg.solve(N1, b)
print(solA)
#solA = solA / (np.linalg.norm(solA) + 10**-16) #normalization
sol_ups = np.linspace(10**-6, 40, ran-1)
sol_downs = np.linspace(10**-6, 40, ran-1)
for i in range(0, ran-1):
sol_ups[i] = solA[2*i]
for i in range(0, ran-1):
sol_downs[i] = solA[2*i+1]
r_plot = np.linspace(10**-6, 40, ran-1)
plt.plot(Jayx_plot, Jayy_plot_a,'--', label='up-j', color='r')
plt.plot(Jayx_plot, Jayy_plot_b,'--', label='down-j', color='b')
plt.plot(r_plot, sol_ups, label='up', color='r'), plt.xlabel("r"),
plt.plot(r_plot, sol_downs, label='down', color='b'), plt.legend(),
plt.ylim(-0.7,0.7)
plt.xlim(0, 42)
plt.ylabel("Psi(r)"), plt.axhline(y=0,color='black')
plt.title("Spinor components") #for r = {}".format(r_in))
plt.show()
sol_fin(1000)
这是我的代码: