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+
31+ if (GlobalV::KS_SOLVER == " selinv" )
32+ {
33+ GlobalV::ofs_running << " Could not calculate occupation." << std::endl;
34+ return ;
35+ }
36+
37+ if (!Occupy::use_gaussian_broadening && !Occupy::use_tetrahedron_method && !Occupy::fixed_occupations)
38+ {
39+ if (GlobalV::TWO_EFERMI)
40+ {
41+ Occupy::iweights (GlobalC::kv.nks ,
42+ GlobalC::kv.wk ,
43+ GlobalV::NBANDS,
44+ GlobalC::ucell.magnet .get_nelup (),
45+ ekb_tmp,
46+ GlobalC::en.ef_up ,
47+ this ->wg ,
48+ 0 ,
49+ GlobalC::kv.isk );
50+ Occupy::iweights (GlobalC::kv.nks ,
51+ GlobalC::kv.wk ,
52+ GlobalV::NBANDS,
53+ GlobalC::ucell.magnet .get_neldw (),
54+ ekb_tmp,
55+ GlobalC::en.ef_dw ,
56+ this ->wg ,
57+ 1 ,
58+ GlobalC::kv.isk );
59+ // ef = ( ef_up + ef_dw ) / 2.0_dp need??? mohan add 2012-04-16
60+ }
61+ else
62+ {
63+ // -1 means don't need to consider spin.
64+ Occupy::iweights (GlobalC::kv.nks ,
65+ GlobalC::kv.wk ,
66+ GlobalV::NBANDS,
67+ GlobalC::CHR.nelec ,
68+ ekb_tmp,
69+ this ->ef ,
70+ this ->wg ,
71+ -1 ,
72+ GlobalC::kv.isk );
73+ }
74+ }
75+ else if (Occupy::use_tetrahedron_method)
76+ {
77+ ModuleBase::WARNING_QUIT (" calculate_weights" , " not implemented yet,coming soon!" );
78+ // if(my_rank == 0)
79+ // {
80+ // tweights(GlobalC::kv.nkstot, nspin, GlobalV::NBANDS, GlobalC::CHR.nelec, ntetra,tetra, GlobalC::wf.et,
81+ // this->ef, this->wg);
82+ // }
83+ }
84+ else if (Occupy::use_gaussian_broadening)
85+ {
86+ if (GlobalV::TWO_EFERMI)
87+ {
88+ double demet_up = 0.0 ;
89+ double demet_dw = 0.0 ;
90+ Occupy::gweights (GlobalC::kv.nks ,
91+ GlobalC::kv.wk ,
92+ GlobalV::NBANDS,
93+ GlobalC::ucell.magnet .get_nelup (),
94+ Occupy::gaussian_parameter,
95+ Occupy::gaussian_type,
96+ ekb_tmp,
97+ GlobalC::en.ef_up ,
98+ demet_up,
99+ this ->wg ,
100+ 0 ,
101+ GlobalC::kv.isk );
102+ Occupy::gweights (GlobalC::kv.nks ,
103+ GlobalC::kv.wk ,
104+ GlobalV::NBANDS,
105+ GlobalC::ucell.magnet .get_neldw (),
106+ Occupy::gaussian_parameter,
107+ Occupy::gaussian_type,
108+ ekb_tmp,
109+ GlobalC::en.ef_dw ,
110+ demet_dw,
111+ this ->wg ,
112+ 1 ,
113+ GlobalC::kv.isk );
114+ GlobalC::en.demet = demet_up + demet_dw;
115+ }
116+ else
117+ {
118+ // -1 means is no related to spin.
119+ Occupy::gweights (GlobalC::kv.nks ,
120+ GlobalC::kv.wk ,
121+ GlobalV::NBANDS,
122+ GlobalC::CHR.nelec ,
123+ Occupy::gaussian_parameter,
124+ Occupy::gaussian_type,
125+ ekb_tmp,
126+ this ->ef ,
127+ GlobalC::en.demet ,
128+ this ->wg ,
129+ -1 ,
130+ GlobalC::kv.isk );
131+ }
132+
133+ // qianrui fix a bug on 2021-7-21
134+ Parallel_Reduce::reduce_double_allpool (GlobalC::en.demet );
135+ }
136+ else if (Occupy::fixed_occupations)
137+ {
138+ // fix occupations need nelup and neldw.
139+ // mohan add 2011-04-03
140+ this ->ef = -1.0e+20 ;
141+ for (int ik = 0 ; ik < GlobalC::kv.nks ; ik++)
142+ {
143+ for (int ibnd = 0 ; ibnd < GlobalV::NBANDS; ibnd++)
144+ {
145+ if (this ->wg (ik, ibnd) > 0.0 )
146+ {
147+ this ->ef = std::max (this ->ef , ekb_tmp[ik][ibnd]);
148+ }
149+ }
150+ }
151+ }
152+
153+ if (GlobalV::TWO_EFERMI)
154+ {
155+ Parallel_Reduce::gather_max_double_all (GlobalC::en.ef_up );
156+ Parallel_Reduce::gather_max_double_all (GlobalC::en.ef_dw );
157+ }
158+ else
159+ {
160+ double ebotom = ekb_tmp[0 ][0 ];
161+ double etop = ekb_tmp[0 ][0 ];
162+ for (int ik = 0 ; ik < GlobalC::kv.nks ; ik++)
163+ {
164+ for (int ib = 0 ; ib < GlobalV::NBANDS; ib++)
165+ {
166+ ebotom = min (ebotom, ekb_tmp[ik][ib]);
167+ etop = max (etop, ekb_tmp[ik][ib]);
168+ }
169+ }
170+
171+ // parallel
172+ Parallel_Reduce::gather_max_double_all (this ->ef );
173+ Parallel_Reduce::gather_max_double_all (etop);
174+ Parallel_Reduce::gather_min_double_all (ebotom);
175+
176+ // not parallel yet!
177+ // OUT(GlobalV::ofs_running,"Top Energy (eV)", etop * ModuleBase::Ry_to_eV);
178+ // OUT(GlobalV::ofs_running,"Fermi Energy (eV)", this->ef * ModuleBase::Ry_to_eV);
179+ // OUT(GlobalV::ofs_running,"Bottom Energy (eV)", ebotom * ModuleBase::Ry_to_eV);
180+ // OUT(GlobalV::ofs_running,"Range Energy (eV)", etop-ebotom * ModuleBase::Ry_to_eV);
181+ }
182+
183+ delete[] ekb_tmp;
184+
185+ return ;
186+ }
187+
188+ } // namespace elecstate
0 commit comments