Skip to content

Commit caa372a

Browse files
dyzhengdyzheng
andauthored
Feature: optimized default settings of mixing_beta and mixing_gg0 (#2036)
* Feature: optimized default settings of mixing_beta and mixing_gg0 * Fix: error in CI --------- Co-authored-by: dyzheng <[email protected]>
1 parent b9fada9 commit caa372a

File tree

9 files changed

+232
-5
lines changed

9 files changed

+232
-5
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,14 @@ calculations.
520520
### mixing_beta
521521

522522
- **Type**: Real
523-
- **Description**: mixing parameter: 0 means no new charge
524-
- **Default**: 0.7
523+
- **Description**: mixing parameter. We recommand the following options:
524+
- default: -10.0 means program will autoset **mixing_beta** and **mixing_gg0** before charge mixing method starts.
525+
- Default values of transition metal system are **mixing_beta=0.2** and **mixing_gg0=1.5**;
526+
- Default values of metal system (bandgap <= 1.0 eV) are **mixing_beta=0.2** and **mixing_gg0=0.0**;
527+
- Default values of other systems (bandgap > 1.0eV) are **mixing_beta=0.7** and **mixing_gg0=0.0**.
528+
- 0: keep charge density unchanged, usually used for restarting with **init_chg=file** or testing.
529+
- 0.1 or less: if convergence of SCF calculation is difficult to reach, please try **0 < mixing_beta < 0.1**
530+
- **Default**: -10.0
525531

526532
### mixing_ndim
527533

source/module_base/element_elec_config.h

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,128 @@ const std::map<std::string, int> MinZval
251251
{"Og", 32}
252252
};
253253

254+
const std::map<std::string, int> IsTransMetal
255+
= {
256+
{"H", 0},
257+
{"He", 0},
258+
{"Li", 0},
259+
{"Be", 0},
260+
{"B", 0},
261+
{"C", 0},
262+
{"N", 0},
263+
{"O", 0},
264+
{"F", 0},
265+
{"Ne", 0},
266+
{"Na", 0},
267+
{"Mg", 0},
268+
{"Al", 0},
269+
{"Si", 0},
270+
{"P", 0},
271+
{"S", 0},
272+
{"Cl", 0},
273+
{"Ar", 0},
274+
{"K", 0},
275+
{"Ca", 0},
276+
{"Sc", 1},
277+
{"Ti", 1},
278+
{"V", 1},
279+
{"Cr", 1},
280+
{"Mn", 1},
281+
{"Fe", 1},
282+
{"Co", 1},
283+
{"Ni", 1},
284+
{"Cu", 1},
285+
{"Zn", 1},
286+
{"Ga", 0},
287+
{"Ge", 0},
288+
{"As", 0},
289+
{"Se", 0},
290+
{"Br", 0},
291+
{"Kr", 0},
292+
{"Rb", 0},
293+
{"Sr", 0},
294+
{"Y", 1},
295+
{"Zr", 1},
296+
{"Nb", 1},
297+
{"Mo", 1},
298+
{"Tc", 1},
299+
{"Ru", 1},
300+
{"Rh", 1},
301+
{"Pd", 1},
302+
{"Ag", 1},
303+
{"Cd", 1},
304+
{"In", 0},
305+
{"Sn", 0},
306+
{"Sb", 0},
307+
{"Te", 0},
308+
{"I", 0},
309+
{"Xe", 0},
310+
{"Cs", 0},
311+
{"Ba", 0},
312+
{"La", 1},
313+
{"Ce", 1},
314+
{"Pr", 1},
315+
{"Nd", 1},
316+
{"Pm", 1},
317+
{"Sm", 1},
318+
{"Eu", 1},
319+
{"Gd", 1},
320+
{"Tb", 1},
321+
{"Dy", 1},
322+
{"Ho", 1},
323+
{"Er", 1},
324+
{"Tm", 1},
325+
{"Yb", 1},
326+
{"Lu", 1},
327+
{"Hf", 1},
328+
{"Ta", 1},
329+
{"W", 1},
330+
{"Re", 1},
331+
{"Os", 1},
332+
{"Ir", 1},
333+
{"Pt", 1},
334+
{"Au", 1},
335+
{"Hg", 1},
336+
{"Tl", 0},
337+
{"Pb", 0},
338+
{"Bi", 0},
339+
{"Po", 0},
340+
{"At", 0},
341+
{"Rn", 0},
342+
{"Fr", 0},
343+
{"Ra", 0},
344+
{"Ac", 1},
345+
{"Th", 1},
346+
{"Pa", 1},
347+
{"U" , 1},
348+
{"Np", 1},
349+
{"Pu", 1},
350+
{"Am", 1},
351+
{"Cm", 1},
352+
{"Bk", 1},
353+
{"Cf", 1},
354+
{"Es", 1},
355+
{"Fm", 1},
356+
{"Md", 1},
357+
{"No", 1},
358+
{"Lr", 1},
359+
{"Rf", 1},
360+
{"Db", 1},
361+
{"Sg", 1},
362+
{"Bh", 1},
363+
{"Hs", 1},
364+
{"Mt", 1},
365+
{"Ds", 1},
366+
{"Rg", 1},
367+
{"Cn", 1},
368+
{"Nh", 0},
369+
{"Fl", 0},
370+
{"Mc", 0},
371+
{"Lv", 0},
372+
{"Ts", 0},
373+
{"Og", 0}
374+
};
375+
254376
}
255377

256378
#endif

source/module_elecstate/energy.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,11 @@ void energy::cal_converged(elecstate::ElecState* pelec)
511511

512512
void energy::cal_bandgap(const elecstate::ElecState* pelec)
513513
{
514+
if(pelec->ekb.nr == 0 || pelec->ekb.nc == 0)
515+
{//which means no homo and no lumo
516+
this->bandgap = 0.0;
517+
return;
518+
}
514519
int nbands = GlobalV::NBANDS;
515520
int nks = GlobalC::kv.nks;
516521
double homo = pelec->ekb(0,0);
@@ -534,6 +539,12 @@ void energy::cal_bandgap(const elecstate::ElecState* pelec)
534539

535540
void energy::cal_bandgap_updw(const elecstate::ElecState* pelec)
536541
{
542+
if(pelec->ekb.nr == 0 || pelec->ekb.nc == 0)
543+
{//which means no homo and no lumo
544+
this->bandgap_up = 0.0;
545+
this->bandgap_dw = 0.0;
546+
return;
547+
}
537548
int nbands = GlobalV::NBANDS;
538549
int nks = GlobalC::kv.nks;
539550
double homo_up = pelec->ekb(0,0);

source/module_elecstate/module_charge/charge_mixing.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "module_base/inverse_matrix.h"
44
#include "module_base/parallel_reduce.h"
55
#include "module_base/timer.h"
6+
#include "module_base/element_elec_config.h"
67

78
Charge_Mixing::Charge_Mixing()
89
{
@@ -47,6 +48,60 @@ void Charge_Mixing::set_mixing
4748
return;
4849
}
4950

51+
void Charge_Mixing::need_auto_set()
52+
{
53+
this->autoset = true;
54+
}
55+
56+
void Charge_Mixing::auto_set(const double& bandgap_in, const UnitCell& ucell_)
57+
{
58+
//auto set parameters once
59+
if(!this->autoset)
60+
{
61+
return;
62+
}
63+
else {
64+
this->autoset = false;
65+
}
66+
GlobalV::ofs_running<<"--------------AUTO-SET---------------"<<std::endl;
67+
//0.2 for metal and 0.7 for others
68+
if(bandgap_in * ModuleBase::Ry_to_eV < 1.0)
69+
{
70+
this->mixing_beta = 0.2;
71+
}
72+
else
73+
{
74+
this->mixing_beta = 0.7;
75+
}
76+
GlobalV::ofs_running<<" Autoset mixing_beta to "<<this->mixing_beta<<std::endl;
77+
78+
bool has_trans_metal = false;
79+
// find elements of cell
80+
for(int it=0;it<ucell_.ntype;it++)
81+
{
82+
if(ModuleBase::IsTransMetal.find(ucell_.atoms[it].ncpp.psd) != ModuleBase::IsTransMetal.end())
83+
{
84+
if(ModuleBase::IsTransMetal.at(ucell_.atoms[it].ncpp.psd))
85+
{
86+
has_trans_metal = true;
87+
}
88+
}
89+
}
90+
// auto set kerker mixing for trans metal system
91+
if(has_trans_metal)
92+
{
93+
this->mixing_gg0 = 1.5;
94+
}
95+
else
96+
{
97+
this->mixing_gg0 = 0.0;
98+
}
99+
GlobalV::ofs_running<<" Autoset mixing_gg0 to "<<this->mixing_gg0<<std::endl;
100+
GlobalV::ofs_running<<"-------------------------------------"<<std::endl;
101+
//auto set for inhomogeneous system
102+
103+
}
104+
50105
double Charge_Mixing::get_drho(Charge* chr, const double nelec)
51106
{
52107
for (int is=0; is<GlobalV::NSPIN; is++)

source/module_elecstate/module_charge/charge_mixing.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "module_base/global_function.h"
1414
#include "module_base/global_variable.h"
1515
#include "module_base/matrix.h"
16+
#include "module_cell/unitcell.h"
1617
#include "charge.h"
1718
class Charge_Mixing
1819
{
@@ -32,6 +33,9 @@ class Charge_Mixing
3233
const bool &mixing_tau_in
3334
);//mohan add mixing_gg0_in 2014-09-27
3435

36+
void need_auto_set();
37+
void auto_set(const double& bandgap_in, const UnitCell& ucell_);
38+
3539
double get_drho(Charge* chr, const double nelec);
3640

3741
void mix_rho(const int &iter, Charge* chr);// mix rho
@@ -131,6 +135,9 @@ class Charge_Mixing
131135

132136
std::complex<double>*** dF; // dF(i) = rhog(i) - rhog_save(i), (GlobalV::NSPIN, rstep, rhopw->npw)
133137
std::complex<double>*** dn; // dn(i) = rhog(i+1) - rhog(i), (GlobalV::NSPIN, rstep, rhopw->npw)
138+
139+
private:
140+
bool autoset = false;
134141
};
135142

136143
#endif

source/module_esolver/esolver_ks.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,26 @@ namespace ModuleESolver
219219
}
220220
else
221221
{
222-
//charge mixing
222+
//----------charge mixing---------------
223+
//before first calling mix_rho(), bandgap and cell structure can be analyzed to get better default parameters
224+
if(iter == 1)
225+
{
226+
double bandgap_for_autoset = 0.0;
227+
if (!GlobalV::TWO_EFERMI)
228+
{
229+
GlobalC::en.cal_bandgap(this->pelec);
230+
bandgap_for_autoset = GlobalC::en.bandgap;
231+
}
232+
else
233+
{
234+
GlobalC::en.cal_bandgap_updw(this->pelec);
235+
bandgap_for_autoset = std::min(GlobalC::en.bandgap_up, GlobalC::en.bandgap_dw);
236+
}
237+
GlobalC::CHR_MIX.auto_set(bandgap_for_autoset, GlobalC::ucell);
238+
}
223239
//conv_elec = this->estate.mix_rho();
224240
GlobalC::CHR_MIX.mix_rho(iter, pelec->charge);
241+
//----------charge mixing done-----------
225242
}
226243
}
227244
#ifdef __MPI

source/module_io/input.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ void Input::Default(void)
264264
// charge mixing
265265
//----------------------------------------------------------
266266
mixing_mode = "pulay";
267-
mixing_beta = 0.7;
267+
mixing_beta = -10.0;
268268
mixing_ndim = 8;
269269
mixing_gg0 = 0.00; // used in kerker method. mohan add 2014-09-27
270270
mixing_tau = false;

source/module_io/input_conv.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,15 @@ void Input_Conv::Convert(void)
493493
INPUT.mixing_ndim,
494494
INPUT.mixing_gg0,
495495
INPUT.mixing_tau); // mohan modify 2014-09-27, add mixing_gg0
496+
//using bandgap to auto set mixing_beta
497+
if(std::abs(INPUT.mixing_beta + 10.0) < 1e-6)
498+
{
499+
GlobalC::CHR_MIX.need_auto_set();
500+
}
501+
else if(INPUT.mixing_beta > 1.0 || INPUT.mixing_beta<0.0)
502+
{
503+
ModuleBase::WARNING("INPUT", "You'd better set mixing_beta to [0.0, 1.0]!");
504+
}
496505

497506
//----------------------------------------------------------
498507
// iteration

source/module_io/test/input_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ TEST_F(InputTest, Default)
137137
EXPECT_EQ(INPUT.smearing_method,"fixed");
138138
EXPECT_DOUBLE_EQ(INPUT.smearing_sigma,0.01);
139139
EXPECT_EQ(INPUT.mixing_mode,"pulay");
140-
EXPECT_DOUBLE_EQ(INPUT.mixing_beta,0.7);
140+
EXPECT_DOUBLE_EQ(INPUT.mixing_beta,-10.0);
141141
EXPECT_EQ(INPUT.mixing_ndim,8);
142142
EXPECT_DOUBLE_EQ(INPUT.mixing_gg0,0.00);
143143
EXPECT_EQ(INPUT.init_wfc,"atomic");

0 commit comments

Comments
 (0)