這一章繼續講c_bands的重要部份,計算 |\psi_j\rangle = H|\phi_j\rangle 的h_psi -> h_psi_函數。
由於DFT考慮的效應越來越多,h_psi函數也就成了個逐漸疊buff的函數,最基本的是兩項
! 動能 T * phi,直接在G空間計算
DO
ibnd
=
1
,
m
hpsi
(
1
:
n
,
ibnd
)
=
g2kin
(
1
:
n
)
*
psi
(
1
:
n
,
ibnd
)
ENDDO
! 勢能(離子,Vxc等) V * phi,實空間計算
CALL
vloc_psi_k
(
lda
,
n
,
m
,
psi
,
vrs
(
1
,
current_spin
),
hpsi
)
其他效應包括
! Meta-GGA, 比如SCAN
IF
(
xclib_dft_is
(
'meta'
))
CALL
h_psi_meta
(
lda
,
n
,
m
,
psi
,
hpsi
)
! Exact Exchange, 混成泛函
CALL
vexx
(
lda
,
n
,
m
,
psi
,
hpsi
,
becp
)
! 體相電場,https://www.quantum-espresso.org/Doc/INPUT_PW.html#lelfield
CALL
h_epsi_her_apply
(
lda
,
n
,
m
,
psi
,
hpsi
,
ipol
,
efield_cry
(
ipol
)
)
! DFT + U
CALL
vhpsi
(
lda
,
n
,
m
,
psi
,
hpsi
)
囊括這些效應,只需要在上述這些函數中,對hpsi進行累加即可
COMPLEX
(
DP
),
INTENT
(
INOUT
)
::
hpsi
(
lda
,
m
)
hpsi
=
hpsi
+
....
籠統地說,除了動能計算是非常簡單粗暴的G空間向量 乘法,所有的勢能波函數乘法都是在實空間進行的。基本思路如下:
- 構建實空間的勢能函數V(r)。大部份的勢場函數 ,這一步在進入c_bands之前就計算完成了,應該會在後面詳細講(再次挖坑)。
- 對G空間波函數\phi(G) 進行傅立葉變換FFT,得到實空間波函數 \phi(r) ;
- 在實空間進行對應的乘法 \psi(r) = V(r)\phi(r) ;
- 將 \psi(r) 進行傅立葉變換回到G空間 \psi(G) .
相應的程式如下 (vloc_psi_k) [1] :
DO
ibnd
=
1
,
m
! 第ibnd個波函數 psi(G) 賦值一個臨時變量psic
DO
j
=
1
,
n
psic
(
dffts
%
nl
(
igk_k
(
j
,
current_k
)))
=
psi
(
j
,
ibnd
)
ENDDO
! psic做FFT,註意psic的值既是輸入也是輸出,也就是說結束後psic中存了實空間的波函數
! 這也是為什麽要把psi的值拷貝給psic
CALL
invfft
(
'Wave'
,
psic
,
dffts
)
! 在實空間計算 psi * V,
! 註意這裏是對所有實空間格點dffts%nnr遍歷
! 結束後 psic再次變成 V(r)\phi(r)
! 這一切都是為了省記憶體空間.....
DO
j
=
1
,
dffts
%
nnr
psic
(
j
)
=
psic
(
j
)
*
v
(
j
)
ENDDO
! 將V\phi經過FFT變回到G空間,同樣的,psic被改變了,成了V\phi(G)
CALL
fwfft
(
'Wave'
,
psic
,
dffts
)
! 將 psic 累加到 hpsi 上,hpsi是輸出,psic將被釋放
DO
j
=
1
,
n
hpsi
(
j
,
ibnd
)
=
hpsi
(
j
,
ibnd
)
+
psic
(
dffts
%
nl
(
igk_k
(
j
,
current_k
)))
ENDDO
ENDDO
如我上一章提到的,這一章很線性,邏輯上沒啥難點。重點就是了解勢場是實空間計算,以及如何計算的即可。
這兩章就解決了如何計算哈密頓量 和解本征值/矢的問題,下一章.....下一章該講什麽來著?
(早知道不挖這麽大的坑了,含淚填吧.....)
哦想起來了,下一章講怎麽有了本征值/矢,怎麽算占據數和電荷密度 (sum_band)。
參考
- ^ 這一段是實際的函數,註釋是我加的。包括註釋也就這麽長,可謂十分簡潔易懂。前提是不引入openmp,能帶並列等效率最佳化部份