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
13#ifndef TGINT_H
14#define TGINT_H
15template <typename T>
16struct TGint;
17
18template <>
19struct TGint<double>
20{
22};
23
24template <>
25struct TGint<std::complex<double>>
26{
27 using type = Gint_k;
28};
29#endif
30
31namespace ModuleIO
32{
33
34inline void set_para2d_MO(const Parallel_Orbitals& pv, const int nbands, Parallel_2D& p2d)
35{
36 std::ofstream ofs;
37#ifdef __MPI
38 p2d.set(nbands, nbands, pv.nb, pv.blacs_ctxt);
39#else
40 p2d.set_serial(nbands, nbands);
41#endif
42}
43
44template <typename T>
45inline std::vector<T> cVc(T* V,
46 T* c,
47 const int nbasis,
48 const int nbands,
49 const Parallel_Orbitals& pv,
50 const Parallel_2D& p2d)
51{
52 std::vector<T> Vc(pv.nloc_wfc, 0.0);
53 char transa = 'N';
54 char transb = 'N';
55 const T alpha = (T)1.0;
56 const T beta = (T)0.0;
57#ifdef __MPI
58 const int i1 = 1;
59 ScalapackConnector::gemm(transa, transb,
60 nbasis, nbands, nbasis,
61 alpha, V, i1, i1, pv.desc,
62 c, i1, i1, pv.desc_wfc,
63 beta, Vc.data(), i1, i1, pv.desc_wfc);
64#else
65 container::BlasConnector::gemm(transa, transb, nbasis, nbands, nbasis, alpha, V, nbasis, c, nbasis, beta, Vc.data(), nbasis);
66#endif
67 std::vector<T> cVc(p2d.nloc, 0.0);
68 transa = (std::is_same<T, double>::value ? 'T' : 'C');
69#ifdef __MPI
70 ScalapackConnector::gemm(transa, transb,
71 nbands, nbands, nbasis,
72 alpha, c, i1, i1, pv.desc_wfc,
73 Vc.data(), i1, i1, pv.desc_wfc,
74 beta, cVc.data(), i1, i1, p2d.desc);
75#else
76 container::BlasConnector::gemm(transa, transb, nbands, nbands, nbasis, alpha, c, nbasis, Vc.data(), nbasis, beta, cVc.data(), nbasis);
77#endif
78 return cVc;
79}
80
81inline double get_real(const std::complex<double>& c)
82{
83 return c.real();
84}
85
86inline double get_real(const double& d)
87{
88 return d;
89}
90
91template <typename T>
92double all_band_energy(const int ik, const std::vector<T>& mat_mo, const Parallel_2D& p2d, const ModuleBase::matrix& wg)
93{
94 double e = 0.0;
95 for (int i = 0; i < p2d.get_row_size(); ++i)
96 {
97 for (int j = 0; j < p2d.get_col_size(); ++j)
98 {
99 if (p2d.local2global_row(i) == p2d.local2global_col(j))
100 {
101 e += get_real(mat_mo[j * p2d.get_row_size() + i]) * wg(ik, p2d.local2global_row(i));
102 }
103 }
104 }
106 return e;
107}
108
109template <typename T>
110std::vector<double> orbital_energy(const int ik, const int nbands, const std::vector<T>& mat_mo, const Parallel_2D& p2d)
111{
112#ifdef __DEBUG
113 assert(nbands >= 0);
114#endif
115 std::vector<double> e(nbands, 0.0);
116 for (int i = 0; i < nbands; ++i)
117 {
118 if (p2d.in_this_processor(i, i))
119 {
120 const int index = p2d.global2local_col(i) * p2d.get_row_size() + p2d.global2local_row(i);
121 e[i] = get_real(mat_mo[index]);
122 }
123 }
124 Parallel_Reduce::reduce_all(e.data(), nbands);
125 return e;
126}
127
128#ifndef SET_GINT_POINTER_H
129#define SET_GINT_POINTER_H
130// mohan update 2024-04-01
131template <typename T>
132void set_gint_pointer(Gint_Gamma& gint_gamma, Gint_k& gint_k, typename TGint<T>::type*& gint);
133
134// mohan update 2024-04-01
135template <>
136void set_gint_pointer<double>(Gint_Gamma& gint_gamma, Gint_k& gint_k, typename TGint<double>::type*& gint)
137{
138 gint = &gint_gamma;
139}
140
141// mohan update 2024-04-01
142template <>
143void set_gint_pointer<std::complex<double>>(Gint_Gamma& gint_gamma,
144 Gint_k& gint_k,
145 typename TGint<std::complex<double>>::type*& gint)
146{
147 gint = &gint_k;
148}
149#endif
150
151inline void write_orb_energy(const K_Vectors& kv,
152 const int nspin0, const int nbands,
153 const std::vector<std::vector<double>>& e_orb,
154 const std::string& term, const std::string& label, const bool app = false)
155{
156 assert(e_orb.size() == kv.get_nks());
157 const int nk = kv.get_nks() / nspin0;
158 std::ofstream ofs;
159 ofs.open(PARAM.globalv.global_out_dir + term + "_" + (label == "" ? "out.dat" : label + "_out.dat"),
160 app ? std::ios::app : std::ios::out);
161 ofs << nk << "\n" << nspin0 << "\n" << nbands << "\n";
162 ofs << std::scientific << std::setprecision(16);
163 for (int ik = 0; ik < nk; ++ik)
164 {
165 for (int is = 0; is < nspin0; ++is)
166 {
167 for (auto e : e_orb[is * nk + ik])
168 { // Hartree and eV
169 ofs << e / 2. << "\t" << e * ModuleBase::Ry_to_eV << "\n";
170 }
171 }
172 }
173}
174
177template <typename TK, typename TR>
178void write_Vxc(const int nspin,
179 const int nbasis,
180 const int drank,
181 const Parallel_Orbitals* pv,
182 const psi::Psi<TK>& psi,
183 const UnitCell& ucell,
185 surchem& solvent,
186 const ModulePW::PW_Basis& rho_basis,
187 const ModulePW::PW_Basis& rhod_basis,
188 const ModuleBase::matrix& vloc,
189 const Charge& chg,
190 Gint_Gamma& gint_gamma, // mohan add 2024-04-01
191 Gint_k& gint_k, // mohan add 2024-04-01
192 const K_Vectors& kv,
193 const std::vector<double>& orb_cutoff,
194 const ModuleBase::matrix& wg,
195 Grid_Driver& gd
196#ifdef __EXX
197 ,
198 std::vector<std::map<int, std::map<TAC, RI::Tensor<double>>>>* Hexxd = nullptr,
199 std::vector<std::map<int, std::map<TAC, RI::Tensor<std::complex<double>>>>>* Hexxc = nullptr
200#endif
201)
202{
203 ModuleBase::TITLE("ModuleIO", "write_Vxc");
204 int nbands = wg.nc;
205 // 1. real-space xc potential
206 // ModuleBase::matrix vr_xc(nspin, chg.nrxx);
207 double etxc = 0.0;
208 double vtxc = 0.0;
209 // elecstate::PotXC* potxc(&rho_basis, &etxc, vtxc, nullptr);
210 // potxc.cal_v_eff(&chg, &ucell, vr_xc);
212 = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc);
213 std::vector<std::string> compnents_list = {"xc"};
214 potxc->pot_register(compnents_list);
215 potxc->update_from_charge(&chg, &ucell);
216
217 // 2. allocate AO-matrix
218 // R (the number of hR: 1 for nspin=1, 4; 2 for nspin=2)
219 int nspin0 = (nspin == 2) ? 2 : 1;
220 std::vector<hamilt::HContainer<TR>> vxcs_R_ao(nspin0, hamilt::HContainer<TR>(ucell, pv));
221 for (int is = 0; is < nspin0; ++is) {
222 vxcs_R_ao[is].set_zero();
223 if (std::is_same<TK, double>::value) { vxcs_R_ao[is].fix_gamma(); }
224 }
225 // k (size for each k-point)
226 hamilt::HS_Matrix_K<TK> vxc_k_ao(pv, 1); // only hk is needed, sk is skipped
227
228 // 3. allocate operators and contribute HR
229 // op (corresponding to hR)
230 typename TGint<TK>::type* gint = nullptr;
231
232 set_gint_pointer<TK>(gint_gamma, gint_k, gint);
233
234 std::vector<hamilt::Veff<hamilt::OperatorLCAO<TK, TR>>*> vxcs_op_ao(nspin0);
235 for (int is = 0; is < nspin0; ++is)
236 {
237 vxcs_op_ao[is] = new hamilt::Veff<hamilt::OperatorLCAO<TK, TR>>(gint,
238 &vxc_k_ao, kv.kvec_d, potxc, &vxcs_R_ao[is], &ucell, orb_cutoff, &gd, nspin);
239
240 vxcs_op_ao[is]->contributeHR();
241 }
242 std::vector<std::vector<double>> e_orb_locxc; // orbital energy (local XC)
243 std::vector<std::vector<double>> e_orb_tot; // orbital energy (total)
244#ifdef __EXX
245 hamilt::OperatorEXX<hamilt::OperatorLCAO<TK, TR>> vexx_op_ao(&vxc_k_ao,
246 &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, hamilt::Add_Hexx_Type::k);
247 hamilt::HS_Matrix_K<TK> vexxonly_k_ao(pv, 1); // only hk is needed, sk is skipped
248 hamilt::OperatorEXX<hamilt::OperatorLCAO<TK, TR>> vexxonly_op_ao(&vexxonly_k_ao,
249 &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, hamilt::Add_Hexx_Type::k);
250 std::vector<std::vector<double>> e_orb_exx; // orbital energy (EXX)
251#endif
252 hamilt::OperatorDFTU<hamilt::OperatorLCAO<TK, TR>> vdftu_op_ao(&vxc_k_ao, kv.kvec_d, nullptr, kv.isk);
253
254 // 4. calculate and write the MO-matrix Exc
255 Parallel_2D p2d;
256 set_para2d_MO(*pv, nbands, p2d);
257
258 // ======test=======
259 // double total_energy = 0.0;
260 // double exx_energy = 0.0;
261 // ======test=======
262 for (int ik = 0; ik < kv.get_nks(); ++ik)
263 {
264 vxc_k_ao.set_zero_hk();
265 int is = kv.isk[ik];
266 dynamic_cast<hamilt::OperatorLCAO<TK, TR>*>(vxcs_op_ao[is])->contributeHk(ik);
267 const std::vector<TK>& vlocxc_k_mo = cVc(vxc_k_ao.get_hk(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d);
268
269#ifdef __EXX
270 if (GlobalC::exx_info.info_global.cal_exx)
271 {
272 e_orb_locxc.emplace_back(orbital_energy(ik, nbands, vlocxc_k_mo, p2d));
273 ModuleBase::GlobalFunc::ZEROS(vexxonly_k_ao.get_hk(), pv->nloc);
274 vexx_op_ao.contributeHk(ik);
275 vexxonly_op_ao.contributeHk(ik);
276 std::vector<TK> vexx_k_mo = cVc(vexxonly_k_ao.get_hk(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d);
277 e_orb_exx.emplace_back(orbital_energy(ik, nbands, vexx_k_mo, p2d));
278 // ======test=======
279 // exx_energy += all_band_energy(ik, vexx_k_mo, p2d, wg);
280 // ======test=======
281 }
282#endif
283 if (PARAM.inp.dft_plus_u)
284 {
285 vdftu_op_ao.contributeHk(ik);
286 }
287 const std::vector<TK>& vxc_tot_k_mo = cVc(vxc_k_ao.get_hk(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d);
288 e_orb_tot.emplace_back(orbital_energy(ik, nbands, vxc_tot_k_mo, p2d));
289
290 // write
291
292 // mohan add 2025-06-02
293 const int istep = -1;
294 const int out_label = 1; // 1 means .txt while 2 means .dat
295 const bool out_app_flag = 0;
296 const bool gamma_only = PARAM.globalv.gamma_only_local;
297
298 std::string vxc_file = ModuleIO::filename_output(
300 "vxc","nao",ik,kv.ik2iktot,nspin,kv.get_nkstot(),
301 out_label,out_app_flag,gamma_only,istep);
302
303 ModuleIO::save_mat(istep,
304 vxc_tot_k_mo.data(),
305 nbands,
306 false /*binary*/,
308 true /*triangle*/,
309 out_app_flag /*append*/,
310 vxc_file,
311 p2d,
312 drank);
313 // ======test=======
314 // total_energy += all_band_energy(ik, vxc_tot_k_mo, p2d, wg);
315 // ======test=======
316 }
317 // ======test=======
318 // total_energy -= 0.5 * exx_energy;
319 // std::cout << "total energy: " << total_energy << std::endl;
320 // std::cout << "etxc: " << etxc << std::endl;
321 // std::cout << "vtxc_cal: " << total_energy - 0.5 * exx_energy << std::endl;
322 // std::cout << "vtxc_ref: " << vtxc << std::endl;
323 // std::cout << "exx_energy: " << 0.5 * exx_energy << std::endl;
324 // ======test=======
325 delete potxc;
326 for (int is = 0; is < nspin0; ++is)
327 {
328 delete vxcs_op_ao[is];
329 }
330
331 if (GlobalV::MY_RANK == 0)
332 {
333 write_orb_energy(kv, nspin0, nbands, e_orb_tot, "vxc", "");
334#ifdef __EXX
335 if (GlobalC::exx_info.info_global.cal_exx)
336 {
337 write_orb_energy(kv, nspin0, nbands, e_orb_locxc, "vxc", "local");
338 write_orb_energy(kv, nspin0, nbands, e_orb_exx, "vxc", "exx");
339 }
340#endif
341 }
342}
343} // namespace ModuleIO
344#endif
Definition charge.h:20
Definition gint_gamma.h:23
Definition gint_k.h:13
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:16
Definition potential_new.h:48
void pot_register(const std::vector< std::string > &components_list)
Definition potential_new.cpp:62
void update_from_charge(const Charge *const chg, const UnitCell *const ucell)
Definition potential_new.cpp:152
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:20
void contributeHR()
Definition veff_lcao.cpp:60
Definition psi.h:37
Definition surchem.h:15
std::complex< double > complex
Definition diago_cusolver.cpp:13
#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
This class has two functions: restart psi from the previous calculation, and write psi to the disk.
Definition cal_dos.h:9
void set_para2d_MO(const Parallel_Orbitals &pv, const int nbands, Parallel_2D &p2d)
Definition write_vxc.hpp:34
double get_real(const std::complex< double > &c)
Definition write_vxc.hpp:81
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:110
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:45
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
void set_gint_pointer< double >(Gint_Gamma &gint_gamma, Gint_k &gint_k, typename TGint< double >::type *&gint)
Definition write_vxc.hpp:136
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)
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, Gint_Gamma &gint_gamma, Gint_k &gint_k, 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:178
void set_gint_pointer(Gint_Gamma &gint_gamma, Gint_k &gint_k, typename TGint< T >::type *&gint)
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:92
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:151
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_dngvd_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:554
int out_ndigits
Assuming 8 digits precision is needed for matrices output.
Definition input_parameter.h:393
bool gamma_only_local
Definition system_parameter.h:38
std::string global_out_dir
global output directory
Definition system_parameter.h:42
Definition write_vxc.hpp:16