Как я могу более точно оценить собственные значения энергии из уравнения Шредингера, используя метод стрельбы? - PullRequest
1 голос
/ 06 мая 2020

Я пытаюсь использовать «метод стрельбы» для решения уравнения Шредингера для достаточно произвольного потенциала в 1D. Но собственные значения, оцененные таким образом в случае потенциалов, которые не имеют жестких границ (где потенциал становится бесконечным), не очень точны по сравнению с аналитическими результатами.

Я думал, что проблему можно решить, создав пространственные сетка более мелкая, но изменение пространственной сетки практически не влияет на собственные значения. оценивается путем решения соответствующего ivp с помощью odeint от scipy - эти функции достаточно точны. Наконец, изменение второй границы, чтобы сделать волновую функцию d ie в более глубокой части классически запрещенной области, также не привело к практическому улучшению собственного значения (изменения, обнаруженные только в 9-м или 10-м разряде десятичной дроби, но сделали волновые функции более низкого энергетического состояния расходятся в конечных точках, чтобы усугубить ситуацию).

Я не могу найти, что изменить, чтобы получить более точные собственные значения. Граничное условие или размер шага? Моя реализация go была неправильной, или это из-за ошибок округления или других «Python вещей»?

Пример - потенциал Морзе (https://en.wikipedia.org/wiki/Morse_potential)

import numpy as np
from scipy.integrate import odeint,simps
from scipy.optimize import bisect
from math import e,floor

xe,lam=1.0,6.0 # parameters for potential
def V(x):return (lam**2)*(e**(-2*(x-xe))-2*(e**-(x-xe))) # morse potential definition

bound1,bound2,bval1,bval2=0,xe+15,0,0 # Bval,Bval2=wavefunction values at x=bound1,bound2
X=np.linspace(bound1,bound2,1000) # region of integration
Erange=np.geomspace(-(lam**2),-0.0001,100) # region of Energy level searching

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): # solves an ivp with odeint
    y0=np.array([initial1,initial2])
    return odeint(f,y0,X)[:,0]

def psiboundval(E1):  # finds 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): # finds 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

print "Numerical results:",shoot(Erange)
print "Analytical results:",[-(lam-n-0.5)**2 for n in range(0,int(floor(lam-0.5)+1))]

Выход

>>> Numerical results: [-30.24833663 -20.24320174 -12.23610971  -6.23177902  -2.23431356
  -0.24381032]
Analytical results: [-30.25, -20.25, -12.25, -6.25, -2.25, -0.25]

Для состояний с более высокой энергией наблюдается снижение точности. Желательно, чтобы точность была как минимум до 4-го знака после запятой (если не больше) для всех состояний.

...