diff --git a/examples/21_deepks/01_pw_H2O/INPUT b/examples/21_deepks/01_pw_H2O/INPUT index d242fd6da11..4ea63bb5020 100644 --- a/examples/21_deepks/01_pw_H2O/INPUT +++ b/examples/21_deepks/01_pw_H2O/INPUT @@ -14,7 +14,7 @@ scf_nmax 50 #Parameters (3.Basis) basis_type pw -gamma_only 1 ### Abacus will generate/overwrite a KPT file when gamma_only is set to 1. +gamma_only 0 # Gamma-point sampling is specified in KPT. #Parameters (4.Smearing) smearing_method gaussian diff --git a/examples/21_deepks/01_pw_H2O/KPT b/examples/21_deepks/01_pw_H2O/KPT index da8500ebdb8..c289c0158aa 100644 --- a/examples/21_deepks/01_pw_H2O/KPT +++ b/examples/21_deepks/01_pw_H2O/KPT @@ -2,4 +2,3 @@ K_POINTS 0 Gamma 1 1 1 0 0 0 -###This file will be overwritten by Abacus because either kspacing is used or gamma_only is set to 1 diff --git a/examples/27_imp_sol/01_pw_Pt_slab/INPUT b/examples/27_imp_sol/01_pw_Pt_slab/INPUT index 8f71fa25b6d..eff90618153 100644 --- a/examples/27_imp_sol/01_pw_Pt_slab/INPUT +++ b/examples/27_imp_sol/01_pw_Pt_slab/INPUT @@ -8,7 +8,7 @@ ecutwfc 60 ###Energy cutoff needs to be tested to ensure your calcu scf_nmax 200 scf_thr 1.0e-7 basis_type pw -gamma_only 1 ### Abacus will generate/overwrite a KPT file when gamma_only is set to 1. +gamma_only 0 # Gamma-point sampling is specified in KPT. smearing_method gauss smearing_sigma 0.015 mixing_type broyden diff --git a/examples/27_imp_sol/01_pw_Pt_slab/KPT b/examples/27_imp_sol/01_pw_Pt_slab/KPT new file mode 100644 index 00000000000..c289c0158aa --- /dev/null +++ b/examples/27_imp_sol/01_pw_Pt_slab/KPT @@ -0,0 +1,4 @@ +K_POINTS +0 +Gamma +1 1 1 0 0 0 diff --git a/examples/28_efield/01_Pt_slab/INPUT b/examples/28_efield/01_Pt_slab/INPUT index 40019be4598..0a2718ec072 100644 --- a/examples/28_efield/01_Pt_slab/INPUT +++ b/examples/28_efield/01_Pt_slab/INPUT @@ -8,7 +8,7 @@ ecutwfc 60 ###Energy cutoff needs to be tested to ensure your calcu scf_nmax 200 scf_thr 1.0e-7 basis_type pw -gamma_only 1 ### Abacus will generate/overwrite a KPT file when gamma_only is set to 1. +gamma_only 0 # Gamma-point sampling is specified in KPT. smearing_method gauss smearing_sigma 0.015 mixing_type broyden diff --git a/examples/28_efield/01_Pt_slab/KPT b/examples/28_efield/01_Pt_slab/KPT new file mode 100644 index 00000000000..c289c0158aa --- /dev/null +++ b/examples/28_efield/01_Pt_slab/KPT @@ -0,0 +1,4 @@ +K_POINTS +0 +Gamma +1 1 1 0 0 0 diff --git a/examples/29_dipole_corr/01_Pt_slab/INPUT1 b/examples/29_dipole_corr/01_Pt_slab/INPUT1 index b47a2493686..a726ac29bb0 100644 --- a/examples/29_dipole_corr/01_Pt_slab/INPUT1 +++ b/examples/29_dipole_corr/01_Pt_slab/INPUT1 @@ -8,7 +8,7 @@ ecutwfc 60 scf_nmax 200 scf_thr 1.0e-7 basis_type pw -gamma_only 1 +gamma_only 0 # Gamma-point sampling is specified in KPT. smearing_method gauss smearing_sigma 0.02 mixing_type broyden diff --git a/examples/29_dipole_corr/01_Pt_slab/INPUT2 b/examples/29_dipole_corr/01_Pt_slab/INPUT2 index 863800edbea..c43fbb4427b 100644 --- a/examples/29_dipole_corr/01_Pt_slab/INPUT2 +++ b/examples/29_dipole_corr/01_Pt_slab/INPUT2 @@ -8,7 +8,7 @@ ecutwfc 60 scf_nmax 200 scf_thr 1.0e-7 basis_type pw -gamma_only 1 +gamma_only 0 # Gamma-point sampling is specified in KPT. smearing_method gauss smearing_sigma 0.02 mixing_type broyden diff --git a/examples/29_dipole_corr/01_Pt_slab/KPT b/examples/29_dipole_corr/01_Pt_slab/KPT new file mode 100644 index 00000000000..c289c0158aa --- /dev/null +++ b/examples/29_dipole_corr/01_Pt_slab/KPT @@ -0,0 +1,4 @@ +K_POINTS +0 +Gamma +1 1 1 0 0 0 diff --git a/examples/31_comp_charge/01_Pt_slab/INPUT b/examples/31_comp_charge/01_Pt_slab/INPUT index 925d04a2f23..b20e1463f7f 100644 --- a/examples/31_comp_charge/01_Pt_slab/INPUT +++ b/examples/31_comp_charge/01_Pt_slab/INPUT @@ -8,7 +8,7 @@ ecutwfc 60 ###Energy cutoff needs to be tested to ensure your calcu scf_nmax 200 scf_thr 1.0e-7 basis_type pw -gamma_only 1 ### Abacus will generate/overwrite a KPT file when gamma_only is set to 1. +gamma_only 0 # Gamma-point sampling is specified in KPT. smearing_method gauss smearing_sigma 0.015 mixing_type broyden diff --git a/examples/31_comp_charge/01_Pt_slab/KPT b/examples/31_comp_charge/01_Pt_slab/KPT new file mode 100644 index 00000000000..c289c0158aa --- /dev/null +++ b/examples/31_comp_charge/01_Pt_slab/KPT @@ -0,0 +1,4 @@ +K_POINTS +0 +Gamma +1 1 1 0 0 0 diff --git a/source/source_io/module_parameter/read_inp_estruc.cpp b/source/source_io/module_parameter/read_inp_estruc.cpp index b5841a81e31..a846d0a44b0 100644 --- a/source/source_io/module_parameter/read_inp_estruc.cpp +++ b/source/source_io/module_parameter/read_inp_estruc.cpp @@ -793,30 +793,24 @@ This setting takes effect only when the selected exchange-correlation functional "set to 1, a fast algorithm is used"; item.category = "Electronic structure"; item.type = "Boolean"; - item.description = R"(Whether to use gamma_only algorithm. -* 0: more than one k-point is used and the ABACUS is slower compared to the gamma only algorithm. -* 1: ABACUS uses gamma only, the algorithm is faster and you don't need to specify the k-points file. + item.description = R"(Whether to use the optimized Gamma-only algorithm. +* 0: use the general k-point algorithm, including for a single Gamma point. +* 1: use the optimized algorithm for localized orbitals with nspin=1 or 2; no KPT file is needed. -Note: If gamma_only is set to 1, the KPT file will be overwritten. So make sure to turn off gamma_only for multi-k calculations.)"; +PW calculations require gamma_only=0. For Gamma-point sampling in PW, specify a 1 1 1 0 0 0 Gamma mesh in KPT. An explicit gamma_only=1 with basis_type=pw is an input error; the input reader does not create or overwrite KPT.)"; item.default_value = "0"; item.unit = ""; item.set_availability("basis_type==lcao"); read_sync_bool(input.gamma_only); - item.reset_value = [](const Input_Item& item, Parameter& para) { + item.check_value = [](const Input_Item& item, const Parameter& para) { if (para.input.basis_type == "pw" && para.input.gamma_only) { - para.input.gamma_only = false; - GlobalV::ofs_warning << " WARNING : gamma_only has not been implemented for pw yet" << std::endl; - GlobalV::ofs_warning << "gamma_only is not supported in the pw model" << std::endl; - GlobalV::ofs_warning << " the INPUT parameter gamma_only has been reset to 0" << std::endl; - GlobalV::ofs_warning << " and a new KPT is generated with gamma point as the only k point"<< std::endl; - GlobalV::ofs_warning << " Auto generating k-points file: " << para.input.kpoint_file << std::endl; - std::ofstream ofs(para.input.kpoint_file.c_str()); - ofs << "K_POINTS" << std::endl; - ofs << "0" << std::endl; - ofs << "Gamma" << std::endl; - ofs << "1 1 1 0 0 0" << std::endl; - ofs.close(); + const std::string message + = "Invalid INPUT gamma_only=" + longstring(item.str_values) + + " with basis_type=pw. PW requires gamma_only=0; for Gamma-point sampling, " + "use a 1 1 1 0 0 0 Gamma mesh in KPT. KPT is not modified.\n" + "See https://abacus.deepmodeling.com/en/latest/advanced/input_files/input-main.html#gamma-only"; + ModuleBase::WARNING_QUIT("ReadInput", message); } if (para.input.basis_type == "lcao" && para.input.gamma_only) { diff --git a/source/source_io/test_serial/read_input_item_test.cpp b/source/source_io/test_serial/read_input_item_test.cpp index 096b5c45150..1551ff57dff 100644 --- a/source/source_io/test_serial/read_input_item_test.cpp +++ b/source/source_io/test_serial/read_input_item_test.cpp @@ -1145,20 +1145,18 @@ TEST_F(InputTest, Item_test) auto it = find_label("gamma_only", readinput.input_lists); TestParameters::input(param).basis_type = "pw"; TestParameters::input(param).gamma_only = true; - std::string filename = TestParameters::input(param).kpoint_file; - it->second.reset_value(it->second, param); - EXPECT_EQ(TestParameters::input(param).gamma_only, false); - std::ifstream ifs(filename); - std::string line; - std::getline(ifs, line); - ifs.close(); - EXPECT_EQ(line, "K_POINTS"); + it->second.str_values = {"1"}; + EXPECT_EXIT(it->second.check_value(it->second, param), ::testing::ExitedWithCode(1), ""); + EXPECT_TRUE(TestParameters::input(param).gamma_only); + + TestParameters::input(param).gamma_only = false; + EXPECT_NO_THROW(it->second.check_value(it->second, param)); TestParameters::input(param).basis_type = "lcao"; TestParameters::input(param).gamma_only = true; TestParameters::input(param).nspin = 4; testing::internal::CaptureStdout(); - EXPECT_EXIT(it->second.reset_value(it->second, param), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(it->second.check_value(it->second, param), ::testing::ExitedWithCode(1), ""); output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("NOTICE")); @@ -1271,6 +1269,71 @@ TEST_F(InputTest, Item_test) } } +TEST_F(InputTest, RejectPwGammaOnlyWithoutChangingKpt) +{ + const std::string filename = testing::TempDir() + "abacus_pw_gamma_INPUT"; + const std::string kpt = testing::TempDir() + "abacus_pw_gamma_KPT"; + const std::string content = "K_POINTS\n0\nGamma\n2 3 4 0 0 0\n"; + for (const bool existing_kpt : {false, true}) + { + SCOPED_TRACE(existing_kpt); + if (existing_kpt) + { + std::ofstream output(kpt.c_str()); + output << content; + } + { + std::ofstream input(filename.c_str()); + input << "INPUT_PARAMETERS\nbasis_type pw\ngamma_only 1\nkpoint_file " << kpt << "\n"; + } + ModuleIO::ReadInput reader(0); + reader.check_ntype_flag = false; + Parameter param; + testing::internal::CaptureStdout(); + EXPECT_EXIT(reader.read_parameters(param, filename), testing::ExitedWithCode(1), ""); + const std::string diagnostic = testing::internal::GetCapturedStdout(); + EXPECT_THAT(diagnostic, testing::HasSubstr("Invalid INPUT gamma_only=1")); + EXPECT_THAT(diagnostic, testing::HasSubstr("PW requires gamma_only=0")); + EXPECT_THAT(diagnostic, testing::HasSubstr("1 1 1 0 0 0 Gamma mesh")); + EXPECT_THAT(diagnostic, testing::HasSubstr("input-main.html#gamma-only")); + std::ifstream actual(kpt.c_str()); + if (existing_kpt) + { + std::stringstream buffer; + buffer << actual.rdbuf(); + EXPECT_EQ(buffer.str(), content); + actual.close(); + EXPECT_EQ(std::remove(kpt.c_str()), 0); + } + else + { + EXPECT_FALSE(actual.is_open()); + } + EXPECT_EQ(std::remove(filename.c_str()), 0); + } +} + +TEST_F(InputTest, AcceptSupportedGammaOnlyInputs) +{ + const std::string filename = testing::TempDir() + "abacus_supported_gamma_INPUT"; + for (const std::string parameters : {"basis_type pw\ngamma_only 0\n", + "basis_type lcao\ngamma_only 1\nnspin 1\n", + "basis_type lcao\ngamma_only 1\nnspin 2\n"}) + { + SCOPED_TRACE(parameters); + { + std::ofstream input(filename.c_str()); + input << "INPUT_PARAMETERS\n" << parameters; + } + ModuleIO::ReadInput reader(0); + reader.check_ntype_flag = false; + Parameter param; + reader.read_parameters(param, filename); + EXPECT_EQ(param.inp.gamma_only, param.inp.basis_type == "lcao"); + EXPECT_EQ(std::remove(filename.c_str()), 0); + } +} + TEST_F(InputTest, HsOutputAliases) { { diff --git a/tests/01_PW/027_PW_PINT_RKS/INPUT b/tests/01_PW/027_PW_PINT_RKS/INPUT index 9f6289afa2a..a55ad662dd0 100644 --- a/tests/01_PW/027_PW_PINT_RKS/INPUT +++ b/tests/01_PW/027_PW_PINT_RKS/INPUT @@ -10,7 +10,7 @@ ecutwfc 50 scf_nmax 20 basis_type pw -gamma_only 1 +gamma_only 0 # Gamma-point sampling is specified in KPT. init_wfc nao diff --git a/tests/01_PW/028_PW_PINT_UKS/INPUT b/tests/01_PW/028_PW_PINT_UKS/INPUT index ed8277f05c5..cb629e2925d 100644 --- a/tests/01_PW/028_PW_PINT_UKS/INPUT +++ b/tests/01_PW/028_PW_PINT_UKS/INPUT @@ -16,7 +16,7 @@ mixing_beta_mag 0.4 ks_solver cg basis_type pw -gamma_only 1 +gamma_only 0 # Gamma-point sampling is specified in KPT. nspin 2 pseudo_dir ../../../tests/PP_ORB orbital_dir ../../../tests/PP_ORB diff --git a/tests/09_DeePKS/97_PW_ORB_deepks_s/INPUT b/tests/09_DeePKS/97_PW_ORB_deepks_s/INPUT index 3cf927acfaa..6bb9dd432e7 100644 --- a/tests/09_DeePKS/97_PW_ORB_deepks_s/INPUT +++ b/tests/09_DeePKS/97_PW_ORB_deepks_s/INPUT @@ -14,7 +14,7 @@ scf_nmax 50 #Parameters (3.Basis) basis_type pw -gamma_only 1 +gamma_only 0 # Gamma-point sampling is specified in KPT. #Parameters (4.Smearing) smearing_method gaussian diff --git a/tests/09_DeePKS/98_PW_ORB_deepks_p/INPUT b/tests/09_DeePKS/98_PW_ORB_deepks_p/INPUT index 39b2060b461..3b6f6167ba6 100644 --- a/tests/09_DeePKS/98_PW_ORB_deepks_p/INPUT +++ b/tests/09_DeePKS/98_PW_ORB_deepks_p/INPUT @@ -14,7 +14,7 @@ scf_nmax 50 #Parameters (3.Basis) basis_type pw -gamma_only 1 +gamma_only 0 # Gamma-point sampling is specified in KPT. #Parameters (4.Smearing) smearing_method gaussian diff --git a/tests/09_DeePKS/99_PW_ORB_deepks_d/INPUT b/tests/09_DeePKS/99_PW_ORB_deepks_d/INPUT index 7126cc9cba5..ecabcd246b2 100644 --- a/tests/09_DeePKS/99_PW_ORB_deepks_d/INPUT +++ b/tests/09_DeePKS/99_PW_ORB_deepks_d/INPUT @@ -13,7 +13,7 @@ scf_nmax 50 #Parameters (3.Basis) basis_type pw -gamma_only 1 +gamma_only 0 # Gamma-point sampling is specified in KPT. #Parameters (4.Smearing) smearing_method gaussian