变分蒙特卡洛:变分能量低于基态能量

计算科学 Python 迭代法 蒙特卡洛
2021-12-08 12:45:56

我正在为氢和氦原子编写 VMC 模拟,但在我的两个代码中,某些波函数的变分能量不仅在统计上与我的期望值不同,而且还低于我的基态能量。

对于氢原子,我知道基态能量是0.5Ha. 如果我使用试验波函数e1.2r(在哪里r是我的原子核和电子之间的距离)我得到的能量低于我的基态能量(我被告知我的基态能量是我的变分能量的下限)。如果我使用确切的波函数(er) 我明白了0.5Ha确切地。

我对此感到非常困惑-我猜是因为对于某些试验波函数,我的变分能量低于我的基态能量,所以我必须做一些非常错误的事情-但是如果我使用确切的波函数,我确实得到了确切的能量。为什么会这样?

这里是我的代码供参考。导入数学导入随机导入numpy

b = numpy.float_(1.2)

def psiT(r): #my trial wavefunction
    return (math.exp(-b*r))

def Elocal(r): 
    return -0.5*((b*b)-((2*b)/r))-(1/r)

def r(x,y,z): 
    return math.sqrt(math.pow(x,2)+math.pow(y,2)+math.pow(z,2))

ne = 3
a = 0
e = numpy.array([random.random() for i in range (ne)])

dr = 1.05
#equilibriate
for n in range (10000):
#move my electrons
    dt = numpy.array([dr*random.uniform(-1,1) for i in range (ne)])

    ep = e+dt
#was this move good?  
    R1 = r(e[0],e[1],e[2])
    Rp1 = r(ep[0],ep[1],ep[2])

    psip = psiT(Rp1)
    psi = psiT(R1)
    W = math.pow(psip/psi,2)  

    if W >= random.random():
        e = ep
        a = a+1
#accumulate
El = 0
q = 0
srt = 0
for n in range (10000):
#move my electrons
    dt = numpy.array([dr*random.uniform(-1,1) for i in range (ne)])

    ep = e+dt
    #was this move good?  
    R1 = r(e[0],e[1],e[2])
    Rp1 = r(ep[0],ep[1],ep[2])

    psip = psiT(Rp1)
    psi = psiT(R1)
    W = math.pow(psip/psi,2)    

    if W >= random.random():
        El = El+Elocal(Rp1)
        q = q+1
#ignore srt and s, I use them for error analysis which I have not     included here
        srt = srt+math.pow(Elocal(Rp1),2)
        s = math.pow((Elocal(Rp1))-(El/q),2)
        e = ep

print El/q
print q
1个回答

试验波函数,exp(1.2r), 不尊重尖点条件 - 波函数的导数需要取消1/r库仑项。如果没有正确的尖点条件,局部能量会在原点发散,这可能会导致积分值出现收敛问题。

一般来说,前导词应该是exp(Zr)(在哪里Z是核电荷)。要创建具有正确尖点的氢的试验波函数,请尝试添加更高的幂r,exp(r+ar2), 在哪里a是变分参数。

蒙特卡洛积分也有一个错误——接受和拒绝的移动都应该包含在总和中(这个代码只包括接受的移动)。否则,单个能量值在最终积分中的权重错误。并且能量(E1)的最终值应该除以总和中的总数(10000),而不仅仅是接受的数量。