我正在尝试使用“射击方法”来求解薛定谔方程,以获得一维中合理的任意势。但是,与分析结果相比,在没有硬边界的势能的情况下如此评估的特征值并不准确。
我认为可以通过使空间网格更精细来解决问题,但是更改空间网格实际上对特征值没有任何影响。我并没有使能量网格更精细,因为精细到正确特征值的工作是通过 SciPy 的二分法来解决的,而波函数是通过odeint从 SciPy 求解相关的 IVP 来评估的,这些函数足够准确。
最后,改变第二个边界使波函数在经典禁区的更深部分消失也没有带来特征值的实际改进(仅在小数点后第 9 位或第 10 位发现变化,但使低能态的波函数在端点处发散使事情变得更糟)。
我找不到要修改的内容以获得更准确的特征值。边界条件还是步长?我的实现是否出错了,还是由于舍入错误或其他“Python 事物”?
示例:莫尔斯电位
import numpy as np
from scipy.integrate import odeint
from scipy.optimize import bisect
def V(x, xe=1.0, lam=6.0):
"""Morse potential definition"""
return lam**2*(np.exp(-2*(x- xe)) - 2*np.exp(-(x - xe)))
def func(y, x):
"""
Utility function for returning RHS of the differential equation.
"""
psi, phi = y # psi=eigenfunction, phi=spatial derivative of psi
return np.array([phi, -(E - V(x))*psi])
def ivp(f, initial1, initial2, X):
"""Solve an ivp with odeint"""
y0 = np.array([initial1, initial2])
return odeint(f, y0, X)[:, 0]
def psiboundval(E1):
"""
Find out value of eigenfunction at bound2 for energy E1
by solving ivp.
"""
global E;
E = E1
S = ivp(func, bval1, E1, X)
return S[(len(S)) - 1] - bval2
def shoot(Erange):
"""
Find out accurate eigenvalues from approximate ones in
Erange by bisect.
"""
global E
Y = np.array([psiboundval(E) for E in Erange])
eigval = np.array([bisect(psiboundval, Erange[i], Erange[i + 1])
for i in np.where(np.diff(np.signbit(Y)))[0]])
return eigval
#%% Solution
xe, lam = 1.0, 6.0 # parameters for potential
# Bval, Bval2 = wavefunction values at x = bound1, bound2
bound1, bound2, bval1, bval2 = 0, xe + 15, 0, 0
X = np.linspace(bound1, bound2, 1000) # region of integration
Erange = np.geomspace(-lam**2, -0.0001, 100) # region of Energy level searching
print("Numerical results:", np.round(shoot(Erange), 4))
print("Analytical results:",
[-(lam - n - 0.5)**2 for n in range(0, int(np.floor(lam - 0.5) + 1))])
输出
Numerical results: [-30.2483 -20.2432 -12.2361 -6.2318 -2.2343 -0.2438]
Analytical results: [-30.25, -20.25, -12.25, -6.25, -2.25, -0.25]
对于更高的能量状态,精度会降低。对于所有状态,精度至少要达到小数点后 4 位(如果不是更多的话)是可取的。