1+ #include " elecstate.h"
2+ #include " src_pw/occupy.h"
3+ #include " module_base/global_variable.h"
4+ #include " module_base/tool_title.h"
5+ #include " src_pw/global.h"
6+ #include " src_parallel/parallel_reduce.h"
7+
8+ namespace elecstate
9+ {
10+
11+ const double * ElecState::getRho (int spin) const
12+ {
13+ // hamilt::MatrixBlock<double> temp{&(this->charge->rho[spin][0]), 1, this->charge->nrxx}; // this->chr->get_nspin(), this->chr->get_nrxx()};
14+ return &(this ->charge ->rho [spin][0 ]);
15+ }
16+
17+ void ElecState::calculate_weights (void )
18+ {
19+ ModuleBase::TITLE (" ElecState" , " calculate_weights" );
20+
21+ // for test
22+ // std::cout << " gaussian_broadening = " << use_gaussian_broadening << std::endl;
23+ // std::cout << " tetrahedron_method = " << use_tetrahedron_method << std::endl;
24+ // std::cout << " fixed_occupations = " << fixed_occupations << std::endl;
25+ double ** ekb_tmp = new double *[this ->ekb .nr ];
26+ for (int i=0 ; i<this ->ekb .nr ; ++i)
27+ {
28+ ekb_tmp[i] = &(this ->ekb (i, 0 ));
29+ }
30+ int nbands = this ->ekb .nc ;
31+
32+ if (GlobalV::KS_SOLVER == " selinv" )
33+ {
34+ GlobalV::ofs_running << " Could not calculate occupation." << std::endl;
35+ return ;
36+ }
37+
38+ if (!Occupy::use_gaussian_broadening && !Occupy::use_tetrahedron_method && !Occupy::fixed_occupations)
39+ {
40+ if (GlobalV::TWO_EFERMI)
41+ {
42+ Occupy::iweights (GlobalC::kv.nks ,
43+ GlobalC::kv.wk ,
44+ nbands,
45+ GlobalC::ucell.magnet .get_nelup (),
46+ ekb_tmp,
47+ GlobalC::en.ef_up ,
48+ this ->wg ,
49+ 0 ,
50+ GlobalC::kv.isk );
51+ Occupy::iweights (GlobalC::kv.nks ,
52+ GlobalC::kv.wk ,
53+ nbands,
54+ GlobalC::ucell.magnet .get_neldw (),
55+ ekb_tmp,
56+ GlobalC::en.ef_dw ,
57+ this ->wg ,
58+ 1 ,
59+ GlobalC::kv.isk );
60+ // ef = ( ef_up + ef_dw ) / 2.0_dp need??? mohan add 2012-04-16
61+ }
62+ else
63+ {
64+ // -1 means don't need to consider spin.
65+ Occupy::iweights (GlobalC::kv.nks ,
66+ GlobalC::kv.wk ,
67+ nbands,
68+ GlobalC::CHR.nelec ,
69+ ekb_tmp,
70+ this ->ef ,
71+ this ->wg ,
72+ -1 ,
73+ GlobalC::kv.isk );
74+ }
75+ }
76+ else if (Occupy::use_tetrahedron_method)
77+ {
78+ ModuleBase::WARNING_QUIT (" calculate_weights" , " not implemented yet,coming soon!" );
79+ // if(my_rank == 0)
80+ // {
81+ // tweights(GlobalC::kv.nkstot, nspin, nbands, GlobalC::CHR.nelec, ntetra,tetra, GlobalC::wf.et,
82+ // this->ef, this->wg);
83+ // }
84+ }
85+ else if (Occupy::use_gaussian_broadening)
86+ {
87+ if (GlobalV::TWO_EFERMI)
88+ {
89+ double demet_up = 0.0 ;
90+ double demet_dw = 0.0 ;
91+ Occupy::gweights (GlobalC::kv.nks ,
92+ GlobalC::kv.wk ,
93+ nbands,
94+ GlobalC::ucell.magnet .get_nelup (),
95+ Occupy::gaussian_parameter,
96+ Occupy::gaussian_type,
97+ ekb_tmp,
98+ GlobalC::en.ef_up ,
99+ demet_up,
100+ this ->wg ,
101+ 0 ,
102+ GlobalC::kv.isk );
103+ Occupy::gweights (GlobalC::kv.nks ,
104+ GlobalC::kv.wk ,
105+ nbands,
106+ GlobalC::ucell.magnet .get_neldw (),
107+ Occupy::gaussian_parameter,
108+ Occupy::gaussian_type,
109+ ekb_tmp,
110+ GlobalC::en.ef_dw ,
111+ demet_dw,
112+ this ->wg ,
113+ 1 ,
114+ GlobalC::kv.isk );
115+ GlobalC::en.demet = demet_up + demet_dw;
116+ }
117+ else
118+ {
119+ // -1 means is no related to spin.
120+ Occupy::gweights (GlobalC::kv.nks ,
121+ GlobalC::kv.wk ,
122+ nbands,
123+ GlobalC::CHR.nelec ,
124+ Occupy::gaussian_parameter,
125+ Occupy::gaussian_type,
126+ ekb_tmp,
127+ this ->ef ,
128+ GlobalC::en.demet ,
129+ this ->wg ,
130+ -1 ,
131+ GlobalC::kv.isk );
132+ }
133+
134+ // qianrui fix a bug on 2021-7-21
135+ Parallel_Reduce::reduce_double_allpool (GlobalC::en.demet );
136+ }
137+ else if (Occupy::fixed_occupations)
138+ {
139+ // fix occupations need nelup and neldw.
140+ // mohan add 2011-04-03
141+ this ->ef = -1.0e+20 ;
142+ for (int ik = 0 ; ik < GlobalC::kv.nks ; ik++)
143+ {
144+ for (int ibnd = 0 ; ibnd < nbands; ibnd++)
145+ {
146+ if (this ->wg (ik, ibnd) > 0.0 )
147+ {
148+ this ->ef = std::max (this ->ef , ekb_tmp[ik][ibnd]);
149+ }
150+ }
151+ }
152+ }
153+
154+ if (GlobalV::TWO_EFERMI)
155+ {
156+ Parallel_Reduce::gather_max_double_all (GlobalC::en.ef_up );
157+ Parallel_Reduce::gather_max_double_all (GlobalC::en.ef_dw );
158+ }
159+ else
160+ {
161+ double ebotom = ekb_tmp[0 ][0 ];
162+ double etop = ekb_tmp[0 ][0 ];
163+ for (int ik = 0 ; ik < GlobalC::kv.nks ; ik++)
164+ {
165+ for (int ib = 0 ; ib < nbands; ib++)
166+ {
167+ ebotom = min (ebotom, ekb_tmp[ik][ib]);
168+ etop = max (etop, ekb_tmp[ik][ib]);
169+ }
170+ }
171+
172+ // parallel
173+ Parallel_Reduce::gather_max_double_all (this ->ef );
174+ Parallel_Reduce::gather_max_double_all (etop);
175+ Parallel_Reduce::gather_min_double_all (ebotom);
176+
177+ // not parallel yet!
178+ // OUT(GlobalV::ofs_running,"Top Energy (eV)", etop * ModuleBase::Ry_to_eV);
179+ // OUT(GlobalV::ofs_running,"Fermi Energy (eV)", this->ef * ModuleBase::Ry_to_eV);
180+ // OUT(GlobalV::ofs_running,"Bottom Energy (eV)", ebotom * ModuleBase::Ry_to_eV);
181+ // OUT(GlobalV::ofs_running,"Range Energy (eV)", etop-ebotom * ModuleBase::Ry_to_eV);
182+ }
183+
184+ delete[] ekb_tmp;
185+
186+ return ;
187+ }
188+
189+ double ElecState::eBandK (const int & ik)
190+ {
191+ ModuleBase::TITLE (" ElecStatePW" ," eBandK" );
192+ double eband_k = 0.0 ;
193+ for (int ibnd = 0 ;ibnd < this ->ekb .nc ; ibnd++)
194+ {
195+ eband_k += this ->ekb (ik, ibnd) * this ->wg (ik, ibnd);
196+ }
197+ return eband_k;
198+ }
199+
200+ void ElecState::print_band (const int &ik, const int &printe, const int &iter)
201+ {
202+ // check the band energy.
203+ bool wrong = false ;
204+ int nbands = this ->ekb .nc ;
205+ for (int ib=0 ; ib<nbands; ++ib)
206+ {
207+ if ( abs ( this ->ekb (ik, ib) ) > 1.0e10 )
208+ {
209+ GlobalV::ofs_warning << " ik=" << ik+1 << " ib=" << ib+1 << " " << this ->ekb (ik, ib) << " Ry" << std::endl;
210+ wrong = true ;
211+ }
212+ }
213+ if (wrong)
214+ {
215+ ModuleBase::WARNING_QUIT (" Threshold_Elec::print_eigenvalue" ," Eigenvalues are too large!" );
216+ }
217+
218+
219+
220+ if (GlobalV::MY_RANK==0 )
221+ {
222+ // if( GlobalV::DIAGO_TYPE == "selinv" ) xiaohui modify 2013-09-02
223+ if (GlobalV::KS_SOLVER==" selinv" ) // xiaohui add 2013-09-02
224+ {
225+ GlobalV::ofs_running << " No eigenvalues are available for selected inversion methods." << std::endl;
226+ }
227+ else
228+ {
229+ if ( printe>0 && ((iter+1 ) % printe == 0 ))
230+ {
231+ // NEW_PART("ENERGY BANDS (Rydberg), (eV)");
232+ GlobalV::ofs_running << std::setprecision (6 );
233+ GlobalV::ofs_running << " Energy (eV) & Occupations for spin=" << GlobalV::CURRENT_SPIN+1 << " K-point=" << ik+1 << std::endl;
234+ GlobalV::ofs_running << std::setiosflags (ios::showpoint);
235+ for (int ib=0 ;ib<nbands;ib++)
236+ {
237+ GlobalV::ofs_running << " " << std::setw (6 ) << ib+1
238+ << std::setw (15 ) << this ->ekb (ik, ib) * ModuleBase::Ry_to_eV;
239+ // for the first electron iteration, we don't have the energy
240+ // spectrum, so we can't get the occupations.
241+ GlobalV::ofs_running << std::setw (15 ) << this ->wg (ik,ib);
242+ GlobalV::ofs_running << std::endl;
243+ }
244+ }
245+ }
246+ }
247+ return ;
248+ }
249+
250+ } // namespace elecstate
0 commit comments