Python 使用scipy.integrate.odeint在调用时完成的多余工作(可能是错误的Dfun类型)

Python 使用scipy.integrate.odeint在调用时完成的多余工作(可能是错误的Dfun类型),python,scipy,physics,odeint,Python,Scipy,Physics,Odeint,我正在用Python编写一段代码,预测氢的能级,我将用它作为研究夸克偶素能级的模板。我正在使用scipy.integrate.odeint()函数来求解Shroedinger方程,它适用于n=6以下的较低能级。我不认为我需要做更多的工作,但是odeint会返回在这个调用中完成的多余工作(可能是错误的Dfun类型)。这只会鼓励我扩展我可以预测的内容 我使用的Shroedinger方程代换是: u'' - (l*(l+1)/r**2 - 2mu_e(E-V_emag(r))) * u = 0 =&g

我正在用Python编写一段代码,预测氢的能级,我将用它作为研究夸克偶素能级的模板。我正在使用
scipy.integrate.odeint()
函数来求解Shroedinger方程,它适用于
n=6
以下的较低能级。我不认为我需要做更多的工作,但是odeint会返回
在这个调用中完成的多余工作(可能是错误的Dfun类型)。
这只会鼓励我扩展我可以预测的内容

我使用的Shroedinger方程代换是:

u'' - (l*(l+1)/r**2 - 2mu_e(E-V_emag(r))) * u = 0
=>
u' = v
v' = ((l*(l+1))/(r**2) - 2.0*mu_e*(E - V_emag(r)))*u
然后我在它上面使用
scipy.integrate.odeint()
,迭代能量,并使用我定义的其他函数来评估结果中的转折点和节点。我找到能级的方法是找到最低可能的E值,其中转折点和节点的数量与其应该匹配;然后将
L
增加1并找到新的地面能量,例如,如果
L=0
我将找到
n=1
能量,如果
L=3
,我将找到
n=2
能量

一旦代码增加到
L=7
,它就不会返回任何有用的内容。
r
的范围已经扩展,但我尝试保持不变以减少步骤数,但没有效果。代码是自学的,所以在我的研究中,我读过关于雅各比派的书。恐怕我还没有弄清楚它们是什么,或者我是否需要它们。有什么想法吗

def v_emag(r):
    v = -alpha/r
    return v

def s_e(y,r,l,E): #Shroedinger equation for electromagntism
    x = numpy.zeros_like(y)
    x[0] = y[1]
    x[1] = ((l*(l+1))/(r**2) - 2.0*mu_e*(E - V_emag(r)))*y[0]
    return x

def i_s_e(l,E,start=0.001,stop=None,step=(0.005*bohr)):
    if stop is None:
        stop = ((l+1)*30-10)*bohr
    r = numpy.arange(start,stop,step)
    y = odeint(s_e,y0,r,args=(l,E))
    return y

def inormalise_e(l,E,start=0.001,stop=None,step=(0.005*bohr)):
    if stop is None:
        stop = ((l+1)*30-10)*bohr
    r = numpy.arange(start,stop,step)
    f = i_s_e(l,E,start,stop,step)[:,0]
    f2 = f**2
    area = numpy.trapz(f2,x=r)
    return f/(numpy.sqrt(area))

def inodes_e(l,E,start=0.001,stop=None,step=(0.005*bohr)):
    if stop is None:
        stop = ((l+1)*30-10)*bohr
    x = i_s_e(l,E,start,stop,step)
    r = numpy.arange(start,stop,step)
    k=0
    for i in range(len(r)-1):
        if x[i,0]*x[i+1,0] < 0: #If u value times next u value <0,
            k+=1               #crossing of u=0 has occured, therefore count node
    return k

def iturns_e(l,E,start=0.001,stop=None,step=(0.005*bohr)):
    if stop is None:
        stop = ((l+1)*30-10)*bohr
    x = i_s_e(l,E,start,stop,step)
    r = numpy.arange(start,stop,step)
    k = 0
    for i in range(len(r)-1):
        if x[i,1]*x[i+1,1] < 0: #If du/dr value times next du/dr value <0,
            k=k+1               #crossing of du/dr=0, therefore a maximum/minimum
    return k

l = 0
while l < 10:    #The ground state for a system with a non-zero angular momentum will
    E1 = -1.5e-08    #be the energy level of principle quantum number l-1, therefore
    E3 = 0           #by changing l, we can find n by searching for the ground state
    E2 = 0.5*(E1+E3)
    i = 0
    while i < 40:
        N1 = inodes_e(l,E1)
        N2 = inodes_e(l,E2)
        N3 = inodes_e(l,E3)
        T1 = iturns_e(l,E1)
        T2 = iturns_e(l,E2)
        T3 = iturns_e(l,E3)
        if N1 != N2:# and T1 != T2: #Looks in lower half first, therefore will tend to ground state
            E3 = E2
            E2 = 0.5*(E1+E3)
        elif N2 != N3:# and T2 != T3:
            E1 = E2
            E2 = 0.5*(E1+E3)
        else:
            print "Can't find satisfactory E in range"
            break

        i += 1
    x = inormalise_e(l,E2)
    if x[((l+1)**2)/0.005] > (x[2*((l+1)**2)/0.005]) and iturns_e(l,E2+1e-20)==1:
        print 'Energy of state: n =',(l+1),'is: ',(E2*(10**9)),'eV'
        l += 1
    else:
        E1 = E2+10e-20
def v_emag(r):
v=-alpha/r
返回v
def s#e(y,r,l,e):#用于电磁的Shroedinger方程
x=numpy.zeros_like(y)
x[0]=y[1]
x[1]=((l*(l+1))/(r**2)-2.0*mu_e*(e-V_emag(r)))*y[0]
返回x
定义i_s_e(l,e,开始=0.001,停止=无,步骤=(0.005*波尔)):
如果停止为无:
停止=((l+1)*30-10)*波尔
r=numpy.arange(开始、停止、步骤)
y=odeint(s_e,y0,r,args=(l,e))
返回y
def非标准化(l,e,开始=0.001,停止=无,步骤=(0.005*波尔)):
如果停止为无:
停止=((l+1)*30-10)*波尔
r=numpy.arange(开始、停止、步骤)
f=i_s_e(l,e,开始,停止,步骤)[:,0]
f2=f**2
面积=numpy.trapz(f2,x=r)
返回f/(单位面积)
定义索引节点(l,e,开始=0.001,停止=无,步骤=(0.005*波尔)):
如果停止为无:
停止=((l+1)*30-10)*波尔
x=i_s_e(l,e,开始,停止,步骤)
r=numpy.arange(开始、停止、步骤)
k=0
对于范围内的i(透镜(r)-1):

如果x[i,0]*x[i+1,0]<0:#如果u值乘以下一个u值我不知道你的代码到底出了什么问题,我也不完全确定你的
是什么,而你能展示你的代码吗?顺便说一句,这个薛定谔方程不是有解析解吗?我知道它有解析解,但是它没有强力势的解析解,所以我使用氢的已知结果来确保我的代码在用于夸克偶素之前工作。以前从未使用过薛定谔方程,但可以说,
odeint()
只适用于“行为良好”的函数,即。,所有衍生品的价值都不应过高。据我所见,极点在0,导致非常大的值接近0,这会导致数值不稳定。我实际上使用了u(r)=r*psi(r)的替换来避免r=0时的未定义性质的问题。这意味着我实际上控制了不稳定性(并简化了方程)。当使用非零l值绘制时,波函数的值在r=0时为零。
而i和截面
如果停止为无
,则它将根据增加的能量水平调整范围的终点
import numpy as np
import scipy as sp
from scipy.integrate import odeint

m_e, m_p, hbar = sp.constants.m_e, sp.constants.m_p, sp.constants.hbar
mu_e = m_e*m_p/(m_e + m_p)
bohr = sp.constants.physical_constants['Bohr radius'][0]
Rinfhc = sp.constants.physical_constants['Rydberg constant times hc in J'][0]
RHhc = Rinfhc * mu_e / m_e

fac = sp.constants.e**2/4/sp.pi/sp.constants.epsilon_0

def V(r):
    return -fac/r

def deriv(y, r, l, E):
    y1, y2 = y
    dy1dr = y2
    dy2dr = -2*y2/r - (2*mu_e/hbar**2*(E - V(r)) - l*(l+1)/r**2)*y1
    return dy1dr, dy2dr

def solveSE(l, E, y0):
    rstep = 0.001 * bohr
    rmin = rstep
    rmax = 200*l * bohr         # 
    r = np.arange(rmin, rmax, rstep)
    y, dydt = odeint(deriv, y0, r, args=(l,E)).T
    return r, y, dydt

n = 10
l = 2
y0 = (bohr, -bohr)
E = -RHhc / n**2
r, psi, dpsi_dr = solveSE(l, E, y0)

import pylab
pylab.plot(r, psi)
pylab.show()