Skip to content

Commit 1e0b275

Browse files
wenfei-liwenfei-li
andauthored
Feature : added paw_cell_libpaw and test (#2815)
* added some subroutines for info gathering * added paw_cell_libpaw and test * added explanations on unit tests --------- Co-authored-by: wenfei-li <[email protected]>
1 parent 0eedc3c commit 1e0b275

File tree

9 files changed

+427
-0
lines changed

9 files changed

+427
-0
lines changed

source/module_cell/module_paw/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_library(
44
paw_element.cpp
55
paw_sphbes.cpp
66
paw_cell.cpp
7+
paw_cell_libpaw.cpp
78
)
89

910
if(ENABLE_COVERAGE)

source/module_cell/module_paw/paw_cell.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "paw_element.h"
1414
#include "paw_atom.h"
15+
#include "module_base/matrix3.h"
1516

1617
class Paw_Cell
1718
{
@@ -20,6 +21,8 @@ class Paw_Cell
2021
Paw_Cell(){};
2122
~Paw_Cell(){};
2223

24+
// PART I. Operations in ABACUS
25+
2326
void init_paw_cell(
2427
const double ecutwfc_in, const double cell_factor_in,
2528
const double omega_in,
@@ -151,6 +154,63 @@ class Paw_Cell
151154

152155
void set_ylm(const int npw_in, const double ** kpg);
153156

157+
// Part II. Passing infor for the initialization of PAW
158+
159+
public:
160+
// The following gathers information needed by LibPAW, they will be inserted
161+
// to proper places in the main program
162+
163+
// Cutoff energies, sets ecut and ecutpaw
164+
void set_libpaw_ecut(const double ecut_in, const double ecutpaw_in);
165+
// Sets rprimd, gprimd, gmet and ucvol
166+
// Input is latvec and lat0, will calculate the required info
167+
void set_libpaw_cell(const ModuleBase::Matrix3 latvec, const double lat0);
168+
// FFT grid information, sets ngfft and ngfftdg
169+
void set_libpaw_fft(const int nx_in, const int ny_in, const int nz_in,
170+
const int nxdg_in, const int nydg_in, const int nzdg_in);
171+
// Sets natom, ntypat, typat and xred
172+
void set_libpaw_atom(const int natom_in, const int ntypat_in, const int * typat_in, const double * xred_in);
173+
// Sets filename_list
174+
void set_libpaw_files();
175+
176+
// Extract the information
177+
double get_libpaw_ecut() {return ecut;}
178+
double get_libpaw_ecutpaw() {return ecutpaw;}
179+
std::vector<double> get_libpaw_rprimd() {return rprimd;}
180+
std::vector<double> get_libpaw_gprimd() {return gprimd;}
181+
std::vector<double> get_libpaw_gmet() {return gmet;}
182+
double get_libpaw_ucvol() {return ucvol;}
183+
std::vector<int> get_libpaw_ngfft() {return ngfft;}
184+
std::vector<int> get_libpaw_ngfftdg() {return ngfftdg;}
185+
int get_libpaw_natom() {return natom;}
186+
int get_libpaw_ntypat() {return ntypat;}
187+
std::vector<int> get_libpaw_typat() {return typat;}
188+
std::vector<double> get_libpaw_xred() {return xred;}
189+
char* get_libpaw_filename_list() {return filename_list;}
190+
191+
private:
192+
// Info to be passed to libpaw_interface:
193+
// 1. ecut, ecutpaw : kinetic energy cutoff of the planewave basis set
194+
// there will be one coarse grid for density/potential, and a fine grid for PAW
195+
// the unit is in Hartree
196+
// 2. rprimd, gprimd : real and reciprocal space lattice vectors, respectively
197+
// unit for rprimd is in Bohr, and for gprimd is in Bohr^-1
198+
// 3. gmet : reciprocal space metric (bohr^-2)
199+
// 4. ucvol : volume of unit cell (Bohr^3)
200+
// 5. ngfft, ngfftdg : dimension of FFT grids of the corase and fine grids
201+
// 6. natom, ntypat, typat: #. atoms, #. element types
202+
// and typat records the type of each atom
203+
// 7. xred : coordinate of each atom, in terms of rprimd (namely, direct coordinate)
204+
// 8. filename_list : filename of the PAW xml files for each element
205+
206+
double ecut, ecutpaw;
207+
std::vector<double> rprimd, gprimd, gmet;
208+
double ucvol;
209+
std::vector<int> ngfft, ngfftdg;
210+
int natom, ntypat;
211+
std::vector<int> typat;
212+
std::vector<double> xred;
213+
char* filename_list;
154214
};
155215

156216
#endif
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
#include "module_base/tool_quit.h"
2+
#include "module_base/tool_title.h"
3+
#include "paw_cell.h"
4+
#include "module_base/global_variable.h"
5+
6+
// The subroutines here are used to gather information from the main ABACUS program
7+
// 1. ecut, ecutpaw : kinetic energy cutoff of the planewave basis set
8+
// there will be one coarse grid for density/potential, and a fine grid for PAW
9+
// the unit is in Hartree
10+
// 2. rprimd, gprimd : real and reciprocal space lattice vectors, respectively
11+
// unit for rprimd is in Bohr, and for gprimd is in Bohr^-1
12+
// 3. gmet : reciprocal space metric (bohr^-2)
13+
// 4. ucvol : volume of unit cell (Bohr^3)
14+
// 5. ngfft, ngfftdg : dimension of FFT grids of the corase and fine grids
15+
// 6. natom, ntypat, typat: #. atoms, #. element types
16+
// and typat records the type of each atom
17+
// 7. xred : coordinate of each atom, in terms of rprimd (namely, direct coordinate)
18+
// 8. filename_list : filename of the PAW xml files for each element
19+
20+
// Cutoff energies, sets ecut and ecutpaw
21+
void Paw_Cell::set_libpaw_ecut(const double ecut_in, const double ecutpaw_in)
22+
{
23+
ModuleBase::TITLE("Paw_Cell", "set_libpaw_ecut");
24+
ecut = ecut_in;
25+
ecutpaw = ecutpaw_in;
26+
}
27+
28+
// inverse of 3 by 3 matrix, needed by set_libpaw_cell to calculate gprimd
29+
// adapted from m_symtk/matr3inv of ABINIT
30+
31+
void matr3inv(std::vector<double>& mat_in, std::vector<double>& mat_out)
32+
{
33+
34+
assert(mat_in.size() == 9);
35+
assert(mat_out.size() == 9);
36+
37+
double t1 = mat_in[4] * mat_in[8] - mat_in[7] * mat_in[5];
38+
double t2 = mat_in[7] * mat_in[2] - mat_in[1] * mat_in[8];
39+
double t3 = mat_in[1] * mat_in[5] - mat_in[4] * mat_in[2];
40+
double det = mat_in[0] * t1 + mat_in[3] * t2 + mat_in[6] * t3;
41+
42+
double dd;
43+
if (std::abs(det) > 1e-16)
44+
{
45+
dd = 1.0 / det;
46+
}
47+
else
48+
{
49+
ModuleBase::WARNING_QUIT("matr3inv", "matrix is singular!");
50+
}
51+
52+
mat_out[0] = t1 * dd;
53+
mat_out[3] = t2 * dd;
54+
mat_out[6] = t3 * dd;
55+
mat_out[1] = (mat_in[6] * mat_in[5] - mat_in[3] * mat_in[8]) * dd;
56+
mat_out[4] = (mat_in[0] * mat_in[8] - mat_in[6] * mat_in[2]) * dd;
57+
mat_out[7] = (mat_in[3] * mat_in[2] - mat_in[0] * mat_in[5]) * dd;
58+
mat_out[2] = (mat_in[3] * mat_in[7] - mat_in[6] * mat_in[4]) * dd;
59+
mat_out[5] = (mat_in[6] * mat_in[1] - mat_in[0] * mat_in[7]) * dd;
60+
mat_out[8] = (mat_in[0] * mat_in[4] - mat_in[3] * mat_in[1]) * dd;
61+
}
62+
63+
// calculates G = A^T A for 3 by 3 matrix
64+
// G_ij = sum_k A_ki A_kj
65+
66+
void mattmat(std::vector<double>& mat_in, std::vector<double>& mat_out)
67+
{
68+
mat_out[0] = mat_in[0] * mat_in[0] + mat_in[1] * mat_in[1] + mat_in[2] * mat_in[2];
69+
mat_out[1] = mat_in[0] * mat_in[3] + mat_in[1] * mat_in[4] + mat_in[2] * mat_in[5];
70+
mat_out[2] = mat_in[0] * mat_in[6] + mat_in[1] * mat_in[7] + mat_in[2] * mat_in[8];
71+
mat_out[3] = mat_in[3] * mat_in[0] + mat_in[4] * mat_in[1] + mat_in[5] * mat_in[2];
72+
mat_out[4] = mat_in[3] * mat_in[3] + mat_in[4] * mat_in[4] + mat_in[5] * mat_in[5];
73+
mat_out[5] = mat_in[3] * mat_in[6] + mat_in[4] * mat_in[7] + mat_in[5] * mat_in[8];
74+
mat_out[6] = mat_in[6] * mat_in[0] + mat_in[7] * mat_in[1] + mat_in[8] * mat_in[2];
75+
mat_out[7] = mat_in[6] * mat_in[3] + mat_in[7] * mat_in[4] + mat_in[8] * mat_in[5];
76+
mat_out[8] = mat_in[6] * mat_in[6] + mat_in[7] * mat_in[7] + mat_in[8] * mat_in[8];
77+
}
78+
79+
// Sets rprimd, gprimd, gmet and ucvol
80+
// Only real space lattice vector needed, others are to be calculated
81+
void Paw_Cell::set_libpaw_cell(const ModuleBase::Matrix3 latvec, const double lat0)
82+
{
83+
ModuleBase::TITLE("Paw_Cell", "set_libpaw_cell");
84+
85+
rprimd.resize(9);
86+
gprimd.resize(9);
87+
gmet.resize(9);
88+
89+
rprimd[0] = latvec.e11 * lat0;
90+
rprimd[1] = latvec.e12 * lat0;
91+
rprimd[2] = latvec.e13 * lat0;
92+
rprimd[3] = latvec.e21 * lat0;
93+
rprimd[4] = latvec.e22 * lat0;
94+
rprimd[5] = latvec.e23 * lat0;
95+
rprimd[6] = latvec.e31 * lat0;
96+
rprimd[7] = latvec.e32 * lat0;
97+
rprimd[8] = latvec.e33 * lat0;
98+
99+
// calculating gprimd, gmet and ucvol, adapted from m_geometry/metric of ABINIT
100+
101+
// Compute first dimensional primitive translation vectors in reciprocal space
102+
// gprimd from rprimd
103+
// Then, computes metrics for real and recip space rmet and gmet using length
104+
// dimensional primitive translation vectors in columns of rprimd(3,3) and gprimd(3,3).
105+
// gprimd is the inverse transpose of rprimd.
106+
// i.e. $ rmet_{i,j}= \sum_k ( rprimd_{k,i}*rprimd_{k,j} ) $
107+
// $ gmet_{i,j}= \sum_k ( gprimd_{k,i}*gprimd_{k,j} ) $
108+
// Also computes unit cell volume ucvol in $\textrm{bohr}^3$
109+
110+
// Compute unit cell volume
111+
// ucvol=rprimd(1,1)*(rprimd(2,2)*rprimd(3,3)-rprimd(3,2)*rprimd(2,3))+&
112+
// rprimd(2,1)*(rprimd(3,2)*rprimd(1,3)-rprimd(1,2)*rprimd(3,3))+&
113+
// rprimd(3,1)*(rprimd(1,2)*rprimd(2,3)-rprimd(2,2)*rprimd(1,3))
114+
ucvol = rprimd[0] * (rprimd[4] * rprimd[8] - rprimd[7] * rprimd[5])
115+
+ rprimd[3] * (rprimd[7] * rprimd[2] - rprimd[1] * rprimd[8])
116+
+ rprimd[6] * (rprimd[1] * rprimd[5] - rprimd[4] * rprimd[2]);
117+
// ucvol = det3r(rprimd)
118+
119+
if (std::abs(ucvol) < 1e-12)
120+
{
121+
ModuleBase::WARNING_QUIT("set_libpaw_cell", "ucvol vanishingly small");
122+
}
123+
124+
// ABACUS allows negative volume, but it seems ABINIT do not
125+
// I am not quite sure why, but to avoid possible complications I will follow ABINIT here
126+
// as the user can always just exchange two axis to make it positive
127+
if (ucvol < 0)
128+
{
129+
ModuleBase::WARNING_QUIT("set_libpaw_cell", "ucvol negative, one way to solve is to exchange two cell axis");
130+
}
131+
132+
// Generate gprimd
133+
matr3inv(rprimd, gprimd);
134+
135+
// Compute reciprocal space metric.
136+
mattmat(gprimd, gmet);
137+
}
138+
139+
// FFT grid information, sets ngfft and ngfftdg
140+
void Paw_Cell::set_libpaw_fft(const int nx_in, const int ny_in, const int nz_in,
141+
const int nxdg_in, const int nydg_in, const int nzdg_in)
142+
{
143+
ngfft.resize(3);
144+
ngfftdg.resize(3);
145+
146+
ngfft[0] = nx_in;
147+
ngfft[1] = ny_in;
148+
ngfft[2] = nz_in;
149+
ngfftdg[0] = nxdg_in;
150+
ngfftdg[1] = nydg_in;
151+
ngfftdg[2] = nzdg_in;
152+
}
153+
154+
// Sets natom, ntypat, typat and xred
155+
// !!!!!!!Note : the index stored in typat here will start from 1, not 0 !!!!!!
156+
void Paw_Cell::set_libpaw_atom(const int natom_in, const int ntypat_in, const int* typat_in, const double* xred_in)
157+
{
158+
natom = natom_in;
159+
ntypat = ntypat_in;
160+
161+
typat.resize(natom);
162+
xred.resize(3 * natom);
163+
164+
for(int iat = 0; iat < natom; iat ++)
165+
{
166+
typat[iat] = typat_in[iat];
167+
for(int j = 0; j < 3; j ++)
168+
{
169+
xred[3 * iat + j] = xred_in[3 * iat + j];
170+
}
171+
}
172+
}
173+
174+
// Sets filename_list
175+
// I'm going to read directly from STRU file
176+
void Paw_Cell::set_libpaw_files()
177+
{
178+
ModuleBase::TITLE("Paw_Cell", "set_libpaw_files");
179+
180+
if(GlobalV::MY_RANK == 0)
181+
{
182+
std::ifstream ifa(GlobalV::stru_file.c_str(), std::ios::in);
183+
if (!ifa)
184+
{
185+
ModuleBase::WARNING_QUIT("set_libpaw_files", "can not open stru file");
186+
}
187+
188+
std::string line;
189+
while(!ifa.eof())
190+
{
191+
getline(ifa,line);
192+
if (line.find("PAW_FILES") != std::string::npos) break;
193+
}
194+
195+
filename_list = new char[ntypat*264];
196+
for(int i = 0; i < ntypat; i++)
197+
{
198+
std::string filename;
199+
ifa >> filename;
200+
for(int j = 0; j < filename.size(); j++)
201+
{
202+
filename_list[264*i+j] = filename[j];
203+
}
204+
}
205+
}
206+
}

source/module_cell/module_paw/test/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ install(FILES sphbes_ref.dat func.dat qlist.dat fq_ref.dat
66
eigts.dat ca.dat rhoij.dat vkb_ref.dat
77
Si_test.xml gnorm.dat ptilde_ref.dat psi.dat rhoij1.dat
88
H.LDA_PW-JTH.xml Fe.GGA_PBE-JTH.xml O.GGA_PBE-JTH.xml Si.GGA_PBE-JTH.xml
9+
STRU
910
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
1011

1112
AddTest(
@@ -24,4 +25,10 @@ AddTest(
2425
TARGET Test_Paw2
2526
LIBS ${math_libs} base device
2627
SOURCES test_paw2.cpp ../paw_atom.cpp
28+
)
29+
30+
AddTest(
31+
TARGET Test_Paw3
32+
LIBS ${math_libs} base device
33+
SOURCES test_paw3.cpp ../paw_atom.cpp ../paw_cell_libpaw.cpp
2734
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
PAW_FILES
2+
C.xml
3+
H.xml

source/module_cell/module_paw/test/test_paw.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33

44
#include "../paw_element.h"
55

6+
/*
7+
Subroutines related to the processing of PAW xml files:
8+
9+
1. init_paw_element, which prepares some related values
10+
2. read_paw_xml, which reads the xml file and stores the information
11+
12+
plus subroutines related to the processing of projector functions:
13+
1. spherical_bessel_function: helper functions, returns values of spherical bessel functions
14+
2. spherical_bessel_transform: carries out spherical bessel transform
15+
3. splint and spline: performs cubic spline interpolation
16+
17+
*/
18+
619
class Test_Read_Paw : public testing::Test
720
{
821
protected:

source/module_cell/module_paw/test/test_paw1.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33

44
#include "../paw_cell.h"
55

6+
/*
7+
Unit Test for subroutines related to the calculation of rhoij,
8+
where reciprocal space wavefunctions are passed from outside, and rhoij is calculated:
9+
10+
1. init_paw_cell and set_paw_k, which collects necessary information
11+
2. accumulate_rhoij, which calculates sum_n <psi_n|p_i><p_j|psi_n>
12+
13+
plus two mathematical subroutines:
14+
3. calc_ylm, which gives values of spherical harmonics
15+
4. ass_leg_pol, which gives values of legendre polynomials
16+
17+
*/
18+
619
class Test_Paw_Cell : public testing::Test
720
{
821
protected:

source/module_cell/module_paw/test/test_paw2.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
#include <iostream>
44

55
#include "../paw_atom.h"
6+
/*
7+
8+
Unit Test for subroutines related to the processing of rhoij,
9+
the on-site density matrix to be used for PAW:
10+
1. set_ca, which passes <psi|ptilde> from outside and saves it
11+
2. accumulate_rhoij, which accumulates the contribution of one band
12+
3. convert_rhoij, which converts rhoij to format required by PAW
13+
14+
*/
615

716
class Test_Paw_Atom : public testing::Test
817
{

0 commit comments

Comments
 (0)