ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
phi_operator.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <vector>
5#include <utility>
7#include "big_grid.h"
8
9namespace ModuleGint
10{
11
20{
21 public:
22 enum class TriPart{Upper, Lower, Full};
23
24 // constructor
25 PhiOperator()=default;
26
27 // set the big grid that the phiOperator is associated with
28 void set_bgrid(std::shared_ptr<const BigGrid> biggrid);
29
30 // getter
31 int get_rows() const {return rows_;}
32 int get_cols() const {return cols_;}
33
34 // get phi of the big grid
35 // the dimension of phi is num_mgrids * (\sum_{i=0}^{atoms_->size()} atoms_[i]->nw)
36 template<typename T>
37 void set_phi(T* phi) const;
38
39 // get phi and the gradient of phi of the big grid
40 // the dimension of phi and dphi is num_mgrids * (\sum_{i=0}^{atoms_->size()} atoms_[i]->nw)
41 // if you do not need phi, you can set phi to nullptr.
42 void set_phi_dphi(double* phi, double* dphi_x, double* dphi_y, double* dphi_z) const;
43
44 // get the hessian of the wave function values of the big grid
45 // the dimension of ddphi is num_mgrids * (\sum_{i=0}^{atoms_->size()} atoms_[i]->nw)
46 void set_ddphi(
47 double* ddphi_xx, double* ddphi_xy, double* ddphi_xz,
48 double* ddphi_yy, double* ddphi_yz, double* ddphi_zz) const;
49
50 // phi_dm(ir,iwt_2) = \sum_{iwt_1} phi(ir,iwt_1) * dm(iwt_1,iwt_2)
51 // The phi_dm output is always double regardless of Tin: this keeps the
52 // downstream phi_dot_phi reading a uniform fp64 right-hand side. When
53 // Tin=float the GEMM still runs in fp32 (K is small ~10, so per-call
54 // accumulation in fp32 is fine); only the final write into phi_dm casts
55 // to double.
56 template<typename Tin>
57 void phi_mul_dm(
58 const Tin*const phi, // phi(ir,iwt)
59 const HContainer<Tin>& dm, // dm(iwt_1,iwt_2)
60 const bool is_symm,
61 double*const phi_dm) const; // phi_dm(ir,iwt)
62
63 // result(ir,iwt) = phi(ir,iwt) * vl(ir)
64 template<typename T>
65 void phi_mul_vldr3(
66 const T*const vl, // vl(ir)
67 const T dr3,
68 const T*const phi, // phi(ir,iwt)
69 T*const result) const; // result(ir,iwt)
70
71 // hr(iwt_i,iwt_j) = \sum_{ir} phi_i(ir,iwt_i) * phi_i(ir,iwt_j)
72 // this is a thread-safe function.
73 // The accumulator hr is always double: when Tin=float we want fp32 multiplies
74 // but fp64 accumulation across many biggrids to avoid catastrophic precision loss.
75 template<typename Tin>
76 void phi_mul_phi(
77 const Tin*const phi_i, // phi_i(ir,iwt)
78 const Tin*const phi_j, // phi_j(ir,iwt)
79 HContainer<double>& hr, // hr(iwt_i,iwt_j)
80 const TriPart part) const;
81
82 // rho(ir) = \sum_{iwt} \phi_i(ir,iwt) * \phi_j(ir,iwt)
83 // phi_j is always double-typed (it is the output of phi_mul_dm, which now
84 // accumulates into a double buffer regardless of Tin). The inner dot
85 // product is accumulated in double too: fp32 phi_i + fp64 phi_j → fp64.
86 template<typename Tin>
87 void phi_dot_phi(
88 const Tin*const phi_i, // phi_i(ir,iwt)
89 const double*const phi_j, // phi_j(ir,iwt)
90 double*const rho) const; // rho(ir)
91
92 void phi_dot_dphi(
93 const double* phi,
94 const double* dphi_x,
95 const double* dphi_y,
96 const double* dphi_z,
97 ModuleBase::matrix *fvl) const;
98
99 void phi_dot_dphi_r(
100 const double* phi,
101 const double* dphi_x,
102 const double* dphi_y,
103 const double* dphi_z,
104 ModuleBase::matrix *svl) const;
105
106 void cal_env_gamma(
107 const double* phi,
108 const double* wfc,
109 const vector<int>& trace_lo,
110 double* rho) const;
111
112 void cal_env_k(
113 const double* phi,
114 const std::complex<double>* wfc,
115 const vector<int>& trace_lo,
116 const int ik,
117 const int nspin,
118 const int npol,
119 const int lgd,
120 const std::vector<Vec3d>& kvec_c,
121 const std::vector<Vec3d>& kvec_d,
122 double* rho) const;
123
124 private:
125 void init_atom_pair_idx_();
126
127 // get the index of the first and the last meshgrid that both atom a and atom b affect
128 // Note that atom_pair_range_ only stores the cases where a <= b, so this function is needed to retrieve the value
129 const std::pair<int, int>& get_atom_pair_start_end_idx_(int a, int b) const
130 {
131 int x = std::min(a, b);
132 int y = std::abs(a - b);
133 return atom_pair_range_[(2 * biggrid_->get_atoms_num() - x + 1) * x / 2 + y];
134 }
135
136 bool is_atom_on_mgrid(int atom_idx, int mgrid_idx) const
137 {
138 return is_atom_on_mgrid_[atom_idx * rows_ + mgrid_idx];
139 }
140
141 // the row number of the phi matrix
142 // rows_ = biggrid_->get_mgrids_num()
143 int rows_;
144
145 // the column number of the phi matrix
146 // cols_ = biggrid_->get_phi_len()
147 int cols_;
148
149 // the local index of the meshgrids
150 std::vector<int> mgrid_lidx_;
151
152 // the big grid that the phi matrix is associated with
153 std::shared_ptr<const BigGrid> biggrid_;
154
155 // the relative coordinates of the atoms and the meshgrids
156 // atom_rcoords_[i][j] is the relative coordinate of the jth meshgrid and the ith atom
157 std::vector<std::vector<Vec3d>> atom_rcoords_;
158
159 // record whether the atom affects the meshgrid
160 // is_atom_on_mgrid_[i * rows_ + j] = true if the ith atom affects jhe ith meshgrid, otherwise false
161 std::vector<bool> is_atom_on_mgrid_;
162
163 // the start index of the phi of each atom
164 std::vector<int> atoms_startidx_;
165
166 // the length of phi of each atom
167 // atoms_phi_len_[i] = biggrid_->get_atom(i)->get_nw()
168 // TODO: remove it
169 std::vector<int> atoms_phi_len_;
170
171 // This data structure is used to store the index of the first and last meshgrid affected by each atom pair
172 std::vector<std::pair<int, int>> atom_pair_range_;
173};
174
175}
176
177#include "phi_operator.hpp"
Definition matrix.h:18
The class phiOperator is used to perform operations on the wave function matrix phi,...
Definition phi_operator.h:20
int get_rows() const
Definition phi_operator.h:31
bool is_atom_on_mgrid(int atom_idx, int mgrid_idx) const
Definition phi_operator.h:136
int get_cols() const
Definition phi_operator.h:32
void phi_dot_dphi_r(const double *phi, const double *dphi_x, const double *dphi_y, const double *dphi_z, ModuleBase::matrix *svl) const
Definition phi_operator.cpp:98
void cal_env_gamma(const double *phi, const double *wfc, const vector< int > &trace_lo, double *rho) const
Definition phi_operator.cpp:133
void phi_dot_dphi(const double *phi, const double *dphi_x, const double *dphi_y, const double *dphi_z, ModuleBase::matrix *fvl) const
Definition phi_operator.cpp:68
std::vector< bool > is_atom_on_mgrid_
Definition phi_operator.h:161
void set_phi_dphi(double *phi, double *dphi_x, double *dphi_y, double *dphi_z) const
Definition phi_operator.cpp:35
void phi_mul_vldr3(const T *const vl, const T dr3, const T *const phi, T *const result) const
Definition phi_operator.hpp:121
std::shared_ptr< const BigGrid > biggrid_
Definition phi_operator.h:153
void init_atom_pair_idx_()
Definition phi_operator.cpp:217
void phi_dot_phi(const Tin *const phi_i, const double *const phi_j, double *const rho) const
Definition phi_operator.hpp:231
std::vector< std::pair< int, int > > atom_pair_range_
Definition phi_operator.h:172
const std::pair< int, int > & get_atom_pair_start_end_idx_(int a, int b) const
Definition phi_operator.h:129
void phi_mul_phi(const Tin *const phi_i, const Tin *const phi_j, HContainer< double > &hr, const TriPart part) const
Definition phi_operator.hpp:144
std::vector< std::vector< Vec3d > > atom_rcoords_
Definition phi_operator.h:157
TriPart
Definition phi_operator.h:22
std::vector< int > atoms_phi_len_
Definition phi_operator.h:169
std::vector< int > mgrid_lidx_
Definition phi_operator.h:150
void phi_mul_dm(const Tin *const phi, const HContainer< Tin > &dm, const bool is_symm, double *const phi_dm) const
Definition phi_operator.hpp:52
void set_ddphi(double *ddphi_xx, double *ddphi_xy, double *ddphi_xz, double *ddphi_yy, double *ddphi_yz, double *ddphi_zz) const
Definition phi_operator.cpp:51
void cal_env_k(const double *phi, const std::complex< double > *wfc, const vector< int > &trace_lo, const int ik, const int nspin, const int npol, const int lgd, const std::vector< Vec3d > &kvec_c, const std::vector< Vec3d > &kvec_d, double *rho) const
Definition phi_operator.cpp:160
void set_bgrid(std::shared_ptr< const BigGrid > biggrid)
Definition phi_operator.cpp:8
std::vector< int > atoms_startidx_
Definition phi_operator.h:164
void set_phi(T *phi) const
Definition phi_operator.hpp:11
int rows_
Definition phi_operator.h:143
int cols_
Definition phi_operator.h:147
Definition hcontainer.h:144
#define T
Definition exp.cpp:237
Definition batch_biggrid.cpp:4