15 const psi::Psi<std::complex<double>, Device>* kspw_psi,
20 const std::string& global_out_dir,
21 const bool if_separate_k,
32 for (
int ip = 0; ip < kpar; ++ip)
40 std::vector<int> bands_picked(nbands, 0);
43 if (
static_cast<int>(out_pchg.size()) > nbands)
46 "The number of bands specified by `out_pchg` in the "
47 "INPUT file exceeds `nbands`!");
51 for (
int value: out_pchg)
53 if (value != 0 && value != 1)
56 "The elements of `out_pchg` must be either 0 or 1. "
57 "Invalid values found!");
63 int length = std::min(
static_cast<int>(out_pchg.size()), nbands);
64 for (
int i = 0; i < length; ++i)
67 bands_picked[i] =
static_cast<int>(out_pchg[i]);
71 std::vector<std::complex<double>> wfcr(nxyz);
72 std::vector<std::vector<double>> rho_band(nspin, std::vector<double>(nxyz));
75 std::complex<double>* wfcr_device =
nullptr;
76 if (!std::is_same<Device, base_device::DEVICE_CPU>::value)
81 for (
int ib = 0; ib < nbands; ++ib)
84 if (!bands_picked[ib])
89 for (
int is = 0; is < nspin; ++is)
91 std::fill(rho_band[is].begin(), rho_band[is].end(), 0.0);
96 for (
int ik = 0; ik < nks; ++ik)
99 const int spin_index = kv.
isk[ik];
100 const int k_number = ikstot % (nkstot / nspin) + 1;
105 if (std::is_same<Device, base_device::DEVICE_CPU>::value)
107 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr.data(), ik);
111 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr_device, ik);
114 base_device::DEVICE_CPU,
115 Device>()(wfcr.data(), wfcr_device, nxyz);
119 double wg_sum_k = 0.0;
131 "Real space partial charge output currently do not support "
132 "noncollinear polarized calculation (nspin = 4)!");
135 double w1 =
static_cast<double>(wg_sum_k / ucell->
omega);
137 for (
int i = 0; i < nxyz; ++i)
139 rho_band[spin_index][i] = std::norm(wfcr[i]) * w1;
142 std::stringstream ssc;
143 ssc << global_out_dir <<
"pchgi" << ib + 1 <<
"s" << spin_index + 1 <<
"k" << k_number <<
".cube";
146 rho_band[spin_index].data(),
160 for (
int ik = 0; ik < nks; ++ik)
163 const int spin_index = kv.
isk[ik];
164 const int k_number = ikstot % (nkstot / nspin) + 1;
169 if (std::is_same<Device, base_device::DEVICE_CPU>::value)
171 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr.data(), ik);
175 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr_device, ik);
178 base_device::DEVICE_CPU,
179 Device>()(wfcr.data(), wfcr_device, nxyz);
182 double w1 =
static_cast<double>(kv.
wk[ik] / ucell->
omega);
184 for (
int i = 0; i < nxyz; ++i)
186 rho_band[spin_index][i] += std::norm(wfcr[i]) * w1;
192 if (kpar > 1 && chr !=
nullptr)
194 for (
int is = 0; is < nspin; ++is)
204 for (
int is = 0; is < nspin; ++is)
207 std::vector<double*> rho_save_pointers(nspin);
208 for (
int s = 0; s < nspin; ++s)
210 rho_save_pointers[s] = rho_band[s].data();
213 std::vector<std::vector<std::complex<double>>> rhog(nspin,
214 std::vector<std::complex<double>>(chr_ngmc));
217 std::vector<std::complex<double>*> rhog_pointers(nspin);
218 for (
int s = 0; s < nspin; ++s)
220 rhog_pointers[s] = rhog[s].data();
224 rho_save_pointers.data(),
225 rhog_pointers.data(),
232 for (
int is = 0; is < nspin; ++is)
234 std::stringstream ssc;
235 ssc << global_out_dir <<
"pchgi" << ib + 1 <<
"s" << is + 1 <<
".cube";
void get_pchg_pw(const std::vector< int > &out_pchg, const int nbands, const int nspin, const int nxyz, const int chr_ngmc, UnitCell *ucell, const psi::Psi< std::complex< double >, Device > *kspw_psi, const ModulePW::PW_Basis *pw_rhod, const ModulePW::PW_Basis_K *pw_wfc, const Device *ctx, const Parallel_Grid &pgrid, const std::string &global_out_dir, const bool if_separate_k, const K_Vectors &kv, const int kpar, const int my_pool, const Charge *chr)
Definition get_pchg_pw.h:9
void write_vdata_palgrid(const Parallel_Grid &pgrid, const double *const data, const int is, const int nspin, const int iter, const std::string &fn, const double ef, const UnitCell *const ucell, const int precision=11, const int out_fermi=1, const bool reduce_all_pool=false)
write volumetric data on the parallized grid into a .cube file
Definition write_cube.cpp:15