Python、numpy 和复杂函数 (PDE)

计算科学 pde Python 麻木的 量子力学
2021-12-05 18:07:23

更新 4

我几乎已经放弃了做这件事。这是与时间无关的薛定谔方程的解,因此解析解为: 这意味着对于所有 t。但是,我无法在数字上进行这项工作,我也不知道为什么。ψ(x,t)=ψ(x,0)eiEt|ψ(x,t)|2=|ψ(x,0)|2

我最近失败的尝试:

from numpy import *
from scitools.all import *

V0= 10.0 #eV
a= 1.0 #nm
c = 299792.0 # nm per ps
m= (0.510*10**6)/(c**2) #eV/c**2
hbar= 6.58*10**(-4) #eV ps

z = 1.456 # fra c
alpha = 16.2 # fra c

def Psi0(x):
    psi = x.astype(complex128)
    ka = (z/a)*sqrt((alpha/z)**2 -1.)
    A = exp(ka*a)*cos(z)/(a + 1./ka)
    B = 1./(a+ 1./ka)
    for i in range(len(x)):
        if x[i]<-a or x[i]>a:
            psi[i] = A*exp(-ka*abs(x[i]))
        else:
            psi[i] = B*cos((z/a)*x[i])
    return psi


x = linspace(-8.0,8.0,1001).astype(complex128)
t = linspace(0.0,0.1,2001).astype(complex128)

dx = x[2]-x[1]
dt = t[2]-t[1]
k1 = 1.j*hbar/(2.0*m)
k2 = 1.j/hbar

def V(x,a=1.0):
    V = zeros(len(x)).astype(complex128)
    for i in range(len(x)):
        if x[i] >= -a and x[i] <= a:
            V[i] = -V0
    return V

def d2(Psi, dx):
    D2P = zeros(len(Psi)).astype(complex128)
    for i in range(len(D2P)-2):
        D2P[i+1] = (Psi[i+2] - 2*Psi[i+1] + Psi[i])/(dx**2)
    return D2P

def sch(Psi,x,dx):
    return k1*d2(Psi,dx) - k2*V(x)*Psi

Psi = []
Psi.append(Psi0(x).astype(complex128))

a = abs(Psi[0])**2
plot(x.real, a, xlabel='x', ylabel='f')

''' Euler '''
'''for i in range(len(t)):
    b = dx*sum(abs(Psi[-1] + dt*sch(Psi[-1],x,dx))**2)
    Psi.append((Psi[-1] + dt*sch(Psi[-1],x,dx))/sqrt(b))
    print b
'''
'midpoint'
for i in range(len(t)):
    a = Psi[-1] + dt*sch(Psi[-1] + (dt/2.)*sch(Psi[-1],x,dx),x,dx)
    b = dx*sum(abs(a)**2)
    Psi.append(a/sqrt(b))
    print b

counter = 0
forhver = 10

for i in range(len(t)):
    if counter == forhver:
        a = abs(Psi[i])**2
        plot(x.real, a, axis=[-8, 2, -1, 3], xlabel='x', ylabel='f', legend='t=%4.2f' % i, savefig='obl8%04d.png' % i)
        counter = 0
    counter += 1

movie('obl8*.png')

更新 3:

我将单位从每秒米更改为每皮秒纳米。它使代码运行良好。但是,它看起来不正确: http ://sineofmadness.com/wp-content/uploads/2014/11/movie.gif

无论我选择哪个,并且我可以在五个之间进行选择,它都会变成双钟形曲线。我使用了中点法和欧拉法。它给出或多或少相同的结果。上面的动画对我来说是数字错误。然而,我现在已经用几种不同的方法看到了这个结果。ψ(x,0)

这对任何人来说都是正确的吗?

原版的

我正在努力解决量子物理学中的一种特定类型的问题(一维):假设我有一个函数,我必须使用薛定谔方程(通过动画 ): 所以,我所做的是定义势函数和二阶导数,并使用欧拉方法。起初,绘图函数不断丢弃函数的虚部,因此我决定将的值存储在单独的数组中。但是,它仍然不起作用。我遇到问题,比如数组中的每个元素都不是数字,或者函数保持不变(即ψ(x,0)|ψ(x,t)|2

22md2ψdx2+V(x)ψ=idψdt
ψ(x,t)ψ(x,t)=ψ(x,0)对于一些之后的所有 t )。t0

2个回答

警告:我没有阅读超出声明的内容

所以,我所做的是定义势函数和二阶导数,并使用欧拉方法。

因此,您的代码可能还有其他问题,但这已经是根本问题。

您正在尝试使用欧拉方法求解波动方程。这在数值上是不稳定的。 要了解原因,请注意二阶导数算子(及其中心有限差分离散化)是对称的,并且只有负实特征值。当你将它与虚数单位乘以时间导数相结合时,你会发现这个方程的动力学是波状的——半离散化的特征值是纯虚数。同时,欧拉法的稳定区域:

{zC:|1+z|1

不包含任何假想轴(除了原点)。

您应该使用在虚轴上稳定的时间离散化而不是欧拉法,例如中点法或梯形法。在这个问题的答案中可以找到一些好的方法和参考:

有没有简单的方法来数值求解瞬态薛定谔方程?

首先,您应该简化问题,以便您可以单独测试各个部分。让代码首先使用 V = 0。更简单的 Psi0 也会有所帮助。

其次,您需要更好地了解哪里出了问题。Python 包括 python 调试器 pdb。如果您将以下行:“import pdb;pdb.set_trace()”放入您的代码中,它会给您一个提示,您可以在其中查看变量的内容、尝试不同的命令、绘制变量等等。pdb 文档可以帮助您解决这个问题。我建议在您的时间循环之前执行此操作,以查看是否所有内容都已正确初始化。然后,将其粘贴在循环中,以便准确识别失败的地方。调试一行比调试整个代码要容易得多。

第三,坚持!根据您的第一个代码,我要说很多其他的事情,但第二个解决了大部分问题。