From b69c08538fa2cf11bb42b3d0e9a3c2b35fcae5af Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 23 Jan 2026 20:25:54 +0800 Subject: [PATCH 1/8] Refactor: Encapsulate timer functionality in timer_wrapper.h --- source/source_base/timer_wrapper.h | 56 +++++++++++++++++++ source/source_esolver/esolver_fp.h | 10 +--- source/source_esolver/esolver_ks.cpp | 15 +---- source/source_esolver/esolver_of.cpp | 14 ++--- source/source_esolver/esolver_of_tddft.cpp | 6 +- .../source_pw/module_ofdft/of_print_info.cpp | 32 +++-------- source/source_pw/module_ofdft/of_print_info.h | 20 +++---- 7 files changed, 84 insertions(+), 69 deletions(-) create mode 100644 source/source_base/timer_wrapper.h diff --git a/source/source_base/timer_wrapper.h b/source/source_base/timer_wrapper.h new file mode 100644 index 00000000000..6da3f391e37 --- /dev/null +++ b/source/source_base/timer_wrapper.h @@ -0,0 +1,56 @@ +#ifndef TIMER_WRAPPER_H +#define TIMER_WRAPPER_H + +#include + +#ifdef __MPI +#include +#endif + +namespace ModuleBase { + +/** + * @brief Time point type that works in both MPI and non-MPI environments + */ +typedef double TimePoint; + +/** + * @brief Get current time as a TimePoint + * + * @return TimePoint Current time + */ +inline TimePoint get_time() +{ +#ifdef __MPI + int is_initialized = 0; + MPI_Initialized(&is_initialized); + if (is_initialized) + { + return MPI_Wtime(); + } + else + { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count() / 1e6; + } +#else + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count() / 1e6; +#endif +} + +/** + * @brief Calculate duration between two TimePoints in seconds + * + * @param start Start time point + * @param end End time point + * @return double Duration in seconds + */ +inline double get_duration(const TimePoint& start, const TimePoint& end) +{ + return end - start; +} + +} + +#endif // TIMER_WRAPPER_H \ No newline at end of file diff --git a/source/source_esolver/esolver_fp.h b/source/source_esolver/esolver_fp.h index b2bb8f065e2..94faa31e74a 100644 --- a/source/source_esolver/esolver_fp.h +++ b/source/source_esolver/esolver_fp.h @@ -3,9 +3,7 @@ #include "esolver.h" -#ifndef __MPI -#include -#endif +#include "source_base/timer_wrapper.h" #include "source_basis/module_pw/pw_basis.h" // plane wave basis #include "source_cell/module_symmetry/symmetry.h" // symmetry analysis @@ -83,11 +81,7 @@ class ESolver_FP: public ESolver bool pw_rho_flag = false; ///< flag for pw_rho, 0: not initialized, 1: initialized //! the start time of scf iteration - #ifdef __MPI - double iter_time; - #else - std::chrono::system_clock::time_point iter_time; - #endif + ModuleBase::TimePoint iter_time; }; } // namespace ModuleESolver diff --git a/source/source_esolver/esolver_ks.cpp b/source/source_esolver/esolver_ks.cpp index 166e7b3fb9d..8c0c6511726 100644 --- a/source/source_esolver/esolver_ks.cpp +++ b/source/source_esolver/esolver_ks.cpp @@ -1,4 +1,5 @@ #include "esolver_ks.h" +#include "source_base/timer_wrapper.h" // for jason output information #include "source_io/json_output/init_info.h" @@ -190,11 +191,7 @@ void ESolver_KS::iter_init(UnitCell& ucell, const int istep, const in ModuleIO::write_head(GlobalV::ofs_running, istep, iter, this->basisname); } -#ifdef __MPI - iter_time = MPI_Wtime(); -#else - iter_time = std::chrono::system_clock::now(); -#endif + iter_time = ModuleBase::get_time(); if (PARAM.inp.esolver_type == "ksdft") { @@ -281,13 +278,7 @@ void ESolver_KS::iter_finish(UnitCell& ucell, const int istep, int& i // the end, print time -#ifdef __MPI - double duration = (double)(MPI_Wtime() - iter_time); -#else - double duration - = (std::chrono::duration_cast(std::chrono::system_clock::now() - iter_time)).count() - / static_cast(1e6); -#endif + double duration = ModuleBase::get_duration(iter_time, ModuleBase::get_time()); // print energies elecstate::print_etot(ucell.magnet, *pelec, conv_esolver, iter, drho, diff --git a/source/source_esolver/esolver_of.cpp b/source/source_esolver/esolver_of.cpp index 4debfde4d59..b17cf6fb9df 100644 --- a/source/source_esolver/esolver_of.cpp +++ b/source/source_esolver/esolver_of.cpp @@ -27,10 +27,10 @@ ESolver_OF::ESolver_OF() ESolver_OF::~ESolver_OF() { - //**************************************************** - // do not add any codes in this deconstructor funcion - //**************************************************** - delete psi_; + //**************************************************** + // do not add any codes in this deconstructor funcion + //**************************************************** + delete psi_; delete[] this->pphi_; for (int i = 0; i < PARAM.inp.nspin; ++i) @@ -137,11 +137,7 @@ void ESolver_OF::runner(UnitCell& ucell, const int istep) this->iter_ = 0; bool conv_esolver = false; // this conv_esolver is added by mohan 20250302 -#ifdef __MPI - this->iter_time = MPI_Wtime(); -#else - this->iter_time = std::chrono::system_clock::now(); -#endif + this->iter_time = ModuleBase::get_time(); while (true) { diff --git a/source/source_esolver/esolver_of_tddft.cpp b/source/source_esolver/esolver_of_tddft.cpp index daeda628cbe..12a398a2f74 100644 --- a/source/source_esolver/esolver_of_tddft.cpp +++ b/source/source_esolver/esolver_of_tddft.cpp @@ -41,11 +41,7 @@ void ESolver_OF_TDDFT::runner(UnitCell& ucell, const int istep) this->iter_ = 0; bool conv_esolver = false; // this conv_esolver is added by mohan 20250302 -#ifdef __MPI - this->iter_time = MPI_Wtime(); -#else - this->iter_time = std::chrono::system_clock::now(); -#endif + this->iter_time = ModuleBase::get_time(); if (this->phi_td.empty()) { diff --git a/source/source_pw/module_ofdft/of_print_info.cpp b/source/source_pw/module_ofdft/of_print_info.cpp index ea411bcb1b7..fa19083dcdc 100644 --- a/source/source_pw/module_ofdft/of_print_info.cpp +++ b/source/source_pw/module_ofdft/of_print_info.cpp @@ -8,17 +8,13 @@ * and write the components of the total energy into running_log. */ void OFDFT::print_info(const int iter, - #ifdef __MPI - double &iter_time, - #else - std::chrono::system_clock::time_point &iter_time, - #endif - const double &energy_current, - const double &energy_last, - const double &normdLdphi, - const elecstate::ElecState *pelec, - KEDF_Manager *kedf_manager, - const bool conv_esolver) + ModuleBase::TimePoint &iter_time, + const double &energy_current, + const double &energy_last, + const double &normdLdphi, + const elecstate::ElecState *pelec, + KEDF_Manager *kedf_manager, + const bool conv_esolver) { if (iter == 0) { @@ -35,13 +31,7 @@ void OFDFT::print_info(const int iter, {"tn", "TN"} }; std::string iteration = prefix_map[PARAM.inp.of_method] + std::to_string(iter); -#ifdef __MPI - double duration = (double)(MPI_Wtime() - iter_time); -#else - double duration - = (std::chrono::duration_cast(std::chrono::system_clock::now() - iter_time)).count() - / static_cast(1e6); -#endif + double duration = ModuleBase::get_duration(iter_time, ModuleBase::get_time()); std::cout << " " << std::setw(8) << iteration << std::setw(18) << std::scientific << std::setprecision(8) << energy_current * ModuleBase::Ry_to_eV << std::setw(18) << (energy_current - energy_last) * ModuleBase::Ry_to_eV @@ -141,9 +131,5 @@ void OFDFT::print_info(const int iter, GlobalV::ofs_running << table.str() << std::endl; // reset the iter_time for the next iteration -#ifdef __MPI - iter_time = MPI_Wtime(); -#else - iter_time = std::chrono::system_clock::now(); -#endif + iter_time = ModuleBase::get_time(); } diff --git a/source/source_pw/module_ofdft/of_print_info.h b/source/source_pw/module_ofdft/of_print_info.h index b60eeb69db6..dd45e6bbc6d 100644 --- a/source/source_pw/module_ofdft/of_print_info.h +++ b/source/source_pw/module_ofdft/of_print_info.h @@ -4,24 +4,20 @@ #include "source_estate/elecstate.h" // electronic states #include "source_pw/module_ofdft/kedf_manager.h" -#include +#include "source_base/timer_wrapper.h" namespace OFDFT { void print_info(const int iter, - #ifdef __MPI - double &iter_time, - #else - std::chrono::system_clock::time_point &iter_time, - #endif - const double &energy_current, - const double &energy_last, - const double &normdLdphi, - const elecstate::ElecState *pelec, - KEDF_Manager *kedf_manager, - const bool conv_esolver); + ModuleBase::TimePoint &iter_time, + const double &energy_current, + const double &energy_last, + const double &normdLdphi, + const elecstate::ElecState *pelec, + KEDF_Manager *kedf_manager, + const bool conv_esolver); } From 382926887a20b868df74a8eefef3b299c232fb1a Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 23 Jan 2026 20:54:14 +0800 Subject: [PATCH 2/8] Refactor timer code and clean_esolver function 1. Remove #ifdef __MPI from timer code, encapsulate in timer_wrapper.h 2. Move ESolver clean logic to after_all_runners method 3. Replace clean_esolver calls with direct delete p_esolver 4. Remove #ifdef __MPI from delete p_esolver 5. Add Cblacs_exit(1) in after_all_runners for LCAO calculations --- source/source_esolver/esolver.cpp | 51 ++++++++--------------- source/source_esolver/esolver.h | 2 +- source/source_esolver/esolver_ks_lcao.cpp | 28 ++++++++----- source/source_main/driver_run.cpp | 8 +--- 4 files changed, 39 insertions(+), 50 deletions(-) diff --git a/source/source_esolver/esolver.cpp b/source/source_esolver/esolver.cpp index 2d896733137..4809c6df776 100644 --- a/source/source_esolver/esolver.cpp +++ b/source/source_esolver/esolver.cpp @@ -311,23 +311,23 @@ ESolver* init_esolver(const Input_para& inp, UnitCell& ucell) // of LR-TDDFT is implemented. std::cout << " PREPARING FOR EXCITED STATES." << std::endl; // initialize the 2nd ESolver_LR at the temporary pointer - ModuleESolver::ESolver* p_esolver_lr = nullptr; - if (PARAM.globalv.gamma_only_local) - { - p_esolver_lr = new LR::ESolver_LR( - std::move(*dynamic_cast*>(p_esolver)), - inp, - ucell); - } - else - { - p_esolver_lr = new LR::ESolver_LR, double>( - std::move(*dynamic_cast, double>*>(p_esolver)), - inp, - ucell); - } - // clean the 1st ESolver_KS and swap the pointer - ModuleESolver::clean_esolver(p_esolver, false); // do not call Cblacs_exit, remain it for the 2nd ESolver + ModuleESolver::ESolver* p_esolver_lr = nullptr; + if (PARAM.globalv.gamma_only_local) + { + p_esolver_lr = new LR::ESolver_LR( + std::move(*dynamic_cast*>(p_esolver)), + inp, + ucell); + } + else + { + p_esolver_lr = new LR::ESolver_LR, double>( + std::move(*dynamic_cast, double>*>(p_esolver)), + inp, + ucell); + } + // clean the 1st ESolver_KS and swap the pointer + delete p_esolver; return p_esolver_lr; } #endif @@ -355,20 +355,5 @@ ESolver* init_esolver(const Input_para& inp, UnitCell& ucell) + " line " + std::to_string(__LINE__)); } -void clean_esolver(ESolver*& pesolver, const bool lcao_cblacs_exit) -{ -// Zhang Xiaoyang modified in 2024/7/6: -// Note: because of the init method of serial lcao hsolver -// it needs no release step for it, or this [delete] will cause Segmentation Fault -// Probably it will be modified later. -#ifdef __MPI - delete pesolver; -#ifdef __LCAO - if (lcao_cblacs_exit) - { - Cblacs_exit(1); - } -#endif -#endif -} + } // namespace ModuleESolver diff --git a/source/source_esolver/esolver.h b/source/source_esolver/esolver.h index 6716ea0c965..dd621cfe155 100644 --- a/source/source_esolver/esolver.h +++ b/source/source_esolver/esolver.h @@ -69,7 +69,7 @@ std::string determine_type(); */ ESolver* init_esolver(const Input_para& inp, UnitCell& ucell); -void clean_esolver(ESolver*& pesolver, const bool lcao_cblacs_exit = false); + } // namespace ModuleESolver diff --git a/source/source_esolver/esolver_ks_lcao.cpp b/source/source_esolver/esolver_ks_lcao.cpp index 3a2fb57496b..47b66489549 100644 --- a/source/source_esolver/esolver_ks_lcao.cpp +++ b/source/source_esolver/esolver_ks_lcao.cpp @@ -293,17 +293,25 @@ void ESolver_KS_LCAO::after_all_runners(UnitCell& ucell) ESolver_KS::after_all_runners(ucell); auto* hamilt_lcao = dynamic_cast*>(this->p_hamilt); - if(!hamilt_lcao) - { - ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::after_all_runners","p_hamilt does not exist"); - } + if(!hamilt_lcao) + { + ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::after_all_runners","p_hamilt does not exist"); + } - ModuleIO::ctrl_runner_lcao(ucell, - PARAM.inp, this->kv, this->pelec, this->dmat, this->pv, this->Pgrid, - this->gd, this->psi, this->chr, hamilt_lcao, - this->two_center_bundle_, - this->orb_, this->pw_rho, this->pw_rhod, - this->sf, this->locpp.vloc, this->exx_nao, this->solvent); + ModuleIO::ctrl_runner_lcao(ucell, + PARAM.inp, this->kv, this->pelec, this->dmat, this->pv, this->Pgrid, + this->gd, this->psi, this->chr, hamilt_lcao, + this->two_center_bundle_, + this->orb_, this->pw_rho, this->pw_rhod, + this->sf, this->locpp.vloc, this->exx_nao, this->solvent); + + +#ifdef __MPI +#ifdef __LCAO + // Exit BLACS environment for LCAO calculations + Cblacs_exit(1); +#endif +#endif ModuleBase::timer::tick("ESolver_KS_LCAO", "after_all_runners"); } diff --git a/source/source_main/driver_run.cpp b/source/source_main/driver_run.cpp index 990aa56751e..895b06bf577 100644 --- a/source/source_main/driver_run.cpp +++ b/source/source_main/driver_run.cpp @@ -90,11 +90,6 @@ void Driver::driver_run() else if (cal == "get_pchg" || cal == "get_wf" || cal == "gen_bessel" || cal == "gen_opt_abfs" || cal == "test_memory" || cal == "test_neighbour") { - //! supported "other" functions: - //! get_pchg(LCAO), - //! test_memory(PW,LCAO), - //! test_neighbour(LCAO), - //! gen_bessel(PW), et al. const int istep = 0; p_esolver->others(ucell, istep); } @@ -106,7 +101,8 @@ void Driver::driver_run() //! 5: clean up esolver p_esolver->after_all_runners(ucell); - ModuleESolver::clean_esolver(p_esolver); + delete p_esolver; + this->finalize_hardware(); //! 6: output the json file From 5aec24c4537454b267a3493cb32eec9b5a9a6f7d Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Sun, 25 Jan 2026 17:03:12 +0800 Subject: [PATCH 3/8] Refactor spar_exx.h: add English comments and improve dependency structure - Added detailed English comments to cal_HR_exx function - Moved implementation to cpp file and added explicit instantiations - Improved header file organization with sections - Removed unnecessary LCAO_hamilt.hpp include - Enhanced endif comments for better code readability --- source/source_lcao/spar_exx.cpp | 174 +++++++++++++++++++++++++++++++- source/source_lcao/spar_exx.h | 57 +++++++++-- 2 files changed, 222 insertions(+), 9 deletions(-) diff --git a/source/source_lcao/spar_exx.cpp b/source/source_lcao/spar_exx.cpp index 6538da70727..b19eee7c396 100644 --- a/source/source_lcao/spar_exx.cpp +++ b/source/source_lcao/spar_exx.cpp @@ -1,4 +1,174 @@ #ifdef __EXX -#include "LCAO_hamilt.hpp" -#endif + +#include "spar_exx.h" + +// -------------------------------------------------------- +// Header files needed for implementation only +// -------------------------------------------------------- + +#include +#include +#include + +#include "source_base/abfs-vector3_order.h" +#include "source_base/global_variable.h" +#include "source_base/timer.h" +#include "source_hamilt/module_xc/exx_info.h" +#include "source_io/module_parameter/parameter.h" +#include "source_lcao/module_ri/RI_2D_Comm.h" +#include "source_lcao/module_ri/RI_Util.hpp" + +// -------------------------------------------------------- +// Implementation of the cal_HR_exx function +// -------------------------------------------------------- + +namespace sparse_format +{ + +/** + * @brief Implementation of the cal_HR_exx function + */ +template +void cal_HR_exx( + const UnitCell& ucell, + const Parallel_Orbitals& pv, + LCAO_HS_Arrays& HS_Arrays, + const int& current_spin, + const double& sparse_threshold, + const int (&nmp)[3], + const std::vector>, RI::Tensor>>>& Hexxs) +{ + ModuleBase::TITLE("sparse_format", "cal_HR_exx"); + ModuleBase::timer::tick("sparse_format", "cal_HR_exx"); + + const Tdata frac = GlobalC::exx_info.info_global.hybrid_alpha; + + std::map> atoms_pos; + for (int iat = 0; iat < ucell.nat; ++iat) + { + atoms_pos[iat] = RI_Util::Vector3_to_array3(ucell.atoms[ucell.iat2it[iat]].tau[ucell.iat2ia[iat]]); + } + const std::array, 3> latvec + = {RI_Util::Vector3_to_array3(ucell.a1), + RI_Util::Vector3_to_array3(ucell.a2), + RI_Util::Vector3_to_array3(ucell.a3)}; + + const std::array Rs_period = {nmp[0], nmp[1], nmp[2]}; + + RI::Cell_Nearest cell_nearest; + cell_nearest.init(atoms_pos, latvec, Rs_period); + + const std::vector is_list + = (PARAM.inp.nspin != 4) ? std::vector{current_spin} : std::vector{0, 1, 2, 3}; + + for (const int is: is_list) + { + int is0_b = 0; + int is1_b = 0; + std::tie(is0_b, is1_b) = RI_2D_Comm::split_is_block(is); + + if (Hexxs.empty()) + { + break; + } + + for (const auto& HexxA: Hexxs[is]) + { + const int iat0 = HexxA.first; + for (const auto& HexxB: HexxA.second) + { + const int iat1 = HexxB.first.first; + + const Abfs::Vector3_Order R = RI_Util::array3_to_Vector3( + cell_nearest.get_cell_nearest_discrete(iat0, iat1, HexxB.first.second)); + + HS_Arrays.all_R_coor.insert(R); + + const RI::Tensor& Hexx = HexxB.second; + + for (size_t iw0 = 0; iw0 < Hexx.shape[0]; ++iw0) + { + const int iwt0 = RI_2D_Comm::get_iwt(ucell, iat0, iw0, is0_b); + const int iwt0_local = pv.global2local_row(iwt0); + + if (iwt0_local < 0) + { + continue; + } + + for (size_t iw1 = 0; iw1 < Hexx.shape[1]; ++iw1) + { + const int iwt1 = RI_2D_Comm::get_iwt(ucell, iat1, iw1, is1_b); + const int iwt1_local = pv.global2local_col(iwt1); + + if (iwt1_local < 0) + { + continue; + } + + if (std::abs(Hexx(iw0, iw1)) > sparse_threshold) + { + if (PARAM.inp.nspin == 1 || PARAM.inp.nspin == 2) + { + auto& HR_sparse_ptr = HS_Arrays.HR_sparse[current_spin][R][iwt0]; + double& HR_sparse = HR_sparse_ptr[iwt1]; + HR_sparse += RI::Global_Func::convert(frac * Hexx(iw0, iw1)); + if (std::abs(HR_sparse) <= sparse_threshold) + { + HR_sparse_ptr.erase(iwt1); + } + } + else if (PARAM.inp.nspin == 4) + { + auto& HR_sparse_ptr = HS_Arrays.HR_soc_sparse[R][iwt0]; + + std::complex& HR_sparse = HR_sparse_ptr[iwt1]; + + HR_sparse += RI::Global_Func::convert>(frac * Hexx(iw0, iw1)); + + if (std::abs(HR_sparse) <= sparse_threshold) + { + HR_sparse_ptr.erase(iwt1); + } + } + else + { + throw std::invalid_argument(std::string(__FILE__) + " line " + + std::to_string(__LINE__)); + } + } + } + } + } + } + } + + ModuleBase::timer::tick("sparse_format", "cal_HR_exx"); +} + +// -------------------------------------------------------- +// Explicit instantiations for double and complex types +// -------------------------------------------------------- + +template void cal_HR_exx( + const UnitCell& ucell, + const Parallel_Orbitals& pv, + LCAO_HS_Arrays& HS_Arrays, + const int& current_spin, + const double& sparse_thr, + const int (&nmp)[3], + const std::vector>, RI::Tensor>>>& Hexxs); + +template void cal_HR_exx>( + const UnitCell& ucell, + const Parallel_Orbitals& pv, + LCAO_HS_Arrays& HS_Arrays, + const int& current_spin, + const double& sparse_thr, + const int (&nmp)[3], + const std::vector>, RI::Tensor>>>>& Hexxs); + +} // namespace sparse_format + +#endif // __EXX diff --git a/source/source_lcao/spar_exx.h b/source/source_lcao/spar_exx.h index c12c4a14ced..4aca75aa5ae 100644 --- a/source/source_lcao/spar_exx.h +++ b/source/source_lcao/spar_exx.h @@ -3,20 +3,44 @@ #ifdef __EXX -#include -#include +// -------------------------------------------------------- +// Header files - minimal set for declaration only +// -------------------------------------------------------- + +#include #include #include #include -#include "source_lcao/LCAO_HS_arrays.hpp" #include "source_basis/module_ao/parallel_orbitals.h" #include "source_cell/unitcell.h" +#include "source_lcao/LCAO_HS_arrays.hpp" + +// -------------------------------------------------------- +// Namespace - merged into one block +// -------------------------------------------------------- + namespace sparse_format { +/** + * @brief Calculate the Hamiltonian matrix elements in real space using EXX data in sparse format + * + * This function computes the Hamiltonian matrix elements in real space (HR) from EXX data, + * which is stored in a sparse tensor format. The results are added to the HS_Arrays structure. + * + * @tparam Tdata Data type for the matrix elements (double or std::complex) + * @param ucell Unit cell information + * @param pv Parallel orbitals information for distributed computation + * @param HS_Arrays Structure to store Hamiltonian and overlap matrix arrays + * @param current_spin Current spin channel (0 or 1 for spin-polarized calculations) + * @param sparse_thr Threshold for sparse matrix construction + * @param nmp Periodic boundary conditions in reciprocal space + * @param Hexxs EXX data stored as a nested map structure of tensors + */ template -void cal_HR_exx(const UnitCell& ucell, +void cal_HR_exx( + const UnitCell& ucell, const Parallel_Orbitals& pv, LCAO_HS_Arrays& HS_Arrays, const int& current_spin, @@ -24,7 +48,26 @@ void cal_HR_exx(const UnitCell& ucell, const int (&nmp)[3], const std::vector>, RI::Tensor>>>& Hexxs); +// Explicit instantiations for double and complex types +extern template void cal_HR_exx( + const UnitCell& ucell, + const Parallel_Orbitals& pv, + LCAO_HS_Arrays& HS_Arrays, + const int& current_spin, + const double& sparse_thr, + const int (&nmp)[3], + const std::vector>, RI::Tensor>>>& Hexxs); + +extern template void cal_HR_exx>( + const UnitCell& ucell, + const Parallel_Orbitals& pv, + LCAO_HS_Arrays& HS_Arrays, + const int& current_spin, + const double& sparse_thr, + const int (&nmp)[3], + const std::vector>, RI::Tensor>>>>& Hexxs); + } -#include "source_lcao/LCAO_hamilt.hpp" -#endif -#endif + +#endif // __EXX +#endif // SPARSE_FORMAT_EXX_H From 5615dfe5050db0170ee0090fa50d9b4031a0e63a Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Sun, 25 Jan 2026 17:03:36 +0800 Subject: [PATCH 4/8] Remove empty LCAO_hamilt.hpp file The LCAO_hamilt.hpp file was empty after moving its implementation to spar_exx.cpp. This commit removes the unused header file and updates all references to it. --- source/source_lcao/LCAO_hamilt.hpp | 142 ----------------------------- 1 file changed, 142 deletions(-) delete mode 100644 source/source_lcao/LCAO_hamilt.hpp diff --git a/source/source_lcao/LCAO_hamilt.hpp b/source/source_lcao/LCAO_hamilt.hpp deleted file mode 100644 index 69179f64c18..00000000000 --- a/source/source_lcao/LCAO_hamilt.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "source_io/module_parameter/parameter.h" - -#ifndef LCAO_HAMILT_HPP -#define LCAO_HAMILT_HPP - -#include "source_base/abfs-vector3_order.h" -#include "source_base/global_variable.h" -#include "source_base/timer.h" -#include "source_lcao/module_ri/RI_2D_Comm.h" -#include "source_lcao/spar_exx.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EXX -// Peize Lin add 2022.09.13 - -template -void sparse_format::cal_HR_exx( - const UnitCell& ucell, - const Parallel_Orbitals& pv, - LCAO_HS_Arrays& HS_Arrays, - const int& current_spin, - const double& sparse_threshold, - const int (&nmp)[3], - const std::vector>, RI::Tensor>>>& Hexxs) -{ - ModuleBase::TITLE("sparse_format", "cal_HR_exx"); - ModuleBase::timer::tick("sparse_format", "cal_HR_exx"); - - const Tdata frac = GlobalC::exx_info.info_global.hybrid_alpha; - - std::map> atoms_pos; - for (int iat = 0; iat < ucell.nat; ++iat) - { - atoms_pos[iat] = RI_Util::Vector3_to_array3(ucell.atoms[ucell.iat2it[iat]].tau[ucell.iat2ia[iat]]); - } - const std::array, 3> latvec - = {RI_Util::Vector3_to_array3(ucell.a1), // too bad to use GlobalC here, - RI_Util::Vector3_to_array3(ucell.a2), - RI_Util::Vector3_to_array3(ucell.a3)}; - - const std::array Rs_period = {nmp[0], nmp[1], nmp[2]}; - - RI::Cell_Nearest cell_nearest; - cell_nearest.init(atoms_pos, latvec, Rs_period); - - const std::vector is_list - = (PARAM.inp.nspin != 4) ? std::vector{current_spin} : std::vector{0, 1, 2, 3}; - - for (const int is: is_list) - { - int is0_b = 0; - int is1_b = 0; - std::tie(is0_b, is1_b) = RI_2D_Comm::split_is_block(is); - - if (Hexxs.empty()) - { - break; - } - - for (const auto& HexxA: Hexxs[is]) - { - const int iat0 = HexxA.first; - for (const auto& HexxB: HexxA.second) - { - const int iat1 = HexxB.first.first; - - const Abfs::Vector3_Order R = RI_Util::array3_to_Vector3( - cell_nearest.get_cell_nearest_discrete(iat0, iat1, HexxB.first.second)); - - HS_Arrays.all_R_coor.insert(R); - - const RI::Tensor& Hexx = HexxB.second; - - for (size_t iw0 = 0; iw0 < Hexx.shape[0]; ++iw0) - { - const int iwt0 = RI_2D_Comm::get_iwt(ucell, iat0, iw0, is0_b); - const int iwt0_local = pv.global2local_row(iwt0); - - if (iwt0_local < 0) - { - continue; - } - - for (size_t iw1 = 0; iw1 < Hexx.shape[1]; ++iw1) - { - const int iwt1 = RI_2D_Comm::get_iwt(ucell, iat1, iw1, is1_b); - const int iwt1_local = pv.global2local_col(iwt1); - - if (iwt1_local < 0) - { - continue; - } - - if (std::abs(Hexx(iw0, iw1)) > sparse_threshold) - { - if (PARAM.inp.nspin == 1 || PARAM.inp.nspin == 2) - { - auto& HR_sparse_ptr = HS_Arrays.HR_sparse[current_spin][R][iwt0]; - double& HR_sparse = HR_sparse_ptr[iwt1]; - HR_sparse += RI::Global_Func::convert(frac * Hexx(iw0, iw1)); - if (std::abs(HR_sparse) <= sparse_threshold) - { - HR_sparse_ptr.erase(iwt1); - } - } - else if (PARAM.inp.nspin == 4) - { - auto& HR_sparse_ptr = HS_Arrays.HR_soc_sparse[R][iwt0]; - - std::complex& HR_sparse = HR_sparse_ptr[iwt1]; - - HR_sparse += RI::Global_Func::convert>(frac * Hexx(iw0, iw1)); - - if (std::abs(HR_sparse) <= sparse_threshold) - { - HR_sparse_ptr.erase(iwt1); - } - } - else - { - throw std::invalid_argument(std::string(__FILE__) + " line " - + std::to_string(__LINE__)); - } - } - } - } - } - } - } - - ModuleBase::timer::tick("sparse_format", "cal_HR_exx"); -} -#endif - -#endif From b8ab6cbf2b7c732d4064f46ad7b9f4b5417e6eaa Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Sun, 25 Jan 2026 17:04:00 +0800 Subject: [PATCH 5/8] Fix circular dependency between exx_info.h and xc_functional.h - Removed #include xc_functional.h from exx_info.h - Removed #include exx_info.h from xc_functional.h This breaks the circular dependency between these two header files, allowing them to compile independently. --- source/source_hamilt/module_xc/exx_info.h | 1 - source/source_hamilt/module_xc/xc_functional.h | 1 - 2 files changed, 2 deletions(-) diff --git a/source/source_hamilt/module_xc/exx_info.h b/source/source_hamilt/module_xc/exx_info.h index 55ae60668f2..c9584f9b609 100644 --- a/source/source_hamilt/module_xc/exx_info.h +++ b/source/source_hamilt/module_xc/exx_info.h @@ -2,7 +2,6 @@ #define EXX_INFO_H #include "source_lcao/module_ri/conv_coulomb_pot_k.h" -#include "xc_functional.h" #include #include diff --git a/source/source_hamilt/module_xc/xc_functional.h b/source/source_hamilt/module_xc/xc_functional.h index 067ceef7cf8..86dcb4049d7 100644 --- a/source/source_hamilt/module_xc/xc_functional.h +++ b/source/source_hamilt/module_xc/xc_functional.h @@ -15,7 +15,6 @@ #include "source_base/global_variable.h" #include "source_base/vector3.h" #include "source_base/matrix.h" -#include "exx_info.h" #include "source_basis/module_pw/pw_basis_k.h" #include "source_estate/module_charge/charge.h" #include "source_cell/unitcell.h" From ac0306adc83a5bc586c296318fb0a854556fa495 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Sun, 25 Jan 2026 17:04:21 +0800 Subject: [PATCH 6/8] Fix dependencies in LCAO sparse format headers - Removed unnecessary #include source_lcao/hamilt_lcao.h from spar_dh.h, spar_hsr.h, and spar_u.h - Added direct dependencies to spar_dh.h: matrix.h, parallel_orbitals.h, two_center_bundle.h, ORB_read.h - Adjusted include order in spar_hsr.h and spar_u.h - Added necessary include to spar_hsr.cpp for HamiltLCAO access --- source/source_lcao/spar_dh.h | 5 ++++- source/source_lcao/spar_hsr.cpp | 1 + source/source_lcao/spar_hsr.h | 3 ++- source/source_lcao/spar_u.h | 3 +-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/source_lcao/spar_dh.h b/source/source_lcao/spar_dh.h index c176096e516..3df85fefc99 100644 --- a/source/source_lcao/spar_dh.h +++ b/source/source_lcao/spar_dh.h @@ -1,11 +1,14 @@ #ifndef SPAR_DH_H #define SPAR_DH_H +#include "source_base/matrix.h" +#include "source_basis/module_ao/parallel_orbitals.h" +#include "source_basis/module_nao/two_center_bundle.h" +#include "source_basis/module_ao/ORB_read.h" #include "source_cell/module_neighbor/sltk_atom_arrange.h" #include "source_cell/module_neighbor/sltk_grid_driver.h" #include "source_lcao/LCAO_HS_arrays.hpp" #include "source_lcao/force_stress_arrays.h" -#include "source_lcao/hamilt_lcao.h" #include namespace sparse_format diff --git a/source/source_lcao/spar_hsr.cpp b/source/source_lcao/spar_hsr.cpp index b0c1ce21394..fb74a15f230 100644 --- a/source/source_lcao/spar_hsr.cpp +++ b/source/source_lcao/spar_hsr.cpp @@ -1,4 +1,5 @@ #include "spar_hsr.h" +#include "source_lcao/hamilt_lcao.h" #include "source_io/module_parameter/parameter.h" #include "source_lcao/module_hcontainer/hcontainer.h" diff --git a/source/source_lcao/spar_hsr.h b/source/source_lcao/spar_hsr.h index b9c13349145..b93765fec9c 100644 --- a/source/source_lcao/spar_hsr.h +++ b/source/source_lcao/spar_hsr.h @@ -2,7 +2,8 @@ #define SPARSE_FORMAT_HSR_H #include "source_lcao/LCAO_HS_arrays.hpp" -#include "source_lcao/hamilt_lcao.h" +#include "source_lcao/module_hcontainer/hcontainer.h" +#include "source_hamilt/hamilt.h" #include "source_lcao/module_dftu/dftu.h" // mohan add 20251107 namespace sparse_format diff --git a/source/source_lcao/spar_u.h b/source/source_lcao/spar_u.h index 5ac5c8a3659..4940a3c5ff3 100644 --- a/source/source_lcao/spar_u.h +++ b/source/source_lcao/spar_u.h @@ -1,11 +1,10 @@ #ifndef SPARSE_FORMAT_U_H #define SPARSE_FORMAT_U_H +#include "source_base/abfs-vector3_order.h" #include "source_cell/module_neighbor/sltk_atom_arrange.h" #include "source_cell/module_neighbor/sltk_grid_driver.h" -#include "source_lcao/hamilt_lcao.h" #include "source_lcao/module_dftu/dftu.h" // mohan add 20251107 -#include "source_base/abfs-vector3_order.h" namespace sparse_format { From e3892f004e05d28b5a0bdb3990148eee7216b645 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Sun, 25 Jan 2026 17:04:42 +0800 Subject: [PATCH 7/8] Add necessary includes to cpp files for compilation - Added xc_functional.h include to esolver_ks_pw.cpp for XC_Functional class access - Added xc_functional.h include to input_conv.cpp for XC_Functional class access - Added parallel_comm.h include to op_exx_pw.cpp for KP_WORLD communication - Added global_variable.h and exx_info.h includes to stress_pw.cpp for GlobalC namespace access These changes fix compilation errors caused by the dependency refactoring. --- source/source_esolver/esolver_ks_pw.cpp | 1 + source/source_io/input_conv.cpp | 1 + source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp | 1 + source/source_pw/module_pwdft/stress_pw.cpp | 2 ++ 4 files changed, 5 insertions(+) diff --git a/source/source_esolver/esolver_ks_pw.cpp b/source/source_esolver/esolver_ks_pw.cpp index b98fe6490e9..11088a6daf9 100644 --- a/source/source_esolver/esolver_ks_pw.cpp +++ b/source/source_esolver/esolver_ks_pw.cpp @@ -17,6 +17,7 @@ #include "source_pw/module_pwdft/forces.h" #include "source_pw/module_pwdft/stress_pw.h" +#include "source_hamilt/module_xc/xc_functional.h" // use XC_Functional #ifdef __DSP #include "source_base/kernels/dsp/dsp_connector.h" diff --git a/source/source_io/input_conv.cpp b/source/source_io/input_conv.cpp index d174cefeae9..111040d812a 100644 --- a/source/source_io/input_conv.cpp +++ b/source/source_io/input_conv.cpp @@ -14,6 +14,7 @@ #include #include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info +#include "source_hamilt/module_xc/xc_functional.h" // use XC_Functional #ifdef __EXX #include "source_lcao/module_ri/exx_abfs-jle.h" #endif diff --git a/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp b/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp index c5be374e1d9..a949a806c73 100644 --- a/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp +++ b/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp @@ -3,6 +3,7 @@ #include "source_base/constants.h" #include "source_base/global_variable.h" #include "source_base/parallel_common.h" +#include "source_base/parallel_comm.h" // use KP_WORLD #include "source_base/parallel_reduce.h" #include "source_base/module_external/lapack_connector.h" #include "source_base/timer.h" diff --git a/source/source_pw/module_pwdft/stress_pw.cpp b/source/source_pw/module_pwdft/stress_pw.cpp index 919d1288bfe..8cd8959ff9f 100644 --- a/source/source_pw/module_pwdft/stress_pw.cpp +++ b/source/source_pw/module_pwdft/stress_pw.cpp @@ -1,9 +1,11 @@ #include "stress_pw.h" #include "source_base/timer.h" +#include "source_base/global_variable.h" // use GlobalC #include "source_hamilt/module_vdw/vdw.h" #include "source_io/output_log.h" #include "source_hamilt/module_xc/xc_functional.h" +#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info template void Stress_PW::cal_stress(ModuleBase::matrix& sigmatot, From 7ca736d3ce9e7068ebf07c0aceff5fd6443eb969 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Sun, 25 Jan 2026 22:49:56 +0800 Subject: [PATCH 8/8] add #include in spar_hsr.h --- source/source_esolver/esolver_ks_lcaopw.cpp | 1 + source/source_lcao/spar_hsr.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/source/source_esolver/esolver_ks_lcaopw.cpp b/source/source_esolver/esolver_ks_lcaopw.cpp index 97823e7c1b2..8768d3bce49 100644 --- a/source/source_esolver/esolver_ks_lcaopw.cpp +++ b/source/source_esolver/esolver_ks_lcaopw.cpp @@ -30,6 +30,7 @@ #include "source_io/to_wannier90_pw.h" #include "source_io/write_elecstat_pot.h" #include "source_io/module_parameter/parameter.h" +#include "source_hamilt/module_xc/xc_functional.h" #include #include diff --git a/source/source_lcao/spar_hsr.h b/source/source_lcao/spar_hsr.h index b93765fec9c..b196d3be3b9 100644 --- a/source/source_lcao/spar_hsr.h +++ b/source/source_lcao/spar_hsr.h @@ -6,6 +6,10 @@ #include "source_hamilt/hamilt.h" #include "source_lcao/module_dftu/dftu.h" // mohan add 20251107 +#ifdef __EXX +#include +#endif + namespace sparse_format { #ifdef __MPI