1+ #include " elecstate_lcao.h"
2+ #include " math_tools.h"
3+ #include " module_base/timer.h"
4+ #include " src_lcao/grid_technique.h"
5+
6+ namespace elecstate
7+ {
8+
9+ // for gamma_only(double case) and multi-k(complex<double> case)
10+ template <typename T> void ElecStateLCAO::cal_dm (const ModuleBase::matrix& wg,
11+ const psi::Psi<T>& wfc,
12+ psi::Psi<T>& dm)
13+ {
14+ ModuleBase::TITLE (" ElecStateLCAO" , " cal_dm" );
15+
16+ dm.resize ( wfc.get_nk (), this ->loc ->ParaV ->ncol , this ->loc ->ParaV ->nrow );
17+ const int nbands_local = wfc.get_nbands ();
18+ const int nbasis_local = wfc.get_nbasis ();
19+
20+ // dm = wfc.T * wg * wfc.conj()
21+ // dm[is](iw1,iw2) = \sum_{ib} wfc[is](ib,iw1).T * wg(is,ib) * wfc[is](ib,iw2).conj()
22+ for (int ik=0 ; ik<wfc.get_nk (); ++ik)
23+ {
24+ wfc.fix_k (ik);
25+ dm.fix_k (ik);
26+ // wg_wfc(ib,iw) = wg[ib] * wfc(ib,iw);
27+ psi::Psi<T> wg_wfc ( wfc, 1 );
28+
29+ int ib_global = 0 ;
30+ for (int ib_local=0 ; ib_local<nbands_local; ++ib_local)
31+ {
32+ while (ib_local != this ->loc ->ParaV ->trace_loc_col [ib_global])
33+ {
34+ ++ib_global;
35+ if (ib_global>=wg.nc )
36+ {
37+ ModuleBase::WARNING_QUIT (" ElecStateLCAO::cal_dm" , " please check trace_loc_col!" );
38+ }
39+ }
40+ const double wg_local = wg (ik, ib_global);
41+ T* wg_wfc_pointer = &(wg_wfc (0 , ib_local, 0 ));
42+ BlasConnector::scal ( nbasis_local, wg_local, wg_wfc_pointer, 1 );
43+ }
44+
45+ // C++: dm(iw1,iw2) = wfc(ib,iw1).T * wg_wfc(ib,iw2)
46+ #ifdef __MPI
47+ psiMulPsiMpi (wg_wfc, wfc, dm, this ->loc ->ParaV ->desc_wfc , this ->loc ->ParaV ->desc );
48+ #else
49+ psiMulPsi (wg_wfc, wfc, dm);
50+ #endif
51+ }
52+
53+ return ;
54+ }
55+
56+ void ElecStateLCAO::psiToRho (const psi::Psi<std::complex <double >>& psi)
57+ {
58+ ModuleBase::TITLE (" ElecStateLCAO" , " psiToRho" );
59+ ModuleBase::timer::tick (" ElecStateLCAO" , " psiToRho" );
60+
61+ psi::Psi<std::complex <double >> dm_k_2d (psi.get_nk (), psi.get_nbasis (), psi.get_nbasis ());
62+
63+ ModuleBase::GlobalFunc::NOTE (" Calculate the density matrix." );
64+ // this->loc->cal_dk_k(GlobalC::GridT);
65+ if (GlobalV::KS_SOLVER == " genelpa" || GlobalV::KS_SOLVER == " scalapack_gvx"
66+ || GlobalV::KS_SOLVER == " lapack" ) // Peize Lin test 2019-05-15
67+ {
68+ this ->cal_dm (this ->wg , psi, dm_k_2d);
69+ }
70+
71+ for (int is = 0 ; is < GlobalV::NSPIN; is++)
72+ {
73+ ModuleBase::GlobalFunc::ZEROS (this ->charge ->rho [is], this ->charge ->nrxx ); // mohan 2009-11-10
74+ }
75+
76+ // ------------------------------------------------------------
77+ // calculate the charge density on real space grid.
78+ // ------------------------------------------------------------
79+
80+ ModuleBase::GlobalFunc::NOTE (" Calculate the charge on real space grid!" );
81+ // uhm.GK.cal_rho_k(this->loc->DM_R);
82+
83+ this ->charge ->renormalize_rho ();
84+
85+ ModuleBase::timer::tick (" ElecStateLCAO" , " psiToRho" );
86+ return ;
87+ }
88+
89+ // Gamma_only case
90+ void ElecStateLCAO::psiToRho (const psi::Psi<double >& psi)
91+ {
92+ ModuleBase::TITLE (" ElecStateLCAO" , " psiToRho" );
93+ ModuleBase::timer::tick (" ElecStateLCAO" , " psiToRho" );
94+
95+ if (GlobalV::KS_SOLVER == " genelpa" || GlobalV::KS_SOLVER == " scalapack_gvx"
96+ || GlobalV::KS_SOLVER == " lapack" )
97+ {
98+ // LiuXh modify 2021-09-06, clear memory, cal_dk_gamma() not used for genelpa solver.
99+ // density matrix has already been calculated.
100+ ModuleBase::timer::tick (" ElecStateLCAO" , " cal_dm_2d" );
101+
102+ psi::Psi<double > dm_gamma_2d (psi.get_nk (), psi.get_nbasis (), psi.get_nbasis ());
103+ // caution:wfc and dm
104+ this ->cal_dm (this ->wg , psi, dm_gamma_2d);
105+
106+ ModuleBase::timer::tick (" ElecStateLCAO" , " cal_dm_2d" );
107+
108+ // this->loc->cal_dk_gamma_from_2D(); // transform dm_gamma[is].c to this->loc->DM[is]
109+ }
110+
111+ for (int is = 0 ; is < GlobalV::NSPIN; is++)
112+ {
113+ ModuleBase::GlobalFunc::ZEROS (this ->charge ->rho [is], this ->charge ->nrxx ); // mohan 2009-11-10
114+ }
115+
116+ // ------------------------------------------------------------
117+ // calculate the charge density on real space grid.
118+ // ------------------------------------------------------------
119+ ModuleBase::GlobalFunc::NOTE (" Calculate the charge on real space grid!" );
120+ // uhm.GG.cal_rho(this->loc->DM);
121+
122+ this ->charge ->renormalize_rho ();
123+
124+ ModuleBase::timer::tick (" ElecStateLCAO" , " psiToRho" );
125+ return ;
126+ }
127+
128+ } // namespace elecstate
0 commit comments