ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
phi_operator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "phi_operator.h"
6
7namespace ModuleGint
8{
9
10template<typename T>
11void PhiOperator::set_phi(T* phi) const
12{
13 for(int i = 0; i < biggrid_->get_atoms_num(); ++i)
14 {
15 const auto atom = biggrid_->get_atom(i);
16 atom->set_phi(atoms_relative_coords_[i], cols_, phi);
17 phi += atom->get_nw();
18 }
19}
20
21// phi_dm(ir,iwt_2) = \sum_{iwt_1} phi(ir,iwt_1) * dm(iwt_1,iwt_2)
22template<typename T>
24 const T*const phi, // phi(ir,iwt)
25 const HContainer<T>& dm, // dm(iwt_1,iwt_2)
26 const bool is_symm,
27 T*const phi_dm) const // phi_dm(ir,iwt)
28{
29 ModuleBase::GlobalFunc::ZEROS(phi_dm, rows_ * cols_);
30
31 for(int i = 0; i < biggrid_->get_atoms_num(); ++i)
32 {
33 const auto atom_i = biggrid_->get_atom(i);
34 const auto r_i = atom_i->get_R();
35
36 if(is_symm)
37 {
38 const auto dm_mat = dm.find_matrix(atom_i->get_iat(), atom_i->get_iat(), 0, 0, 0);
39 constexpr T alpha = 1.0;
40 constexpr T beta = 1.0;
42 'L', 'U',
43 atoms_phi_len_[i], rows_,
44 alpha, dm_mat->get_pointer(), atoms_phi_len_[i],
45 &phi[0 * cols_ + atoms_startidx_[i]], cols_,
46 beta, &phi_dm[0 * cols_ + atoms_startidx_[i]], cols_);
47 }
48
49 const int start = is_symm ? i + 1 : 0;
50
51 for(int j = start; j < biggrid_->get_atoms_num(); ++j)
52 {
53 const auto atom_j = biggrid_->get_atom(j);
54 const auto r_j = atom_j->get_R();
55 // FIXME may be r = r_j - r_i
56 const auto dm_mat = dm.find_matrix(atom_i->get_iat(), atom_j->get_iat(), r_i-r_j);
57
58 // if dm_mat is nullptr, it means this atom pair does not affect any meshgrid in the unitcell
59 if(dm_mat == nullptr)
60 {
61 continue;
62 }
63
64 const int start_idx = get_atom_pair_start_end_idx_(i, j).first;
65 const int end_idx = get_atom_pair_start_end_idx_(i, j).second;
66 const int len = end_idx - start_idx + 1;
67
68 // if len<=0, it means this atom pair does not affect any meshgrid in this biggrid
69 if(len <= 0)
70 {
71 continue;
72 }
73
74 const T alpha = is_symm ? 2.0 : 1.0;
75 constexpr T beta = 1.0;
77 'N', 'N',
78 len, atoms_phi_len_[j], atoms_phi_len_[i],
79 alpha, &phi[start_idx * cols_ + atoms_startidx_[i]], cols_,
80 dm_mat->get_pointer(), atoms_phi_len_[j],
81 beta, &phi_dm[start_idx * cols_ + atoms_startidx_[j]], cols_);
82 }
83 }
84}
85
86// result(ir) = phi(ir) * vl(ir)
87template<typename T>
89 const T*const vl, // vl(ir)
90 const T dr3,
91 const T*const phi, // phi(ir,iwt)
92 T*const result) const // result(ir,iwt)
93{
94 int idx = 0;
95 for(int i = 0; i < biggrid_->get_mgrids_num(); i++)
96 {
97 T vldr3_mgrid = vl[meshgrids_local_idx_[i]] * dr3;
98 for(int j = 0; j < cols_; j++)
99 {
100 result[idx] = phi[idx] * vldr3_mgrid;
101 idx++;
102 }
103 }
104}
105
106// hr(iwt_i,iwt_j) += \sum_{ir} phi_i(ir,iwt_i) * phi_i(ir,iwt_j)
107// this is a thread-safe function
108template<typename T>
110 const T*const phi_i, // phi_i(ir,iwt)
111 const T*const phi_j, // phi_j(ir,iwt)
112 HContainer<T>& hr, // hr(iwt_i,iwt_j)
113 const Triangular_Matrix triangular_matrix) const
114{
115 std::vector<T> tmp_hr;
116 for(int i = 0; i < biggrid_->get_atoms_num(); ++i)
117 {
118 const auto atom_i = biggrid_->get_atom(i);
119 const auto& r_i = atom_i->get_R();
120 const int iat_i = atom_i->get_iat();
121 const int n_i = atoms_phi_len_[i];
122
123 for(int j = 0; j < biggrid_->get_atoms_num(); ++j)
124 {
125 const auto atom_j = biggrid_->get_atom(j);
126 const auto& r_j = atom_j->get_R();
127 const int iat_j = atom_j->get_iat();
128 const int n_j = atoms_phi_len_[j];
129
130 // only calculate the upper triangle matrix
131 if(triangular_matrix==Triangular_Matrix::Upper && iat_i>iat_j)
132 {
133 continue;
134 }
135 // only calculate the upper triangle matrix
136 else if(triangular_matrix==Triangular_Matrix::Lower && iat_i<iat_j)
137 {
138 continue;
139 }
140
141 // FIXME may be r = r_j - r_i
142 const auto result = hr.find_matrix(iat_i, iat_j, r_i-r_j);
143
144 if(result == nullptr)
145 {
146 continue;
147 }
148
149 const int start_idx = get_atom_pair_start_end_idx_(i, j).first;
150 const int end_idx = get_atom_pair_start_end_idx_(i, j).second;
151 const int len = end_idx - start_idx + 1;
152
153 if(len <= 0)
154 {
155 continue;
156 }
157
158 tmp_hr.resize(n_i * n_j);
159 ModuleBase::GlobalFunc::ZEROS(tmp_hr.data(), n_i*n_j);
160
161 constexpr T alpha=1, beta=1;
163 'T', 'N', n_i, n_j, len,
164 alpha, phi_i + start_idx * cols_ + atoms_startidx_[i], cols_,
165 phi_j + start_idx * cols_ + atoms_startidx_[j], cols_,
166 beta, tmp_hr.data(), n_j,
168
169 result->add_array_ts(tmp_hr.data());
170 }
171 }
172}
173
174// rho(ir) = \sum_{iwt} \phi_i(ir,iwt) * \phi_j^*(ir,iwt)
175template<typename T>
177 const T*const phi_i, // phi_i(ir,iwt)
178 const T*const phi_j, // phi_j(ir,iwt)
179 T*const rho) const // rho(ir)
180{
181 constexpr int inc = 1;
182 for(int i = 0; i < biggrid_->get_mgrids_num(); ++i)
183 {
184 rho[meshgrids_local_idx_[i]] += BlasConnector::dotc(cols_, phi_j+i*cols_, inc, phi_i+i*cols_, inc);
185 }
186}
187
188} // namespace ModuleGint
static float dotc(const int n, const float *const X, const int incX, const float *const Y, const int incY, base_device::AbacusDevice_t device_type=base_device::AbacusDevice_t::CpuDevice)
Definition blas_connector_vector.cpp:224
static void gemm(const char transa, const char transb, const int m, const int n, const int k, const float alpha, const float *a, const int lda, const float *b, const int ldb, const float beta, float *c, const int ldc, base_device::AbacusDevice_t device_type=base_device::AbacusDevice_t::CpuDevice)
Definition blas_connector_matrix.cpp:20
static void symm_cm(const char side, const char uplo, const int m, const int n, const float alpha, const float *a, const int lda, const float *b, const int ldb, const float beta, float *c, const int ldc, base_device::AbacusDevice_t device_type=base_device::AbacusDevice_t::CpuDevice)
Definition blas_connector_matrix.cpp:361
void phi_mul_phi(const T *const phi_i, const T *const phi_j, HContainer< T > &hr, const Triangular_Matrix triangular_matrix) const
Definition phi_operator.hpp:109
void phi_mul_vldr3(const T *const vl, const T dr3, const T *const phi, T *const result) const
Definition phi_operator.hpp:88
void phi_dot_phi(const T *const phi_i, const T *const phi_j, T *const rho) const
Definition phi_operator.hpp:176
std::shared_ptr< const BigGrid > biggrid_
Definition phi_operator.h:143
std::vector< std::vector< Vec3d > > atoms_relative_coords_
Definition phi_operator.h:147
const std::pair< int, int > & get_atom_pair_start_end_idx_(int a, int b) const
Definition phi_operator.h:119
std::vector< int > atoms_phi_len_
Definition phi_operator.h:159
Triangular_Matrix
Definition phi_operator.h:22
std::vector< int > atoms_startidx_
Definition phi_operator.h:154
void set_phi(T *phi) const
Definition phi_operator.hpp:11
void phi_mul_dm(const T *const phi, const HContainer< T > &dm, const bool is_symm, T *const phi_dm) const
Definition phi_operator.hpp:23
int cols_
Definition phi_operator.h:137
Definition hcontainer.h:144
BaseMatrix< T > * find_matrix(int i, int j, int rx, int ry, int rz)
find BaseMatrix with atom index atom_i and atom_j and R index (rx, ry, rz) This interface can be used...
Definition hcontainer.cpp:261
#define T
Definition exp.cpp:237
void ZEROS(std::complex< T > *u, const TI n)
Definition global_function.h:109
Definition batch_biggrid.cpp:4
@ CpuDevice
Definition types.h:14
iclock::time_point start
Definition test_partition.cpp:22