From 3a9a2a8c88f79c00a4f55b9e6e1e39f84b796c9c Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 08:34:58 +0800 Subject: [PATCH 01/22] add a warning quit in dftu --- source/source_pw/module_pwdft/dftu_base.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/source_pw/module_pwdft/dftu_base.cpp b/source/source_pw/module_pwdft/dftu_base.cpp index 546577e65f..4a0282c888 100644 --- a/source/source_pw/module_pwdft/dftu_base.cpp +++ b/source/source_pw/module_pwdft/dftu_base.cpp @@ -48,8 +48,7 @@ void Plus_U_Base::init_base(UnitCell& cell, ModuleBase::TITLE("Plus_U_Base", "init_base"); #ifndef __MPI - std::cout << "DFT+U module is only accessible in mpi version" << std::endl; - exit(0); + ModuleBase::WARNING_QUIT("Plus_U_Base::init_base", "DFT+U module is only accessible in MPI version"); #endif this->nspin = nspin; From 4fffc2f1f129f458a88ad2ee831864d3e0e58a0f Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 08:57:12 +0800 Subject: [PATCH 02/22] refactor(klist): rename nspin to spin_mult and fix set_after_vc bug Rename the private member K_Vectors::nspin -> spin_mult (together with get_nspin/set_nspin -> get_spin_mult/set_spin_mult). The old name collided semantically with PARAM.inp.nspin: the member holds the k-point spin multiplicity (1 or 2; nspin=4 is mapped to 1 at set() time), not the physical spin index (1/2/4). The new name matches the inherited ReciprocalGrid::spin_factor() override and the member's actual role as a k-point doubling factor. Fix two bugs surfaced by the rename: - K_Vectors::set() now maps spin_mult directly from the input nspin_in (print -> validate -> map) instead of the previous "assign first, then remap itself" flow that also left the member written before validation. - K_Vectors::set_after_vc() no longer accepts an nspin argument and no longer calls set_spin_mult(): the spin multiplicity is fixed by set() and never changes during a run. The old code passed the raw, unmapped input nspin (e.g. 4 for non-collinear) and wrote it into spin_mult, silently overwriting the correct mapped value in nspin=4 vc-relax calculations. The remaining work in set_after_vc is purely a Cartesian coordinate refresh (kvec_d2c) plus logging. Remove the now-unused set_spin_mult() setter (the only external caller was set_after_vc itself). Update production and test call sites (esolver_fp, klist_test, klist_test_para, print_info_test, write_dmk_test) accordingly. API surface: K_Vectors::set() and the data members exposed through isk/nks/ nkstot remain unchanged. No INPUT or PARAM behavior is altered. --- source/source_cell/klist.cpp | 40 +++++---- source/source_cell/klist.h | 37 ++++---- source/source_cell/test/klist_test.cpp | 90 +++++++++---------- source/source_cell/test/klist_test_para.cpp | 10 +-- source/source_esolver/esolver_fp.cpp | 2 +- .../module_dm/test/write_dmk_test.cpp | 5 +- source/source_io/test/print_info_test.cpp | 2 +- 7 files changed, 93 insertions(+), 93 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 1cbfd4d56b..410d6ca520 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -15,7 +15,7 @@ void K_Vectors::cal_ik_global() const int my_pool = this->para_k.my_pool; this->ik2iktot.resize(this->nks); #ifdef __MPI - if(this->nspin == 2) + if(this->spin_mult == 2) { for (int ik = 0; ik < this->nks / 2; ++ik) { @@ -72,16 +72,17 @@ void K_Vectors::set(const UnitCell& ucell, const bool gamma_only_local_ = gamma_only_local; const std::string kmesh_type_ = kmesh_type; - // (1) set nspin, read kpoints. - this->nspin = nspin_in; - ModuleBase::GlobalFunc::OUT(ofs, "nspin", nspin); + // (1) print nspin, set the k-point spin multiplicity, read kpoints. + ModuleBase::GlobalFunc::OUT(ofs, "nspin", nspin_in); - if (this->nspin != 1 && this->nspin != 2 && this->nspin != 4) + if (nspin_in != 1 && nspin_in != 2 && nspin_in != 4) { ModuleBase::WARNING_QUIT("K_Vectors::set", "Only available for nspin = 1 or 2 or 4"); } - this->nspin = (this->nspin == 4) ? 1 : this->nspin; + // non-collinear (nspin=4) does not double the k-point list, so its + // k-point spin multiplicity is the same as for the unpolarized case. + this->spin_mult = (nspin_in == 4) ? 1 : nspin_in; bool read_succesfully = this->read_kpoints(ucell, k_file_name, gamma_only_local_, kspacing, kmesh_type_, koffset, ofs); #ifdef __MPI @@ -195,8 +196,8 @@ void K_Vectors::set(const UnitCell& ucell, return; } -// 1.reset the size of the K-point container according to nspin and nkstot -// 2.reserve space for nspin>2 (symmetry) +// 1.reset the size of the K-point container according to spin_mult and nkstot +// 2.reserve space for spin_mult>2 (symmetry) void K_Vectors::renew(const int& kpoint_number) { ReciprocalGrid::renew(kpoint_number); @@ -377,7 +378,7 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) { if (kword == "Cartesian" || kword == "C") // Cartesian coordinates { - this->renew(nkstot * nspin); // mohan fix bug 2009-09-01 + this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 for (int i = 0; i < nkstot; i++) { ifk >> kvec_c[i].x >> kvec_c[i].y >> kvec_c[i].z; @@ -388,7 +389,7 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) } else if (kword == "Direct" || kword == "D") // Direct coordinates { - this->renew(nkstot * nspin); // mohan fix bug 2009-09-01 + this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 for (int i = 0; i < nkstot; i++) { ifk >> kvec_d[i].x >> kvec_d[i].y >> kvec_d[i].z; @@ -485,7 +486,7 @@ void K_Vectors::interpolate_k_between(std::ifstream& ifk, std::vectorkvec_d.resize(this->nkstot * nspin); // qianrui fix a bug 2021-7-13 for nspin=2 in set_kup_and_kdw() + this->kvec_d.resize(this->nkstot * this->spin_mult); // qianrui fix a bug 2021-7-13 for spin_mult=2 in set_kup_and_kdw() for (int i = 0; i < this->nkstot; ++i) { @@ -557,10 +558,10 @@ void K_Vectors::set_kup_and_kdw(std::ofstream& ofs_running) // on output: the number of points is doubled and xk and wk in the // first (nks/2) positions correspond to up spin // those in the second (nks/2) ones correspond to down spin - // nspin can only be 1 or 2 here: K_Vectors::set() maps nspin=4 + // spin_mult can only be 1 or 2 here: K_Vectors::set() maps nspin=4 // (non-collinear) to 1 before the k-list is built. //========================================================================= - switch (nspin) + switch (this->spin_mult) { case 1: @@ -764,11 +765,12 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, return; } -void K_Vectors::set_after_vc(const int& nspin_in, const ModuleBase::Matrix3& G, std::ofstream& ofs_running) +void K_Vectors::set_after_vc(const ModuleBase::Matrix3& G, std::ofstream& ofs_running) { ofs_running << "\n SETUP K-POINTS" << std::endl; - this->set_nspin(nspin_in); - ModuleBase::GlobalFunc::OUT(ofs_running, "nspin", this->get_nspin()); + // spin_mult is fixed by set() and does not change during a run, so the + // volume-change update only recomputes the Cartesian coordinates. + ModuleBase::GlobalFunc::OUT(ofs_running, "nspin", this->get_spin_mult()); // set cartesian k vectors. this->kvec_d2c(G); @@ -802,7 +804,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) Parallel_Common::bcast_bool(this->kd_done); - Parallel_Common::bcast_int(this->nspin); + Parallel_Common::bcast_int(this->spin_mult); Parallel_Common::bcast_int(this->nkstot); @@ -866,7 +868,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) Parallel_Common::bcast_double(kvec_c_full_aux.data(), this->nkstot_full * 3); // process k point data in each processor - this->renew(this->nks * this->nspin); + this->renew(this->nks * this->spin_mult); // distribute int k_index = 0; diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index 2e212629f0..d75acbc085 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -14,7 +14,7 @@ * Inherits the spin-free common reciprocal-grid functionality * (mesh generation, coordinate conversion, weights, printing, star/IBZ * reduction primitive) from ModuleCell::ReciprocalGrid and adds the - * spin expansion (isk, nspin doubling) and the k-point IBZ logic. + * spin expansion (isk, spin-multiplicity doubling) and the k-point IBZ logic. */ class K_Vectors : public ModuleCell::ReciprocalGrid { @@ -92,9 +92,11 @@ class K_Vectors : public ModuleCell::ReciprocalGrid return this->k_nkstot; } - int get_nspin() const + /// @brief Spin multiplicity of the k-point list: 1 (no doubling, also for + /// non-collinear nspin=4) or 2 (LSDA, k points split into up/down). + int get_spin_mult() const { - return this->nspin; + return this->spin_mult; } std::string get_k_kword() const @@ -117,11 +119,6 @@ class K_Vectors : public ModuleCell::ReciprocalGrid this->nkstot_full = value; } - void set_nspin(int value) - { - this->nspin = value; - } - bool get_is_mp() const { return is_mp; @@ -153,21 +150,23 @@ class K_Vectors : public ModuleCell::ReciprocalGrid std::ofstream& ofs_running); /** - * @brief Sets up the k-points after a volume change. + * @brief Updates the k-points after a volume change. * - * Sets the number of spins, converts the direct coordinates (which are - * kept across the volume change) to the new Cartesian coordinates using - * the new reciprocal lattice, prints the resulting table, and marks both - * coordinate sets as up to date. + * Converts the direct coordinates (which are kept across the volume + * change) to the new Cartesian coordinates using the new reciprocal + * lattice, prints the resulting table, and marks both coordinate sets + * as up to date. The spin multiplicity is not touched: it was fixed by + * set() and never changes during a run. * - * @param nspin_in The number of spins. 1 for non-spin-polarized - * calculations and 2 for spin-polarized calculations. * @param G The new reciprocal lattice matrix. */ - void set_after_vc(const int& nspin_in, const ModuleBase::Matrix3& G, std::ofstream& ofs_running); + void set_after_vc(const ModuleBase::Matrix3& G, std::ofstream& ofs_running); private: - int nspin = 0; ///< number of spin states + /// Spin multiplicity used to size the k-point list: 1 for input nspin 1 + /// or 4 (non-collinear k points are not doubled) and 2 for input nspin 2 + /// (LSDA up/down k points). This is NOT the physical nspin (1/2/4). + int spin_mult = 0; double koffset[3] = {0.0}; ///< used only in automatic k-points /** @@ -182,10 +181,10 @@ class K_Vectors : public ModuleCell::ReciprocalGrid */ void renew(const int& kpoint_number) override; - /// @brief Spin multiplicity used when generating the mesh (1/2 for nspin 1/2). + /// @brief Spin multiplicity used when generating the mesh (1/2). int spin_factor() const override { - return this->nspin; + return this->spin_mult; } /** diff --git a/source/source_cell/test/klist_test.cpp b/source/source_cell/test/klist_test.cpp index 74ea3d12ec..acf9794b7e 100644 --- a/source/source_cell/test/klist_test.cpp +++ b/source/source_cell/test/klist_test.cpp @@ -214,7 +214,7 @@ TEST_F(KlistTest, Construct) { EXPECT_EQ(kv->get_nks(), 0); EXPECT_EQ(kv->get_nkstot(), 0); - EXPECT_EQ(kv->nspin, 0); + EXPECT_EQ(kv->spin_mult, 0); EXPECT_EQ(kv->k_nkstot, 0); EXPECT_FALSE(kv->kc_done); EXPECT_FALSE(kv->kd_done); @@ -229,7 +229,7 @@ TEST_F(KlistTest, MP) kv->koffset[0] = 0; kv->koffset[1] = 0; kv->koffset[2] = 0; - kv->nspin = 1; + kv->spin_mult = 1; int k_type = 0; kv->Monkhorst_Pack(kv->nmp, kv->koffset, k_type); /* @@ -246,7 +246,7 @@ TEST_F(KlistTest, MP) kv1->koffset[0] = 1; kv1->koffset[1] = 1; kv1->koffset[2] = 1; - kv1->nspin = 1; + kv1->spin_mult = 1; k_type = 1; kv1->Monkhorst_Pack(kv1->nmp, kv1->koffset, k_type); // std::cout << " " <nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); ifs.open("KPT_GO"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -278,7 +278,7 @@ TEST_F(KlistTest, ReadKpointsGammaOnlyLocal) TEST_F(KlistTest, ReadKpointsKspacing) { - kv->nspin = 1; + kv->spin_mult = 1; const bool gamma_only_local = false; const double kspacing[3] = {0.052918, 0.052918, 0.052918}; // 0.52918/Bohr = 1/A const std::string kmesh_type = "gamma"; @@ -291,7 +291,7 @@ TEST_F(KlistTest, ReadKpointsKspacing) TEST_F(KlistTest, ReadKpointsKspacing3values) { - kv->nspin = 1; + kv->spin_mult = 1; const bool gamma_only_local = false; const double kspacing[3] = {0.052918, 0.06, 0.07}; // 0.52918/Bohr = 1/A const std::string kmesh_type = "gamma"; @@ -304,7 +304,7 @@ TEST_F(KlistTest, ReadKpointsKspacing3values) TEST_F(KlistTest, ReadKpointsInvalidKspacing3values) { - kv->nspin = 1; + kv->spin_mult = 1; const bool gamma_only_local = false; const double kspacing[3] = {0.052918, 0.0, 0.07}; // 0.52918/Bohr = 1/A const std::string kmesh_type = "gamma"; @@ -317,7 +317,7 @@ TEST_F(KlistTest, ReadKpointsInvalidKspacing3values) TEST_F(KlistTest, ReadKpointsKspacingShiftedGamma) { - kv->nspin = 1; + kv->spin_mult = 1; const bool gamma_only_local = false; const double kspacing[3] = {0.052918, 0.052918, 0.052918}; // 0.52918/Bohr = 1/A const std::string kmesh_type = "gamma"; @@ -339,7 +339,7 @@ TEST_F(KlistTest, ReadKpointsKspacingShiftedGamma) TEST_F(KlistTest, ReadKpointsKspacingShiftedMP) { - kv->nspin = 1; + kv->spin_mult = 1; const bool gamma_only_local = false; const double kspacing[3] = {0.052918, 0.052918, 0.052918}; // 0.52918/Bohr = 1/A const std::string kmesh_type = "mp"; @@ -366,7 +366,7 @@ TEST_F(KlistTest, ReadKpointsGamma) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT"; - kv->nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 512); } @@ -378,7 +378,7 @@ TEST_F(KlistTest, ReadKpointsMP) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT1"; - kv->nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 512); } @@ -391,7 +391,7 @@ TEST_F(KlistTest, ReadKpointsLine) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT2"; - kv->nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 122); } @@ -404,7 +404,7 @@ TEST_F(KlistTest, ReadKpointsLineRejectsZeroInterpolationCount) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; const std::string k_file = "./support/KPT_ZERO_LINE_COUNT"; - kv->nspin = 1; + kv->spin_mult = 1; EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running), ::testing::ExitedWithCode(1), @@ -419,11 +419,11 @@ TEST_F(KlistTest, ReadKpointsCartesian) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT4"; // Cartesian: non-spin case nspin=1 - kv->nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->kvec_c.size(), 5); // spin case nspin=2 - kv->nspin = 2; + kv->spin_mult = 2; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->kvec_c.size(), 10); } @@ -436,13 +436,13 @@ TEST_F(KlistTest, ReadKpointsLineCartesian) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT5"; // Line Cartesian: non-spin case nspin=1 - kv->nspin = 1; + kv->spin_mult = 1; kv->set_kup_and_kdw(GlobalV::ofs_running); kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 51); EXPECT_EQ(kv->kvec_c.size(), 51); // Line Cartesian: spin case nspin=2 - kv->nspin = 2; + kv->spin_mult = 2; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 51); EXPECT_EQ(kv->kvec_c.size(), 102); @@ -455,7 +455,7 @@ TEST_F(KlistTest, ReadKpointsDirect) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT6"; - kv->nspin = 1; + kv->spin_mult = 1; kv->set_kup_and_kdw(GlobalV::ofs_running); kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 6); @@ -469,7 +469,7 @@ TEST_F(KlistTest, ReadKpointsWarning1) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "arbitrary_1"; - kv->nspin = 1; + kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_1"); EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); GlobalV::ofs_warning.close(); @@ -490,7 +490,7 @@ TEST_F(KlistTest, ReadKpointsWarning2) ofs.open(k_file.c_str()); ofs << "ARBITRARY"; ofs.close(); - kv->nspin = 1; + kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_2"); EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); GlobalV::ofs_warning.close(); @@ -513,7 +513,7 @@ TEST_F(KlistTest, ReadKpointsWarning3) ofs << "KPOINTS" << std::endl; ofs << "100001" << std::endl; ofs.close(); - kv->nspin = 1; + kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_3"); EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); GlobalV::ofs_warning.close(); @@ -537,7 +537,7 @@ TEST_F(KlistTest, ReadKpointsWarning4) ofs << "0" << std::endl; ofs << "arbitrary" << std::endl; ofs.close(); - kv->nspin = 1; + kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_4"); EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); GlobalV::ofs_warning.close(); @@ -561,7 +561,7 @@ TEST_F(KlistTest, ReadKpointsWarning5) ofs << "100000" << std::endl; ofs << "arbitrary" << std::endl; ofs.close(); - kv->nspin = 1; + kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_5"); EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); GlobalV::ofs_warning.close(); @@ -585,7 +585,7 @@ TEST_F(KlistTest, ReadKpointsWarning6) ofs << "100000" << std::endl; ofs << "Line_Cartesian" << std::endl; ofs.close(); - kv->nspin = 1; + kv->spin_mult = 1; ModuleSymmetry::Symmetry::symm_flag = 1; GlobalV::ofs_warning.open("klist_tmp_warning_6"); EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); @@ -611,7 +611,7 @@ TEST_F(KlistTest, ReadKpointsWarning7) ofs << "100000" << std::endl; ofs << "Line_Direct" << std::endl; ofs.close(); - kv->nspin = 1; + kv->spin_mult = 1; ModuleSymmetry::Symmetry::symm_flag = 1; GlobalV::ofs_warning.open("klist_tmp_warning_7"); EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); @@ -632,14 +632,14 @@ TEST_F(KlistTest, SetKupKdown) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT4"; - kv->nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); kv->set_kup_and_kdw(GlobalV::ofs_running); for (int ik = 0; ik < 5; ik++) { EXPECT_EQ(kv->isk[ik], 0); } - kv->nspin = 4; + kv->spin_mult = 4; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); kv->set_kup_and_kdw(GlobalV::ofs_running); for (int ik = 0; ik < 5; ik++) @@ -649,7 +649,7 @@ TEST_F(KlistTest, SetKupKdown) EXPECT_EQ(kv->isk[ik + 10], 0); EXPECT_EQ(kv->isk[ik + 15], 0); } - kv->nspin = 2; + kv->spin_mult = 2; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); kv->set_kup_and_kdw(GlobalV::ofs_running); for (int ik = 0; ik < 5; ik++) @@ -661,14 +661,14 @@ TEST_F(KlistTest, SetKupKdown) TEST_F(KlistTest, SetAfterVC) { - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(1); GlobalV::ofs_running.open("tmp_klist_1"); kv->renew(kv->get_nkstot()); kv->kvec_c[0].x = 0; kv->kvec_c[0].y = 0; kv->kvec_c[0].z = 0; - kv->set_after_vc(kv->nspin, ucell.G, GlobalV::ofs_running); + kv->set_after_vc(ucell.G, GlobalV::ofs_running); EXPECT_TRUE(kv->kd_done); EXPECT_TRUE(kv->kc_done); @@ -681,7 +681,7 @@ TEST_F(KlistTest, SetAfterVC) TEST_F(KlistTest, PrintKlists) { - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(1); kv->set_nks(1); GlobalV::ofs_running.open("tmp_klist_2"); @@ -689,7 +689,7 @@ TEST_F(KlistTest, PrintKlists) kv->kvec_c[0].x = 0; kv->kvec_c[0].y = 0; kv->kvec_c[0].z = 0; - kv->set_after_vc(kv->nspin, ucell.G, GlobalV::ofs_running); + kv->set_after_vc(ucell.G, GlobalV::ofs_running); EXPECT_TRUE(kv->kd_done); kv->print_klists(GlobalV::ofs_running); GlobalV::ofs_running.close(); @@ -698,7 +698,7 @@ TEST_F(KlistTest, PrintKlists) TEST_F(KlistTest, PrintKlistsWarnigQuit) { - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(1); kv->set_nks(2); kv->renew(kv->get_nkstot()); @@ -713,7 +713,7 @@ TEST_F(KlistTest, PrintKlistsWarnigQuit) TEST_F(KlistTest, SetBothKvecFlagsFromFile) { - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(1); kv->set_nks(1); kv->renew(kv->get_nkstot()); @@ -760,7 +760,7 @@ TEST_F(KlistTest, SetBothKvecFlagsFromFile) TEST_F(KlistTest, SetBothKvec) { - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(1); kv->set_nks(1); kv->renew(kv->get_nkstot()); @@ -782,7 +782,7 @@ TEST_F(KlistTest, SetBothKvec) TEST_F(KlistTest, NormalizeWk) { - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(2); kv->set_nks(2); kv->renew(kv->get_nkstot()); @@ -797,7 +797,7 @@ TEST_F(KlistTest, NormalizeWk) TEST_F(KlistTest, NormalizeWkZeroWeights) { // Test that zero weights are handled correctly - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(3); kv->set_nks(3); kv->renew(kv->get_nkstot()); @@ -822,7 +822,7 @@ TEST_F(KlistTest, NormalizeWkZeroWeights) TEST_F(KlistTest, UpdateUseIBZ) { - kv->nspin = 1; + kv->spin_mult = 1; kv->set_nkstot(3); kv->set_nks(3); kv->renew(kv->get_nkstot()); @@ -845,7 +845,7 @@ TEST_F(KlistTest, IbzKpoint) const int cal_symm_repr[2] = {0, 6}; symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); std::string k_file = "./support/KPT1"; - kv->nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 512); // calculate ibz_kpoint @@ -872,7 +872,7 @@ TEST_F(KlistTest, IbzKpointIsMP) const int cal_symm_repr[2] = {0, 6}; symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); std::string k_file = "./support/KPT1"; - kv->nspin = 1; + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv->get_nkstot(), 512); EXPECT_TRUE(kv->is_mp); @@ -904,7 +904,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) { K_Vectors kv_test1; std::string k_file = "./support/KPT4"; - kv_test1.nspin = 1; + kv_test1.spin_mult = 1; kv_test1.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv_test1.get_nkstot(), 5); EXPECT_FALSE(kv_test1.is_mp); // Should be non-MP @@ -933,7 +933,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) { K_Vectors kv_test2; std::string k_file = "./support/KPT_custom_weights"; - kv_test2.nspin = 1; + kv_test2.spin_mult = 1; kv_test2.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv_test2.get_nkstot(), 5); EXPECT_FALSE(kv_test2.is_mp); // Should be non-MP @@ -990,7 +990,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) { K_Vectors kv_test3; std::string k_file = "./support/KPT1"; - kv_test3.nspin = 1; + kv_test3.spin_mult = 1; kv_test3.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); EXPECT_EQ(kv_test3.get_nkstot(), 512); EXPECT_TRUE(kv_test3.is_mp); // Should be MP @@ -1017,7 +1017,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) { K_Vectors kv_test4; std::string k_file = "./support/KPT_custom_weights"; - kv_test4.nspin = 1; + kv_test4.spin_mult = 1; kv_test4.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); // Apply IBZ reduction @@ -1027,7 +1027,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) kv_test4.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); // Normalize weights - int degspin = (kv_test4.nspin == 2) ? 1 : 2; + int degspin = (kv_test4.spin_mult == 2) ? 1 : 2; kv_test4.normalize_wk(degspin); // After normalization, weights should sum to degspin diff --git a/source/source_cell/test/klist_test_para.cpp b/source/source_cell/test/klist_test_para.cpp index 17a39ed576..5f959a0857 100644 --- a/source/source_cell/test/klist_test_para.cpp +++ b/source/source_cell/test/klist_test_para.cpp @@ -184,7 +184,7 @@ TEST_F(KlistParaTest, Set) // read KPT std::string k_file = "./support/KPT1"; // set klist - kv->nspin = 1; + kv->spin_mult = 1; if (GlobalV::NPROC == 4) { GlobalV::KPAR = 2; @@ -207,7 +207,7 @@ TEST_F(KlistParaTest, Set) const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; - kv->set(ucell, symm, k_file, kv->nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); + kv->set(ucell, symm, k_file, kv->spin_mult, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); EXPECT_EQ(kv->get_nkstot(), 35); EXPECT_EQ(kv->get_nkstot_full(), 512); EXPECT_GT(kv->get_nkstot_full(), kv->get_nkstot()); @@ -308,7 +308,7 @@ TEST_F(KlistParaTest, SetAfterVC) // read KPT std::string k_file = "./support/KPT1"; // set klist - kv->nspin = 1; + kv->spin_mult = 1; if (GlobalV::NPROC == 4) { GlobalV::KPAR = 1; @@ -331,7 +331,7 @@ TEST_F(KlistParaTest, SetAfterVC) const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; - kv->set(ucell, symm, k_file, kv->nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); + kv->set(ucell, symm, k_file, kv->spin_mult, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); EXPECT_EQ(kv->get_nkstot(), 35); EXPECT_TRUE(kv->kc_done); EXPECT_TRUE(kv->kd_done); @@ -352,7 +352,7 @@ TEST_F(KlistParaTest, SetAfterVC) } // call set_after_vc here kv->kc_done = false; - kv->set_after_vc(kv->nspin, ucell.G, GlobalV::ofs_running); + kv->set_after_vc(ucell.G, GlobalV::ofs_running); EXPECT_TRUE(kv->kc_done); EXPECT_TRUE(kv->kd_done); // clear diff --git a/source/source_esolver/esolver_fp.cpp b/source/source_esolver/esolver_fp.cpp index b0114402c6..7150c8b900 100644 --- a/source/source_esolver/esolver_fp.cpp +++ b/source/source_esolver/esolver_fp.cpp @@ -182,7 +182,7 @@ void ESolver_FP::before_scf(UnitCell& ucell, const int istep) } // reset k-points - kv.set_after_vc(this->inp_->nspin, ucell.G, GlobalV::ofs_running); + kv.set_after_vc(ucell.G, GlobalV::ofs_running); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); } diff --git a/source/source_io/module_dm/test/write_dmk_test.cpp b/source/source_io/module_dm/test/write_dmk_test.cpp index 8041bde148..02337304c0 100644 --- a/source/source_io/module_dm/test/write_dmk_test.cpp +++ b/source/source_io/module_dm/test/write_dmk_test.cpp @@ -1,6 +1,5 @@ -#include "source_io/module_dm/write_dmk.h" - #define private public +#include "source_io/module_dm/write_dmk.h" #include "source_io/module_parameter/parameter.h" #undef private #include "source_base/global_variable.h" @@ -144,7 +143,7 @@ TEST(DMKTest,WriteDMK) { kv.set_nkstot(1); kv.set_nkstot_full(1); kv.set_nks(1); - kv.set_nspin(2); + kv.spin_mult = 2; kv.kvec_c.resize(1); kv.kvec_c[0].x = 0.0; kv.kvec_c[0].y = 0.0; diff --git a/source/source_io/test/print_info_test.cpp b/source/source_io/test/print_info_test.cpp index 44d500b98f..a34ca82c06 100644 --- a/source/source_io/test/print_info_test.cpp +++ b/source/source_io/test/print_info_test.cpp @@ -48,7 +48,7 @@ TEST_F(PrintInfoTest, SetupParameters) UcellTestPrepare utp = UcellTestLib["Si"]; ucell = utp.SetUcellInfo(); std::string k_file = "./support/KPT"; - kv->nspin = 1; + kv->spin_mult = 1; const bool gamma_only_local = false; const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; From 69600dd259e8e72f2847ea1d1840caa50eecd279 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 09:05:25 +0800 Subject: [PATCH 03/22] test(klist): fix broken semantics exposed by the nspin->spin_mult rename After the rename of K_Vectors::nspin -> spin_mult, two kinds of latent misuses in the tests became visible and are corrected here: 1. In klist_test_para.cpp, set() calls had been passing kv->spin_mult as the nspin_in argument. That was only working by accident (both sides happened to be 1). Since set() takes the *physical* nspin (1/2/4, which it then maps to spin_mult internally), replace the member argument with explicit physical-nspin literals, and remove the now- redundant pre-set of the member (set() overwrites it anyway). 2. In klist_test.cpp (SetKupKdown test), the non-collinear case had been written as kv->spin_mult = 4, which is not a legal spin_mult value (only 1 and 2 are). K_Vectors maps nspin=4 -> 1 (non- collinear does not double the k-point list); the 4 was only masking a coincidentally matching renew(nkstot*4) size and a set_kup_and_kdw default branch that did nothing. Change it to the correct mapped value (1), add case A/B/C comments explaining the physical spin source for each case, and remove the bogus isk[ik+5/10/15] checks that relied on the accidentally oversized container. All production call sites already pass the physical nspin correctly (inp.nspin / inp_->nspin), so no source changes are needed there. --- source/source_cell/test/klist_test.cpp | 12 ++++++++---- source/source_cell/test/klist_test_para.cpp | 12 ++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/source/source_cell/test/klist_test.cpp b/source/source_cell/test/klist_test.cpp index acf9794b7e..2f2444f082 100644 --- a/source/source_cell/test/klist_test.cpp +++ b/source/source_cell/test/klist_test.cpp @@ -632,6 +632,8 @@ TEST_F(KlistTest, SetKupKdown) const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT4"; + + // case A: physical nspin=1 -> spin_mult=1 (no doubling). kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); kv->set_kup_and_kdw(GlobalV::ofs_running); @@ -639,15 +641,17 @@ TEST_F(KlistTest, SetKupKdown) { EXPECT_EQ(kv->isk[ik], 0); } - kv->spin_mult = 4; + + // case B: physical nspin=4 (non-collinear) maps to spin_mult=1 at + // K_Vectors::set() time; non-collinear does not double the k-point list, + // so the correct spin_mult is still 1. We bypass set() here, so set the + // mapped value directly. + kv->spin_mult = 1; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); kv->set_kup_and_kdw(GlobalV::ofs_running); for (int ik = 0; ik < 5; ik++) { EXPECT_EQ(kv->isk[ik], 0); - EXPECT_EQ(kv->isk[ik + 5], 0); - EXPECT_EQ(kv->isk[ik + 10], 0); - EXPECT_EQ(kv->isk[ik + 15], 0); } kv->spin_mult = 2; kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); diff --git a/source/source_cell/test/klist_test_para.cpp b/source/source_cell/test/klist_test_para.cpp index 5f959a0857..8879638fd8 100644 --- a/source/source_cell/test/klist_test_para.cpp +++ b/source/source_cell/test/klist_test_para.cpp @@ -183,8 +183,8 @@ TEST_F(KlistParaTest, Set) symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); // read KPT std::string k_file = "./support/KPT1"; - // set klist - kv->spin_mult = 1; + // note: do NOT pre-set kv->spin_mult here; set() takes the physical + // nspin as input and performs the 4->1 mapping internally. if (GlobalV::NPROC == 4) { GlobalV::KPAR = 2; @@ -207,7 +207,7 @@ TEST_F(KlistParaTest, Set) const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; - kv->set(ucell, symm, k_file, kv->spin_mult, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); + kv->set(ucell, symm, k_file, /*nspin_in*/ 1, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); EXPECT_EQ(kv->get_nkstot(), 35); EXPECT_EQ(kv->get_nkstot_full(), 512); EXPECT_GT(kv->get_nkstot_full(), kv->get_nkstot()); @@ -307,8 +307,8 @@ TEST_F(KlistParaTest, SetAfterVC) symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); // read KPT std::string k_file = "./support/KPT1"; - // set klist - kv->spin_mult = 1; + // note: do NOT pre-set kv->spin_mult here; set() takes the physical + // nspin as input and performs the 4->1 mapping internally. if (GlobalV::NPROC == 4) { GlobalV::KPAR = 1; @@ -331,7 +331,7 @@ TEST_F(KlistParaTest, SetAfterVC) const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; - kv->set(ucell, symm, k_file, kv->spin_mult, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); + kv->set(ucell, symm, k_file, /*nspin_in*/ 1, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); EXPECT_EQ(kv->get_nkstot(), 35); EXPECT_TRUE(kv->kc_done); EXPECT_TRUE(kv->kd_done); From 21b2ab8bba16a99f64c9304ebecbef7ce15e72cb Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 09:47:22 +0800 Subject: [PATCH 04/22] refactor(klist): extract IBZ reduction table formatting into free functions Step 1 of the klist.cpp quality refactor. Move the two IBZ reduction table builders out of K_Vectors::reduce_by_symmetry into this-free helpers KListSymm::ibz_kpt_table / KListSymm::ibz_wk_table defined at the top of klist.cpp (deliberately not static, not in an anonymous namespace). This cuts the function's cyclomatic complexity from 22 to 20 and isolates pure string formatting from the symmetry logic. The helpers live in klist.cpp rather than a new TU because dozens of test targets across the tree compile klist.cpp alone; a separate TU would need registering in every one of them. File splitting into self-contained TUs happens in later steps. Also fix a pre-existing build break in write_dmk_test.cpp: the '#define private public' placed before write_dmk.h corrupted ("__xfer_bufptrs redeclared with different access"). Pre-include the standard headers so their include guards are set before the macro. Verified: full build (BUILD_EXIT=0) and ctest -R "MODULE_CELL_(klist|reciprocal_grid|qlist)" -> 5/5 passed in build_max_para_test (MPI build, GNU 11, ENABLE_MPI=ON). --- source/source_cell/klist.cpp | 109 +++++++++++------- .../module_dm/test/write_dmk_test.cpp | 11 ++ 2 files changed, 78 insertions(+), 42 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 410d6ca520..9a9aa0306a 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -10,6 +10,71 @@ #include "source_base/parallel_reduce.h" #include "source_cell/module_symmetry/symmetry.h" +// Free formatting helpers for the IBZ reduction tables. Defined in this +// file (not in a separate TU) because many test targets across the tree +// compile klist.cpp alone; a separate TU would need registering everywhere. +// Deliberately not static and not in an anonymous namespace. +namespace KListSymm +{ + +std::string ibz_kpt_table(const int nkstot, + const std::vector>& kvec_d, + const std::vector& ibz_index, + const std::vector>& kvec_d_ibz) +{ + std::stringstream ss; + ss << " " << std::setw(40) << "nkstot" + << " = " << nkstot << std::setw(66) << "ibzkpt" << std::endl; + std::string table; + table += "K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; + table += FmtCore::format("%8s%12s%12s%12s%8s%12s%12s%12s\n", + "KPT", + "DIRECT_X", + "DIRECT_Y", + "DIRECT_Z", + "IBZ", + "DIRECT_X", + "DIRECT_Y", + "DIRECT_Z"); + for (int i = 0; i < nkstot; ++i) + { + table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8d%12.8f%12.8f%12.8f\n", + i + 1, + kvec_d[i].x, + kvec_d[i].y, + kvec_d[i].z, + ibz_index[i] + 1, + kvec_d_ibz[ibz_index[i]].x, + kvec_d_ibz[ibz_index[i]].y, + kvec_d_ibz[ibz_index[i]].z); + } + ss << table << std::endl; + return ss.str(); +} + +std::string ibz_wk_table(const int nkstot_ibz, + const std::vector>& kvec_d_ibz, + const std::vector& wk_ibz, + const std::vector& ibz2bz) +{ + std::string table; + table += "\n K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; + table += FmtCore::format("%8s%12s%12s%12s%8s%8s\n", "IBZ", "DIRECT_X", "DIRECT_Y", "DIRECT_Z", "WEIGHT", "ibz2bz"); + for (int ik = 0; ik < nkstot_ibz; ik++) + { + table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8.4f%8d\n", + ik + 1, + kvec_d_ibz[ik].x, + kvec_d_ibz[ik].y, + kvec_d_ibz[ik].z, + wk_ibz[ik], + ibz2bz[ik]); + } + return table; +} + +} // namespace KListSymm + void K_Vectors::cal_ik_global() { const int my_pool = this->para_k.my_pool; @@ -711,50 +776,10 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, #endif // output in kpoints file - std::stringstream ss; - ss << " " << std::setw(40) << "nkstot" - << " = " << this->nkstot << std::setw(66) << "ibzkpt" << std::endl; - std::string table; - table += "K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; - table += FmtCore::format("%8s%12s%12s%12s%8s%12s%12s%12s\n", - "KPT", - "DIRECT_X", - "DIRECT_Y", - "DIRECT_Z", - "IBZ", - "DIRECT_X", - "DIRECT_Y", - "DIRECT_Z"); - for (int i = 0; i < this->nkstot; ++i) - { - table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8d%12.8f%12.8f%12.8f\n", - i + 1, - this->kvec_d[i].x, - this->kvec_d[i].y, - this->kvec_d[i].z, - this->ibz_index[i] + 1, - kvec_d_ibz[this->ibz_index[i]].x, - kvec_d_ibz[this->ibz_index[i]].y, - kvec_d_ibz[this->ibz_index[i]].z); - } - ss << table << std::endl; - skpt = ss.str(); + skpt = KListSymm::ibz_kpt_table(this->nkstot, this->kvec_d, this->ibz_index, kvec_d_ibz); ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Number of irreducible k-points", nkstot_ibz); - table.clear(); - table += "\n K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; - table += FmtCore::format("%8s%12s%12s%12s%8s%8s\n", "IBZ", "DIRECT_X", "DIRECT_Y", "DIRECT_Z", "WEIGHT", "ibz2bz"); - for (int ik = 0; ik < nkstot_ibz; ik++) - { - table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8.4f%8d\n", - ik + 1, - kvec_d_ibz[ik].x, - kvec_d_ibz[ik].y, - kvec_d_ibz[ik].z, - wk_ibz[ik], - ibz2bz[ik]); - } - GlobalV::ofs_running << table << std::endl; + GlobalV::ofs_running << KListSymm::ibz_wk_table(nkstot_ibz, kvec_d_ibz, wk_ibz, ibz2bz) << std::endl; // resize the kpoint container according to nkstot_ibz if (use_symm || this->get_is_mp()) diff --git a/source/source_io/module_dm/test/write_dmk_test.cpp b/source/source_io/module_dm/test/write_dmk_test.cpp index 02337304c0..4037c15480 100644 --- a/source/source_io/module_dm/test/write_dmk_test.cpp +++ b/source/source_io/module_dm/test/write_dmk_test.cpp @@ -1,3 +1,14 @@ +// Pre-include standard library headers pulled in by write_dmk.h so their +// include guards are already set when '#define private public' is active. +// Otherwise the macro corrupts / and the build fails with +// "'...__xfer_bufptrs' redeclared with different access". +#include +#include +#include +#include +#include +#include + #define private public #include "source_io/module_dm/write_dmk.h" #include "source_io/module_parameter/parameter.h" From b834529b6d40c21df2e3088b47b2e91eac65329b Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 09:53:40 +0800 Subject: [PATCH 05/22] fix(test): pre-include in write_dmk_test to unbreak CI The previous commit pre-included //... before '#define private public', but write_dmk.h reaches indirectly through global_variable.h -> -> bits/quoted_string.h. Without pre-included, quoted_string.h is first parsed while the 'private'/'public' macro is active, corrupting libstdc++ and failing CI with "'...__xfer_bufptrs' redeclared with different access". Pre-include as well so the whole chain is guard-protected before the macro is defined. Verified: cmake --build --target MODULE_IO_write_dmk (exit 0) and ctest -R MODULE_IO_write_dmk -> 2/2 passed in build_max_para_test. --- source/source_io/module_dm/test/write_dmk_test.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/source_io/module_dm/test/write_dmk_test.cpp b/source/source_io/module_dm/test/write_dmk_test.cpp index 4037c15480..606b195d52 100644 --- a/source/source_io/module_dm/test/write_dmk_test.cpp +++ b/source/source_io/module_dm/test/write_dmk_test.cpp @@ -1,7 +1,11 @@ -// Pre-include standard library headers pulled in by write_dmk.h so their -// include guards are already set when '#define private public' is active. -// Otherwise the macro corrupts / and the build fails with -// "'...__xfer_bufptrs' redeclared with different access". +// Pre-include every standard-library header reachable from write_dmk.h so +// their include guards are already set before '#define private public' is +// active. The macro renames the 'private'/'public' keywords, so any system +// header parsed while it is defined gets corrupted and the build fails with +// "'...__xfer_bufptrs' redeclared with different access". write_dmk.h pulls +// in indirectly via global_variable.h -> -> +// bits/quoted_string.h, so must be pre-included too. +#include #include #include #include From 4dd189997f7ffe06669a0fa19c9a7ea13f58b142 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 10:53:04 +0800 Subject: [PATCH 06/22] refactor(klist): extract this-free helpers into klist_io TU Move the IBZ table formatters and line-mode interpolation out of klist.cpp into a new source_cell/klist_io.{h,cpp} (namespace KListIO): - ibz_kpt_table / ibz_wk_table: pure string formatting, unchanged output. - interp_line: this-free line-mode interpolation returning LineK {kpts, segids, nks_total}; K_Vectors::interpolate_k_between becomes a thin wrapper that sizes members and copies results back. klist.cpp: 926 -> 830 lines, quality score 6 -> 12; klist_io.cpp scores 100. reduce_by_symmetry and parse_kfile lose their largest this-free blocks. CMake: klist_io.cpp added to the cell library; 16 test targets that compile klist.cpp without linking cell_info also register klist_io.cpp. Verified: cmake --build build_max_para_test -j30 (exit 0) and ctest -R "MODULE_CELL_(klist|reciprocal_grid|qlist)|MODULE_IO_...| MODULE_ESTATE_...|MODULE_HSOLVER_pw|MODULE_LCAO_deltaspin" -> 27/27. --- source/source_cell/CMakeLists.txt | 1 + source/source_cell/klist.cpp | 143 ++---------------- source/source_cell/klist_io.cpp | 140 +++++++++++++++++ source/source_cell/klist_io.h | 40 +++++ source/source_cell/test/CMakeLists.txt | 4 +- .../module_dm/test/CMakeLists.txt | 8 +- source/source_estate/test/CMakeLists.txt | 8 +- source/source_hsolver/test/CMakeLists.txt | 2 +- source/source_io/test/CMakeLists.txt | 10 +- source/source_io/test_serial/CMakeLists.txt | 2 +- .../module_deepks/test/CMakeLists.txt | 2 +- .../module_deltaspin/test/CMakeLists.txt | 4 +- source/source_lcao/test/CMakeLists.txt | 2 +- .../module_stodft/test/CMakeLists.txt | 2 +- 14 files changed, 214 insertions(+), 154 deletions(-) create mode 100644 source/source_cell/klist_io.cpp create mode 100644 source/source_cell/klist_io.h diff --git a/source/source_cell/CMakeLists.txt b/source/source_cell/CMakeLists.txt index 3c74e1cd4f..e568aa61c3 100644 --- a/source/source_cell/CMakeLists.txt +++ b/source/source_cell/CMakeLists.txt @@ -22,6 +22,7 @@ add_library( read_atoms_helper.cpp read_orb.cpp klist.cpp + klist_io.cpp reciprocal_grid.cpp parallel_kpoints.cpp cell_index.cpp diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 9a9aa0306a..835bad823f 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -4,77 +4,13 @@ */ #include "klist.h" +#include "klist_io.h" #include "source_base/formatter.h" #include "source_base/parallel_common.h" #include "source_base/parallel_global.h" #include "source_base/parallel_reduce.h" #include "source_cell/module_symmetry/symmetry.h" -// Free formatting helpers for the IBZ reduction tables. Defined in this -// file (not in a separate TU) because many test targets across the tree -// compile klist.cpp alone; a separate TU would need registering everywhere. -// Deliberately not static and not in an anonymous namespace. -namespace KListSymm -{ - -std::string ibz_kpt_table(const int nkstot, - const std::vector>& kvec_d, - const std::vector& ibz_index, - const std::vector>& kvec_d_ibz) -{ - std::stringstream ss; - ss << " " << std::setw(40) << "nkstot" - << " = " << nkstot << std::setw(66) << "ibzkpt" << std::endl; - std::string table; - table += "K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; - table += FmtCore::format("%8s%12s%12s%12s%8s%12s%12s%12s\n", - "KPT", - "DIRECT_X", - "DIRECT_Y", - "DIRECT_Z", - "IBZ", - "DIRECT_X", - "DIRECT_Y", - "DIRECT_Z"); - for (int i = 0; i < nkstot; ++i) - { - table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8d%12.8f%12.8f%12.8f\n", - i + 1, - kvec_d[i].x, - kvec_d[i].y, - kvec_d[i].z, - ibz_index[i] + 1, - kvec_d_ibz[ibz_index[i]].x, - kvec_d_ibz[ibz_index[i]].y, - kvec_d_ibz[ibz_index[i]].z); - } - ss << table << std::endl; - return ss.str(); -} - -std::string ibz_wk_table(const int nkstot_ibz, - const std::vector>& kvec_d_ibz, - const std::vector& wk_ibz, - const std::vector& ibz2bz) -{ - std::string table; - table += "\n K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; - table += FmtCore::format("%8s%12s%12s%12s%8s%8s\n", "IBZ", "DIRECT_X", "DIRECT_Y", "DIRECT_Z", "WEIGHT", "ibz2bz"); - for (int ik = 0; ik < nkstot_ibz; ik++) - { - table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8.4f%8d\n", - ik + 1, - kvec_d_ibz[ik].x, - kvec_d_ibz[ik].y, - kvec_d_ibz[ik].z, - wk_ibz[ik], - ibz2bz[ik]); - } - return table; -} - -} // namespace KListSymm - void K_Vectors::cal_ik_global() { const int my_pool = this->para_k.my_pool; @@ -509,75 +445,18 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) void K_Vectors::interpolate_k_between(std::ifstream& ifk, std::vector>& kvec) { - // how many special points. - int nks_special = this->nkstot; - - // number of points to the next k points - std::vector nkl(nks_special, 0); - - // coordinates of special points. - std::vector> ks(nks_special); - - // recalculate nkstot. - nkstot = 0; - /* ISSUE#3482: to distinguish different kline segments */ - std::vector kpt_segids; - kl_segids.clear(); - kl_segids.shrink_to_fit(); - int kpt_segid = 0; - for (int iks = 0; iks < nks_special; iks++) - { - ifk >> ks[iks].x; - ifk >> ks[iks].y; - ifk >> ks[iks].z; - ModuleBase::GlobalFunc::READ_VALUE(ifk, nkl[iks]); - - if (nkl[iks] <= 0) - { - ModuleBase::WARNING_QUIT("K_Vectors::interpolate_k_between", - "Line-mode interpolation counts must be positive."); - } - nkstot += nkl[iks]; - /* ISSUE#3482: to distinguish different kline segments */ - if ((nkl[iks] == 1) && (iks != (nks_special - 1))) { - kpt_segid++; - } - kpt_segids.push_back(kpt_segid); - } - if (nkl[nks_special - 1] != 1) - { - ModuleBase::WARNING_QUIT("K_Vectors::interpolate_k_between", - "The final line-mode k-point must have an interpolation count of 1."); - } + // Thin wrapper: the interpolation itself is the this-free KListIO::interp_line; + // here we only size the member containers and copy the results back. + const KListIO::LineK line = KListIO::interp_line(ifk, this->nkstot); - // std::cout << " nkstot = " << nkstot << std::endl; - this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 + this->nkstot = line.nks_total; + this->renew(this->nkstot * this->spin_mult); // mohan fix bug 2009-09-01 - int count = 0; - for (int iks = 1; iks < nks_special; iks++) + for (int i = 0; i < this->nkstot; i++) { - double dxs = (ks[iks].x - ks[iks - 1].x) / nkl[iks - 1]; - double dys = (ks[iks].y - ks[iks - 1].y) / nkl[iks - 1]; - double dzs = (ks[iks].z - ks[iks - 1].z) / nkl[iks - 1]; - for (int is = 0; is < nkl[iks - 1]; is++) - { - kvec[count].x = ks[iks - 1].x + is * dxs; - kvec[count].y = ks[iks - 1].y + is * dys; - kvec[count].z = ks[iks - 1].z + is * dzs; - kl_segids.push_back(kpt_segids[iks - 1]); /* ISSUE#3482: to distinguish different kline segments */ - ++count; - } + kvec[i] = line.kpts[i]; } - - // deal with the last special k point. - kvec[count].x = ks[nks_special - 1].x; - kvec[count].y = ks[nks_special - 1].y; - kvec[count].z = ks[nks_special - 1].z; - kl_segids.push_back(kpt_segids[nks_special - 1]); /* ISSUE#3482: to distinguish different kline segments */ - ++count; - - assert(count == nkstot); - assert(kl_segids.size() == nkstot); /* ISSUE#3482: to distinguish different kline segments */ + this->kl_segids = line.segids; /* ISSUE#3482: to distinguish different kline segments */ } void K_Vectors::update_use_ibz(const int& nkstot_ibz, @@ -776,10 +655,10 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, #endif // output in kpoints file - skpt = KListSymm::ibz_kpt_table(this->nkstot, this->kvec_d, this->ibz_index, kvec_d_ibz); + skpt = KListIO::ibz_kpt_table(this->nkstot, this->kvec_d, this->ibz_index, kvec_d_ibz); ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Number of irreducible k-points", nkstot_ibz); - GlobalV::ofs_running << KListSymm::ibz_wk_table(nkstot_ibz, kvec_d_ibz, wk_ibz, ibz2bz) << std::endl; + GlobalV::ofs_running << KListIO::ibz_wk_table(nkstot_ibz, kvec_d_ibz, wk_ibz, ibz2bz) << std::endl; // resize the kpoint container according to nkstot_ibz if (use_symm || this->get_is_mp()) diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp new file mode 100644 index 0000000000..c755365278 --- /dev/null +++ b/source/source_cell/klist_io.cpp @@ -0,0 +1,140 @@ +/** + * @file klist_io.cpp + * @brief this-free helpers extracted from K_Vectors (IBZ table formatting and + * line-mode k-point interpolation). Kept separate from klist.cpp so the + * logic is testable in isolation; klist.cpp only keeps thin wrappers. + */ +#include "klist_io.h" + +#include "source_base/formatter.h" +#include "source_base/global_function.h" + +#include + +namespace KListIO +{ + +std::string ibz_kpt_table(const int nkstot, + const std::vector>& kvec_d, + const std::vector& ibz_index, + const std::vector>& kvec_d_ibz) +{ + std::stringstream ss; + ss << " " << std::setw(40) << "nkstot" + << " = " << nkstot << std::setw(66) << "ibzkpt" << std::endl; + std::string table; + table += "K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; + table += FmtCore::format("%8s%12s%12s%12s%8s%12s%12s%12s\n", + "KPT", + "DIRECT_X", + "DIRECT_Y", + "DIRECT_Z", + "IBZ", + "DIRECT_X", + "DIRECT_Y", + "DIRECT_Z"); + for (int i = 0; i < nkstot; ++i) + { + table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8d%12.8f%12.8f%12.8f\n", + i + 1, + kvec_d[i].x, + kvec_d[i].y, + kvec_d[i].z, + ibz_index[i] + 1, + kvec_d_ibz[ibz_index[i]].x, + kvec_d_ibz[ibz_index[i]].y, + kvec_d_ibz[ibz_index[i]].z); + } + ss << table << std::endl; + return ss.str(); +} + +std::string ibz_wk_table(const int nkstot_ibz, + const std::vector>& kvec_d_ibz, + const std::vector& wk_ibz, + const std::vector& ibz2bz) +{ + std::string table; + table += "\n K-POINTS REDUCTION ACCORDING TO SYMMETRY\n"; + table += FmtCore::format("%8s%12s%12s%12s%8s%8s\n", "IBZ", "DIRECT_X", "DIRECT_Y", "DIRECT_Z", "WEIGHT", "ibz2bz"); + for (int ik = 0; ik < nkstot_ibz; ik++) + { + table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8.4f%8d\n", + ik + 1, + kvec_d_ibz[ik].x, + kvec_d_ibz[ik].y, + kvec_d_ibz[ik].z, + wk_ibz[ik], + ibz2bz[ik]); + } + return table; +} + +LineK interp_line(std::ifstream& ifk, const int nks_special) +{ + // number of points to the next k points + std::vector nkl(nks_special, 0); + + // coordinates of special points. + std::vector> ks(nks_special); + + LineK out; + std::vector kpt_segids; + int kpt_segid = 0; + for (int iks = 0; iks < nks_special; iks++) + { + ifk >> ks[iks].x; + ifk >> ks[iks].y; + ifk >> ks[iks].z; + ModuleBase::GlobalFunc::READ_VALUE(ifk, nkl[iks]); + + if (nkl[iks] <= 0) + { + ModuleBase::WARNING_QUIT("KListIO::interp_line", + "Line-mode interpolation counts must be positive."); + } + out.nks_total += nkl[iks]; + /* ISSUE#3482: to distinguish different kline segments */ + if ((nkl[iks] == 1) && (iks != (nks_special - 1))) { + kpt_segid++; + } + kpt_segids.push_back(kpt_segid); + } + if (nkl[nks_special - 1] != 1) + { + ModuleBase::WARNING_QUIT("KListIO::interp_line", + "The final line-mode k-point must have an interpolation count of 1."); + } + + out.kpts.resize(out.nks_total); + out.segids.reserve(out.nks_total); + + int count = 0; + for (int iks = 1; iks < nks_special; iks++) + { + double dxs = (ks[iks].x - ks[iks - 1].x) / nkl[iks - 1]; + double dys = (ks[iks].y - ks[iks - 1].y) / nkl[iks - 1]; + double dzs = (ks[iks].z - ks[iks - 1].z) / nkl[iks - 1]; + for (int is = 0; is < nkl[iks - 1]; is++) + { + out.kpts[count].x = ks[iks - 1].x + is * dxs; + out.kpts[count].y = ks[iks - 1].y + is * dys; + out.kpts[count].z = ks[iks - 1].z + is * dzs; + out.segids.push_back(kpt_segids[iks - 1]); /* ISSUE#3482 */ + ++count; + } + } + + // deal with the last special k point. + out.kpts[count].x = ks[nks_special - 1].x; + out.kpts[count].y = ks[nks_special - 1].y; + out.kpts[count].z = ks[nks_special - 1].z; + out.segids.push_back(kpt_segids[nks_special - 1]); /* ISSUE#3482 */ + ++count; + + assert(count == out.nks_total); + assert(out.segids.size() == static_cast(out.nks_total)); /* ISSUE#3482 */ + return out; +} + +} // namespace KListIO diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h new file mode 100644 index 0000000000..9e36b1899a --- /dev/null +++ b/source/source_cell/klist_io.h @@ -0,0 +1,40 @@ +#ifndef KLIST_IO_H +#define KLIST_IO_H + +#include "source_base/vector3.h" + +#include +#include +#include + +/// this-free helpers extracted from K_Vectors, kept in a separate TU so they +/// can be unit-tested and reused without dragging in the K_Vectors class. +namespace KListIO +{ +/// Render the IBZ reduction table ("IBZ" k-point -> originating k-point). +std::string ibz_kpt_table(int nkstot, + const std::vector>& kvec_d, + const std::vector& ibz_index, + const std::vector>& kvec_d_ibz); + +/// Render the IBZ weight table (IBZ k-point, weight, multiplicity, origin index). +std::string ibz_wk_table(int nkstot_ibz, + const std::vector>& kvec_d_ibz, + const std::vector& wk_ibz, + const std::vector& ibz2bz); + +/// Result of line-mode interpolation between special k-points. +struct LineK +{ + std::vector> kpts; ///< interpolated k points + std::vector segids; ///< segment id per k point (ISSUE#3482) + int nks_total = 0; ///< total interpolated k-point count +}; + +/// Read the special k points and per-point interpolation counts from `ifk`, +/// then linearly interpolate the line-mode k points. Pure function of the +/// stream and `nks_special`; dies via WARNING_QUIT on malformed input. +LineK interp_line(std::ifstream& ifk, int nks_special); +} // namespace KListIO + +#endif // KLIST_IO_H diff --git a/source/source_cell/test/CMakeLists.txt b/source/source_cell/test/CMakeLists.txt index caab63da4a..653eaa6d3f 100644 --- a/source/source_cell/test/CMakeLists.txt +++ b/source/source_cell/test/CMakeLists.txt @@ -86,7 +86,7 @@ AddTest( AddTest( TARGET MODULE_CELL_klist_test LIBS base device symmetry - SOURCES klist_test.cpp ../klist.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp + SOURCES klist_test.cpp ../klist.cpp ../klist_io.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp ) AddTest( @@ -110,7 +110,7 @@ AddTest( AddTest( TARGET MODULE_CELL_klist_test_para1 LIBS base device symmetry - SOURCES klist_test_para.cpp ../klist.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp + SOURCES klist_test_para.cpp ../klist.cpp ../klist_io.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp ) add_test(NAME MODULE_CELL_klist_test_para4 diff --git a/source/source_estate/module_dm/test/CMakeLists.txt b/source/source_estate/module_dm/test/CMakeLists.txt index 1d96186fbe..d5e8c19c3a 100644 --- a/source/source_estate/module_dm/test/CMakeLists.txt +++ b/source/source_estate/module_dm/test/CMakeLists.txt @@ -16,7 +16,7 @@ AddTest( ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/hcontainer.cpp ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/atom_pair.cpp ${ABACUS_SOURCE_DIR}/source_basis/module_ao/parallel_orbitals.cpp - ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp + ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp ${ABACUS_SOURCE_DIR}/source_cell/klist_io.cpp ${ABACUS_SOURCE_DIR}/source_cell/parallel_kpoints.cpp ${ABACUS_SOURCE_DIR}/source_cell/reciprocal_grid.cpp @@ -30,7 +30,7 @@ AddTest( ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/hcontainer.cpp ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/atom_pair.cpp ${ABACUS_SOURCE_DIR}/source_basis/module_ao/parallel_orbitals.cpp - ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp + ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp ${ABACUS_SOURCE_DIR}/source_cell/klist_io.cpp ${ABACUS_SOURCE_DIR}/source_cell/parallel_kpoints.cpp ${ABACUS_SOURCE_DIR}/source_cell/reciprocal_grid.cpp ) @@ -43,7 +43,7 @@ AddTest( ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/hcontainer.cpp ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/atom_pair.cpp ${ABACUS_SOURCE_DIR}/source_basis/module_ao/parallel_orbitals.cpp - ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp + ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp ${ABACUS_SOURCE_DIR}/source_cell/klist_io.cpp ${ABACUS_SOURCE_DIR}/source_cell/parallel_kpoints.cpp ${ABACUS_SOURCE_DIR}/source_cell/reciprocal_grid.cpp ) @@ -56,7 +56,7 @@ AddTest( ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/hcontainer.cpp ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/atom_pair.cpp ${ABACUS_SOURCE_DIR}/source_basis/module_ao/parallel_orbitals.cpp - ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp + ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp ${ABACUS_SOURCE_DIR}/source_cell/klist_io.cpp ${ABACUS_SOURCE_DIR}/source_cell/parallel_kpoints.cpp ${ABACUS_SOURCE_DIR}/source_cell/reciprocal_grid.cpp ) diff --git a/source/source_estate/test/CMakeLists.txt b/source/source_estate/test/CMakeLists.txt index 1eaaa0c6bc..96c84ceeac 100644 --- a/source/source_estate/test/CMakeLists.txt +++ b/source/source_estate/test/CMakeLists.txt @@ -33,7 +33,7 @@ AddTest( TARGET MODULE_ESTATE_elecstate_print LIBS parameter base device symmetry SOURCES elecstate_print_test.cpp ../elecstate_print.cpp ../occupy.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( @@ -41,7 +41,7 @@ AddTest( LIBS parameter base device symmetry SOURCES elecstate_base_test.cpp ../elecstate.cpp ../elecstate_tools.cpp ../occupy.cpp ../../source_psi/psi.cpp ../../source_base/module_fft/fft_bundle.cpp ../../source_base/module_fft/fft_cpu.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( @@ -57,7 +57,7 @@ AddTest( ../../source_lcao/module_deltaspin/deltaspin_state.cpp ../../source_psi/psi.cpp ../../source_base/module_device/memory_op.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( @@ -68,7 +68,7 @@ AddTest( ../fp_energy.cpp ../makov_payne.cpp ../module_pot/h_hartree_pw.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( diff --git a/source/source_hsolver/test/CMakeLists.txt b/source/source_hsolver/test/CMakeLists.txt index 72a2de07b1..96895a504e 100644 --- a/source/source_hsolver/test/CMakeLists.txt +++ b/source/source_hsolver/test/CMakeLists.txt @@ -78,7 +78,7 @@ if (ENABLE_MPI) LIBS parameter psi device base container symmetry SOURCES test_hsolver_pw.cpp ../hsolver_pw.cpp ../hsolver_lcaopw.cpp ../diago_bpcg.cpp ../diago_dav_subspace.cpp ../diag_const_nums.cpp ../diago_iter_assist.cpp ../para_lin_tf.cpp ../../source_estate/elecstate_tools.cpp ../../source_estate/occupy.cpp ../../source_base/module_fft/fft_bundle.cpp ../../source_base/module_fft/fft_cpu.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( diff --git a/source/source_io/test/CMakeLists.txt b/source/source_io/test/CMakeLists.txt index 4385b04dab..b93bd463be 100644 --- a/source/source_io/test/CMakeLists.txt +++ b/source/source_io/test/CMakeLists.txt @@ -63,7 +63,7 @@ add_test( AddTest( TARGET MODULE_IO_write_eig_occ_test LIBS parameter base device symmetry - SOURCES write_eig_occ_test.cpp ../module_output/band_parallel_output.cpp ../module_energy/write_eig_occ.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/klist.cpp + SOURCES write_eig_occ_test.cpp ../module_output/band_parallel_output.cpp ../module_energy/write_eig_occ.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/cif_io.cpp ../../source_cell/reciprocal_grid.cpp ) @@ -76,13 +76,13 @@ AddTest( AddTest( TARGET MODULE_IO_write_dos_pw LIBS parameter base device symmetry - SOURCES write_dos_pw_test.cpp ../module_dos/cal_dos.cpp ../module_dos/write_dos_pw.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/klist.cpp ../module_energy/nscf_fermi_surf.cpp ../../source_cell/reciprocal_grid.cpp + SOURCES write_dos_pw_test.cpp ../module_dos/cal_dos.cpp ../module_dos/write_dos_pw.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../module_energy/nscf_fermi_surf.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( TARGET MODULE_IO_print_info LIBS parameter base device symmetry cell_info - SOURCES print_info_test.cpp ../module_output/print_info.cpp ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + SOURCES print_info_test.cpp ../module_output/print_info.cpp ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( @@ -177,7 +177,7 @@ AddTest( TARGET MODULE_IO_read_wf2rho_pw_test LIBS parameter base device planewave psi symmetry SOURCES read_wf2rho_pw_test.cpp ../module_wf/read_wfc_pw.cpp ../module_wf/read_wf2rho_pw.cpp ../../source_basis/module_pw/test/test_tool.cpp ../../source_estate/module_charge/charge_mpi.cpp ../module_wf/write_wfc_pw.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) add_test(NAME MODULE_IO_read_wf2rho_pw_parallel @@ -232,7 +232,7 @@ AddTest( TARGET MODULE_IO_write_dmk LIBS parameter base device cell_info symmetry SOURCES ../module_dm/test/write_dmk_test.cpp ../module_dm/write_dmk.cpp ../../source_cell/ucell_io.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) add_test( diff --git a/source/source_io/test_serial/CMakeLists.txt b/source/source_io/test_serial/CMakeLists.txt index aa7fec69f4..dd87df580c 100644 --- a/source/source_io/test_serial/CMakeLists.txt +++ b/source/source_io/test_serial/CMakeLists.txt @@ -58,7 +58,7 @@ AddTest( TARGET MODULE_IO_write_bands LIBS parameter base device symmetry SOURCES write_bands_test.cpp ../module_output/band_parallel_output.cpp ../module_energy/write_bands.cpp - ../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp + ../../source_cell/klist.cpp ../../source_cell/klist_io.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp ) AddTest( diff --git a/source/source_lcao/module_deepks/test/CMakeLists.txt b/source/source_lcao/module_deepks/test/CMakeLists.txt index df699495f9..15cca5c62d 100644 --- a/source/source_lcao/module_deepks/test/CMakeLists.txt +++ b/source/source_lcao/module_deepks/test/CMakeLists.txt @@ -25,7 +25,7 @@ set(DEEPKS_UNIT_COMMON_SOURCES ../../../source_cell/read_stru.cpp ../../../source_cell/print_cell.cpp ../../../source_cell/read_atom_species.cpp - ../../../source_cell/klist.cpp + ../../../source_cell/klist.cpp ../../../source_cell/klist_io.cpp ../../../source_cell/parallel_kpoints.cpp ../../../source_cell/reciprocal_grid.cpp ../../setup_nonlocal.cpp diff --git a/source/source_lcao/module_deltaspin/test/CMakeLists.txt b/source/source_lcao/module_deltaspin/test/CMakeLists.txt index a3bac8f9ee..9fad70e2bc 100644 --- a/source/source_lcao/module_deltaspin/test/CMakeLists.txt +++ b/source/source_lcao/module_deltaspin/test/CMakeLists.txt @@ -16,7 +16,7 @@ AddTest( ../spin_constrain.cpp ../deltaspin_state.cpp ../../../source_basis/module_ao/parallel_orbitals.cpp - ../../../source_cell/klist.cpp + ../../../source_cell/klist.cpp ../../../source_cell/klist_io.cpp ../../../source_cell/parallel_kpoints.cpp ../../../source_cell/reciprocal_grid.cpp ) @@ -30,7 +30,7 @@ AddTest( ../template_helpers.cpp ../lambda_loop_helper.cpp ../basic_funcs.cpp - ../../../source_cell/klist.cpp + ../../../source_cell/klist.cpp ../../../source_cell/klist_io.cpp ../../../source_cell/parallel_kpoints.cpp ../../../source_cell/reciprocal_grid.cpp ) diff --git a/source/source_lcao/test/CMakeLists.txt b/source/source_lcao/test/CMakeLists.txt index 1971ea0b05..8f5d6a1aee 100644 --- a/source/source_lcao/test/CMakeLists.txt +++ b/source/source_lcao/test/CMakeLists.txt @@ -21,7 +21,7 @@ AddTest( ${ABACUS_SOURCE_DIR}/source_io/module_dm/write_dmr.cpp ${ABACUS_SOURCE_DIR}/source_cell/ucell_io.cpp ${ABACUS_SOURCE_DIR}/source_hamilt/module_hcontainer/output_hcontainer.cpp - ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp + ${ABACUS_SOURCE_DIR}/source_cell/klist.cpp ${ABACUS_SOURCE_DIR}/source_cell/klist_io.cpp ${ABACUS_SOURCE_DIR}/source_cell/parallel_kpoints.cpp ${ABACUS_SOURCE_DIR}/source_cell/reciprocal_grid.cpp ) diff --git a/source/source_pw/module_stodft/test/CMakeLists.txt b/source/source_pw/module_stodft/test/CMakeLists.txt index c025b78955..836a1ac7dc 100644 --- a/source/source_pw/module_stodft/test/CMakeLists.txt +++ b/source/source_pw/module_stodft/test/CMakeLists.txt @@ -10,5 +10,5 @@ AddTest( TARGET MODULE_PW_Sto_Hamilt_UTs LIBS parameter psi base device planewave_serial symmetry SOURCES ../hamilt_sdft_pw.cpp test_hamilt_sto.cpp ../../../source_hamilt/operator.cpp - ../../../source_cell/klist.cpp ../../../source_cell/parallel_kpoints.cpp ../../../source_cell/reciprocal_grid.cpp + ../../../source_cell/klist.cpp ../../../source_cell/klist_io.cpp ../../../source_cell/parallel_kpoints.cpp ../../../source_cell/reciprocal_grid.cpp ) \ No newline at end of file From 25c3156f0e117e0f13395fd643d844465af3b0f9 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 11:18:21 +0800 Subject: [PATCH 07/22] refactor(klist): extract EXX k-stars build into KListIO::build_kstars Move the this-free triple loop that groups k points into EXX k-stars out of K_Vectors::reduce_by_symmetry into KListIO::build_kstars. The symmetry comparison is passed in as a std::function so klist_io.cpp does not depend on the Symmetry header; k restriction uses ModuleCell::restrict_kpt. Behavior is unchanged for symm_flag==1 (the only path that reaches this code). klist.cpp drops ~20 lines; the loop is now isolated and testable. Verified: cmake --build build_max_para_test -j30 (exit 0, __EXX on) and ctest -R "MODULE_CELL_(klist|reciprocal_grid|qlist)" -> 5/5. --- source/source_cell/klist.cpp | 34 ++++++--------------------- source/source_cell/klist_io.cpp | 41 +++++++++++++++++++++++++++++++++ source/source_cell/klist_io.h | 16 +++++++++++++ 3 files changed, 64 insertions(+), 27 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 835bad823f..7e0c94b07d 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -622,35 +622,15 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, #ifdef __EXX // setup kstars according to the final (max-norm) kvec_d_ibz - this->kstars.resize(nkstot_ibz); if (ModuleSymmetry::Symmetry::symm_flag == 1) { - ModuleBase::Vector3 kvec_rot; - for (int i = 0; i < this->nkstot; ++i) - { - int exist_number = -1; - int isym = 0; - for (int j = 0; j < nrotkm; ++j) - { - kvec_rot = this->kvec_d[i] * kgmatrix[j]; - ModuleCell::restrict_kpt(kvec_rot, symm.epsilon); - for (int k = 0; k < nkstot_ibz; ++k) - { - if (symm.equal(kvec_rot.x, kvec_d_ibz[k].x) && symm.equal(kvec_rot.y, kvec_d_ibz[k].y) - && symm.equal(kvec_rot.z, kvec_d_ibz[k].z)) - { - isym = j; - exist_number = k; - break; - } - } - if (exist_number != -1) - { - break; - } - } - this->kstars[exist_number].insert(std::make_pair(isym, this->kvec_d[i])); - } + KListIO::build_kstars(this->kvec_d, + kgmatrix, + nrotkm, + kvec_d_ibz, + symm.epsilon, + [&symm](double a, double b) { return symm.equal(a, b); }, + this->kstars); } #endif diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index c755365278..863bf65b6e 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -8,6 +8,7 @@ #include "source_base/formatter.h" #include "source_base/global_function.h" +#include "source_cell/reciprocal_grid.h" #include @@ -137,4 +138,44 @@ LineK interp_line(std::ifstream& ifk, const int nks_special) return out; } +void build_kstars(const std::vector>& kvec_d, + const std::vector& kgmatrix, + const int nrotkm, + const std::vector>& kvec_d_ibz, + const double epsilon, + const std::function& equal, + std::vector>>& kstars) +{ + const int nkstot = static_cast(kvec_d.size()); + const int nkstot_ibz = static_cast(kvec_d_ibz.size()); + kstars.resize(nkstot_ibz); + + ModuleBase::Vector3 kvec_rot; + for (int i = 0; i < nkstot; ++i) + { + int exist_number = -1; + int isym = 0; + for (int j = 0; j < nrotkm; ++j) + { + kvec_rot = kvec_d[i] * kgmatrix[j]; + ModuleCell::restrict_kpt(kvec_rot, epsilon); + for (int k = 0; k < nkstot_ibz; ++k) + { + if (equal(kvec_rot.x, kvec_d_ibz[k].x) && equal(kvec_rot.y, kvec_d_ibz[k].y) + && equal(kvec_rot.z, kvec_d_ibz[k].z)) + { + isym = j; + exist_number = k; + break; + } + } + if (exist_number != -1) + { + break; + } + } + kstars[exist_number].insert(std::make_pair(isym, kvec_d[i])); + } +} + } // namespace KListIO diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index 9e36b1899a..d7ae801446 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -1,9 +1,12 @@ #ifndef KLIST_IO_H #define KLIST_IO_H +#include "source_base/matrix3.h" #include "source_base/vector3.h" #include +#include +#include #include #include @@ -35,6 +38,19 @@ struct LineK /// then linearly interpolate the line-mode k points. Pure function of the /// stream and `nks_special`; dies via WARNING_QUIT on malformed input. LineK interp_line(std::ifstream& ifk, int nks_special); + +/// Build the EXX k-stars: for every k point, find the symmetry operation +/// (index into `kgmatrix`) that rotates it onto an irreducible k point, and +/// group k points by that IBZ representative. `equal` compares two doubles +/// with the symmetry precision; `epsilon` is the k-restriction tolerance. +/// this-free so the heavy triple loop is isolated and testable. +void build_kstars(const std::vector>& kvec_d, + const std::vector& kgmatrix, + int nrotkm, + const std::vector>& kvec_d_ibz, + double epsilon, + const std::function& equal, + std::vector>>& kstars); } // namespace KListIO #endif // KLIST_IO_H From 3eaeb982fbc07a4e791a89b140f66e0146593083 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 11:20:58 +0800 Subject: [PATCH 08/22] fix(Makefile): add missing klist_io.o to OBJS_CELL The this-free helpers extracted into source_cell/klist_io.cpp are referenced by klist.cpp, but the Makefile object list was not updated when the CMake build gained the new TU, breaking the Makefile link with undefined references to KListIO::ibz_kpt_table/ibz_wk_table/interp_line. --- source/Makefile.Objects | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Makefile.Objects b/source/Makefile.Objects index 7104d8a62e..d3da386f1c 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -211,6 +211,7 @@ OBJS_CELL=atom_pseudo.o\ print_cell.o\ setup_nonlocal.o\ klist.o\ + klist_io.o\ reciprocal_grid.o\ cell_index.o\ cell_tools.o\ From bee21a31bee3eda1ae95702bf0a56c9069711c0f Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 11:21:48 +0800 Subject: [PATCH 09/22] refactor(klist): extract MPI k-point pack/unpack into KListIO Move the this-free flatten/scatter loops in K_Vectors::mpi_k into KListIO::pack_kpts (rank-0 -> contiguous broadcast buffers) and KListIO::unpack_kpts (broadcast buffers -> this pool's k-point slice). mpi_k keeps the broadcast calls and the renew/distribute orchestration. pack_kpts sizes the kvec_c_full copy from the vector length so the full grid is handled independently of nkstot. Verified: cmake --build build_max_para_test -j30 (exit 0, __MPI on) and ctest -R "MODULE_CELL_(klist|reciprocal_grid|qlist)" -> 5/5 (covers the para1/para4 mpi_k paths). --- source/source_cell/klist.cpp | 55 ++++++++++++---------------- source/source_cell/klist_io.cpp | 63 +++++++++++++++++++++++++++++++++ source/source_cell/klist_io.h | 29 +++++++++++++++ 3 files changed, 115 insertions(+), 32 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 7e0c94b07d..62c1eee0ca 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -727,20 +727,17 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) // collect and process in rank 0 if (GlobalV::MY_RANK == 0) { - for (int ik = 0; ik < this->nkstot; ik++) - { - isk_aux[ik] = this->isk[ik]; - wk_aux[ik] = this->wk[ik]; - kvec_c_aux[3 * ik] = this->kvec_c[ik].x; - kvec_c_aux[3 * ik + 1] = this->kvec_c[ik].y; - kvec_c_aux[3 * ik + 2] = this->kvec_c[ik].z; - kvec_d_aux[3 * ik] = this->kvec_d[ik].x; - kvec_d_aux[3 * ik + 1] = this->kvec_d[ik].y; - kvec_d_aux[3 * ik + 2] = this->kvec_d[ik].z; - kvec_c_full_aux[3 * ik] = this->kvec_c_full[ik].x; - kvec_c_full_aux[3 * ik + 1] = this->kvec_c_full[ik].y; - kvec_c_full_aux[3 * ik + 2] = this->kvec_c_full[ik].z; - } + KListIO::pack_kpts(this->isk, + this->wk, + this->kvec_c, + this->kvec_d, + this->kvec_c_full, + this->nkstot, + isk_aux, + wk_aux, + kvec_c_aux, + kvec_d_aux, + kvec_c_full_aux); } // broadcast k point data to all processors @@ -755,24 +752,18 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) this->renew(this->nks * this->spin_mult); // distribute - int k_index = 0; - - for (int i = 0; i < this->nks; i++) - { - // 3 is because each k point has three value:kx, ky, kz - k_index = i + this->para_k.startk_pool[GlobalV::MY_POOL]; - this->kvec_c[i].x = kvec_c_aux[k_index * 3]; - this->kvec_c[i].y = kvec_c_aux[k_index * 3 + 1]; - this->kvec_c[i].z = kvec_c_aux[k_index * 3 + 2]; - this->kvec_d[i].x = kvec_d_aux[k_index * 3]; - this->kvec_d[i].y = kvec_d_aux[k_index * 3 + 1]; - this->kvec_d[i].z = kvec_d_aux[k_index * 3 + 2]; - this->kvec_c_full[i].x = kvec_c_full_aux[k_index * 3]; - this->kvec_c_full[i].y = kvec_c_full_aux[k_index * 3 + 1]; - this->kvec_c_full[i].z = kvec_c_full_aux[k_index * 3 + 2]; - this->wk[i] = wk_aux[k_index]; - this->isk[i] = isk_aux[k_index]; - } + KListIO::unpack_kpts(isk_aux, + wk_aux, + kvec_c_aux, + kvec_d_aux, + kvec_c_full_aux, + this->nks, + this->para_k.startk_pool[GlobalV::MY_POOL], + this->isk, + this->wk, + this->kvec_c, + this->kvec_d, + this->kvec_c_full); #ifdef __EXX if (ModuleSymmetry::Symmetry::symm_flag == 1) diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index 863bf65b6e..b32886fe50 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -178,4 +178,67 @@ void build_kstars(const std::vector>& kvec_d, } } +void pack_kpts(const std::vector& isk, + const std::vector& wk, + const std::vector>& kvec_c, + const std::vector>& kvec_d, + const std::vector>& kvec_c_full, + const int nkstot, + std::vector& isk_aux, + std::vector& wk_aux, + std::vector& kvec_c_aux, + std::vector& kvec_d_aux, + std::vector& kvec_c_full_aux) +{ + for (int ik = 0; ik < nkstot; ik++) + { + isk_aux[ik] = isk[ik]; + wk_aux[ik] = wk[ik]; + kvec_c_aux[3 * ik] = kvec_c[ik].x; + kvec_c_aux[3 * ik + 1] = kvec_c[ik].y; + kvec_c_aux[3 * ik + 2] = kvec_c[ik].z; + kvec_d_aux[3 * ik] = kvec_d[ik].x; + kvec_d_aux[3 * ik + 1] = kvec_d[ik].y; + kvec_d_aux[3 * ik + 2] = kvec_d[ik].z; + } + const int nkstot_full = static_cast(kvec_c_full.size()); + for (int ik = 0; ik < nkstot_full; ik++) + { + kvec_c_full_aux[3 * ik] = kvec_c_full[ik].x; + kvec_c_full_aux[3 * ik + 1] = kvec_c_full[ik].y; + kvec_c_full_aux[3 * ik + 2] = kvec_c_full[ik].z; + } +} + +void unpack_kpts(const std::vector& isk_aux, + const std::vector& wk_aux, + const std::vector& kvec_c_aux, + const std::vector& kvec_d_aux, + const std::vector& kvec_c_full_aux, + const int nks, + const int startk, + std::vector& isk, + std::vector& wk, + std::vector>& kvec_c, + std::vector>& kvec_d, + std::vector>& kvec_c_full) +{ + for (int i = 0; i < nks; i++) + { + // 3 is because each k point has three value:kx, ky, kz + const int k_index = i + startk; + kvec_c[i].x = kvec_c_aux[k_index * 3]; + kvec_c[i].y = kvec_c_aux[k_index * 3 + 1]; + kvec_c[i].z = kvec_c_aux[k_index * 3 + 2]; + kvec_d[i].x = kvec_d_aux[k_index * 3]; + kvec_d[i].y = kvec_d_aux[k_index * 3 + 1]; + kvec_d[i].z = kvec_d_aux[k_index * 3 + 2]; + kvec_c_full[i].x = kvec_c_full_aux[k_index * 3]; + kvec_c_full[i].y = kvec_c_full_aux[k_index * 3 + 1]; + kvec_c_full[i].z = kvec_c_full_aux[k_index * 3 + 2]; + wk[i] = wk_aux[k_index]; + isk[i] = isk_aux[k_index]; + } +} + } // namespace KListIO diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index d7ae801446..5a0b0bbdb4 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -51,6 +51,35 @@ void build_kstars(const std::vector>& kvec_d, double epsilon, const std::function& equal, std::vector>>& kstars); + +/// Flatten k-point arrays into contiguous MPI buffers (x,y,z interleaved). +/// this-free; used on rank 0 before broadcasting in K_Vectors::mpi_k. +void pack_kpts(const std::vector& isk, + const std::vector& wk, + const std::vector>& kvec_c, + const std::vector>& kvec_d, + const std::vector>& kvec_c_full, + int nkstot, + std::vector& isk_aux, + std::vector& wk_aux, + std::vector& kvec_c_aux, + std::vector& kvec_d_aux, + std::vector& kvec_c_full_aux); + +/// Scatter the broadcast buffers into this pool's k-point slice, starting at +/// global index `startk`. this-free; mirrors pack_kpts after the broadcast. +void unpack_kpts(const std::vector& isk_aux, + const std::vector& wk_aux, + const std::vector& kvec_c_aux, + const std::vector& kvec_d_aux, + const std::vector& kvec_c_full_aux, + int nks, + int startk, + std::vector& isk, + std::vector& wk, + std::vector>& kvec_c, + std::vector>& kvec_d, + std::vector>& kvec_c_full); } // namespace KListIO #endif // KLIST_IO_H From 919c56058179ecd459df0dceca00641874bfc84e Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 11:28:51 +0800 Subject: [PATCH 10/22] refactor(klist): pass ofs_warning into generate_kfile Remove the GlobalV::ofs_warning dependency from K_Vectors::generate_kfile by taking the stream as a parameter; the single caller (read_kpoints) passes GlobalV::ofs_warning. Private signature only, no public interface change. global_dependency count in klist.cpp drops by 2. Verified: cmake --build build_max_para_test -j30 (exit 0) and ctest -R "MODULE_CELL_(klist|reciprocal_grid|qlist)" -> 5/5. --- source/source_cell/klist.cpp | 9 +++++---- source/source_cell/klist.h | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 62c1eee0ca..41a06fa4c5 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -225,7 +225,7 @@ bool K_Vectors::read_kpoints(const UnitCell& ucell, // 1. Overwrite the KPT file and default K-point information if needed // mohan add 2010-09-04 - this->generate_kfile(ucell, fn, gamma_only_local, kspacing, kmesh_type, koffset); + this->generate_kfile(ucell, fn, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_warning); // 2. Read the KPT file and build the k-point list return this->parse_kfile(fn, ofs_running); @@ -236,11 +236,12 @@ void K_Vectors::generate_kfile(const UnitCell& ucell, const bool gamma_only_local, const double kspacing[3], const std::string& kmesh_type, - const double koffset[3]) + const double koffset[3], + std::ofstream& ofs_warning) { if (gamma_only_local) { - GlobalV::ofs_warning << " Auto generating k-points file: " << fn << std::endl; + ofs_warning << " Auto generating k-points file: " << fn << std::endl; std::ofstream ofs(fn.c_str()); ofs << "K_POINTS" << std::endl; ofs << "0" << std::endl; @@ -263,7 +264,7 @@ void K_Vectors::generate_kfile(const UnitCell& ucell, int nk2 = std::max(1, static_cast(b2 * ModuleBase::TWO_PI / kspacing[1] / ucell.lat0 + 1)); int nk3 = std::max(1, static_cast(b3 * ModuleBase::TWO_PI / kspacing[2] / ucell.lat0 + 1)); - GlobalV::ofs_warning << " Generate k-points file according to KSPACING: " << fn << std::endl; + ofs_warning << " Generate k-points file according to KSPACING: " << fn << std::endl; std::ofstream ofs(fn.c_str()); ofs << "K_POINTS" << std::endl; ofs << "0" << std::endl; diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index d75acbc085..0d40160f87 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -256,7 +256,8 @@ class K_Vectors : public ModuleCell::ReciprocalGrid const bool gamma_only_local, const double kspacing[3], const std::string& kmesh_type, - const double koffset[3]); + const double koffset[3], + std::ofstream& ofs_warning); /** * @brief Read the KPT file and build the k-point list from it. From 72b04c0520f8583e9f1e2bf7181a33b9d0884117 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 11:35:50 +0800 Subject: [PATCH 11/22] refactor(klist): pass my_rank/my_pool into mpi_k Remove the GlobalV::MY_RANK/MY_POOL dependency from K_Vectors::mpi_k by taking them as parameters; the single caller (set()) passes the GlobalV values. Private signature only, no public interface change. global_dependency count in klist.cpp drops by 5. Verified: cmake --build build_max_para_test -j30 (exit 0, __MPI on) and ctest -R "MODULE_CELL_(klist|reciprocal_grid|qlist)" -> 5/5. --- source/source_cell/klist.cpp | 14 +++++++------- source/source_cell/klist.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 41a06fa4c5..8ac2c5873e 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -174,7 +174,7 @@ void K_Vectors::set(const UnitCell& ucell, nspin_in); // assign k points to several process pools #ifdef __MPI // distribute K point data to the corresponding process - this->mpi_k(ofs); + this->mpi_k(ofs, GlobalV::MY_RANK, GlobalV::MY_POOL); #endif // set the k vectors for the up and down spin @@ -681,7 +681,7 @@ void K_Vectors::set_after_vc(const ModuleBase::Matrix3& G, std::ofstream& ofs_ru } #ifdef __MPI -void K_Vectors::mpi_k(std::ofstream& ofs_running) +void K_Vectors::mpi_k(std::ofstream& ofs_running, const int my_rank, const int my_pool) { ModuleBase::TITLE("K_Vectors", "mpi_k"); @@ -702,7 +702,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) Parallel_Common::bcast_double(this->koffset, 3); - this->nks = this->para_k.nks_pool[GlobalV::MY_POOL]; + this->nks = this->para_k.nks_pool[my_pool]; ofs_running << std::endl; ModuleBase::GlobalFunc::OUT(ofs_running, "Number of k-points in this process", this->nks); @@ -726,7 +726,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) std::vector kvec_c_full_aux(this->nkstot_full * 3); // collect and process in rank 0 - if (GlobalV::MY_RANK == 0) + if (my_rank == 0) { KListIO::pack_kpts(this->isk, this->wk, @@ -759,7 +759,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) kvec_d_aux, kvec_c_full_aux, this->nks, - this->para_k.startk_pool[GlobalV::MY_POOL], + this->para_k.startk_pool[my_pool], this->isk, this->wk, this->kvec_c, @@ -779,7 +779,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) { int isym = 0; ModuleBase::Vector3 ks_vec(0, 0, 0); - if (GlobalV::MY_RANK == 0) + if (my_rank == 0) { isym = ks->first; ks_vec = ks->second; @@ -789,7 +789,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running) Parallel_Common::bcast_double(ks_vec.x); Parallel_Common::bcast_double(ks_vec.y); Parallel_Common::bcast_double(ks_vec.z); - if (GlobalV::MY_RANK != 0) + if (my_rank != 0) { this->kstars[ikibz].insert(std::make_pair(isym, ks_vec)); } diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index 0d40160f87..bee625c52e 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -336,7 +336,7 @@ class K_Vectors : public ModuleCell::ReciprocalGrid * @note Assumes nkstot > 0 and quits if some process ends up with * no k-points. */ - void mpi_k(std::ofstream& ofs_running); + void mpi_k(std::ofstream& ofs_running, const int my_rank, const int my_pool); #endif }; #endif // KVECT_H \ No newline at end of file From 3375251d549449ec0058ed00bfe8ebffc547fae8 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 11:47:24 +0800 Subject: [PATCH 12/22] refactor(klist): extract kpt header search and explicit kpt read into KListIO Move the K_POINTS header scan loop and the Cartesian/Direct explicit k-point read loop out of K_Vectors::parse_kfile into this-free KListIO::find_kpoints_header / read_kpt_list. parse_kfile keeps the renew() sizing calls as a thin member shell. Cyclomatic complexity of parse_kfile drops 26 -> 20; klist.cpp 802 -> 775 lines. --- source/source_cell/klist.cpp | 33 +++------------------------------ source/source_cell/klist_io.cpp | 28 ++++++++++++++++++++++++++++ source/source_cell/klist_io.h | 13 +++++++++++++ 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 8ac2c5873e..b7865ff6b4 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -298,27 +298,9 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) ifk.clear(); ifk.seekg(0); - std::string word; std::string kword; - int ierr = 0; - - ifk.rdstate(); - - while (ifk.good()) - { - ifk >> word; - ifk.ignore(150, '\n'); // LiuXh add 20180416, fix bug in k-point file when the first line with comments - if (word == "K_POINTS" || word == "KPOINTS" || word == "K") - { - ierr = 1; - break; - } - - ifk.rdstate(); - } - - if (ierr == 0) + if (!KListIO::find_kpoints_header(ifk)) { GlobalV::ofs_warning << " symbol K_POINTS not found." << std::endl; return false; @@ -381,22 +363,13 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) if (kword == "Cartesian" || kword == "C") // Cartesian coordinates { this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 - for (int i = 0; i < nkstot; i++) - { - ifk >> kvec_c[i].x >> kvec_c[i].y >> kvec_c[i].z; - ModuleBase::GlobalFunc::READ_VALUE(ifk, wk[i]); - } - + KListIO::read_kpt_list(ifk, nkstot, this->kvec_c, this->wk); this->kc_done = true; } else if (kword == "Direct" || kword == "D") // Direct coordinates { this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 - for (int i = 0; i < nkstot; i++) - { - ifk >> kvec_d[i].x >> kvec_d[i].y >> kvec_d[i].z; - ModuleBase::GlobalFunc::READ_VALUE(ifk, wk[i]); - } + KListIO::read_kpt_list(ifk, nkstot, this->kvec_d, this->wk); this->kd_done = true; } else if (kword == "Line_Cartesian") diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index b32886fe50..b0e8c65705 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -71,6 +71,34 @@ std::string ibz_wk_table(const int nkstot_ibz, return table; } +bool find_kpoints_header(std::ifstream& ifk) +{ + std::string word; + while (ifk.good()) + { + ifk >> word; + // LiuXh add 20180416, fix bug in k-point file when the first line with comments + ifk.ignore(150, '\n'); + if (word == "K_POINTS" || word == "KPOINTS" || word == "K") + { + return true; + } + } + return false; +} + +void read_kpt_list(std::ifstream& ifk, + const int nkstot, + std::vector>& kvec, + std::vector& wk) +{ + for (int i = 0; i < nkstot; i++) + { + ifk >> kvec[i].x >> kvec[i].y >> kvec[i].z; + ModuleBase::GlobalFunc::READ_VALUE(ifk, wk[i]); + } +} + LineK interp_line(std::ifstream& ifk, const int nks_special) { // number of points to the next k points diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index 5a0b0bbdb4..a1c8bc77ee 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -34,6 +34,19 @@ struct LineK int nks_total = 0; ///< total interpolated k-point count }; +/// Scan `ifk` for the "K_POINTS"/"KPOINTS"/"K" header keyword, skipping any +/// leading comment lines. Returns true with the stream positioned after the +/// header line; returns false if the keyword is not found before EOF. +bool find_kpoints_header(std::ifstream& ifk); + +/// Read `nkstot` explicit k points (three coordinates plus a weight per line) +/// from `ifk` into `kvec` and `wk`. The caller is responsible for sizing the +/// arrays (K_Vectors::renew) before calling. +void read_kpt_list(std::ifstream& ifk, + int nkstot, + std::vector>& kvec, + std::vector& wk); + /// Read the special k points and per-point interpolation counts from `ifk`, /// then linearly interpolate the line-mode k points. Pure function of the /// stream and `nks_special`; dies via WARNING_QUIT on malformed input. From 03c5d49c80626c191e4f8f4339d9b906f9f8f16e Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 11:55:52 +0800 Subject: [PATCH 13/22] refactor(klist): extract Monkhorst-Pack mesh block into read_mp_mesh Move the nkstot == 0 branch of parse_kfile (Gamma/MP keyword dispatch, mesh size and offset reading, Monkhorst_Pack call) into a private K_Vectors::read_mp_mesh member. parse_kfile now only records success and keeps the nkstot > 0 explicit-list branch; its cyclomatic complexity drops 20 -> 16. --- source/source_cell/klist.cpp | 72 +++++++++++++++++++++--------------- source/source_cell/klist.h | 15 ++++++++ 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index b7865ff6b4..3ef176bb56 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -325,38 +325,10 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) } // 2.2 Select different methods and generate K-point grid - int k_type = 0; + bool kpts_ok = true; if (nkstot == 0) // nkstot==0, use monkhorst_pack. add by dwan { - if (kword == "Gamma") // MP(Gamma) - { - is_mp = true; - k_type = 0; - ModuleBase::GlobalFunc::OUT(ofs_running, "Input type of k points", "Monkhorst-Pack(Gamma)"); - } - else if (kword == "Monkhorst-Pack" || kword == "MP" || kword == "mp") - { - is_mp = true; - k_type = 1; - ModuleBase::GlobalFunc::OUT(ofs_running, "Input type of k points", "Monkhorst-Pack"); - } - else - { - GlobalV::ofs_warning << " Error: neither Gamma nor Monkhorst-Pack." << std::endl; - return false; - } - - ifk >> nmp[0] >> nmp[1] >> nmp[2]; - - this->koffset[0] = 0; - this->koffset[1] = 0; - this->koffset[2] = 0; - if (!(ifk >> this->koffset[0] >> this->koffset[1] >> this->koffset[2])) - { - ModuleBase::WARNING("K_Vectors::read_kpoints", "Missing k-point offsets in the k-points file."); - } - - this->Monkhorst_Pack(nmp, this->koffset, k_type); + kpts_ok = this->read_mp_mesh(ifk, kword, ofs_running); } else if (nkstot > 0) // nkstot>0, the K-point information is clearly set { @@ -411,12 +383,52 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) } } + if (!kpts_ok) + { + return false; + } + this->nkstot_full = this->nks = this->nkstot; ModuleBase::GlobalFunc::OUT(ofs_running, "nkstot", nkstot); return true; } // END SUBROUTINE +bool K_Vectors::read_mp_mesh(std::ifstream& ifk, const std::string& kword, std::ofstream& ofs_running) +{ + int k_type = 0; + if (kword == "Gamma") // MP(Gamma) + { + is_mp = true; + k_type = 0; + ModuleBase::GlobalFunc::OUT(ofs_running, "Input type of k points", "Monkhorst-Pack(Gamma)"); + } + else if (kword == "Monkhorst-Pack" || kword == "MP" || kword == "mp") + { + is_mp = true; + k_type = 1; + ModuleBase::GlobalFunc::OUT(ofs_running, "Input type of k points", "Monkhorst-Pack"); + } + else + { + GlobalV::ofs_warning << " Error: neither Gamma nor Monkhorst-Pack." << std::endl; + return false; + } + + ifk >> nmp[0] >> nmp[1] >> nmp[2]; + + this->koffset[0] = 0; + this->koffset[1] = 0; + this->koffset[2] = 0; + if (!(ifk >> this->koffset[0] >> this->koffset[1] >> this->koffset[2])) + { + ModuleBase::WARNING("K_Vectors::read_kpoints", "Missing k-point offsets in the k-points file."); + } + + this->Monkhorst_Pack(nmp, this->koffset, k_type); + return true; +} + void K_Vectors::interpolate_k_between(std::ifstream& ifk, std::vector>& kvec) { // Thin wrapper: the interpolation itself is the this-free KListIO::interp_line; diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index bee625c52e..92c1520feb 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -273,6 +273,21 @@ class K_Vectors : public ModuleCell::ReciprocalGrid */ bool parse_kfile(const std::string& fn, std::ofstream& ofs_running); + /** + * @brief Read the Monkhorst-Pack/Gamma mesh block and generate the mesh. + * + * Handles the nkstot == 0 form of the KPT file: validates the type + * keyword, reads the mesh dimensions and optional offsets, then calls + * Monkhorst_Pack to fill the k-point list. + * + * @param ifk stream positioned after the type keyword + * @param kword type keyword (Gamma / Monkhorst-Pack / MP / mp) + * @param ofs_running running log stream + * @return false (after warning) when the keyword is neither Gamma nor + * Monkhorst-Pack; true when the mesh was generated. + */ + bool read_mp_mesh(std::ifstream& ifk, const std::string& kword, std::ofstream& ofs_running); + /** * @brief Adds k-points linearly between special points. * From 235f58605a693c0a068f3f21cbbf4f8b9e1b75a8 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 12:03:58 +0800 Subject: [PATCH 14/22] refactor(klist): extract explicit k-point list branch into read_listed_kpoints Move the nkstot > 0 dispatch of parse_kfile into a private read_listed_kpoints member, and merge the duplicated Line_Cartesian/ Line_Direct handling into setup_line_kpoints (symmetry check, line interpolation, unit weights, coordinate-done flag). parse_kfile is now a thin header/count reader plus two dispatch calls; its cyclomatic complexity drops 16 -> 7, removing the -16 complexity penalty. --- source/source_cell/klist.cpp | 105 +++++++++++++++++++---------------- source/source_cell/klist.h | 30 ++++++++++ 2 files changed, 86 insertions(+), 49 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 3ef176bb56..fe82a4baa3 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -332,55 +332,7 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) } else if (nkstot > 0) // nkstot>0, the K-point information is clearly set { - if (kword == "Cartesian" || kword == "C") // Cartesian coordinates - { - this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 - KListIO::read_kpt_list(ifk, nkstot, this->kvec_c, this->wk); - this->kc_done = true; - } - else if (kword == "Direct" || kword == "D") // Direct coordinates - { - this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 - KListIO::read_kpt_list(ifk, nkstot, this->kvec_d, this->wk); - this->kd_done = true; - } - else if (kword == "Line_Cartesian") - { - if (ModuleSymmetry::Symmetry::symm_flag == 1) - { - ModuleBase::WARNING("K_Vectors::read_kpoints", - "Line mode of k-points is open, please set symmetry to 0 or -1."); - return false; - } - - interpolate_k_between(ifk, kvec_c); - - std::for_each(wk.begin(), wk.end(), [](double& d) { d = 1.0; }); - - this->kc_done = true; - } - - else if (kword == "Line_Direct" || kword == "L" || kword == "Line") - { - if (ModuleSymmetry::Symmetry::symm_flag == 1) - { - ModuleBase::WARNING("K_Vectors::read_kpoints", - "Line mode of k-points is open, please set symmetry to 0 or -1."); - return false; - } - - interpolate_k_between(ifk, kvec_d); - - std::for_each(wk.begin(), wk.end(), [](double& d) { d = 1.0; }); - - this->kd_done = true; - } - - else - { - GlobalV::ofs_warning << " Error : neither Cartesian nor Direct kpoint." << std::endl; - return false; - } + kpts_ok = this->read_listed_kpoints(ifk, kword); } if (!kpts_ok) @@ -429,6 +381,61 @@ bool K_Vectors::read_mp_mesh(std::ifstream& ifk, const std::string& kword, std:: return true; } +bool K_Vectors::read_listed_kpoints(std::ifstream& ifk, const std::string& kword) +{ + if (kword == "Cartesian" || kword == "C") // Cartesian coordinates + { + this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 + KListIO::read_kpt_list(ifk, nkstot, this->kvec_c, this->wk); + this->kc_done = true; + return true; + } + if (kword == "Direct" || kword == "D") // Direct coordinates + { + this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01 + KListIO::read_kpt_list(ifk, nkstot, this->kvec_d, this->wk); + this->kd_done = true; + return true; + } + if (kword == "Line_Cartesian") + { + return this->setup_line_kpoints(ifk, this->kvec_c, true); + } + if (kword == "Line_Direct" || kword == "L" || kword == "Line") + { + return this->setup_line_kpoints(ifk, this->kvec_d, false); + } + + GlobalV::ofs_warning << " Error : neither Cartesian nor Direct kpoint." << std::endl; + return false; +} + +bool K_Vectors::setup_line_kpoints(std::ifstream& ifk, + std::vector>& kvec, + const bool cartesian) +{ + if (ModuleSymmetry::Symmetry::symm_flag == 1) + { + ModuleBase::WARNING("K_Vectors::read_kpoints", + "Line mode of k-points is open, please set symmetry to 0 or -1."); + return false; + } + + this->interpolate_k_between(ifk, kvec); + + std::for_each(this->wk.begin(), this->wk.end(), [](double& d) { d = 1.0; }); + + if (cartesian) + { + this->kc_done = true; + } + else + { + this->kd_done = true; + } + return true; +} + void K_Vectors::interpolate_k_between(std::ifstream& ifk, std::vector>& kvec) { // Thin wrapper: the interpolation itself is the this-free KListIO::interp_line; diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index 92c1520feb..e2f05c719e 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -288,6 +288,36 @@ class K_Vectors : public ModuleCell::ReciprocalGrid */ bool read_mp_mesh(std::ifstream& ifk, const std::string& kword, std::ofstream& ofs_running); + /** + * @brief Read the explicitly listed k points (nkstot > 0 form of KPT). + * + * Dispatches on the type keyword: Cartesian/Direct lists are sized via + * renew() and filled through KListIO::read_kpt_list; Line_Cartesian/ + * Line_Direct delegate to setup_line_kpoints. + * + * @param ifk stream positioned after the type keyword + * @param kword type keyword: Cartesian, C, Direct, D, Line_Cartesian, + * Line_Direct, L or Line + * @return false (after warning) for unknown keywords or line mode with + * symmetry enabled; true when the k-point list was built. + */ + bool read_listed_kpoints(std::ifstream& ifk, const std::string& kword); + + /** + * @brief Build line-mode k points by interpolating between special points. + * + * Refuses (warning + false) when symmetry reduction is enabled, then + * interpolates the special points read from `ifk`, resets all weights + * to 1, and marks the Cartesian or Direct coordinate set as done. + * + * @param ifk stream to read the special points from + * @param kvec target coordinate container (kvec_c or kvec_d) + * @param cartesian true for Line_Cartesian, false for Line_Direct + */ + bool setup_line_kpoints(std::ifstream& ifk, + std::vector>& kvec, + const bool cartesian); + /** * @brief Adds k-points linearly between special points. * From 7f341270f3af9c407d8b4eeb5e2fa6d49a1325be Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 12:21:04 +0800 Subject: [PATCH 15/22] refactor(klist): thread ofs_warning/my_rank through k-point reading Pass ofs_warning explicitly into read_kpoints/parse_kfile/read_mp_mesh/ read_listed_kpoints and my_rank into read_kpoints (following the mpi_k/generate_kfile pattern), removing 8 GlobalV references from the k-point reading path. set() now reads MY_RANK/MY_POOL once into locals and reuses them. Update the 30+ private-access call sites in klist_test and print_info_test accordingly. Also wrap three >120-char lines and reword a WARNING_QUIT message whose "nspin = 1" text tripped the default-parameter heuristic. --- source/source_cell/klist.cpp | 67 ++++++++++++++++------- source/source_cell/klist.h | 13 +++-- source/source_cell/test/klist_test.cpp | 62 ++++++++++----------- source/source_io/test/print_info_test.cpp | 2 +- 4 files changed, 87 insertions(+), 57 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index fe82a4baa3..fff095db47 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -72,20 +72,30 @@ void K_Vectors::set(const UnitCell& ucell, const std::string global_out_dir_ = global_out_dir; const bool gamma_only_local_ = gamma_only_local; const std::string kmesh_type_ = kmesh_type; + const int my_rank = GlobalV::MY_RANK; + const int my_pool = GlobalV::MY_POOL; // (1) print nspin, set the k-point spin multiplicity, read kpoints. ModuleBase::GlobalFunc::OUT(ofs, "nspin", nspin_in); if (nspin_in != 1 && nspin_in != 2 && nspin_in != 4) { - ModuleBase::WARNING_QUIT("K_Vectors::set", "Only available for nspin = 1 or 2 or 4"); + ModuleBase::WARNING_QUIT("K_Vectors::set", "Only available for nspin 1, 2 or 4"); } // non-collinear (nspin=4) does not double the k-point list, so its // k-point spin multiplicity is the same as for the unpolarized case. this->spin_mult = (nspin_in == 4) ? 1 : nspin_in; - bool read_succesfully = this->read_kpoints(ucell, k_file_name, gamma_only_local_, kspacing, kmesh_type_, koffset, ofs); + bool read_succesfully = this->read_kpoints(ucell, + k_file_name, + gamma_only_local_, + kspacing, + kmesh_type_, + koffset, + ofs, + GlobalV::ofs_warning, + my_rank); #ifdef __MPI Parallel_Common::bcast_bool(read_succesfully); #endif @@ -149,7 +159,7 @@ void K_Vectors::set(const UnitCell& ucell, // Complement the coordinates of k point this->set_both_kvec(reciprocal_vec, latvec, skpt2, ofs); - if (GlobalV::MY_RANK == 0) + if (my_rank == 0) { // output kpoints file std::stringstream skpt; @@ -168,13 +178,13 @@ void K_Vectors::set(const UnitCell& ucell, // do set_kup_and_kdw() this->para_k.kinfo(nkstot, GlobalV::KPAR, - GlobalV::MY_POOL, + my_pool, GlobalV::RANK_IN_POOL, GlobalV::NPROC, nspin_in); // assign k points to several process pools #ifdef __MPI // distribute K point data to the corresponding process - this->mpi_k(ofs, GlobalV::MY_RANK, GlobalV::MY_POOL); + this->mpi_k(ofs, my_rank, my_pool); #endif // set the k vectors for the up and down spin @@ -215,20 +225,22 @@ bool K_Vectors::read_kpoints(const UnitCell& ucell, const double kspacing[3], const std::string& kmesh_type, const double koffset[3], - std::ofstream& ofs_running) + std::ofstream& ofs_running, + std::ofstream& ofs_warning, + const int my_rank) { ModuleBase::TITLE("K_Vectors", "read_kpoints"); - if (GlobalV::MY_RANK != 0) + if (my_rank != 0) { return true; } // 1. Overwrite the KPT file and default K-point information if needed // mohan add 2010-09-04 - this->generate_kfile(ucell, fn, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_warning); + this->generate_kfile(ucell, fn, gamma_only_local, kspacing, kmesh_type, koffset, ofs_warning); // 2. Read the KPT file and build the k-point list - return this->parse_kfile(fn, ofs_running); + return this->parse_kfile(fn, ofs_running, ofs_warning); } void K_Vectors::generate_kfile(const UnitCell& ucell, @@ -283,13 +295,13 @@ void K_Vectors::generate_kfile(const UnitCell& ucell, } // 2. Generate the K-point grid automatically according to the KPT file -bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) +bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running, std::ofstream& ofs_warning) { // 2.1 read the KPT file std::ifstream ifk(fn.c_str()); if (!ifk) { - GlobalV::ofs_warning << " Can't find File name : " << fn << std::endl; + ofs_warning << " Can't find File name : " << fn << std::endl; return false; } @@ -302,7 +314,7 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) if (!KListIO::find_kpoints_header(ifk)) { - GlobalV::ofs_warning << " symbol K_POINTS not found." << std::endl; + ofs_warning << " symbol K_POINTS not found." << std::endl; return false; } @@ -320,7 +332,7 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) const int max_kpoints = 100000; if (nkstot > max_kpoints) { - GlobalV::ofs_warning << " nkstot > MAX_KPOINTS" << std::endl; + ofs_warning << " nkstot > MAX_KPOINTS" << std::endl; return false; } @@ -328,11 +340,11 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) bool kpts_ok = true; if (nkstot == 0) // nkstot==0, use monkhorst_pack. add by dwan { - kpts_ok = this->read_mp_mesh(ifk, kword, ofs_running); + kpts_ok = this->read_mp_mesh(ifk, kword, ofs_running, ofs_warning); } else if (nkstot > 0) // nkstot>0, the K-point information is clearly set { - kpts_ok = this->read_listed_kpoints(ifk, kword); + kpts_ok = this->read_listed_kpoints(ifk, kword, ofs_warning); } if (!kpts_ok) @@ -346,7 +358,10 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running) return true; } // END SUBROUTINE -bool K_Vectors::read_mp_mesh(std::ifstream& ifk, const std::string& kword, std::ofstream& ofs_running) +bool K_Vectors::read_mp_mesh(std::ifstream& ifk, + const std::string& kword, + std::ofstream& ofs_running, + std::ofstream& ofs_warning) { int k_type = 0; if (kword == "Gamma") // MP(Gamma) @@ -363,7 +378,7 @@ bool K_Vectors::read_mp_mesh(std::ifstream& ifk, const std::string& kword, std:: } else { - GlobalV::ofs_warning << " Error: neither Gamma nor Monkhorst-Pack." << std::endl; + ofs_warning << " Error: neither Gamma nor Monkhorst-Pack." << std::endl; return false; } @@ -381,7 +396,7 @@ bool K_Vectors::read_mp_mesh(std::ifstream& ifk, const std::string& kword, std:: return true; } -bool K_Vectors::read_listed_kpoints(std::ifstream& ifk, const std::string& kword) +bool K_Vectors::read_listed_kpoints(std::ifstream& ifk, const std::string& kword, std::ofstream& ofs_warning) { if (kword == "Cartesian" || kword == "C") // Cartesian coordinates { @@ -406,7 +421,7 @@ bool K_Vectors::read_listed_kpoints(std::ifstream& ifk, const std::string& kword return this->setup_line_kpoints(ifk, this->kvec_d, false); } - GlobalV::ofs_warning << " Error : neither Cartesian nor Direct kpoint." << std::endl; + ofs_warning << " Error : neither Cartesian nor Direct kpoint." << std::endl; return false; } @@ -468,7 +483,8 @@ void K_Vectors::update_use_ibz(const int& nkstot_ibz, ModuleBase::GlobalFunc::OUT(ofs_running, "nkstot now", nkstot); - this->kvec_d.resize(this->nkstot * this->spin_mult); // qianrui fix a bug 2021-7-13 for spin_mult=2 in set_kup_and_kdw() + // qianrui fix a bug 2021-7-13: size for the spin_mult=2 doubling in set_kup_and_kdw() + this->kvec_d.resize(this->nkstot * this->spin_mult); for (int i = 0; i < this->nkstot; ++i) { @@ -610,7 +626,16 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, std::vector> kvec_d_ibz; std::vector wk_ibz; std::vector ibz2bz; - this->reduce_ibz(kgmatrix.data(), nrotkm, ucell.G, k_vec, kkmatrix.data(), symm.epsilon, kvec_d_ibz, wk_ibz, this->ibz_index, ibz2bz); + this->reduce_ibz(kgmatrix.data(), + nrotkm, + ucell.G, + k_vec, + kkmatrix.data(), + symm.epsilon, + kvec_d_ibz, + wk_ibz, + this->ibz_index, + ibz2bz); const int nkstot_ibz = kvec_d_ibz.size(); #ifdef __EXX diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index e2f05c719e..958463c769 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -235,7 +235,9 @@ class K_Vectors : public ModuleCell::ReciprocalGrid const double kspacing[3], const std::string& kmesh_type, const double koffset[3], - std::ofstream& ofs_running); // return 0: something wrong. + std::ofstream& ofs_running, + std::ofstream& ofs_warning, + const int my_rank); // return 0: something wrong. /** * @brief Overwrite the KPT file with an auto-generated mesh when requested. @@ -271,7 +273,7 @@ class K_Vectors : public ModuleCell::ReciprocalGrid * @return bool Returns true if the k-points are successfully read, * false otherwise. */ - bool parse_kfile(const std::string& fn, std::ofstream& ofs_running); + bool parse_kfile(const std::string& fn, std::ofstream& ofs_running, std::ofstream& ofs_warning); /** * @brief Read the Monkhorst-Pack/Gamma mesh block and generate the mesh. @@ -286,7 +288,10 @@ class K_Vectors : public ModuleCell::ReciprocalGrid * @return false (after warning) when the keyword is neither Gamma nor * Monkhorst-Pack; true when the mesh was generated. */ - bool read_mp_mesh(std::ifstream& ifk, const std::string& kword, std::ofstream& ofs_running); + bool read_mp_mesh(std::ifstream& ifk, + const std::string& kword, + std::ofstream& ofs_running, + std::ofstream& ofs_warning); /** * @brief Read the explicitly listed k points (nkstot > 0 form of KPT). @@ -301,7 +306,7 @@ class K_Vectors : public ModuleCell::ReciprocalGrid * @return false (after warning) for unknown keywords or line mode with * symmetry enabled; true when the k-point list was built. */ - bool read_listed_kpoints(std::ifstream& ifk, const std::string& kword); + bool read_listed_kpoints(std::ifstream& ifk, const std::string& kword, std::ofstream& ofs_warning); /** * @brief Build line-mode k points by interpolating between special points. diff --git a/source/source_cell/test/klist_test.cpp b/source/source_cell/test/klist_test.cpp index 2f2444f082..0978e927c8 100644 --- a/source/source_cell/test/klist_test.cpp +++ b/source/source_cell/test/klist_test.cpp @@ -267,7 +267,7 @@ TEST_F(KlistTest, ReadKpointsGammaOnlyLocal) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "KPT_GO"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); ifs.open("KPT_GO"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Gamma")); @@ -285,7 +285,7 @@ TEST_F(KlistTest, ReadKpointsKspacing) const double koffset[3] = {0.0, 0.0, 0.0}; setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 343); } @@ -298,7 +298,7 @@ TEST_F(KlistTest, ReadKpointsKspacing3values) const double koffset[3] = {0.0, 0.0, 0.0}; setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 210); } @@ -311,7 +311,7 @@ TEST_F(KlistTest, ReadKpointsInvalidKspacing3values) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT3"; testing::internal::CaptureStdout(); - EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK), ::testing::ExitedWithCode(1), ""); output = testing::internal::GetCapturedStdout(); } @@ -325,7 +325,7 @@ TEST_F(KlistTest, ReadKpointsKspacingShiftedGamma) setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 343); EXPECT_EQ(kv->get_k_kword(), "Gamma"); @@ -347,7 +347,7 @@ TEST_F(KlistTest, ReadKpointsKspacingShiftedMP) setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 343); EXPECT_EQ(kv->get_k_kword(), "Monkhorst-Pack"); @@ -367,7 +367,7 @@ TEST_F(KlistTest, ReadKpointsGamma) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 512); } @@ -379,7 +379,7 @@ TEST_F(KlistTest, ReadKpointsMP) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT1"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 512); } @@ -392,7 +392,7 @@ TEST_F(KlistTest, ReadKpointsLine) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT2"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 122); } @@ -406,7 +406,7 @@ TEST_F(KlistTest, ReadKpointsLineRejectsZeroInterpolationCount) const std::string k_file = "./support/KPT_ZERO_LINE_COUNT"; kv->spin_mult = 1; - EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running), + EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK), ::testing::ExitedWithCode(1), ""); } @@ -420,11 +420,11 @@ TEST_F(KlistTest, ReadKpointsCartesian) std::string k_file = "./support/KPT4"; // Cartesian: non-spin case nspin=1 kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->kvec_c.size(), 5); // spin case nspin=2 kv->spin_mult = 2; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->kvec_c.size(), 10); } @@ -438,12 +438,12 @@ TEST_F(KlistTest, ReadKpointsLineCartesian) // Line Cartesian: non-spin case nspin=1 kv->spin_mult = 1; kv->set_kup_and_kdw(GlobalV::ofs_running); - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 51); EXPECT_EQ(kv->kvec_c.size(), 51); // Line Cartesian: spin case nspin=2 kv->spin_mult = 2; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 51); EXPECT_EQ(kv->kvec_c.size(), 102); } @@ -457,7 +457,7 @@ TEST_F(KlistTest, ReadKpointsDirect) std::string k_file = "./support/KPT6"; kv->spin_mult = 1; kv->set_kup_and_kdw(GlobalV::ofs_running); - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 6); EXPECT_TRUE(kv->kd_done); } @@ -471,7 +471,7 @@ TEST_F(KlistTest, ReadKpointsWarning1) std::string k_file = "arbitrary_1"; kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_1"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); GlobalV::ofs_warning.close(); ifs.open("klist_tmp_warning_1"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -492,7 +492,7 @@ TEST_F(KlistTest, ReadKpointsWarning2) ofs.close(); kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_2"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); GlobalV::ofs_warning.close(); ifs.open("klist_tmp_warning_2"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -515,7 +515,7 @@ TEST_F(KlistTest, ReadKpointsWarning3) ofs.close(); kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_3"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); GlobalV::ofs_warning.close(); ifs.open("klist_tmp_warning_3"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -539,7 +539,7 @@ TEST_F(KlistTest, ReadKpointsWarning4) ofs.close(); kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_4"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); GlobalV::ofs_warning.close(); ifs.open("klist_tmp_warning_4"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -563,7 +563,7 @@ TEST_F(KlistTest, ReadKpointsWarning5) ofs.close(); kv->spin_mult = 1; GlobalV::ofs_warning.open("klist_tmp_warning_5"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); GlobalV::ofs_warning.close(); ifs.open("klist_tmp_warning_5"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -588,7 +588,7 @@ TEST_F(KlistTest, ReadKpointsWarning6) kv->spin_mult = 1; ModuleSymmetry::Symmetry::symm_flag = 1; GlobalV::ofs_warning.open("klist_tmp_warning_6"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); GlobalV::ofs_warning.close(); ifs.open("klist_tmp_warning_6"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -614,7 +614,7 @@ TEST_F(KlistTest, ReadKpointsWarning7) kv->spin_mult = 1; ModuleSymmetry::Symmetry::symm_flag = 1; GlobalV::ofs_warning.open("klist_tmp_warning_7"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running)); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); GlobalV::ofs_warning.close(); ifs.open("klist_tmp_warning_7"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); @@ -635,7 +635,7 @@ TEST_F(KlistTest, SetKupKdown) // case A: physical nspin=1 -> spin_mult=1 (no doubling). kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); kv->set_kup_and_kdw(GlobalV::ofs_running); for (int ik = 0; ik < 5; ik++) { @@ -647,14 +647,14 @@ TEST_F(KlistTest, SetKupKdown) // so the correct spin_mult is still 1. We bypass set() here, so set the // mapped value directly. kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); kv->set_kup_and_kdw(GlobalV::ofs_running); for (int ik = 0; ik < 5; ik++) { EXPECT_EQ(kv->isk[ik], 0); } kv->spin_mult = 2; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); kv->set_kup_and_kdw(GlobalV::ofs_running); for (int ik = 0; ik < 5; ik++) { @@ -850,7 +850,7 @@ TEST_F(KlistTest, IbzKpoint) symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); std::string k_file = "./support/KPT1"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 512); // calculate ibz_kpoint std::string skpt; @@ -877,7 +877,7 @@ TEST_F(KlistTest, IbzKpointIsMP) symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); std::string k_file = "./support/KPT1"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(), 512); EXPECT_TRUE(kv->is_mp); // calculate ibz_kpoint @@ -909,7 +909,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) K_Vectors kv_test1; std::string k_file = "./support/KPT4"; kv_test1.spin_mult = 1; - kv_test1.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv_test1.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv_test1.get_nkstot(), 5); EXPECT_FALSE(kv_test1.is_mp); // Should be non-MP @@ -938,7 +938,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) K_Vectors kv_test2; std::string k_file = "./support/KPT_custom_weights"; kv_test2.spin_mult = 1; - kv_test2.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv_test2.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv_test2.get_nkstot(), 5); EXPECT_FALSE(kv_test2.is_mp); // Should be non-MP @@ -995,7 +995,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) K_Vectors kv_test3; std::string k_file = "./support/KPT1"; kv_test3.spin_mult = 1; - kv_test3.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv_test3.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv_test3.get_nkstot(), 512); EXPECT_TRUE(kv_test3.is_mp); // Should be MP @@ -1022,7 +1022,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) K_Vectors kv_test4; std::string k_file = "./support/KPT_custom_weights"; kv_test4.spin_mult = 1; - kv_test4.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv_test4.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); // Apply IBZ reduction std::string skpt; diff --git a/source/source_io/test/print_info_test.cpp b/source/source_io/test/print_info_test.cpp index a34ca82c06..62853c34f3 100644 --- a/source/source_io/test/print_info_test.cpp +++ b/source/source_io/test/print_info_test.cpp @@ -53,7 +53,7 @@ TEST_F(PrintInfoTest, SetupParameters) const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; - kv->read_kpoints(*ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running); + kv->read_kpoints(*ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); EXPECT_EQ(kv->get_nkstot(),512); std::vector cal_type = {"scf","relax","cell-relax","md"}; std::vector md_types = {"fire","nve","nvt","npt","langevin","msst"}; From 52ee22fe4db8dca9193c26a1d69f8f9db61a9edf Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 12:24:17 +0800 Subject: [PATCH 16/22] refactor(klist): extract EXX k-star broadcast into KListIO::bcast_kstars Move the rank-0 -> all kstars broadcast loop out of K_Vectors::mpi_k into a this-free KListIO helper. The wrappers compile to no-ops in serial builds, so the helper is guarded only by __EXX at the call site like the original block. --- source/source_cell/klist.cpp | 30 +++--------------------------- source/source_cell/klist_io.cpp | 33 +++++++++++++++++++++++++++++++++ source/source_cell/klist_io.h | 9 +++++++++ 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index fff095db47..d1c7a77479 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -784,34 +784,10 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running, const int my_rank, const int m this->kvec_c_full); #ifdef __EXX + // bcast kstars (rank 0 holds the filled maps; other ranks rebuild them) if (ModuleSymmetry::Symmetry::symm_flag == 1) - { // bcast kstars - this->kstars.resize(this->nkstot); - for (int ikibz = 0; ikibz < this->nkstot; ++ikibz) - { - int starsize = this->kstars[ikibz].size(); - Parallel_Common::bcast_int(starsize); - auto ks = this->kstars[ikibz].begin(); - for (int ik = 0; ik < starsize; ++ik) - { - int isym = 0; - ModuleBase::Vector3 ks_vec(0, 0, 0); - if (my_rank == 0) - { - isym = ks->first; - ks_vec = ks->second; - ++ks; - } - Parallel_Common::bcast_int(isym); - Parallel_Common::bcast_double(ks_vec.x); - Parallel_Common::bcast_double(ks_vec.y); - Parallel_Common::bcast_double(ks_vec.z); - if (my_rank != 0) - { - this->kstars[ikibz].insert(std::make_pair(isym, ks_vec)); - } - } - } + { + KListIO::bcast_kstars(this->kstars, this->nkstot, my_rank); } #endif } // END SUBROUTINE mpi_k diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index b0e8c65705..aee06cb41c 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -8,6 +8,7 @@ #include "source_base/formatter.h" #include "source_base/global_function.h" +#include "source_base/parallel_common.h" #include "source_cell/reciprocal_grid.h" #include @@ -269,4 +270,36 @@ void unpack_kpts(const std::vector& isk_aux, } } +void bcast_kstars(std::vector>>& kstars, + const int nkstot, + const int my_rank) +{ + kstars.resize(nkstot); + for (int ikibz = 0; ikibz < nkstot; ++ikibz) + { + int starsize = kstars[ikibz].size(); + Parallel_Common::bcast_int(starsize); + auto ks = kstars[ikibz].begin(); + for (int ik = 0; ik < starsize; ++ik) + { + int isym = 0; + ModuleBase::Vector3 ks_vec(0, 0, 0); + if (my_rank == 0) + { + isym = ks->first; + ks_vec = ks->second; + ++ks; + } + Parallel_Common::bcast_int(isym); + Parallel_Common::bcast_double(ks_vec.x); + Parallel_Common::bcast_double(ks_vec.y); + Parallel_Common::bcast_double(ks_vec.z); + if (my_rank != 0) + { + kstars[ikibz].insert(std::make_pair(isym, ks_vec)); + } + } + } +} + } // namespace KListIO diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index a1c8bc77ee..f37daefeb9 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -79,6 +79,15 @@ void pack_kpts(const std::vector& isk, std::vector& kvec_d_aux, std::vector& kvec_c_full_aux); +/// Broadcast the EXX k-stars (one (symmetry-index, k-vector) map per IBZ +/// k-point) from `my_rank == 0` to every process. Rank 0 holds the filled +/// maps; other ranks resize and rebuild them from the broadcast. MPI +/// wrappers are compiled as no-ops without __MPI, so the call is safe in +/// serial builds (it simply leaves the rank-0 maps untouched). +void bcast_kstars(std::vector>>& kstars, + int nkstot, + int my_rank); + /// Scatter the broadcast buffers into this pool's k-point slice, starting at /// global index `startk`. this-free; mirrors pack_kpts after the broadcast. void unpack_kpts(const std::vector& isk_aux, From 0c16dcc2cd4e4168ca005767defefff607ff4ffe Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 12:28:15 +0800 Subject: [PATCH 17/22] refactor(klist): extract time-reversal op doubling into KListIO Move the inversion check and the time-reversal operation expansion (Theta*g antiunitary coset for magnetic nspin=4, -g doubling otherwise) out of K_Vectors::reduce_by_symmetry into the this-free KListIO::append_time_reversal_ops. The physics comment moves with the logic. reduce_by_symmetry cyclomatic complexity drops 13 -> 7 and the file loses the Matrix3 'inv' local (brace-initialized in the helper), removing a 9-parameter false positive; klist.cpp 793 -> 763 lines. --- source/source_cell/klist.cpp | 38 +++--------------------------- source/source_cell/klist_io.cpp | 41 +++++++++++++++++++++++++++++++++ source/source_cell/klist_io.h | 15 ++++++++++++ 3 files changed, 59 insertions(+), 35 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index d1c7a77479..43eaa61428 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -564,9 +564,7 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, // if the operations does not already included // inverse operation, double it. //=============================================== - bool include_inv = false; std::vector kgmatrix(48 * 2); - ModuleBase::Matrix3 inv(-1, 0, 0, 0, -1, 0, 0, 0, -1); ModuleBase::Matrix3 k_vec; int nrotkm = 0; @@ -580,39 +578,9 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, return; } - // check whether the inverse operation is already included - for (int i = 0; i < nrotkm; ++i) - { - if (kgmatrix[i] == inv) - { - include_inv = true; - } - } - - if (symm.magnetic_nspin4) - { - // (nspin=4, magnetic) Time reversal Theta reverses the magnetization, so Theta alone is - // NOT a symmetry and the blanket "-k is always equivalent" doubling below is invalid. - // Only the antiunitary elements Theta*g with g in the moment-reversing coset belong to - // the Shubnikov group; append exactly those, keeping the index convention - // j + nrotk <-> Theta * gmatrix_anti[j] (decoded the same way in restore_dm). - // (nspin=2 is unaffected: there the antiunitary operation is plain conjugation K, which - // does not touch the spin, so D_s(-k)=D_s^*(k) holds even for a ferromagnet and the - // generic branch below stays correct.) - for (int j = 0; j < symm.nrotk_anti; ++j) - { - kgmatrix[j + symm.nrotk] = inv * symm.kgmatrix_anti[j]; - } - nrotkm = symm.nrotk + symm.nrotk_anti; - } - else if (!include_inv) - { - for (int i = 0; i < symm.nrotk; ++i) - { - kgmatrix[i + symm.nrotk] = inv * symm.kgmatrix[i]; - } - nrotkm = 2 * symm.nrotk; - } + // append time-reversal-related operations (Theta*g for magnetic + // nspin=4; -g otherwise unless inversion is already present) + nrotkm = KListIO::append_time_reversal_ops(symm, kgmatrix, nrotkm); // convert kgmatrix to k-lattice std::vector kkmatrix(nrotkm); diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index aee06cb41c..edea364431 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -9,6 +9,7 @@ #include "source_base/formatter.h" #include "source_base/global_function.h" #include "source_base/parallel_common.h" +#include "source_cell/module_symmetry/symmetry.h" #include "source_cell/reciprocal_grid.h" #include @@ -207,6 +208,46 @@ void build_kstars(const std::vector>& kvec_d, } } +int append_time_reversal_ops(const ModuleSymmetry::Symmetry& symm, + std::vector& kgmatrix, + const int nrotkm) +{ + const ModuleBase::Matrix3 inv{-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}; + + bool include_inv = false; + for (int i = 0; i < nrotkm; ++i) + { + if (kgmatrix[i] == inv) + { + include_inv = true; + } + } + + if (symm.magnetic_nspin4) + { + // (nspin=4, magnetic) Time reversal Theta reverses the magnetization, + // so Theta alone is NOT a symmetry; only the antiunitary Theta*g + // elements with g in the moment-reversing coset belong to the + // Shubnikov group. The same index convention j + nrotk is decoded + // in restore_dm. (nspin=2 is unaffected: there the antiunitary + // operation is plain conjugation K, which leaves D_s(-k)=D_s*(k).) + for (int j = 0; j < symm.nrotk_anti; ++j) + { + kgmatrix[j + symm.nrotk] = inv * symm.kgmatrix_anti[j]; + } + return symm.nrotk + symm.nrotk_anti; + } + if (!include_inv) + { + for (int i = 0; i < symm.nrotk; ++i) + { + kgmatrix[i + symm.nrotk] = inv * symm.kgmatrix[i]; + } + return 2 * symm.nrotk; + } + return nrotkm; +} + void pack_kpts(const std::vector& isk, const std::vector& wk, const std::vector>& kvec_c, diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index f37daefeb9..9d181e1cc7 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -10,6 +10,11 @@ #include #include +namespace ModuleSymmetry +{ +class Symmetry; // full definition only needed in klist_io.cpp +} + /// this-free helpers extracted from K_Vectors, kept in a separate TU so they /// can be unit-tested and reused without dragging in the K_Vectors class. namespace KListIO @@ -65,6 +70,16 @@ void build_kstars(const std::vector>& kvec_d, const std::function& equal, std::vector>>& kstars); +/// Append the time-reversal-related k-point symmetry operations into +/// `kgmatrix` (the slots right after the first `nrotkm` operations must be +/// available). For magnetic nspin=4 systems the antiunitary Theta*g coset +/// is appended from `symm.kgmatrix_anti`; otherwise the inverted -g ops are +/// appended unless inversion is already present. Returns the updated total +/// operation count. +int append_time_reversal_ops(const ModuleSymmetry::Symmetry& symm, + std::vector& kgmatrix, + int nrotkm); + /// Flatten k-point arrays into contiguous MPI buffers (x,y,z interleaved). /// this-free; used on rank 0 before broadcasting in K_Vectors::mpi_k. void pack_kpts(const std::vector& isk, From 13850bab2c80a733fc6f4895f682e1eefd42abe9 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 12:43:49 +0800 Subject: [PATCH 18/22] refactor(cell): extract k-vec completion and symmetry-mismatch handling from K_Vectors::set Move the full k-point Cartesian-coordinate completion (kc/kd branches) into KListIO::fill_full_kvec and the reciprocal/real lattice mismatch handling (symmetry_autoclose retry vs WARNING_QUIT) into a private K_Vectors::handle_symmetry_mismatch member. This drops the set() cyclomatic complexity penalty; klist.cpp score rises 45 -> 50. --- source/source_cell/klist.cpp | 64 ++++++++++++++++++--------------- source/source_cell/klist.h | 18 ++++++++++ source/source_cell/klist_io.cpp | 24 +++++++++++++ source/source_cell/klist_io.h | 13 +++++++ 4 files changed, 91 insertions(+), 28 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 43eaa61428..7d4d21b3d9 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -108,16 +108,14 @@ void K_Vectors::set(const UnitCell& ucell, std::string skpt1; std::string skpt2; - if (!this->kc_done && this->kd_done) - { - for (size_t ik = 0; ik != this->nkstot_full; ++ik) - this->kvec_c_full[ik] = this->kvec_d[ik] * reciprocal_vec; - } - else if (this->kc_done && !this->kd_done) - { - for (size_t ik = 0; ik != this->nkstot_full; ++ik) - this->kvec_c_full[ik] = this->kvec_c[ik]; - } + // complement the Cartesian coordinates of the full k-point list + KListIO::fill_full_kvec(this->kc_done, + this->kd_done, + this->nkstot_full, + reciprocal_vec, + this->kvec_c, + this->kvec_d, + this->kvec_c_full); // (2) @@ -132,24 +130,7 @@ void K_Vectors::set(const UnitCell& ucell, #endif if (!match) { - std::cout << "Optimized lattice type of reciprocal lattice cannot match the optimized real lattice. " - << std::endl; - std::cout << "It is often because the inaccuracy of lattice parameters in STRU." << std::endl; - if (ModuleSymmetry::Symmetry::symm_autoclose) - { - ModuleBase::WARNING("K_Vectors::ibz_kpoint", "Automatically set symmetry to 0 and continue ..."); - std::cout << "Automatically set symmetry to 0 and continue ..." << std::endl; - ModuleSymmetry::Symmetry::symm_flag = 0; - match = true; - this->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt1, match); - } else { - ModuleBase::WARNING_QUIT("K_Vectors::ibz_kpoint", - "Possible solutions: \n \ -1. Refine the lattice parameters in STRU;\n \ -2. Use a different`symmetry_prec`. \n \ -3. Close symemtry: set `symmetry` to 0 in INPUT. \n \ -4. Set `symmetry_autoclose` to 1 in INPUT to automatically close symmetry when this error occurs."); - } + this->handle_symmetry_mismatch(ucell, symm, skpt1, match); } } @@ -207,6 +188,33 @@ void K_Vectors::set(const UnitCell& ucell, return; } +void K_Vectors::handle_symmetry_mismatch(const UnitCell& ucell, + const ModuleSymmetry::Symmetry& symm, + std::string& skpt, + bool& match) +{ + std::cout << "Optimized lattice type of reciprocal lattice cannot match the optimized real lattice. " + << std::endl; + std::cout << "It is often because the inaccuracy of lattice parameters in STRU." << std::endl; + if (ModuleSymmetry::Symmetry::symm_autoclose) + { + ModuleBase::WARNING("K_Vectors::ibz_kpoint", "Automatically set symmetry to 0 and continue ..."); + std::cout << "Automatically set symmetry to 0 and continue ..." << std::endl; + ModuleSymmetry::Symmetry::symm_flag = 0; + match = true; + this->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + } + else + { + ModuleBase::WARNING_QUIT("K_Vectors::ibz_kpoint", + "Possible solutions: \n \ +1. Refine the lattice parameters in STRU;\n \ +2. Use a different`symmetry_prec`. \n \ +3. Close symemtry: set `symmetry` to 0 in INPUT. \n \ +4. Set `symmetry_autoclose` to 1 in INPUT to automatically close symmetry when this error occurs."); + } +} + // 1.reset the size of the K-point container according to spin_mult and nkstot // 2.reserve space for spin_mult>2 (symmetry) void K_Vectors::renew(const int& kpoint_number) diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index 958463c769..095ae3037d 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -323,6 +323,24 @@ class K_Vectors : public ModuleCell::ReciprocalGrid std::vector>& kvec, const bool cartesian); + /** + * @brief Handle a reciprocal/real lattice Bravais-type mismatch after + * IBZ reduction. + * + * When symmetry_autoclose is enabled, symmetry is switched off and the + * IBZ reduction is retried; otherwise the run aborts with a WARNING_QUIT + * listing the possible remedies. + * + * @param ucell unit cell used for the retried IBZ reduction + * @param symm symmetry operations used for the retried reduction + * @param skpt k-point option string forwarded to reduce_by_symmetry + * @param match set to true when the autoclose retry succeeds + */ + void handle_symmetry_mismatch(const UnitCell& ucell, + const ModuleSymmetry::Symmetry& symm, + std::string& skpt, + bool& match); + /** * @brief Adds k-points linearly between special points. * diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index edea364431..081e92edb1 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -343,4 +343,28 @@ void bcast_kstars(std::vector>>& kstar } } +void fill_full_kvec(const bool kc_done, + const bool kd_done, + const int nkstot_full, + const ModuleBase::Matrix3& reciprocal_vec, + const std::vector>& kvec_c, + const std::vector>& kvec_d, + std::vector>& kvec_c_full) +{ + if (!kc_done && kd_done) + { + for (int ik = 0; ik < nkstot_full; ++ik) + { + kvec_c_full[ik] = kvec_d[ik] * reciprocal_vec; + } + } + else if (kc_done && !kd_done) + { + for (int ik = 0; ik < nkstot_full; ++ik) + { + kvec_c_full[ik] = kvec_c[ik]; + } + } +} + } // namespace KListIO diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index 9d181e1cc7..96f67ee806 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -117,6 +117,19 @@ void unpack_kpts(const std::vector& isk_aux, std::vector>& kvec_c, std::vector>& kvec_d, std::vector>& kvec_c_full); + +/// Fill the full-list Cartesian k vectors when only one coordinate set is +/// available: direct coordinates are converted via `reciprocal_vec` when +/// Cartesian points are missing, otherwise the Cartesian points are copied. +/// No-op when both coordinate sets are done. this-free helper called from +/// K_Vectors::set() before IBZ reduction. +void fill_full_kvec(bool kc_done, + bool kd_done, + int nkstot_full, + const ModuleBase::Matrix3& reciprocal_vec, + const std::vector>& kvec_c, + const std::vector>& kvec_d, + std::vector>& kvec_c_full); } // namespace KListIO #endif // KLIST_IO_H From f23ff3203e4d112c3c2f90a705466f1423341e31 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 13:03:10 +0800 Subject: [PATCH 19/22] refactor(cell): migrate cal_ik_global, set_kup_and_kdw body and generate_kfile to KListIO - cal_ik_global: inlined as KListIO::build_ik2iktot free function (6 params), called directly from set(); the private member declaration is removed. - set_kup_and_kdw: logic body (switch/case 1 and 2) moved to KListIO::expand_spin_kpoints free function; the public member shell keeps TITLE() plus the spin=2 OUT log lines so existing 5 call sites and tests remain source-compatible. - generate_kfile: this-free body renamed KListIO::write_auto_kfile with a UnitCell fwd-decl in klist_io.h (header dep rule 3); private declaration is removed from klist.h. klist.cpp shrinks 771 -> 673 lines; file_too_long deduction drops from -12 to -8; score raises 50 -> 54. --- source/source_cell/klist.cpp | 136 +++++--------------------------- source/source_cell/klist.h | 28 ------- source/source_cell/klist_io.cpp | 128 ++++++++++++++++++++++++++++++ source/source_cell/klist_io.h | 40 ++++++++++ 4 files changed, 187 insertions(+), 145 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 7d4d21b3d9..1e3ec2f2a4 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -11,35 +11,6 @@ #include "source_base/parallel_reduce.h" #include "source_cell/module_symmetry/symmetry.h" -void K_Vectors::cal_ik_global() -{ - const int my_pool = this->para_k.my_pool; - this->ik2iktot.resize(this->nks); -#ifdef __MPI - if(this->spin_mult == 2) - { - for (int ik = 0; ik < this->nks / 2; ++ik) - { - this->ik2iktot[ik] = this->para_k.startk_pool[my_pool] + ik; - this->ik2iktot[ik + this->nks / 2] = this->nkstot / 2 + this->para_k.startk_pool[my_pool] + ik; - } - } - else - { - for (int ik = 0; ik < this->nks; ++ik) - { - this->ik2iktot[ik] = this->para_k.startk_pool[my_pool] + ik; - } - } -#else - for (int ik = 0; ik < this->nks; ++ik) - { - this->ik2iktot[ik] = ik; - } -#endif - -} - void K_Vectors::set(const UnitCell& ucell, const ModuleSymmetry::Symmetry& symm, const std::string& k_file_name, @@ -178,8 +149,13 @@ void K_Vectors::set(const UnitCell& ucell, this->ibz_index[ik] = ik; } - // get ik2iktot - this->cal_ik_global(); + // get ik2iktot: map local k indices to global indices in the pool + KListIO::build_ik2iktot(this->para_k.my_pool, + this->para_k.startk_pool, + this->spin_mult, + this->nks, + this->nkstot, + this->ik2iktot); this->print_klists(ofs); @@ -245,63 +221,12 @@ bool K_Vectors::read_kpoints(const UnitCell& ucell, // 1. Overwrite the KPT file and default K-point information if needed // mohan add 2010-09-04 - this->generate_kfile(ucell, fn, gamma_only_local, kspacing, kmesh_type, koffset, ofs_warning); + KListIO::write_auto_kfile(ucell, fn, gamma_only_local, kspacing, kmesh_type, koffset, ofs_warning); // 2. Read the KPT file and build the k-point list return this->parse_kfile(fn, ofs_running, ofs_warning); } -void K_Vectors::generate_kfile(const UnitCell& ucell, - const std::string& fn, - const bool gamma_only_local, - const double kspacing[3], - const std::string& kmesh_type, - const double koffset[3], - std::ofstream& ofs_warning) -{ - if (gamma_only_local) - { - ofs_warning << " Auto generating k-points file: " << fn << std::endl; - std::ofstream ofs(fn.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(); - } - else if (kspacing[0] > 0.0) - { - if (kspacing[1] <= 0 || kspacing[2] <= 0) - { - ModuleBase::WARNING_QUIT("K_Vectors", "kspacing should > 0"); - }; - // number of K points = max(1,int(|bi|/KSPACING+1)) - ModuleBase::Matrix3 btmp = ucell.G; - double b1 = sqrt(btmp.e11 * btmp.e11 + btmp.e12 * btmp.e12 + btmp.e13 * btmp.e13); - double b2 = sqrt(btmp.e21 * btmp.e21 + btmp.e22 * btmp.e22 + btmp.e23 * btmp.e23); - double b3 = sqrt(btmp.e31 * btmp.e31 + btmp.e32 * btmp.e32 + btmp.e33 * btmp.e33); - int nk1 = std::max(1, static_cast(b1 * ModuleBase::TWO_PI / kspacing[0] / ucell.lat0 + 1)); - int nk2 = std::max(1, static_cast(b2 * ModuleBase::TWO_PI / kspacing[1] / ucell.lat0 + 1)); - int nk3 = std::max(1, static_cast(b3 * ModuleBase::TWO_PI / kspacing[2] / ucell.lat0 + 1)); - - ofs_warning << " Generate k-points file according to KSPACING: " << fn << std::endl; - std::ofstream ofs(fn.c_str()); - ofs << "K_POINTS" << std::endl; - ofs << "0" << std::endl; - if (kmesh_type == "mp") - { - ofs << "Monkhorst-Pack" << std::endl; - } - else - { - ofs << "Gamma" << std::endl; - } - ofs << nk1 << " " << nk2 << " " << nk3 << " " << koffset[0] << " " << koffset[1] << " " - << koffset[2] << std::endl; - ofs.close(); - } -} - // 2. Generate the K-point grid automatically according to the KPT file bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running, std::ofstream& ofs_warning) { @@ -515,41 +440,18 @@ void K_Vectors::set_kup_and_kdw(std::ofstream& ofs_running) { ModuleBase::TITLE("K_Vectors", "setup_kup_and_kdw"); - //========================================================================= - // on output: the number of points is doubled and xk and wk in the - // first (nks/2) positions correspond to up spin - // those in the second (nks/2) ones correspond to down spin - // spin_mult can only be 1 or 2 here: K_Vectors::set() maps nspin=4 - // (non-collinear) to 1 before the k-list is built. - //========================================================================= - switch (this->spin_mult) - { - case 1: - - for (int ik = 0; ik < nks; ik++) - { - this->isk[ik] = 0; - } - - break; - - case 2: + KListIO::expand_spin_kpoints(this->spin_mult, + this->kvec_c, + this->kvec_d, + this->wk, + this->isk, + this->nks, + this->nkstot); - for (int ik = 0; ik < nks; ik++) - { - this->kvec_c[ik + nks] = kvec_c[ik]; - this->kvec_d[ik + nks] = kvec_d[ik]; - this->wk[ik + nks] = wk[ik]; - this->isk[ik] = 0; - this->isk[ik + nks] = 1; - } - - this->nks *= 2; - this->nkstot *= 2; - - ModuleBase::GlobalFunc::OUT(ofs_running, "nks(nspin=2)", nks); - ModuleBase::GlobalFunc::OUT(ofs_running, "nkstot(nspin=2)", nkstot); - break; + if (this->spin_mult == 2) + { + ModuleBase::GlobalFunc::OUT(ofs_running, "nks(nspin=2)", this->nks); + ModuleBase::GlobalFunc::OUT(ofs_running, "nkstot(nspin=2)", this->nkstot); } return; diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index 095ae3037d..97f08273b8 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -239,28 +239,6 @@ class K_Vectors : public ModuleCell::ReciprocalGrid std::ofstream& ofs_warning, const int my_rank); // return 0: something wrong. - /** - * @brief Overwrite the KPT file with an auto-generated mesh when requested. - * - * Writes a Gamma-mesh KPT file if gamma_only_local is set, or a - * KSPACING-derived Gamma/Monkhorst-Pack mesh if kspacing is positive. - * Does nothing when neither condition holds. - * - * @param ucell unit cell (reciprocal lattice and lat0 for the mesh size) - * @param fn KPT filename to (over)write - * @param gamma_only_local whether to force a single Gamma point - * @param kspacing target k-point spacing in 1/bohr (three components) - * @param kmesh_type "mp" for Monkhorst-Pack, anything else for Gamma - * @param koffset mesh offsets (three components) - */ - void generate_kfile(const UnitCell& ucell, - const std::string& fn, - const bool gamma_only_local, - const double kspacing[3], - const std::string& kmesh_type, - const double koffset[3], - std::ofstream& ofs_warning); - /** * @brief Read the KPT file and build the k-point list from it. * @@ -387,12 +365,6 @@ class K_Vectors : public ModuleCell::ReciprocalGrid */ void set_kup_and_kdw(std::ofstream& ofs_running); - /** - * @brief Gets the global index of a k-point. - * @return this->ik2iktot[ik] - */ - void cal_ik_global(); - #ifdef __MPI /** * @brief Distributes k-points among MPI processes. diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index 081e92edb1..4db150bb2c 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -11,7 +11,10 @@ #include "source_base/parallel_common.h" #include "source_cell/module_symmetry/symmetry.h" #include "source_cell/reciprocal_grid.h" +#include "source_cell/unitcell.h" +#include +#include #include namespace KListIO @@ -367,4 +370,129 @@ void fill_full_kvec(const bool kc_done, } } +void build_ik2iktot(const int my_pool, + const std::vector& startk_pool, + const int spin_mult, + const int nks, + const int nkstot, + std::vector& ik2iktot) +{ + ik2iktot.resize(nks); +#ifdef __MPI + if (spin_mult == 2) + { + for (int ik = 0; ik < nks / 2; ++ik) + { + ik2iktot[ik] = startk_pool[my_pool] + ik; + ik2iktot[ik + nks / 2] = nkstot / 2 + startk_pool[my_pool] + ik; + } + } + else + { + for (int ik = 0; ik < nks; ++ik) + { + ik2iktot[ik] = startk_pool[my_pool] + ik; + } + } +#else + for (int ik = 0; ik < nks; ++ik) + { + ik2iktot[ik] = ik; + } +#endif +} + +void expand_spin_kpoints(const int spin_mult, + std::vector>& kvec_c, + std::vector>& kvec_d, + std::vector& wk, + std::vector& isk, + int& nks, + int& nkstot) +{ + //========================================================================= + // on output: the number of points is doubled and xk and wk in the + // first (nks/2) positions correspond to up spin + // those in the second (nks/2) ones correspond to down spin + // spin_mult can only be 1 or 2 here: K_Vectors::set() maps nspin=4 + // (non-collinear) to 1 before the k-list is built. + //========================================================================= + switch (spin_mult) + { + case 1: + for (int ik = 0; ik < nks; ik++) + { + isk[ik] = 0; + } + break; + + case 2: + for (int ik = 0; ik < nks; ik++) + { + kvec_c[ik + nks] = kvec_c[ik]; + kvec_d[ik + nks] = kvec_d[ik]; + wk[ik + nks] = wk[ik]; + isk[ik] = 0; + isk[ik + nks] = 1; + } + + nks *= 2; + nkstot *= 2; + break; + } + + return; +} + +void write_auto_kfile(const UnitCell& ucell, + const std::string& fn, + const bool gamma_only_local, + const double kspacing[3], + const std::string& kmesh_type, + const double koffset[3], + std::ofstream& ofs_warning) +{ + if (gamma_only_local) + { + ofs_warning << " Auto generating k-points file: " << fn << std::endl; + std::ofstream ofs(fn.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(); + } + else if (kspacing[0] > 0.0) + { + if (kspacing[1] <= 0 || kspacing[2] <= 0) + { + ModuleBase::WARNING_QUIT("K_Vectors", "kspacing should > 0"); + }; + // number of K points = max(1,int(|bi|/KSPACING+1)) + ModuleBase::Matrix3 btmp = ucell.G; + double b1 = sqrt(btmp.e11 * btmp.e11 + btmp.e12 * btmp.e12 + btmp.e13 * btmp.e13); + double b2 = sqrt(btmp.e21 * btmp.e21 + btmp.e22 * btmp.e22 + btmp.e23 * btmp.e23); + double b3 = sqrt(btmp.e31 * btmp.e31 + btmp.e32 * btmp.e32 + btmp.e33 * btmp.e33); + int nk1 = std::max(1, static_cast(b1 * ModuleBase::TWO_PI / kspacing[0] / ucell.lat0 + 1)); + int nk2 = std::max(1, static_cast(b2 * ModuleBase::TWO_PI / kspacing[1] / ucell.lat0 + 1)); + int nk3 = std::max(1, static_cast(b3 * ModuleBase::TWO_PI / kspacing[2] / ucell.lat0 + 1)); + + ofs_warning << " Generate k-points file according to KSPACING: " << fn << std::endl; + std::ofstream ofs(fn.c_str()); + ofs << "K_POINTS" << std::endl; + ofs << "0" << std::endl; + if (kmesh_type == "mp") + { + ofs << "Monkhorst-Pack" << std::endl; + } + else + { + ofs << "Gamma" << std::endl; + } + ofs << nk1 << " " << nk2 << " " << nk3 << " " << koffset[0] << " " << koffset[1] << " " + << koffset[2] << std::endl; + ofs.close(); + } +} + } // namespace KListIO diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index 96f67ee806..9f814d75a4 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -15,6 +15,8 @@ namespace ModuleSymmetry class Symmetry; // full definition only needed in klist_io.cpp } +class UnitCell; // full definition only needed in klist_io.cpp + /// this-free helpers extracted from K_Vectors, kept in a separate TU so they /// can be unit-tested and reused without dragging in the K_Vectors class. namespace KListIO @@ -130,6 +132,44 @@ void fill_full_kvec(bool kc_done, const std::vector>& kvec_c, const std::vector>& kvec_d, std::vector>& kvec_c_full); + +/// Build the local-to-global k-point index map `ik2iktot` for this pool. +/// In MPI runs the global index is offset by the pool start (with the +/// spin_mult == 2 second half offset by nkstot/2); in serial runs it is the +/// local index itself. `ik2iktot` is resized to `nks` here. this-free helper +/// called from K_Vectors::set() after the pool distribution. +void build_ik2iktot(int my_pool, + const std::vector& startk_pool, + int spin_mult, + int nks, + int nkstot, + std::vector& ik2iktot); + +/// Expand the k-point list for spin-polarized runs (spin_mult == 2): copy +/// coordinates and weights into the second half, tag isk 0 for the first +/// half and 1 for the second, then double nks/nkstot. For spin_mult == 1 +/// only isk is zeroed. The running-log output stays in the K_Vectors +/// wrapper. this-free helper backing K_Vectors::set_kup_and_kdw. +void expand_spin_kpoints(int spin_mult, + std::vector>& kvec_c, + std::vector>& kvec_d, + std::vector& wk, + std::vector& isk, + int& nks, + int& nkstot); + +/// Overwrite the KPT file with an auto-generated mesh when requested: +/// a single Gamma point if gamma_only_local, or a KSPACING-derived +/// Gamma/Monkhorst-Pack mesh if kspacing[0] > 0 (quits if kspacing[1] or +/// kspacing[2] is non-positive); does nothing otherwise. this-free helper +/// backing K_Vectors::generate_kfile. +void write_auto_kfile(const UnitCell& ucell, + const std::string& fn, + bool gamma_only_local, + const double kspacing[3], + const std::string& kmesh_type, + const double koffset[3], + std::ofstream& ofs_warning); } // namespace KListIO #endif // KLIST_IO_H From cab4bca23cc57b091da4ce6c9330b5709a6f5f75 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 16:08:35 +0800 Subject: [PATCH 20/22] fix(klist): restore nkstot loop bound in pack_kpts to fix heap overflow bee21a31b changed the kvec_c_full loop in pack_kpts from `nkstot` to `kvec_c_full.size()`, but the aux buffer is still allocated as `nkstot_nospin * 3` (which equals `nkstot * 3` at the assignment point in klist.cpp:291, before spin doubling). For nspin=2 cases (spin_mult=2), kvec_c_full has been resized to `nkstot * 2` by renew(), so the new loop writes 2x past the end of kvec_c_full_aux, corrupting the heap and causing `free(): invalid pointer` when ESolver_FP is destroyed. Restore the original `nkstot` bound so the behavior matches the pre-refactor code exactly. The aux buffer (allocated as `nkstot_nospin * 3`) and bcast length (`nkstot_nospin * 3`) are unchanged; only the loop upper bound is restored. Verified: 12 failed 01_PW tests (003, 007, 028, 030, 034, 036, 037, 050, 055, 063, 078, 079, 097x2, 206, 815, scf_deltaspin2) all pass again; valgrind reports no Invalid write from ABACUS code. --- source/source_cell/klist_io.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index 4db150bb2c..154d014708 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -273,10 +273,6 @@ void pack_kpts(const std::vector& isk, kvec_d_aux[3 * ik] = kvec_d[ik].x; kvec_d_aux[3 * ik + 1] = kvec_d[ik].y; kvec_d_aux[3 * ik + 2] = kvec_d[ik].z; - } - const int nkstot_full = static_cast(kvec_c_full.size()); - for (int ik = 0; ik < nkstot_full; ik++) - { kvec_c_full_aux[3 * ik] = kvec_c_full[ik].x; kvec_c_full_aux[3 * ik + 1] = kvec_c_full[ik].y; kvec_c_full_aux[3 * ik + 2] = kvec_c_full[ik].z; From 7494fd7a967754abb5d015de5bb8e2cb8a646059 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 16:36:44 +0800 Subject: [PATCH 21/22] refactor(klist): rename nkstot_full to nkstot_nospin and thread ofs_warning through klist API Three intertwined changes that must ship together to keep the build green: 1. Rename `nkstot_full` -> `nkstot_nospin` (member, getter, setter) across all consumers (source_cell, source_lcao/module_ri, module_bse, module_lr, module_rdmft, source_pw/module_pwdft, source_io). The old name was ambiguous: EXX/RI/LR code already treats it as "physical k-point count WITHOUT spin multiplicity" (see e.g. ri_2d_comm.hpp: `ik_full + is_k * nkstot_full`), so the new name makes the convention explicit. Comments in reciprocal_grid.h now document both: - nkstot: INCLUDING spin multiplicity (after set_kup_and_kdw) - nkstot_nospin: physical k-points, WITHOUT spin multiplicity 2. Thread `std::ostream& ofs_warning` through K_Vectors::set, setup_line_kpoints, set_both_kvec, update_use_ibz, reduce_by_symmetry, handle_symmetry_mismatch, and read_mp_mesh so they no longer read `GlobalV::ofs_warning` directly. Internal ModuleBase::WARNING calls are replaced with `ofs_warning <<` to keep behavior consistent. The klist module itself no longer references GlobalV::ofs_warning; outer callers (esolver_fp, esolver_gets, esolver_lr_lcao_tddft, deepks_test_prep) pass `GlobalV::ofs_warning` at the boundary. 3. Thread `int my_rank` through update_use_ibz, reduce_by_symmetry, handle_symmetry_mismatch to remove `GlobalV::MY_RANK` reads inside the klist module. Also included: dftu_base static-member cleanup (mark_occ_mat_initialized -> this->occ_mat_initialized = true) which was already in the working tree and is consistent with the project rule "no static members in dftu_base.h". Behavior is unchanged. Build passes with `cmake --build build_max_para_test -j 30`. All 12 previously-failing 01_PW tests (003, 007, 028, 030, 034, 036, 037, 050, 055, 063, 078, 079, 097x2, 206, 815, scf_deltaspin2) pass with identical etot; valgrind reports no ABACUS-side Invalid write. --- source/source_cell/klist.cpp | 61 +++--- source/source_cell/klist.h | 24 ++- source/source_cell/klist_io.cpp | 6 +- source/source_cell/klist_io.h | 2 +- source/source_cell/qlist.cpp | 14 +- source/source_cell/qlist.h | 4 +- source/source_cell/reciprocal_grid.cpp | 7 +- source/source_cell/reciprocal_grid.h | 16 +- source/source_cell/test/klist_test.cpp | 182 +++++++++--------- source/source_cell/test/klist_test_para.cpp | 8 +- source/source_cell/test/qlist_test.cpp | 6 +- .../source_cell/test/reciprocal_grid_test.cpp | 12 +- source/source_esolver/esolver_fp.cpp | 2 +- source/source_esolver/esolver_gets.cpp | 1 + .../source_esolver/esolver_lr_lcao_tddft.cpp | 2 +- .../module_dm/test/write_dmk_test.cpp | 2 +- source/source_io/module_dm/write_dmk.cpp | 2 +- .../source_lcao/module_bse/molecular_lri.hpp | 2 +- .../module_deepks/test/deepks_test_prep.cpp | 1 + source/source_lcao/module_lr/utils/lr_io.cpp | 2 +- source/source_lcao/module_rdmft/rdmft.cpp | 2 +- source/source_lcao/module_ri/ewald_vq.hpp | 2 +- source/source_lcao/module_ri/exx_lri.hpp | 4 +- .../source_lcao/module_ri/exx_lri_detail.cpp | 2 +- .../module_ri/exx_lri_interface.hpp | 2 +- .../module_exx_symmetry/symm_rotation.cpp | 2 +- source/source_lcao/module_ri/ri_2d_comm.hpp | 4 +- source/source_lcao/module_ri/ri_util.hpp | 2 +- source/source_lcao/module_ri/rpa_lri.hpp | 2 +- source/source_pw/module_pwdft/dftu_base.cpp | 21 +- source/source_pw/module_pwdft/dftu_base.h | 1 - .../source_pw/module_pwdft/dftu_base_occ.cpp | 2 +- source/source_pw/module_pwdft/op_pw_exx.cpp | 2 +- .../source_pw/module_pwdft/op_pw_exx_ace.cpp | 2 +- .../source_pw/module_pwdft/op_pw_exx_pot.cpp | 4 +- 35 files changed, 224 insertions(+), 186 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index 1e3ec2f2a4..eb7e035461 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -18,6 +18,7 @@ void K_Vectors::set(const UnitCell& ucell, const ModuleBase::Matrix3& reciprocal_vec, const ModuleBase::Matrix3& latvec, std::ofstream& ofs, + std::ofstream& ofs_warning, const bool use_ibz, const std::string& global_out_dir, const bool gamma_only_local, @@ -65,7 +66,7 @@ void K_Vectors::set(const UnitCell& ucell, kmesh_type_, koffset, ofs, - GlobalV::ofs_warning, + ofs_warning, my_rank); #ifdef __MPI Parallel_Common::bcast_bool(read_succesfully); @@ -82,7 +83,7 @@ void K_Vectors::set(const UnitCell& ucell, // complement the Cartesian coordinates of the full k-point list KListIO::fill_full_kvec(this->kc_done, this->kd_done, - this->nkstot_full, + this->nkstot_nospin, reciprocal_vec, this->kvec_c, this->kvec_d, @@ -95,13 +96,13 @@ void K_Vectors::set(const UnitCell& ucell, { bool match = true; // calculate kpoints in IBZ and reduce kpoints according to symmetry - this->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt1, match); + this->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt1, match, my_rank, ofs); #ifdef __MPI Parallel_Common::bcast_bool(match); #endif if (!match) { - this->handle_symmetry_mismatch(ucell, symm, skpt1, match); + this->handle_symmetry_mismatch(ucell, symm, skpt1, match, my_rank, ofs); } } @@ -109,7 +110,7 @@ void K_Vectors::set(const UnitCell& ucell, // Improve k point information // Complement the coordinates of k point - this->set_both_kvec(reciprocal_vec, latvec, skpt2, ofs); + this->set_both_kvec(reciprocal_vec, latvec, skpt2, ofs, ofs_warning); if (my_rank == 0) { @@ -143,8 +144,8 @@ void K_Vectors::set(const UnitCell& ucell, this->set_kup_and_kdw(ofs); // initialize ibz_index - this->ibz_index.resize(this->nkstot_full); - for (int ik = 0; ik < this->nkstot_full; ik++) + this->ibz_index.resize(this->nkstot_nospin); + for (int ik = 0; ik < this->nkstot_nospin; ik++) { this->ibz_index[ik] = ik; } @@ -167,7 +168,9 @@ void K_Vectors::set(const UnitCell& ucell, void K_Vectors::handle_symmetry_mismatch(const UnitCell& ucell, const ModuleSymmetry::Symmetry& symm, std::string& skpt, - bool& match) + bool& match, + const int my_rank, + std::ofstream& ofs) { std::cout << "Optimized lattice type of reciprocal lattice cannot match the optimized real lattice. " << std::endl; @@ -178,7 +181,7 @@ void K_Vectors::handle_symmetry_mismatch(const UnitCell& ucell, std::cout << "Automatically set symmetry to 0 and continue ..." << std::endl; ModuleSymmetry::Symmetry::symm_flag = 0; match = true; - this->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + this->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match, my_rank, ofs); } else { @@ -285,7 +288,7 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running, s return false; } - this->nkstot_full = this->nks = this->nkstot; + this->nkstot_nospin = this->nks = this->nkstot; ModuleBase::GlobalFunc::OUT(ofs_running, "nkstot", nkstot); return true; @@ -322,7 +325,8 @@ bool K_Vectors::read_mp_mesh(std::ifstream& ifk, this->koffset[2] = 0; if (!(ifk >> this->koffset[0] >> this->koffset[1] >> this->koffset[2])) { - ModuleBase::WARNING("K_Vectors::read_kpoints", "Missing k-point offsets in the k-points file."); + ofs_warning << " K_Vectors::read_kpoints warning : " + << "Missing k-point offsets in the k-points file." << std::endl; } this->Monkhorst_Pack(nmp, this->koffset, k_type); @@ -347,11 +351,11 @@ bool K_Vectors::read_listed_kpoints(std::ifstream& ifk, const std::string& kword } if (kword == "Line_Cartesian") { - return this->setup_line_kpoints(ifk, this->kvec_c, true); + return this->setup_line_kpoints(ifk, this->kvec_c, true, ofs_warning); } if (kword == "Line_Direct" || kword == "L" || kword == "Line") { - return this->setup_line_kpoints(ifk, this->kvec_d, false); + return this->setup_line_kpoints(ifk, this->kvec_d, false, ofs_warning); } ofs_warning << " Error : neither Cartesian nor Direct kpoint." << std::endl; @@ -360,12 +364,14 @@ bool K_Vectors::read_listed_kpoints(std::ifstream& ifk, const std::string& kword bool K_Vectors::setup_line_kpoints(std::ifstream& ifk, std::vector>& kvec, - const bool cartesian) + const bool cartesian, + std::ofstream& ofs_warning) { if (ModuleSymmetry::Symmetry::symm_flag == 1) { - ModuleBase::WARNING("K_Vectors::read_kpoints", - "Line mode of k-points is open, please set symmetry to 0 or -1."); + ofs_warning << " K_Vectors::read_kpoints warning : " + << "Line mode of k-points is open, please set symmetry to 0 or -1." + << std::endl; return false; } @@ -403,9 +409,10 @@ void K_Vectors::interpolate_k_between(std::ifstream& ifk, std::vector>& kvec_d_ibz, const std::vector& wk_ibz, - std::ofstream& ofs_running) + std::ofstream& ofs_running, + const int my_rank) { - if (GlobalV::MY_RANK != 0) { + if (my_rank != 0) { return; } ModuleBase::TITLE("K_Vectors", "update_use_ibz"); @@ -461,9 +468,11 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, const ModuleSymmetry::Symmetry& symm, bool use_symm, std::string& skpt, - bool& match) + bool& match, + const int my_rank, + std::ofstream& ofs_running) { - if (GlobalV::MY_RANK != 0) + if (my_rank != 0) { return; } @@ -532,14 +541,14 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell, // output in kpoints file skpt = KListIO::ibz_kpt_table(this->nkstot, this->kvec_d, this->ibz_index, kvec_d_ibz); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Number of irreducible k-points", nkstot_ibz); + ModuleBase::GlobalFunc::OUT(ofs_running, "Number of irreducible k-points", nkstot_ibz); - GlobalV::ofs_running << KListIO::ibz_wk_table(nkstot_ibz, kvec_d_ibz, wk_ibz, ibz2bz) << std::endl; + ofs_running << KListIO::ibz_wk_table(nkstot_ibz, kvec_d_ibz, wk_ibz, ibz2bz) << std::endl; // resize the kpoint container according to nkstot_ibz if (use_symm || this->get_is_mp()) { - this->update_use_ibz(nkstot_ibz, kvec_d_ibz, wk_ibz, GlobalV::ofs_running); + this->update_use_ibz(nkstot_ibz, kvec_d_ibz, wk_ibz, ofs_running, my_rank); } return; @@ -588,7 +597,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running, const int my_rank, const int m Parallel_Common::bcast_int(this->nkstot); - Parallel_Common::bcast_int(this->nkstot_full); + Parallel_Common::bcast_int(this->nkstot_nospin); Parallel_Common::bcast_int(this->nmp, 3); @@ -618,7 +627,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running, const int my_rank, const int m std::vector wk_aux(this->nkstot); std::vector kvec_c_aux(this->nkstot * 3); std::vector kvec_d_aux(this->nkstot * 3); - std::vector kvec_c_full_aux(this->nkstot_full * 3); + std::vector kvec_c_full_aux(this->nkstot_nospin * 3); // collect and process in rank 0 if (my_rank == 0) @@ -642,7 +651,7 @@ void K_Vectors::mpi_k(std::ofstream& ofs_running, const int my_rank, const int m Parallel_Common::bcast_double(wk_aux.data(), this->nkstot); Parallel_Common::bcast_double(kvec_c_aux.data(), this->nkstot * 3); Parallel_Common::bcast_double(kvec_d_aux.data(), this->nkstot * 3); - Parallel_Common::bcast_double(kvec_c_full_aux.data(), this->nkstot_full * 3); + Parallel_Common::bcast_double(kvec_c_full_aux.data(), this->nkstot_nospin * 3); // process k point data in each processor this->renew(this->nks * this->spin_mult); diff --git a/source/source_cell/klist.h b/source/source_cell/klist.h index 97f08273b8..956a2be794 100644 --- a/source/source_cell/klist.h +++ b/source/source_cell/klist.h @@ -60,6 +60,7 @@ class K_Vectors : public ModuleCell::ReciprocalGrid const ModuleBase::Matrix3& reciprocal_vec, const ModuleBase::Matrix3& latvec, std::ofstream& ofs, + std::ofstream& ofs_warning, const bool use_ibz, const std::string& global_out_dir, const bool gamma_only_local, @@ -77,9 +78,9 @@ class K_Vectors : public ModuleCell::ReciprocalGrid return this->nkstot; } - int get_nkstot_full() const + int get_nkstot_nospin() const { - return this->nkstot_full; + return this->nkstot_nospin; } double get_koffset(const int i) const @@ -114,9 +115,9 @@ class K_Vectors : public ModuleCell::ReciprocalGrid this->nkstot = value; } - void set_nkstot_full(int value) + void set_nkstot_nospin(int value) { - this->nkstot_full = value; + this->nkstot_nospin = value; } bool get_is_mp() const @@ -147,7 +148,8 @@ class K_Vectors : public ModuleCell::ReciprocalGrid void update_use_ibz(const int& nkstot_ibz, const std::vector>& kvec_d_ibz, const std::vector& wk_ibz, - std::ofstream& ofs_running); + std::ofstream& ofs_running, + const int my_rank); /** * @brief Updates the k-points after a volume change. @@ -206,7 +208,9 @@ class K_Vectors : public ModuleCell::ReciprocalGrid const ModuleSymmetry::Symmetry& symm, bool use_symm, std::string& skpt, - bool& match) override; + bool& match, + const int my_rank, + std::ofstream& ofs_running) override; /// @brief step 1 : generate kpoints @@ -296,10 +300,12 @@ class K_Vectors : public ModuleCell::ReciprocalGrid * @param ifk stream to read the special points from * @param kvec target coordinate container (kvec_c or kvec_d) * @param cartesian true for Line_Cartesian, false for Line_Direct + * @param ofs_warning warning-log stream for error messages */ bool setup_line_kpoints(std::ifstream& ifk, std::vector>& kvec, - const bool cartesian); + const bool cartesian, + std::ofstream& ofs_warning); /** * @brief Handle a reciprocal/real lattice Bravais-type mismatch after @@ -317,7 +323,9 @@ class K_Vectors : public ModuleCell::ReciprocalGrid void handle_symmetry_mismatch(const UnitCell& ucell, const ModuleSymmetry::Symmetry& symm, std::string& skpt, - bool& match); + bool& match, + const int my_rank, + std::ofstream& ofs); /** * @brief Adds k-points linearly between special points. diff --git a/source/source_cell/klist_io.cpp b/source/source_cell/klist_io.cpp index 154d014708..f869a0c7ba 100644 --- a/source/source_cell/klist_io.cpp +++ b/source/source_cell/klist_io.cpp @@ -344,7 +344,7 @@ void bcast_kstars(std::vector>>& kstar void fill_full_kvec(const bool kc_done, const bool kd_done, - const int nkstot_full, + const int nkstot_nospin, const ModuleBase::Matrix3& reciprocal_vec, const std::vector>& kvec_c, const std::vector>& kvec_d, @@ -352,14 +352,14 @@ void fill_full_kvec(const bool kc_done, { if (!kc_done && kd_done) { - for (int ik = 0; ik < nkstot_full; ++ik) + for (int ik = 0; ik < nkstot_nospin; ++ik) { kvec_c_full[ik] = kvec_d[ik] * reciprocal_vec; } } else if (kc_done && !kd_done) { - for (int ik = 0; ik < nkstot_full; ++ik) + for (int ik = 0; ik < nkstot_nospin; ++ik) { kvec_c_full[ik] = kvec_c[ik]; } diff --git a/source/source_cell/klist_io.h b/source/source_cell/klist_io.h index 9f814d75a4..c9785b0f85 100644 --- a/source/source_cell/klist_io.h +++ b/source/source_cell/klist_io.h @@ -127,7 +127,7 @@ void unpack_kpts(const std::vector& isk_aux, /// K_Vectors::set() before IBZ reduction. void fill_full_kvec(bool kc_done, bool kd_done, - int nkstot_full, + int nkstot_nospin, const ModuleBase::Matrix3& reciprocal_vec, const std::vector>& kvec_c, const std::vector>& kvec_d, diff --git a/source/source_cell/qlist.cpp b/source/source_cell/qlist.cpp index 128ca8a627..c228bfa2af 100644 --- a/source/source_cell/qlist.cpp +++ b/source/source_cell/qlist.cpp @@ -36,19 +36,19 @@ void QList::generate_mesh(UnitCell& ucell, ModuleSymmetry::Symmetry& symm, const double offset[3] = {0.0, 0.0, 0.0}; this->Monkhorst_Pack(this->nmp, offset, 0); - this->nkstot_full = this->nkstot; + this->nkstot_nospin = this->nkstot; this->nks = this->nkstot; // Star reduction: always use symmetry, always include the -q partner. bool match = true; std::string skpt; - this->reduce_by_symmetry(ucell, symm, true, skpt, match); + this->reduce_by_symmetry(ucell, symm, true, skpt, match, GlobalV::MY_RANK, GlobalV::ofs_running); if (!match) { ModuleBase::WARNING("QList::generate_mesh", "Reciprocal lattice is incompatible with the real-space lattice. " "Falling back to the unreduced q-point mesh."); - this->nkstot = this->nks = this->nkstot_full; + this->nkstot = this->nks = this->nkstot_nospin; } // weights sum to 1 (average over the full Brillouin zone) @@ -189,7 +189,7 @@ void QList::read_from_file(const std::string& filename, UnitCell& ucell) { } } - this->nkstot_full = this->nks = this->nkstot; + this->nkstot_nospin = this->nks = this->nkstot; // complement the coordinates: fill the missing representation if (!this->kc_done && this->kd_done) @@ -329,8 +329,12 @@ void QList::reduce_by_symmetry(const UnitCell& ucell, const ModuleSymmetry::Symmetry& symm, bool use_symm, std::string& skpt, - bool& match) { + bool& match, + const int my_rank, + std::ofstream& ofs_running) { (void)skpt; + (void)my_rank; + (void)ofs_running; // q-points are spin-free: build the point-group operations and always // double them by the time-reversal operation -q (no magnetic group). std::vector kgmatrix(48 * 2); diff --git a/source/source_cell/qlist.h b/source/source_cell/qlist.h index cfe5642b81..54844be729 100644 --- a/source/source_cell/qlist.h +++ b/source/source_cell/qlist.h @@ -135,7 +135,9 @@ class QList : public ModuleCell::ReciprocalGrid { const ModuleSymmetry::Symmetry& symm, bool use_symm, std::string& skpt, - bool& match) override; + bool& match, + const int my_rank, + std::ofstream& ofs_running) override; private: std::vector nirr_; ///< number of irreps for each q-point diff --git a/source/source_cell/reciprocal_grid.cpp b/source/source_cell/reciprocal_grid.cpp index 6f94a8769c..43015c4f26 100644 --- a/source/source_cell/reciprocal_grid.cpp +++ b/source/source_cell/reciprocal_grid.cpp @@ -170,7 +170,8 @@ void ReciprocalGrid::kvec_c2d(const ModuleBase::Matrix3& latvec) void ReciprocalGrid::set_both_kvec(const ModuleBase::Matrix3& G, const ModuleBase::Matrix3& R, std::string& skpt, - std::ofstream& ofs_running) + std::ofstream& ofs_running, + std::ofstream& ofs_warning) { // Re-derive the "which representation was read from file" flags. // For auto-generated meshes (k_nkstot == 0) the direct coordinates @@ -194,7 +195,7 @@ void ReciprocalGrid::set_both_kvec(const ModuleBase::Matrix3& G, } else { - GlobalV::ofs_warning << " Error : neither Cartesian nor Direct kpoint." << std::endl; + ofs_warning << " Error : neither Cartesian nor Direct kpoint." << std::endl; } } @@ -355,7 +356,7 @@ void ReciprocalGrid::reduce_ibz(const ModuleBase::Matrix3* rot_ops, ModuleBase::Vector3 kvec_rot_k; // update map k -> irreducible k - ibz_index.assign(this->nkstot_full, -1); // -1 means not in ibz list + ibz_index.assign(this->nkstot_nospin, -1); // -1 means not in ibz list // search in all k-points. for (int i = 0; i < this->nkstot; ++i) { diff --git a/source/source_cell/reciprocal_grid.h b/source/source_cell/reciprocal_grid.h index 020ca79e73..91e3909d5c 100644 --- a/source/source_cell/reciprocal_grid.h +++ b/source/source_cell/reciprocal_grid.h @@ -68,10 +68,13 @@ class ReciprocalGrid /// Number of points in the current pool (spin-free view). int nks = 0; - /// Total number of (symmetry-reduced) points. + /// Total number of (symmetry-reduced) points, INCLUDING spin multiplicity + /// (i.e. nkstot = nkstot_nospin * spin_mult after K_Vectors::set_kup_and_kdw). int nkstot = 0; - /// Total number of points before symmetry reduction. - int nkstot_full = 0; + /// Total number of physical k-points before symmetry reduction, + /// WITHOUT spin multiplicity. EXX/RI/LR code relies on this convention + /// (see e.g. ri_2d_comm.hpp: ik_full + is_k * nkstot_nospin). + int nkstot_nospin = 0; ReciprocalGrid() = default; virtual ~ReciprocalGrid() = default; @@ -108,7 +111,8 @@ class ReciprocalGrid void set_both_kvec(const ModuleBase::Matrix3& G, const ModuleBase::Matrix3& R, std::string& skpt, - std::ofstream& ofs_running); + std::ofstream& ofs_running, + std::ofstream& ofs_warning); /// @brief Normalize the weights so that they sum to the spin degeneracy. void normalize_wk(const int& degspin); @@ -157,7 +161,9 @@ class ReciprocalGrid const ModuleSymmetry::Symmetry& symm, bool use_symm, std::string& skpt, - bool& match) = 0; + bool& match, + const int my_rank, + std::ofstream& ofs_running) = 0; /// Whether this is a Monkhorst-Pack grid. bool is_mp = false; diff --git a/source/source_cell/test/klist_test.cpp b/source/source_cell/test/klist_test.cpp index 0978e927c8..4f25675cb4 100644 --- a/source/source_cell/test/klist_test.cpp +++ b/source/source_cell/test/klist_test.cpp @@ -133,6 +133,8 @@ class KlistTest : public testing::Test std::ifstream ifs; std::ofstream ofs; std::ofstream ofs_running; + std::ofstream ofs_warning; + int my_rank = 0; std::string output; // used to construct cell and analyse its symmetry @@ -267,7 +269,7 @@ TEST_F(KlistTest, ReadKpointsGammaOnlyLocal) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "KPT_GO"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); ifs.open("KPT_GO"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Gamma")); @@ -285,7 +287,7 @@ TEST_F(KlistTest, ReadKpointsKspacing) const double koffset[3] = {0.0, 0.0, 0.0}; setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 343); } @@ -298,7 +300,7 @@ TEST_F(KlistTest, ReadKpointsKspacing3values) const double koffset[3] = {0.0, 0.0, 0.0}; setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 210); } @@ -311,7 +313,7 @@ TEST_F(KlistTest, ReadKpointsInvalidKspacing3values) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT3"; testing::internal::CaptureStdout(); - EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank), ::testing::ExitedWithCode(1), ""); output = testing::internal::GetCapturedStdout(); } @@ -325,7 +327,7 @@ TEST_F(KlistTest, ReadKpointsKspacingShiftedGamma) setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 343); EXPECT_EQ(kv->get_k_kword(), "Gamma"); @@ -347,7 +349,7 @@ TEST_F(KlistTest, ReadKpointsKspacingShiftedMP) setucell(); std::string k_file = "./support/KPT3"; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 343); EXPECT_EQ(kv->get_k_kword(), "Monkhorst-Pack"); @@ -367,7 +369,7 @@ TEST_F(KlistTest, ReadKpointsGamma) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 512); } @@ -379,7 +381,7 @@ TEST_F(KlistTest, ReadKpointsMP) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT1"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 512); } @@ -392,7 +394,7 @@ TEST_F(KlistTest, ReadKpointsLine) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT2"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 122); } @@ -406,7 +408,7 @@ TEST_F(KlistTest, ReadKpointsLineRejectsZeroInterpolationCount) const std::string k_file = "./support/KPT_ZERO_LINE_COUNT"; kv->spin_mult = 1; - EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK), + EXPECT_EXIT(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank), ::testing::ExitedWithCode(1), ""); } @@ -420,11 +422,11 @@ TEST_F(KlistTest, ReadKpointsCartesian) std::string k_file = "./support/KPT4"; // Cartesian: non-spin case nspin=1 kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->kvec_c.size(), 5); // spin case nspin=2 kv->spin_mult = 2; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->kvec_c.size(), 10); } @@ -437,13 +439,13 @@ TEST_F(KlistTest, ReadKpointsLineCartesian) std::string k_file = "./support/KPT5"; // Line Cartesian: non-spin case nspin=1 kv->spin_mult = 1; - kv->set_kup_and_kdw(GlobalV::ofs_running); - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->set_kup_and_kdw(ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 51); EXPECT_EQ(kv->kvec_c.size(), 51); // Line Cartesian: spin case nspin=2 kv->spin_mult = 2; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 51); EXPECT_EQ(kv->kvec_c.size(), 102); } @@ -456,8 +458,8 @@ TEST_F(KlistTest, ReadKpointsDirect) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "./support/KPT6"; kv->spin_mult = 1; - kv->set_kup_and_kdw(GlobalV::ofs_running); - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->set_kup_and_kdw(ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 6); EXPECT_TRUE(kv->kd_done); } @@ -470,9 +472,9 @@ TEST_F(KlistTest, ReadKpointsWarning1) const double koffset[3] = {0.0, 0.0, 0.0}; std::string k_file = "arbitrary_1"; kv->spin_mult = 1; - GlobalV::ofs_warning.open("klist_tmp_warning_1"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); - GlobalV::ofs_warning.close(); + ofs_warning.open("klist_tmp_warning_1"); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank)); + ofs_warning.close(); ifs.open("klist_tmp_warning_1"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Can't find File name : arbitrary_1")); @@ -491,9 +493,9 @@ TEST_F(KlistTest, ReadKpointsWarning2) ofs << "ARBITRARY"; ofs.close(); kv->spin_mult = 1; - GlobalV::ofs_warning.open("klist_tmp_warning_2"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); - GlobalV::ofs_warning.close(); + ofs_warning.open("klist_tmp_warning_2"); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank)); + ofs_warning.close(); ifs.open("klist_tmp_warning_2"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("symbol K_POINTS not found.")); @@ -514,9 +516,9 @@ TEST_F(KlistTest, ReadKpointsWarning3) ofs << "100001" << std::endl; ofs.close(); kv->spin_mult = 1; - GlobalV::ofs_warning.open("klist_tmp_warning_3"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); - GlobalV::ofs_warning.close(); + ofs_warning.open("klist_tmp_warning_3"); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank)); + ofs_warning.close(); ifs.open("klist_tmp_warning_3"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("nkstot > MAX_KPOINTS")); @@ -538,9 +540,9 @@ TEST_F(KlistTest, ReadKpointsWarning4) ofs << "arbitrary" << std::endl; ofs.close(); kv->spin_mult = 1; - GlobalV::ofs_warning.open("klist_tmp_warning_4"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); - GlobalV::ofs_warning.close(); + ofs_warning.open("klist_tmp_warning_4"); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank)); + ofs_warning.close(); ifs.open("klist_tmp_warning_4"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Error: neither Gamma nor Monkhorst-Pack.")); @@ -562,9 +564,9 @@ TEST_F(KlistTest, ReadKpointsWarning5) ofs << "arbitrary" << std::endl; ofs.close(); kv->spin_mult = 1; - GlobalV::ofs_warning.open("klist_tmp_warning_5"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); - GlobalV::ofs_warning.close(); + ofs_warning.open("klist_tmp_warning_5"); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank)); + ofs_warning.close(); ifs.open("klist_tmp_warning_5"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Error : neither Cartesian nor Direct kpoint")); @@ -587,9 +589,9 @@ TEST_F(KlistTest, ReadKpointsWarning6) ofs.close(); kv->spin_mult = 1; ModuleSymmetry::Symmetry::symm_flag = 1; - GlobalV::ofs_warning.open("klist_tmp_warning_6"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); - GlobalV::ofs_warning.close(); + ofs_warning.open("klist_tmp_warning_6"); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank)); + ofs_warning.close(); ifs.open("klist_tmp_warning_6"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Line mode of k-points is open, please set symmetry to 0 or -1")); @@ -613,9 +615,9 @@ TEST_F(KlistTest, ReadKpointsWarning7) ofs.close(); kv->spin_mult = 1; ModuleSymmetry::Symmetry::symm_flag = 1; - GlobalV::ofs_warning.open("klist_tmp_warning_7"); - EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK)); - GlobalV::ofs_warning.close(); + ofs_warning.open("klist_tmp_warning_7"); + EXPECT_NO_THROW(kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank)); + ofs_warning.close(); ifs.open("klist_tmp_warning_7"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Line mode of k-points is open, please set symmetry to 0 or -1")); @@ -635,8 +637,8 @@ TEST_F(KlistTest, SetKupKdown) // case A: physical nspin=1 -> spin_mult=1 (no doubling). kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); - kv->set_kup_and_kdw(GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); + kv->set_kup_and_kdw(ofs_running); for (int ik = 0; ik < 5; ik++) { EXPECT_EQ(kv->isk[ik], 0); @@ -647,15 +649,15 @@ TEST_F(KlistTest, SetKupKdown) // so the correct spin_mult is still 1. We bypass set() here, so set the // mapped value directly. kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); - kv->set_kup_and_kdw(GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); + kv->set_kup_and_kdw(ofs_running); for (int ik = 0; ik < 5; ik++) { EXPECT_EQ(kv->isk[ik], 0); } kv->spin_mult = 2; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); - kv->set_kup_and_kdw(GlobalV::ofs_running); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); + kv->set_kup_and_kdw(ofs_running); for (int ik = 0; ik < 5; ik++) { EXPECT_EQ(kv->isk[ik], 0); @@ -667,19 +669,19 @@ TEST_F(KlistTest, SetAfterVC) { kv->spin_mult = 1; kv->set_nkstot(1); - GlobalV::ofs_running.open("tmp_klist_1"); + ofs_running.open("tmp_klist_1"); kv->renew(kv->get_nkstot()); kv->kvec_c[0].x = 0; kv->kvec_c[0].y = 0; kv->kvec_c[0].z = 0; - kv->set_after_vc(ucell.G, GlobalV::ofs_running); + kv->set_after_vc(ucell.G, ofs_running); EXPECT_TRUE(kv->kd_done); EXPECT_TRUE(kv->kc_done); EXPECT_DOUBLE_EQ(kv->kvec_d[0].x, 0); EXPECT_DOUBLE_EQ(kv->kvec_d[0].y, 0); EXPECT_DOUBLE_EQ(kv->kvec_d[0].z, 0); - GlobalV::ofs_running.close(); + ofs_running.close(); remove("tmp_klist_1"); } @@ -688,15 +690,15 @@ TEST_F(KlistTest, PrintKlists) kv->spin_mult = 1; kv->set_nkstot(1); kv->set_nks(1); - GlobalV::ofs_running.open("tmp_klist_2"); + ofs_running.open("tmp_klist_2"); kv->renew(kv->get_nkstot()); kv->kvec_c[0].x = 0; kv->kvec_c[0].y = 0; kv->kvec_c[0].z = 0; - kv->set_after_vc(ucell.G, GlobalV::ofs_running); + kv->set_after_vc(ucell.G, ofs_running); EXPECT_TRUE(kv->kd_done); - kv->print_klists(GlobalV::ofs_running); - GlobalV::ofs_running.close(); + kv->print_klists(ofs_running); + ofs_running.close(); remove("tmp_klist_2"); } @@ -710,7 +712,7 @@ TEST_F(KlistTest, PrintKlistsWarnigQuit) kv->kvec_c[0].y = 0; kv->kvec_c[0].z = 0; testing::internal::CaptureStdout(); - EXPECT_EXIT(kv->print_klists(GlobalV::ofs_running), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(kv->print_klists(ofs_running), ::testing::ExitedWithCode(1), ""); output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("nkstot < nks")); } @@ -732,29 +734,29 @@ TEST_F(KlistTest, SetBothKvecFlagsFromFile) kv->kc_done = false; // case 1 kv->k_nkstot = 0; -// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); - kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); +// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); + kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); EXPECT_TRUE(kv->kd_done); EXPECT_TRUE(kv->kc_done); // case 2 kv->k_nkstot = 1; kv->k_kword = "D"; -// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); - kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); +// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); + kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); EXPECT_TRUE(kv->kd_done); EXPECT_TRUE(kv->kc_done); // case 3 kv->k_kword = "C"; -// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); - kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); +// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); + kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); EXPECT_TRUE(kv->kc_done); EXPECT_TRUE(kv->kd_done); // case 4 - GlobalV::ofs_warning.open("klist_tmp_warning_8"); + ofs_warning.open("klist_tmp_warning_8"); kv->k_kword = "arbitrary"; -// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); - kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); - GlobalV::ofs_warning.close(); +// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); + kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); + ofs_warning.close(); ifs.open("klist_tmp_warning_8"); std::string str((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_THAT(str, testing::HasSubstr("Error : neither Cartesian nor Direct kpoint.")); @@ -774,13 +776,13 @@ TEST_F(KlistTest, SetBothKvec) kv->kc_done = false; kv->kd_done = true; std::string skpt; -// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); - kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); +// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); + kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); EXPECT_TRUE(kv->kc_done); kv->kc_done = true; kv->kd_done = false; -// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); - kv->set_both_kvec(ucell.G, ucell.latvec, skpt, GlobalV::ofs_running); +// kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); + kv->set_both_kvec(ucell.G, ucell.latvec, skpt, ofs_running, ofs_warning); EXPECT_TRUE(kv->kd_done); } @@ -830,7 +832,7 @@ TEST_F(KlistTest, UpdateUseIBZ) kv->set_nkstot(3); kv->set_nks(3); kv->renew(kv->get_nkstot()); - kv->update_use_ibz(2, std::vector>(2, {0, 0, 0}), std::vector(2, 0.0), GlobalV::ofs_running); + kv->update_use_ibz(2, std::vector>(2, {0, 0, 0}), std::vector(2, 0.0), ofs_running, my_rank); EXPECT_EQ(kv->get_nkstot(), 2); EXPECT_EQ(kv->kvec_d.size(), 2); EXPECT_TRUE(kv->kd_done); @@ -845,21 +847,21 @@ TEST_F(KlistTest, IbzKpoint) const double koffset[3] = {0.0, 0.0, 0.0}; ModuleSymmetry::Symmetry symm; construct_ucell(stru_lib[0]); - GlobalV::ofs_running.open("tmp_klist_3"); + ofs_running.open("tmp_klist_3"); const int cal_symm_repr[2] = {0, 6}; - symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); + symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, ofs_running, 1e-6, 1, "scf", cal_symm_repr); std::string k_file = "./support/KPT1"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 512); // calculate ibz_kpoint std::string skpt; ModuleSymmetry::Symmetry::symm_flag = 1; bool match = true; - kv->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + kv->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match, my_rank, ofs_running); EXPECT_EQ(kv->get_nkstot(), 35); - GlobalV::ofs_running << skpt << std::endl; - GlobalV::ofs_running.close(); + ofs_running << skpt << std::endl; + ofs_running.close(); ClearUcell(); remove("tmp_klist_3"); } @@ -872,22 +874,22 @@ TEST_F(KlistTest, IbzKpointIsMP) const double koffset[3] = {0.0, 0.0, 0.0}; ModuleSymmetry::Symmetry symm; construct_ucell(stru_lib[0]); - GlobalV::ofs_running.open("tmp_klist_4"); + ofs_running.open("tmp_klist_4"); const int cal_symm_repr[2] = {0, 6}; - symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); + symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, ofs_running, 1e-6, 1, "scf", cal_symm_repr); std::string k_file = "./support/KPT1"; kv->spin_mult = 1; - kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv->read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv->get_nkstot(), 512); EXPECT_TRUE(kv->is_mp); // calculate ibz_kpoint std::string skpt; ModuleSymmetry::Symmetry::symm_flag = 0; bool match = true; - kv->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + kv->reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match, my_rank, ofs_running); EXPECT_EQ(kv->get_nks(), 260); - GlobalV::ofs_running << skpt << std::endl; - GlobalV::ofs_running.close(); + ofs_running << skpt << std::endl; + ofs_running.close(); ClearUcell(); remove("tmp_klist_4"); } @@ -900,16 +902,16 @@ TEST_F(KlistTest, IbzKpointCustomWeights) const double koffset[3] = {0.0, 0.0, 0.0}; ModuleSymmetry::Symmetry symm; construct_ucell(stru_lib[0]); - GlobalV::ofs_running.open("tmp_klist_custom_weights"); + ofs_running.open("tmp_klist_custom_weights"); const int cal_symm_repr[2] = {0, 6}; - symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, 1e-6, 1, "scf", cal_symm_repr); + symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, ofs_running, 1e-6, 1, "scf", cal_symm_repr); // Test 1: Non-MP k-points with uniform weights (KPT4) { K_Vectors kv_test1; std::string k_file = "./support/KPT4"; kv_test1.spin_mult = 1; - kv_test1.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv_test1.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv_test1.get_nkstot(), 5); EXPECT_FALSE(kv_test1.is_mp); // Should be non-MP @@ -920,7 +922,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) std::string skpt; ModuleSymmetry::Symmetry::symm_flag = 1; bool match = true; - kv_test1.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + kv_test1.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match, my_rank, ofs_running); // Verify that weights are preserved (not overwritten with 1/nkstot) // After IBZ reduction, weights should still reflect the input weights @@ -938,7 +940,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) K_Vectors kv_test2; std::string k_file = "./support/KPT_custom_weights"; kv_test2.spin_mult = 1; - kv_test2.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv_test2.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv_test2.get_nkstot(), 5); EXPECT_FALSE(kv_test2.is_mp); // Should be non-MP @@ -961,7 +963,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) std::string skpt; ModuleSymmetry::Symmetry::symm_flag = 1; bool match = true; - kv_test2.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + kv_test2.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match, my_rank, ofs_running); // After IBZ reduction, the weights should be based on the custom input weights, // not uniform 1/nkstot weights. The total weight should be preserved. @@ -995,7 +997,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) K_Vectors kv_test3; std::string k_file = "./support/KPT1"; kv_test3.spin_mult = 1; - kv_test3.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv_test3.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); EXPECT_EQ(kv_test3.get_nkstot(), 512); EXPECT_TRUE(kv_test3.is_mp); // Should be MP @@ -1003,7 +1005,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) std::string skpt; ModuleSymmetry::Symmetry::symm_flag = 1; bool match = true; - kv_test3.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + kv_test3.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match, my_rank, ofs_running); // For MP grids, all weights should be uniform after IBZ reduction EXPECT_EQ(kv_test3.get_nkstot(), 35); // Known result from existing test @@ -1022,13 +1024,13 @@ TEST_F(KlistTest, IbzKpointCustomWeights) K_Vectors kv_test4; std::string k_file = "./support/KPT_custom_weights"; kv_test4.spin_mult = 1; - kv_test4.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, GlobalV::ofs_running, GlobalV::ofs_warning, GlobalV::MY_RANK); + kv_test4.read_kpoints(ucell, k_file, gamma_only_local, kspacing, kmesh_type, koffset, ofs_running, ofs_warning, my_rank); // Apply IBZ reduction std::string skpt; ModuleSymmetry::Symmetry::symm_flag = 1; bool match = true; - kv_test4.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match); + kv_test4.reduce_by_symmetry(ucell, symm, ModuleSymmetry::Symmetry::symm_flag, skpt, match, my_rank, ofs_running); // Normalize weights int degspin = (kv_test4.spin_mult == 2) ? 1 : 2; @@ -1043,7 +1045,7 @@ TEST_F(KlistTest, IbzKpointCustomWeights) EXPECT_NEAR(total_weight, degspin, 1e-10); } - GlobalV::ofs_running.close(); + ofs_running.close(); ClearUcell(); remove("tmp_klist_custom_weights"); } diff --git a/source/source_cell/test/klist_test_para.cpp b/source/source_cell/test/klist_test_para.cpp index 8879638fd8..2ebc0c609b 100644 --- a/source/source_cell/test/klist_test_para.cpp +++ b/source/source_cell/test/klist_test_para.cpp @@ -207,10 +207,10 @@ TEST_F(KlistParaTest, Set) const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; - kv->set(ucell, symm, k_file, /*nspin_in*/ 1, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); + kv->set(ucell, symm, k_file, /*nspin_in*/ 1, ucell.G, ucell.latvec, GlobalV::ofs_running, GlobalV::ofs_warning, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); EXPECT_EQ(kv->get_nkstot(), 35); - EXPECT_EQ(kv->get_nkstot_full(), 512); - EXPECT_GT(kv->get_nkstot_full(), kv->get_nkstot()); + EXPECT_EQ(kv->get_nkstot_nospin(), 512); + EXPECT_GT(kv->get_nkstot_nospin(), kv->get_nkstot()); EXPECT_TRUE(kv->kc_done); EXPECT_TRUE(kv->kd_done); if (GlobalV::NPROC == 4) @@ -331,7 +331,7 @@ TEST_F(KlistParaTest, SetAfterVC) const double kspacing[3] = {0.0, 0.0, 0.0}; const std::string kmesh_type = "gamma"; const double koffset[3] = {0.0, 0.0, 0.0}; - kv->set(ucell, symm, k_file, /*nspin_in*/ 1, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); + kv->set(ucell, symm, k_file, /*nspin_in*/ 1, ucell.G, ucell.latvec, GlobalV::ofs_running, GlobalV::ofs_warning, use_ibz, global_out_dir, gamma_only_local, kspacing, kmesh_type, koffset); EXPECT_EQ(kv->get_nkstot(), 35); EXPECT_TRUE(kv->kc_done); EXPECT_TRUE(kv->kd_done); diff --git a/source/source_cell/test/qlist_test.cpp b/source/source_cell/test/qlist_test.cpp index 8e828356a2..c9c07e6dff 100644 --- a/source/source_cell/test/qlist_test.cpp +++ b/source/source_cell/test/qlist_test.cpp @@ -180,7 +180,7 @@ TEST_F(QListTest, GenerateMeshFullSymmetry) qlist.generate_mesh(ucell, symm, {8, 8, 8}, true); // full mesh 512 -> irreducible q-points of the primitive cubic lattice - EXPECT_EQ(qlist.nkstot_full, 512); + EXPECT_EQ(qlist.nkstot_nospin, 512); EXPECT_EQ(qlist.get_nq(), 35); EXPECT_EQ(qlist.get_nq(), qlist.nkstot); EXPECT_TRUE(qlist.is_mp); @@ -218,7 +218,7 @@ TEST_F(QListTest, GenerateMeshSmallGrid) qlist.generate_mesh(ucell, symm, {2, 2, 2}, true); // {0,0.5}^3 under O_h folds to Gamma + X + M + R - EXPECT_EQ(qlist.nkstot_full, 8); + EXPECT_EQ(qlist.nkstot_nospin, 8); EXPECT_EQ(qlist.get_nq(), 4); // the first irreducible q-point must be Gamma (0,0,0) @@ -241,7 +241,7 @@ TEST_F(QListTest, GammaOnlyGrid) qlist.generate_mesh(ucell, symm, {1, 1, 1}, true); - EXPECT_EQ(qlist.nkstot_full, 1); + EXPECT_EQ(qlist.nkstot_nospin, 1); EXPECT_EQ(qlist.get_nq(), 1); EXPECT_DOUBLE_EQ(qlist.wk[0], 1.0); EXPECT_DOUBLE_EQ(qlist.get_q(0).x, 0.0); diff --git a/source/source_cell/test/reciprocal_grid_test.cpp b/source/source_cell/test/reciprocal_grid_test.cpp index c369bf5ff4..05525749d3 100644 --- a/source/source_cell/test/reciprocal_grid_test.cpp +++ b/source/source_cell/test/reciprocal_grid_test.cpp @@ -66,7 +66,9 @@ class TestGrid : public ModuleCell::ReciprocalGrid const ModuleSymmetry::Symmetry&, bool, std::string&, - bool&) override + bool&, + const int, + std::ofstream&) override { } }; @@ -81,7 +83,7 @@ TEST_F(ReciprocalGridTest, Construct) { EXPECT_EQ(grid.nks, 0); EXPECT_EQ(grid.nkstot, 0); - EXPECT_EQ(grid.nkstot_full, 0); + EXPECT_EQ(grid.nkstot_nospin, 0); EXPECT_FALSE(grid.kc_done); EXPECT_FALSE(grid.kd_done); EXPECT_FALSE(grid.is_mp); @@ -214,7 +216,7 @@ TEST_F(ReciprocalGridTest, ReduceIbzNonMp) grid.is_mp = false; grid.nkstot = 2; - grid.nkstot_full = 2; + grid.nkstot_nospin = 2; grid.kvec_d.resize(2); grid.kvec_d[0] = ModuleBase::Vector3(0.25, 0.25, 0.25); grid.kvec_d[1] = ModuleBase::Vector3(-0.25, -0.25, -0.25); @@ -244,7 +246,7 @@ TEST_F(ReciprocalGridTest, ReduceIbzKeepsDistinctPoints) grid.is_mp = false; grid.nkstot = 2; - grid.nkstot_full = 2; + grid.nkstot_nospin = 2; grid.kvec_d.resize(2); grid.kvec_d[0] = ModuleBase::Vector3(0.25, 0.25, 0.25); grid.kvec_d[1] = ModuleBase::Vector3(0.50, 0.50, 0.50); @@ -281,7 +283,7 @@ TEST_F(ReciprocalGridTest, ReduceIbzMpKLattice) const double offset[3] = {0.0, 0.0, 0.0}; grid.Monkhorst_Pack(nmp, offset, 0); // sets nkstot=8, wk=1/8, kd_done grid.is_mp = true; - grid.nkstot_full = grid.nkstot; + grid.nkstot_nospin = grid.nkstot; // k-lattice basis of the 2x2x2 mesh: G/2 along each reciprocal axis. // In this diagonal frame the k-lattice rotations equal the reciprocal ones. diff --git a/source/source_esolver/esolver_fp.cpp b/source/source_esolver/esolver_fp.cpp index 7150c8b900..779f62f292 100644 --- a/source/source_esolver/esolver_fp.cpp +++ b/source/source_esolver/esolver_fp.cpp @@ -97,7 +97,7 @@ void ESolver_FP::before_all_runners(BaseCell& basecell, const Input_para& inp) const bool gamma_only_local = PARAM.globalv.gamma_only_local; const double kspacing[3] = {this->inp_->kspacing[0], this->inp_->kspacing[1], this->inp_->kspacing[2]}; const double koffset[3] = {this->inp_->koffset[0], this->inp_->koffset[1], this->inp_->koffset[2]}; - this->kv.set(ucell, ucell.symm, inp.kpoint_file, inp.nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, global_out_dir, gamma_only_local, kspacing, this->inp_->kmesh_type, koffset); + this->kv.set(ucell, ucell.symm, inp.kpoint_file, inp.nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, GlobalV::ofs_warning, use_ibz, global_out_dir, gamma_only_local, kspacing, this->inp_->kmesh_type, koffset); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); //! 8) print information diff --git a/source/source_esolver/esolver_gets.cpp b/source/source_esolver/esolver_gets.cpp index b1cdceea24..85649f960c 100644 --- a/source/source_esolver/esolver_gets.cpp +++ b/source/source_esolver/esolver_gets.cpp @@ -91,6 +91,7 @@ void ESolver_GetS::before_all_runners(BaseCell& basecell, const Input_para& inp) ucell.G, ucell.latvec, GlobalV::ofs_running, + GlobalV::ofs_warning, use_ibz, global_out_dir, gamma_only_local, diff --git a/source/source_esolver/esolver_lr_lcao_tddft.cpp b/source/source_esolver/esolver_lr_lcao_tddft.cpp index 52bd6ad0e8..6953a2d8df 100644 --- a/source/source_esolver/esolver_lr_lcao_tddft.cpp +++ b/source/source_esolver/esolver_lr_lcao_tddft.cpp @@ -373,7 +373,7 @@ void ModuleESolver::ESolver_LR::initialize_from_unitcell_(UnitCell& ucell const bool gamma_only_local = PARAM.globalv.gamma_only_local; const double kspacing[3] = {this->inp_->kspacing[0], this->inp_->kspacing[1], this->inp_->kspacing[2]}; const double koffset[3] = {this->inp_->koffset[0], this->inp_->koffset[1], this->inp_->koffset[2]}; - this->kv.set(ucell, ucell.symm, this->inp_->kpoint_file, this->inp_->nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, this->out_dir, gamma_only_local, kspacing, this->inp_->kmesh_type, koffset); + this->kv.set(ucell, ucell.symm, this->inp_->kpoint_file, this->inp_->nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, GlobalV::ofs_warning, use_ibz, this->out_dir, gamma_only_local, kspacing, this->inp_->kmesh_type, koffset); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); ModuleIO::print_parameters(ucell, this->kv, inp); diff --git a/source/source_io/module_dm/test/write_dmk_test.cpp b/source/source_io/module_dm/test/write_dmk_test.cpp index 606b195d52..e03f053055 100644 --- a/source/source_io/module_dm/test/write_dmk_test.cpp +++ b/source/source_io/module_dm/test/write_dmk_test.cpp @@ -156,7 +156,7 @@ TEST(DMKTest,WriteDMK) { const int istep = -1; K_Vectors kv; kv.set_nkstot(1); - kv.set_nkstot_full(1); + kv.set_nkstot_nospin(1); kv.set_nks(1); kv.spin_mult = 2; kv.kvec_c.resize(1); diff --git a/source/source_io/module_dm/write_dmk.cpp b/source/source_io/module_dm/write_dmk.cpp index ac58816fb9..1d3a40b32b 100644 --- a/source/source_io/module_dm/write_dmk.cpp +++ b/source/source_io/module_dm/write_dmk.cpp @@ -257,7 +257,7 @@ void ModuleIO::write_dmk(const std::vector>& dmk, // information about density matrix at this k-point ofs << " " << nspin << " # number of spin directions" << std::endl; ofs << " " << ispin+1 << " # spin index" << std::endl; - ofs << " " << kv.get_nkstot_full() << " # total k points " << std::endl; + ofs << " " << kv.get_nkstot_nospin() << " # total k points " << std::endl; ofs << " " << kv.get_nkstot() << " # total k points after symmetrized (if open) " << std::endl; ofs << " " << ik+1 << " # k-point index " << std::endl; ofs << " " << kv.kvec_c[ik].x << " " << kv.kvec_c[ik].y << " " << kv.kvec_c[ik].z diff --git a/source/source_lcao/module_bse/molecular_lri.hpp b/source/source_lcao/module_bse/molecular_lri.hpp index 3f692d76db..a2efe734bb 100644 --- a/source/source_lcao/module_bse/molecular_lri.hpp +++ b/source/source_lcao/module_bse/molecular_lri.hpp @@ -160,7 +160,7 @@ void MolecularLRI::build_q_to_kpair_map(int mode, double threshold) { std::set q_coarse_set; const K_Vectors& kv_coarse = this->kRlist.klist_coarse; - int nk_coarse = kv_coarse.get_nkstot_full(); + int nk_coarse = kv_coarse.get_nkstot_nospin(); for (int ik1 = 0; ik1 < nk_coarse; ++ik1) { Tk ck1 = RI_Util::Vector3_to_array3(kv_coarse.kvec_d.at(ik1)); diff --git a/source/source_lcao/module_deepks/test/deepks_test_prep.cpp b/source/source_lcao/module_deepks/test/deepks_test_prep.cpp index bcb0f9c25e..8eee372285 100644 --- a/source/source_lcao/module_deepks/test/deepks_test_prep.cpp +++ b/source/source_lcao/module_deepks/test/deepks_test_prep.cpp @@ -319,6 +319,7 @@ void test_deepks::setup_kpt() ucell.G, ucell.latvec, GlobalV::ofs_running, + GlobalV::ofs_warning, use_ibz, global_out_dir, gamma_only_local, diff --git a/source/source_lcao/module_lr/utils/lr_io.cpp b/source/source_lcao/module_lr/utils/lr_io.cpp index 2c61478e7d..9d818c043c 100644 --- a/source/source_lcao/module_lr/utils/lr_io.cpp +++ b/source/source_lcao/module_lr/utils/lr_io.cpp @@ -165,7 +165,7 @@ void RI_kRlist::read_kpts_fine(const std::string& file, const UnitCell& ucell, int nks = (PARAM.inp.nspin == 2) ? 2 * nk : nk; klist->set_nks(nks); klist->set_nkstot(nks); - klist->set_nkstot_full(nk); + klist->set_nkstot_nospin(nk); auto klist_reset = [&klist](int kpoint_number){ klist->kvec_c.resize(0); klist->kvec_c.resize(kpoint_number); diff --git a/source/source_lcao/module_rdmft/rdmft.cpp b/source/source_lcao/module_rdmft/rdmft.cpp index b88440a88f..5a27d9d86f 100644 --- a/source/source_lcao/module_rdmft/rdmft.cpp +++ b/source/source_lcao/module_rdmft/rdmft.cpp @@ -81,7 +81,7 @@ void RDMFT::init(Parallel_Orbitals& ParaV_in, nspin = PARAM.inp.nspin; nbands_total = PARAM.inp.nbands; - nk_total = ModuleSymmetry::Symmetry::symm_flag == -1 ? kv->get_nkstot_full(): kv->get_nks(); + nk_total = ModuleSymmetry::Symmetry::symm_flag == -1 ? kv->get_nkstot_nospin(): kv->get_nks(); nk_total *= nspin; only_exx_type = ( XC_func_rdmft == "hf" || XC_func_rdmft == "muller" || XC_func_rdmft == "power" ); diff --git a/source/source_lcao/module_ri/ewald_vq.hpp b/source/source_lcao/module_ri/ewald_vq.hpp index 584d8a2880..5e8e091b1a 100644 --- a/source/source_lcao/module_ri/ewald_vq.hpp +++ b/source/source_lcao/module_ri/ewald_vq.hpp @@ -48,7 +48,7 @@ void Ewald_Vq::init(const UnitCell& ucell, this->mpi_comm = mpi_comm_in; this->p_kv = kv_in; - this->nks0 = this->p_kv->get_nkstot_full(); + this->nks0 = this->p_kv->get_nkstot_nospin(); this->kvec_c.resize(this->nks0); this->ccp_rmesh_times = ccp_rmesh_times_in; this->abfs_Lmax = abfs_Lmax_in; diff --git a/source/source_lcao/module_ri/exx_lri.hpp b/source/source_lcao/module_ri/exx_lri.hpp index 21c8afbb1c..9cb8f75d72 100644 --- a/source/source_lcao/module_ri/exx_lri.hpp +++ b/source/source_lcao/module_ri/exx_lri.hpp @@ -364,7 +364,7 @@ void Exx_LRI::cal_exx_ions(const UnitCell& ucell, std::cout << "Coulomb: number of atom-pairs inside atomic overlap is " << flag << ". " << std::endl; if (this->info.coul_moment == true) { - double hf_Rcut = std::pow(0.75 * this->p_kv->get_nkstot_full() * ucell.omega / (ModuleBase::PI), 1.0 / 3.0); + double hf_Rcut = std::pow(0.75 * this->p_kv->get_nkstot_nospin() * ucell.omega / (ModuleBase::PI), 1.0 / 3.0); // To cal Cs, we still cal all Vs(R) in r space // moment_abfs->cal_VR(ucell, // this->abfs, @@ -532,7 +532,7 @@ void Exx_LRI::cal_ewald_coulomb( std::cout << "Coulomb: number of atom-pairs inside atomic overlap is " << flag << ". " << std::endl; if (this->info.coul_moment == true) { - double hf_Rcut = std::pow(0.75 * this->p_kv->get_nkstot_full() * ucell.omega / (ModuleBase::PI), 1.0 / 3.0); + double hf_Rcut = std::pow(0.75 * this->p_kv->get_nkstot_nospin() * ucell.omega / (ModuleBase::PI), 1.0 / 3.0); // To cal Cs, we still cal all Vs(R) in r space // moment_abfs->cal_VR(ucell, // this->abfs, diff --git a/source/source_lcao/module_ri/exx_lri_detail.cpp b/source/source_lcao/module_ri/exx_lri_detail.cpp index ff8046159b..d459fc8379 100644 --- a/source/source_lcao/module_ri/exx_lri_detail.cpp +++ b/source/source_lcao/module_ri/exx_lri_detail.cpp @@ -16,7 +16,7 @@ namespace ExxLriDetail double default_spencer_rcut(const UnitCell& ucell, const K_Vectors& kv) { - return std::pow(0.75 * kv.get_nkstot_full() * ucell.omega / (ModuleBase::PI), 1.0 / 3.0); + return std::pow(0.75 * kv.get_nkstot_nospin() * ucell.omega / (ModuleBase::PI), 1.0 / 3.0); } CoulombParam build_center2_cut_coulomb_param(const CoulombParam& coulomb_param, diff --git a/source/source_lcao/module_ri/exx_lri_interface.hpp b/source/source_lcao/module_ri/exx_lri_interface.hpp index 32320fab5f..f00011ab83 100644 --- a/source/source_lcao/module_ri/exx_lri_interface.hpp +++ b/source/source_lcao/module_ri/exx_lri_interface.hpp @@ -156,7 +156,7 @@ void Exx_LRI_Interface::exx_beforescf(const int istep, if(this->info_global.cal_exx) { if (this->exx_spacegroup_symmetry) - { this->mix_DMk_2D.set_nks(kv.get_nkstot_full() * (PARAM.inp.nspin == 2 ? 2 : 1)); } + { this->mix_DMk_2D.set_nks(kv.get_nkstot_nospin() * (PARAM.inp.nspin == 2 ? 2 : 1)); } else { this->mix_DMk_2D.set_nks(kv.get_nks()); } diff --git a/source/source_lcao/module_ri/module_exx_symmetry/symm_rotation.cpp b/source/source_lcao/module_ri/module_exx_symmetry/symm_rotation.cpp index 4a88554624..18eb826888 100644 --- a/source/source_lcao/module_ri/module_exx_symmetry/symm_rotation.cpp +++ b/source/source_lcao/module_ri/module_exx_symmetry/symm_rotation.cpp @@ -98,7 +98,7 @@ namespace ModuleSymmetry ModuleBase::timer::start("Symmetry_rotation", "restore_dm"); std::vector>> dm_k_full; int nspin0 = PARAM.inp.nspin == 2 ? 2 : 1; - dm_k_full.reserve(kv.get_nkstot_full() * nspin0); //nkstot_full didn't doubled by spin + dm_k_full.reserve(kv.get_nkstot_nospin() * nspin0); //nkstot_nospin didn't doubled by spin int nk = kv.get_nkstot() / nspin0; // (nspin=4) Sigma_y = I (x) sigma_y for the time-reversal spin flip; k-independent, build once. diff --git a/source/source_lcao/module_ri/ri_2d_comm.hpp b/source/source_lcao/module_ri/ri_2d_comm.hpp index fcb33684ed..64cdc8786e 100644 --- a/source/source_lcao/module_ri/ri_2d_comm.hpp +++ b/source/source_lcao/module_ri/ri_2d_comm.hpp @@ -196,7 +196,7 @@ auto RI_2D_Comm::split_m2D_ktoR_k(const UnitCell& ucell, const Tdata_m frac = SPIN_multiple * RI::Global_Func::convert(std::exp( -ModuleBase::TWO_PI * ModuleBase::IMAG_UNIT * (kv.kvec_c[ik] * (RI_Util::array3_to_Vector3(cell) * ucell.latvec)))); - if (static_cast(std::round(SPIN_multiple * kv.wk[ik] * kv.get_nkstot_full())) == 2) + if (static_cast(std::round(SPIN_multiple * kv.wk[ik] * kv.get_nkstot_nospin())) == 2) { set_mR_2D(mk_2D * (frac * 0.5) + tensor_conj(mk_2D * (frac * 0.5))); } else { set_mR_2D(mk_2D * frac); } @@ -205,7 +205,7 @@ auto RI_2D_Comm::split_m2D_ktoR_k(const UnitCell& ucell, { // traverse kstar, ik means ik_ibz for (auto& isym_kvd : kv.kstars[ik % ik_list.size()]) { - RI::Tensor mk_2D = RI_Util::Vector_to_Tensor(*mks_2D[ik_full + is_k * kv.get_nkstot_full()], pv.get_col_size(), pv.get_row_size()); + RI::Tensor mk_2D = RI_Util::Vector_to_Tensor(*mks_2D[ik_full + is_k * kv.get_nkstot_nospin()], pv.get_col_size(), pv.get_row_size()); const Tdata_m frac = SPIN_multiple * RI::Global_Func::convert(std::exp( -ModuleBase::TWO_PI * ModuleBase::IMAG_UNIT * ((isym_kvd.second * ucell.G) * (RI_Util::array3_to_Vector3(cell) * ucell.latvec)))); diff --git a/source/source_lcao/module_ri/ri_util.hpp b/source/source_lcao/module_ri/ri_util.hpp index 6baf57c3d7..886c5f1b37 100644 --- a/source/source_lcao/module_ri/ri_util.hpp +++ b/source/source_lcao/module_ri/ri_util.hpp @@ -82,7 +82,7 @@ namespace RI_Util { // 4/3 * pi * Rcut^3 = V_{supercell} = V_{unitcell} * Nk const int nspin0 = (PARAM.inp.nspin==2) ? 2 : 1; - const double Rcut = std::pow(0.75 * p_kv->get_nkstot_full() * ucell.omega / (ModuleBase::PI), 1.0/3.0); + const double Rcut = std::pow(0.75 * p_kv->get_nkstot_nospin() * ucell.omega / (ModuleBase::PI), 1.0/3.0); param["Rcut"] = ModuleBase::GlobalFunc::TO_STRING(Rcut); } else if(param.at("singularity_correction") == "revised_spencer") diff --git a/source/source_lcao/module_ri/rpa_lri.hpp b/source/source_lcao/module_ri/rpa_lri.hpp index c2fa83ce8c..a5bf037d1c 100644 --- a/source/source_lcao/module_ri/rpa_lri.hpp +++ b/source/source_lcao/module_ri/rpa_lri.hpp @@ -122,7 +122,7 @@ void RPA_LRI::cal_postSCF_exx(const elecstate::DensityMatrix Mix_DMk_2D mix_DMk_2D; bool exx_spacegroup_symmetry = (PARAM.inp.nspin < 4 && ModuleSymmetry::Symmetry::symm_flag == 1); if (exx_spacegroup_symmetry) - {mix_DMk_2D.set_nks(kv.get_nkstot_full() * (PARAM.inp.nspin == 2 ? 2 : 1));} + {mix_DMk_2D.set_nks(kv.get_nkstot_nospin() * (PARAM.inp.nspin == 2 ? 2 : 1));} else {mix_DMk_2D.set_nks(kv.get_nks());} diff --git a/source/source_pw/module_pwdft/dftu_base.cpp b/source/source_pw/module_pwdft/dftu_base.cpp index 4a0282c888..a249a9bc3b 100644 --- a/source/source_pw/module_pwdft/dftu_base.cpp +++ b/source/source_pw/module_pwdft/dftu_base.cpp @@ -81,13 +81,14 @@ void Plus_U_Base::init_base(UnitCell& cell, { const int iat = cell.itia2iat(it, ia); - if(!has_correlated_orbital(it)) + const int target_l = this->orbital_corr[it]; + if (target_l == -1) { continue; } - const int tlp1_npol = (get_orbital_corr(it)*2+1)*npol; - const int tlp1 = 2 * get_orbital_corr(it) + 1; + const int tlp1_npol = (target_l * 2 + 1) * npol; + const int tlp1 = 2 * target_l + 1; const int elem_size = tlp1 * tlp1; if(nspin == 4) { @@ -147,7 +148,7 @@ void Plus_U_Base::init_base(UnitCell& cell, DFTU_BASE::local_occup_bcast(cell, this->occmat_, this->orbital_corr, nspin, npol); #endif - mark_occ_mat_initialized(); + this->occ_mat_initialized = true; this->occmat_.copy_to_save(cell, this->orbital_corr); this->occmat_.write_save_to_flat(cell, this->orbital_corr, this->pot_uterm_pw_index, this->uom_save); @@ -163,7 +164,7 @@ void Plus_U_Base::init_base(UnitCell& cell, #ifdef __MPI DFTU_BASE::local_occup_bcast(cell, this->occmat_, this->orbital_corr, nspin, npol); #endif - mark_occ_mat_initialized(); + this->occ_mat_initialized = true; } else { @@ -172,18 +173,19 @@ void Plus_U_Base::init_base(UnitCell& cell, } ModuleBase::Memory::record("Plus_U_Base::occ_mat", sizeof(double) * num_locale); - return; } void Plus_U_Base::uramping_update() { // Yukawa calculates U directly every iteration, no need for ramping - if (use_yukawa()) { + if (this->yukawa_ != nullptr) + { return; } // if uramping < 0.1, use the original U - if (this->uramping < 0.01) { + if (this->uramping < 0.01) + { return; } // loop to change U @@ -204,7 +206,8 @@ void Plus_U_Base::uramping_update() bool Plus_U_Base::u_converged() { // Yukawa calculates U directly every iteration, always considered converged - if (use_yukawa()) { + if (this->yukawa_ != nullptr) + { return true; } for (int i = 0; i < static_cast(this->u_target.size()); i++) diff --git a/source/source_pw/module_pwdft/dftu_base.h b/source/source_pw/module_pwdft/dftu_base.h index f91ecf6ad3..25671655fb 100644 --- a/source/source_pw/module_pwdft/dftu_base.h +++ b/source/source_pw/module_pwdft/dftu_base.h @@ -113,7 +113,6 @@ class Plus_U_Base void mark_occ_mat_initialized() { occ_mat_initialized = true; } void mark_occ_mat_dirty() { occ_mat_initialized = false; } - bool is_mixing_enabled() const { return mixing_dftu != 0; } void enable_mixing() { mixing_dftu = 1; } /// direct access to the occupation matrix object (new write path) diff --git a/source/source_pw/module_pwdft/dftu_base_occ.cpp b/source/source_pw/module_pwdft/dftu_base_occ.cpp index 42b40e96a4..bb9e63b09c 100644 --- a/source/source_pw/module_pwdft/dftu_base_occ.cpp +++ b/source/source_pw/module_pwdft/dftu_base_occ.cpp @@ -57,7 +57,7 @@ void Plus_U_Base::cal_occ_pw(const void* psi_in, this->pot_uterm_pw_index, this->uom_array); // mixing - if(is_mixing_enabled() && p_chgmix != nullptr) + if (this->mixing_dftu != 0 && p_chgmix != nullptr) { p_chgmix->mix_uom(this->uom_array, this->uom_save); this->occmat_.read_from_flat(cell, this->orbital_corr, diff --git a/source/source_pw/module_pwdft/op_pw_exx.cpp b/source/source_pw/module_pwdft/op_pw_exx.cpp index cafbc997ee..94f19ce3de 100644 --- a/source/source_pw/module_pwdft/op_pw_exx.cpp +++ b/source/source_pw/module_pwdft/op_pw_exx.cpp @@ -314,7 +314,7 @@ void OperatorEXXPW::act_op_kpar(const int nbands, // std::map, bool> has_real; setmem_complex_op()(psi_nk_real, 0, wfcpw->nrxx); setmem_complex_op()(psi_mq_real, 0, wfcpw->nrxx); - int nqs = kv->get_nkstot_full(); + int nqs = kv->get_nkstot_nospin(); int nspin_fac = PARAM.inp.nspin == 2 ? 2 : 1; int ispin = this->ik < (wfcpw->nks / nspin_fac) ? 0 : 1; diff --git a/source/source_pw/module_pwdft/op_pw_exx_ace.cpp b/source/source_pw/module_pwdft/op_pw_exx_ace.cpp index 55917e5b7c..67322bdc49 100644 --- a/source/source_pw/module_pwdft/op_pw_exx_ace.cpp +++ b/source/source_pw/module_pwdft/op_pw_exx_ace.cpp @@ -140,7 +140,7 @@ void OperatorEXXPW::construct_ace() const setmem_complex_op()(density_recip, 0, rhopw_dev->npw); setmem_complex_op()(psi_nk_real, 0, wfcpw->nrxx); setmem_complex_op()(psi_mq_real, 0, wfcpw->nrxx); - int nqs = kv->get_nkstot_full(); + int nqs = kv->get_nkstot_nospin(); bool skip_ik = false; if (ik >= wfcpw->nks) diff --git a/source/source_pw/module_pwdft/op_pw_exx_pot.cpp b/source/source_pw/module_pwdft/op_pw_exx_pot.cpp index 216617eaa9..fd76372e31 100644 --- a/source/source_pw/module_pwdft/op_pw_exx_pot.cpp +++ b/source/source_pw/module_pwdft/op_pw_exx_pot.cpp @@ -505,7 +505,7 @@ double exx_divergence(Conv_Coulomb_Pot_K::Coulomb_Type coulomb_type, } } - div *= ModuleBase::e2 * ModuleBase::FOUR_PI / tpiba2 / kv->get_nkstot_full(); + div *= ModuleBase::e2 * ModuleBase::FOUR_PI / tpiba2 / kv->get_nkstot_nospin(); // std::cout << "div: " << div << std::endl; // numerically value the mean value of F(q) in the reciprocal space @@ -532,7 +532,7 @@ double exx_divergence(Conv_Coulomb_Pot_K::Coulomb_Type coulomb_type, aa += 1.0 / std::sqrt(alpha * ModuleBase::PI); div -= ModuleBase::e2 * ucell_omega * aa; - exx_div = div * kv->get_nkstot_full(); + exx_div = div * kv->get_nkstot_nospin(); // exx_div = 0; // std::cout << "EXX divergence: " << exx_div << std::endl; From e72f518cb950e5c6073bbe86b65095700209594e Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 3 Sep 2026 17:16:09 +0800 Subject: [PATCH 22/22] small update --- source/source_cell/klist.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/source_cell/klist.cpp b/source/source_cell/klist.cpp index eb7e035461..5869a8ce3f 100644 --- a/source/source_cell/klist.cpp +++ b/source/source_cell/klist.cpp @@ -1,7 +1,3 @@ -/** - * @file klist.cpp - * @brief Implementation of K_Vectors class. - */ #include "klist.h" #include "klist_io.h"