ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
to_qo.h
Go to the documentation of this file.
1#ifndef TOQO_H
2#define TOQO_H
3
4#include <iostream>
5#include <string>
10/*
11 Quasiatomic Orbital (QO) transformation and analysis
12
13 Technical details and procedures:
14 1. first project a given set of atomic orbitals onto one certain set, nao or pw(not implemented)
15 AO now supports hydrogen-like radial orbitals
16 2. project AO onto the eigenstate, then substrate them from AO, get AO'
17 3. Diagonalize AO' and use canoincal orthogonalization to find in total m states (m is arbitrary to user)
18 4. merge space spanned by eigenstate and the one of m states
19 5. project AO onto this new space basis
20
21 Functionalities:
22 1. support different projectors like:
23 (1) hydrogen-like: full, minimal and double. Full may exceed the dimensional of space of nao, minimal
24 will not in most cases
25 (2) pseudowavefunction (pswfc): only avaiable for pseudpotentials with pswfc, unlike SG15.
26 2. output overlap between the given projectors and nao, so make it easy to calculate QO and Hamiltonian in
27 QO representation.
28
29 Workflow:
30 1. create an instance of toQO: toQO()
31 2. initialize the class: initialize()
32 2.1. import information from unitcell: unwrap_unitcell()
33 2.2. build orbitals, nao and ao: build_nao() and build_ao()
34 2.3. scan neighboring list: scan_supercell()
35 2.4. allocate memory for ovlp_ao_nao_R_ and ovlp_ao_nao_k_: clean_up(), deallocate_ovlp() and allocate_ovlp()
36 3. calculate overlap S(k): calculate()
37 3.1. calculate S(R) for all R: calculate_ovlpk(), calculate_ovlpR()
38 3.2. fold S(R) to S(k): fold_ovlpR()
39*/
40class toQO
41{
42 public:
43 // constructor is identical with what INPUT needs to define a toQO task
44 // how user defines a QO task in INPUT, how it is constructed here, this
45 // is to ensure the self-containedness of the class, as much as possible
46 // to avoid introducing variables not from constructor or other under
47 // control functions.
48 toQO(const std::string& qo_basis, //< basis of QO, hydrogen or pswfc
49 const std::vector<std::string>& strategies, //< strategies for each atom type, more details see manual
50 const double& qo_thr, //< threshold for QO
51 const std::vector<double>& screening_coeffs); //< screening coefficients for pseudowavefunction or Slater screening
52 ~toQO();
53
54 // initialize function is to import program-related information, it is,
55 // more dynamic than constructor because this is actually an interface
56 // to states of rest of program, unlike constructor, actually defines
57 // the state of the class.
58 void initialize(const std::string& out_dir, //< directory of output files
59 const std::string& pseudo_dir, //< directory of pseudopotentials
60 const std::string& orbital_dir, //< directory of numerical atomic orbitals
61 const UnitCell* p_ucell, //< interface to the unitcell
62 const std::vector<ModuleBase::Vector3<double>>& kvecs_d, //< kpoints
63 std::ofstream& ofs_running, //< output stream for running information
64 const int& rank, //< rank of present processor
65 const int& nranks); //< total number of processors
66 // import structure, including supercell and kvectors are read in this function
67 void read_structures(const UnitCell* p_ucell, //< interface to the unitcell
68 const std::vector<ModuleBase::Vector3<double>>& kvecs_d, //< kpoints
69 const int& iproc, //< rank of present processor
70 const int& nprocs); //< total number of processors
71
72 // Two-center integral
73 // QO is just one kind of representation, here it is representation from numerical
74 // atomic orbitals spanned space to atomic orbitals spanned space. Therefore two-center
75 // integral is the core of the whole transformation, it calculates the overlap between
76 // atomic orbitals and numerical atomic orbitals
77 // for |>: to build RadialCollection filled with AtomicRadials
78 void build_nao(const int ntype, //< number of atom types
79 const std::string orbital_dir, //< directory of numerical atomic orbitals
80 const std::string* const orbital_fn, //< filenames of numerical atomic orbitals
81 const int rank); //< rank of present processor
82 // for <|: to build RadialCollection filled with PswfcRadials or HydrogenRadials
83 void build_ao(const int ntype, //< number of atom types
84 const std::string pseudo_dir, //< directory of pseudopotentials
85 const std::string* const pspot_fn = nullptr, //< filenames of pseudopotentials
86 const std::vector<double> screening_coeffs = std::vector<double>(), //< screening coefficients of pseudopotentials
87 const double qo_thr = 1e-10, //< threshold for QO
88 const std::ofstream& ofs = std::ofstream(), //< output stream for running information
89 const int rank = 0); //< rank of present processor
90 // for <|: to build RadialCollection filled with HydrogenRadials
91 void build_hydrogen(const int ntype, //< number of atom types
92 const double* const charges, //< charges of atoms
93 const bool slater_screening, //< whether use slater screening
94 const int* const nmax, //< maximum principle quantum number of atoms
95 const double qo_thr, //< threshold for QO
96 const int rank); //< rank of present processor
97 // for <|: to build RadialCollection filled with PswfcRadials
98 void build_pswfc(const int ntype, //< number of atom types
99 const std::string pseudo_dir, //< directory of pseudopotentials
100 const std::string* const pspot_fn, //< filenames of pseudopotentials
101 const double* const screening_coeffs, //< screening coefficients of pseudopotentials, appears like a factor (exp[-s*r]) scaling the pswfc
102 const double qo_thr, //< threshold for QO
103 const int rank); //< rank of present processor
104 void build_szv();
105 // EXTERNAL EXPOSED FUNCTION, calculate all things in one shot
106 void calculate();
107 // calculate <A(i, R)|phi(j, R')> = Sij(R)
108 void calculate_ovlpR(const int iR); //< iR index of supercell vector
109 // calculate <A(i, k)|phi(j, k)> = Sij(k)
110 void calculate_ovlpk(int ik); //< ik index of kpoint
111 // for overlap I/O
112 // S to file
113 template <typename T>
114 void write_ovlp(const std::string& dir, //< directory of output files
115 const std::vector<T>& matrix, //< matrix to write
116 const int& nrows, //< number of rows
117 const int& ncols, //< number of columns
118 const bool& is_R = false, //< whether it is in real space
119 const int& imat = 0); //< index of matrix
120 // S from file
121 void read_ovlp(const std::string& dir, //< directory of output files
122 const int& nrows, //< number of rows
123 const int& ncols, //< number of columns
124 const bool& is_R = false, //< whether it is in real space
125 const int& imat = 0); //< index of matrix
128 void radialcollection_indexing(const RadialCollection&, //< [in] instance of RadialCollection
129 const std::vector<int>&, //< [in] number of atoms for each type
130 const bool&, //< [in] whether enable orbital filtering
131 std::map<std::tuple<int,int,int,int,int>,int>&, //< [out] mapping from (it,ia,l,zeta,m) to index
132 std::map<int,std::tuple<int,int,int,int,int>>&); //< [out] mapping from index to (it,ia,l,zeta,m)
134 ModuleBase::Vector3<double> cal_two_center_vector(ModuleBase::Vector3<double> rij, //< vector connecting atom i and atom j
135 ModuleBase::Vector3<int> R); //< supercell vector
137 bool orbital_filter_out(const int& itype, //< itype
138 const int& l, //< angular momentum
139 const int& izeta //< zeta
140 );
141
142 void deallocate_ovlp(const bool& is_R = false); //< deallocate memory for ovlp_ao_nao_R_ or ovlp_ao_nao_k_
143 void allocate_ovlp(const bool& is_R = false); //< allocate memory for ovlp_ao_nao_R_ or ovlp_ao_nao_k_
144 void zero_out_ovlps(const bool& is_R); //< zero out ovlp_ao_nao_R_ or ovlp_ao_nao_k_
145 void append_ovlpR_eiRk(int ik, int iR); //< append S(R) to S(k), memory saving
146
147 // MPI related
148 static void bcast_stdvector_ofvector3int(std::vector<ModuleBase::Vector3<int>>& vec,
149 const int rank);
151 const int rank);
152
153 // Neighboring list
155 void scan_supercell(const int& iproc, //< rank of present processor
156 const int& nprocs); //< total number of processors
160 std::vector<ModuleBase::Vector3<int>> scan_supercell_for_atom(int it, //< type of atom i
161 int ia, //< index of atom i
162 int start_it = 0, //< starting scan index of atom type
163 int start_ia = 0); //< starting scan index of atom
166 std::vector<int> rcut_to_supercell_index(double rcut, //< sum of cutoff radius of orbitals of atom i and atom j
167 ModuleBase::Vector3<double> a, //< cell vector a (in Bohr)
168 ModuleBase::Vector3<double> b, //< cell vector b (in Bohr)
169 ModuleBase::Vector3<double> c); //< cell vector c (in Bohr)
172 double norm2_rij_supercell(ModuleBase::Vector3<double> rij, //< vector connecting atom i and atom j in unitcell
173 int n1, //< supercell index 1
174 int n2, //< supercell index 2
175 int n3); //< supercell index 3
177 template <typename T>
178 void eliminate_duplicate_vector3(std::vector<ModuleBase::Vector3<T>>& vector3s);
180 void write_supercells();
181
182 // getters
183 int ntype() const { return ntype_; }
184 int nks() const { return nks_; }
185 std::string qo_basis() const { return qo_basis_; }
186 std::vector<std::string> strategies() const { return strategies_; }
187 std::string strategy(const int itype) const { return strategies_[itype]; }
188 UnitCell* p_ucell() const { return const_cast<UnitCell*>(p_ucell_); }
189 RadialCollection* p_nao() const { return nao_.get(); }
190 RadialCollection* p_ao() const { return ao_.get(); }
191 int nR() const { return nR_; }
192 int nchi() const { return nchi_; }
193 int nphi() const { return nphi_; }
194 std::vector<ModuleBase::Vector3<int>> supercells() const { return supercells_; }
195 std::vector<double> ovlpR() const { return ovlpR_; }
196 double ovlpR(const int i, const int j) const { return ovlpR_[i*nchi_+j]; }
197 std::vector<std::complex<double>> ovlpk() const { return ovlpk_; }
198 std::complex<double> ovlpk(const int i, const int j) const { return ovlpk_[i*nchi_+j]; }
199 std::vector<std::string> symbols() const { return symbols_; }
200 std::vector<double> charges() const { return charges_; }
202 std::vector<ModuleBase::Vector3<double>> kvecs_d() const { return kvecs_d_; }
203
204 private:
205 // Variables defining QO task
206 std::string qo_basis_ = "hydrogen";
207 std::vector<std::string> strategies_;
208 double qo_thr_ = 1e-10;
209 std::vector<double> screening_coeffs_;
210 // Variables defining I/O
211 std::string out_dir_; //< directory of output files
212 std::string pseudo_dir_; //< directory of pseudopotentials
213 std::string orbital_dir_; //< directory of numerical atomic orbitals
214 // Variables defining parallelism
215 int iproc_ = 0;
216 int nprocs_ = 1;
217 // variables defining structure
218 const UnitCell* p_ucell_ = nullptr; //< interface to the unitcell, its lifespan is not managed here
219 std::vector<int> iRs_; //< indices of supercell vectors (local)
220 std::vector<ModuleBase::Vector3<int>> supercells_; //< supercell vectors (global)
221 std::vector<int> iks_; //< indices of kpoints (local)
222 std::vector<ModuleBase::Vector3<double>> kvecs_d_; //< kpoints (global)
223 // Two center integral
224 std::unique_ptr<RadialCollection> nao_; //< numerical atomic orbitals
225 std::unique_ptr<RadialCollection> ao_; //< atomic orbitals
226 std::unique_ptr<TwoCenterIntegrator> overlap_calculator_; //< two center integrator
227 std::vector<double> ovlpR_; //< overlap between atomic orbitals and numerical atomic orbitals, in real space
228 std::vector<std::complex<double>> ovlpk_; //< overlap between atomic orbitals and numerical atomic orbitals, in k space
229 //< indices
230 std::map<std::tuple<int,int,int,int,int>,int> index_ao_; //< mapping from (it,ia,l,zeta,m) to index
231 std::map<int,std::tuple<int,int,int,int,int>> rindex_ao_; //< mapping from index to (it,ia,l,zeta,m)
232 std::map<std::tuple<int,int,int,int,int>,int> index_nao_; //< mapping from (it,ia,l,zeta,m) to index
233 std::map<int,std::tuple<int,int,int,int,int>> rindex_nao_; //< mapping from index to (it,ia,l,zeta,m)
234 // Variables defining dimensions or resource allocation
235 int nks_ = 0; //< number of kpoints for present processor, for S(k)
236 int nks_tot_ = 0; //< total number of kpoints
237 int nR_ = 0; //< number of supercell vectors on present processor, for S(R)
238 int nR_tot_ = 0; //< total number of supercell vectors
239 int nchi_ = 0; //< number of atomic orbitals, chi in \mathbf{S}^{\chi\phi}(\mathbf{k})
240 int nphi_ = 0; //< number of numerical atomic orbitals, phi in \mathbf{S}^{\chi\phi}(\mathbf{k})
241 // Variables defining atoms
242 atom_in atom_database_; //< atomic information database
243 int ntype_ = 0; //< number of atom types
244 std::vector<int> na_; //< number of atoms for each type
245 std::vector<std::string> symbols_; //< symbols of atoms
246 std::vector<double> charges_; //< charges of atoms
247 std::vector<int> nmax_; //< maximum principle quantum number of atoms
248};
249#endif // TOQO_H
3 elements vector
Definition vector3.h:22
A class that holds all numerical radial functions of the same kind.
Definition radial_collection.h:18
Definition unitcell.h:16
Definition atom_in.h:11
Definition to_qo.h:41
const UnitCell * p_ucell_
Definition to_qo.h:218
std::string qo_basis_
Definition to_qo.h:206
void eliminate_duplicate_vector3(std::vector< ModuleBase::Vector3< T > > &vector3s)
eliminate duplicate vectors in a vector of vector3
Definition to_qo_structures.cpp:92
std::vector< int > iRs_
Definition to_qo.h:219
double norm2_rij_supercell(ModuleBase::Vector3< double > rij, int n1, int n2, int n3)
get vector squared norm in supercell
Definition to_qo_structures.cpp:178
int nR_tot_
Definition to_qo.h:238
std::vector< std::string > strategies() const
Definition to_qo.h:186
static void bcast_stdvector_ofvector3double(std::vector< ModuleBase::Vector3< double > > &vec, const int rank)
Definition to_qo_mpi.cpp:36
void calculate_ovlpR(const int iR)
Definition to_qo_kernel.cpp:303
void write_ovlp(const std::string &dir, const std::vector< T > &matrix, const int &nrows, const int &ncols, const bool &is_R=false, const int &imat=0)
Definition to_qo_kernel.cpp:515
void build_pswfc(const int ntype, const std::string pseudo_dir, const std::string *const pspot_fn, const double *const screening_coeffs, const double qo_thr, const int rank)
Definition to_qo_kernel.cpp:213
std::map< int, std::tuple< int, int, int, int, int > > rindex_nao_
Definition to_qo.h:233
std::vector< ModuleBase::Vector3< double > > kvecs_d() const
Definition to_qo.h:202
int nR_
Definition to_qo.h:237
~toQO()
Definition to_qo_kernel.cpp:22
void build_szv()
Definition to_qo_kernel.cpp:248
double ovlpR(const int i, const int j) const
Definition to_qo.h:196
std::string orbital_dir_
Definition to_qo.h:213
std::vector< ModuleBase::Vector3< int > > supercells() const
Definition to_qo.h:194
void read_ovlp(const std::string &dir, const int &nrows, const int &ncols, const bool &is_R=false, const int &imat=0)
Definition to_qo_kernel.cpp:582
void build_hydrogen(const int ntype, const double *const charges, const bool slater_screening, const int *const nmax, const double qo_thr, const int rank)
Definition to_qo_kernel.cpp:194
int ntype_
Definition to_qo.h:243
std::vector< std::string > symbols_
Definition to_qo.h:245
double qo_thr_
Definition to_qo.h:208
bool orbital_filter_out(const int &itype, const int &l, const int &izeta)
when indexing, select where one orbital is really included in the two-center integral
Definition to_qo_kernel.cpp:151
int nR() const
Definition to_qo.h:191
std::vector< int > nmax_
Definition to_qo.h:247
std::vector< int > na_
Definition to_qo.h:244
int nchi_
Definition to_qo.h:239
void initialize(const std::string &out_dir, const std::string &pseudo_dir, const std::string &orbital_dir, const UnitCell *p_ucell, const std::vector< ModuleBase::Vector3< double > > &kvecs_d, std::ofstream &ofs_running, const int &rank, const int &nranks)
Definition to_qo_kernel.cpp:28
int nprocs_
Definition to_qo.h:216
int ntype() const
Definition to_qo.h:183
std::vector< double > screening_coeffs_
Definition to_qo.h:209
std::map< std::tuple< int, int, int, int, int >, int > index_nao_
Definition to_qo.h:232
std::vector< ModuleBase::Vector3< double > > kvecs_d_
Definition to_qo.h:222
ModuleBase::Vector3< double > cal_two_center_vector(ModuleBase::Vector3< double > rij, ModuleBase::Vector3< int > R)
calculate vectors connecting all atom pairs that needed to calculate their overlap
Definition to_qo_structures.cpp:267
void write_supercells()
write supercells information to file
Definition to_qo_structures.cpp:283
std::vector< std::complex< double > > ovlpk_
Definition to_qo.h:228
std::vector< double > ovlpR() const
Definition to_qo.h:195
int nks_
Definition to_qo.h:235
std::vector< std::string > symbols() const
Definition to_qo.h:199
void radialcollection_indexing(const RadialCollection &, const std::vector< int > &, const bool &, std::map< std::tuple< int, int, int, int, int >, int > &, std::map< int, std::tuple< int, int, int, int, int > > &)
build bidirectional map indexing for one single RadialCollection object, which is an axis of two-cent...
Definition to_qo_kernel.cpp:468
int nphi_
Definition to_qo.h:240
std::vector< int > iks_
Definition to_qo.h:221
std::vector< ModuleBase::Vector3< int > > scan_supercell_for_atom(int it, int ia, int start_it=0, int start_ia=0)
this is a basic functional for scanning (ijR) pair for one certain i, return Rs
Definition to_qo_structures.cpp:111
std::string strategy(const int itype) const
Definition to_qo.h:187
std::vector< double > charges_
Definition to_qo.h:246
int nchi() const
Definition to_qo.h:192
std::vector< double > charges() const
Definition to_qo.h:200
std::map< std::tuple< int, int, int, int, int >, int > index_ao_
Definition to_qo.h:230
void build_ao(const int ntype, const std::string pseudo_dir, const std::string *const pspot_fn=nullptr, const std::vector< double > screening_coeffs=std::vector< double >(), const double qo_thr=1e-10, const std::ofstream &ofs=std::ofstream(), const int rank=0)
Definition to_qo_kernel.cpp:261
void calculate()
Definition to_qo_kernel.cpp:387
UnitCell * p_ucell() const
Definition to_qo.h:188
static void bcast_stdvector_ofvector3int(std::vector< ModuleBase::Vector3< int > > &vec, const int rank)
Definition to_qo_mpi.cpp:6
void build_nao(const int ntype, const std::string orbital_dir, const std::string *const orbital_fn, const int rank)
Definition to_qo_kernel.cpp:108
std::string out_dir_
Definition to_qo.h:211
std::complex< double > ovlpk(const int i, const int j) const
Definition to_qo.h:198
std::string qo_basis() const
Definition to_qo.h:185
int iproc_
Definition to_qo.h:215
std::map< int, std::tuple< int, int, int, int, int > > rindex_ao_
Definition to_qo.h:231
std::vector< std::complex< double > > ovlpk() const
Definition to_qo.h:197
int nks_tot_
Definition to_qo.h:236
RadialCollection * p_ao() const
Definition to_qo.h:190
RadialCollection * p_nao() const
Definition to_qo.h:189
std::unique_ptr< TwoCenterIntegrator > overlap_calculator_
Definition to_qo.h:226
std::vector< std::string > strategies_
Definition to_qo.h:207
void zero_out_ovlps(const bool &is_R)
Definition to_qo_kernel.cpp:459
atom_in atom_database_
Definition to_qo.h:242
void allocate_ovlp(const bool &is_R=false)
Definition to_qo_kernel.cpp:436
std::vector< ModuleBase::Vector3< int > > supercells_
Definition to_qo.h:220
void calculate_ovlpk(int ik)
Definition to_qo_kernel.cpp:338
std::unique_ptr< RadialCollection > nao_
Definition to_qo.h:224
std::unique_ptr< RadialCollection > ao_
Definition to_qo.h:225
void deallocate_ovlp(const bool &is_R=false)
Definition to_qo_kernel.cpp:445
atom_in atom_database() const
Definition to_qo.h:201
int nks() const
Definition to_qo.h:184
std::string pseudo_dir_
Definition to_qo.h:212
std::vector< double > ovlpR_
Definition to_qo.h:227
int nphi() const
Definition to_qo.h:193
void append_ovlpR_eiRk(int ik, int iR)
Definition to_qo_kernel.cpp:422
std::vector< int > rcut_to_supercell_index(double rcut, ModuleBase::Vector3< double > a, ModuleBase::Vector3< double > b, ModuleBase::Vector3< double > c)
core algorithm to scan supercells, find the maximal supercell according to present cutoff radius
Definition to_qo_structures.cpp:163
void read_structures(const UnitCell *p_ucell, const std::vector< ModuleBase::Vector3< double > > &kvecs_d, const int &iproc, const int &nprocs)
Definition to_qo_structures.cpp:5
void scan_supercell(const int &iproc, const int &nprocs)
get all possible (n1n2n3) defining supercell and scatter if MPI enabled
Definition to_qo_structures.cpp:193