編寫一個量化計算程序,求解簡單限制性HartreeFock方程(python編寫)

2021-02-26 AI材料設計

上次說完HF方程需要自洽場迭代求解,這次我們來寫一個程序實現自洽場過程。下面是上次解讀的傳送門,建議先看理論再來看這次如何實現自洽場迭代程序

淺談量子化學(2)Hartree Fock


解Hartree-Fock-Roothaan方程:

SCF的過程為:

1.明確一個分子(原子的坐標集合{RA},原子數目{ZA},電子的數量{N},和一個基組)

2.計算所有需求的分子積分

3.重疊積分S對角化,並獲得一個轉換的矩陣X(有兩種方式:對稱正交化和標準正交化)

4.獲得一個初始的密度矩陣P

5.通過密度矩陣P和兩電子積分,帶入方程算出fock矩陣的兩電子積分項G

6.把前面得到的Fock矩陣的兩電子積分項與單電子的哈密頓算法積分相加得到Fock矩陣

7.計算轉換後的Fock矩陣,使用公式

8.對角化F'獲得新的係數矩陣C'和能量本徵值

9.將新的係數矩陣與老的係數矩陣通過X聯繫起來

10.把C帶入方程


獲得其密度矩陣,其表徵電子在分子各個原子中或原子之間的分布情況。

11.判斷是否收斂,可用能量或密度矩陣來判斷---新的密度矩陣(能量)是否與先前的密度矩陣(能量)達到了我們設定的誤差值之內

12.如果程序收斂了,就可以用得到的解去算其他的量子性質了

編寫代碼部分

從上面我們可以得到,第4步往前,都是我們在進行自洽場過程之前需要有的結果,明確你要計算的分子,求出它的,及初始密度矩陣P

為了尋求簡單,我們只算H2分子。為什麼算H2分子呢,因為以上要先求出的值呢,書上都已經給我們求好了。

import mathimport numpy as np

def calc_Hcore_H2(): dim = 2 Hcore = np.zeros( (dim,dim) ) Hcore[0,0] = Hcore[1,1] = -1.1204 Hcore[0,1] = Hcore[1,0] = -0.9584    return Hcore

def calc_S_H2():    dim = 2    S = np.zeros( (dim, dim) )    S[0, 0] = S[1,1] = 1.    S[0, 1] = S[1,0] = 0.6593    return S

將S對角化得X:

def symmetric_orthogonalization(S):            l, U = np.linalg.eigh(S)    l_rt = np.zeros( S.shape )    for i in range(len(l)):        l_rt[i,i] = 1./(math.sqrt(l[i]))    X =  U.dot(l_rt.dot(np.conjugate(U)))     return X

def eri_table(u,v,p,q):        if u < v:        u,v = v,u        if p < q:        p,q = q,p        if (u+1)*(v+1) < (p+1)*(q+1):        u,v,p,q = p,q,u,v            if (u,v,p,q) == (0,0,0,0) or (u,v,p,q) == (1,1,1,1):        return 0.7746    elif (u,v,p,q) == (1,1,0,0):        return 0.5697    elif (u,v,p,q) == (1,0,0,0) or (u,v,p,q) == (1,1,1,0):        return 0.4441    elif (u,v,p,q) == (1,0,1,0):        return 0.2970    else:                print(u,v,p,q)        raise

初始的密度矩陣呢,就寫成零矩陣,反正後期迭代也會產生新的密度矩陣。

def guess_D():    dim = 2    D = np.zeros( (dim,dim) )    return D

前四步我們已經做完了,接下來做第五步計算G,公式見上面

def calc_G_H2(D):
G = np.zeros(D.shape) dim = D.shape[0] for u in range(dim): for v in range(dim): temp = 0. for p in range(dim): for q in range(dim): doubleJ = eri_table(u,v,p,q) K = 0.5 * eri_table(u,q,p,v) temp += D[p,q] * (doubleJ - K) G[u,v] = temp return G

第六步,相加得到Fock矩陣。這一步由於都是變量,所以需要定義在函數當中迭代(待會一起寫)

第七步為計算轉換後的Fock矩陣,並且第八步對角化F'獲得新的係數矩陣C'和能量本徵值,由於是迭代過程也得寫在迭代的函數當中。

第九步將新矩陣與原矩陣聯繫,第十步計算新的密度矩陣,判斷密度矩陣與原矩陣是否收斂

首先要寫一個判斷是否收斂的函數用rmsd均方根誤差來判斷吧。

def calc_rmsd(m1,m2):    d = m1 - m2    ret =  np.sum(d**2)/d.size    return ret

得到新的密度矩陣D,計算均方誤差,如果小於設定值就收斂,將這個值賦給D,如果沒有小於就進行下一次循環(也得寫在迭代函數中,待會一併給出)。

我們再寫一個計算能量的函數

def calc_E0_rhf(D,Hcore,F):        H_F = Hcore + F    row, col = H_F.shape    E0 = 0.    for u in range(row):        for v in range(col):            E0 += D[v,u] * H_F[u,v]    E0 *= 0.5;    return E0
def calc_E1():              E1 = 1/1.4    return E1

最後整合一下以上需要迭代的量寫一個函數:

def rhf(nelec):    n_occ_orbitals = 1 # int(nelec/2)    max_iteration = 10    convergence_threshold = 1.e-4  #最小收斂值    dim = 2 # The number of Basis functions
S = calc_S_H2() X = symmetric_orthogonalization(S) X_adj = np.matrix.getH(X) # np.matrix.getH() returns the adjoint matrix 返回伴隨矩陣
assert np.allclose( X_adj.dot(S.dot(X)), np.identity(dim) ), \ "X does not satisfy (X_adjoint * S * X)"
Hcore = calc_Hcore_H2() D = guess_D()
for i in range(max_iteration): print("**** iteration: {} ****".format(i+1)) G = calc_G_H2(D) F = Hcore + G
F_prime = X_adj.dot(F.dot(X)) e, C_new_prime = np.linalg.eigh(F_prime) #返回厄密矩陣或對稱矩陣的特徵值和特徵向量。
C_new = X.dot(C_new_prime) D_new = calc_D_rhf(C_new, n_occ_orbitals) E0 = calc_E0_rhf(D, Hcore, F) rmsd = calc_rmsd(D_new, D) D = D_new E1 = calc_E1() Etot = E0 + E1 print("Etot: ", Etot) print("RMSD:", rmsd) if rmsd < convergence_threshold: break return E0

我們只需要運行這個函數就可以得到H2分子的能量了。

結果為:

我們使用高斯計算一下H2,做比較

可以說結果相當的接近了!

 

 

參考網站:量子化學計算コードを自作してみた記録 その1https://qiita.com/swakamoto/items/5694fdb099cb96b050e8#%E9%87%8D%E3%81%AA%E3%82%8A%E7%A9%8D%E5%88%86s%E3%81%AE%E5%AF%BE%E8%A7%92%E5%8C%96

參考書籍:Szabo A , Ostlund N S . Modern quantum chemistry : introduction to advanced electronic structure theory[J]. 1989.

如有概念錯誤,還請指出,我將甚為感謝,如需轉載,請在公眾號聊天框說明。

免責聲明:部分圖片及資料來源於網絡,轉載的目的在於傳遞更多信息及分享,如涉及侵權,請聯繫我及時修改或刪除。

相關焦點

  • 一日一技:用Python程序求解二次方程式
    用Python程序求解二次方程式> 當我們已給出係數a,b和c時,用python程序計算二次方程的根值。
  • R語言中求解一元方程的根
    >該函數的結果是一個包含4部分的列表:求解的根root和在該點的函數值f.root;迭代次數iter和求解方程的近似估計的精度estim.prec。如求解 3x + 2 = 0的根,編寫程序及運行結果如下:R中求解一元一次方程的根在該例子中,首先定義了一個函數f,用於返回形如ax+b的值。
  • 如何在Python中編寫簡單代碼,並且速度超越Spark?
    如果你想在Python中編寫簡單代碼,並且用比Spark更快的速度運行,同時無需重新編碼、無需開發者解決部署、擴展和監控問題,可能嗎?你可能會「說我是一個夢想家」。我是一個夢想家,但不是唯一的一個!本篇文章將證明如今可以使用Nuclio和RAPIDSlimg令以上設想成為現實,它們是由NVIDIA孵化的免費開源數據科學加速平臺。
  • 初識pycharm編寫方法
    使用pycharm編輯器 雙擊我們安裝好的pycharm編輯器(安裝過程在前幾節)選擇第一個新建項目第一個pure python是純python,下面的那些是一些擴展,暫時不用,我們就選第一個Location是選擇編寫代碼保存的路徑,根據自己的情況點右側小文件夾按鈕,自行選擇一個路徑保存即可保存後點擊右下角的
  • 數據科學的Python軟體包
    簡單易學與其他任何程式語言相比,選擇Python是一個顯而易見的直接原因。Python使用簡單明了的語法來編寫代碼,用Python編寫代碼非常容易,感覺就像您是用英語編寫直接指令一樣。減少編碼數據科學和機器算法非常複雜,因此我們需要一種可以輕鬆實現並減少代碼數量的程式語言。Python帶有平滑且縮進的語法,可幫助開發人員在更少的代碼中構建程序。
  • 利用python計算函數與x軸之間的面積
    本文要實現一個簡單的功能,在直角坐標系中,求解任意一個函數與x軸之間構成的面積。用數學表達式表示出來就是:也就是求解任意一個函數的絕對值與x軸之間構成的面積,我們以函數sin(x)為例(因為函數sin(x)便於對計算結果進行檢驗),如圖所示:我們用積分的定義來計算,積分就是將函數分成無數的小段,然後對每一小段進行求和處理。
  • 寫一個用迭代法解方程的Java程序
    1.定義解釋 迭代法也稱輾轉法,是一種逐次逼近方法,在使用迭代法解方程組時,其係數矩陣在計算過程中始終不變。它利用計算機運算速度快、適合做重複性操作的特點,讓計算機對一組指令(或一定步驟)進行重複執行,在每次執行這組指令(或步驟)時,都從變量的原值推出它的一個新值。
  • 2019數學建模國賽|Matlab 求解微分方程(組)
    2.函數 dsolve 求解的是常微分方程的精確解法,也稱為常微分方程的符號解.但是,有大量的常微分方程雖然從理論上講,其解是存在的,但我們卻無法求出其解析解,此時,我們需要尋求方程的數值解,在求常微分方程數值解方面,MATLAB 具有豐富的函數,將其統稱為 solver,其一般格式為:           [T,Y]=solver(odefun,tspan,y0)
  • 精研多年,計算瞬間,具有國際水平的有限元軟體FEPG的特色
    精研多年,計算瞬間――具有國際水平的有限元軟體FEPG的特色有限元方法是求解偏微分方程的一種數值方法     偏微分方程是描述客觀世界數量關係的一種重要的數學方法。大量的工程、科學、技術和生產問題常常歸結為微分方程的求解。
  • DeepMind開源薛丁格方程求解程序:從量子力學原理出發,TensorFlow...
    曉查 發自 凹非寺量子位 報導 | 公眾號 QbitAI只要解出薛丁格方程,你就能預測分子的化學性質。但現實很骨感,迄今為止,科學家只能精確求解一個電子的氫原子,即使是只有兩個電子的氦原子都無能為力。
  • 令人讚嘆的8個Python新手工具!
    3、TheanoTheano是一個較老牌和穩定的機器學習python庫之一,雖然目前使用的人數有所下降。但它畢竟是一個祖師級的存在,一定有它的優點所在。Theano基於Python擅長處理多維數組,屬於比較底層的框架,theano起初也是為了深度學習中大規模人工神經網絡算法的運算所設計,我們可利用符號化式語言定義想要的結果,支持GPU加速,非常適合深度學習Python。
  • 機器人課程系列:如何編寫Arduino程序讓四足機器人移動
    這篇文章為你介紹讓四足機器人「走路」的方法,也就是行走的步態(gaits),並教你如何為Arduino編寫程序。關於四足機器人自然界裡有許多用四隻腳走路的動物,這是因為四隻腳是一種很穩定的組合,不需要特別調整姿勢就能保持站姿穩定,又比六足構造單純一些。
  • 【暢言】首先為人編寫程序,其次才是計算機
    老員工寫出的代碼對新員工有示範的作用,如果老員工寫出的程序都是可讀性很差的,那麼新員工會怎麼想呢?他們又會怎麼做呢?很多開發人員每天只顧埋頭苦幹,卻忽略了一些最基本的東西,因此能力很難再次得到提升。在編寫完代碼之後,不要就以為事情做完了,還要編寫一些項目文檔,如詳細設計文檔、單元/集成測試文檔等。在這些文檔裡面,把自己的思路寫清楚,方便以後自己或他人查閱起來能夠很快理解程序思路。
  • python基礎知識科普:python的起源和發展史以及應用場景
    他作為一個數學家其實更大的樂趣卻在計算機編程裡面。在Guido的那個年代程式語言的設計原則是讓機器更快的運行,諸如Pascal、C、Fortran等語言。但是這樣的編程方式,編寫一個程序的過程需要耗費大量的時間,所以他的另一個選擇是shell。Bourne Shell作為UNIX系統的解釋器已經長期存在。
  • 北大楊超:以偏微分方程求解為例,AI如何助力科學計算?
    1950年,馮諾伊曼和他的助手改造了ENIAC的可編程性,並在這個基礎上編寫了世界上第一個天氣預報程序,成功完成了24小時預報,實現了理察森之夢,也成為了科學計算的蓬勃發展的一個重要開端。藉助神經網絡這類數學工具,我們是不是可以解一些之前難以求解的問題呢?在這裡,我列出了三個比較有特色的方程,它們都有強烈的非線性,並且計算區域具有不規則和高維的特點。比如第一個方程的計算區域雖然是二維,但是區域邊界非常複雜。中間是三維的例子,其計算區域是一個扭曲的torus形成,採用經典方法很難準確的刻劃。第三個是100維的超立方體,它高維的性質決定了經典的方法很難去求解。
  • ABB機器人二次開發:基於PC SDK的控制器連接程序編寫
    引言上一期為大家介紹了基於PC SDK的ABB機器人控制器掃描程序的編寫方法,按照程序設計編寫流程,下一步就是機器人控制器的遠程登錄或遠程註銷登錄程序的編寫,也就是控制器的連接與斷開。本期就來為大家介紹一下這個功能的實現方法,使用的計算機語言同樣是C#。
  • 微積分問題的MATLAB求解(一)
    後續幾期,向大家介紹微積分問題的MATLAB求解,今天講解極限,積分和微分方程的求解。1. 極限MATLAB提供了求極限函數limit(),函數調用格式為:y = limit(fun,x,x0)。3 微分方程的數值解求解微積分方程你的數值解常用的MATLAB函數調用如下:[t, x] = ode23(『xprime』, t0, tf, x0, tol, trace)
  • python基礎教程之python是什麼?
    Python是著名的「龜叔」Guido van Rossum在1989年聖誕節期間,為了打發無聊的聖誕節而編寫的一個程式語言。C語言是可以用來編寫作業系統的貼近硬體的語言,所以,C語言適合開發那些追求運行速度、充分發揮硬體性能的程序。而Python是用來編寫應用程式的高級程式語言。當你用一種語言開始作真正的軟體開發時,你除了編寫代碼外,還需要很多基本的已經寫好的現成的東西,來幫助你加快開發進度。
  • 編寫一個簡單的遊戲來練習用 C+編程|Linux 中國
    不管是哪種情況,學習這些新原理的便捷方法是創建一個簡單的猜謎遊戲。這會迫使你了解一門語言如何接收輸入和發送輸出,如何比較數據,如何控制程序的流程,以及如何利用條件來影響結果。它還確保你知道一門語言是如何組織其代碼的;例如,Lua 或Bash可以很容易地作為腳本運行,而Java則需要你創建一個類。