ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
write_vxc.hpp
Go to the documentation of this file.
1#ifndef __WRITE_VXC_H_
2#define __WRITE_VXC_H_
9#include "source_psi/psi.h"
10#include "source_io/write_HS.h"
11#include "source_io/filename.h" // use filename_output function
12
13namespace ModuleIO
14{
15
16inline void set_para2d_MO(const Parallel_Orbitals& pv, const int nbands, Parallel_2D& p2d)
17{
18 std::ofstream ofs;
19#ifdef __MPI
20 p2d.set(nbands, nbands, pv.nb, pv.blacs_ctxt);
21#else
22 p2d.set_serial(nbands, nbands);
23#endif
24}
25
26template <typename T>
27inline std::vector<T> cVc(T* V,
28 T* c,
29 const int nbasis,
30 const int nbands,
31 const Parallel_Orbitals& pv,
32 const Parallel_2D& p2d)
33{
34 std::vector<T> Vc(pv.nloc_wfc, 0.0);
35 char transa = 'N';
36 char transb = 'N';
37 const T alpha = (T)1.0;
38 const T beta = (T)0.0;
39#ifdef __MPI
40 const int i1 = 1;
41 ScalapackConnector::gemm(transa, transb,
42 nbasis, nbands, nbasis,
43 alpha, V, i1, i1, pv.desc,
44 c, i1, i1, pv.desc_wfc,
45 beta, Vc.data(), i1, i1, pv.desc_wfc);
46#else
47 container::BlasConnector::gemm(transa, transb, nbasis, nbands, nbasis, alpha, V, nbasis, c, nbasis, beta, Vc.data(), nbasis);
48#endif
49 std::vector<T> cVc(p2d.nloc, 0.0);
50 transa = (std::is_same<T, double>::value ? 'T' : 'C');
51#ifdef __MPI
52 ScalapackConnector::gemm(transa, transb,
53 nbands, nbands, nbasis,
54 alpha, c, i1, i1, pv.desc_wfc,
55 Vc.data(), i1, i1, pv.desc_wfc,
56 beta, cVc.data(), i1, i1, p2d.desc);
57#else
58 container::BlasConnector::gemm(transa, transb, nbands, nbands, nbasis, alpha, c, nbasis, Vc.data(), nbasis, beta, cVc.data(), nbasis);
59#endif
60 return cVc;
61}
62
63inline double get_real(const std::complex<double>& c)
64{
65 return c.real();
66}
67
68inline double get_real(const double& d)
69{
70 return d;
71}
72
73template <typename T>
74double all_band_energy(const int ik, const std::vector<T>& mat_mo, const Parallel_2D& p2d, const ModuleBase::matrix& wg)
75{
76 double e = 0.0;
77 for (int i = 0; i < p2d.get_row_size(); ++i)
78 {
79 for (int j = 0; j < p2d.get_col_size(); ++j)
80 {
81 if (p2d.local2global_row(i) == p2d.local2global_col(j))
82 {
83 e += get_real(mat_mo[j * p2d.get_row_size() + i]) * wg(ik, p2d.local2global_row(i));
84 }
85 }
86 }
88 return e;
89}
90
91template <typename T>
92std::vector<double> orbital_energy(const int ik, const int nbands, const std::vector<T>& mat_mo, const Parallel_2D& p2d)
93{
94#ifdef __DEBUG
95 assert(nbands >= 0);
96#endif
97 std::vector<double> e(nbands, 0.0);
98 for (int i = 0; i < nbands; ++i)
99 {
100 if (p2d.in_this_processor(i, i))
101 {
102 const int index = p2d.global2local_col(i) * p2d.get_row_size() + p2d.global2local_row(i);
103 e[i] = get_real(mat_mo[index]);
104 }
105 }
106 Parallel_Reduce::reduce_all(e.data(), nbands);
107 return e;
108}
109
110inline void write_orb_energy(const K_Vectors& kv,
111 const int nspin0, const int nbands,
112 const std::vector<std::vector<double>>& e_orb,
113 const std::string& term, const std::string& label, const bool app = false)
114{
115 assert(e_orb.size() == kv.get_nks());
116 const int nk = kv.get_nks() / nspin0;
117 std::ofstream ofs;
118 ofs.open(PARAM.globalv.global_out_dir + term + "_" + (label == "" ? "out.dat" : label + "_out.dat"),
119 app ? std::ios::app : std::ios::out);
120 ofs << nk << "\n" << nspin0 << "\n" << nbands << "\n";
121 ofs << std::scientific << std::setprecision(16);
122 for (int ik = 0; ik < nk; ++ik)
123 {
124 for (int is = 0; is < nspin0; ++is)
125 {
126 for (auto e : e_orb[is * nk + ik])
127 { // Hartree and eV
128 ofs << e / 2. << "\t" << e * ModuleBase::Ry_to_eV << "\n";
129 }
130 }
131 }
132}
133
136template <typename TK, typename TR>
137void write_Vxc(const int nspin,
138 const int nbasis,
139 const int drank,
140 const Parallel_Orbitals* pv,
141 const psi::Psi<TK>& psi,
142 const UnitCell& ucell,
144 surchem& solvent,
145 const ModulePW::PW_Basis& rho_basis,
146 const ModulePW::PW_Basis& rhod_basis,
147 const ModuleBase::matrix& vloc,
148 const Charge& chg,
149 const K_Vectors& kv,
150 const std::vector<double>& orb_cutoff,
151 const ModuleBase::matrix& wg,
152 Grid_Driver& gd
153#ifdef __EXX
154 ,
155 std::vector<std::map<int, std::map<TAC, RI::Tensor<double>>>>* Hexxd = nullptr,
156 std::vector<std::map<int, std::map<TAC, RI::Tensor<std::complex<double>>>>>* Hexxc = nullptr
157#endif
158)
159{
160 ModuleBase::TITLE("ModuleIO", "write_Vxc");
161 int nbands = wg.nc;
162 // 1. real-space xc potential
163 // ModuleBase::matrix vr_xc(nspin, chg.nrxx);
164 double etxc = 0.0;
165 double vtxc = 0.0;
166 // elecstate::PotXC* potxc(&rho_basis, &etxc, vtxc, nullptr);
167 // potxc.cal_v_eff(&chg, &ucell, vr_xc);
169 = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc);
170 std::vector<std::string> compnents_list = {"xc"};
171 potxc->pot_register(compnents_list);
172 potxc->update_from_charge(&chg, &ucell);
173
174 // 2. allocate AO-matrix
175 // R (the number of hR: 1 for nspin=1, 4; 2 for nspin=2)
176 int nspin0 = (nspin == 2) ? 2 : 1;
177 std::vector<hamilt::HContainer<TR>> vxcs_R_ao(nspin0, hamilt::HContainer<TR>(ucell, pv));
178 for (int is = 0; is < nspin0; ++is) {
179 vxcs_R_ao[is].set_zero();
180 if (std::is_same<TK, double>::value) { vxcs_R_ao[is].fix_gamma(); }
181 }
182 // k (size for each k-point)
183 hamilt::HS_Matrix_K<TK> vxc_k_ao(pv, 1); // only hk is needed, sk is skipped
184
185 // 3. allocate operators and contribute HR
186 // op (corresponding to hR)
187
188 std::vector<hamilt::Veff<hamilt::OperatorLCAO<TK, TR>>*> vxcs_op_ao(nspin0);
189 for (int is = 0; is < nspin0; ++is)
190 {
191 vxcs_op_ao[is] = new hamilt::Veff<hamilt::OperatorLCAO<TK, TR>>(
192 &vxc_k_ao, kv.kvec_d, potxc, &vxcs_R_ao[is], &ucell, orb_cutoff, &gd, nspin);
193
194 vxcs_op_ao[is]->contributeHR();
195 }
196 std::vector<std::vector<double>> e_orb_locxc; // orbital energy (local XC)
197 std::vector<std::vector<double>> e_orb_tot; // orbital energy (total)
198#ifdef __EXX
199 hamilt::OperatorEXX<hamilt::OperatorLCAO<TK, TR>> vexx_op_ao(&vxc_k_ao,
200 &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, hamilt::Add_Hexx_Type::k);
201 hamilt::HS_Matrix_K<TK> vexxonly_k_ao(pv, 1); // only hk is needed, sk is skipped
202 hamilt::OperatorEXX<hamilt::OperatorLCAO<TK, TR>> vexxonly_op_ao(&vexxonly_k_ao,
203 &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, hamilt::Add_Hexx_Type::k);
204 std::vector<std::vector<double>> e_orb_exx; // orbital energy (EXX)
205#endif
206 hamilt::OperatorDFTU<hamilt::OperatorLCAO<TK, TR>> vdftu_op_ao(&vxc_k_ao, kv.kvec_d, nullptr, kv.isk);
207
208 // 4. calculate and write the MO-matrix Exc
209 Parallel_2D p2d;
210 set_para2d_MO(*pv, nbands, p2d);
211
212 // ======test=======
213 // double total_energy = 0.0;
214 // double exx_energy = 0.0;
215 // ======test=======
216 for (int ik = 0; ik < kv.get_nks(); ++ik)
217 {
218 vxc_k_ao.set_zero_hk();
219 int is = kv.isk[ik];
220 dynamic_cast<hamilt::OperatorLCAO<TK, TR>*>(vxcs_op_ao[is])->contributeHk(ik);
221 const std::vector<TK>& vlocxc_k_mo = cVc(vxc_k_ao.get_hk(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d);
222
223#ifdef __EXX
224 if (GlobalC::exx_info.info_global.cal_exx)
225 {
226 e_orb_locxc.emplace_back(orbital_energy(ik, nbands, vlocxc_k_mo, p2d));
227 ModuleBase::GlobalFunc::ZEROS(vexxonly_k_ao.get_hk(), pv->nloc);
228 vexx_op_ao.contributeHk(ik);
229 vexxonly_op_ao.contributeHk(ik);
230 std::vector<TK> vexx_k_mo = cVc(vexxonly_k_ao.get_hk(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d);
231 e_orb_exx.emplace_back(orbital_energy(ik, nbands, vexx_k_mo, p2d));
232 // ======test=======
233 // exx_energy += all_band_energy(ik, vexx_k_mo, p2d, wg);
234 // ======test=======
235 }
236#endif
237 if (PARAM.inp.dft_plus_u)
238 {
239 vdftu_op_ao.contributeHk(ik);
240 }
241 const std::vector<TK>& vxc_tot_k_mo = cVc(vxc_k_ao.get_hk(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d);
242 e_orb_tot.emplace_back(orbital_energy(ik, nbands, vxc_tot_k_mo, p2d));
243
244 // write
245
246 // mohan add 2025-06-02
247 const int istep = -1;
248 const int out_label = 1; // 1 means .txt while 2 means .dat
249 const bool out_app_flag = 0;
250 const bool gamma_only = PARAM.globalv.gamma_only_local;
251
252 std::string vxc_file = ModuleIO::filename_output(
254 "vxc","nao",ik,kv.ik2iktot,nspin,kv.get_nkstot(),
255 out_label,out_app_flag,gamma_only,istep);
256
257 ModuleIO::save_mat(istep,
258 vxc_tot_k_mo.data(),
259 nbands,
260 false /*binary*/,
262 true /*triangle*/,
263 out_app_flag /*append*/,
264 vxc_file,
265 p2d,
266 drank);
267 // ======test=======
268 // total_energy += all_band_energy(ik, vxc_tot_k_mo, p2d, wg);
269 // ======test=======
270 }
271 // ======test=======
272 // total_energy -= 0.5 * exx_energy;
273 // std::cout << "total energy: " << total_energy << std::endl;
274 // std::cout << "etxc: " << etxc << std::endl;
275 // std::cout << "vtxc_cal: " << total_energy - 0.5 * exx_energy << std::endl;
276 // std::cout << "vtxc_ref: " << vtxc << std::endl;
277 // std::cout << "exx_energy: " << 0.5 * exx_energy << std::endl;
278 // ======test=======
279 delete potxc;
280 for (int is = 0; is < nspin0; ++is)
281 {
282 delete vxcs_op_ao[is];
283 }
284
285 if (GlobalV::MY_RANK == 0)
286 {
287 write_orb_energy(kv, nspin0, nbands, e_orb_tot, "vxc", "");
288#ifdef __EXX
289 if (GlobalC::exx_info.info_global.cal_exx)
290 {
291 write_orb_energy(kv, nspin0, nbands, e_orb_locxc, "vxc", "local");
292 write_orb_energy(kv, nspin0, nbands, e_orb_exx, "vxc", "exx");
293 }
294#endif
295 }
296}
297} // namespace ModuleIO
298#endif
Definition charge.h:18
Definition sltk_grid_driver.h:43
Definition klist.h:13
int get_nks() const
Definition klist.h:68
std::vector< ModuleBase::Vector3< double > > kvec_d
Cartesian coordinates of k points.
Definition klist.h:16
std::vector< int > ik2iktot
[nks] map ik to the global index of k points
Definition klist.h:128
std::vector< int > isk
ngk, number of plane waves for each k point
Definition klist.h:21
int get_nkstot() const
Definition klist.h:73
Definition matrix.h:19
int nc
Definition matrix.h:24
A class which can convert a function of "r" to the corresponding linear superposition of plane waves ...
Definition pw_basis.h:56
This class packs the basic information of 2D-block-cyclic parallel distribution of an arbitrary matri...
Definition parallel_2d.h:12
bool in_this_processor(const int iw1_all, const int iw2_all) const
check whether a global index is in this process
Definition parallel_2d.cpp:8
int blacs_ctxt
BLACS context.
Definition parallel_2d.h:100
int local2global_col(const int ilc) const
get the global index of a local index (col)
Definition parallel_2d.h:63
int set(const int mg, const int ng, const int nb, const int blacs_ctxt)
Set up the info of a block-cyclic distribution using given BLACS context.
Definition parallel_2d.cpp:115
int get_row_size() const
number of local rows
Definition parallel_2d.h:21
void set_serial(const int mg, const int ng)
Definition parallel_2d.cpp:124
int local2global_row(const int ilr) const
get the global index of a local index (row)
Definition parallel_2d.h:57
int nb
block size
Definition parallel_2d.h:123
int global2local_col(const int igc) const
get the local index of a global index (col)
Definition parallel_2d.h:51
int global2local_row(const int igr) const
get the local index of a global index (row)
Definition parallel_2d.h:45
int64_t nloc
Definition parallel_2d.h:117
int desc[9]
ScaLAPACK descriptor.
Definition parallel_2d.h:103
int get_col_size() const
number of local columns
Definition parallel_2d.h:27
Definition parallel_orbitals.h:9
long nloc_wfc
ncol_bands*nrow
Definition parallel_orbitals.h:20
int desc_wfc[9]
Definition parallel_orbitals.h:37
const Input_para & inp
Definition parameter.h:26
const System_para & globalv
Definition parameter.h:30
static void gemm(const char transa, const char transb, const int M, const int N, const int K, const double alpha, const double *A, const int IA, const int JA, const int *DESCA, const double *B, const int IB, const int JB, const int *DESCB, const double beta, double *C, const int IC, const int JC, const int *DESCC)
Definition scalapack_connector.h:244
Definition structure_factor.h:11
Definition unitcell.h:17
Definition potential_new.h:49
void pot_register(const std::vector< std::string > &components_list)
Definition potential_new.cpp:64
void update_from_charge(const Charge *const chg, const UnitCell *const ucell)
Definition potential_new.cpp:158
Definition hcontainer.h:144
Definition hs_matrix_k.hpp:11
void set_zero_hk()
Definition hs_matrix_k.hpp:29
TK * get_hk()
Definition hs_matrix_k.hpp:23
Definition op_dftu_lcao.h:14
void contributeHk(int ik)
Definition op_dftu_lcao.cpp:24
Definition operator_lcao.h:12
Definition veff_lcao.h:18
void contributeHR()
Definition veff_lcao.cpp:60
Definition psi.h:37
Definition surchem.h:15
#define T
Definition exp.cpp:237
Exx_Info exx_info
Definition test_xc.cpp:29
int MY_RANK
global index of process
Definition global_variable.cpp:21
void ZEROS(std::complex< T > *u, const TI n)
Definition global_function.h:109
const double Ry_to_eV
Definition constants.h:81
void TITLE(const std::string &class_name, const std::string &function_name, const bool disable)
Definition tool_title.cpp:18
Definition cal_dos.h:9
void set_para2d_MO(const Parallel_Orbitals &pv, const int nbands, Parallel_2D &p2d)
Definition write_vxc.hpp:16
double get_real(const std::complex< double > &c)
Definition write_vxc.hpp:63
std::vector< double > orbital_energy(const int ik, const int nbands, const std::vector< T > &mat_mo, const Parallel_2D &p2d)
Definition write_vxc.hpp:92
std::pair< int, TC > TAC
Definition restart_exx_csr.h:11
std::vector< T > cVc(T *V, T *c, const int nbasis, const int nbands, const Parallel_Orbitals &pv, const Parallel_2D &p2d)
Definition write_vxc.hpp:27
void save_mat(const int istep, const T *mat, const int dim, const bool bit, const int precision, const bool tri, const bool app, const std::string &file_name, const Parallel_2D &pv, const int drank, const bool reduce=true)
save a square matrix, such as H(k) and S(k)
Definition write_HS.hpp:99
std::string filename_output(const std::string &directory, const std::string &property, const std::string &basis, const int ik_local, const std::vector< int > &ik2iktot, const int nspin, const int nkstot, const int out_type, const bool out_app_flag, const bool gamma_only, const int istep, const int iter)
Definition filename.cpp:8
void write_Vxc(const int nspin, const int nbasis, const int drank, const Parallel_Orbitals *pv, const psi::Psi< TK > &psi, const UnitCell &ucell, Structure_Factor &sf, surchem &solvent, const ModulePW::PW_Basis &rho_basis, const ModulePW::PW_Basis &rhod_basis, const ModuleBase::matrix &vloc, const Charge &chg, const K_Vectors &kv, const std::vector< double > &orb_cutoff, const ModuleBase::matrix &wg, Grid_Driver &gd)
write the Vxc matrix in KS orbital representation, usefull for GW calculation including terms: local/...
Definition write_vxc.hpp:137
double all_band_energy(const int ik, const std::vector< T > &mat_mo, const Parallel_2D &p2d, const ModuleBase::matrix &wg)
Definition write_vxc.hpp:74
void write_orb_energy(const K_Vectors &kv, const int nspin0, const int nbands, const std::vector< std::vector< double > > &e_orb, const std::string &term, const std::string &label, const bool app=false)
Definition write_vxc.hpp:110
void reduce_all(T &object)
reduce in all process
Definition depend_mock.cpp:14
Definition exx_lip.h:23
Parameter PARAM
Definition parameter.cpp:3
base device SOURCES math_hegvd_test cpp endif() if(ENABLE_GOOGLEBENCH) AddTest(TARGET PERF_MODULE_HSOLVER_KERNELS LIBS parameter $
Definition CMakeLists.txt:10
int dft_plus_u
0: standard DFT calculation (default)
Definition input_parameter.h:558
int out_ndigits
Assuming 8 digits precision is needed for matrices output.
Definition input_parameter.h:395
bool gamma_only_local
Definition system_parameter.h:38
std::string global_out_dir
global output directory
Definition system_parameter.h:42