16 const psi::Psi<std::complex<double>, Device>* kspw_psi,
21 const std::string& global_out_dir,
22 const bool if_separate_k,
33 for (
int ip = 0; ip < kpar; ++ip)
41 std::vector<int> bands_picked(nbands, 0);
44 if (
static_cast<int>(out_pchg.size()) > nbands)
47 "The number of bands specified by `out_pchg` in the "
48 "INPUT file exceeds `nbands`!");
52 for (
int value: out_pchg)
54 if (value != 0 && value != 1)
57 "The elements of `out_pchg` must be either 0 or 1. "
58 "Invalid values found!");
64 int length = std::min(
static_cast<int>(out_pchg.size()), nbands);
65 for (
int i = 0; i < length; ++i)
68 bands_picked[i] =
static_cast<int>(out_pchg[i]);
72 std::vector<std::complex<double>> wfcr(nxyz);
73 std::vector<std::vector<double>> rho_band(nspin, std::vector<double>(nxyz));
76 std::complex<double>* wfcr_device =
nullptr;
77 if (!std::is_same<Device, base_device::DEVICE_CPU>::value)
82 for (
int ib = 0; ib < nbands; ++ib)
85 if (!bands_picked[ib])
90 for (
int is = 0; is < nspin; ++is)
92 std::fill(rho_band[is].begin(), rho_band[is].end(), 0.0);
97 for (
int ik = 0; ik < nks; ++ik)
100 const int spin_index = kv.
isk[ik];
101 const int k_number = ikstot % (nkstot / nspin) + 1;
106 if (std::is_same<Device, base_device::DEVICE_CPU>::value)
108 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr.data(), ik);
112 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr_device, ik);
115 base_device::DEVICE_CPU,
116 Device>()(wfcr.data(), wfcr_device, nxyz);
120 double wg_sum_k = 0.0;
132 "Real space partial charge output currently do not support "
133 "noncollinear polarized calculation (nspin = 4)!");
136 double w1 =
static_cast<double>(wg_sum_k / ucell->
omega);
138 for (
int i = 0; i < nxyz; ++i)
140 rho_band[spin_index][i] = std::norm(wfcr[i]) * w1;
143 std::stringstream ssc;
144 ssc << global_out_dir <<
"pchgi" << ib + 1 <<
"s" << spin_index + 1 <<
"k" << k_number <<
".cube";
147 rho_band[spin_index].data(),
161 for (
int ik = 0; ik < nks; ++ik)
164 const int spin_index = kv.
isk[ik];
165 const int k_number = ikstot % (nkstot / nspin) + 1;
170 if (std::is_same<Device, base_device::DEVICE_CPU>::value)
172 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr.data(), ik);
176 pw_wfc->
recip_to_real(ctx, &kspw_psi[0](ib, 0), wfcr_device, ik);
179 base_device::DEVICE_CPU,
180 Device>()(wfcr.data(), wfcr_device, nxyz);
183 double w1 =
static_cast<double>(kv.
wk[ik] / ucell->
omega);
185 for (
int i = 0; i < nxyz; ++i)
187 rho_band[spin_index][i] += std::norm(wfcr[i]) * w1;
193 if (kpar > 1 && chr !=
nullptr)
195 for (
int is = 0; is < nspin; ++is)
205 for (
int is = 0; is < nspin; ++is)
208 std::vector<double*> rho_save_pointers(nspin);
209 for (
int s = 0; s < nspin; ++s)
211 rho_save_pointers[s] = rho_band[s].data();
214 std::vector<std::vector<std::complex<double>>> rhog(nspin,
215 std::vector<std::complex<double>>(chr_ngmc));
218 std::vector<std::complex<double>*> rhog_pointers(nspin);
219 for (
int s = 0; s < nspin; ++s)
221 rhog_pointers[s] = rhog[s].data();
225 rho_save_pointers.data(),
226 rhog_pointers.data(),
233 for (
int is = 0; is < nspin; ++is)
235 std::stringstream ssc;
236 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:10
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