From 27e35a5c9bac6fe73a4ce087f053a34215f9a2dc Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Mon, 22 Jan 2024 16:04:03 +0800 Subject: [PATCH 1/9] add a new parameter mixing_restart --- source/module_base/global_variable.cpp | 1 + source/module_base/global_variable.h | 1 + source/module_io/input.cpp | 6 ++++++ source/module_io/input.h | 1 + source/module_io/input_conv.cpp | 1 + source/module_io/parameter_pool.cpp | 4 ++++ source/module_io/write_input.cpp | 1 + 7 files changed, 15 insertions(+) diff --git a/source/module_base/global_variable.cpp b/source/module_base/global_variable.cpp index 696bcd6088..eb0dc636e2 100644 --- a/source/module_base/global_variable.cpp +++ b/source/module_base/global_variable.cpp @@ -248,6 +248,7 @@ std::string of_kernel_file = "WTkernel.txt"; std::string MIXING_MODE = "broyden"; double MIXING_BETA = 0.7; int MIXING_NDIM = 8; +int MIXING_RESTART = 0; double MIXING_GG0 = 1.00; double MIXING_BETA_MAG = 1.6; double MIXING_GG0_MAG = 1.00; diff --git a/source/module_base/global_variable.h b/source/module_base/global_variable.h index b1fbb1748d..9fa7dc1c8a 100644 --- a/source/module_base/global_variable.h +++ b/source/module_base/global_variable.h @@ -277,6 +277,7 @@ extern std::string of_kernel_file; // The name of WT kernel file. extern std::string MIXING_MODE; extern double MIXING_BETA; extern int MIXING_NDIM; +extern int MIXING_RESTART; extern double MIXING_GG0; extern bool MIXING_TAU; extern double MIXING_BETA_MAG; diff --git a/source/module_io/input.cpp b/source/module_io/input.cpp index abe8f28ebd..55a274dbf9 100644 --- a/source/module_io/input.cpp +++ b/source/module_io/input.cpp @@ -303,6 +303,7 @@ void Input::Default(void) mixing_mode = "broyden"; mixing_beta = -10; mixing_ndim = 8; + mixing_restart = 0; mixing_gg0 = 1.00; // use Kerker defaultly mixing_beta_mag = -10.0; // only set when nspin == 2 || nspin == 4 mixing_gg0_mag = 0.0; // defaultly exclude Kerker from mixing magnetic density @@ -1256,6 +1257,10 @@ bool Input::Read(const std::string& fn) { read_value(ifs, mixing_ndim); } + else if (strcmp("mixing_restart", word) == 0) + { + read_value(ifs, mixing_restart); + } else if (strcmp("mixing_gg0", word) == 0) // mohan add 2014-09-27 { read_value(ifs, mixing_gg0); @@ -3292,6 +3297,7 @@ void Input::Bcast() Parallel_Common::bcast_string(mixing_mode); Parallel_Common::bcast_double(mixing_beta); Parallel_Common::bcast_int(mixing_ndim); + Parallel_Common::bcast_int(mixing_restart); Parallel_Common::bcast_double(mixing_gg0); // mohan add 2014-09-27 Parallel_Common::bcast_double(mixing_beta_mag); Parallel_Common::bcast_double(mixing_gg0_mag); diff --git a/source/module_io/input.h b/source/module_io/input.h index 6393483cb4..b9c2ac9cae 100644 --- a/source/module_io/input.h +++ b/source/module_io/input.h @@ -232,6 +232,7 @@ class Input std::string mixing_mode; // "plain","broyden",... double mixing_beta; // 0 : no_mixing int mixing_ndim; // used in Broyden method + int mixing_restart; double mixing_gg0; // used in kerker method. mohan add 2014-09-27 double mixing_beta_mag; double mixing_gg0_mag; diff --git a/source/module_io/input_conv.cpp b/source/module_io/input_conv.cpp index a52245d05c..8e00b1f774 100644 --- a/source/module_io/input_conv.cpp +++ b/source/module_io/input_conv.cpp @@ -750,6 +750,7 @@ void Input_Conv::Convert(void) GlobalV::MIXING_MODE = INPUT.mixing_mode; GlobalV::MIXING_BETA = INPUT.mixing_beta; GlobalV::MIXING_NDIM = INPUT.mixing_ndim; + GlobalV::MIXING_RESTART = INPUT.mixing_restart; GlobalV::MIXING_GG0 = INPUT.mixing_gg0; GlobalV::MIXING_BETA_MAG = INPUT.mixing_beta_mag; GlobalV::MIXING_GG0_MAG = INPUT.mixing_gg0_mag; diff --git a/source/module_io/parameter_pool.cpp b/source/module_io/parameter_pool.cpp index cf3e611ab3..524df9de87 100644 --- a/source/module_io/parameter_pool.cpp +++ b/source/module_io/parameter_pool.cpp @@ -818,6 +818,10 @@ void input_parameters_set(std::map input_parameters { INPUT.mixing_ndim = *static_cast(input_parameters["mixing_ndim"].get()); } + else if (input_parameters.count("mixing_restart") != 0) + { + INPUT.mixing_restart = *static_cast(input_parameters["mixing_restart"].get()); + } else if (input_parameters.count("mixing_gg0") != 0) { INPUT.mixing_gg0 = *static_cast(input_parameters["mixing_gg0"].get()); diff --git a/source/module_io/write_input.cpp b/source/module_io/write_input.cpp index 256a7dce73..7a19eea968 100644 --- a/source/module_io/write_input.cpp +++ b/source/module_io/write_input.cpp @@ -248,6 +248,7 @@ ModuleBase::GlobalFunc::OUTP(ofs, "out_bandgap", out_bandgap, "if true, print ou ModuleBase::GlobalFunc::OUTP(ofs, "mixing_type", mixing_mode, "plain; pulay; broyden"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_beta", mixing_beta, "mixing parameter: 0 means no new charge"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_ndim", mixing_ndim, "mixing dimension in pulay or broyden"); + ModuleBase::GlobalFunc::OUTP(ofs, "mixing_restart", mixing_restart, "if to restart mixing during SCF"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_gg0", mixing_gg0, "mixing parameter in kerker"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_beta_mag", mixing_beta_mag, "mixing parameter for magnetic density"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_gg0_mag", mixing_gg0_mag, "mixing parameter in kerker"); From a2a31443047780ff48436472815941700802b96d Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Mon, 22 Jan 2024 16:29:08 +0800 Subject: [PATCH 2/9] do not update rho if iter==mixing_restart --- source/module_esolver/esolver_ks.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index d9877a0969..0b81cb2586 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -436,8 +436,15 @@ namespace ModuleESolver // } // p_chgmix->auto_set(bandgap_for_autoset, GlobalC::ucell); // } - - p_chgmix->mix_rho(pelec->charge); + // mixing will restart after GlobalV::MIXING_RESTART steps + if (GlobalV::MIXING_RESTART > 0 && iter == GlobalV::MIXING_RESTART) + { + continue; // do not update chr->rho if restart mixing + } + else + { + p_chgmix->mix_rho(pelec->charge); // update chr->rho by mixing + } if (GlobalV::SCF_THR_TYPE == 2) pelec->charge->renormalize_rho(); // renormalize rho in R-space would induce a error in K-space //----------charge mixing done----------- } From e0d67b320439fecf4d0177bc52016801a2dd016d Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Mon, 22 Jan 2024 16:44:38 +0800 Subject: [PATCH 3/9] do not update rho if iter==mixing_restart-1 --- source/module_esolver/esolver_ks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 0b81cb2586..a2cb7fa16a 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -437,7 +437,7 @@ namespace ModuleESolver // p_chgmix->auto_set(bandgap_for_autoset, GlobalC::ucell); // } // mixing will restart after GlobalV::MIXING_RESTART steps - if (GlobalV::MIXING_RESTART > 0 && iter == GlobalV::MIXING_RESTART) + if (GlobalV::MIXING_RESTART > 0 && iter == GlobalV::MIXING_RESTART - 1) { continue; // do not update chr->rho if restart mixing } From a7e9e95eb0dfaac22bb6dca9597e8ec95a308cfd Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Mon, 22 Jan 2024 16:48:52 +0800 Subject: [PATCH 4/9] reset mix and rho_mdata if iter==mixing_restart --- source/module_esolver/esolver_ks.cpp | 1 + source/module_esolver/esolver_ks_lcao.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index a2cb7fa16a..f1e1c7ff5d 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -437,6 +437,7 @@ namespace ModuleESolver // p_chgmix->auto_set(bandgap_for_autoset, GlobalC::ucell); // } // mixing will restart after GlobalV::MIXING_RESTART steps + // So, GlobalV::MIXING_RESTART=1 means mix from scratch if (GlobalV::MIXING_RESTART > 0 && iter == GlobalV::MIXING_RESTART - 1) { continue; // do not update chr->rho if restart mixing diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index a7d0a5abdd..4e4b849fb8 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -491,7 +491,7 @@ namespace ModuleESolver template void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) { - if (iter == 1) + if (iter == 1 || iter == GlobalV::MIXING_RESTART) this->p_chgmix->mix_reset(); // mohan update 2012-06-05 From 6e7435beb399dc4fb096c74b112ff58f53cc41f7 Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Mon, 22 Jan 2024 17:27:04 +0800 Subject: [PATCH 5/9] fix SCF exit directly since drho=0 if iter=GlobalV::MIXING_RESTART --- source/module_esolver/esolver_ks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index f1e1c7ff5d..c254c03cf4 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -413,7 +413,7 @@ namespace ModuleESolver this->conv_elec = (drho < this->scf_thr); // If drho < hsolver_error in the first iter or drho < scf_thr, we do not change rho. - if (drho < hsolver_error || this->conv_elec) + if (drho < hsolver_error || (this->conv_elec && iter!=GlobalV::MIXING_RESTART)) { if (drho < hsolver_error) GlobalV::ofs_warning << " drho < hsolver_error, keep charge density unchanged." << std::endl; } From eaa4c533ec714a50d6ce63d4ffbd604f75e3d455 Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Tue, 23 Jan 2024 13:09:47 +0800 Subject: [PATCH 6/9] re-set_mixing in eachiterinit for PW and LCAO --- source/module_esolver/esolver_ks_lcao.cpp | 11 +++++++++++ source/module_esolver/esolver_ks_pw.cpp | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 4e4b849fb8..4c4d6c342f 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -492,7 +492,18 @@ namespace ModuleESolver void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) { if (iter == 1 || iter == GlobalV::MIXING_RESTART) + { + if (iter == GlobalV::MIXING_RESTART) // delete mixing and re-construct it to restart + { + this->p_chgmix->set_mixing(GlobalV::MIXING_MODE, + GlobalV::MIXING_BETA, + GlobalV::MIXING_NDIM, + GlobalV::MIXING_GG0, + GlobalV::MIXING_TAU, + GlobalV::MIXING_BETA_MAG); + } this->p_chgmix->mix_reset(); + } // mohan update 2012-06-05 this->pelec->f_en.deband_harris = this->pelec->cal_delta_eband(); diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index 2e81938ae2..25799fdd42 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -492,9 +492,19 @@ void ESolver_KS_PW::othercalculation(const int istep) template void ESolver_KS_PW::eachiterinit(const int istep, const int iter) { - if (iter == 1) + if (iter == 1 || iter == GlobalV::MIXING_RESTART) + { + if (iter == GlobalV::MIXING_RESTART) // delete mixing and re-construct it to restart + { + this->p_chgmix->set_mixing(GlobalV::MIXING_MODE, + GlobalV::MIXING_BETA, + GlobalV::MIXING_NDIM, + GlobalV::MIXING_GG0, + GlobalV::MIXING_TAU, + GlobalV::MIXING_BETA_MAG); + } this->p_chgmix->mix_reset(); - + } // mohan move harris functional to here, 2012-06-05 // use 'rho(in)' and 'v_h and v_xc'(in) this->pelec->f_en.deband_harris = this->pelec->cal_delta_eband(); From 1c56e3516ffd1b5de4c5014548fdfbc63536a3c4 Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Tue, 23 Jan 2024 13:10:15 +0800 Subject: [PATCH 7/9] enable SCF restarts in esolver_ks::RUN --- source/module_esolver/esolver_ks.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index c254c03cf4..b4fcd83375 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -410,10 +410,10 @@ namespace ModuleESolver } } - this->conv_elec = (drho < this->scf_thr); + this->conv_elec = (drho < this->scf_thr && iter!=GlobalV::MIXING_RESTART); // If drho < hsolver_error in the first iter or drho < scf_thr, we do not change rho. - if (drho < hsolver_error || (this->conv_elec && iter!=GlobalV::MIXING_RESTART)) + if (drho < hsolver_error || this->conv_elec) { if (drho < hsolver_error) GlobalV::ofs_warning << " drho < hsolver_error, keep charge density unchanged." << std::endl; } @@ -440,7 +440,7 @@ namespace ModuleESolver // So, GlobalV::MIXING_RESTART=1 means mix from scratch if (GlobalV::MIXING_RESTART > 0 && iter == GlobalV::MIXING_RESTART - 1) { - continue; // do not update chr->rho if restart mixing + // do not mix charge density } else { @@ -475,6 +475,11 @@ namespace ModuleESolver bool stop = this->do_after_converge(iter); if(stop) break; } + // notice for restart + if (GlobalV::MIXING_RESTART > 0 && iter == GlobalV::MIXING_RESTART - 1) + { + std::cout<<"SCF restart after this step!"< Date: Tue, 23 Jan 2024 14:00:27 +0800 Subject: [PATCH 8/9] add some UnitTests --- source/module_io/test/input_conv_test.cpp | 1 + source/module_io/test/input_test_para.cpp | 1 + source/module_io/test/write_input_test.cpp | 11 +++++++---- source/module_io/write_input.cpp | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/source/module_io/test/input_conv_test.cpp b/source/module_io/test/input_conv_test.cpp index f0d7e43f68..a566827792 100644 --- a/source/module_io/test/input_conv_test.cpp +++ b/source/module_io/test/input_conv_test.cpp @@ -183,6 +183,7 @@ TEST_F(InputConvTest, Conv) EXPECT_EQ(GlobalV::sc_mag_switch,0); EXPECT_TRUE(GlobalV::decay_grad_switch); EXPECT_EQ(GlobalV::sc_file, "sc.json"); + EXPECT_EQ(GlobalV::MIXING_RESTART,0); } TEST_F(InputConvTest, ConvRelax) diff --git a/source/module_io/test/input_test_para.cpp b/source/module_io/test/input_test_para.cpp index 7cc4d6bc73..d005fdfccc 100644 --- a/source/module_io/test/input_test_para.cpp +++ b/source/module_io/test/input_test_para.cpp @@ -381,6 +381,7 @@ TEST_F(InputParaTest, Bcast) EXPECT_TRUE(INPUT.mdp.dump_virial); EXPECT_FALSE(INPUT.mixing_tau); EXPECT_FALSE(INPUT.mixing_dftu); + EXPECT_EQ(INPUT.mixing_restart,0); EXPECT_EQ(INPUT.out_bandgap, 0); EXPECT_EQ(INPUT.out_mat_t, 0); diff --git a/source/module_io/test/write_input_test.cpp b/source/module_io/test/write_input_test.cpp index d61133715d..8dccb5627a 100644 --- a/source/module_io/test/write_input_test.cpp +++ b/source/module_io/test/write_input_test.cpp @@ -384,13 +384,16 @@ TEST_F(write_input, Mixing7) std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(output, testing::HasSubstr("#Parameters (7.Charge Mixing)")); EXPECT_THAT(output, testing::HasSubstr("mixing_type broyden #plain; pulay; broyden")); - EXPECT_THAT(output, - testing::HasSubstr("mixing_beta 0.7 #mixing parameter: 0 means no new charge")); + EXPECT_THAT(output, testing::HasSubstr("mixing_beta 0.7 #mixing parameter: 0 means no new charge")); EXPECT_THAT(output, testing::HasSubstr("mixing_ndim 8 #mixing dimension in pulay or broyden")); EXPECT_THAT(output, testing::HasSubstr("mixing_gg0 0 #mixing parameter in kerker")); + EXPECT_THAT(output, testing::HasSubstr("mixing_beta_mag -10 #mixing parameter for magnetic density")); + EXPECT_THAT(output, testing::HasSubstr("mixing_gg0_mag 0 #mixing parameter in kerker")); + EXPECT_THAT(output, testing::HasSubstr("mixing_gg0_min 0.1 #the minimum kerker coefficient")); + EXPECT_THAT(output, testing::HasSubstr("mixing_angle -10 #angle mixing parameter for non-colinear calculations")); EXPECT_THAT(output, testing::HasSubstr("mixing_tau 0 #whether to mix tau in mGGA calculation")); - EXPECT_THAT(output, - testing::HasSubstr("mixing_dftu 0 #whether to mix locale in DFT+U calculation")); + EXPECT_THAT(output, testing::HasSubstr("mixing_dftu 0 #whether to mix locale in DFT+U calculation")); + EXPECT_THAT(output, testing::HasSubstr("mixing_restart 0 #which step to restart mixing during SCF")); EXPECT_THAT(output, testing::HasSubstr("")); ifs.close(); remove("write_input_test.log"); diff --git a/source/module_io/write_input.cpp b/source/module_io/write_input.cpp index 7a19eea968..e4c2c68464 100644 --- a/source/module_io/write_input.cpp +++ b/source/module_io/write_input.cpp @@ -248,7 +248,7 @@ ModuleBase::GlobalFunc::OUTP(ofs, "out_bandgap", out_bandgap, "if true, print ou ModuleBase::GlobalFunc::OUTP(ofs, "mixing_type", mixing_mode, "plain; pulay; broyden"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_beta", mixing_beta, "mixing parameter: 0 means no new charge"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_ndim", mixing_ndim, "mixing dimension in pulay or broyden"); - ModuleBase::GlobalFunc::OUTP(ofs, "mixing_restart", mixing_restart, "if to restart mixing during SCF"); + ModuleBase::GlobalFunc::OUTP(ofs, "mixing_restart", mixing_restart, "which step to restart mixing during SCF"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_gg0", mixing_gg0, "mixing parameter in kerker"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_beta_mag", mixing_beta_mag, "mixing parameter for magnetic density"); ModuleBase::GlobalFunc::OUTP(ofs, "mixing_gg0_mag", mixing_gg0_mag, "mixing parameter in kerker"); From 6bd076a8141df59cd2df5419c2a7ffbdb35f6c63 Mon Sep 17 00:00:00 2001 From: weiqingzhou Date: Tue, 23 Jan 2024 15:13:46 +0800 Subject: [PATCH 9/9] add some Docs --- docs/advanced/input_files/input-main.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/advanced/input_files/input-main.md b/docs/advanced/input_files/input-main.md index fb721a7486..988e468274 100644 --- a/docs/advanced/input_files/input-main.md +++ b/docs/advanced/input_files/input-main.md @@ -1001,6 +1001,13 @@ We recommend the following options: For systems that are difficult to converge, one could try increasing the value of 'mixing_ndim' to enhance the stability of the self-consistent field (SCF) calculation. - **Default**: 8 +### mixing_restart + +- **Type**: Integer +- **Description**: At `mixing_restart`-th iteration, SCF will restart by using output charge density from perivos iteration as input charge density directly, and start a new mixing. `mixing_restart=0|1` means SCF starts from scratch. + +- **Default**: 0 + ### mixing_gg0 - **Type**: Real