ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
write_vxc_lip.hpp
Go to the documentation of this file.
1#ifndef __WRITE_VXC_LIP_H_
2#define __WRITE_VXC_LIP_H_
7#include "source_psi/psi.h"
9#include "source_cell/klist.h"
11#include "source_io/write_HS.h"
12#include "source_io/filename.h" // use filename_output function
13#include <type_traits>
14
15namespace ModuleIO
16{
17 template<typename T>
18 using Real = typename GetTypeReal<T>::type;
19
20 template<typename FPTYPE>
21 inline FPTYPE get_real(const std::complex<FPTYPE>& c)
22 {
23 return c.real();
24 }
25 template<typename FPTYPE>
26 inline FPTYPE get_real(const FPTYPE& d)
27 {
28 return d;
29 }
30
31 template <typename T>
32 std::vector<T> cVc(T* const V, T* const c, int nbasis, int nbands)
33 {
34 std::vector<T> Vc(nbasis * nbands, 0.0);
35 char transa = 'N';
36 char transb = 'N';
37 const T alpha(1.0, 0.0);
38 const T beta(0.0, 0.0);
39 container::BlasConnector::gemm(transa, transb, nbasis, nbands, nbasis,
40 alpha, V, nbasis, c, nbasis, beta, Vc.data(), nbasis);
41
42 std::vector<T> cVc(nbands * nbands, 0.0);
43 transa = ((std::is_same<T, double>::value || std::is_same<T, float>::value) ? 'T' : 'C');
44 container::BlasConnector::gemm(transa, transb, nbands, nbands, nbasis,
45 alpha, c, nbasis, Vc.data(), nbasis, beta, cVc.data(), nbands);
46 return cVc;
47 }
48
49 template <typename FPTYPE>
50 std::vector<std::complex<FPTYPE>> psi_Hpsi(std::complex<FPTYPE>* const psi,
51 std::complex<FPTYPE>* const hpsi, const int nbasis, const int nbands)
52 {
53 using T = std::complex<FPTYPE>;
54 std::vector<T> cVc(nbands * nbands, (T)0.0);
55 const T alpha(1.0, 0.0);
56 const T beta(0.0, 0.0);
57 container::BlasConnector::gemm('C', 'N', nbands, nbands, nbasis, alpha,
58 psi, nbasis, hpsi, nbasis, beta, cVc.data(), nbands);
59 return cVc;
60 }
61
62 template <typename FPTYPE>
63 std::vector<FPTYPE> orbital_energy(const int ik, const int nbands,
64 const std::vector<std::complex<FPTYPE>>& mat_mo)
65 {
66#ifdef __DEBUG
67 assert(nbands >= 0);
68#endif
69 std::vector<FPTYPE> e(nbands, 0.0);
70 for (int i = 0; i < nbands; ++i)
71 {
72 e[i] = get_real(mat_mo[i * nbands + i]);
73 }
74 return e;
75 }
76
77 template <typename FPTYPE>
78 FPTYPE all_band_energy(const int ik, const int nbands,
79 const std::vector<std::complex<FPTYPE>>& mat_mo, const ModuleBase::matrix& wg)
80 {
81 FPTYPE e = 0.0;
82 for (int i = 0; i < nbands; ++i)
83 {
84 e += get_real(mat_mo[i * nbands + i]) * (FPTYPE)wg(ik, i);
85 }
86 return e;
87 }
88
89 template <typename FPTYPE>
90 FPTYPE all_band_energy(const int ik, const std::vector<FPTYPE>& orbital_energy,
91 const ModuleBase::matrix& wg)
92 {
93 FPTYPE e = 0.0;
94 for (int i = 0; i < orbital_energy.size(); ++i)
95 {
96 e += orbital_energy[i] * (FPTYPE)wg(ik, i);
97 }
98 return e;
99 }
100
103 template <typename FPTYPE>
104 void write_Vxc(int nspin,
105 int naos,
106 int drank,
107 const psi::Psi<std::complex<FPTYPE>>& psi_pw,
108 // const psi::Psi<T>& psi_lcao,
109 const UnitCell& ucell,
111 surchem& solvent,
112 const ModulePW::PW_Basis_K& wfc_basis,
113 const ModulePW::PW_Basis& rho_basis,
114 const ModulePW::PW_Basis& rhod_basis,
115 const ModuleBase::matrix& vloc,
116 const Charge& chg,
117 const K_Vectors& kv,
118 const ModuleBase::matrix& wg
119#ifdef __EXX
120 ,
121 const Exx_Lip<std::complex<FPTYPE>>& exx_lip
122#endif
123 )
124 {
125 using T = std::complex<FPTYPE>;
126 ModuleBase::TITLE("ModuleIO", "write_Vxc_LIP");
127 int nbands = wg.nc;
128 // 1. real-space xc potential
129 // ModuleBase::matrix vr_xc(nspin, chg.nrxx);
130 double etxc = 0.0;
131 double vtxc = 0.0;
132 // elecstate::PotXC* potxc(&rho_basis, &etxc, vtxc, nullptr);
133 // potxc.cal_v_eff(&chg, &ucell, vr_xc);
135 = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc);
136 std::vector<std::string> compnents_list = { "xc" };
137
138 potxc->pot_register(compnents_list);
139 potxc->update_from_charge(&chg, &ucell);
140 // const ModuleBase::matrix vr_localxc = potxc->get_veff_smooth();
141
142 // 2. allocate xc operator
143 psi::Psi<T> hpsi_localxc(psi_pw.get_nk(), psi_pw.get_nbands(), psi_pw.get_nbasis(), kv.ngk, true);
144 hpsi_localxc.zero_out();
145 // std::cout << "hpsi.nk=" << hpsi_localxc.get_nk() << std::endl;
146 // std::cout << "hpsi.nbands=" << hpsi_localxc.get_nbands() << std::endl;
147 // std::cout << "hpsi.nbasis=" << hpsi_localxc.get_nbasis() << std::endl;
149
150
151 std::vector<std::vector<FPTYPE>> e_orb_locxc; // orbital energy (local XC)
152 std::vector<std::vector<FPTYPE>> e_orb_tot; // orbital energy (total)
153 std::vector<std::vector<FPTYPE>> e_orb_exx; // orbital energy (EXX)
154 Parallel_2D p2d_serial;
155 p2d_serial.set_serial(nbands, nbands);
156 // ======test=======
157 std::vector<FPTYPE> exx_energy(kv.get_nks());
158 // ======test=======s
159 for (int ik = 0; ik < kv.get_nks(); ++ik)
160 {
161 // 2.1 local xc
162 vxcs_op_pw = new hamilt::Veff<hamilt::OperatorPW<T>>(kv.isk.data(),
163 potxc->get_veff_smooth_data<FPTYPE>(), potxc->get_veff_smooth().nr, potxc->get_veff_smooth().nc, &wfc_basis);
164 vxcs_op_pw->init(ik); // set k-point index
165 psi_pw.fix_k(ik);
166 hpsi_localxc.fix_k(ik);
167#ifdef __DEBUG
168 assert(hpsi_localxc.get_current_nbas() == psi_pw.get_current_nbas());
169 assert(hpsi_localxc.get_current_nbas() == hpsi_localxc.get_ngk(ik));
170#endif
172 // for (int ib = 0;ib < psi_pw.get_nbands();++ib)
173 // {
174 // std::cout<<"ib="<<ib<<std::endl;
175 // psi::Psi<T> psi_single_band(&psi_pw(ik, ib, 0), 1, 1, psi_pw.get_current_nbas());
176 // psi::Psi<T> hpsi_single_band(&hpsi_localxc(ik, ib, 0), 1, 1, hpsi_localxc.get_current_nbas());
177 // vxcs_op_pw->act(1, psi_pw.get_current_nbas(), psi_pw.npol, psi_single_band.get_pointer(), hpsi_single_band.get_pointer(), psi_pw.get_ngk(ik));
178 // }
179 vxcs_op_pw->act(psi_pw.get_nbands(), psi_pw.get_nbasis(), psi_pw.get_npol(), &psi_pw(ik, 0, 0), &hpsi_localxc(ik, 0, 0), psi_pw.get_ngk(ik));
180 delete vxcs_op_pw;
181 std::vector<T> vxc_local_k_mo = psi_Hpsi(&psi_pw(ik, 0, 0), &hpsi_localxc(ik, 0, 0), psi_pw.get_nbasis(), psi_pw.get_nbands());
182 Parallel_Reduce::reduce_pool(vxc_local_k_mo.data(), nbands * nbands);
183 e_orb_locxc.emplace_back(orbital_energy(ik, nbands, vxc_local_k_mo));
184
185 // 2.2 exx
186 std::vector<T> vxc_tot_k_mo(std::move(vxc_local_k_mo));
187 std::vector<T> vexx_k_ao(naos * naos);
188#if((defined __LCAO)&&(defined __EXX) && !(defined __CUDA)&& !(defined __ROCM))
189 if (GlobalC::exx_info.info_global.cal_exx)
190 {
191 for (int n = 0; n < naos; ++n)
192 {
193 for (int m = 0; m < naos; ++m)
194 {
195 vexx_k_ao[n * naos + m] += (T)GlobalC::exx_info.info_global.hybrid_alpha
196 * exx_lip.get_exx_matrix()[ik][m][n];
197 }
198 }
199 std::vector<T> vexx_k_mo = cVc(vexx_k_ao.data(), &(exx_lip.get_hvec()(ik, 0, 0)), naos, nbands);
200 Parallel_Reduce::reduce_pool(vexx_k_mo.data(), nbands * nbands);
201 e_orb_exx.emplace_back(orbital_energy(ik, nbands, vexx_k_mo));
202 // ======test=======
203 // std::cout << "exx_energy from matrix:" << all_band_energy(ik, nbands, vexx_k_mo, wg) << std::endl;
204 // std::cout << "exx_energy from orbitals: " << all_band_energy(ik, e_orb_exx.at(ik), wg) << std::endl;
205 // std::cout << "exx_energy from exx_lip: " << GlobalC::exx_info.info_global.hybrid_alpha * exx_lip.get_exx_energy() << std::endl;
206 // ======test=======
207 container::BlasConnector::axpy(nbands * nbands, 1.0, vexx_k_mo.data(), 1, vxc_tot_k_mo.data(), 1);
208 }
209#endif
210
212 // mohan add 2025-06-02
213 const int istep = -1;
214 const int out_label = 1; // 1 means .txt while 2 means .dat
215 const bool out_app_flag = 0;
216 const bool gamma_only = PARAM.globalv.gamma_only_local;
217
218 std::string vxc_file = ModuleIO::filename_output(
220 "vxc","nao",ik,kv.ik2iktot,nspin,kv.get_nkstot(),
221 out_label,out_app_flag,gamma_only,istep);
222
223 ModuleIO::save_mat(istep, vxc_tot_k_mo.data(), nbands,
224 false, PARAM.inp.out_ndigits, true,
225 out_app_flag, vxc_file,
226 p2d_serial, drank, false);
227
228 e_orb_tot.emplace_back(orbital_energy(ik, nbands, vxc_tot_k_mo));
229 }
230 //===== test total xc energy =======
231 // std::cout << "xc energy =" << etxc << std::endl;
232 // std::cout << "vtxc=" << vtxc << std::endl;
233 // FPTYPE exc_by_orb = 0.0;
234 // for (int ik = 0;ik < e_orb_locxc.size();++ik)
235 // exc_by_orb += all_band_energy(ik, e_orb_locxc[ik], wg);
236 // std::cout << "xc all-bands energy by orbital =" << exc_by_orb << std::endl;
237 // /// calculate orbital energy by grid integration of vtxc*rho
238 // FPTYPE exc_by_rho = 0.0;
239 // for (int ir = 0;ir < potxc->get_veff_smooth().nc;++ir)
240 // exc_by_rho += potxc->get_veff_smooth()(0, ir) * chg.rho[0][ir];
241 // Parallel_Reduce::reduce_all(exc_by_rho);
242 // exc_by_rho *= ((FPTYPE)ucell.omega * (FPTYPE)GlobalV::NPROC / (FPTYPE)potxc->get_veff_smooth().nc);
243 // std::cout << "xc all-bands energy by rho =" << exc_by_rho << std::endl;
244 //===== test total xc energy =======
245 //===== test total exx energy =======
246// #if((defined __LCAO)&&(defined __EXX) && !(defined __CUDA)&& !(defined __ROCM))
247// if (GlobalC::exx_info.info_global.cal_exx)
248// {
249// FPTYPE exx_by_orb = 0.0;
250// for (int ik = 0;ik < e_orb_exx.size();++ik)
251// exx_by_orb += all_band_energy(ik, e_orb_exx[ik], wg);
252// exx_by_orb /= 2;
253// std::cout << "exx all-bands energy by orbital =" << exx_by_orb << std::endl;
254// FPTYPE exx_from_lip = GlobalC::exx_info.info_global.hybrid_alpha * exx_lip.get_exx_energy();
255// std::cout << "exx all-bands energy from exx_lip =" << exx_from_lip << std::endl;
256// }
257// #endif
258 //===== test total exx energy =======
259 // write the orbital energy for xc and exx in LibRPA format
260 const int nspin0 = (nspin == 2) ? 2 : 1;
261 auto write_orb_energy = [&kv, &nspin0, &nbands](const std::vector<std::vector<FPTYPE>>& e_orb,
262 const std::string& label,
263 const bool app = false) {
264 assert(e_orb.size() == kv.get_nks());
265 const int nk = kv.get_nks() / nspin0;
266 std::ofstream ofs;
267 ofs.open(PARAM.globalv.global_out_dir + "vxc_" + (label == "" ? "out.dat" : label + "_out.dat"),
268 app ? std::ios::app : std::ios::out);
269 ofs << nk << "\n" << nspin0 << "\n" << nbands << "\n";
270 ofs << std::scientific << std::setprecision(16);
271 for (int ik = 0; ik < nk; ++ik)
272 {
273 for (int is = 0; is < nspin0; ++is)
274 {
275 for (auto e : e_orb[is * nk + ik])
276 { // Hartree and eV
277 ofs << e / 2. << "\t" << e * (FPTYPE)ModuleBase::Ry_to_eV << "\n";
278 }
279 }
280 }
281 };
282
283 if (GlobalV::MY_RANK == 0)
284 {
285 write_orb_energy(e_orb_tot, "");
286#if((defined __LCAO)&&(defined __EXX) && !(defined __CUDA)&& !(defined __ROCM))
287 if (GlobalC::exx_info.info_global.cal_exx)
288 {
289 write_orb_energy(e_orb_locxc, "local");
290 write_orb_energy(e_orb_exx, "exx");
291 }
292#endif
293 }
294 }
295} // namespace ModuleIO
296#endif
Definition charge.h:20
Definition exx_lip.h:30
Definition klist.h:13
int get_nks() const
Definition klist.h:68
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
std::vector< int > ngk
wk, weight of k points
Definition klist.h:20
int get_nkstot() const
Definition klist.h:73
Definition matrix.h:19
int nr
Definition matrix.h:23
int nc
Definition matrix.h:24
Special pw_basis class. It includes different k-points.
Definition pw_basis_k.h:57
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
void set_serial(const int mg, const int ng)
Definition parallel_2d.cpp:124
const Input_para & inp
Definition parameter.h:26
const System_para & globalv
Definition parameter.h:30
Definition structure_factor.h:11
Definition unitcell.h:16
Definition potential_new.h:48
ModuleBase::matrix & get_veff_smooth()
Definition potential_new.h:141
void pot_register(const std::vector< std::string > &components_list)
Definition potential_new.cpp:62
FPTYPE * get_veff_smooth_data()
void update_from_charge(const Charge *const chg, const UnitCell *const ucell)
Definition potential_new.cpp:152
Definition veff_lcao.h:20
Definition psi.h:37
int get_current_nbas() const
Definition psi.cpp:474
const int & get_nbasis() const
Definition psi.cpp:348
void zero_out()
Definition psi.cpp:487
const int & get_ngk(const int ik_in) const
Definition psi.cpp:480
void fix_k(const int ik) const
Definition psi.cpp:364
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
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
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::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
typename GetTypeReal< T >::type Real
Definition write_vxc_lip.hpp:18
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
std::vector< std::complex< FPTYPE > > psi_Hpsi(std::complex< FPTYPE > *const psi, std::complex< FPTYPE > *const hpsi, const int nbasis, const int nbands)
Definition write_vxc_lip.hpp:50
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
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_pool(T &object)
Definition depend_mock.cpp:15
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
T type
Definition macros.h:8
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