聲明:本文轉自李雲海科學網博客的博文,本文只做學術交流,不做商業用途,原文請點擊文末閱讀原文。
[me@jacs mos2.save]$ h5dump wfc1.hdf5 > wfc1.txt[me@jacs mos2.save]$ vi wfc1.txt文件一開始是一些屬性信息:
HDF5 "wfc1.hdf5" {GROUP "/" { ATTRIBUTE "gamma_only" { DATATYPE H5T_STRING { STRSIZE 7; STRPAD H5T_STR_SPACEPAD; CSET H5T_CSET_ASCII; CTYPE H5T_C_S1; } DATASPACE SCALAR DATA { (0): ".FALSE." } } ATTRIBUTE "igwx" { DATATYPE H5T_STD_I32LE DATASPACE SCALAR DATA { (0): 7401 } }... ...gamma_only:布爾型,表明此波函數是否由Gamma point specific算法生成,若為True平面波個數會減半scale_factor:浮點型,倒空間基矢笛卡爾坐標縮放因子緊跟其後的是數據集MillerIndices中的數據和屬性。這個數據集存儲了每個平面波對應的倒空間矢量,也就是
DATASET "MillerIndices" { DATATYPE H5T_STD_I32LE DATASPACE SIMPLE { ( 7401, 3 ) / ( 7401, 3 ) } DATA { (0,0): 0, 0, 0, (1,0): 0, 0, -1, (2,0): 0, 0, 1, (3,0): 0, 0, -2, (4,0): 0, 0, 2, (5,0): 0, 0, -3, (6,0): 0, 0, 3,... ... (7399,0): 0, 0, -37, (7400,0): 0, 0, 37 } ATTRIBUTE "bg1" { DATATYPE H5T_ARRAY { [3] H5T_IEEE_F64LE } DATASPACE SCALAR DATA { (0): [ 1.04511, 0.603391, -0 ] } } ATTRIBUTE "bg2" { DATATYPE H5T_ARRAY { [3] H5T_IEEE_F64LE } DATASPACE SCALAR DATA { (0): [ 0, 1.20679, 0 ] } } ATTRIBUTE "bg3" { DATATYPE H5T_ARRAY { [3] H5T_IEEE_F64LE } DATASPACE SCALAR DATA { (0): [ 0, -0, 0.209114 ] } } ATTRIBUTE "doc" { DATATYPE H5T_STRING { STRSIZE 77; STRPAD H5T_STR_SPACEPAD; CSET H5T_CSET_ASCII; CTYPE H5T_C_S1; } DATASPACE SCALAR DATA { (0): "Miller Indices of the wave-vectors, same ordering as wave-function components" } }根據ngw屬性的值,共有7401個平面波。每個平面波對應的倒空間矢量用三個整數存儲,數組尺寸為7401*3。需注意的是,h5dump是用C語言編寫的,數組下標從0開始,並且行優先。FORTRAN則與之相反,在寫入這部分數據的FORTRAN代碼中,數組下標為1-7401,尺寸為3*7401。若用FORTRAN代碼去讀取這部分數據,也應該申請尺寸為3*7401的數組。緊跟數據的是三個屬性bg1-bg3,分別表示倒空間基矢b1-b3的笛卡爾坐標。屬性doc為注釋,表明G矢量的排列順序和平面波展開係數一致。DATASET "evc" { DATATYPE H5T_IEEE_F64LE DATASPACE SIMPLE { ( 9, 14802 ) / ( 9, 14802 ) } DATA { (0,0): 0.54088, -0.00350892, -0.385045, -0.203002, -0.382379, 0.20798, (0,6): 0.110416, 0.163513, 0.108285, -0.164932, 0.00211342, 0.0205407, (0,12): 0.00184674, -0.0205664, 0.0485897, -0.11843, 0.0501221, (0,17): 0.11779, -0.101751, 0.0839421, -0.102832, -0.0826149, (0,22): 0.0918935, 0.00349047, 0.0918404, -0.00468243, 0.0918934, (0,27): 0.00349047, 0.0918404, -0.00468243, 0.0918402, -0.00468273, (0,32): 0.0918932, 0.00349077, -0.064341, -0.0387719, -0.0679325, (0,37): 0.0320652, -0.0683428, -0.0311811, -0.0638325, 0.0396034,... ... (8,14801): 1.42571e-05 } ATTRIBUTE "doc:" { DATATYPE H5T_STRING { STRSIZE 145; STRPAD H5T_STR_SPACEPAD; CSET H5T_CSET_ASCII; CTYPE H5T_C_S1; } DATASPACE SCALAR DATA { (0): "Wave Functions, (npwx,nbnd), each contiguous line represents a wave function, each complex coefficient is given by a couple of contiguous floats" } } }數據部分是一個9*14802的數組,數據類型是雙精度浮點數。9代表9條能帶。由於HDF5庫不支持複數類型,QE把複數的實部和虛部當作兩個相鄰的浮點數處理。根據MillerIndices中的信息,基組中共有7401個平面波,所以每條能帶需要用7401*2=14802個浮點數表示。屬性doc為注釋,由於數據集由FORTRAN程序生成,所以注釋中數組的大小是(npw, nbnd),也就是7401*9,與h5dump顯示方式正好相反。當輸入文件中K點設置方式為K_POINTS {gamma}時,QE會利用平面波展開係數的對稱性把除(0, 0, 0)以外的G矢量約掉一半。此時平面波個數只有1+(7401-1)/2=3401個,波函數展開係數也會減少。在處理波函數(如作內積)時需注意到這一點,把被約掉部分的貢獻考慮進來。波函數讀取我們用一個程序演示下如何用python HDF5庫(h5py)讀取波函數並驗證正交歸一性:#! /usr/bin/env python import h5py import numpy as np f1 = h5py.File("wfc1.hdf5") for i in range(9): for k in range(9): vi = f1['evc'][i].view(complex) vk = f1['evc'][k].view(complex) prod = np.vdot(vi, vk) print("%4d%4d%20.9e%20.9e" % (i+1, k+1, prod.real, prod.imag)) f1.close()第6行打開波函數文件並返回一個HDF5 File對象,第15行關閉該對象。這兩步都是固定操作。在第10-12行中,我們先用f1['evc']獲取波函數展開係數對應的數組,再分別取其第i行和第k行,接著將這兩行從浮點數轉換為複數,最後取其內積。需注意numpy默認的數組行為與C語言一致,下標從0開始,行優先。在使用模守恆贗勢的情況下,波函數的正交歸一性是相當不錯的。對角元都等於1,非對角元非常小:
1 1 1.000000000e+00 0.000000000e+00 1 2 0.000000000e+00 2.385244779e-16 1 3 -1.301042607e-17 5.862823248e-17 1 4 1.044840369e-17 1.153786310e-16 1 5 1.654001236e-17 6.810257889e-17 1 6 1.353084311e-16 1.973247954e-17 1 7 -4.834652305e-17 -2.871150524e-17 1 8 4.886076366e-17 -5.320187141e-17 1 9 8.326672685e-17 -1.994931997e-17 2 1 0.000000000e+00 -2.385244779e-16 2 2 1.000000000e+00 0.000000000e+00 2 3 1.942890293e-16 -6.559423144e-16 2 4 1.863217563e-16 -7.420547919e-17 2 5 7.047404118e-17 -1.284609837e-17 2 6 -8.326672685e-17 3.534499082e-17 2 7 8.792201992e-18 6.776065055e-17 2 8 -7.430109817e-17 -4.297889677e-17 2 9 -1.665334537e-16 -4.683753385e-17 3 1 -1.301042607e-17 -5.862823248e-17 3 2 1.942890293e-16 6.559423144e-16 3 3 1.000000000e+00 0.000000000e+00... ...如果用Gamma point specific算法生成波函數,上述驗證正交歸一性的程序就需要做部分修改:
10 vi = f1['evc'][i].view(complex) 11 vk = f1['evc'][k].view(complex) 12 prod = np.vdot(vi, vk) 13 prod += prod.conjugate() 14 prod -= vi[0].conjugate() * vk[0]第12行計算一次波函數內積,第13行把被約掉部分的貢獻疊加上去。由於(0,0,0)點被計算了兩次,所以要在第14行扣掉一次。正交歸一性如下:1 1 1.000000000e+00 0.000000000e+00 1 2 -1.026468407e-16 0.000000000e+00 1 3 -1.040834086e-16 0.000000000e+00 1 4 5.383665643e-17 0.000000000e+00 1 5 -4.516591433e-17 0.000000000e+00 1 6 3.039221779e-16 0.000000000e+00 1 7 6.630590951e-17 0.000000000e+00 1 8 -9.741762322e-18 0.000000000e+00 1 9 2.636779683e-16 0.000000000e+00 2 1 -1.026468407e-16 0.000000000e+00 2 2 1.000000000e+00 0.000000000e+00 2 3 -5.322843979e-16 0.000000000e+00 2 4 -1.117805618e-16 0.000000000e+00 2 5 -1.351550723e-16 0.000000000e+00 2 6 -1.766979661e-16 0.000000000e+00 2 7 3.830849052e-17 0.000000000e+00 2 8 -6.423501709e-17 0.000000000e+00 2 9 -7.960415638e-17 0.000000000e+00 3 1 -1.040834086e-16 0.000000000e+00 3 2 -5.322843979e-16 0.000000000e+00 3 3 1.000000000e+00 0.000000000e+00... ...讀取波函數以後,計算實空間中某一點的波函數值就很簡單了:程序在這裡就不放了。如果需要計算大量實空間中的點,可以用快速傅立葉變換。如果要驗證波函數空間反演對稱性,只需取一些點,驗證