diff --git a/source/Makefile.Objects b/source/Makefile.Objects index 30c3243dbbd..b6dca9a1325 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -272,7 +272,7 @@ OBJS_ELECSTAT_LCAO=elecstate_lcao.o\ cal_dm_psi.o\ cal_edm_tddft.o\ -OBJS_ESOLVER=esolver.o\ +OBJS_ESOLVER=esolver_factory.o\ esolver_ks.o\ esolver_fp.o\ esolver_ks_pw.o\ diff --git a/source/source_esolver/CMakeLists.txt b/source/source_esolver/CMakeLists.txt index 59e8ead605b..90e1e92cff1 100644 --- a/source/source_esolver/CMakeLists.txt +++ b/source/source_esolver/CMakeLists.txt @@ -1,5 +1,5 @@ list(APPEND objects - esolver.cpp + esolver_factory.cpp esolver_ks.cpp esolver_fp.cpp esolver_ks_pw.cpp diff --git a/source/source_esolver/esolver.h b/source/source_esolver/esolver.h index fcc30b0b359..1f8dc3faf34 100644 --- a/source/source_esolver/esolver.h +++ b/source/source_esolver/esolver.h @@ -49,26 +49,11 @@ class ESolver bool conv_esolver = true; // whether esolver is converged std::string classname; -}; -/** - * @brief A subrutine called in init_esolver() - * This function returns type of ESolver - * Based on PARAM.inp.basis_type and PARAM.inp.esolver_type - * @return [out] std::string The type of ESolver - */ -std::string determine_type(); - -/** - * @brief Determine and initialize an ESolver based on input information. - * - * This function determines the type of ESolver to create based on input information and initializes - * the corresponding ESolver child class. It supports various ESolver types including ksdft_pw, - * ksdft_lcao, ksdft_lcao_tddft, sdft_pw, ofdft, lj_pot, and dp_pot. - * - * @return [out] A pointer to an ESolver object that will be initialized. - */ -ESolver* init_esolver(const Input_para& inp); + protected: + /// Bound in before_all_runners; members use inp_->xxx instead of PARAM.inp.xxx + const Input_para* inp_ = nullptr; +}; } // namespace ModuleESolver diff --git a/source/source_esolver/esolver_dfpt_pw.cpp b/source/source_esolver/esolver_dfpt_pw.cpp index 8c8931b4bcc..217a93705b6 100644 --- a/source/source_esolver/esolver_dfpt_pw.cpp +++ b/source/source_esolver/esolver_dfpt_pw.cpp @@ -86,7 +86,7 @@ void ESolver_DFPT_PW::init_dfpt(UnitCell& ucell) dfpt_ = new ModuleDFPT::DFPT_PW(); - // dfpt_->init(ucell, *this->stp.psi, this->pelec->nelec, PARAM.inp.ecutwfc); + // dfpt_->init(ucell, *this->stp.psi, this->pelec->nelec, this->inp_->ecutwfc); dfpt_->set_parameters("dfpt.in"); diff --git a/source/source_esolver/esolver_dm2rho.cpp b/source/source_esolver/esolver_dm2rho.cpp index 35890aa05bb..c5c323e3eaa 100644 --- a/source/source_esolver/esolver_dm2rho.cpp +++ b/source/source_esolver/esolver_dm2rho.cpp @@ -58,7 +58,7 @@ void ESolver_DM2rho::runner(BaseCell& basecell, const int istep) ModuleIO::read_mat_npz(&(this->pv), ucell, zipname, *(this->dmat.dm->get_DMR_pointer(1))); // if nspin=2, need extra reading - if (PARAM.inp.nspin == 2) + if (this->inp_->nspin == 2) { zipname = "output_DM1.npz"; ModuleIO::read_mat_npz(&(this->pv), ucell, zipname, *(this->dmat.dm->get_DMR_pointer(2))); @@ -66,9 +66,9 @@ void ESolver_DM2rho::runner(BaseCell& basecell, const int istep) // it's dangerous to design psiToRho function like this, mohan note 20251024 // this->pelec->psiToRho(*this->psi); - LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), PARAM.inp.nspin, &this->chr); + LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), this->inp_->nspin, &this->chr); - int nspin0 = PARAM.inp.nspin == 2 ? 2 : 1; + int nspin0 = this->inp_->nspin == 2 ? 2 : 1; for (int is = 0; is < nspin0; is++) { @@ -78,7 +78,7 @@ void ESolver_DM2rho::runner(BaseCell& basecell, const int istep) ModuleIO::write_vdata_palgrid(this->Pgrid, this->chr.rho[is], is, - PARAM.inp.nspin, + this->inp_->nspin, istep, fn, this->pelec->eferm.get_efval(is), diff --git a/source/source_esolver/esolver_double_xc.cpp b/source/source_esolver/esolver_double_xc.cpp index 41aa8f933c3..4bb3f7a5ea8 100644 --- a/source/source_esolver/esolver_double_xc.cpp +++ b/source/source_esolver/esolver_double_xc.cpp @@ -64,11 +64,11 @@ void ESolver_DoubleXC::before_all_runners(BaseCell& basecell, const Inpu int ncol = 0; if (PARAM.globalv.gamma_only_local) { - nsk = PARAM.inp.nspin; + nsk = this->inp_->nspin; ncol = this->pv.ncol_bands; - if (PARAM.inp.ks_solver == "genelpa" || PARAM.inp.ks_solver == "elpa" || PARAM.inp.ks_solver == "lapack" - || PARAM.inp.ks_solver == "pexsi" || PARAM.inp.ks_solver == "cusolver" - || PARAM.inp.ks_solver == "cusolvermp") + if (this->inp_->ks_solver == "genelpa" || this->inp_->ks_solver == "elpa" || this->inp_->ks_solver == "lapack" + || this->inp_->ks_solver == "pexsi" || this->inp_->ks_solver == "cusolver" + || this->inp_->ks_solver == "cusolvermp") { ncol = this->pv.ncol; } @@ -79,19 +79,19 @@ void ESolver_DoubleXC::before_all_runners(BaseCell& basecell, const Inpu #ifdef __MPI ncol = this->pv.ncol_bands; #else - ncol = PARAM.inp.nbands; + ncol = this->inp_->nbands; #endif } this->psi_base = new psi::Psi(nsk, ncol, this->pv.nrow, this->kv.ngk, true); } // 6) initialize the density matrix - this->dmat_base.allocate_dm(&this->kv, &this->pv, PARAM.inp.nspin); + this->dmat_base.allocate_dm(&this->kv, &this->pv, this->inp_->nspin); // 10) inititlize the charge density this->chr_base.set_rhopw(this->pw_rhod); // mohan add 20251130 const bool kin_den = this->chr_base.kin_density(); // mohan add 20251202 - this->chr_base.allocate(PARAM.inp.nspin, kin_den); + this->chr_base.allocate(this->inp_->nspin, kin_den); this->chr_base.init_rho(ucell, this->Pgrid, this->sf.strucFac, ucell.symm, &this->kv); this->chr_base.check_rho(); @@ -127,7 +127,7 @@ void ESolver_DoubleXC::before_scf(UnitCell& ucell, const int istep) //---------------------------------------------------------- //! calculate ewald energy //---------------------------------------------------------- - if (!PARAM.inp.test_skip_ewald) + if (!this->inp_->test_skip_ewald) { // this->pelec_base->f_en.ewald_energy = H_Ewald_pw::compute_ewald(ucell, this->pw_rhod, this->sf.strucFac); this->pelec_base->f_en.ewald_energy = this->pelec->f_en.ewald_energy; @@ -151,17 +151,18 @@ void ESolver_DoubleXC::before_scf(UnitCell& ucell, const int istep) &this->dftu, this->deepks, istep, - this->exx_nao); + this->exx_nao, + this->exx_info_); } - XC_Functional::set_xc_type(PARAM.inp.deepks_out_base); + XC_Functional::set_xc_type(this->inp_->deepks_out_base); elecstate::init_scf(ucell, this->Pgrid, this->sf.strucFac, this->locpp.numeric, istep, PARAM.globalv.global_out_dir, - PARAM.inp, + *this->inp_, this->pelec_base); XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func); @@ -183,13 +184,13 @@ void ESolver_DoubleXC::iter_finish(UnitCell& ucell, const int istep, int ModuleBase::TITLE("ESolver_DoubleXC", "iter_finish"); ModuleBase::timer::start("ESolver_DoubleXC", "iter_finish"); - bool output_iter = PARAM.inp.deepks_out_labels > 0 && PARAM.inp.deepks_out_freq_elec - && (iter % PARAM.inp.deepks_out_freq_elec == 0); + bool output_iter = this->inp_->deepks_out_labels > 0 && this->inp_->deepks_out_freq_elec + && (iter % this->inp_->deepks_out_freq_elec == 0); if (output_iter) { // save output charge density (density after diagnonalization) - for (int is = 0; is < PARAM.inp.nspin; is++) + for (int is = 0; is < this->inp_->nspin; is++) { ModuleBase::GlobalFunc::DCOPY(this->chr.rho[is], this->chr_base.rho[is], this->chr.rhopw->nrxx); if (XC_Functional::get_ked_flag()) @@ -220,7 +221,7 @@ void ESolver_DoubleXC::iter_finish(UnitCell& ucell, const int istep, int // This will change the result of out_hsk // The original result of out_hsk is H of input density, but this change H to that of output density // When converged, these two should be close - if (PARAM.inp.deepks_v_delta > 0 && PARAM.inp.vl_in_h) + if (this->inp_->deepks_v_delta > 0 && this->inp_->vl_in_h) { // update real space Hamiltonian this->p_hamilt->refresh(); @@ -255,7 +256,7 @@ void ESolver_DoubleXC::iter_finish(UnitCell& ucell, const int istep, int // ---------- prepare for base ---------- // set as base functional Temporarily - XC_Functional::set_xc_type(PARAM.inp.deepks_out_base); + XC_Functional::set_xc_type(this->inp_->deepks_out_base); // update pot of pelec_base according to chr_base if (!conv_esolver) @@ -281,14 +282,14 @@ void ESolver_DoubleXC::iter_finish(UnitCell& ucell, const int istep, int // std::endl; #ifdef __MLALGO - const std::string file_ebase = deepks_interface.get_filename("ebase", PARAM.inp.deepks_out_labels, iter); + const std::string file_ebase = deepks_interface.get_filename("ebase", this->inp_->deepks_out_labels, iter); LCAO_deepks_io::save_npy_e(pelec_base->f_en.etot, file_ebase, GlobalV::MY_RANK); #endif // ---------- h_base ---------- - if (PARAM.inp.deepks_v_delta > 0) + if (this->inp_->deepks_v_delta > 0) { - if (PARAM.inp.vl_in_h) + if (this->inp_->vl_in_h) { // update real space Hamiltonian this->p_hamilt_base->refresh(); @@ -307,13 +308,13 @@ void ESolver_DoubleXC::iter_finish(UnitCell& ucell, const int istep, int std::vector h_tot(nks); DeePKS_domain::get_h_tot(this->pv, p_ham_deepks_base, h_tot, PARAM.globalv.nlocal, nks, 'H'); - const std::string file_htot = deepks_interface.get_filename("hbase", PARAM.inp.deepks_out_labels, iter); + const std::string file_htot = deepks_interface.get_filename("hbase", this->inp_->deepks_out_labels, iter); LCAO_deepks_io::save_npy_h(h_tot, file_htot, PARAM.globalv.nlocal, nks, GlobalV::MY_RANK); #endif } // ---------- o_base ---------- - if (PARAM.inp.deepks_bandgap > 0) + if (this->inp_->deepks_bandgap > 0) { // obase isn't implemented yet // don't need to solve p_hamilt_base @@ -324,17 +325,17 @@ void ESolver_DoubleXC::iter_finish(UnitCell& ucell, const int istep, int XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func); } // ---------- prepare for f_base ---------- - else if (PARAM.inp.cal_force && conv_esolver) + else if (this->inp_->cal_force && conv_esolver) { // vnew must be updated for force_scc() even if not output_iter // set as base functional Temporarily - XC_Functional::set_xc_type(PARAM.inp.deepks_out_base); + XC_Functional::set_xc_type(this->inp_->deepks_out_base); this->pelec_base->cal_converged(); // restore to original xc XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func); } - if (PARAM.inp.cal_force) + if (this->inp_->cal_force) { if (!conv_esolver) { @@ -344,7 +345,7 @@ void ESolver_DoubleXC::iter_finish(UnitCell& ucell, const int istep, int else { // copy charge - for (int is = 0; is < PARAM.inp.nspin; is++) + for (int is = 0; is < this->inp_->nspin; is++) { ModuleBase::GlobalFunc::DCOPY(this->chr.rho[is], this->chr_base.rho[is], this->chr.rhopw->nrxx); if (XC_Functional::get_ked_flag()) @@ -388,16 +389,16 @@ void ESolver_DoubleXC::cal_force(BaseCell& basecell, ModuleBase::matrix& Force_Stress_LCAO fsl(this->RA, ucell.nat); // set as base functional Temporarily - XC_Functional::set_xc_type(PARAM.inp.deepks_out_base); + XC_Functional::set_xc_type(this->inp_->deepks_out_base); this->deepks.dpks_out_type = "base"; // for deepks method fsl.getForceStress(ucell, this->get_vdw_result(), - PARAM.inp.cal_force, - PARAM.inp.cal_stress, - PARAM.inp.test_force, - PARAM.inp.test_stress, + this->inp_->cal_force, + this->inp_->cal_stress, + this->inp_->test_force, + this->inp_->test_stress, this->gd, this->pv, this->pelec_base, @@ -415,7 +416,8 @@ void ESolver_DoubleXC::cal_force(BaseCell& basecell, ModuleBase::matrix& this->dftu, this->deepks, this->exx_nao, - &ucell.symm); + &ucell.symm, + this->exx_info_); // restore to original xc XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func); diff --git a/source/source_esolver/esolver_dp.cpp b/source/source_esolver/esolver_dp.cpp index 84359cde992..18efea003ef 100644 --- a/source/source_esolver/esolver_dp.cpp +++ b/source/source_esolver/esolver_dp.cpp @@ -34,6 +34,8 @@ void ESolver_DP::before_all_runners(BaseCell& basecell, const Input_para& inp) basecell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(basecell); + this->inp_ = &inp; + dp_potential = 0; dp_force.create(ucell.nat, 3); dp_virial.create(3, 3); @@ -163,7 +165,7 @@ void ESolver_DP::cal_stress(BaseCell& basecell, ModuleBase::matrix& stress) // external stress double unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; - double external_stress[3] = {PARAM.inp.press1, PARAM.inp.press2, PARAM.inp.press3}; + double external_stress[3] = {this->inp_->press1, this->inp_->press2, this->inp_->press3}; for (int i = 0; i < 3; i++) { stress(i, i) -= external_stress[i] / unit_transform; diff --git a/source/source_esolver/esolver.cpp b/source/source_esolver/esolver_factory.cpp similarity index 83% rename from source/source_esolver/esolver.cpp rename to source/source_esolver/esolver_factory.cpp index 135f6991d05..93e708b4258 100644 --- a/source/source_esolver/esolver.cpp +++ b/source/source_esolver/esolver_factory.cpp @@ -1,5 +1,6 @@ -#include "esolver.h" +#include "esolver_factory.h" +#include "esolver.h" #include "esolver_ks_pw.h" #include "esolver_sdft_pw.h" #include "source_base/module_device/device.h" @@ -28,36 +29,36 @@ namespace ModuleESolver { -std::string determine_type() +std::string determine_type(const Input_para& inp) { std::string esolver_type = "none"; - if (PARAM.inp.basis_type == "pw") + if (inp.basis_type == "pw") { - if (PARAM.inp.esolver_type == "sdft") + if (inp.esolver_type == "sdft") { esolver_type = "sdft_pw"; } - else if (PARAM.inp.esolver_type == "ofdft") + else if (inp.esolver_type == "ofdft") { esolver_type = "ofdft"; } - else if (PARAM.inp.esolver_type == "tdofdft") + else if (inp.esolver_type == "tdofdft") { esolver_type = "tdofdft"; } - else if (PARAM.inp.esolver_type == "ksdft") + else if (inp.esolver_type == "ksdft") { esolver_type = "ksdft_pw"; } } - else if (PARAM.inp.basis_type == "lcao_in_pw") + else if (inp.basis_type == "lcao_in_pw") { #ifdef __LCAO - if (PARAM.inp.esolver_type == "sdft") + if (inp.esolver_type == "sdft") { esolver_type = "sdft_pw"; } - else if (PARAM.inp.esolver_type == "ksdft") + else if (inp.esolver_type == "ksdft") { esolver_type = "ksdft_lip"; } @@ -65,22 +66,22 @@ std::string determine_type() ModuleBase::WARNING_QUIT("ESolver", "Calculation involving numerical orbitals must be compiled with __LCAO"); #endif } - else if (PARAM.inp.basis_type == "lcao") + else if (inp.basis_type == "lcao") { #ifdef __LCAO - if (PARAM.inp.esolver_type == "tddft") + if (inp.esolver_type == "tddft") { esolver_type = "ksdft_lcao_tddft"; } - else if (PARAM.inp.esolver_type == "ksdft") + else if (inp.esolver_type == "ksdft") { esolver_type = "ksdft_lcao"; } - else if (PARAM.inp.esolver_type == "ks-lr") + else if (inp.esolver_type == "ks-lr") { esolver_type = "ksdft_lr_lcao"; } - else if (PARAM.inp.esolver_type == "lr") + else if (inp.esolver_type == "lr") { esolver_type = "lr_lcao"; } @@ -89,15 +90,15 @@ std::string determine_type() #endif } - if (PARAM.inp.esolver_type == "lj") + if (inp.esolver_type == "lj") { esolver_type = "lj_pot"; } - else if (PARAM.inp.esolver_type == "dp") + else if (inp.esolver_type == "dp") { esolver_type = "dp_pot"; } - else if (PARAM.inp.esolver_type == "nep") + else if (inp.esolver_type == "nep") { esolver_type = "nep_pot"; } @@ -108,7 +109,7 @@ std::string determine_type() GlobalV::ofs_running << "\n #ENERGY SOLVER# " << esolver_type << std::endl; - auto device_info = PARAM.inp.device; + auto device_info = inp.device; for (char& c: device_info) { @@ -117,8 +118,8 @@ std::string determine_type() c = std::toupper(c); } } - base_device::information::output_device_info(std::cout, PARAM.inp.device); - base_device::information::output_device_info(GlobalV::ofs_running, PARAM.inp.device); + base_device::information::output_device_info(std::cout, inp.device); + base_device::information::output_device_info(GlobalV::ofs_running, inp.device); /***auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast>(end_time - start_time); std::cout << "hipGetDeviceInfo took " << duration.count() << " seconds" << std::endl;***/ @@ -129,15 +130,15 @@ std::string determine_type() ESolver* init_esolver(const Input_para& inp) { // determine type of esolver based on INPUT information - const std::string esolver_type = determine_type(); + const std::string esolver_type = determine_type(inp); // initialize the corresponding Esolver child class if (esolver_type == "ksdft_pw") { #if ((defined __CUDA) || (defined __ROCM)) - if (PARAM.inp.device == "gpu") + if (inp.device == "gpu") { - if (PARAM.inp.precision == "single") + if (inp.precision == "single") { return new ESolver_KS_PW, base_device::DEVICE_GPU>(); } @@ -147,7 +148,7 @@ ESolver* init_esolver(const Input_para& inp) } } #endif - if (PARAM.inp.precision == "single") + if (inp.precision == "single") { return new ESolver_KS_PW, base_device::DEVICE_CPU>(); } @@ -159,9 +160,9 @@ ESolver* init_esolver(const Input_para& inp) else if (esolver_type == "sdft_pw") { #if ((defined __CUDA) || (defined __ROCM)) - if (PARAM.inp.device == "gpu") + if (inp.device == "gpu") { - // if (PARAM.inp.precision == "single") + // if (inp.precision == "single") // { // return new ESolver_SDFT_PW, base_device::DEVICE_GPU>(); // } @@ -171,7 +172,7 @@ ESolver* init_esolver(const Input_para& inp) // } } #endif - // if (PARAM.inp.precision == "single") + // if (inp.precision == "single") // { // return new ESolver_SDFT_PW, base_device::DEVICE_CPU>(); // } @@ -183,7 +184,7 @@ ESolver* init_esolver(const Input_para& inp) #ifdef __LCAO else if (esolver_type == "ksdft_lip") { - if (PARAM.inp.precision == "single") + if (inp.precision == "single") { return new ESolver_KS_LIP>(); } @@ -194,7 +195,7 @@ ESolver* init_esolver(const Input_para& inp) } else if (esolver_type == "ksdft_lcao") { - if (PARAM.inp.calculation == "get_s") + if (inp.calculation == "get_s") { if (PARAM.globalv.gamma_only_local) { @@ -205,13 +206,13 @@ ESolver* init_esolver(const Input_para& inp) return new ESolver_GetS(); } } - else if (PARAM.inp.deepks_out_base != "none") + else if (inp.deepks_out_base != "none") { if (PARAM.globalv.gamma_only_local) { return new ESolver_DoubleXC(); } - else if (PARAM.inp.nspin < 4) + else if (inp.nspin < 4) { return new ESolver_DoubleXC, double>(); } @@ -220,13 +221,13 @@ ESolver* init_esolver(const Input_para& inp) return new ESolver_DoubleXC, std::complex>(); } } - else if (PARAM.inp.dm_to_rho) + else if (inp.dm_to_rho) { if (PARAM.globalv.gamma_only_local) { ModuleBase::WARNING_QUIT("ESolver", "dm_to_rho is not implemented for gamma_only"); } - else if (PARAM.inp.nspin < 4) + else if (inp.nspin < 4) { return new ESolver_DM2rho, double>(); } @@ -241,7 +242,7 @@ ESolver* init_esolver(const Input_para& inp) { return new ESolver_KS_LCAO(); } - else if (PARAM.inp.nspin < 4) + else if (inp.nspin < 4) { return new ESolver_KS_LCAO, double>(); } @@ -253,10 +254,10 @@ ESolver* init_esolver(const Input_para& inp) } else if (esolver_type == "ksdft_lcao_tddft") { - if (PARAM.inp.nspin < 4) + if (inp.nspin < 4) { #if ((defined __CUDA) /* || (defined __ROCM) */) - if (PARAM.inp.device == "gpu") + if (inp.device == "gpu") { return new ESolver_KS_LCAO_TDDFT(); } @@ -266,7 +267,7 @@ ESolver* init_esolver(const Input_para& inp) else { #if ((defined __CUDA) /* || (defined __ROCM) */) - if (PARAM.inp.device == "gpu") + if (inp.device == "gpu") { return new ESolver_KS_LCAO_TDDFT, base_device::DEVICE_GPU>(); } diff --git a/source/source_esolver/esolver_factory.h b/source/source_esolver/esolver_factory.h new file mode 100644 index 00000000000..381bbf5bb03 --- /dev/null +++ b/source/source_esolver/esolver_factory.h @@ -0,0 +1,39 @@ +#ifndef ESOLVER_FACTORY_H +#define ESOLVER_FACTORY_H + +#include + +struct Input_para; + +namespace ModuleESolver +{ + +class ESolver; + +/** + * @brief Determine the ESolver type string from input parameters. + * + * The type is decided based on inp.basis_type and inp.esolver_type, + * together with device/precision hints written to the running log. + * + * @param [in] inp Input parameters used to determine the ESolver type. + * @return [out] std::string The type label consumed by init_esolver(). + */ +std::string determine_type(const Input_para& inp); + +/** + * @brief Determine and initialize an ESolver based on input information. + * + * This function determines the type of ESolver to create based on input + * information and initializes the corresponding ESolver child class. It + * supports various ESolver types including ksdft_pw, ksdft_lcao, + * ksdft_lcao_tddft, sdft_pw, ofdft, lj_pot, and dp_pot. + * + * @param [in] inp Input parameters used to select and configure the ESolver. + * @return [out] A pointer to the newly created ESolver object. + */ +ESolver* init_esolver(const Input_para& inp); + +} // namespace ModuleESolver + +#endif diff --git a/source/source_esolver/esolver_fp.cpp b/source/source_esolver/esolver_fp.cpp index ee2a863d08f..db8872ca2ec 100644 --- a/source/source_esolver/esolver_fp.cpp +++ b/source/source_esolver/esolver_fp.cpp @@ -39,30 +39,36 @@ void ESolver_FP::before_all_runners(BaseCell& basecell, const Input_para& inp) basecell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(basecell); + this->inp_ = &inp; + ModuleBase::TITLE("ESolver_FP", "before_all_runners"); //! 1) read pseudopotentials - const std::string pseudo_dir = PARAM.inp.pseudo_dir; const std::string global_out_dir = PARAM.globalv.global_out_dir; - const bool out_element_info = PARAM.inp.out_element_info; - const std::string dft_functional = PARAM.inp.dft_functional; - const bool lspinorb = PARAM.inp.lspinorb; - const double pseudo_rcut = PARAM.inp.pseudo_rcut; - const double soc_lambda = PARAM.inp.soc_lambda; - const int nspin = PARAM.inp.nspin; const int npol = PARAM.globalv.npol; - const std::string basis_type = PARAM.inp.basis_type; - const std::string esolver_type = PARAM.inp.esolver_type; - const std::string init_wfc = PARAM.inp.init_wfc; - const int nbands = PARAM.inp.nbands; const bool two_fermi = PARAM.globalv.two_fermi; - const double nelec_delta = PARAM.inp.nelec_delta; - const std::string smearing_method = PARAM.inp.smearing_method; - const std::string ks_solver = PARAM.inp.ks_solver; - const int bndpar = PARAM.inp.bndpar; - const double nelec = PARAM.inp.nelec; - const double nupdown = PARAM.inp.nupdown; - auto atoms_info = unitcell::read_pseudo(GlobalV::ofs_running, ucell, pseudo_dir, global_out_dir, out_element_info, dft_functional, lspinorb, pseudo_rcut, soc_lambda, nspin, npol, basis_type, esolver_type, init_wfc, nbands, two_fermi, nelec_delta, smearing_method, ks_solver, bndpar, nelec, nupdown); + auto atoms_info = unitcell::read_pseudo(GlobalV::ofs_running, + ucell, + this->inp_->pseudo_dir, + global_out_dir, + this->inp_->out_element_info, + this->inp_->dft_functional, + this->inp_->lspinorb, + this->inp_->pseudo_rcut, + this->inp_->soc_lambda, + this->inp_->nspin, + npol, + this->inp_->basis_type, + this->inp_->esolver_type, + this->inp_->init_wfc, + this->inp_->nbands, + two_fermi, + this->inp_->nelec_delta, + this->inp_->smearing_method, + this->inp_->ks_solver, + this->inp_->bndpar, + this->inp_->nelec, + this->inp_->nupdown); elecstate::ParamUpdater::update_from_atoms_info(atoms_info); //! 2) setup pw_rho, pw_rhod, pw_big, sf, and read_pseudopotentials @@ -78,9 +84,9 @@ void ESolver_FP::before_all_runners(BaseCell& basecell, const Input_para& inp) //! 5) symmetry analysis should be performed every time the cell is changed if (ModuleSymmetry::Symmetry::symm_flag == 1) { - const int cal_symm_repr[2] = {PARAM.inp.cal_symm_repr[0], PARAM.inp.cal_symm_repr[1]}; + const int cal_symm_repr[2] = {this->inp_->cal_symm_repr[0], this->inp_->cal_symm_repr[1]}; ucell.symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, - PARAM.inp.symmetry_prec, inp.nspin, PARAM.inp.calculation, cal_symm_repr); + this->inp_->symmetry_prec, inp.nspin, this->inp_->calculation, cal_symm_repr); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); } @@ -89,17 +95,16 @@ void ESolver_FP::before_all_runners(BaseCell& basecell, const Input_para& inp) //! 7) setup k points in the Brillouin zone according to symmetry. const bool use_ibz = !inp.berry_phase && ModuleSymmetry::Symmetry::symm_flag != -1; const bool gamma_only_local = PARAM.globalv.gamma_only_local; - const double kspacing[3] = {PARAM.inp.kspacing[0], PARAM.inp.kspacing[1], PARAM.inp.kspacing[2]}; - const std::string kmesh_type = PARAM.inp.kmesh_type; - const double koffset[3] = {PARAM.inp.koffset[0], PARAM.inp.koffset[1], PARAM.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, kmesh_type, koffset); + 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); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); //! 8) print information ModuleIO::print_parameters(ucell, this->kv, inp); //! 9) parallel of FFT grid - const int nprocgroup = (PARAM.inp.esolver_type == "sdft") ? GlobalV::NPROC_IN_BNDGROUP : GlobalV::NPROC; + const int nprocgroup = (this->inp_->esolver_type == "sdft") ? GlobalV::NPROC_IN_BNDGROUP : GlobalV::NPROC; this->Pgrid.init(this->pw_rhod->nx, this->pw_rhod->ny, this->pw_rhod->nz, this->pw_rhod->nplane, this->pw_rhod->nrxx, pw_big->nbz, pw_big->bz, nprocgroup); @@ -168,14 +173,14 @@ void ESolver_FP::before_scf(UnitCell& ucell, const int istep) // perform symmetry analysis if (ModuleSymmetry::Symmetry::symm_flag == 1) { - const int cal_symm_repr[2] = {PARAM.inp.cal_symm_repr[0], PARAM.inp.cal_symm_repr[1]}; + const int cal_symm_repr[2] = {this->inp_->cal_symm_repr[0], this->inp_->cal_symm_repr[1]}; ucell.symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, - PARAM.inp.symmetry_prec, PARAM.inp.nspin, PARAM.inp.calculation, cal_symm_repr); + this->inp_->symmetry_prec, this->inp_->nspin, this->inp_->calculation, cal_symm_repr); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); } // reset k-points - KVectorUtils::set_after_vc(kv, PARAM.inp.nspin, ucell.G); + KVectorUtils::set_after_vc(kv, this->inp_->nspin, ucell.G); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); } @@ -189,10 +194,10 @@ void ESolver_FP::before_scf(UnitCell& ucell, const int istep) //! Evaluate the vdW correction once for this ionic configuration. this->vdw_result_.reset(); - auto vdw_solver = vdw::make_vdw(ucell, PARAM.inp, &(GlobalV::ofs_running)); + auto vdw_solver = vdw::make_vdw(ucell, *this->inp_, &(GlobalV::ofs_running)); if (vdw_solver != nullptr) { - const vdw::VdwRequest request(PARAM.inp.cal_force, PARAM.inp.cal_stress); + const vdw::VdwRequest request(this->inp_->cal_force, this->inp_->cal_stress); this->vdw_result_.reset(new vdw::VdwResult(vdw_solver->evaluate(request))); this->pelec->f_en.evdw = this->vdw_result_->energy; } @@ -202,17 +207,17 @@ void ESolver_FP::before_scf(UnitCell& ucell, const int istep) } //! calculate ewald energy - if (!PARAM.inp.test_skip_ewald) + if (!this->inp_->test_skip_ewald) { this->pelec->f_en.ewald_energy = H_Ewald_pw::compute_ewald(ucell, this->pw_rhod, this->sf.strucFac); } //! set direction of magnetism, used in non-collinear case - unitcell::cal_ux(ucell, PARAM.inp.nspin); + unitcell::cal_ux(ucell, this->inp_->nspin); //! output the initial charge density ModuleIO::write_chg_init(ucell, this->Pgrid, this->chr, this->pelec->eferm, istep, - PARAM.globalv.global_out_dir, PARAM.inp, PARAM.globalv.two_fermi); + PARAM.globalv.global_out_dir, *this->inp_, PARAM.globalv.two_fermi); return; } @@ -220,18 +225,18 @@ void ESolver_FP::before_scf(UnitCell& ucell, const int istep) void ESolver_FP::iter_finish(UnitCell& ucell, const int istep, int& iter, bool& conv_esolver) { //! output charge density in G-space, or if available, kinetic energy density in G-space - if (PARAM.inp.out_chg[0] != -1) + if (this->inp_->out_chg[0] != -1) { - if (iter % PARAM.inp.out_freq_elec == 0 || iter == PARAM.inp.scf_nmax || conv_esolver) + if (iter % this->inp_->out_freq_elec == 0 || iter == this->inp_->scf_nmax || conv_esolver) { - for (int is = 0; is < PARAM.inp.nspin; is++) + for (int is = 0; is < this->inp_->nspin; is++) { this->pw_rhod->real2recip(this->chr.rho_save[is], this->chr.rhog_save[is]); } - ModuleIO::write_rhog(PARAM.globalv.global_out_dir + PARAM.inp.suffix + "-CHARGE-DENSITY.restart", + ModuleIO::write_rhog(PARAM.globalv.global_out_dir + this->inp_->suffix + "-CHARGE-DENSITY.restart", PARAM.globalv.gamma_only_pw, this->pw_rhod, - PARAM.inp.nspin, + this->inp_->nspin, ucell.GT, this->chr.rhog_save, GlobalV::MY_POOL, @@ -240,17 +245,17 @@ void ESolver_FP::iter_finish(UnitCell& ucell, const int istep, int& iter, bool& if (XC_Functional::get_ked_flag()) { - std::vector> kin_g_space(PARAM.inp.nspin * this->chr.ngmc, {0.0, 0.0}); + std::vector> kin_g_space(this->inp_->nspin * this->chr.ngmc, {0.0, 0.0}); std::vector*> kin_g; - for (int is = 0; is < PARAM.inp.nspin; is++) + for (int is = 0; is < this->inp_->nspin; is++) { kin_g.push_back(kin_g_space.data() + is * this->chr.ngmc); this->pw_rhod->real2recip(this->chr.kin_r_save[is], kin_g[is]); } - ModuleIO::write_rhog(PARAM.globalv.global_out_dir + PARAM.inp.suffix + "-TAU-DENSITY.restart", + ModuleIO::write_rhog(PARAM.globalv.global_out_dir + this->inp_->suffix + "-TAU-DENSITY.restart", PARAM.globalv.gamma_only_pw, this->pw_rhod, - PARAM.inp.nspin, + this->inp_->nspin, ucell.GT, kin_g.data(), GlobalV::MY_POOL, diff --git a/source/source_esolver/esolver_gets.cpp b/source/source_esolver/esolver_gets.cpp index 291c6ebb137..b1cdceea24c 100644 --- a/source/source_esolver/esolver_gets.cpp +++ b/source/source_esolver/esolver_gets.cpp @@ -30,66 +30,51 @@ void ESolver_GetS::before_all_runners(BaseCell& basecell, const Input_para& inp) basecell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(basecell); + this->inp_ = &inp; + ModuleBase::TITLE("ESolver_GetS", "before_all_runners"); ModuleBase::timer::start("ESolver_GetS", "before_all_runners"); // 1.1) read pseudopotentials - const std::string pseudo_dir = PARAM.inp.pseudo_dir; const std::string global_out_dir = PARAM.globalv.global_out_dir; - const bool out_element_info = PARAM.inp.out_element_info; - const std::string dft_functional = PARAM.inp.dft_functional; - const bool lspinorb = PARAM.inp.lspinorb; - const double pseudo_rcut = PARAM.inp.pseudo_rcut; - const double soc_lambda = PARAM.inp.soc_lambda; - const int nspin = PARAM.inp.nspin; const int npol = PARAM.globalv.npol; - const std::string basis_type = PARAM.inp.basis_type; - const std::string esolver_type = PARAM.inp.esolver_type; - const std::string init_wfc = PARAM.inp.init_wfc; - const int nbands = PARAM.inp.nbands; const bool two_fermi = PARAM.globalv.two_fermi; - const double nelec_delta = PARAM.inp.nelec_delta; - const std::string smearing_method = PARAM.inp.smearing_method; - const std::string ks_solver = PARAM.inp.ks_solver; - const int bndpar = PARAM.inp.bndpar; - const double nelec = PARAM.inp.nelec; - const double nupdown = PARAM.inp.nupdown; // nlocal is calculated inside read_pseudo() via CalAtomsInfo::cal_atoms_info() auto atoms_info = unitcell::read_pseudo(GlobalV::ofs_running, ucell, - pseudo_dir, + this->inp_->pseudo_dir, global_out_dir, - out_element_info, - dft_functional, - lspinorb, - pseudo_rcut, - soc_lambda, - nspin, + this->inp_->out_element_info, + this->inp_->dft_functional, + this->inp_->lspinorb, + this->inp_->pseudo_rcut, + this->inp_->soc_lambda, + this->inp_->nspin, npol, - basis_type, - esolver_type, - init_wfc, - nbands, + this->inp_->basis_type, + this->inp_->esolver_type, + this->inp_->init_wfc, + this->inp_->nbands, two_fermi, - nelec_delta, - smearing_method, - ks_solver, - bndpar, - nelec, - nupdown); + this->inp_->nelec_delta, + this->inp_->smearing_method, + this->inp_->ks_solver, + this->inp_->bndpar, + this->inp_->nelec, + this->inp_->nupdown); elecstate::ParamUpdater::update_from_atoms_info(atoms_info); // 1.2) symmetrize things if (ModuleSymmetry::Symmetry::symm_flag == 1) { - const int cal_symm_repr[2] = {PARAM.inp.cal_symm_repr[0], PARAM.inp.cal_symm_repr[1]}; + const int cal_symm_repr[2] = {this->inp_->cal_symm_repr[0], this->inp_->cal_symm_repr[1]}; ucell.symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, - PARAM.inp.symmetry_prec, + this->inp_->symmetry_prec, inp.nspin, - PARAM.inp.calculation, + this->inp_->calculation, cal_symm_repr); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); } @@ -97,9 +82,8 @@ void ESolver_GetS::before_all_runners(BaseCell& basecell, const Input_para& inp) // 1.3) Setup k-points according to symmetry. const bool use_ibz = !inp.berry_phase && ModuleSymmetry::Symmetry::symm_flag != -1; const bool gamma_only_local = PARAM.globalv.gamma_only_local; - const double kspacing[3] = {PARAM.inp.kspacing[0], PARAM.inp.kspacing[1], PARAM.inp.kspacing[2]}; - const std::string kmesh_type = PARAM.inp.kmesh_type; - const double koffset[3] = {PARAM.inp.koffset[0], PARAM.inp.koffset[1], PARAM.inp.koffset[2]}; + 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, @@ -111,7 +95,7 @@ void ESolver_GetS::before_all_runners(BaseCell& basecell, const Input_para& inp) global_out_dir, gamma_only_local, kspacing, - kmesh_type, + this->inp_->kmesh_type, koffset); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); @@ -155,7 +139,7 @@ void ESolver_GetS::runner(BaseCell& basecell, const int istep) // (1) Find adjacent atoms for each atom. double search_radius = -1.0; search_radius = atom_arrange::set_sr_NL(GlobalV::ofs_running, - PARAM.inp.out_level, + this->inp_->out_level, orb_.get_rcutmax_Phi(), ucell.infoNL->get_rcutmax_Beta(), PARAM.globalv.gamma_only_local); @@ -167,14 +151,14 @@ void ESolver_GetS::runner(BaseCell& basecell, const int istep) gd, ucell, search_radius, - PARAM.inp.test_atom_input); + this->inp_->test_atom_input); Record_adj RA; RA.for_2d(ucell, gd, this->pv, PARAM.globalv.gamma_only_local, orb_.cutoffs()); if (this->p_hamilt == nullptr) { - if (PARAM.inp.nspin == 4) + if (this->inp_->nspin == 4) { this->p_hamilt = new hamilt::HamiltLCAO, std::complex>(ucell, @@ -207,14 +191,14 @@ void ESolver_GetS::runner(BaseCell& basecell, const int istep) auto* hamilt_ptr = static_cast>*>(this->p_hamilt); ModuleIO::output_SR(pv, gd, hamilt_ptr, fn); - if (PARAM.inp.out_mat_r[0]) + if (this->inp_->out_mat_r[0]) { cal_r_overlap_R r_matrix; r_matrix.init(ucell, pv, orb_); - r_matrix.out_rR(ucell, gd, istep, PARAM.inp.out_mat_r[1]); + r_matrix.out_rR(ucell, gd, istep, this->inp_->out_mat_r[1]); } - if (PARAM.inp.out_mat_ds[0]) + if (this->inp_->out_mat_ds[0]) { LCAO_HS_Arrays HS_Arrays; // store sparse arrays //! Print out sparse matrix @@ -228,7 +212,7 @@ void ESolver_GetS::runner(BaseCell& basecell, const int istep) kv, false, 1e-10, - PARAM.inp.out_mat_ds[1]); + this->inp_->out_mat_ds[1]); } ModuleBase::timer::end("ESolver_GetS", "runner"); diff --git a/source/source_esolver/esolver_ks.cpp b/source/source_esolver/esolver_ks.cpp index f1e7c240be0..d5dc5f18ddf 100644 --- a/source/source_esolver/esolver_ks.cpp +++ b/source/source_esolver/esolver_ks.cpp @@ -14,6 +14,7 @@ #include "source_io/module_output/output_log.h" // use write_head #include "source_estate/elecstate_print.h" // print_etot #include "source_lcao/module_dftu/dftu.h" // mohan add 2025-11-07 +#include "source_hamilt/module_xc/general_exx_info.h" // for init_general_exx_info namespace ModuleESolver { @@ -44,8 +45,11 @@ void ESolver_KS::before_all_runners(BaseCell& basecell, const Input_para& inp) //! 1) setup "before_all_runniers" in ESolver_FP ESolver_FP::before_all_runners(ucell, inp); - - //! 2) setup some parameters + + //! 2) initialize General_Exx_Info from input parameters + init_general_exx_info(general_exx_info_, inp); + + //! 3) setup some parameters classname = "ESolver_KS"; basisname = ""; @@ -93,27 +97,27 @@ void ESolver_KS::hamilt2rho(UnitCell& ucell, const int istep, const int iter, co // example wavefunctions uses 20 processors while density uses 10. if (PARAM.globalv.ks_run) { - drho = p_chgmix->get_drho(&this->chr, PARAM.inp.nelec); + drho = p_chgmix->get_drho(&this->chr, this->inp_->nelec); hsolver_error = 0.0; - if (iter == 1 && PARAM.inp.calculation != "nscf") + if (iter == 1 && this->inp_->calculation != "nscf") { hsolver_error - = hsolver::cal_hsolve_error(PARAM.inp.basis_type, PARAM.inp.esolver_type, diag_ethr, PARAM.inp.nelec); + = hsolver::cal_hsolve_error(this->inp_->basis_type, this->inp_->esolver_type, diag_ethr, this->inp_->nelec); // The error of HSolver is larger than drho, // so a more precise HSolver should be executed. if (hsolver_error > drho) { - diag_ethr = hsolver::reset_diag_ethr(GlobalV::ofs_running, PARAM.inp.basis_type, - PARAM.inp.esolver_type, PARAM.inp.precision, hsolver_error, - drho, diag_ethr, PARAM.inp.nelec); + diag_ethr = hsolver::reset_diag_ethr(GlobalV::ofs_running, this->inp_->basis_type, + this->inp_->esolver_type, this->inp_->precision, hsolver_error, + drho, diag_ethr, this->inp_->nelec); this->hamilt2rho_single(ucell, istep, iter, diag_ethr); - drho = p_chgmix->get_drho(&this->chr, PARAM.inp.nelec); + drho = p_chgmix->get_drho(&this->chr, this->inp_->nelec); - hsolver_error = hsolver::cal_hsolve_error(PARAM.inp.basis_type, - PARAM.inp.esolver_type, diag_ethr, PARAM.inp.nelec); + hsolver_error = hsolver::cal_hsolve_error(this->inp_->basis_type, + this->inp_->esolver_type, diag_ethr, this->inp_->nelec); } } } @@ -134,7 +138,7 @@ void ESolver_KS::runner(BaseCell& basecell, const int istep) // 2) SCF iterations bool conv_esolver = false; this->niter = this->maxniter; - this->diag_ethr = PARAM.inp.pw_diag_thr; + this->diag_ethr = this->inp_->pw_diag_thr; this->scf_nmax_flag = false; // mohan add 2025-09-21 for (int iter = 1; iter <= this->maxniter; ++iter) { @@ -179,25 +183,25 @@ void ESolver_KS::before_scf(UnitCell& ucell, const int istep) void ESolver_KS::iter_init(UnitCell& ucell, const int istep, const int iter) { - if(PARAM.inp.esolver_type != "tddft") + if(this->inp_->esolver_type != "tddft") { ModuleIO::write_head(GlobalV::ofs_running, istep, iter, this->basisname); } iter_time = ModuleBase::get_time(); - if (PARAM.inp.esolver_type == "ksdft") + if (this->inp_->esolver_type == "ksdft") { - diag_ethr = hsolver::set_diagethr_ks(PARAM.inp.basis_type, PARAM.inp.esolver_type, - PARAM.inp.calculation, PARAM.inp.init_chg, PARAM.inp.precision, istep, iter, - drho, PARAM.inp.pw_diag_thr, diag_ethr, PARAM.inp.nelec, PARAM.inp.scf_thr); + diag_ethr = hsolver::set_diagethr_ks(this->inp_->basis_type, this->inp_->esolver_type, + this->inp_->calculation, this->inp_->init_chg, this->inp_->precision, istep, iter, + drho, this->inp_->pw_diag_thr, diag_ethr, this->inp_->nelec, this->inp_->scf_thr); } - else if (PARAM.inp.esolver_type == "sdft") + else if (this->inp_->esolver_type == "sdft") { - diag_ethr = hsolver::set_diagethr_sdft(PARAM.inp.basis_type, PARAM.inp.esolver_type, - PARAM.inp.calculation, PARAM.inp.init_chg, istep, iter, drho, - PARAM.inp.pw_diag_thr, diag_ethr, PARAM.inp.nbands, esolver_KS_ne, - PARAM.inp.nelec, PARAM.inp.scf_thr); + diag_ethr = hsolver::set_diagethr_sdft(this->inp_->basis_type, this->inp_->esolver_type, + this->inp_->calculation, this->inp_->init_chg, istep, iter, drho, + this->inp_->pw_diag_thr, diag_ethr, this->inp_->nbands, esolver_KS_ne, + this->inp_->nelec, this->inp_->scf_thr); } // save input charge density (rho) @@ -218,9 +222,9 @@ void ESolver_KS::iter_finish(UnitCell& ucell, const int istep, int& iter, bool & } // 1.2) print out eigenvalues and occupations - if (PARAM.inp.out_band[0]) + if (this->inp_->out_band[0]) { - if (iter % PARAM.inp.out_freq_elec == 0 || iter == PARAM.inp.scf_nmax || conv_esolver) + if (iter % this->inp_->out_freq_elec == 0 || iter == this->inp_->scf_nmax || conv_esolver) { ModuleIO::write_eig_iter(this->pelec->ekb,this->pelec->wg,*this->pelec->klist); } @@ -228,7 +232,7 @@ void ESolver_KS::iter_finish(UnitCell& ucell, const int istep, int& iter, bool & // 2.1) compute magnetization, only for spin==2 ucell.magnet.compute_mag(ucell.omega, this->chr.nrxx, this->chr.nxyz, this->chr.rho, - PARAM.inp.nspin, PARAM.globalv.two_fermi, PARAM.inp.nelec, + this->inp_->nspin, PARAM.globalv.two_fermi, this->inp_->nelec, this->pelec->nelec_spin.data()); // 2.2) charge mixing @@ -236,7 +240,7 @@ void ESolver_KS::iter_finish(UnitCell& ucell, const int istep, int& iter, bool & bool converged_u = true; // to avoid unnecessary dependence on dft+u, refactor is needed #ifdef __LCAO - if (PARAM.inp.dft_plus_u) + if (this->inp_->dft_plus_u) { converged_u = this->dftu.u_converged(); } @@ -244,7 +248,7 @@ void ESolver_KS::iter_finish(UnitCell& ucell, const int istep, int& iter, bool & module_charge::chgmixing_ks(iter, ucell, this->pelec, this->chr, this->p_chgmix, this->pw_rhod->nrxx, this->drho, this->oscillate_esolver, conv_esolver, hsolver_error, - this->scf_thr, this->scf_ene_thr, converged_u, PARAM.inp); + this->scf_thr, this->scf_ene_thr, converged_u, *this->inp_); // 2.3) Update potentials (should be done every SF iter) elecstate::update_pot(ucell, this->pelec, this->chr, conv_esolver); @@ -264,7 +268,7 @@ void ESolver_KS::iter_finish(UnitCell& ucell, const int istep, int& iter, bool & double dkin = 0.0; // for meta-GGA if (XC_Functional::get_ked_flag()) { - dkin = p_chgmix->get_dkin(&this->chr, PARAM.inp.nelec); + dkin = p_chgmix->get_dkin(&this->chr, this->inp_->nelec); } // Iter finish @@ -296,7 +300,7 @@ void ESolver_KS::after_scf(UnitCell& ucell, const int istep, const bool conv_eso /* // 1) calculate the kinetic energy density tau - if (PARAM.inp.out_elf[0] > 0) + if (this->inp_->out_elf[0] > 0) { assert(this->psi != nullptr); this->pelec->cal_tau(*(this->psi)); @@ -310,7 +314,7 @@ void ESolver_KS::after_scf(UnitCell& ucell, const int istep, const bool conv_eso ModuleIO::write_eig_file(this->pelec->ekb, this->pelec->wg, this->kv, istep); // 4) write band information to band.txt - ModuleIO::write_bands(PARAM.inp, this->pelec->ekb, this->kv); + ModuleIO::write_bands(*this->inp_, this->pelec->ekb, this->kv); } diff --git a/source/source_esolver/esolver_ks.h b/source/source_esolver/esolver_ks.h index 00f5b33526f..c0b69a87984 100644 --- a/source/source_esolver/esolver_ks.h +++ b/source/source_esolver/esolver_ks.h @@ -7,6 +7,7 @@ #include "source_estate/module_charge/charge_mixing.h" // use charge mixing #include "source_hamilt/hamilt.h" // use Hamiltonian #include "source_hamilt/hamilt_base.h" // use Hamiltonian base class +#include "source_hamilt/module_xc/general_exx_info.h" // ESolver owns General_Exx_Info value #include "source_lcao/module_dftu/dftu.h" // mohan add 20251107 #include "source_pw/module_pwdft/vnl_pw.h" @@ -73,6 +74,9 @@ class ESolver_KS : public ESolver_FP int niter; //! iter steps actually used in scf bool oscillate_esolver = false; // whether esolver is oscillated bool scf_nmax_flag = false; // whether scf has reached nmax, mohan add 20250921 + + /// General EXX info owned by ESolver, initialized from input parameters. + General_Exx_Info general_exx_info_; }; } // namespace ModuleESolver #endif diff --git a/source/source_esolver/esolver_ks_lcao.cpp b/source/source_esolver/esolver_ks_lcao.cpp index 4c35d007229..9f958d68a79 100644 --- a/source/source_esolver/esolver_ks_lcao.cpp +++ b/source/source_esolver/esolver_ks_lcao.cpp @@ -55,13 +55,16 @@ void ESolver_KS_LCAO::before_all_runners(BaseCell& basecell, const Input ModuleBase::TITLE("ESolver_KS_LCAO", "before_all_runners"); ModuleBase::timer::start("ESolver_KS_LCAO", "before_all_runners"); - // 0) init EXX - moved from constructor to ensure GlobalC::exx_info.info_global is already set - this->exx_nao.init(ucell); - - // 1) before_all_runners in ESolver_KS + // 1) before_all_runners in ESolver_KS (includes init_general_exx_info) ESolver_KS::before_all_runners(ucell, inp); - // 2) autoset nbands in ElecState before init_basis (for Psi 2d division) + // 2) init full Exx_Info for LCAO (includes info_ri, info_opt_abfs, info_lip) + init_exx_info(this->exx_info_, inp); + + // 3) init EXX NAO - must be after init_exx_info + this->exx_nao.init(ucell, this->exx_info_); + + // 3) autoset nbands in ElecState before init_basis (for Psi 2d division) if (this->pelec == nullptr) { // TK stands for double and std::complex? @@ -69,16 +72,16 @@ void ESolver_KS_LCAO::before_all_runners(BaseCell& basecell, const Input this->kv.get_nks(), this->pw_big); } - // 3) read LCAO orbitals/projectors and construct the interpolation tables. + // 4) read LCAO orbitals/projectors and construct the interpolation tables. LCAO_domain::init_basis_lcao(this->pv, inp.onsite_radius, inp.lcao_ecut, inp.lcao_dk, inp.lcao_dr, inp.lcao_rmax, ucell, two_center_bundle_, orb_); - // 4) setup EXX calculations + // 5) setup EXX calculations if (inp.calculation == "gen_opt_abfs") { #ifdef __EXX Exx_Opt_Orb exx_opt_orb; - exx_opt_orb.generate_matrix(GlobalC::exx_info.info_opt_abfs, this->kv, ucell, this->orb_); + exx_opt_orb.generate_matrix(exx_info_.info_opt_abfs, this->kv, ucell, this->orb_); #else ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::before_all_runners", "calculation=gen_opt_abfs must compile __EXX"); #endif @@ -90,7 +93,7 @@ void ESolver_KS_LCAO::before_all_runners(BaseCell& basecell, const Input LCAO_domain::set_pot(ucell, this->kv, this->sf, *this->pw_rho, *this->pw_rhod, this->pelec, this->orb_, this->pv, this->locpp, this->dftu, - this->solvent, this->exx_nao, this->deepks, inp); + this->solvent, this->exx_nao, this->deepks, inp, this->exx_info_); //! if kpar is not divisible by nks, print a warning ModuleIO::print_kpar(this->kv.get_nks(), PARAM.globalv.kpar_lcao); @@ -100,7 +103,7 @@ void ESolver_KS_LCAO::before_all_runners(BaseCell& basecell, const Input { rdmft_solver.init(this->pv, ucell, this->gd, this->kv, *(this->pelec), this->orb_, - two_center_bundle_, inp.dft_functional, inp.rdmft_power_alpha); + two_center_bundle_, inp.dft_functional, inp.rdmft_power_alpha, this->exx_info_); } ModuleBase::timer::end("ESolver_KS_LCAO", "before_all_runners"); @@ -119,12 +122,12 @@ void ESolver_KS_LCAO::before_scf(UnitCell& ucell, const int istep) //! 2) find search radius double search_radius = atom_arrange::set_sr_NL(GlobalV::ofs_running, - PARAM.inp.out_level, orb_.get_rcutmax_Phi(), ucell.infoNL->get_rcutmax_Beta(), + this->inp_->out_level, orb_.get_rcutmax_Phi(), ucell.infoNL->get_rcutmax_Beta(), PARAM.globalv.gamma_only_local); //! 3) use search_radius to search adj atoms atom_arrange::search(PARAM.globalv.search_pbc, GlobalV::ofs_running, - this->gd, ucell, search_radius, PARAM.inp.test_atom_input); + this->gd, ucell, search_radius, this->inp_->test_atom_input); //! 4) initialize NAO basis set // here new is a unique pointer, which will be deleted automatically @@ -153,7 +156,7 @@ void ESolver_KS_LCAO::before_scf(UnitCell& ucell, const int istep) { this->p_hamilt = new hamilt::HamiltLCAO( ucell, this->gd, &this->pv, this->pelec->pot, this->kv, - two_center_bundle_, orb_, this->dmat.dm, &this->dftu, this->deepks, istep, exx_nao); + two_center_bundle_, orb_, this->dmat.dm, &this->dftu, this->deepks, istep, exx_nao, this->exx_info_); } // 9) for each ionic step, the overlap must be rebuilt @@ -163,14 +166,14 @@ void ESolver_KS_LCAO::before_scf(UnitCell& ucell, const int istep) // reference from a null unique_ptr (undefined behaviour). if (two_center_bundle_.overlap_orb_alpha) { - this->deepks.build_overlap(ucell, orb_, pv, gd, *(two_center_bundle_.overlap_orb_alpha), PARAM.inp); + this->deepks.build_overlap(ucell, orb_, pv, gd, *(two_center_bundle_.overlap_orb_alpha), *this->inp_); } // 10) prepare sc calculation - init_deltaspin_lcao(ucell, PARAM.inp, &(this->pv), this->kv, this->p_hamilt, this->psi, this->dmat.dm, this->pelec); + init_deltaspin_lcao(ucell, *this->inp_, &(this->pv), this->kv, this->p_hamilt, this->psi, this->dmat.dm, this->pelec); // 11) set xc type before the first cal of xc in pelec->init_scf, Peize Lin add 2016-12-03 - this->exx_nao.before_scf(ucell, this->kv, orb_, this->p_chgmix, istep, PARAM.inp); + this->exx_nao.before_scf(ucell, this->kv, orb_, this->p_chgmix, istep, *this->inp_, this->exx_info_); // 12) initalize DM(R), which has the same size with Hamiltonian(R) auto* hamilt_lcao = dynamic_cast*>(this->p_hamilt); @@ -185,21 +188,21 @@ void ESolver_KS_LCAO::before_scf(UnitCell& ucell, const int istep) if(istep == 0)//if the first scf step, readin DMR from file, { //calculate or readin the density matrix DMR - if(PARAM.inp.init_chg == "dm" || PARAM.inp.init_chg == "dm_no_renormalize") + if(this->inp_->init_chg == "dm" || this->inp_->init_chg == "dm_no_renormalize") { //! 13.1.1) init charge density from density matrix file - LCAO_domain::init_chg_dm(PARAM.globalv.global_readin_dir, PARAM.inp.nspin, + LCAO_domain::init_chg_dm(PARAM.globalv.global_readin_dir, this->inp_->nspin, this->dmat, ucell, &(this->pv), this->pelec->charge); } - if(PARAM.inp.init_chg == "hr") + if(this->inp_->init_chg == "hr") { //! 13.1.2) init charge density from Hamiltonian matrix file - LCAO_domain::init_chg_hr(PARAM.globalv.global_readin_dir, PARAM.inp.nspin, + LCAO_domain::init_chg_hr(PARAM.globalv.global_readin_dir, this->inp_->nspin, static_cast*>(this->p_hamilt), ucell, &(this->pv), this->psi[0], this->pelec, *this->dmat.dm, - this->chr, PARAM.inp.ks_solver); + this->chr, this->inp_->ks_solver); } } - else if(PARAM.inp.esolver_type!="tddft")//if not, use the DMR calculated from last step + else if(this->inp_->esolver_type!="tddft")//if not, use the DMR calculated from last step { // 13.1.2) two cases are considered: // 1. DMK in DensityMatrix is not empty (istep > 0), then DMR is initialized by DMK @@ -208,7 +211,7 @@ void ESolver_KS_LCAO::before_scf(UnitCell& ucell, const int istep) } // 13.2) init_scf, should be before_scf? mohan add 2025-03-10 elecstate::init_scf(ucell, this->Pgrid, this->sf.strucFac, this->locpp.numeric, - istep, PARAM.globalv.global_out_dir, PARAM.inp, this->pelec); + istep, PARAM.globalv.global_out_dir, *this->inp_, this->pelec); #ifdef __MLALGO // 14) initialize DM2(R) of DeePKS, the DM2(R) is different from DM(R) @@ -216,10 +219,10 @@ void ESolver_KS_LCAO::before_scf(UnitCell& ucell, const int istep) #endif // 16) the electron charge density should be symmetrized, - Symmetry_rho::symmetrize_rho(PARAM.inp.nspin, this->chr, this->pw_rho, ucell.symm); + Symmetry_rho::symmetrize_rho(this->inp_->nspin, this->chr, this->pw_rho, ucell.symm); // 17) update of RDMFT, added by jghan - if (PARAM.inp.rdmft == true) + if (this->inp_->rdmft == true) { rdmft_solver.update_ion(ucell, *(this->pw_rho), this->locpp.vloc, this->sf.strucFac); } @@ -248,13 +251,13 @@ void ESolver_KS_LCAO::cal_force(BaseCell& basecell, ModuleBase::matrix& deepks.dpks_out_type = "tot"; // for deepks method - fsl.getForceStress(ucell, this->get_vdw_result(), PARAM.inp.cal_force, PARAM.inp.cal_stress, - PARAM.inp.test_force, PARAM.inp.test_stress, + fsl.getForceStress(ucell, this->get_vdw_result(), this->inp_->cal_force, this->inp_->cal_stress, + this->inp_->test_force, this->inp_->test_stress, this->gd, this->pv, this->pelec, this->dmat, this->psi, two_center_bundle_, orb_, force, this->scs, this->locpp, this->sf, this->kv, this->pw_rho, this->solvent, this->dftu, this->deepks, - this->exx_nao, &ucell.symm, PARAM.inp.td_stype, + this->exx_nao, &ucell.symm, this->exx_info_, this->inp_->td_stype, static_cast*>(this->p_hamilt)); // delete RA after cal_force @@ -305,11 +308,11 @@ void ESolver_KS_LCAO::after_all_runners(BaseCell& basecell) } ModuleIO::ctrl_runner_lcao(ucell, - PARAM.inp, this->kv, this->pelec, this->dmat, this->pv, this->Pgrid, + *this->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); + this->sf, this->locpp.vloc, this->exx_nao, this->exx_info_, this->solvent); #ifdef __MPI @@ -331,20 +334,20 @@ void ESolver_KS_LCAO::iter_init(UnitCell& ucell, const int istep, const ESolver_KS::iter_init(ucell, istep, iter); module_charge::chgmixing_ks_lcao(iter, this->p_chgmix, this->dftu, - this->dmat.dm->get_DMR_pointer(1)->get_nnr(), PARAM.inp); + this->dmat.dm->get_DMR_pointer(1)->get_nnr(), *this->inp_); if (iter == 1) { - this->gint_precision_controller_.set_mode(PARAM.inp.gint_precision); + this->gint_precision_controller_.set_mode(this->inp_->gint_precision); this->gint_precision_controller_.reset_for_new_scf(); this->gint_info_->set_exec_precision(this->gint_precision_controller_.current_precision()); - if (PARAM.inp.gint_precision == "mix") + if (this->inp_->gint_precision == "mix") { GlobalV::ofs_running << "\n >> Gint mixed-precision mode: starting SCF with fp32" << " (will switch to fp64 when drho is small enough)" << std::endl; std::cout << " >> NOTICE: Gint grid-integration starts with fp32 (mixed-precision mode)" << std::endl; } - else if (PARAM.inp.gint_precision == "single") + else if (this->inp_->gint_precision == "single") { GlobalV::ofs_running << "\n >> Gint single-precision mode: using fp32 throughout SCF" << std::endl; std::cout << " >> NOTICE: Gint grid-integration uses fp32 throughout SCF (single-precision mode)" << std::endl; @@ -354,15 +357,15 @@ void ESolver_KS_LCAO::iter_init(UnitCell& ucell, const int istep, const // mohan update 2012-06-05 this->pelec->f_en.deband_harris = this->pelec->cal_delta_eband(ucell); - if (istep == 0 && PARAM.inp.init_wfc == "file") + if (istep == 0 && this->inp_->init_wfc == "file") { int exx_two_level_step = 0; #ifdef __EXX - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info_.info_global.cal_exx) { // the following steps are only needed in the first outer exx loop exx_two_level_step - = GlobalC::exx_info.info_ri.real_number ? + = exx_info_.info_ri.real_number ? this->exx_nao.exd->two_level_step : this->exx_nao.exc->two_level_step; } #endif @@ -371,9 +374,9 @@ void ESolver_KS_LCAO::iter_init(UnitCell& ucell, const int istep, const #ifdef __EXX // calculate exact-exchange - if (PARAM.inp.calculation != "nscf") + if (this->inp_->calculation != "nscf") { - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_.info_ri.real_number) { this->exx_nao.exd->exx_eachiterinit(istep, ucell, *this->dmat.dm, this->kv, iter); } @@ -384,27 +387,27 @@ void ESolver_KS_LCAO::iter_init(UnitCell& ucell, const int istep, const } #endif - init_dftu_lcao(istep, iter, PARAM.inp.dft_plus_u, &(this->dftu), this->dmat.dm, ucell, this->chr.rho, this->pw_rho->nrxx); + init_dftu_lcao(istep, iter, this->inp_->dft_plus_u, &(this->dftu), this->dmat.dm, ucell, this->chr.rho, this->pw_rho->nrxx); #ifdef __MLALGO // the density matrixes of DeePKS have been updated in each iter this->deepks.ld.set_hr_cal(true); // HR in HamiltLCAO should be recalculate - if (PARAM.inp.deepks_scf) + if (this->inp_->deepks_scf) { this->p_hamilt->refresh(); } #endif - if (PARAM.inp.vl_in_h) + if (this->inp_->vl_in_h) { // update real space Hamiltonian this->p_hamilt->refresh(); } // save density matrix DMR for mixing - if (PARAM.inp.mixing_restart > 0 && PARAM.inp.mixing_dmr && this->p_chgmix->mixing_restart_count > 0) + if (this->inp_->mixing_restart > 0 && this->inp_->mixing_dmr && this->p_chgmix->mixing_restart_count > 0) { this->dmat.dm->save_DMR(); } @@ -418,19 +421,19 @@ void ESolver_KS_LCAO::hamilt2rho_single(UnitCell& ucell, int istep, int // 1) reset energy this->pelec->f_en.eband = 0.0; this->pelec->f_en.demet = 0.0; - bool skip_charge = PARAM.inp.calculation == "nscf" ? true : false; + bool skip_charge = this->inp_->calculation == "nscf" ? true : false; // 2) run the inner lambda loop to contrain atomic moments with the DeltaSpin method bool skip_solve = false; - if (PARAM.inp.sc_mag_switch) + if (this->inp_->sc_mag_switch) { spinconstrain::SpinConstrain& sc = spinconstrain::SpinConstrain::getScInstance(); - if (PARAM.inp.sc_lambda_strategy == "linear_scan") + if (this->inp_->sc_lambda_strategy == "linear_scan") { sc.run_lambda_linear_scan(iter - 1); skip_solve = true; } - else if (!sc.mag_converged() && this->drho > 0 && this->drho < PARAM.inp.sc_scf_thr) + else if (!sc.mag_converged() && this->drho > 0 && this->drho < this->inp_->sc_scf_thr) { sc.run_lambda_loop(iter - 1); sc.set_mag_converged(true); @@ -447,27 +450,27 @@ void ESolver_KS_LCAO::hamilt2rho_single(UnitCell& ucell, int istep, int if (!skip_solve) { hsolver::HSolverLCAO hsolver_lcao_obj(&(this->pv), - PARAM.inp.ks_solver, + this->inp_->ks_solver, PARAM.globalv.kpar_lcao, PARAM.globalv.nlocal, - PARAM.inp.nbands, - PARAM.inp.nelec, - PARAM.inp.device == "gpu"); + this->inp_->nbands, + this->inp_->nelec, + this->inp_->device == "gpu"); hsolver_lcao_obj.solve(static_cast*>(this->p_hamilt), this->psi[0], this->pelec, *this->dmat.dm, - this->chr, PARAM.inp.nspin, skip_charge); + this->chr, this->inp_->nspin, skip_charge); } else { // Lambda loop updated the density matrix (DM) but not the real-space charge density. // HSolver was skipped, so we need to sync rho from DM manually. - LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), PARAM.inp.nspin, &this->chr); + LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), this->inp_->nspin, &this->chr); } // 4) EXX #ifdef __EXX - if (PARAM.inp.calculation != "nscf") + if (this->inp_->calculation != "nscf") { - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_.info_ri.real_number) { this->exx_nao.exd->exx_hamilt2rho(*this->pelec, this->pv, iter); } @@ -479,7 +482,7 @@ void ESolver_KS_LCAO::hamilt2rho_single(UnitCell& ucell, int istep, int #endif // 5) symmetrize the charge density - Symmetry_rho::symmetrize_rho(PARAM.inp.nspin, this->chr, this->pw_rho, ucell.symm); + Symmetry_rho::symmetrize_rho(this->inp_->nspin, this->chr, this->pw_rho, ucell.symm); // 6) calculate delta energy this->pelec->f_en.deband = this->pelec->cal_delta_eband(ucell); @@ -501,13 +504,13 @@ void ESolver_KS_LCAO::iter_finish(UnitCell& ucell, const int istep, int& const std::vector>& dm_vec = this->dmat.dm->get_DMK_vector(); // 1) calculate the local occupation number matrix and energy correction in DFT+U - finish_dftu_lcao(iter, conv_esolver, PARAM.inp.dft_plus_u, PARAM.inp.out_chg[0], &(this->dftu), ucell, dm_vec, this->kv, this->p_chgmix->get_mixing_beta(), hamilt_lcao, PARAM.globalv.global_out_dir, PARAM.inp.nspin, PARAM.globalv.npol); + finish_dftu_lcao(iter, conv_esolver, this->inp_->dft_plus_u, this->inp_->out_chg[0], &(this->dftu), ucell, dm_vec, this->kv, this->p_chgmix->get_mixing_beta(), hamilt_lcao, PARAM.globalv.global_out_dir, this->inp_->nspin, PARAM.globalv.npol); // 2) for deepks, calculate delta_e, output labels during electronic steps - this->deepks.delta_e(ucell, this->kv, this->orb_, this->pv, this->gd, dm_vec, this->pelec->f_en, PARAM.inp); + this->deepks.delta_e(ucell, this->kv, this->orb_, this->pv, this->gd, dm_vec, this->pelec->f_en, *this->inp_); // 3) for delta spin - cal_mi_lcao_wrapper(iter, PARAM.inp); + cal_mi_lcao_wrapper(iter, *this->inp_); // call iter_finish() of ESolver_KS, where band gap is printed, // eig and occ are printed, magnetization is calculated, @@ -525,19 +528,19 @@ void ESolver_KS_LCAO::iter_finish(UnitCell& ucell, const int istep, int& // mix density matrix if mixing_restart + mixing_dmr + not first // mixing_restart at every iter except the last iter - if(iter != PARAM.inp.scf_nmax && !conv_esolver) + if(iter != this->inp_->scf_nmax && !conv_esolver) { - if (PARAM.inp.mixing_restart > 0 && this->p_chgmix->mixing_restart_count > 0 && PARAM.inp.mixing_dmr) + if (this->inp_->mixing_restart > 0 && this->p_chgmix->mixing_restart_count > 0 && this->inp_->mixing_dmr) { this->p_chgmix->mix_dmr(this->dmat.dm); } } // control the output related to the finished iteration - ModuleIO::ctrl_iter_lcao(ucell, PARAM.inp, this->kv, this->pelec, *this->dmat.dm, + ModuleIO::ctrl_iter_lcao(ucell, *this->inp_, this->kv, this->pelec, *this->dmat.dm, this->pv, this->gd, this->psi, this->chr, this->p_chgmix, hamilt_lcao, this->orb_, this->deepks, - this->exx_nao, iter, istep, conv_esolver, this->scf_ene_thr); + this->exx_nao, this->exx_info_, iter, istep, conv_esolver, this->scf_ene_thr); } template @@ -553,9 +556,9 @@ void ESolver_KS_LCAO::after_scf(UnitCell& ucell, const int istep, const ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::after_scf","p_hamilt does not exist"); } - if (PARAM.inp.out_elf[0] > 0) + if (this->inp_->out_elf[0] > 0) { - LCAO_domain::dm2tau(this->dmat.dm->get_DMR_vector(), PARAM.inp.nspin, this->pelec->charge); + LCAO_domain::dm2tau(this->dmat.dm->get_DMR_vector(), this->inp_->nspin, this->pelec->charge); } //! 1) call after_scf() of ESolver_KS @@ -563,15 +566,15 @@ void ESolver_KS_LCAO::after_scf(UnitCell& ucell, const int istep, const //! 2) output of lcao every few ionic steps ModuleIO::ctrl_scf_lcao(ucell, - PARAM.inp, this->kv, this->pelec, this->dmat.dm, this->pv, + *this->inp_, this->kv, this->pelec, this->dmat.dm, this->pv, this->gd, this->psi, hamilt_lcao, this->dftu, this->two_center_bundle_, this->orb_, this->pw_wfc, this->pw_rho, this->pw_big, this->sf, this->pw_rhod, this->locpp.vloc, this->solvent, - this->rdmft_solver, this->deepks, this->exx_nao, + this->rdmft_solver, this->deepks, this->exx_nao, this->exx_info_, this->conv_esolver, this->scf_nmax_flag, istep); //! 3) Clean up RA, which is used to serach for adjacent atoms - if (!PARAM.inp.cal_force && !PARAM.inp.cal_stress) + if (!this->inp_->cal_force && !this->inp_->cal_stress) { this->RA.delete_grid(); } diff --git a/source/source_esolver/esolver_ks_lcao.h b/source/source_esolver/esolver_ks_lcao.h index 8d371040efc..50ee0e6da7a 100644 --- a/source/source_esolver/esolver_ks_lcao.h +++ b/source/source_esolver/esolver_ks_lcao.h @@ -2,6 +2,7 @@ #define ESOLVER_KS_LCAO_H #include "esolver_ks.h" +#include "source_hamilt/module_xc/exx_info.h" // LCAO owns full Exx_Info #include "source_lcao/record_adj.h" // adjacent atoms #include "source_basis/module_nao/two_center_bundle.h" // nao basis #include "source_hamilt/module_gint/gint_info.h" @@ -81,6 +82,9 @@ class ESolver_KS_LCAO : public ESolver_KS // For deepks method, mohan add 2025-10-08 Setup_DeePKS deepks; + /// Full EXX info for LCAO (includes info_ri, info_opt_abfs, info_lip) + Exx_Info exx_info_; + // For exact-exchange energy, mohan add 2025-10-08 Exx_NAO exx_nao; @@ -97,19 +101,6 @@ class ESolver_KS_LCAO : public ESolver_KS bool have_force = false; GintPrecisionController gint_precision_controller_; - - - public: - const Record_adj & get_RA() const { return RA; } - const Grid_Driver & get_gd() const { return gd; } - const Parallel_Orbitals & get_pv() const { return pv; } - const std::unique_ptr & get_gint_info() const { return gint_info_; } - const TwoCenterBundle & get_two_center_bundle() const { return two_center_bundle_; } - const rdmft::RDMFT & get_rdmft_solver() const { return rdmft_solver; } - const LCAO_Orbitals & get_orb() const { return orb_; } - const ModuleBase::matrix & get_scs() const { return scs; } - const Setup_DeePKS & get_deepks() const { return deepks; } - const Exx_NAO & get_exx_nao() const { return exx_nao; } }; } // namespace ModuleESolver #endif diff --git a/source/source_esolver/esolver_ks_lcao_tddft.cpp b/source/source_esolver/esolver_ks_lcao_tddft.cpp index 415cb7c59e5..f767c4b2107 100644 --- a/source/source_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/source_esolver/esolver_ks_lcao_tddft.cpp @@ -34,17 +34,6 @@ ESolver_KS_LCAO_TDDFT::ESolver_KS_LCAO_TDDFT() { this->classname = "ESolver_rtTDDFT"; this->basisname = "LCAO"; - - // If the device is GPU, we must open use_tensor and use_lapack - ct::DeviceType ct_device_type = ct::DeviceTypeToEnum::value; - if (ct_device_type == ct::DeviceType::GpuDevice) - { - use_tensor = true; - if (PARAM.inp.ks_solver != "cusolvermp") - { - use_lapack = true; - } - } } template @@ -78,6 +67,17 @@ void ESolver_KS_LCAO_TDDFT::before_all_runners(BaseCell& basecell, c basecell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(basecell); + // If the device is GPU, we must open use_tensor and use_lapack + ct::DeviceType ct_device_type = ct::DeviceTypeToEnum::value; + if (ct_device_type == ct::DeviceType::GpuDevice) + { + use_tensor = true; + if (inp.ks_solver != "cusolvermp") + { + use_lapack = true; + } + } + // Build the shared field state before the base ESolver registers potential // components. Both propagation gauges and the length-gauge potential must // observe the same electronic-step counter. @@ -104,7 +104,7 @@ void ESolver_KS_LCAO_TDDFT::before_all_runners(BaseCell& basecell, c TD_info::td_vel_op = td_p; totstep += TD_info::estep_shift; - if (PARAM.inp.init_wfc == "file") + if (this->inp_->init_wfc == "file") { if (!ModuleIO::read_wfc_nao(PARAM.globalv.global_readin_dir, this->pv, @@ -113,7 +113,7 @@ void ESolver_KS_LCAO_TDDFT::before_all_runners(BaseCell& basecell, c this->pelec->wg, this->kv.ik2iktot, this->kv.get_nkstot(), - PARAM.inp.nspin, + this->inp_->nspin, 0, TD_info::estep_shift)) { @@ -146,7 +146,7 @@ void ESolver_KS_LCAO_TDDFT::runner(BaseCell& basecell, const int ist this->td_mg_->init_DR(sR_template, &ucell, &this->pv, this->two_center_bundle_.overlap_orb.get()); } - if (PARAM.inp.td_stype == 2) + if (this->inp_->td_stype == 2) { this->dmat.dm->cal_DMR_td(td_p->get_phase_hybrid(), TD_info::cart_At); } @@ -157,7 +157,7 @@ void ESolver_KS_LCAO_TDDFT::runner(BaseCell& basecell, const int ist ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT SCF"); // Initialize velocity operator for current calculation - if (PARAM.inp.td_stype != 1 && TD_info::out_current == 1) + if (this->inp_->td_stype != 1 && TD_info::out_current == 1) { // initialize the velocity operator velocity_mat = new Velocity_op(&ucell, &(this->gd), &this->pv, this->orb_, this->two_center_bundle_.overlap_orb.get()); @@ -165,11 +165,11 @@ void ESolver_KS_LCAO_TDDFT::runner(BaseCell& basecell, const int ist velocity_mat->calculate_grad_term(); velocity_mat->calculate_vcomm_r(); } - int estep_max = (istep == 0 && !PARAM.inp.mdp.md_restart) ? 1 : PARAM.inp.estep_per_md; + int estep_max = (istep == 0 && !this->inp_->mdp.md_restart) ? 1 : this->inp_->estep_per_md; // mohan change md_nstep from 0 to 1, 2026-01-04 - if (PARAM.inp.mdp.md_nstep == 1) + if (this->inp_->mdp.md_nstep == 1) { - estep_max = PARAM.inp.estep_per_md + 1; + estep_max = this->inp_->estep_per_md + 1; } // Reset laststep matrix and wfc, if any atom cross the boundary @@ -183,13 +183,13 @@ void ESolver_KS_LCAO_TDDFT::runner(BaseCell& basecell, const int ist this->totstep++; this->print_step(); // update At - if (PARAM.inp.td_stype > 0) + if (this->inp_->td_stype > 0) { // TDFieldManager owns the midpoint-vector-potential update. Static // mirrors are synchronized afterward for legacy RT-TDDFT clients. td_field_manager_->advance_vector_gauge(); elecstate::H_TDDFT_pw::sync_compatibility_state(*td_field_manager_); - if (PARAM.inp.out_efield && GlobalV::MY_RANK == 0) + if (this->inp_->out_efield && GlobalV::MY_RANK == 0) { ModuleIO::write_td_field_values(*td_field_manager_, PARAM.globalv.global_out_dir); } @@ -203,17 +203,17 @@ void ESolver_KS_LCAO_TDDFT::runner(BaseCell& basecell, const int ist { this->CE.update_all_dis(ucell); this->CE.extrapolate_charge(&this->Pgrid, ucell, &this->chr, &this->sf, GlobalV::ofs_running, GlobalV::ofs_warning); - this->exx_nao.before_scf(ucell, this->kv, this->orb_, this->p_chgmix, totstep, PARAM.inp); + this->exx_nao.before_scf(ucell, this->kv, this->orb_, this->p_chgmix, totstep, *this->inp_, this->exx_info_); elecstate::init_scf(ucell, this->Pgrid, this->sf.strucFac, this->locpp.numeric, istep, PARAM.globalv.global_out_dir, - PARAM.inp, + *this->inp_, this->pelec); - if (totstep <= PARAM.inp.td_tend + 1) + if (totstep <= this->inp_->td_tend + 1) { TD_info::evolve_once = true; } @@ -223,7 +223,7 @@ void ESolver_KS_LCAO_TDDFT::runner(BaseCell& basecell, const int ist //---------------------------------------------------------------- bool conv_esolver = false; this->niter = this->maxniter; - this->diag_ethr = PARAM.inp.pw_diag_thr; + this->diag_ethr = this->inp_->pw_diag_thr; for (int iter = 1; iter <= this->maxniter; ++iter) { ModuleIO::write_head_td(GlobalV::ofs_running, istep, totstep, iter, this->basisname); @@ -253,23 +253,23 @@ void ESolver_KS_LCAO_TDDFT::runner(BaseCell& basecell, const int ist // 7) after_scf //---------------------------------------------------------------- this->after_scf(ucell, totstep, conv_esolver); - if (!restart_done && PARAM.inp.mdp.md_restart) + if (!restart_done && this->inp_->mdp.md_restart) { restart_done = true; - estep += TD_info::estep_shift % PARAM.inp.estep_per_md; + estep += TD_info::estep_shift % this->inp_->estep_per_md; if (estep == 0) { break; } // mohan add 2026-01-04, change md_nstep!=0 to md_nstep!=1 - if (PARAM.inp.mdp.md_nstep != 1) + if (this->inp_->mdp.md_nstep != 1) { estep -= 1; } } } - if (PARAM.inp.td_stype != 1 && TD_info::out_current == 1) + if (this->inp_->td_stype != 1 && TD_info::out_current == 1) { delete velocity_mat; } @@ -298,12 +298,12 @@ void ESolver_KS_LCAO_TDDFT::hamilt2rho_single(UnitCell& ucell, const this->td_mg_->update_DR(sR_template, &ucell, &this->pv, this->two_center_bundle_.overlap_orb.get()); } - if (PARAM.inp.init_wfc == "file") + if (this->inp_->init_wfc == "file") { if (istep >= TD_info::estep_shift + 1) { module_rt::Evolve_elec::solve_psi(istep, - PARAM.inp.nbands, + this->inp_->nbands, PARAM.globalv.nlocal, this->kv.get_nks(), static_cast>*>(this->p_hamilt), @@ -314,7 +314,7 @@ void ESolver_KS_LCAO_TDDFT::hamilt2rho_single(UnitCell& ucell, const this->Sk_laststep, this->pelec->ekb, GlobalV::ofs_running, - PARAM.inp.propagator, + this->inp_->propagator, use_tensor, use_lapack, this->td_mg_, @@ -327,7 +327,7 @@ void ESolver_KS_LCAO_TDDFT::hamilt2rho_single(UnitCell& ucell, const else if (istep >= 1) { module_rt::Evolve_elec::solve_psi(istep, - PARAM.inp.nbands, + this->inp_->nbands, PARAM.globalv.nlocal, this->kv.get_nks(), static_cast>*>(this->p_hamilt), @@ -338,7 +338,7 @@ void ESolver_KS_LCAO_TDDFT::hamilt2rho_single(UnitCell& ucell, const this->Sk_laststep, this->pelec->ekb, GlobalV::ofs_running, - PARAM.inp.propagator, + this->inp_->propagator, use_tensor, use_lapack, this->td_mg_, @@ -354,20 +354,20 @@ void ESolver_KS_LCAO_TDDFT::hamilt2rho_single(UnitCell& ucell, const this->pelec->f_en.demet = 0.0; if (this->psi != nullptr) { - bool skip_charge = PARAM.inp.calculation == "nscf" ? true : false; + bool skip_charge = this->inp_->calculation == "nscf" ? true : false; hsolver::HSolverLCAO> hsolver_lcao_obj(&this->pv, - PARAM.inp.ks_solver, + this->inp_->ks_solver, PARAM.globalv.kpar_lcao, PARAM.globalv.nlocal, - PARAM.inp.nbands, - PARAM.inp.nelec, - PARAM.inp.device == "gpu"); + this->inp_->nbands, + this->inp_->nelec, + this->inp_->device == "gpu"); hsolver_lcao_obj.solve(static_cast>*>(this->p_hamilt), this->psi[0], this->pelec, *this->dmat.dm, this->chr, - PARAM.inp.nspin, + this->inp_->nspin, skip_charge); } } @@ -375,10 +375,10 @@ void ESolver_KS_LCAO_TDDFT::hamilt2rho_single(UnitCell& ucell, const // Symmetrize the charge density only for ground state if (istep <= 1) { - Symmetry_rho::symmetrize_rho(PARAM.inp.nspin, this->chr, this->pw_rho, ucell.symm); + Symmetry_rho::symmetrize_rho(this->inp_->nspin, this->chr, this->pw_rho, ucell.symm); } #ifdef __EXX - if (GlobalC::exx_info.info_ri.real_number) + if (this->exx_info_.info_ri.real_number) this->exx_nao.exd->exx_hamilt2rho(*this->pelec, this->pv, iter); else this->exx_nao.exc->exx_hamilt2rho(*this->pelec, this->pv, iter); @@ -405,7 +405,7 @@ void ESolver_KS_LCAO_TDDFT::iter_finish(UnitCell& ucell, std::setprecision(6); for (int ik = 0; ik < this->kv.get_nks(); ik++) { - for (int ib = 0; ib < PARAM.inp.nbands; ib++) + for (int ib = 0; ib < this->inp_->nbands; ib++) { GlobalV::ofs_running << " " << std::setw(9) << ik + 1 << std::setw(8) << ib + 1 << std::setw(12) << this->pelec->wg(ik, ib) << std::endl; @@ -422,8 +422,8 @@ void ESolver_KS_LCAO_TDDFT::iter_finish(UnitCell& ucell, this->store_h_s_psi(ucell, istep, iter, force_save); // Calculate energy-density matrix for RT-TDDFT - if (conv_esolver && estep == estep_max - 1 && istep >= (PARAM.inp.init_wfc == "file" ? 0 : 1) && PARAM.inp.td_edm == 0 - && PARAM.inp.td_stype != 2) + if (conv_esolver && estep == estep_max - 1 && istep >= (this->inp_->init_wfc == "file" ? 0 : 1) && this->inp_->td_edm == 0 + && this->inp_->td_stype != 2) { if (use_tensor && use_lapack) { @@ -442,7 +442,7 @@ void ESolver_KS_LCAO_TDDFT::iter_finish(UnitCell& ucell, template void ESolver_KS_LCAO_TDDFT::store_h_s_psi(UnitCell& ucell, const int istep, const int iter, const bool conv_esolver) { - const int nbands = PARAM.inp.nbands; + const int nbands = this->inp_->nbands; const int nlocal = PARAM.globalv.nlocal; // Store wave function, Hamiltonian and Overlap matrix @@ -580,7 +580,8 @@ void ESolver_KS_LCAO_TDDFT::after_scf(UnitCell& ucell, const int ist hamilt_lcao, this->RA, this->td_p, - this->exx_nao); + this->exx_nao, + this->exx_info_); ModuleBase::timer::end(this->classname, "after_scf"); } @@ -588,11 +589,11 @@ void ESolver_KS_LCAO_TDDFT::after_scf(UnitCell& ucell, const int ist template void ESolver_KS_LCAO_TDDFT::weight_dm_rho(const UnitCell& ucell) { - if (PARAM.inp.ocp == 1) + if (this->inp_->ocp == 1) { - elecstate::fixed_weights(PARAM.inp.ocp_kb, - PARAM.inp.nbands, - PARAM.inp.nelec, + elecstate::fixed_weights(this->inp_->ocp_kb, + this->inp_->nbands, + this->inp_->nelec, this->pelec->klist, this->pelec->wg, this->pelec->skip_weights); @@ -602,7 +603,7 @@ void ESolver_KS_LCAO_TDDFT::weight_dm_rho(const UnitCell& ucell) elecstate::calEBand(this->pelec->ekb, this->pelec->wg, this->pelec->f_en); elecstate::cal_dm_psi(this->dmat.dm->get_paraV_pointer(), this->pelec->wg, this->psi[0], *this->dmat.dm); - if (PARAM.inp.td_stype == 2) + if (this->inp_->td_stype == 2) { this->dmat.dm->cal_DMR_td(td_p->get_phase_hybrid(), TD_info::cart_At); } @@ -612,7 +613,7 @@ void ESolver_KS_LCAO_TDDFT::weight_dm_rho(const UnitCell& ucell) } // get the real-space charge density, mohan add 2025-10-24 - LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), PARAM.inp.nspin, &this->chr); + LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), this->inp_->nspin, &this->chr); } template class ESolver_KS_LCAO_TDDFT; diff --git a/source/source_esolver/esolver_ks_lcaopw.cpp b/source/source_esolver/esolver_ks_lcaopw.cpp index eec914f5bce..1d61cee3a04 100644 --- a/source/source_esolver/esolver_ks_lcaopw.cpp +++ b/source/source_esolver/esolver_ks_lcaopw.cpp @@ -77,6 +77,15 @@ namespace ModuleESolver basecell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(basecell); ESolver_KS_PW::before_all_runners(basecell, inp); + + // Initialize LIP-specific info_lip_ from general_exx_info_ and input + this->info_lip_.ccp_type = this->general_exx_info_.ccp_type; + this->info_lip_.hse_omega = this->general_exx_info_.hse_omega; + if (!inp.exx_fock_lambda.empty()) + { + this->info_lip_.lambda = std::stod(inp.exx_fock_lambda[0]); + } + auto* p_psi_init = static_cast*>(this->stp.p_psi_init); delete this->psi_local; this->psi_local = new psi::Psi(this->stp.psi_cpu->get_nk(), @@ -88,10 +97,10 @@ namespace ModuleESolver if (inp.calculation == "scf" || inp.calculation == "relax" || inp.calculation == "cell-relax" || inp.calculation == "md") { - if (GlobalC::exx_info.info_global.cal_exx) + if (this->general_exx_info_.cal_exx) { XC_Functional::set_xc_first_loop(ucell); - this->exx_lip = std::unique_ptr>(new Exx_Lip(GlobalC::exx_info.info_lip, + this->exx_lip = std::unique_ptr>(new Exx_Lip(this->info_lip_, &this->kv, this->psi_local, this->stp.template get_psi_t(), @@ -109,7 +118,7 @@ namespace ModuleESolver { ESolver_KS_PW::iter_init(ucell, istep, iter); #ifdef __EXX - if (GlobalC::exx_info.info_global.cal_exx && !GlobalC::exx_info.info_global.separate_loop && this->two_level_step) { + if (this->general_exx_info_.cal_exx && !this->general_exx_info_.separate_loop && this->two_level_step) { this->exx_lip->cal_exx(); } #endif @@ -130,27 +139,27 @@ namespace ModuleESolver hsolver::DiagoIterAssist::need_subspace = ((istep == 0 || istep == 1) && iter == 1) ? false : true; hsolver::DiagoIterAssist::SCF_ITER = iter; hsolver::DiagoIterAssist::PW_DIAG_THR = ethr; - hsolver::DiagoIterAssist::PW_DIAG_NMAX = PARAM.inp.pw_diag_nmax; - bool skip_charge = PARAM.inp.calculation == "nscf" ? true : false; + hsolver::DiagoIterAssist::PW_DIAG_NMAX = this->inp_->pw_diag_nmax; + bool skip_charge = this->inp_->calculation == "nscf" ? true : false; hsolver::HSolverLIP hsolver_lip_obj(this->pw_wfc, PARAM.globalv.use_uspp, - PARAM.inp.basis_type, - PARAM.inp.calculation); - hsolver_lip_obj.solve(static_cast*>(this->p_hamilt), *this->stp.template get_psi_t(), this->pelec, - *this->psi_local, skip_charge,ucell.tpiba,ucell.nat); + this->inp_->basis_type, + this->inp_->calculation); + hsolver_lip_obj.solve(static_cast*>(this->p_hamilt), *this->stp.template get_psi_t(), this->pelec, + *this->psi_local, skip_charge,ucell.tpiba,ucell.nat, this->general_exx_info_); // add exx #ifdef __EXX - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; + bool cal_exx = this->general_exx_info_.cal_exx; + double hybrid_alpha = this->general_exx_info_.hybrid_alpha; if (cal_exx) { this->pelec->set_exx(this->exx_lip->get_exx_energy(), cal_exx, hybrid_alpha); // Peize Lin add 2019-03-09 } #endif - Symmetry_rho::symmetrize_rho(PARAM.inp.nspin, this->chr, this->pw_rhod, ucell.symm); + Symmetry_rho::symmetrize_rho(this->inp_->nspin, this->chr, this->pw_rhod, ucell.symm); // deband is calculated from "output" charge density calculated // in sum_band @@ -166,12 +175,12 @@ namespace ModuleESolver ESolver_KS_PW::iter_finish(ucell, istep, iter, conv_esolver); #ifdef __EXX - if (GlobalC::exx_info.info_global.cal_exx && conv_esolver) + if (this->general_exx_info_.cal_exx && conv_esolver) { // no separate_loop case - if (!GlobalC::exx_info.info_global.separate_loop) + if (!this->general_exx_info_.separate_loop) { - GlobalC::exx_info.info_global.hybrid_step = 1; + this->general_exx_info_.hybrid_step = 1; // in no_separate_loop case, scf loop only did twice // in first scf loop, exx updated once in beginning, @@ -189,7 +198,7 @@ namespace ModuleESolver } // has separate_loop case // exx converged or get max exx steps - else if (this->two_level_step == GlobalC::exx_info.info_global.hybrid_step + else if (this->two_level_step == this->general_exx_info_.hybrid_step || (iter == 1 && this->two_level_step != 0)) { conv_esolver = true; @@ -230,16 +239,16 @@ namespace ModuleESolver ESolver_KS_PW::after_all_runners(basecell); #ifdef __LCAO - if (PARAM.inp.out_mat_xc) + if (this->inp_->out_mat_xc) { #ifdef __EXX - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; + bool cal_exx = this->general_exx_info_.cal_exx; + double hybrid_alpha = this->general_exx_info_.hybrid_alpha; #else bool cal_exx = false; double hybrid_alpha = 0.0; #endif - ModuleIO::write_Vxc(PARAM.inp.nspin, + ModuleIO::write_Vxc(this->inp_->nspin, PARAM.globalv.nlocal, GlobalV::DRANK, *this->stp.template get_psi_t(), diff --git a/source/source_esolver/esolver_ks_lcaopw.h b/source/source_esolver/esolver_ks_lcaopw.h index caf801e4962..63dc3ed13c0 100644 --- a/source/source_esolver/esolver_ks_lcaopw.h +++ b/source/source_esolver/esolver_ks_lcaopw.h @@ -2,6 +2,7 @@ #define ESOLVER_KS_LIP_H #include "source_esolver/esolver_ks_pw.h" #include "source_hsolver/hsolver_lcaopw.h" +#include "source_hamilt/module_xc/exx_info_lip.h" #ifdef __EXX #include "source_lcao/module_ri/exx_lip.h" @@ -36,6 +37,9 @@ class ESolver_KS_LIP : public ESolver_KS_PW psi::Psi* psi_local = nullptr; ///< psi for all local NAOs + /// LIP-specific EXX info (lambda, ccp_type, hse_omega) + Exx_Info_Lip info_lip_; + #ifdef __EXX std::unique_ptr> exx_lip; int two_level_step = 0; diff --git a/source/source_esolver/esolver_ks_pw.cpp b/source/source_esolver/esolver_ks_pw.cpp index ab9c0cbfadb..f2fccf7e3c3 100644 --- a/source/source_esolver/esolver_ks_pw.cpp +++ b/source/source_esolver/esolver_ks_pw.cpp @@ -16,7 +16,7 @@ #include "source_estate/module_charge/chgmixing.h" // use charge mixing, mohan add 20251006 #include "source_estate/setup_estate_pw.h" // mohan add 20251005 -#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info +#include "source_hamilt/module_xc/general_exx_info.h" // for General_Exx_Info type used via general_exx_info_ #include "source_io/module_ctrl/ctrl_output_pw.h" // mohan add 20250927 #include "source_pw/module_pwdft/deltaspin_pw.h" // mohan add 20250309 #include "source_pw/module_pwdft/setup_pot.h" // mohan add 20250929 @@ -65,7 +65,8 @@ void ESolver_KS_PW::allocate_hamilt(const UnitCell& ucell) &this->kv, &this->ppcell, &this->dftu, - &ucell); + &ucell, + &this->general_exx_info_); } template @@ -92,7 +93,7 @@ void ESolver_KS_PW::before_all_runners(BaseCell& basecell, const Inpu this->solvent, inp); - this->stp.before_runner(ucell, this->kv, this->sf, *this->pw_wfc, this->ppcell.lmaxkb, PARAM.inp); + this->stp.before_runner(ucell, this->kv, this->sf, *this->pw_wfc, this->ppcell.lmaxkb, *this->inp_); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT BASIS"); @@ -126,7 +127,7 @@ void ESolver_KS_PW::before_all_runners(BaseCell& basecell, const Inpu } //! Initialize exx pw - this->exx_helper->init(ucell, inp, this->pelec->wg); + this->exx_helper->init(ucell, inp, this->pelec->wg, this->general_exx_info_); } template @@ -138,11 +139,11 @@ void ESolver_KS_PW::before_scf(UnitCell& ucell, const int istep) ESolver_KS::before_scf(ucell, istep); //! Init variables (once the cell has changed) - pw::update_cell_pw(ucell, this->ppcell, this->kv, this->pw_wfc, PARAM.inp); + pw::update_cell_pw(ucell, this->ppcell, this->kv, this->pw_wfc, *this->inp_); if (ucell.cell_parameter_updated) { - this->stp.p_psi_init->prepare_init(PARAM.inp.pw_seed, istep); + this->stp.p_psi_init->prepare_init(this->inp_->pw_seed, istep); } //! Init Hamiltonian (cell changed) @@ -176,13 +177,13 @@ void ESolver_KS_PW::before_scf(UnitCell& ucell, const int istep) this->pw_wfc, this->pw_rhod, PARAM.globalv.global_out_dir, - PARAM.inp); + *this->inp_); // setup psi (electronic wave functions) this->stp.init(this->p_hamilt); //! Setup EXX helper for Hamiltonian and psi - exx_helper->before_scf(this->p_hamilt, this->stp.template get_psi_t(), PARAM.inp); + exx_helper->before_scf(this->p_hamilt, this->stp.template get_psi_t(), *this->inp_, this->general_exx_info_); ModuleBase::timer::end("ESolver_KS_PW", "before_scf"); } @@ -192,7 +193,7 @@ void ESolver_KS_PW::iter_init(UnitCell& ucell, const int istep, const { ESolver_KS::iter_init(ucell, istep, iter); - module_charge::chgmixing_ks_pw(iter, this->p_chgmix, this->dftu, PARAM.inp); + module_charge::chgmixing_ks_pw(iter, this->p_chgmix, this->dftu, *this->inp_); // mohan move harris functional here, 2012-06-05 // use 'rho(in)' and 'v_h and v_xc'(in) @@ -221,31 +222,31 @@ void ESolver_KS_PW::hamilt2rho_single(UnitCell& ucell, const int iste this->pelec->f_en.demet = 0.0; // setup diagonalization parameters - hsolver::setup_diago_params_pw(istep, iter, ethr, PARAM.inp); + hsolver::setup_diago_params_pw(istep, iter, ethr, *this->inp_); - bool skip_charge = PARAM.inp.calculation == "nscf" ? true : false; + bool skip_charge = this->inp_->calculation == "nscf" ? true : false; // run the inner lambda loop to contrain atomic moments with the DeltaSpin method - bool skip_solve = pw::run_deltaspin_lambda_loop(iter - 1, this->drho, PARAM.inp); + bool skip_solve = pw::run_deltaspin_lambda_loop(iter - 1, this->drho, *this->inp_); if (!skip_solve) { hsolver::HSolverPW hsolver_pw_obj(this->pw_wfc, - PARAM.inp.calculation, - PARAM.inp.basis_type, - PARAM.inp.ks_solver, + this->inp_->calculation, + this->inp_->basis_type, + this->inp_->ks_solver, PARAM.globalv.use_uspp, - PARAM.inp.nspin, + this->inp_->nspin, hsolver::DiagoIterAssist::SCF_ITER, hsolver::DiagoIterAssist::PW_DIAG_NMAX, hsolver::DiagoIterAssist::PW_DIAG_THR, hsolver::DiagoIterAssist::need_subspace, - PARAM.inp.nbands, - PARAM.inp.diago_smooth_ethr, - PARAM.inp.pw_diag_ndim, - PARAM.inp.diag_subspace, - PARAM.inp.nb2d, - PARAM.inp.use_k_continuity); + this->inp_->nbands, + this->inp_->diago_smooth_ethr, + this->inp_->pw_diag_ndim, + this->inp_->diag_subspace, + this->inp_->nb2d, + this->inp_->use_k_continuity); hsolver_pw_obj.solve(static_cast*>(this->p_hamilt), *this->stp.template get_psi_t(), @@ -259,7 +260,7 @@ void ESolver_KS_PW::hamilt2rho_single(UnitCell& ucell, const int iste } // symmetrize the charge density - Symmetry_rho::symmetrize_rho(PARAM.inp.nspin, this->chr, this->pw_rhod, ucell.symm); + Symmetry_rho::symmetrize_rho(this->inp_->nspin, this->chr, this->pw_rhod, ucell.symm); ModuleBase::timer::end("ESolver_KS_PW", "hamilt2rho_single"); } @@ -268,8 +269,8 @@ template void ESolver_KS_PW::iter_finish(UnitCell& ucell, const int istep, int& iter, bool& conv_esolver) { // Related to EXX - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; + bool cal_exx = general_exx_info_.cal_exx; + double hybrid_alpha = general_exx_info_.hybrid_alpha; if (cal_exx && !exx_helper->get_op_first_iter()) { this->pelec->set_exx(exx_helper->cal_exx_energy(this->stp.template get_psi_t()), @@ -297,15 +298,15 @@ void ESolver_KS_PW::iter_finish(UnitCell& ucell, const int istep, int &this->chr, this->stp.template get_psi_t(), ucell, - PARAM.inp, + *this->inp_, conv_esolver, iter); // check if oscillate for delta_spin method - pw::check_deltaspin_oscillation(iter, this->drho, this->p_chgmix, PARAM.inp); + pw::check_deltaspin_oscillation(iter, this->drho, this->p_chgmix, *this->inp_); // the output quantities - ModuleIO::ctrl_iter_pw(istep, iter, conv_esolver, this->stp.psi_cpu, this->kv, this->pw_wfc, PARAM.inp); + ModuleIO::ctrl_iter_pw(istep, iter, conv_esolver, this->stp.psi_cpu, this->kv, this->pw_wfc, *this->inp_); } template @@ -315,7 +316,7 @@ void ESolver_KS_PW::after_scf(UnitCell& ucell, const int istep, const ModuleBase::timer::start("ESolver_KS_PW", "after_scf"); // Calculate kinetic energy density tau for ELF if needed - if (PARAM.inp.out_elf[0] > 0) + if (this->inp_->out_elf[0] > 0) { auto* elec_pw = static_cast*>(this->pelec); auto& psi = *this->stp.template get_psi_t(); @@ -336,7 +337,7 @@ void ESolver_KS_PW::after_scf(UnitCell& ucell, const int istep, const this->pw_big, this->stp, this->Pgrid, - PARAM.inp); + *this->inp_); ModuleBase::timer::end("ESolver_KS_PW", "after_scf"); } @@ -397,12 +398,13 @@ void ESolver_KS_PW::cal_stress(BaseCell& basecell, ModuleBase::matrix &this->sf, &this->kv, this->pw_wfc, + this->general_exx_info_, this->stp.template get_psi_d()); // external stress double unit_transform = 0.0; unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; - double external_stress[3] = {PARAM.inp.press1, PARAM.inp.press2, PARAM.inp.press3}; + double external_stress[3] = {this->inp_->press1, this->inp_->press2, this->inp_->press3}; for (int i = 0; i < 3; i++) { stress(i, i) -= external_stress[i] / unit_transform; @@ -429,7 +431,7 @@ void ESolver_KS_PW::after_all_runners(BaseCell& basecell) this->ppcell, this->solvent, this->Pgrid, - PARAM.inp); + *this->inp_); elecstate::teardown_estate_pw(this->pelec, this->vsep_cell); } diff --git a/source/source_esolver/esolver_lj.cpp b/source/source_esolver/esolver_lj.cpp index 3ddd664e9b2..2e9b23c7b82 100644 --- a/source/source_esolver/esolver_lj.cpp +++ b/source/source_esolver/esolver_lj.cpp @@ -26,6 +26,9 @@ void ESolver_LJ::before_all_runners(BaseCell& cell, const Input_para& inp) { cell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(cell); + + this->inp_ = &inp; + lj_potential = 0; lj_force.create(ucell.nat, 3); lj_virial.create(3, 3); @@ -235,7 +238,7 @@ void ESolver_LJ::runner(BaseCell& cell, const int istep) // external stress double unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; - double external_stress[3] = {PARAM.inp.press1, PARAM.inp.press2, PARAM.inp.press3}; + double external_stress[3] = {this->inp_->press1, this->inp_->press2, this->inp_->press3}; for (int i = 0; i < 3; i++) { stress(i, i) -= external_stress[i] / unit_transform; diff --git a/source/source_esolver/esolver_lr_lcao_bse.cpp b/source/source_esolver/esolver_lr_lcao_bse.cpp index 9f44fcfa0f6..409d9139fe7 100644 --- a/source/source_esolver/esolver_lr_lcao_bse.cpp +++ b/source/source_esolver/esolver_lr_lcao_bse.cpp @@ -44,7 +44,7 @@ void ESolver_BSE::before_all_runners(BaseCell& basecell, const Input_para this->two_center_bundle_.to_LCAO_Orbitals(this->orb_, inp.lcao_ecut, inp.lcao_dk, inp.lcao_dr, inp.lcao_rmax, inp.out_element_info, inp.cal_force); this->orb_cutoff_ = this->orb_.cutoffs(); - if (LR_Util::tolower(this->input.abs_gauge) == "velocity") + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity") { this->setup_2center_table(this->two_center_bundle_, this->orb_, ucell); } @@ -127,7 +127,7 @@ void ESolver_BSE::before_all_runners(BaseCell& basecell, const Input_para ModuleGint::Gint::set_gint_info(this->gint_info_.get()); this->pot.resize(this->nspin, nullptr); - if (this->input.lr_solver != "spectrum" && this->input.lr_solver != "plot") + if (this->inp_->lr_solver != "spectrum" && this->inp_->lr_solver != "plot") { this->mo_lri = LR_Util::make_unique>(*this->ucell_, this->nk, @@ -135,14 +135,14 @@ void ESolver_BSE::before_all_runners(BaseCell& basecell, const Input_para this->nocc[0], this->nvirt[0], *this->psi_ks_global, - this->input.bse_q_approx_mode, - this->input.bse_q_approx_threshold, - this->input.out_ri_cv, + this->inp_->bse_q_approx_mode, + this->inp_->bse_q_approx_threshold, + this->inp_->out_ri_cv, this->out_dir, GlobalV::MY_RANK, GlobalV::NPROC); - if (!this->input.bse_ri_hartree && this->input.ri_hartree_benchmark == "none") + if (!this->inp_->bse_ri_hartree && this->inp_->ri_hartree_benchmark == "none") { Charge chg_gs; this->read_ks_chg(chg_gs); @@ -172,9 +172,9 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) auto vfile_in = [&](const std::string& label)->std::string { return this->in_dir + "Excitation_Amplitude_" + label + "_" + std::to_string(GlobalV::MY_RANK) + ".dat";}; - if (this->input.lr_solver == "elpa") + if (this->inp_->lr_solver == "elpa") { - if (this->input.bse_spin_types == std::vector{"ipa"}) + if (this->inp_->bse_spin_types == std::vector{"ipa"}) { this->ipa_solver(); } @@ -187,17 +187,17 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) this->orb_cutoff_, this->gd, *this->psi_ks, *this->psi_ks_global, this->eig_gw, *this->mo_lri, this->pot[0], this->kv, this->paraX_, this->paraC_, this->paraMat_, - this->input.bse_spin_types, - this->input.bse_tda, - this->input.bse_ri_hartree, - this->input.bse_mem_save, - this->input.bse_continue, - this->input.out_bse_ab, + this->inp_->bse_spin_types, + this->inp_->bse_tda, + this->inp_->bse_ri_hartree, + this->inp_->bse_mem_save, + this->inp_->bse_continue, + this->inp_->out_bse_ab, this->out_dir, this->in_dir, GlobalV::MY_RANK, GlobalV::NPROC, - this->input.ri_hartree_benchmark); + this->inp_->ri_hartree_benchmark); auto write_tda_states = [&](const std::string& label, const Real* e, @@ -228,9 +228,9 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "write full states " + label); }; - if ((this->input.bse_tda == "both" || this->input.bse_tda == "tda")) + if ((this->inp_->bse_tda == "both" || this->inp_->bse_tda == "tda")) { - for (int is = 0; is < this->input.bse_spin_types.size(); ++is) + for (int is = 0; is < this->inp_->bse_spin_types.size(); ++is) { bse_matrix.tda_solver(is, this->nstates, @@ -249,9 +249,9 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) std::cout << "Excition binding energies (eV):" << (direct_gap - tda_ene[is * this->nstates]) * ModuleBase::Ry_to_eV << std::endl; - if (this->input.out_wfc_lr) + if (this->inp_->out_wfc_lr) { - write_tda_states(this->input.bse_spin_types[is], + write_tda_states(this->inp_->bse_spin_types[is], &this->tda_ene[is * this->nstates], this->X[is].template data(), this->nloc_per_state, @@ -260,9 +260,9 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) malloc_trim(0); } } - if ((this->input.bse_tda == "both" || this->input.bse_tda == "full")) + if ((this->inp_->bse_tda == "both" || this->inp_->bse_tda == "full")) { - for (int is = 0; is < this->input.bse_spin_types.size(); ++is) + for (int is = 0; is < this->inp_->bse_spin_types.size(); ++is) { bse_matrix.full_solver(is, this->nstates, @@ -281,9 +281,9 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) std::cout << "Excition binding energies (eV):" << (direct_gap - full_ene[is * this->nstates]) * ModuleBase::Ry_to_eV << std::endl; - if (this->input.out_wfc_lr) + if (this->inp_->out_wfc_lr) { - write_full_states(this->input.bse_spin_types[is], + write_full_states(this->inp_->bse_spin_types[is], &this->full_ene[is * this->nstates], this->full_X[is].template data(), this->full_Y[is].template data(), @@ -295,7 +295,7 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) } } } - else if (this->input.lr_solver == "spectrum" || this->input.lr_solver == "plot") + else if (this->inp_->lr_solver == "spectrum" || this->inp_->lr_solver == "plot") { std::cout << "Reading BSE excitation states from file." << std::endl; auto read_tda_states = [&](const std::string& label, Real* e, T* v, const int& dim, const int& nst)->void @@ -325,22 +325,22 @@ void ESolver_BSE::runner(BaseCell& basecell, const int istep) ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "finish reading " + vfile_in("full_Y_"+label)); }; - if (this->input.bse_tda == "both" || this->input.bse_tda == "tda") + if (this->inp_->bse_tda == "both" || this->inp_->bse_tda == "tda") { - for (int is = 0; is < this->input.bse_spin_types.size(); ++is) + for (int is = 0; is < this->inp_->bse_spin_types.size(); ++is) { - read_tda_states(this->input.bse_spin_types[is], + read_tda_states(this->inp_->bse_spin_types[is], &this->tda_ene[is * this->nstates], this->X[is].template data(), this->nloc_per_state, this->nstates); } } - if (this->input.bse_tda == "both" || this->input.bse_tda == "full") + if (this->inp_->bse_tda == "both" || this->inp_->bse_tda == "full") { - for (int is = 0; is < this->input.bse_spin_types.size(); ++is) + for (int is = 0; is < this->inp_->bse_spin_types.size(); ++is) { - read_full_states(this->input.bse_spin_types[is], + read_full_states(this->inp_->bse_spin_types[is], &this->full_ene[is * this->nstates], this->full_X[is].template data(), this->full_Y[is].template data(), @@ -381,25 +381,25 @@ void ESolver_BSE::after_all_runners(BaseCell& basecell) ModuleBase::timer::start("ESolver_BSE", "after_all_runners"); const std::string& output_dir = this->out_dir; const std::set benchmarks = {"abacus-librpa", "abacus", "none" }; - if (benchmarks.find(this->input.ri_hartree_benchmark) == benchmarks.end()) + if (benchmarks.find(this->inp_->ri_hartree_benchmark) == benchmarks.end()) { return; } // no need to calculate the spectrum - if (this->input.lr_solver == "plot") + if (this->inp_->lr_solver == "plot") { for (int is = 0; is < this->X.size(); ++is) { - std::cout << "plot BSE exciton wavefunction for state: " << this->input.plot_istate - << ", spin type: " << this->input.bse_spin_types[is] << std::endl; + std::cout << "plot BSE exciton wavefunction for state: " << this->inp_->plot_istate + << ", spin type: " << this->inp_->bse_spin_types[is] << std::endl; LR_Util::ExcitonPlotter eplot(this->nspin, this->nbasis, this->nocc, this->nvirt, *this->psi_ks, *this->ucell_, this->kv, this->gd, this->orb_cutoff_, this->Pgrid, *this->pw_rho, this->paraX_, this->paraC_, this->paraMat_, output_dir, &this->tda_ene[is * this->nstates], this->X[is].template data(), false/*openshell*/, &this->orb_); - const std::string plot_type = LR_Util::tolower(this->input.exciton_plot_type); - const std::string plot_format = LR_Util::tolower(this->input.exciton_plot_format); + const std::string plot_type = LR_Util::tolower(this->inp_->exciton_plot_type); + const std::string plot_format = LR_Util::tolower(this->inp_->exciton_plot_format); const bool write_slice = (plot_format == "slice" || plot_format == "both"); const bool write_cube = (plot_format == "cube" || plot_format == "both"); @@ -416,50 +416,50 @@ void ESolver_BSE::after_all_runners(BaseCell& basecell) "ESolver_BSE", "conditional exciton density only supports exciton_plot_format = slice"); } - if (this->input.exciton_fixed_coordinate.size() != 6) + if (this->inp_->exciton_fixed_coordinate.size() != 6) { ModuleBase::WARNING_QUIT( "ESolver_BSE", "exciton_fixed_coordinate must contain six values: hole x y z followed by electron x y z"); } - const std::array r_h_fix = {this->input.exciton_fixed_coordinate[0], - this->input.exciton_fixed_coordinate[1], - this->input.exciton_fixed_coordinate[2]}; - const std::array r_e_fix = {this->input.exciton_fixed_coordinate[3], - this->input.exciton_fixed_coordinate[4], - this->input.exciton_fixed_coordinate[5]}; - eplot.plot_cond_slice(this->input.plot_istate, r_h_fix, - this->input.exciton_slice_plane, - this->input.exciton_slice_pos, - this->input.exciton_slice_npoints, - this->input.exciton_slice_range, "elec"); - eplot.plot_cond_slice(this->input.plot_istate, r_e_fix, - this->input.exciton_slice_plane, - this->input.exciton_slice_pos, - this->input.exciton_slice_npoints, - this->input.exciton_slice_range, "hole"); + const std::array r_h_fix = {this->inp_->exciton_fixed_coordinate[0], + this->inp_->exciton_fixed_coordinate[1], + this->inp_->exciton_fixed_coordinate[2]}; + const std::array r_e_fix = {this->inp_->exciton_fixed_coordinate[3], + this->inp_->exciton_fixed_coordinate[4], + this->inp_->exciton_fixed_coordinate[5]}; + eplot.plot_cond_slice(this->inp_->plot_istate, r_h_fix, + this->inp_->exciton_slice_plane, + this->inp_->exciton_slice_pos, + this->inp_->exciton_slice_npoints, + this->inp_->exciton_slice_range, "elec"); + eplot.plot_cond_slice(this->inp_->plot_istate, r_e_fix, + this->inp_->exciton_slice_plane, + this->inp_->exciton_slice_pos, + this->inp_->exciton_slice_npoints, + this->inp_->exciton_slice_range, "hole"); } else if (plot_type == "average") { if (write_cube) { // Average hole density: integrates out the electron coordinate - eplot.plot_average_density(this->input.plot_istate, "hole"); + eplot.plot_average_density(this->inp_->plot_istate, "hole"); // Average electron density: integrates out the hole coordinate - eplot.plot_average_density(this->input.plot_istate, "elec"); + eplot.plot_average_density(this->inp_->plot_istate, "elec"); } if (write_slice) { - eplot.plot_average_slice(this->input.plot_istate, "hole", - this->input.exciton_slice_plane, - this->input.exciton_slice_pos, - this->input.exciton_slice_npoints, - this->input.exciton_slice_range); - eplot.plot_average_slice(this->input.plot_istate, "elec", - this->input.exciton_slice_plane, - this->input.exciton_slice_pos, - this->input.exciton_slice_npoints, - this->input.exciton_slice_range); + eplot.plot_average_slice(this->inp_->plot_istate, "hole", + this->inp_->exciton_slice_plane, + this->inp_->exciton_slice_pos, + this->inp_->exciton_slice_npoints, + this->inp_->exciton_slice_range); + eplot.plot_average_slice(this->inp_->plot_istate, "elec", + this->inp_->exciton_slice_plane, + this->inp_->exciton_slice_pos, + this->inp_->exciton_slice_npoints, + this->inp_->exciton_slice_range); } } else @@ -468,17 +468,17 @@ void ESolver_BSE::after_all_runners(BaseCell& basecell) } } } - if (this->input.lr_solver == "spectrum" || this->input.lr_solver == "elpa") + if (this->inp_->lr_solver == "spectrum" || this->inp_->lr_solver == "elpa") { std::cout << "Calculating BSE optical absorption spectrum." << std::endl; - if (LR_Util::tolower(this->input.abs_gauge) == "velocity" ) + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity" ) { - const int nspin_tmp = this->input.nspin == 2 ? 2 : 1; + const int nspin_tmp = this->inp_->nspin == 2 ? 2 : 1; this->velocity_mo = LR_Util::cal_velocity_mo(*this->ucell_, this->gd, this->two_center_bundle_, this->paraMat_, this->paraC_, this->kv, *this->psi_ks, this->nk, nspin_tmp, this->nbasis, this->nocc, this->nvirt); } - if (this->input.bse_tda == "both" || this->input.bse_tda == "tda") + if (this->inp_->bse_tda == "both" || this->inp_->bse_tda == "tda") { for (int is = 0; is < this->X.size(); ++is) { @@ -487,19 +487,19 @@ void ESolver_BSE::after_all_runners(BaseCell& basecell) this->paraX_, this->paraC_, this->paraMat_, &this->tda_ene[is * this->nstates], this->eig_ks.c, this->X[is].template data(), this->nstates, false/*openshell*/, - LR_Util::tolower(this->input.abs_gauge), GlobalV::MY_RANK, output_dir); - if (LR_Util::tolower(this->input.abs_gauge) == "velocity") + LR_Util::tolower(this->inp_->abs_gauge), GlobalV::MY_RANK, output_dir); + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity") { spectrum.set_vmo(this->velocity_mo.data()); } spectrum.cal_spectrum(); - spectrum.transition_analysis(this->input.bse_spin_types[is]+"_tda"); - if (this->input.bse_spin_types[is] != "triplet") // triplets has no transition dipole and no contribution to the spectrum + spectrum.transition_analysis(this->inp_->bse_spin_types[is]+"_tda"); + if (this->inp_->bse_spin_types[is] != "triplet") // triplets has no transition dipole and no contribution to the spectrum { spectrum.write_transition_dipole(output_dir + - "trans_dipole_" + this->input.bse_spin_types[is] + "_tda.dat"); + "trans_dipole_" + this->inp_->bse_spin_types[is] + "_tda.dat"); // ============================== for test ============================== - if (LR_Util::tolower(this->input.abs_gauge) == "velocity") + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity") { //// TEST the formula v/omega rather than v/(e_a-e_i) // spectrum.test_transition_dipoles_velocity_omega(); // spectrum.write_transition_dipole(out_dir + @@ -509,7 +509,7 @@ void ESolver_BSE::after_all_runners(BaseCell& basecell) } } } - if (this->input.bse_tda == "both" || this->input.bse_tda == "full") + if (this->inp_->bse_tda == "both" || this->inp_->bse_tda == "full") { for (int is = 0;is < this->full_X.size();++is) { @@ -518,19 +518,19 @@ void ESolver_BSE::after_all_runners(BaseCell& basecell) this->paraX_, this->paraC_, this->paraMat_, &this->full_ene[is * this->nstates], this->eig_ks.c, this->full_X[is].template data(), this->nstates, false/*openshell*/, - LR_Util::tolower(this->input.abs_gauge), GlobalV::MY_RANK, output_dir); - if (LR_Util::tolower(this->input.abs_gauge) == "velocity") + LR_Util::tolower(this->inp_->abs_gauge), GlobalV::MY_RANK, output_dir); + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity") { spectrum.set_vmo(this->velocity_mo.data()); } spectrum.set_Y(this->full_Y[is].template data()); spectrum.set_full(true); spectrum.cal_spectrum(); - spectrum.transition_analysis(this->input.bse_spin_types[is]+"_full"); - if (this->input.bse_spin_types[is] != "triplet") // triplets has no transition dipole and no contribution to the spectrum + spectrum.transition_analysis(this->inp_->bse_spin_types[is]+"_full"); + if (this->inp_->bse_spin_types[is] != "triplet") // triplets has no transition dipole and no contribution to the spectrum { spectrum.write_transition_dipole(output_dir + - "trans_dipole_" + this->input.bse_spin_types[is] + "_full.dat"); + "trans_dipole_" + this->inp_->bse_spin_types[is] + "_full.dat"); } } } @@ -545,7 +545,7 @@ void ESolver_BSE::ipa_solver() ModuleBase::TITLE("ESolver_BSE", "ipa_solver"); ModuleBase::timer::start("ESolver_BSE", "ipa_solver"); std::cout << "Independent particle approximation is used, assign X as identity matrix directly." << std::endl; - assert(this->input.bse_tda == "tda"); + assert(this->inp_->bse_tda == "tda"); std::vector ev(this->nk * this->nocc[0] * this->nvirt[0], 0.0); for (int ik = 0; ik < this->nk; ++ik) { @@ -600,11 +600,11 @@ void ESolver_BSE::lri_init() // if (GlobalV::MY_RANK == 0) // comment to read from all processes to avoid communication // { Cs_in = LRI_CV_Tools::read_Cs_ao_all(this->rpa_dir); - if (this->input.ri_hartree_benchmark == "aims-librpa" ) + if (this->inp_->ri_hartree_benchmark == "aims-librpa" ) { Vs_in = LR_IO::read_coulomb_mat_general_k(this->rpa_dir, Cs_in, this->kRlist); } - else if (this->input.ri_hartree_benchmark == "none" || this->input.ri_hartree_benchmark == "abacus-librpa" ) + else if (this->inp_->ri_hartree_benchmark == "none" || this->inp_->ri_hartree_benchmark == "abacus-librpa" ) { Vs_in = LR_IO::read_coulomb_mat_k(this->rpa_dir, Cs_in, this->kRlist); } @@ -613,7 +613,7 @@ void ESolver_BSE::lri_init() #ifdef __MPI MPI_Barrier(MPI_COMM_WORLD); #endif - this->mo_lri->init(Cs_in, Vs_in, Ws_in, GlobalC::exx_info.info_ri); + this->mo_lri->init(Cs_in, Vs_in, Ws_in, this->exx_info.info_ri); malloc_trim(0); ModuleBase::TITLE("ESolver_BSE", "Finish LRI init"); } @@ -631,14 +631,14 @@ void ESolver_BSE::read_ks_wfc() int nk_file = 0; int nspin_file = 0; int nocc_file = 0; - int nspin_tmp = this->input.nspin == 2 ? 2 : 1; + int nspin_tmp = this->inp_->nspin == 2 ? 2 : 1; LR_IO::parse_band_out_file(this->rpa_dir, nbands_file, nk_file, nspin_file, nocc_file); if (nk_file != this->nk) { ModuleBase::WARNING_QUIT("ESolver_BSE", "Inconsistence: The nk in `band_out` is " + std::to_string(nk_file) + ", while BSE::nk is " + std::to_string(this->nk)); } std::vector eig_gw_info; - if (this->input.bse_use_fine_kgrid) + if (this->inp_->bse_use_fine_kgrid) { eig_gw_info = LR_IO::read_energy_qp_from_band_files(this->kv, this->nocc[0], this->nvirt[0], ncore, this->rpa_dir, this->nk, nspin_tmp, nspin_file); @@ -705,11 +705,11 @@ void ESolver_BSE::init_pot(const Charge& chg_gs) using ST = LR::PotHxcLR::SpinType; case 1: case 2: this->pot[0] = std::make_shared(this->xc_kernel, *this->pw_rho, *this->ucell_, chg_gs, this->Pgrid, - ST::S1, this->input.lr_init_xc_kernel); + ST::S1, this->inp_->lr_init_xc_kernel); break; // case 2: - // this->pot[0] = std::make_shared(xc_kernel, *this->pw_rho, ucell, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_singlet, input.lr_init_xc_kernel); - // this->pot[1] = std::make_shared(xc_kernel, *this->pw_rho, ucell, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_triplet, input.lr_init_xc_kernel); + // this->pot[0] = std::make_shared(xc_kernel, *this->pw_rho, ucell, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_singlet, this->inp_->lr_init_xc_kernel); + // this->pot[1] = std::make_shared(xc_kernel, *this->pw_rho, ucell, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_triplet, this->inp_->lr_init_xc_kernel); // break; default: throw std::invalid_argument("ESolver_BSE: nspin must be 1 or 2"); @@ -735,8 +735,8 @@ void ESolver_BSE::allocate_eigen_infos() * (this->openshell ? this->paraX_[0].get_local_size() + this->paraX_[1].get_local_size() : this->paraX_[0].get_local_size()); - int n_spin_types = this->input.bse_spin_types.size(); - if (this->input.bse_tda == "both" || this->input.bse_tda == "tda") { + int n_spin_types = this->inp_->bse_spin_types.size(); + if (this->inp_->bse_tda == "both" || this->inp_->bse_tda == "tda") { BSE_Util::print_mem_estimate("TDA BSE eigen states", n_spin_types * static_cast(this->nstates) * (1 + this->nloc_per_state), @@ -745,7 +745,7 @@ void ESolver_BSE::allocate_eigen_infos() this->X.resize(n_spin_types, LR_Util::newTensor({ this->nstates, this->nloc_per_state })); for (auto& x : this->X) { x.zero(); } } - if (this->input.bse_tda == "both" || this->input.bse_tda == "full") { + if (this->inp_->bse_tda == "both" || this->inp_->bse_tda == "full") { BSE_Util::print_mem_estimate("full BSE eigen states", n_spin_types * static_cast(this->nstates) * (1 + 2 * this->nloc_per_state), diff --git a/source/source_esolver/esolver_lr_lcao_tddft.cpp b/source/source_esolver/esolver_lr_lcao_tddft.cpp index 94a678afe65..4eed9f35f8f 100644 --- a/source/source_esolver/esolver_lr_lcao_tddft.cpp +++ b/source/source_esolver/esolver_lr_lcao_tddft.cpp @@ -21,7 +21,7 @@ #include "source_lcao/module_lr/operator_casida/operator_lr_diag.h" // for precondition #ifdef __EXX #include "source_lcao/module_ri/exx_lri_interface.h" -#include "source_hamilt/module_xc/exx_info.h" +#include "source_hamilt/module_xc/exx_info.h" // for init_exx_info #endif #ifdef __EXX @@ -76,14 +76,14 @@ void ModuleESolver::ESolver_LR::setup_2center_table(TwoCenterBundle& two_ #ifdef __FFT_TWO_CENTER two_center_bundle.tabulate(); #else - two_center_bundle.tabulate(inp.lcao_ecut, inp.lcao_dk, inp.lcao_dr, inp.lcao_rmax); + two_center_bundle.tabulate(this->inp_->lcao_ecut, this->inp_->lcao_dk, this->inp_->lcao_dr, this->inp_->lcao_rmax); #endif - if (input.vnl_in_h) + if (this->inp_->vnl_in_h) { auto* lcao_nl = new LCAONonlocalInfo(); lcao_nl->setupNonlocal(ucell.ntype, ucell.atoms, GlobalV::ofs_running, orb, - input.basis_type, input.out_element_info, - input.lspinorb, input.nspin); + this->inp_->basis_type, this->inp_->out_element_info, + this->inp_->lspinorb, this->inp_->nspin); ucell.infoNL.reset(lcao_nl); two_center_bundle.build_beta(ucell.ntype, lcao_nl->get_nonlocal().Beta); } @@ -95,7 +95,7 @@ void ModuleESolver::ESolver_LR::parameter_check()const const std::set lr_solvers = { "dav", "lapack" , "spectrum", "dav_subspace", "cg", "elpa", "plot" }; const std::set xc_kernels = { "rpa", "lda", "pwlda", "pbe", "hf", "hse", "bse" }; const std::set abs_gauge = { "velocity", "length" }; - if (lr_solvers.find(this->input.lr_solver) == lr_solvers.end()) { + if (lr_solvers.find(this->inp_->lr_solver) == lr_solvers.end()) { throw std::invalid_argument("ESolver_LR: unknown type of lr_solver"); } if (xc_kernels.find(this->xc_kernel) == xc_kernels.end()) { @@ -104,7 +104,7 @@ void ModuleESolver::ESolver_LR::parameter_check()const if (this->nspin != 1 && this->nspin != 2) { throw std::invalid_argument("LR-TDDFT only supports nspin = 1 or 2 now"); } - if (abs_gauge.find(this->input.abs_gauge) == abs_gauge.end()) { + if (abs_gauge.find(this->inp_->abs_gauge) == abs_gauge.end()) { throw std::invalid_argument("ESolver_LR: unknown type of abs_gauge"); } } @@ -112,17 +112,17 @@ void ModuleESolver::ESolver_LR::parameter_check()const template void ModuleESolver::ESolver_LR::set_dimension() { - this->nspin = input.nspin; - this->nstates = input.lr_nstates; + this->nspin = this->inp_->nspin; + this->nstates = this->inp_->lr_nstates; this->nbasis = PARAM.globalv.nlocal; - int ks_nbands = input.nbands; + int ks_nbands = this->inp_->nbands; this->nocc_max = LR_Util::cal_nocc(LR_Util::cal_nelec(*this->ucell_)); - if (input.ri_hartree_benchmark == "aims" || input.ri_hartree_benchmark == "aims-librpa" - && !input.aims_nbasis.empty()) + if (this->inp_->ri_hartree_benchmark == "aims" || this->inp_->ri_hartree_benchmark == "aims-librpa" + && !this->inp_->aims_nbasis.empty()) { // calculate total number of basis funcs, see https://en.cppreference.com/w/cpp/algorithm/inner_product - this->nbasis = std::inner_product(input.aims_nbasis.begin(), /* iterator1.begin */ - input.aims_nbasis.end(), /* iterator1.end */ + this->nbasis = std::inner_product(this->inp_->aims_nbasis.begin(), /* iterator1.begin */ + this->inp_->aims_nbasis.end(), /* iterator1.end */ this->ucell_->atoms, /* iterator2.begin */ 0, /* init value */ std::plus(), /* iter op1 */ @@ -130,7 +130,7 @@ void ModuleESolver::ESolver_LR::set_dimension() std::cout << "nbasis from aims: " << this->nbasis << std::endl; for (int it = 0; it < this->ucell_->ntype; ++it) { - this->ucell_->atoms[it].nw = input.aims_nbasis[it]; + this->ucell_->atoms[it].nw = this->inp_->aims_nbasis[it]; } const_cast(this->ucell_)->set_iat2iwt(1); // update iat2iwt for aims_nbasis 25-05-23 @@ -138,19 +138,19 @@ void ModuleESolver::ESolver_LR::set_dimension() int nk_file = 0; int nspin_file = 0; int nocc_file = 0; - LR_IO::parse_band_out_file(input.rpa_outdir, nbands_file, nk_file, nspin_file, nocc_file); + LR_IO::parse_band_out_file(this->inp_->rpa_outdir, nbands_file, nk_file, nspin_file, nocc_file); std::cout << "nocc from band_out: " << nocc_file << std::endl; ks_nbands = nbands_file; this->nocc_max = nocc_file; } // calculate the number of occupied and unoccupied states // which determines the basis size of the excited states - this->nocc_in = std::max(1, std::min(input.nocc, this->nocc_max)); + this->nocc_in = std::max(1, std::min(this->inp_->nocc, this->nocc_max)); this->nvirt_in = ks_nbands - this->nocc_max; //nbands-nocc - if (input.nvirt > this->nvirt_in) { GlobalV::ofs_running << "ESolver_LR: input nvirt is too large to cover by nbands, set nvirt = nbands - nocc = " << this->nvirt_in << std::endl; } - else if (input.nvirt > 0) { this->nvirt_in = input.nvirt; } + if (this->inp_->nvirt > this->nvirt_in) { GlobalV::ofs_running << "ESolver_LR: input nvirt is too large to cover by nbands, set nvirt = nbands - nocc = " << this->nvirt_in << std::endl; } + else if (this->inp_->nvirt > 0) { this->nvirt_in = this->inp_->nvirt; } this->nbands = this->nocc_in + this->nvirt_in; - this->nk = input.nspin == 2 ? this->kv.get_nks() / 2 : this->kv.get_nks(); + this->nk = this->inp_->nspin == 2 ? this->kv.get_nks() / 2 : this->kv.get_nks(); this->nocc.resize(nspin, nocc_in); this->nvirt.resize(nspin, nvirt_in); if (this->nstates <= 0) { @@ -196,7 +196,7 @@ void ModuleESolver::ESolver_LR::reset_dim_spin2() { throw std::invalid_argument("ESolver_LR: nstates > nocc*nvirt*nk"); } - if (input.lr_unrestricted) + if (this->inp_->lr_unrestricted) { this->openshell = true; } @@ -206,11 +206,11 @@ template ModuleESolver::ESolver_LR::ESolver_LR(const Input_para& inp, const std::string& in_dir, const std::string& out_dir) - : input(inp), in_dir(in_dir), out_dir(out_dir) + : in_dir(in_dir), out_dir(out_dir) +{ #ifdef __EXX - , exx_info(GlobalC::exx_info) + init_exx_info(this->exx_info, inp); #endif -{ } template @@ -219,6 +219,7 @@ void ModuleESolver::ESolver_LR::before_all_runners(BaseCell& basecell, co basecell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(basecell); this->ucell_ = &ucell; + this->inp_ = &inp; if (inp.esolver_type == "ks-lr") { ModuleESolver::ESolver_KS_LCAO ks_solver; @@ -239,7 +240,7 @@ void ModuleESolver::ESolver_LR::initialize_from_ks_(ModuleESolver::ESolve { ModuleBase::TITLE("ESolver_LR", "ESolver_LR(KS)"); - if (this->input.lr_solver == "spectrum") + if (this->inp_->lr_solver == "spectrum") { throw std::invalid_argument("when lr_solver==spectrum, esolver_type must be `lr` to skip KS calculation."); } @@ -276,7 +277,7 @@ void ModuleESolver::ESolver_LR::initialize_from_ks_(ModuleESolver::ESolve this->eig_ks = std::move(ks_sol.pelec->ekb); }; #ifdef __MPI - if (this->nbands == input.nbands) + if (this->nbands == this->inp_->nbands) { move_gs(); } @@ -320,7 +321,7 @@ void ModuleESolver::ESolver_LR::initialize_from_ks_(ModuleESolver::ESolve if (xc_kernel == "hf" || xc_kernel == "hse") { // if the same kernel is calculated in the esolver_ks, move it - std::string dft_functional = LR_Util::tolower(input.dft_functional); + std::string dft_functional = LR_Util::tolower(this->inp_->dft_functional); if (ks_sol.exx_nao.exd && std::is_same::value && xc_kernel == dft_functional) { this->move_exx_lri(ks_sol.exx_nao.exd->exx_ptr); } else if (ks_sol.exx_nao.exc && std::is_same>::value && xc_kernel == dft_functional) { @@ -333,13 +334,13 @@ void ModuleESolver::ESolver_LR::initialize_from_ks_(ModuleESolver::ESolve exx_info.sync_from_global(); this->exx_lri = std::make_shared>(exx_info.info_ri); this->exx_lri->init(MPI_COMM_WORLD, ucell,this->kv, ks_sol.orb_); - this->exx_lri->cal_exx_ions(ucell,input.out_ri_cv); + this->exx_lri->cal_exx_ions(ucell,this->inp_->out_ri_cv); } } #endif this->pelec = new elecstate::ElecStateLCAO(); orb_cutoff_ = ks_sol.orb_.cutoffs(); - if (LR_Util::tolower(input.abs_gauge) == "velocity") + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity") { this->two_center_bundle_ = std::move(ks_sol.two_center_bundle_); } @@ -359,17 +360,16 @@ void ModuleESolver::ESolver_LR::initialize_from_unitcell_(UnitCell& ucell // necessary steps in ESolver_KS::before_all_runners : symmetry and k-points if (ModuleSymmetry::Symmetry::symm_flag == 1) { - const int cal_symm_repr[2] = {input.cal_symm_repr[0], input.cal_symm_repr[1]}; + const int cal_symm_repr[2] = {this->inp_->cal_symm_repr[0], this->inp_->cal_symm_repr[1]}; ucell.symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running, - input.symmetry_prec, input.nspin, input.calculation, cal_symm_repr); + this->inp_->symmetry_prec, this->inp_->nspin, this->inp_->calculation, cal_symm_repr); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); } const bool use_ibz = false; const bool gamma_only_local = PARAM.globalv.gamma_only_local; - const double kspacing[3] = {input.kspacing[0], input.kspacing[1], input.kspacing[2]}; - const std::string kmesh_type = input.kmesh_type; - const double koffset[3] = {input.koffset[0], input.koffset[1], input.koffset[2]}; - this->kv.set(ucell, ucell.symm, input.kpoint_file, input.nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, use_ibz, this->out_dir, gamma_only_local, kspacing, kmesh_type, koffset); + 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); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); ModuleIO::print_parameters(ucell, this->kv, inp); @@ -382,7 +382,7 @@ void ModuleESolver::ESolver_LR::initialize_from_unitcell_(UnitCell& ucell two_center_bundle_.to_LCAO_Orbitals(orb, inp.lcao_ecut, inp.lcao_dk, inp.lcao_dr, inp.lcao_rmax, inp.out_element_info, inp.cal_force); orb_cutoff_ = orb.cutoffs(); - if (LR_Util::tolower(input.abs_gauge) == "velocity") + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity") { setup_2center_table(this->two_center_bundle_, orb, ucell); } @@ -394,7 +394,7 @@ void ModuleESolver::ESolver_LR::initialize_from_unitcell_(UnitCell& ucell this->paraMat_.set_desc_wfc_Eij(this->nbasis, this->nbands, paraMat_.get_row_size()); int err = this->paraMat_.set_nloc_wfc_Eij(this->nbands, GlobalV::ofs_running, GlobalV::ofs_warning); this->paraMat_.set_atomic_trace(ucell.get_iat2iwt(), ucell.nat, this->nbasis); - if (input.ri_hartree_benchmark != "aims") { this->paraMat_.set_atomic_trace(ucell.get_iat2iwt(), ucell.nat, this->nbasis); } + if (this->inp_->ri_hartree_benchmark != "aims") { this->paraMat_.set_atomic_trace(ucell.get_iat2iwt(), ucell.nat, this->nbasis); } #else this->paraMat_.nrow_bands = this->nbasis; this->paraMat_.ncol_bands = this->nbands; @@ -434,13 +434,13 @@ void ModuleESolver::ESolver_LR::initialize_from_unitcell_(UnitCell& ucell pw_big->bz, GlobalV::NPROC); Charge chg_gs; - if (input.ri_hartree_benchmark == "none") { this->read_ks_chg(chg_gs); } + if (this->inp_->ri_hartree_benchmark == "none") { this->read_ks_chg(chg_gs); } this->init_pot(chg_gs); // search adjacent atoms and init Gint double search_radius = -1.0; search_radius = atom_arrange::set_sr_NL(GlobalV::ofs_running, - input.out_level, + this->inp_->out_level, orb.get_rcutmax_Phi(), ucell.infoNL->get_rcutmax_Beta(), PARAM.globalv.gamma_only_local); @@ -449,7 +449,7 @@ void ModuleESolver::ESolver_LR::initialize_from_unitcell_(UnitCell& ucell this->gd, *this->ucell_, search_radius, - input.test_atom_input); + this->inp_->test_atom_input); gint_info_.reset( new ModuleGint::GintInfo( this->pw_big->nbx, @@ -470,14 +470,14 @@ void ModuleESolver::ESolver_LR::initialize_from_unitcell_(UnitCell& ucell ModuleGint::Gint::set_gint_info(gint_info_.get()); // if EXX from scratch, init 2-center integral and calculate Cs, Vs #ifdef __EXX - if ((xc_kernel == "hf" || xc_kernel == "hse") && this->input.lr_solver != "spectrum") + if ((xc_kernel == "hf" || xc_kernel == "hse") && this->inp_->lr_solver != "spectrum") { // set ccp_type according to the xc_kernel if (xc_kernel == "hf") { exx_info.info_global.ccp_type = Conv_Coulomb_Pot_K::Ccp_Type::Hf; } else if (xc_kernel == "hse") { exx_info.info_global.ccp_type = Conv_Coulomb_Pot_K::Ccp_Type::Erfc; } this->exx_lri = std::make_shared>(exx_info.info_ri); this->exx_lri->init(MPI_COMM_WORLD, ucell,this->kv, orb); - this->exx_lri->cal_exx_ions(ucell,input.out_ri_cv); + this->exx_lri->cal_exx_ions(ucell,this->inp_->out_ri_cv); } // else #endif @@ -498,25 +498,25 @@ void ModuleESolver::ESolver_LR::runner(BaseCell& basecell, const int iste auto efile_out = [&](const std::string& label)->std::string {return this->out_dir + "Excitation_Energy_" + label + ".dat";}; auto vfile_out = [&](const std::string& label)->std::string {return this->out_dir + "Excitation_Amplitude_" + label + "_" + std::to_string(GlobalV::MY_RANK) + ".dat";}; - if (this->input.lr_solver == "elpa") + if (this->inp_->lr_solver == "elpa") { ModuleBase::WARNING_QUIT("ESolver_LR", "ESolver_LR doesn't support elpa now."); } - else if (this->input.lr_solver != "spectrum") + else if (this->inp_->lr_solver != "spectrum") { auto write_states = [&](const std::string& label, const Real* e, const T* v, const int& dim, const int& nst, const int& prec = 8)->void { if (GlobalV::MY_RANK == 0) { assert(nst == LR_Util::write_value(efile_out(label), prec, e, nst)); } assert(nst * dim == LR_Util::write_value(vfile_out(label), prec, v, nst, dim)); }; - std::vector precondition(this->input.lr_solver == "lapack" ? 0 : nloc_per_state, 1.0); + std::vector precondition(this->inp_->lr_solver == "lapack" ? 0 : nloc_per_state, 1.0); // allocate and initialize A matrix and density matrix if (openshell) { for (int is : {0, 1}) { - if (input.lr_solver != "lapack") { + if (this->inp_->lr_solver != "lapack") { const int offset_is = is * this->paraX_[0].get_local_size(); OperatorLRDiag pre_op(this->eig_ks.c + is * nk * (nocc[0] + nvirt[0]), this->paraX_[is], this->nk, this->nocc[is], this->nvirt[is]); pre_op.act(1, offset_is, 1, precondition.data() + offset_is, precondition.data() + offset_is); @@ -544,13 +544,13 @@ void ModuleESolver::ESolver_LR::runner(BaseCell& basecell, const int iste this->paraMat_); LR::HSolver::solve(hulr, this->X[0].template data(), nloc_per_state, nstates, this->nk, this->nocc, this->nvirt, this->paraX_, - this->pelec->ekb.c, this->input.lr_solver, - this->input.lr_thr, precondition); - if (input.out_wfc_lr) { write_states("openshell", this->pelec->ekb.c, this->X[0].template data(), nloc_per_state, nstates); } + this->pelec->ekb.c, this->inp_->lr_solver, + this->inp_->lr_thr, precondition); + if (this->inp_->out_wfc_lr) { write_states("openshell", this->pelec->ekb.c, this->X[0].template data(), nloc_per_state, nstates); } } else { - if (input.lr_solver != "lapack") { + if (this->inp_->lr_solver != "lapack") { OperatorLRDiag pre_op(this->eig_ks.c, this->paraX_[0], this->nk, this->nocc[0], this->nvirt[0]); pre_op.act(1, nloc_per_state, 1, precondition.data(), precondition.data()); } @@ -579,15 +579,15 @@ void ModuleESolver::ESolver_LR::runner(BaseCell& basecell, const int iste this->paraMat_, spin_types[is], this->out_dir, - input.ri_hartree_benchmark, - (input.ri_hartree_benchmark == "aims" ? input.aims_nbasis : std::vector({}))); + this->inp_->ri_hartree_benchmark, + (this->inp_->ri_hartree_benchmark == "aims" ? this->inp_->aims_nbasis : std::vector({}))); LR::HSolver::solve(hlr, this->X[is].template data(), nloc_per_state, nstates, this->nk, this->nocc, this->nvirt, this->paraX_, this->pelec->ekb.c + is * nstates, - this->input.lr_solver, - this->input.lr_thr, + this->inp_->lr_solver, + this->inp_->lr_thr, precondition); - if (input.out_wfc_lr) { write_states(spin_types[is], this->pelec->ekb.c + is * nstates, this->X[is].template data(), nloc_per_state, nstates); } + if (this->inp_->out_wfc_lr) { write_states(spin_types[is], this->pelec->ekb.c + is * nstates, this->X[is].template data(), nloc_per_state, nstates); } } } } @@ -631,20 +631,20 @@ void ModuleESolver::ESolver_LR::after_all_runners(BaseCell& basecell) UnitCell& ucell = static_cast(basecell); ModuleBase::TITLE("ESolver_LR", "after_all_runners"); - if (input.ri_hartree_benchmark != "none") { return; } //no need to calculate the spectrum in the benchmark routine + if (this->inp_->ri_hartree_benchmark != "none") { return; } //no need to calculate the spectrum in the benchmark routine //cal spectrum - if (LR_Util::tolower(this->input.abs_gauge) == "velocity" ) + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity" ) { - const int nspin_tmp = input.nspin == 2 ? 2 : 1; + const int nspin_tmp = this->inp_->nspin == 2 ? 2 : 1; this->velocity_mo = LR_Util::cal_velocity_mo(*this->ucell_, this->gd, this->two_center_bundle_, this->paraMat_, this->paraC_, this->kv, *this->psi_ks, this->nk, nspin_tmp, this->nbasis, this->nocc, this->nvirt); } std::vector freq(100); std::vector abs_wavelen_range({ 20, 200 });//default range - if (input.abs_wavelen_range.size() >= 2 && std::abs(input.abs_wavelen_range[1] - input.abs_wavelen_range[0]) > 0.02) + if (this->inp_->abs_wavelen_range.size() >= 2 && std::abs(this->inp_->abs_wavelen_range[1] - this->inp_->abs_wavelen_range[0]) > 0.02) { - abs_wavelen_range = input.abs_wavelen_range; + abs_wavelen_range = this->inp_->abs_wavelen_range; } double lambda_diff = std::abs(abs_wavelen_range[1] - abs_wavelen_range[0]); double lambda_min = std::min(abs_wavelen_range[1], abs_wavelen_range[0]); @@ -656,18 +656,18 @@ void ModuleESolver::ESolver_LR::after_all_runners(BaseCell& basecell) *this->ucell_, this->kv, this->gd, this->orb_cutoff_, this->two_center_bundle_, this->paraX_, this->paraC_, this->paraMat_, &this->pelec->ekb.c[is * nstates], this->eig_ks.c, this->X[is].template data(), nstates, openshell, - LR_Util::tolower(input.abs_gauge), GlobalV::MY_RANK, this->out_dir); - if (LR_Util::tolower(this->input.abs_gauge) == "velocity" ) {spectrum.set_vmo(this->velocity_mo.data());} + LR_Util::tolower(this->inp_->abs_gauge), GlobalV::MY_RANK, this->out_dir); + if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity" ) {spectrum.set_vmo(this->velocity_mo.data());} spectrum.cal_spectrum(); spectrum.transition_analysis(spin_types[is]+"_tda"); if (spin_types[is] != "triplet") // triplets has no transition dipole and no contribution to the spectrum { - spectrum.optical_absorption_method1(freq, input.abs_broadening); + spectrum.optical_absorption_method1(freq, this->inp_->abs_broadening); spectrum.write_transition_dipole(this->out_dir + "trans_dipole_" + spin_types[is] + "_tda.dat"); // =============================================== for test ==================================================== - // spectrum.optical_absorption_method2(freq, input.abs_broadening); - // if (LR_Util::tolower(input.abs_gauge) == "velocity") + // spectrum.optical_absorption_method2(freq, this->inp_->abs_broadening); + // if (LR_Util::tolower(this->inp_->abs_gauge) == "velocity") // { // TEST the formula v/omega rather than v/(e_a-e_i) // spectrum.test_transition_dipoles_velocity_omega(); // spectrum.write_transition_dipole(this->out_dir + @@ -699,7 +699,7 @@ void ModuleESolver::ESolver_LR::setup_eigenvectors_X() auto spin_types = (nspin == 2 && !openshell) ? std::vector({ "singlet", "triplet" }) : std::vector({ "updown" }); // if spectrum-only, read the LR-eigenstates from file and return - if (this->input.lr_solver != "spectrum") { set_X_initial_guess(); } + if (this->inp_->lr_solver != "spectrum") { set_X_initial_guess(); } } template @@ -753,16 +753,16 @@ template void ModuleESolver::ESolver_LR::init_pot(const Charge& chg_gs) { this->pot.resize(nspin, nullptr); - if (this->input.ri_hartree_benchmark != "none") { return; } //no need to initialize potential for Hxc kernel in the RI-benchmark routine + if (this->inp_->ri_hartree_benchmark != "none") { return; } //no need to initialize potential for Hxc kernel in the RI-benchmark routine switch (nspin) { using ST = PotHxcLR::SpinType; case 1: - this->pot[0] = std::make_shared(xc_kernel, *this->pw_rho, *this->ucell_, chg_gs, Pgrid, ST::S1, input.lr_init_xc_kernel); + this->pot[0] = std::make_shared(xc_kernel, *this->pw_rho, *this->ucell_, chg_gs, Pgrid, ST::S1, this->inp_->lr_init_xc_kernel); break; case 2: - this->pot[0] = std::make_shared(xc_kernel, *this->pw_rho, *this->ucell_, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_singlet, input.lr_init_xc_kernel); - this->pot[1] = std::make_shared(xc_kernel, *this->pw_rho, *this->ucell_, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_triplet, input.lr_init_xc_kernel); + this->pot[0] = std::make_shared(xc_kernel, *this->pw_rho, *this->ucell_, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_singlet, this->inp_->lr_init_xc_kernel); + this->pot[1] = std::make_shared(xc_kernel, *this->pw_rho, *this->ucell_, chg_gs, Pgrid, openshell ? ST::S2_updown : ST::S2_triplet, this->inp_->lr_init_xc_kernel); break; default: throw std::invalid_argument("ESolver_LR: nspin must be 1 or 2"); @@ -776,7 +776,7 @@ void ModuleESolver::ESolver_LR::read_ks_wfc() this->pelec->ekb.create(this->kv.get_nks(), this->nbands); this->pelec->wg.create(this->kv.get_nks(), this->nbands); - if (input.ri_hartree_benchmark == "aims") // for aims benchmark + if (this->inp_->ri_hartree_benchmark == "aims") // for aims benchmark { #ifdef __EXX int ncore = 0; @@ -795,7 +795,7 @@ void ModuleESolver::ESolver_LR::read_ks_wfc() this->pelec->wg, this->kv.ik2iktot, this->kv.get_nkstot(), - input.nspin, + this->inp_->nspin, /*skip_bands=*/this->nocc_max - this->nocc_in)) { ModuleBase::WARNING_QUIT("ESolver_LR", "read ground-state wavefunction failed."); } diff --git a/source/source_esolver/esolver_lr_lcao_tddft.h b/source/source_esolver/esolver_lr_lcao_tddft.h index 16b684f7b79..ba1cc9418b0 100644 --- a/source/source_esolver/esolver_lr_lcao_tddft.h +++ b/source/source_esolver/esolver_lr_lcao_tddft.h @@ -19,6 +19,7 @@ #ifdef __EXX // #include #include "source_lcao/module_ri/exx_lri.h" +#include "source_hamilt/module_xc/exx_info.h" // for Exx_Info value member #endif namespace ModuleESolver { @@ -51,7 +52,6 @@ namespace ModuleESolver }; protected: - const Input_para& input; const std::string in_dir; const std::string out_dir; const UnitCell* ucell_ = nullptr; @@ -140,7 +140,7 @@ namespace ModuleESolver std::shared_ptr> exx_lri = nullptr; void move_exx_lri(std::shared_ptr>&); void move_exx_lri(std::shared_ptr>>&); - Exx_Info& exx_info; + Exx_Info exx_info; #endif }; } diff --git a/source/source_esolver/esolver_nep.cpp b/source/source_esolver/esolver_nep.cpp index c130a34ad89..fac612c3207 100644 --- a/source/source_esolver/esolver_nep.cpp +++ b/source/source_esolver/esolver_nep.cpp @@ -31,6 +31,8 @@ void ESolver_NEP::before_all_runners(BaseCell& basecell, const Input_para& inp) basecell.require_kind(BaseCell::Kind::unit_cell, __FUNCTION__); UnitCell& ucell = static_cast(basecell); + this->inp_ = &inp; + nep_potential = 0.0; nep_force.create(ucell.nat, 3); nep_virial.create(3, 3); @@ -184,7 +186,7 @@ void ESolver_NEP::cal_stress(BaseCell& basecell, ModuleBase::matrix& stress) // external stress double unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; - double external_stress[3] = {PARAM.inp.press1, PARAM.inp.press2, PARAM.inp.press3}; + double external_stress[3] = {this->inp_->press1, this->inp_->press2, this->inp_->press3}; for (int i = 0; i < 3; i++) { stress(i, i) -= external_stress[i] / unit_transform; diff --git a/source/source_esolver/esolver_of.cpp b/source/source_esolver/esolver_of.cpp index 8357ff2a9e7..11d73a7e14b 100644 --- a/source/source_esolver/esolver_of.cpp +++ b/source/source_esolver/esolver_of.cpp @@ -29,7 +29,7 @@ ESolver_OF::~ESolver_OF() delete psi_; delete[] this->pphi_; - for (int i = 0; i < PARAM.inp.nspin; ++i) + for (int i = 0; i < this->inp_->nspin; ++i) { delete[] this->pdirect_[i]; delete[] this->pdLdphi_[i]; @@ -95,7 +95,7 @@ void ESolver_OF::before_all_runners(BaseCell& basecell, const Input_para& inp) // calculate the total local pseudopotential in real space const int istep=0; elecstate::init_scf(ucell, Pgrid, sf.strucFac, locpp.numeric, istep, - PARAM.globalv.global_out_dir, PARAM.inp, this->pelec); + PARAM.globalv.global_out_dir, *this->inp_, this->pelec); // liuyu move here 2023-10-09 // D in uspp need vloc, thus behind init_scf() @@ -200,17 +200,17 @@ void ESolver_OF::before_opt(const int istep, UnitCell& ucell) this->init_elecstate(ucell); // Initialize KEDF - this->kedf_manager_->init(PARAM.inp, this->pw_rho, this->dV_, this->nelec_[0]); + this->kedf_manager_->init(*this->inp_, this->pw_rho, this->dV_, this->nelec_[0]); // Initialize optimization methods this->init_opt(); // Refresh the arrays delete this->psi_; - this->psi_ = new psi::Psi(1, PARAM.inp.nspin, + this->psi_ = new psi::Psi(1, this->inp_->nspin, this->pw_rho->nrxx, this->pw_rho->nrxx, true); - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { this->pphi_[is] = this->psi_->get_pointer(is); } @@ -219,9 +219,9 @@ void ESolver_OF::before_opt(const int istep, UnitCell& ucell) this->ptemp_rho_ = new Charge(); this->ptemp_rho_->set_rhopw(this->pw_rho); const bool kin_den = this->ptemp_rho_->kin_density(); // mohan add 20251202 - this->ptemp_rho_->allocate(PARAM.inp.nspin, kin_den); + this->ptemp_rho_->allocate(this->inp_->nspin, kin_den); - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { delete[] this->pdLdphi_[is]; delete[] this->pdEdphi_[is]; @@ -234,10 +234,10 @@ void ESolver_OF::before_opt(const int istep, UnitCell& ucell) } } - elecstate::init_scf(ucell, Pgrid, sf.strucFac, locpp.numeric, istep, PARAM.globalv.global_out_dir, PARAM.inp, this->pelec); + elecstate::init_scf(ucell, Pgrid, sf.strucFac, locpp.numeric, istep, PARAM.globalv.global_out_dir, *this->inp_, this->pelec); - const int nspin = PARAM.inp.nspin; - if (PARAM.inp.init_chg == "file") + const int nspin = this->inp_->nspin; + if (this->inp_->init_chg == "file") { Symmetry_rho::symmetrize_rho(nspin, this->chr, this->pw_rho, ucell.symm); for (int is = 0; is < nspin; ++is) @@ -288,14 +288,14 @@ void ESolver_OF::before_opt(const int istep, UnitCell& ucell) void ESolver_OF::update_potential(UnitCell& ucell) { // (1) get dL/dphi - unitcell::cal_ux(ucell, PARAM.inp.nspin); + unitcell::cal_ux(ucell, this->inp_->nspin); this->pelec->pot->update_from_charge(&this->chr, &ucell); // Hartree + XC + external this->kedf_manager_->get_potential(this->chr.rho, this->pphi_, this->pw_rho, this->pelec->pot->get_eff_v()); // KEDF potential - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { const double* vr_eff = this->pelec->pot->get_eff_v(is); for (int ir = 0; ir < this->pw_rho->nrxx; ++ir) @@ -317,12 +317,12 @@ void ESolver_OF::update_potential(UnitCell& ucell) // =========================================================================== this->normdLdphi_ = 0.; - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { this->normdLdphi_ += this->inner_product(this->pdLdphi_[is], this->pdLdphi_[is], this->pw_rho->nrxx, 1.0); } Parallel_Reduce::reduce_all(this->normdLdphi_); - this->normdLdphi_ = sqrt(this->normdLdphi_ / this->pw_rho->nxyz / PARAM.inp.nspin); + this->normdLdphi_ = sqrt(this->normdLdphi_ / this->pw_rho->nxyz / this->inp_->nspin); } /** @@ -335,8 +335,8 @@ void ESolver_OF::optimize(UnitCell& ucell) // (1) get |d0> with optimization algorithm this->get_direction(ucell); // initialize temp_phi and temp_rho used in line search - double** ptemp_phi = new double*[PARAM.inp.nspin]; - for (int is = 0; is < PARAM.inp.nspin; ++is) + double** ptemp_phi = new double*[this->inp_->nspin]; + for (int is = 0; is < this->inp_->nspin; ++is) { ptemp_phi[is] = new double[this->pw_rho->nrxx]; for (int ir = 0; ir < this->pw_rho->nrxx; ++ir) @@ -350,8 +350,8 @@ void ESolver_OF::optimize(UnitCell& ucell) this->adjust_direction(); // (3) make sure that dEdtheta<0 at theta = 0 - double* dEdtheta = new double[PARAM.inp.nspin]; // dE/dtheta of tempPhi - ModuleBase::GlobalFunc::ZEROS(dEdtheta, PARAM.inp.nspin); + double* dEdtheta = new double[this->inp_->nspin]; // dE/dtheta of tempPhi + ModuleBase::GlobalFunc::ZEROS(dEdtheta, this->inp_->nspin); this->check_direction(dEdtheta, ptemp_phi, ucell); // this->test_direction(dEdtheta, ptemp_phi, ucell); @@ -359,7 +359,7 @@ void ESolver_OF::optimize(UnitCell& ucell) // (4) call line search to find the best theta (step length) this->get_step_length(dEdtheta, ptemp_phi, ucell); - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { delete[] ptemp_phi[is]; } @@ -374,7 +374,7 @@ void ESolver_OF::optimize(UnitCell& ucell) */ void ESolver_OF::update_rho() { - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { for (int ir = 0; ir < this->pw_rho->nrxx; ++ir) { @@ -387,7 +387,7 @@ void ESolver_OF::update_rho() // if (ModuleSymmetry::Symmetry::symm_flag == 1) // { // Symmetry_rho srho; - // for (int is = 0; is < PARAM.inp.nspin; is++) + // for (int is = 0; is < this->inp_->nspin; is++) // { // srho.begin(is, *(this->chr), this->pw_rho, Pgrid, ucell.symm); // for (int ibs = 0; ibs < this->pw_rho->nrxx; ++ibs) @@ -468,7 +468,7 @@ void ESolver_OF::after_opt(const int istep, UnitCell& ucell, const bool conv_eso //------------------------------------------------------------------ // 1) calculate kinetic energy density and ELF //------------------------------------------------------------------ - if (PARAM.inp.out_elf[0] > 0) + if (this->inp_->out_elf[0] > 0) { this->kedf_manager_->get_energy_density(this->chr.rho, this->pphi_, this->pw_rho, this->chr.kin_r); } @@ -488,7 +488,7 @@ void ESolver_OF::after_opt(const int istep, UnitCell& ucell, const bool conv_eso //------------------------------------------------------------------ // Generate data if needed //------------------------------------------------------------------ - if (PARAM.inp.of_ml_gene_data) + if (this->inp_->of_ml_gene_data) { this->pelec->pot->update_from_charge(&this->chr, &ucell); // Hartree + XC + external this->kedf_manager_->get_potential(this->chr.rho, @@ -534,7 +534,7 @@ double ESolver_OF::cal_energy() this->pelec->cal_energies(2); double kinetic_energy = this->kedf_manager_->get_energy(); // kinetic energy double pseudopot_energy = 0.; // electron-ion interaction energy - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { pseudopot_energy += this->inner_product(this->pelec->pot->get_fixed_v(), this->chr.rho[is], diff --git a/source/source_esolver/esolver_of_interface.cpp b/source/source_esolver/esolver_of_interface.cpp index 1c507e7a95f..4240db9b94c 100644 --- a/source/source_esolver/esolver_of_interface.cpp +++ b/source/source_esolver/esolver_of_interface.cpp @@ -41,10 +41,10 @@ void ESolver_OF::init_opt() } // optimize theta if nspin=2 - if (PARAM.inp.nspin == 2) + if (this->inp_->nspin == 2) { this->opt_cg_mag_ = new ModuleBase::Opt_CG; - this->opt_cg_mag_->allocate(PARAM.inp.nspin); + this->opt_cg_mag_->allocate(this->inp_->nspin); } } @@ -59,7 +59,7 @@ void ESolver_OF::cal_potential_wrapper(double* ptemp_phi, double* rdLdphi) */ void ESolver_OF::get_direction(UnitCell& ucell) { - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { if (this->of_method_ == "tn") { @@ -104,7 +104,7 @@ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& double kinetic_energy = 0.0; // kinetic energy double pseudopot_energy = 0.0; // electron-ion interaction energy - if (PARAM.inp.nspin == 1) + if (this->inp_->nspin == 1) { int numDC = 0; // iteration number of line search strcpy(this->task_, "START"); @@ -164,16 +164,16 @@ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& } } } - else if (PARAM.inp.nspin == 2) + else if (this->inp_->nspin == 2) { ModuleBase::WARNING_QUIT("esolver_of", "Sorry, SPIN2 case is not supported by OFDFT for now."); // ========================== Under testing ========================== // this->opt_cg_mag_->refresh(); - // double *pthetaDir = new double[PARAM.inp.nspin]; - // double *temp_theta = new double[PARAM.inp.nspin]; - // ModuleBase::GlobalFunc::ZEROS(pthetaDir, PARAM.inp.nspin); - // ModuleBase::GlobalFunc::ZEROS(temp_theta, PARAM.inp.nspin); + // double *pthetaDir = new double[this->inp_->nspin]; + // double *temp_theta = new double[this->inp_->nspin]; + // ModuleBase::GlobalFunc::ZEROS(pthetaDir, this->inp_->nspin); + // ModuleBase::GlobalFunc::ZEROS(temp_theta, this->inp_->nspin); // double thetaAlpha = 0.; // double alphaTol = 1e-4; // double maxThetaDir = 0.; @@ -189,7 +189,7 @@ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& // if (dEdalpha >= 0.) // { - // for (int is = 0; is < PARAM.inp.nspin; ++is) + // for (int is = 0; is < this->inp_->nspin; ++is) // { // pthetaDir[is] = -dEdtheta[is]; // } @@ -209,7 +209,7 @@ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& // this->pelec->f_en.calculate_etot(this->pw_rho->nrxx, // if (strncmp(this->task_, "FG", 2) == 0) // { - // for (int is = 0; is < PARAM.inp.nspin; ++is) + // for (int is = 0; is < this->inp_->nspin; ++is) // { // temp_theta[is] = this->theta_[is] + thetaAlpha * // pthetaDir[is]; for (int ir = 0; ir < @@ -251,7 +251,7 @@ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& // } // } - // for (int is = 0; is < PARAM.inp.nspin; ++is) this->theta_[is] + // for (int is = 0; is < this->inp_->nspin; ++is) this->theta_[is] // += thetaAlpha * pthetaDir[is]; if (sqrt(dEdtheta[0] * // dEdtheta[0] + dEdtheta[1] * dEdtheta[1]) < alphaTol) break; // thetaIter++; @@ -261,7 +261,7 @@ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& // delete[] pthetaDir; // ========================== Under testing ========================== } - else if (PARAM.inp.nspin == 4) + else if (this->inp_->nspin == 4) { ModuleBase::WARNING_QUIT("esolver_of", "Sorry, SPIN4 case is not supported by OFDFT for now."); } diff --git a/source/source_esolver/esolver_of_tddft.cpp b/source/source_esolver/esolver_of_tddft.cpp index 47ef2ad6290..e4ed2ba66d4 100644 --- a/source/source_esolver/esolver_of_tddft.cpp +++ b/source/source_esolver/esolver_of_tddft.cpp @@ -43,11 +43,11 @@ void ESolver_OF_TDDFT::runner(BaseCell& basecell, const int istep) if (this->phi_td.empty()) { - const int size = PARAM.inp.nspin * this->pw_rho->nrxx; + const int size = this->inp_->nspin * this->pw_rho->nrxx; this->phi_td.resize(size, std::complex(0.0, 0.0)); } - if ((istep==0) && PARAM.inp.init_chg != "file") + if ((istep==0) && this->inp_->init_chg != "file") { while (true) { @@ -80,7 +80,7 @@ void ESolver_OF_TDDFT::runner(BaseCell& basecell, const int istep) #ifdef _OPENMP #pragma omp parallel for collapse(2) #endif - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { for (int ir = 0; ir < this->pw_rho->nrxx; ++ir) { @@ -88,12 +88,12 @@ void ESolver_OF_TDDFT::runner(BaseCell& basecell, const int istep) } } } - else if ((istep==0) && PARAM.inp.init_chg == "file") + else if ((istep==0) && this->inp_->init_chg == "file") { #ifdef _OPENMP #pragma omp parallel for collapse(2) #endif - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { for (int ir = 0; ir < this->pw_rho->nrxx; ++ir) { @@ -108,7 +108,7 @@ void ESolver_OF_TDDFT::runner(BaseCell& basecell, const int istep) #ifdef _OPENMP #pragma omp parallel for collapse(2) #endif - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { for (int ir = 0; ir < this->pw_rho->nrxx; ++ir) { diff --git a/source/source_esolver/esolver_of_tool.cpp b/source/source_esolver/esolver_of_tool.cpp index 59f8cea33ea..5656f88223b 100644 --- a/source/source_esolver/esolver_of_tool.cpp +++ b/source/source_esolver/esolver_of_tool.cpp @@ -32,29 +32,29 @@ void ESolver_OF::init_elecstate(UnitCell& ucell) &(this->pelec->f_en.vtxc)); // There is no Operator in ESolver_OF, register Potentials here! std::vector pot_register_in; - if (PARAM.inp.vion_in_h) + if (this->inp_->vion_in_h) { pot_register_in.push_back("local"); } - if (PARAM.inp.vh_in_h) + if (this->inp_->vh_in_h) { pot_register_in.push_back("hartree"); } // no variable can choose xc, maybe it is necessary pot_register_in.push_back("xc"); - if (PARAM.inp.imp_sol) + if (this->inp_->imp_sol) { pot_register_in.push_back("surchem"); } - if (PARAM.inp.efield_flag) + if (this->inp_->efield_flag) { pot_register_in.push_back("efield"); } - if (PARAM.inp.gate_flag) + if (this->inp_->gate_flag) { pot_register_in.push_back("gatefield"); } - if (PARAM.inp.ml_exx) + if (this->inp_->ml_exx) { pot_register_in.push_back("ml_exx"); } @@ -73,13 +73,13 @@ void ESolver_OF::allocate_array() { // Initialize the "wavefunction", which is sqrt(rho) this->psi_ = new psi::Psi(1, - PARAM.inp.nspin, + this->inp_->nspin, this->pw_rho->nrxx, this->pw_rho->nrxx, true); - ModuleBase::Memory::record("OFDFT::Psi", sizeof(double) * PARAM.inp.nspin * this->pw_rho->nrxx); - this->pphi_ = new double*[PARAM.inp.nspin]; - for (int is = 0; is < PARAM.inp.nspin; ++is) + ModuleBase::Memory::record("OFDFT::Psi", sizeof(double) * this->inp_->nspin * this->pw_rho->nrxx); + this->pphi_ = new double*[this->inp_->nspin]; + for (int is = 0; is < this->inp_->nspin; ++is) { this->pphi_[is] = this->psi_->get_pointer(is); } @@ -90,25 +90,25 @@ void ESolver_OF::allocate_array() this->ptemp_rho_ = new Charge(); this->ptemp_rho_->set_rhopw(this->pw_rho); const bool kin_den = this->ptemp_rho_->kin_density(); // mohan add 20251202 - this->ptemp_rho_->allocate(PARAM.inp.nspin, kin_den); + this->ptemp_rho_->allocate(this->inp_->nspin, kin_den); - this->theta_ = new double[PARAM.inp.nspin]; - this->pdLdphi_ = new double*[PARAM.inp.nspin]; - this->pdEdphi_ = new double*[PARAM.inp.nspin]; - this->pdirect_ = new double*[PARAM.inp.nspin]; - this->precip_dir_ = new std::complex*[PARAM.inp.nspin]; + this->theta_ = new double[this->inp_->nspin]; + this->pdLdphi_ = new double*[this->inp_->nspin]; + this->pdEdphi_ = new double*[this->inp_->nspin]; + this->pdirect_ = new double*[this->inp_->nspin]; + this->precip_dir_ = new std::complex*[this->inp_->nspin]; - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { this->pdLdphi_[is] = new double[this->pw_rho->nrxx]; this->pdEdphi_[is] = new double[this->pw_rho->nrxx]; this->pdirect_[is] = new double[this->pw_rho->nrxx]; this->precip_dir_[is] = new std::complex[pw_rho->npw]; } - ModuleBase::Memory::record("OFDFT::pdLdphi_", sizeof(double) * PARAM.inp.nspin * this->pw_rho->nrxx); - ModuleBase::Memory::record("OFDFT::pdEdphi_", sizeof(double) * PARAM.inp.nspin * this->pw_rho->nrxx); - ModuleBase::Memory::record("OFDFT::pdirect_", sizeof(double) * PARAM.inp.nspin * this->pw_rho->nrxx); - ModuleBase::Memory::record("OFDFT::precip_dir_", sizeof(std::complex) * PARAM.inp.nspin * this->pw_rho->npw); + ModuleBase::Memory::record("OFDFT::pdLdphi_", sizeof(double) * this->inp_->nspin * this->pw_rho->nrxx); + ModuleBase::Memory::record("OFDFT::pdEdphi_", sizeof(double) * this->inp_->nspin * this->pw_rho->nrxx); + ModuleBase::Memory::record("OFDFT::pdirect_", sizeof(double) * this->inp_->nspin * this->pw_rho->nrxx); + ModuleBase::Memory::record("OFDFT::precip_dir_", sizeof(std::complex) * this->inp_->nspin * this->pw_rho->npw); } /** @@ -120,10 +120,10 @@ void ESolver_OF::allocate_array() */ void ESolver_OF::cal_potential(double* ptemp_phi, double* rdLdphi, UnitCell& ucell) { - double** dEdtemp_phi = new double*[PARAM.inp.nspin]; - double** temp_phi = new double*[PARAM.inp.nspin]; + double** dEdtemp_phi = new double*[this->inp_->nspin]; + double** temp_phi = new double*[this->inp_->nspin]; - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { dEdtemp_phi[is] = new double[this->pw_rho->nrxx]; if (is == this->tn_spin_flag_) @@ -140,7 +140,7 @@ void ESolver_OF::cal_potential(double* ptemp_phi, double* rdLdphi, UnitCell& uce } } - unitcell::cal_ux(ucell, PARAM.inp.nspin); + unitcell::cal_ux(ucell, this->inp_->nspin); this->pelec->pot->update_from_charge(this->ptemp_rho_, &ucell); ModuleBase::matrix& vr_eff = this->pelec->pot->get_eff_v(); @@ -157,7 +157,7 @@ void ESolver_OF::cal_potential(double* ptemp_phi, double* rdLdphi, UnitCell& uce { rdLdphi[i] = dEdtemp_phi[this->tn_spin_flag_][i] - 2. * temp_mu * ptemp_phi[i]; } - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { delete[] dEdtemp_phi[is]; } @@ -180,7 +180,7 @@ void ESolver_OF::cal_dEdtheta(double** ptemp_phi, Charge* temp_rho, UnitCell& uc { double* dphi_dtheta = new double[this->pw_rho->nrxx]; - unitcell::cal_ux(ucell, PARAM.inp.nspin); + unitcell::cal_ux(ucell, this->inp_->nspin); this->pelec->pot->update_from_charge(temp_rho, &ucell); ModuleBase::matrix& vr_eff = this->pelec->pot->get_eff_v(); @@ -188,7 +188,7 @@ void ESolver_OF::cal_dEdtheta(double** ptemp_phi, Charge* temp_rho, UnitCell& uc ptemp_phi, this->pw_rho, vr_eff); // KEDF potential - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { for (int ir = 0; ir < this->pw_rho->nrxx; ++ir) { @@ -225,16 +225,16 @@ double ESolver_OF::cal_mu(double* pphi, double* pdEdphi, double nelec) void ESolver_OF::adjust_direction(void) { // filter the high frequency term in direction if of_full_pw = false - if (!PARAM.inp.of_full_pw) + if (!this->inp_->of_full_pw) { - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { pw_rho->real2recip(this->pdirect_[is], this->precip_dir_[is]); pw_rho->recip2real(this->precip_dir_[is], this->pdirect_[is]); } } - if (PARAM.inp.nspin == 1) + if (this->inp_->nspin == 1) { double temp_theta = 0; // temp_theta = |d'|/|d0 + phi|, theta = min(theta, temp_theta) @@ -265,9 +265,9 @@ void ESolver_OF::adjust_direction(void) temp_theta = norm_direction / temp_theta; this->theta_[0] = std::min(this->theta_[0], temp_theta); } - else if (PARAM.inp.nspin == 2) // theta = 0 + else if (this->inp_->nspin == 2) // theta = 0 { - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { // (1) make direction orthogonal to phi // |d'> = |d0> - |phi>/nelec @@ -305,15 +305,15 @@ void ESolver_OF::adjust_direction(void) */ void ESolver_OF::check_direction(double* dEdtheta, double** ptemp_phi, UnitCell& ucell) { - assert(PARAM.inp.nspin > 0); - double* temp_theta = new double[PARAM.inp.nspin]; - ModuleBase::GlobalFunc::ZEROS(temp_theta, PARAM.inp.nspin); + assert(this->inp_->nspin > 0); + double* temp_theta = new double[this->inp_->nspin]; + ModuleBase::GlobalFunc::ZEROS(temp_theta, this->inp_->nspin); double max_dEdtheta = 1e5; // threshould of dEdtheta, avoid the unstable optimization this->cal_dEdtheta(ptemp_phi, this->ptemp_rho_, ucell, temp_theta, dEdtheta); // Assert dEdtheta(theta = 0) < 0, otherwise line search will not work. - for (int is = 0; is < PARAM.inp.nspin; ++is) + for (int is = 0; is < this->inp_->nspin; ++is) { if (dEdtheta[is] > max_dEdtheta) { diff --git a/source/source_esolver/esolver_sdft_pw.cpp b/source/source_esolver/esolver_sdft_pw.cpp index c11ca41182f..808fbbe035c 100644 --- a/source/source_esolver/esolver_sdft_pw.cpp +++ b/source/source_esolver/esolver_sdft_pw.cpp @@ -19,7 +19,6 @@ namespace ModuleESolver template ESolver_SDFT_PW::ESolver_SDFT_PW() - : stoche(PARAM.inp.nche_sto, PARAM.inp.method_sto, PARAM.inp.emax_sto, PARAM.inp.emin_sto) { this->classname = "ESolver_SDFT_PW"; this->basisname = "PW"; @@ -42,6 +41,7 @@ void ESolver_SDFT_PW::before_all_runners(BaseCell& basecell, const In // 1) initialize parameters from int Input class this->nche_sto = inp.nche_sto; this->method_sto = inp.method_sto; + this->stoche.init(inp.nche_sto, inp.method_sto, inp.emax_sto, inp.emin_sto); // 2) run "before_all_runners" in ESolver_KS ESolver_KS_PW::before_all_runners(ucell, inp); @@ -109,9 +109,9 @@ void ESolver_SDFT_PW::before_scf(UnitCell& ucell, const int istep) &this->stoche.emax_sto); this->p_hamilt_sto = static_cast*>(this->p_hamilt); - if (istep > 0 && PARAM.inp.nbands_sto != 0 && PARAM.inp.initsto_freq > 0 && istep % PARAM.inp.initsto_freq == 0) + if (istep > 0 && this->inp_->nbands_sto != 0 && this->inp_->initsto_freq > 0 && istep % this->inp_->initsto_freq == 0) { - this->stowf.update_sto_orbitals(PARAM.inp.seed_sto); + this->stowf.update_sto_orbitals(this->inp_->seed_sto); } ModuleBase::timer::end("ESolver_SDFT_PW", "before_scf"); @@ -147,9 +147,9 @@ void ESolver_SDFT_PW::hamilt2rho_single(UnitCell& ucell, int istep, i this->pelec->f_en.demet = 0.0; // setup diagonalization parameters for SDFT - hsolver::setup_diago_params_sdft(istep, iter, ethr, PARAM.inp); + hsolver::setup_diago_params_sdft(istep, iter, ethr, *this->inp_); - bool skip_charge = PARAM.inp.calculation == "nscf" ? true : false; + bool skip_charge = this->inp_->calculation == "nscf" ? true : false; // hsolver only exists in this function hsolver::HSolverPW_SDFT hsolver_pw_sdft_obj(&this->kv, @@ -157,23 +157,23 @@ void ESolver_SDFT_PW::hamilt2rho_single(UnitCell& ucell, int istep, i this->stowf, this->stoche, this->p_hamilt_sto, - PARAM.inp.calculation, - PARAM.inp.basis_type, - PARAM.inp.ks_solver, + this->inp_->calculation, + this->inp_->basis_type, + this->inp_->ks_solver, PARAM.globalv.use_uspp, - PARAM.inp.nspin, + this->inp_->nspin, hsolver::DiagoIterAssist::SCF_ITER, hsolver::DiagoIterAssist::PW_DIAG_NMAX, hsolver::DiagoIterAssist::PW_DIAG_THR, hsolver::DiagoIterAssist::need_subspace, - PARAM.inp.nbands, - PARAM.inp.diago_smooth_ethr, - PARAM.inp.pw_diag_ndim, - PARAM.inp.diag_subspace, - PARAM.inp.nb2d, + this->inp_->nbands, + this->inp_->diago_smooth_ethr, + this->inp_->pw_diag_ndim, + this->inp_->diag_subspace, + this->inp_->nb2d, PARAM.globalv.ks_run, PARAM.globalv.all_ks_run, - PARAM.inp.bndpar); + this->inp_->bndpar); hsolver_pw_sdft_obj.solve(ucell, static_cast*>(this->p_hamilt), @@ -191,7 +191,7 @@ void ESolver_SDFT_PW::hamilt2rho_single(UnitCell& ucell, int istep, i if (PARAM.globalv.ks_run) { - Symmetry_rho::symmetrize_rho(PARAM.inp.nspin, this->chr, this->pw_rho, ucell.symm); + Symmetry_rho::symmetrize_rho(this->inp_->nspin, this->chr, this->pw_rho, ucell.symm); this->pelec->f_en.deband = this->pelec->cal_delta_eband(ucell); } else @@ -275,7 +275,7 @@ void ESolver_SDFT_PW::after_all_runners(BaseCell& basecell) } // 3) write down DOS - if (PARAM.inp.out_dos) + if (this->inp_->out_dos) { if (!std::is_same>::value || !std::is_same::value) { @@ -289,19 +289,19 @@ void ESolver_SDFT_PW::after_all_runners(BaseCell& basecell) reinterpret_cast>*>(this->p_hamilt), this->stoche, reinterpret_cast, base_device::DEVICE_CPU>*>(&stowf)); - sto_dos.decide_param(PARAM.inp.dos_nche, - PARAM.inp.emin_sto, - PARAM.inp.emax_sto, + sto_dos.decide_param(this->inp_->dos_nche, + this->inp_->emin_sto, + this->inp_->emax_sto, PARAM.globalv.dos_setemin, PARAM.globalv.dos_setemax, - PARAM.inp.dos_emin_ev, - PARAM.inp.dos_emax_ev, - PARAM.inp.dos_scale); - sto_dos.caldos(PARAM.inp.dos_sigma, PARAM.inp.dos_edelta_ev, PARAM.inp.npart_sto); + this->inp_->dos_emin_ev, + this->inp_->dos_emax_ev, + this->inp_->dos_scale); + sto_dos.caldos(this->inp_->dos_sigma, this->inp_->dos_edelta_ev, this->inp_->npart_sto); } // 4) sKG cost memory, and it should be placed at the end of the program - if (PARAM.inp.cal_cond) + if (this->inp_->cal_cond) { Sto_EleCond sto_elecond( &ucell, @@ -313,14 +313,14 @@ void ESolver_SDFT_PW::after_all_runners(BaseCell& basecell) static_cast, Device>*>(this->p_hamilt), this->stoche, &stowf); - sto_elecond.decide_nche(PARAM.inp.cond_dt, 1e-8, this->nche_sto, PARAM.inp.emin_sto, PARAM.inp.emax_sto); - sto_elecond.sKG(PARAM.inp.cond_smear, - PARAM.inp.cond_fwhm, - PARAM.inp.cond_wcut, - PARAM.inp.cond_dw, - PARAM.inp.cond_dt, - PARAM.inp.cond_nonlocal, - PARAM.inp.npart_sto); + sto_elecond.decide_nche(this->inp_->cond_dt, 1e-8, this->nche_sto, this->inp_->emin_sto, this->inp_->emax_sto); + sto_elecond.sKG(this->inp_->cond_smear, + this->inp_->cond_fwhm, + this->inp_->cond_wcut, + this->inp_->cond_dw, + this->inp_->cond_dt, + this->inp_->cond_nonlocal, + this->inp_->npart_sto); } } diff --git a/source/source_esolver/lcao_others.cpp b/source/source_esolver/lcao_others.cpp index ccae19902b7..961c0302e5c 100644 --- a/source/source_esolver/lcao_others.cpp +++ b/source/source_esolver/lcao_others.cpp @@ -37,7 +37,7 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) ModuleBase::TITLE("ESolver_KS_LCAO", "others"); ModuleBase::timer::start("ESolver_KS_LCAO", "others"); - const std::string cal_type = PARAM.inp.calculation; + const std::string cal_type = this->inp_->calculation; if (cal_type == "test_memory") { @@ -56,13 +56,13 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) { // test_search_neighbor(); std::cout << FmtCore::format("\n * * * * * *\n << Start %s.\n", "testing neighbour"); - double search_radius = PARAM.inp.search_radius; + double search_radius = this->inp_->search_radius; atom_arrange::search(PARAM.globalv.search_pbc, GlobalV::ofs_running, this->gd, ucell, search_radius, - PARAM.inp.test_atom_input, + this->inp_->test_atom_input, true); std::cout << FmtCore::format(" >> Finish %s.\n * * * * * *\n", "testing neighbour"); return; @@ -75,7 +75,7 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) // 1. prepare HS matrices, prepare grid integral // (1) Find adjacent atoms for each atom. double search_radius = atom_arrange::set_sr_NL(GlobalV::ofs_running, - PARAM.inp.out_level, + this->inp_->out_level, orb_.get_rcutmax_Phi(), ucell.infoNL->get_rcutmax_Beta(), PARAM.globalv.gamma_only_local); @@ -85,7 +85,7 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) this->gd, ucell, search_radius, - PARAM.inp.test_atom_input); + this->inp_->test_atom_input); // (3) Periodic condition search for each grid. gint_info_.reset(new ModuleGint::GintInfo(this->pw_big->nbx, @@ -139,26 +139,27 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) &this->dftu, this->deepks, istep, - this->exx_nao); + this->exx_nao, + this->exx_info_); } // for each ionic step, the overlap must be rebuilt // since it depends on ionic positions - this->deepks.build_overlap(ucell, orb_, pv, gd, *(two_center_bundle_.overlap_orb_alpha), PARAM.inp); + this->deepks.build_overlap(ucell, orb_, pv, gd, *(two_center_bundle_.overlap_orb_alpha), *this->inp_); - if (PARAM.inp.sc_mag_switch) + if (this->inp_->sc_mag_switch) { spinconstrain::SpinConstrain& sc = spinconstrain::SpinConstrain::getScInstance(); - sc.init_sc(PARAM.inp.sc_thr, - PARAM.inp.nsc, - PARAM.inp.nsc_min, - PARAM.inp.alpha_trial, - PARAM.inp.sccut, - PARAM.inp.sc_drop_thr, + sc.init_sc(this->inp_->sc_thr, + this->inp_->nsc, + this->inp_->nsc_min, + this->inp_->alpha_trial, + this->inp_->sccut, + this->inp_->sc_drop_thr, ucell, - PARAM.inp.sc_direction_only, + this->inp_->sc_direction_only, &(this->pv), - PARAM.inp.nspin, + this->inp_->nspin, this->kv, this->p_hamilt, this->psi, @@ -170,11 +171,11 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) // cal_ux should be called before init_scf because // the direction of ux is used in noncoline_rho //========================================================= - unitcell::cal_ux(ucell, PARAM.inp.nspin); + unitcell::cal_ux(ucell, this->inp_->nspin); // pelec should be initialized before these calculations elecstate::init_scf(ucell, this->Pgrid, this->sf.strucFac, this->locpp.numeric, - istep, PARAM.globalv.global_out_dir, PARAM.inp, this->pelec); + istep, PARAM.globalv.global_out_dir, *this->inp_, this->pelec); // self consistent calculations for electronic ground state if (cal_type == "get_pchg") @@ -187,10 +188,10 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) this->pelec->wg, this->pelec->eferm.get_all_ef(), this->pw_rhod->nrxx, - PARAM.inp.out_pchg, - PARAM.inp.nbands, - PARAM.inp.nelec, - PARAM.inp.nspin, + this->inp_->out_pchg, + this->inp_->nbands, + this->inp_->nelec, + this->inp_->nspin, &ucell, this->Pgrid, &this->gd, @@ -206,17 +207,17 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) this->pelec->eferm.get_all_ef(), this->pw_rhod, this->pw_rhod->nrxx, - PARAM.inp.out_pchg, - PARAM.inp.nbands, - PARAM.inp.nelec, - PARAM.inp.nspin, + this->inp_->out_pchg, + this->inp_->nbands, + this->inp_->nelec, + this->inp_->nspin, &ucell, this->Pgrid, &this->gd, this->kv, PARAM.globalv.global_out_dir, GlobalV::ofs_running, - PARAM.inp.if_separate_k, + this->inp_->if_separate_k, this->chr.ngmc); } std::cout << FmtCore::format(" >> Finish %s.\n * * * * * *\n", "getting partial charge"); @@ -232,13 +233,13 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) this->pw_wfc, this->Pgrid, this->pv, - PARAM.inp.out_wfc_pw, + this->inp_->out_wfc_pw, this->kv, - PARAM.inp.nelec, - PARAM.inp.out_wfc_norm, - PARAM.inp.out_wfc_re_im, - PARAM.inp.nbands, - PARAM.inp.nspin, + this->inp_->nelec, + this->inp_->out_wfc_norm, + this->inp_->out_wfc_re_im, + this->inp_->nbands, + this->inp_->nspin, PARAM.globalv.nlocal, PARAM.globalv.global_out_dir, GlobalV::ofs_running); @@ -250,13 +251,13 @@ void ESolver_KS_LCAO::others(BaseCell& basecell, const int istep) this->pw_wfc, this->Pgrid, this->pv, - PARAM.inp.out_wfc_pw, + this->inp_->out_wfc_pw, this->kv, - PARAM.inp.nelec, - PARAM.inp.out_wfc_norm, - PARAM.inp.out_wfc_re_im, - PARAM.inp.nbands, - PARAM.inp.nspin, + this->inp_->nelec, + this->inp_->out_wfc_norm, + this->inp_->out_wfc_re_im, + this->inp_->nbands, + this->inp_->nspin, PARAM.globalv.nlocal, PARAM.globalv.global_out_dir, GlobalV::ofs_running); diff --git a/source/source_esolver/pw_others.cpp b/source/source_esolver/pw_others.cpp index ebb2662ca6e..9048191e549 100644 --- a/source/source_esolver/pw_others.cpp +++ b/source/source_esolver/pw_others.cpp @@ -17,7 +17,7 @@ void ESolver_KS_PW::others(BaseCell& basecell, const int istep) ModuleBase::TITLE("ESolver_KS_PW", "others"); - const std::string cal_type = PARAM.inp.calculation; + const std::string cal_type = this->inp_->calculation; if (cal_type == "test_memory") { @@ -34,9 +34,9 @@ void ESolver_KS_PW::others(BaseCell& basecell, const int istep) Numerical_Descriptor nc; nc.output_descriptor(ucell, *(this->stp.psi_cpu), - PARAM.inp.bessel_descriptor_lmax, - PARAM.inp.bessel_descriptor_rcut, - PARAM.inp.bessel_descriptor_tolerence, + this->inp_->bessel_descriptor_lmax, + this->inp_->bessel_descriptor_rcut, + this->inp_->bessel_descriptor_tolerence, this->kv.get_nks()); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "GENERATE DESCRIPTOR FOR DEEPKS"); } diff --git a/source/source_hamilt/module_xc/coulomb_config.h b/source/source_hamilt/module_xc/coulomb_config.h new file mode 100644 index 00000000000..702686c848f --- /dev/null +++ b/source/source_hamilt/module_xc/coulomb_config.h @@ -0,0 +1,21 @@ +#ifndef COULOMB_CONFIG_H +#define COULOMB_CONFIG_H + +#include +#include +#include + +namespace Conv_Coulomb_Pot_K +{ + enum class Coulomb_Type{Fock, Erfc}; + enum class Ccp_Type{ // parameter: + Ccp, // + Hf, // "hf_Rcut" + Erfc, // "hse_omega" + Erf}; // "hse_omega", "hf_Rcut" + enum class Coulomb_Method{Center2, Ewald}; // Different methods for constructing the Coulomb matrix. +} + +using CoulombParam = std::map>>; + +#endif // COULOMB_CONFIG_H diff --git a/source/source_hamilt/module_xc/exx_info.cpp b/source/source_hamilt/module_xc/exx_info.cpp index 84168910529..923fef63d44 100644 --- a/source/source_hamilt/module_xc/exx_info.cpp +++ b/source/source_hamilt/module_xc/exx_info.cpp @@ -1,9 +1,234 @@ #include "exx_info.h" +#include "general_exx_info.h" + +#include "source_io/module_parameter/input_parameter.h" +#include "source_base/global_function.h" + +#include +#include +#include +#include //---------------------------------------------------------- -// init "GLOBAL CLASS" object +// Initialize General_Exx_Info from input parameters. +// Extracted from init_exx_info to allow PW modules to use +// a lightweight config without depending on Exx_Info. +// Peize Lin add 2018-06-20, refactored 2026. //---------------------------------------------------------- -namespace GlobalC +bool init_general_exx_info(General_Exx_Info& info, const Input_para& inp) { - Exx_Info exx_info; -} \ No newline at end of file + std::string dft_functional_lower = inp.dft_functional; + std::transform(inp.dft_functional.begin(), + inp.dft_functional.end(), + dft_functional_lower.begin(), + tolower); + bool generate_opt_orb = false; + if (dft_functional_lower == "hf" + || dft_functional_lower == "pbe0" || dft_functional_lower == "b3lyp" || dft_functional_lower == "hse" + || dft_functional_lower == "scan0" + || dft_functional_lower == "muller" || dft_functional_lower == "power" + || dft_functional_lower == "cwp22" || dft_functional_lower == "wp22" + || dft_functional_lower == "lc_pbe" + || dft_functional_lower == "lc_wpbe" + || dft_functional_lower == "lrc_wpbe" + || dft_functional_lower == "lrc_wpbeh" + || dft_functional_lower == "cam_pbeh") + { + info.cal_exx = true; + + info.hybrid_alpha = 0; + std::vector fock_alpha(inp.exx_fock_alpha.size()); + for(std::size_t i=0; i erfc_alpha(inp.exx_erfc_alpha.size()); + for(std::size_t i=0; i0); + for(std::size_t i=0; i -#include -#include -#include - -struct Exx_Info_Global +/// Backward-compatible alias: Exx_Info_Global inherits all members +/// from General_Exx_Info without adding anything. +struct Exx_Info_Global : public General_Exx_Info { - bool cal_exx = false; - - std::map>> coulomb_param; - - // Fock: - // "alpha": "0" - // "singularity_correction": "limits" / "spencer" / "revised_spencer" / "massidda" / "carrier" - // "lambda": "0.3" - // "Rcut" - // Erfc: - // "alpha": "0" - // "omega": "0.11" - // "singularity_correction": "limits" / "spencer" / "revised_spencer" - // "Rcut" - - Conv_Coulomb_Pot_K::Ccp_Type ccp_type; - double hybrid_alpha = 0.25; - double hse_omega = 0.11; - double mixing_beta_for_loop1 = 1.0; - - bool separate_loop = true; - size_t hybrid_step = 1; }; #endif \ No newline at end of file diff --git a/source/source_hamilt/module_xc/exx_info_lip.h b/source/source_hamilt/module_xc/exx_info_lip.h index ed12840250f..23085b90754 100644 --- a/source/source_hamilt/module_xc/exx_info_lip.h +++ b/source/source_hamilt/module_xc/exx_info_lip.h @@ -1,7 +1,7 @@ #ifndef EXX_INFO_LIP_H #define EXX_INFO_LIP_H -#include "source_lcao/module_ri/conv_coulomb_pot_k.h" +#include "source_hamilt/module_xc/coulomb_config.h" struct Exx_Info_Lip { diff --git a/source/source_hamilt/module_xc/general_exx_info.h b/source/source_hamilt/module_xc/general_exx_info.h new file mode 100644 index 00000000000..9ab1d6ec33e --- /dev/null +++ b/source/source_hamilt/module_xc/general_exx_info.h @@ -0,0 +1,43 @@ +#ifndef GENERAL_EXX_INFO_H +#define GENERAL_EXX_INFO_H + +#include "coulomb_config.h" + +#include + +/// General EXX configuration, independent of basis type. +/// Contains the fields needed by both PW and LCAO EXX calculations. +struct General_Exx_Info +{ + bool cal_exx = false; + + CoulombParam coulomb_param; + + // Fock: + // "alpha": "0" + // "singularity_correction": "limits" / "spencer" / "revised_spencer" / "massidda" / "carrier" + // "lambda": "0.3" + // "Rcut" + // Erfc: + // "alpha": "0" + // "omega": "0.11" + // "singularity_correction": "limits" / "spencer" / "revised_spencer" + // "Rcut" + + Conv_Coulomb_Pot_K::Ccp_Type ccp_type; + double hybrid_alpha = 0.25; + double hse_omega = 0.11; + double mixing_beta_for_loop1 = 1.0; + + bool separate_loop = true; + size_t hybrid_step = 1; +}; + +/// Forward declaration for Input_para (full definition in input_parameter.h) +struct Input_para; + +/// Initialize General_Exx_Info from input parameters. +/// Returns true if opt_orb mode is requested (generate_opt_orb). +bool init_general_exx_info(General_Exx_Info& info, const Input_para& inp); + +#endif // GENERAL_EXX_INFO_H diff --git a/source/source_hamilt/module_xc/libxc_mgga_wrap.cpp b/source/source_hamilt/module_xc/libxc_mgga_wrap.cpp index 416dd2788f8..6ebbd28d235 100644 --- a/source/source_hamilt/module_xc/libxc_mgga_wrap.cpp +++ b/source/source_hamilt/module_xc/libxc_mgga_wrap.cpp @@ -4,7 +4,7 @@ #ifdef __LIBXC -#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info +#include "source_hamilt/module_xc/exx_info.h" // for Exx_Info type #include "source_hamilt/module_xc/xc_functional.h" #include "libxc_abacus.h" #include diff --git a/source/source_hamilt/module_xc/libxc_setup.cpp b/source/source_hamilt/module_xc/libxc_setup.cpp index 2349509068a..4ee53b9bddc 100644 --- a/source/source_hamilt/module_xc/libxc_setup.cpp +++ b/source/source_hamilt/module_xc/libxc_setup.cpp @@ -6,7 +6,7 @@ #include "source_base/formatter.h" #ifdef __EXX -#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info +#include "source_hamilt/module_xc/exx_info.h" // for Exx_Info type #endif #include diff --git a/source/source_hsolver/hsolver_lcaopw.cpp b/source/source_hsolver/hsolver_lcaopw.cpp index 66a14263ee9..a4644e33258 100644 --- a/source/source_hsolver/hsolver_lcaopw.cpp +++ b/source/source_hsolver/hsolver_lcaopw.cpp @@ -8,7 +8,7 @@ #include "source_pw/module_pwdft/hamilt_pw.h" #include "source_hsolver/diago_iter_assist.h" #include "source_estate/elecstate_tools.h" -#include "source_hamilt/module_xc/exx_info.h" +#include "source_hamilt/module_xc/general_exx_info.h" #ifdef __EXX @@ -28,7 +28,8 @@ void HSolverLIP::solve(hamilt::Hamilt* pHamilt, // ESolver_KS_PW::p_hamilt psi::Psi& transform, const bool skip_charge, const double tpiba, - const int nat) + const int nat, + const General_Exx_Info& exx_info) { ModuleBase::TITLE("HSolverLIP", "solve"); ModuleBase::timer::start("HSolverLIP", "solve"); @@ -43,8 +44,8 @@ void HSolverLIP::solve(hamilt::Hamilt* pHamilt, // ESolver_KS_PW::p_hamilt #ifdef __EXX auto& exx_lip = dynamic_cast*>(pHamilt)->exx_lip; - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; + bool cal_exx = exx_info.cal_exx; + double hybrid_alpha = exx_info.hybrid_alpha; auto add_exx_to_subspace_hamilt = [&ik, &exx_lip, cal_exx, hybrid_alpha](T* hcc, const int naos) -> void { if (cal_exx) { diff --git a/source/source_hsolver/hsolver_lcaopw.h b/source/source_hsolver/hsolver_lcaopw.h index c226376b0ca..30b40da2384 100644 --- a/source/source_hsolver/hsolver_lcaopw.h +++ b/source/source_hsolver/hsolver_lcaopw.h @@ -4,6 +4,10 @@ #include "source_estate/elecstate.h" #include "source_hamilt/hamilt.h" #include "source_base/macros.h" + +/// General_Exx_Info forward declaration, full definition in general_exx_info.h +struct General_Exx_Info; + namespace hsolver { @@ -36,7 +40,8 @@ class HSolverLIP psi::Psi& transform, const bool skip_charge, const double tpiba, - const int nat); + const int nat, + const General_Exx_Info& exx_info); private: ModulePW::PW_Basis_K* wfc_basis = nullptr; diff --git a/source/source_hsolver/test/diago_bpcg_test.cpp b/source/source_hsolver/test/diago_bpcg_test.cpp index 17309b354f9..7b07f3e3996 100644 --- a/source/source_hsolver/test/diago_bpcg_test.cpp +++ b/source/source_hsolver/test/diago_bpcg_test.cpp @@ -98,7 +98,7 @@ class DiagoBPCGPrepare double *en = new double[npw]; int ik = 1; hamilt::Hamilt>* ha; - ha =new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + ha =new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); int* ngk = new int [1]; //psi::Psi> psi(ngk,ik,nband,npw); psi::Psi> psi; diff --git a/source/source_hsolver/test/diago_cg_float_test.cpp b/source/source_hsolver/test/diago_cg_float_test.cpp index 01e2223e811..2d3ec2e0d77 100644 --- a/source/source_hsolver/test/diago_cg_float_test.cpp +++ b/source/source_hsolver/test/diago_cg_float_test.cpp @@ -107,7 +107,7 @@ class DiagoCGPrepare float *en = new float[npw]; int ik = 1; hamilt::Hamilt>* ha; - ha =new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + ha =new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); psi::Psi> psi; psi.resize(ik,nband,npw); //psi.fix_k(0); diff --git a/source/source_hsolver/test/diago_cg_real_test.cpp b/source/source_hsolver/test/diago_cg_real_test.cpp index 29db2b9a6d9..96c1c7c048c 100644 --- a/source/source_hsolver/test/diago_cg_real_test.cpp +++ b/source/source_hsolver/test/diago_cg_real_test.cpp @@ -107,7 +107,7 @@ class DiagoCGPrepare double* en = new double[npw]; int ik = 1; hamilt::Hamilt* ha; - ha = new hamilt::HamiltPW(nullptr, nullptr, nullptr, nullptr); + ha = new hamilt::HamiltPW(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); int* ngk = new int[1]; psi::Psi psi; psi.resize(ik, nband, npw); diff --git a/source/source_hsolver/test/diago_cg_test.cpp b/source/source_hsolver/test/diago_cg_test.cpp index d5408a5d21c..a7fd847a92e 100644 --- a/source/source_hsolver/test/diago_cg_test.cpp +++ b/source/source_hsolver/test/diago_cg_test.cpp @@ -103,7 +103,7 @@ class DiagoCGPrepare double *en = new double[npw]; int ik = 1; hamilt::Hamilt>* ha; - ha =new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + ha =new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); psi::Psi> psi; psi.resize(ik,nband,npw); //psi.fix_k(0); diff --git a/source/source_hsolver/test/diago_david_float_test.cpp b/source/source_hsolver/test/diago_david_float_test.cpp index b061601caa9..cfdff1de8e8 100644 --- a/source/source_hsolver/test/diago_david_float_test.cpp +++ b/source/source_hsolver/test/diago_david_float_test.cpp @@ -83,7 +83,7 @@ class DiagoDavPrepare //do Diago_David::diag() float* en = new float[npw]; hamilt::Hamilt> *phm; - phm = new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + phm = new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); #ifdef __MPI const hsolver::diag_comm_info comm_info = {POOL_WORLD, mypnum, nprocs}; diff --git a/source/source_hsolver/test/diago_david_real_test.cpp b/source/source_hsolver/test/diago_david_real_test.cpp index a3bfb15e5eb..9d1e453aae0 100644 --- a/source/source_hsolver/test/diago_david_real_test.cpp +++ b/source/source_hsolver/test/diago_david_real_test.cpp @@ -82,7 +82,7 @@ class DiagoDavPrepare //do Diago_David::diag() double* en = new double[npw]; hamilt::Hamilt* phm; - phm = new hamilt::HamiltPW(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + phm = new hamilt::HamiltPW(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); #ifdef __MPI const hsolver::diag_comm_info comm_info = {POOL_WORLD, mypnum, nprocs}; diff --git a/source/source_hsolver/test/diago_david_test.cpp b/source/source_hsolver/test/diago_david_test.cpp index 9dfc3a03f78..7348c5de274 100644 --- a/source/source_hsolver/test/diago_david_test.cpp +++ b/source/source_hsolver/test/diago_david_test.cpp @@ -87,7 +87,7 @@ class DiagoDavPrepare //do Diago_David::diag() double* en = new double[npw]; hamilt::Hamilt> *phm; - phm = new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + phm = new hamilt::HamiltPW>(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); #ifdef __MPI const hsolver::diag_comm_info comm_info = {POOL_WORLD, mypnum, nprocs}; diff --git a/source/source_hsolver/test/diago_mock.h b/source/source_hsolver/test/diago_mock.h index 75cced8409a..cbab29db8d6 100644 --- a/source/source_hsolver/test/diago_mock.h +++ b/source/source_hsolver/test/diago_mock.h @@ -573,12 +573,13 @@ template<> void hamilt::HamiltPW::updateHk(const int ik) } template<> hamilt::HamiltPW::HamiltPW( - elecstate::Potential* pot_in, - ModulePW::PW_Basis_K* wfc_basis, - K_Vectors* pkv, + elecstate::Potential* pot_in, + ModulePW::PW_Basis_K* wfc_basis, + K_Vectors* pkv, pseudopot_cell_vnl* ppcell, Plus_U* p_dftu, // mohan add 20251108 - const UnitCell* ucell) + const UnitCell* ucell, + const General_Exx_Info* exx_info) { this->ops = new OperatorMock; } @@ -594,12 +595,13 @@ template<> void hamilt::HamiltPW>::updateHk(const int ik) } template<> hamilt::HamiltPW>::HamiltPW( - elecstate::Potential* pot_in, - ModulePW::PW_Basis_K* wfc_basis, - K_Vectors* pkv, + elecstate::Potential* pot_in, + ModulePW::PW_Basis_K* wfc_basis, + K_Vectors* pkv, pseudopot_cell_vnl* ppcell, Plus_U* p_dftu, // mohan add 20251108 - const UnitCell* ucell) + const UnitCell* ucell, + const General_Exx_Info* exx_info) { this->ops = new OperatorMock>; } @@ -615,12 +617,13 @@ template<> void hamilt::HamiltPW>::updateHk(const int ik) } template<> hamilt::HamiltPW>::HamiltPW( - elecstate::Potential* pot_in, - ModulePW::PW_Basis_K* wfc_basis, - K_Vectors* pkv, + elecstate::Potential* pot_in, + ModulePW::PW_Basis_K* wfc_basis, + K_Vectors* pkv, pseudopot_cell_vnl* ppcell, Plus_U* p_dftu, // mohan add 20251108 - const UnitCell* ucell) + const UnitCell* ucell, + const General_Exx_Info* exx_info) { this->ops = new OperatorMock>; } diff --git a/source/source_hsolver/test/test_hsolver_pw.cpp b/source/source_hsolver/test/test_hsolver_pw.cpp index 2e6a07fffb8..5d0bc8cf284 100644 --- a/source/source_hsolver/test/test_hsolver_pw.cpp +++ b/source/source_hsolver/test/test_hsolver_pw.cpp @@ -11,6 +11,7 @@ #include "hsolver_pw_sup.h" #include "hsolver_supplementary_mock.h" #include "source_base/global_variable.h" +#include "source_hamilt/module_xc/general_exx_info.h" // for General_Exx_Info type #include "source_hsolver/hsolver_pw.h" #undef private #undef protected @@ -373,7 +374,8 @@ TEST_F(TestHSolverPW, SolveLcaoInPW) { // check solve() elecstate_test.ekb.c[0] = 1.0; elecstate_test.ekb.c[1] = 2.0; - + + General_Exx_Info exx_info_local; hsolver::HSolverLIP> hs_f_lip = hsolver::HSolverLIP>(&pwbk, PARAM.sys.use_uspp, @@ -384,7 +386,7 @@ TEST_F(TestHSolverPW, SolveLcaoInPW) { PARAM.sys.use_uspp, PARAM.input.basis_type, PARAM.input.calculation); - hs_f_lip.solve(&hamilt_test_f, psi_test_cf, &elecstate_test,transform_test_cf, true,0.0,0); + hs_f_lip.solve(&hamilt_test_f, psi_test_cf, &elecstate_test,transform_test_cf, true,0.0,0, exx_info_local); EXPECT_DOUBLE_EQ(hsolver::DiagoIterAssist>::avg_iter, 0.0); for (int i = 0; i < psi_test_cf.size(); i++) { @@ -395,7 +397,7 @@ TEST_F(TestHSolverPW, SolveLcaoInPW) { elecstate_test.ekb.c[0] = 1.0; elecstate_test.ekb.c[1] = 2.0; - hs_d_lip.solve(&hamilt_test_d, psi_test_cd, &elecstate_test, transform_test_cd, true,0.0,0); + hs_d_lip.solve(&hamilt_test_d, psi_test_cd, &elecstate_test, transform_test_cd, true,0.0,0, exx_info_local); EXPECT_DOUBLE_EQ(hsolver::DiagoIterAssist>::avg_iter, 0.0); for (int i = 0; i < psi_test_cd.size(); i++) { diff --git a/source/source_hsolver/test/test_hsolver_sdft.cpp b/source/source_hsolver/test/test_hsolver_sdft.cpp index 06840f091c9..0820922019d 100644 --- a/source/source_hsolver/test/test_hsolver_sdft.cpp +++ b/source/source_hsolver/test/test_hsolver_sdft.cpp @@ -81,16 +81,6 @@ void elecstate::ElecStatePW, base_device::DEVICE_CPU>::init { } -template -StoChe::StoChe(const int& nche, const int& method, const REAL& emax_sto, const REAL& emin_sto) -{ - this->nche = nche; -} -template -StoChe::~StoChe() -{ -} - template class StoChe; template @@ -262,8 +252,10 @@ namespace ModulePW { class TestHSolverPW_SDFT : public ::testing::Test { public: - TestHSolverPW_SDFT() : stoche(8, 1, 0, 0), elecstate_test(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) + TestHSolverPW_SDFT() : elecstate_test(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) { + stoche.nche = 8; + stoche.method_sto = 1; } ModulePW::PW_Basis_K pwbk; Stochastic_WF> stowf; diff --git a/source/source_io/module_ctrl/ctrl_iter_lcao.cpp b/source/source_io/module_ctrl/ctrl_iter_lcao.cpp index df862f49e17..22a66fcff68 100644 --- a/source/source_io/module_ctrl/ctrl_iter_lcao.cpp +++ b/source/source_io/module_ctrl/ctrl_iter_lcao.cpp @@ -1,6 +1,7 @@ #include "ctrl_iter_lcao.h" // use ctrl_iter_lcao() #include "source_base/global_variable.h" // use GlobalC +#include "source_hamilt/module_xc/exx_info.h" #ifdef __MLALGO #include "source_lcao/module_deepks/lcao_deepks.h" #include "source_lcao/module_deepks/lcao_deepks_iface.h" @@ -28,6 +29,7 @@ void ctrl_iter_lcao(UnitCell& ucell, // unit cell * LCAO_Orbitals &orb, // orbital info * Setup_DeePKS &deepks, Exx_NAO &exx_nao, + const Exx_Info& exx_info, int &iter, const int istep, bool &conv_esolver, @@ -47,8 +49,8 @@ void ctrl_iter_lcao(UnitCell& ucell, // unit cell * } #ifdef __EXX - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - bool real_number = GlobalC::exx_info.info_ri.real_number; + bool cal_exx = exx_info.info_global.cal_exx; + bool real_number = exx_info.info_ri.real_number; if (inp.calculation != "nscf") { @@ -98,6 +100,7 @@ template void ctrl_iter_lcao(UnitCell& ucell, // unit cell * LCAO_Orbitals &orb, // orbital info * Setup_DeePKS &deepks, Exx_NAO &exx_nao, + const Exx_Info& exx_info, int &iter, const int istep, bool &conv_esolver, @@ -118,6 +121,7 @@ template void ctrl_iter_lcao, double>(UnitCell& ucell, // u LCAO_Orbitals &orb, // orbital info * Setup_DeePKS> &deepks, Exx_NAO> &exx_nao, + const Exx_Info& exx_info, int &iter, const int istep, bool &conv_esolver, @@ -138,6 +142,7 @@ template void ctrl_iter_lcao, std::complex>(UnitCel LCAO_Orbitals &orb, // orbital info * Setup_DeePKS> &deepks, Exx_NAO> &exx_nao, + const Exx_Info& exx_info, int &iter, const int istep, bool &conv_esolver, diff --git a/source/source_io/module_ctrl/ctrl_iter_lcao.h b/source/source_io/module_ctrl/ctrl_iter_lcao.h index 6297d4f1d03..795c7d18db4 100644 --- a/source/source_io/module_ctrl/ctrl_iter_lcao.h +++ b/source/source_io/module_ctrl/ctrl_iter_lcao.h @@ -29,6 +29,7 @@ void ctrl_iter_lcao(UnitCell& ucell, // unit cell * LCAO_Orbitals &orb, // orbital info * Setup_DeePKS &deepks, Exx_NAO &exx_nao, + const Exx_Info& exx_info, int &iter, const int istep, bool &conv_esolver, diff --git a/source/source_io/module_ctrl/ctrl_output_td.cpp b/source/source_io/module_ctrl/ctrl_output_td.cpp index 1a5c37dc89c..d4308630fc0 100644 --- a/source/source_io/module_ctrl/ctrl_output_td.cpp +++ b/source/source_io/module_ctrl/ctrl_output_td.cpp @@ -23,7 +23,8 @@ void ctrl_output_td(const UnitCell& ucell, hamilt::HamiltLCAO, TR>* p_hamilt, Record_adj& RA, TD_info* td_p, - const Exx_NAO>& exx_nao + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info ) { ModuleBase::TITLE("ModuleIO", "ctrl_output_td"); @@ -51,7 +52,7 @@ void ctrl_output_td(const UnitCell& ucell, } else if(TD_info::out_current==2) { - ModuleIO::write_current(ucell, grid, istep, psi, pelec, kv, pv, orb, td_p, p_hamilt->getSR(), p_hamilt->getHR(), exx_nao); + ModuleIO::write_current(ucell, grid, istep, psi, pelec, kv, pv, orb, td_p, p_hamilt->getSR(), p_hamilt->getHR(), exx_nao, exx_info); } // (3) Output file for restart if (PARAM.inp.out_freq_td > 0) // default value of out_freq_td is 0 @@ -87,7 +88,8 @@ template void ctrl_output_td(const UnitCell&, hamilt::HamiltLCAO, double>*, Record_adj&, TD_info*, - const Exx_NAO>& + const Exx_NAO>&, + const Exx_Info& ); template void ctrl_output_td>(const UnitCell&, @@ -105,7 +107,8 @@ template void ctrl_output_td>(const UnitCell&, hamilt::HamiltLCAO, std::complex>*, Record_adj&, TD_info*, - const Exx_NAO>& + const Exx_NAO>&, + const Exx_Info& ); } // namespace ModuleIO \ No newline at end of file diff --git a/source/source_io/module_ctrl/ctrl_output_td.h b/source/source_io/module_ctrl/ctrl_output_td.h index 67153b8e258..6a20c43c93d 100644 --- a/source/source_io/module_ctrl/ctrl_output_td.h +++ b/source/source_io/module_ctrl/ctrl_output_td.h @@ -12,6 +12,7 @@ #include "source_psi/psi.h" #include "source_lcao/hamilt_lcao.h" #include "source_lcao/setup_exx.h" +#include "source_hamilt/module_xc/exx_info.h" // for Exx_Info #ifdef __EXX #include #endif @@ -35,7 +36,8 @@ void ctrl_output_td(const UnitCell& ucell, hamilt::HamiltLCAO, TR>* p_hamilt, Record_adj& RA, TD_info* td_p, - const Exx_NAO>& exx_nao + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info ); } // namespace ModuleIO diff --git a/source/source_io/module_ctrl/ctrl_runner_lcao.cpp b/source/source_io/module_ctrl/ctrl_runner_lcao.cpp index 269ea5e89d2..bfc3b859c3e 100644 --- a/source/source_io/module_ctrl/ctrl_runner_lcao.cpp +++ b/source/source_io/module_ctrl/ctrl_runner_lcao.cpp @@ -35,6 +35,7 @@ void ctrl_runner_lcao(UnitCell& ucell, // unitcell Structure_Factor &sf, // structure factor ModuleBase::matrix &vloc, // local pseudopotential Exx_NAO &exx_nao, + const Exx_Info& exx_info, surchem &solvent) // solvent model { ModuleBase::TITLE("ModuleIO", "ctrl_runner_lcao"); @@ -56,7 +57,7 @@ void ctrl_runner_lcao(UnitCell& ucell, // unitcell // 3) print out exchange-correlation potential if (inp.out_mat_xc) { - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; + bool cal_exx = exx_info.info_global.cal_exx; ModuleIO::write_Vxc(inp.nspin, PARAM.globalv.nlocal, GlobalV::DRANK, @@ -73,7 +74,8 @@ void ctrl_runner_lcao(UnitCell& ucell, // unitcell orb.cutoffs(), pelec->wg, gd, - cal_exx + cal_exx, + exx_info #ifdef __EXX , exx_nao.exd ? &exx_nao.exd->get_Hexxs() : nullptr, @@ -84,9 +86,9 @@ void ctrl_runner_lcao(UnitCell& ucell, // unitcell if (inp.out_mat_xc2[0]) { - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; - bool real_number = GlobalC::exx_info.info_ri.real_number; + bool cal_exx = exx_info.info_global.cal_exx; + double hybrid_alpha = exx_info.info_global.hybrid_alpha; + bool real_number = exx_info.info_ri.real_number; ModuleIO::write_Vxc_R(inp.nspin, &pv, ucell, @@ -130,7 +132,8 @@ void ctrl_runner_lcao(UnitCell& ucell, // unitcell pelec->wg, gd, orb.cutoffs(), - two_center_bundle + two_center_bundle, + exx_info #ifdef __EXX , exx_nao.exd ? &exx_nao.exd->get_Hexxs() : nullptr, @@ -164,6 +167,7 @@ template void ctrl_runner_lcao(UnitCell& ucell, // unitcell Structure_Factor &sf, // structure factor ModuleBase::matrix &vloc, // local pseudopotential Exx_NAO &exx_nao, + const Exx_Info& exx_info, surchem &solvent); // solvent model // TK: complex TR: double @@ -185,6 +189,7 @@ template void ctrl_runner_lcao, double>(UnitCell& ucell, Structure_Factor &sf, // structure factor ModuleBase::matrix &vloc, // local pseudopotential Exx_NAO> &exx_nao, + const Exx_Info& exx_info, surchem &solvent); // solvent model // TK: complex TR: complex @@ -206,6 +211,7 @@ template void ctrl_runner_lcao, std::complex>(UnitC Structure_Factor &sf, // structure factor ModuleBase::matrix &vloc, // local pseudopotential Exx_NAO> &exx_nao, + const Exx_Info& exx_info, surchem &solvent); // solvent model } // end namespace diff --git a/source/source_io/module_ctrl/ctrl_runner_lcao.h b/source/source_io/module_ctrl/ctrl_runner_lcao.h index 95c4fe4658a..fcf790214e4 100644 --- a/source/source_io/module_ctrl/ctrl_runner_lcao.h +++ b/source/source_io/module_ctrl/ctrl_runner_lcao.h @@ -32,6 +32,7 @@ void ctrl_runner_lcao(UnitCell& ucell, // unitcell Structure_Factor &sf, // structure factor ModuleBase::matrix &vloc, // local pseudopotential Exx_NAO &exx_nao, + const Exx_Info& exx_info, surchem &solvent); // solvent model } diff --git a/source/source_io/module_ctrl/ctrl_scf_lcao.cpp b/source/source_io/module_ctrl/ctrl_scf_lcao.cpp index b6506ee9315..e6bb5e7f2e9 100644 --- a/source/source_io/module_ctrl/ctrl_scf_lcao.cpp +++ b/source/source_io/module_ctrl/ctrl_scf_lcao.cpp @@ -1,4 +1,5 @@ #include "ctrl_scf_lcao.h" // use ctrl_scf_lcao() +#include "source_hamilt/module_xc/exx_info.h" #include "source_base/formatter.h" #include "source_base/tool_quit.h" // use ModuleBase::WARNING_QUIT @@ -41,13 +42,13 @@ #ifdef __EXX template -void setup_exx_dh_params(ModuleIO::WriteDHParams& dh_params, Exx_NAO& exx_nao) +void setup_exx_dh_params(ModuleIO::WriteDHParams& dh_params, Exx_NAO& exx_nao, const Exx_Info& exx_info) {} template <> -void setup_exx_dh_params(ModuleIO::WriteDHParams& dh_params, Exx_NAO& exx_nao) +void setup_exx_dh_params(ModuleIO::WriteDHParams& dh_params, Exx_NAO& exx_nao, const Exx_Info& exx_info) { - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { if (exx_nao.exd) { dh_params.exd = exx_nao.exd.get(); } if (exx_nao.exc) { dh_params.exc = exx_nao.exc.get(); } @@ -55,7 +56,7 @@ void setup_exx_dh_params(ModuleIO::WriteDHParams& dh_params, Exx_NAO -void setup_exx_h_params(ModuleIO::WriteHParams& h_params, Exx_NAO& exx_nao) +void setup_exx_h_params(ModuleIO::WriteHParams& h_params, Exx_NAO& exx_nao, const Exx_Info& exx_info) { // Only the gamma-only (TK==double) specialization below actually writes V^EXX(R). // This generic body is instantiated for the multi-k (TK==std::complex) path, where the @@ -67,13 +68,13 @@ void setup_exx_h_params(ModuleIO::WriteHParams& h_params, Exx_NAO& exx_nao) } template <> -void setup_exx_h_params(ModuleIO::WriteHParams& h_params, Exx_NAO& exx_nao) +void setup_exx_h_params(ModuleIO::WriteHParams& h_params, Exx_NAO& exx_nao, const Exx_Info& exx_info) { - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { if (exx_nao.exd) { h_params.exd = exx_nao.exd.get(); } if (exx_nao.exc) { h_params.exc = exx_nao.exc.get(); } - ModuleIO::write_h_exx(h_params); + ModuleIO::write_h_exx(h_params, exx_info); } } #endif @@ -101,6 +102,7 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell, rdmft::RDMFT& rdmft_solver, // for RDMFT Setup_DeePKS& deepks, Exx_NAO& exx_nao, + const Exx_Info& exx_info, const bool conv_esolver, const bool scf_nmax_flag, const int istep) @@ -404,9 +406,9 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell, #ifdef __EXX // dV^EXX/dR output is wired for the gamma (TK==double) exx interfaces. exd/exc are // mutually exclusive (real vs complex Hexx); write_dH_exx picks by info_ri.real_number. - setup_exx_dh_params(dh_params, exx_nao); + setup_exx_dh_params(dh_params, exx_nao, exx_info); #endif - ModuleIO::write_dH_components(dh_params); + ModuleIO::write_dH_components(dh_params, exx_info); delete pot_vl; delete pot_vh; delete pot_vxc; @@ -454,10 +456,10 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell, ModuleIO::write_h_vxc(h_params); } #ifdef __EXX - if (inp.out_mat_h_exx[0] && GlobalC::exx_info.info_global.cal_exx) + if (inp.out_mat_h_exx[0] && exx_info.info_global.cal_exx) { // V^EXX(R) output is wired for the gamma (TK==double) exx interfaces. - setup_exx_h_params(h_params, exx_nao); + setup_exx_h_params(h_params, exx_nao, exx_info); } #endif } @@ -616,8 +618,8 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell, //! 15) Output Hexx matrix in LCAO basis // (see `out_chg` in docs/advanced/input_files/input-main.md) //------------------------------------------------------------------ - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - bool real_number = GlobalC::exx_info.info_ri.real_number; + bool cal_exx = exx_info.info_global.cal_exx; + bool real_number = exx_info.info_ri.real_number; if (inp.out_chg[0]) { @@ -640,7 +642,7 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell, //------------------------------------------------------------------ if (inp.rpa) { - RPA_LRI rpa_lri_double(GlobalC::exx_info.info_ri); + RPA_LRI rpa_lri_double(exx_info.info_ri); rpa_lri_double.postSCF(ucell, MPI_COMM_WORLD, *dm, pelec, kv, orb, pv, *psi); if (inp.rpa_out_vel) rpa_lri_double.out_velocity(ucell, gd, two_center_bundle, pv, *psi, pelec); @@ -752,6 +754,7 @@ template void ModuleIO::ctrl_scf_lcao( rdmft::RDMFT& rdmft_solver, // for RDMFT Setup_DeePKS& deepks, Exx_NAO& exx_nao, + const Exx_Info& exx_info, const bool conv_esolver, const bool scf_nmax_flag, const int istep); @@ -780,6 +783,7 @@ template void ModuleIO::ctrl_scf_lcao, double>( rdmft::RDMFT, double>& rdmft_solver, // for RDMFT Setup_DeePKS>& deepks, Exx_NAO>& exx_nao, + const Exx_Info& exx_info, const bool conv_esolver, const bool scf_nmax_flag, const int istep); @@ -807,6 +811,7 @@ template void ModuleIO::ctrl_scf_lcao, std::complex rdmft::RDMFT, std::complex>& rdmft_solver, // for RDMFT Setup_DeePKS>& deepks, Exx_NAO>& exx_nao, + const Exx_Info& exx_info, const bool conv_esolver, const bool scf_nmax_flag, const int istep); diff --git a/source/source_io/module_ctrl/ctrl_scf_lcao.h b/source/source_io/module_ctrl/ctrl_scf_lcao.h index ce923aae52f..53749f3c97b 100644 --- a/source/source_io/module_ctrl/ctrl_scf_lcao.h +++ b/source/source_io/module_ctrl/ctrl_scf_lcao.h @@ -44,6 +44,7 @@ void ctrl_scf_lcao(UnitCell& ucell, rdmft::RDMFT& rdmft_solver, // for RDMFT Setup_DeePKS& deepks, Exx_NAO& exx_nao, + const Exx_Info& exx_info, const bool conv_esolver, const bool scf_nmax_flag, const int istep); diff --git a/source/source_io/module_current/td_current_io.h b/source/source_io/module_current/td_current_io.h index c0ac2d6f409..8242adc699b 100644 --- a/source/source_io/module_current/td_current_io.h +++ b/source/source_io/module_current/td_current_io.h @@ -7,6 +7,7 @@ #include "source_lcao/module_rt/velocity_op.h" #include "source_lcao/setup_exx.h" #include "source_lcao/module_rt/td_info.h" +#include "source_hamilt/module_xc/exx_info.h" // for Exx_Info #ifdef __EXX #include #endif @@ -53,7 +54,8 @@ void write_current( TD_info* td_p, const hamilt::HContainer* sR, const hamilt::HContainer* hR, - const Exx_NAO>& exx_nao + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info ); void set_rR_from_hR(const UnitCell& ucell, const Grid_Driver& GridD, @@ -69,7 +71,8 @@ void sum_HR( const K_Vectors& kv, const hamilt::HContainer* hR, hamilt::HContainer>* full_hR, - const Exx_NAO>& exx_nao + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info ); template diff --git a/source/source_io/module_current/td_current_io_comm.cpp b/source/source_io/module_current/td_current_io_comm.cpp index 28583e1fd14..90f172317c7 100644 --- a/source/source_io/module_current/td_current_io_comm.cpp +++ b/source/source_io/module_current/td_current_io_comm.cpp @@ -190,7 +190,8 @@ void ModuleIO::sum_HR(const UnitCell& ucell, const K_Vectors& kv, const hamilt::HContainer* hR, hamilt::HContainer>* full_hR, - const Exx_NAO>& exx_nao) + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info) { ModuleBase::TITLE("ModuleIO", "sum_HR"); ModuleBase::timer::start("ModuleIO", "sum_HR"); @@ -205,7 +206,7 @@ void ModuleIO::sum_HR(const UnitCell& ucell, < 1e-10); RI::Cell_Nearest cell_nearest; // reallocate full_hR for BvK used in EXX - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { const std::array Rs_period = {kv.nmp[0], kv.nmp[1], kv.nmp[2]}; if (use_cell_nearest) @@ -241,14 +242,14 @@ void ModuleIO::sum_HR(const UnitCell& ucell, } #ifdef __EXX // add HexxR to complex full_hR - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { for (size_t is = 0; is != PARAM.inp.nspin; ++is) { if (use_cell_nearest) { RI_2D_Comm::add_HexxR(is, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info.info_global.hybrid_alpha, exx_nao.exc->get_Hexxs(), pv, PARAM.globalv.npol, @@ -258,7 +259,7 @@ void ModuleIO::sum_HR(const UnitCell& ucell, else { RI_2D_Comm::add_HexxR(is, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info.info_global.hybrid_alpha, exx_nao.exc->get_Hexxs(), pv, PARAM.globalv.npol, @@ -752,7 +753,8 @@ void ModuleIO::write_current(const UnitCell& ucell, TD_info* td_p, const hamilt::HContainer* sR, const hamilt::HContainer* hR, - const Exx_NAO>& exx_nao) + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info) { ModuleBase::TITLE("ModuleIO", "write_current"); ModuleBase::timer::start("ModuleIO", "write_current"); @@ -762,7 +764,7 @@ void ModuleIO::write_current(const UnitCell& ucell, hamilt::HContainer>* full_hR; full_hR = new hamilt::HContainer>(pv); current_k.resize(kv.get_nks()); - sum_HR(ucell, *pv, kv, hR, full_hR, exx_nao); + sum_HR(ucell, *pv, kv, hR, full_hR, exx_nao, exx_info); cal_current_comm_k(ucell, GridD, orb, pv, kv, td_p, *sR, *full_hR, psi, pelec, current_k); delete full_hR; @@ -828,7 +830,8 @@ template void ModuleIO::write_current(const UnitCell& ucell, TD_info* td_p, const hamilt::HContainer* sR, const hamilt::HContainer* hR, - const Exx_NAO>& exx_nao); + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info); template void ModuleIO::write_current>(const UnitCell& ucell, const Grid_Driver& GridD, @@ -841,5 +844,6 @@ template void ModuleIO::write_current>(const UnitCell& ucel TD_info* td_p, const hamilt::HContainer>* sR, const hamilt::HContainer>* hR, - const Exx_NAO>& exx_nao); + const Exx_NAO>& exx_nao, + const Exx_Info& exx_info); #endif //__LCAO diff --git a/source/source_io/module_dhs/write_dh.cpp b/source/source_io/module_dhs/write_dh.cpp index fcbf680aa40..8d01ce67f96 100644 --- a/source/source_io/module_dhs/write_dh.cpp +++ b/source/source_io/module_dhs/write_dh.cpp @@ -128,13 +128,13 @@ void write_dh_perI(WriteDHParams& params, } } -void write_dH_components(WriteDHParams& params) +void write_dH_components(WriteDHParams& params, const Exx_Info& exx_info) { ModuleBase::TITLE("ModuleIO", "write_dH_components"); ModuleBase::timer::start("ModuleIO", "write_dH_components"); // nspin=4 (noncollinear) is not supported: needs complex spinor blocks (HContainer>) - // plus noncollinear Gint kernels that do not exist for the dvlocal/drho paths. + // plus noncollinear Gint kernels that do not exist for the dvlocal/drho paths. if (PARAM.inp.nspin == 4) { ModuleBase::WARNING_QUIT("write_dH_components", @@ -146,7 +146,7 @@ void write_dH_components(WriteDHParams& params) // The EXX interfaces carried by WriteDHParams are gamma-only (see write_dh.h): at multi-k // dH^EXX would be the derivative with respect to every mirror atom, which this output is // not meant for. Quit instead of writing a dH sum that silently omits the EXX term. - if (GlobalC::exx_info.info_global.cal_exx && !PARAM.globalv.gamma_only_local + if (exx_info.info_global.cal_exx && !PARAM.globalv.gamma_only_local && (PARAM.inp.out_mat_dh[0] || PARAM.inp.out_mat_dh_exx[0])) { ModuleBase::WARNING_QUIT("write_dH_components", @@ -164,7 +164,7 @@ void write_dH_components(WriteDHParams& params) if (PARAM.inp.out_mat_dh[0]) { - write_dH_sum(params); + write_dH_sum(params, exx_info); } if (PARAM.inp.out_mat_dh_t[0]) @@ -197,7 +197,7 @@ void write_dH_components(WriteDHParams& params) #ifdef __EXX if (PARAM.inp.out_mat_dh_exx[0]) { - write_dH_exx(params); + write_dH_exx(params, exx_info); } #endif diff --git a/source/source_io/module_dhs/write_dh.h b/source/source_io/module_dhs/write_dh.h index 60d9e5db567..ebe5842fa92 100644 --- a/source/source_io/module_dhs/write_dh.h +++ b/source/source_io/module_dhs/write_dh.h @@ -7,6 +7,7 @@ #include "source_estate/module_pot/potential_new.h" #include "source_lcao/lcao_domain.h" #include "source_hamilt/module_hcontainer/hcontainer.h" +#include "source_hamilt/module_xc/exx_info.h" #include #include @@ -92,7 +93,7 @@ void write_dh_perI(WriteDHParams& params, std::array*>, 3>& g, const std::vector& atom_filter = {}); -void write_dH_components(WriteDHParams& params); +void write_dH_components(WriteDHParams& params, const Exx_Info& exx_info); bool write_dH_t(WriteDHParams& params); @@ -108,10 +109,10 @@ bool write_dH_vxc(WriteDHParams& params); bool write_dH_vxc_pulay(WriteDHParams& params); -bool write_dH_sum(WriteDHParams& params); +bool write_dH_sum(WriteDHParams& params, const Exx_Info& exx_info); #ifdef __EXX -bool write_dH_exx(WriteDHParams& params); +bool write_dH_exx(WriteDHParams& params, const Exx_Info& exx_info); #endif } // namespace ModuleIO diff --git a/source/source_io/module_dhs/write_dh_terms.cpp b/source/source_io/module_dhs/write_dh_terms.cpp index aadf886ba61..2c71c9684fb 100644 --- a/source/source_io/module_dhs/write_dh_terms.cpp +++ b/source/source_io/module_dhs/write_dh_terms.cpp @@ -359,14 +359,14 @@ bool write_dH_vxc_pulay(WriteDHParams& params) } #ifdef __EXX -bool write_dH_exx(WriteDHParams& params) +bool write_dH_exx(WriteDHParams& params, const Exx_Info& exx_info) { ModuleBase::TITLE("ModuleIO", "write_dH_exx"); ModuleBase::timer::start("ModuleIO", "write_dH_exx"); bool ok = false; // exd (real Hexx) and exc (complex Hexx) are mutually exclusive; pick by real_number. - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info.info_ri.real_number) { if (params.exd != nullptr) { @@ -393,7 +393,7 @@ bool write_dH_exx(WriteDHParams& params) // full sum. Each term is built into its own per-atom-I containers (via the same fillers the // per-term writers use) and accumulated with HContainer::add_value_union, which unions the // (generally different) sparsities and sums values. Each term already carries its own sign. -bool write_dH_sum(WriteDHParams& params) +bool write_dH_sum(WriteDHParams& params, const Exx_Info& exx_info) { ModuleBase::TITLE("ModuleIO", "write_dH_sum"); ModuleBase::timer::start("ModuleIO", "write_dH_sum"); @@ -407,9 +407,9 @@ bool write_dH_sum(WriteDHParams& params) const bool do_exx = (params.exd != nullptr || params.exc != nullptr); if (do_exx) { - if (GlobalC::exx_info.info_ri.real_number && params.exd != nullptr) + if (exx_info.info_ri.real_number && params.exd != nullptr) params.exd->cal_exx_dHs(*params.ucell, pv, nspin); - else if (!GlobalC::exx_info.info_ri.real_number && params.exc != nullptr) + else if (!exx_info.info_ri.real_number && params.exc != nullptr) params.exc->cal_exx_dHs(*params.ucell, pv, nspin); } #endif @@ -459,7 +459,7 @@ bool write_dH_sum(WriteDHParams& params) if (do_exx) { PerIContainers c(pv, nat); - if (GlobalC::exx_info.info_ri.real_number && params.exd != nullptr) + if (exx_info.info_ri.real_number && params.exd != nullptr) fill_dH_exx(params, params.exd, ispin, c); else if (params.exc != nullptr) fill_dH_exx(params, params.exc, ispin, c); diff --git a/source/source_io/module_energy/write_eband_terms.hpp b/source/source_io/module_energy/write_eband_terms.hpp index 327fdfea664..6622356a99f 100644 --- a/source/source_io/module_energy/write_eband_terms.hpp +++ b/source/source_io/module_energy/write_eband_terms.hpp @@ -26,7 +26,8 @@ void write_eband_terms(const int nspin, const ModuleBase::matrix& wg, Grid_Driver& gd, const std::vector& orb_cutoff, - const TwoCenterBundle& two_center_bundle + const TwoCenterBundle& two_center_bundle, + const Exx_Info& exx_info #ifdef __EXX , std::vector>>>* Hexxd = nullptr, @@ -182,7 +183,7 @@ void write_eband_terms(const int nspin, // 5. xc (including exx) if (!PARAM.inp.out_mat_xc) // avoid duplicate output { - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; + bool cal_exx = exx_info.info_global.cal_exx; write_Vxc(nspin, nbasis, drank, @@ -199,7 +200,8 @@ void write_eband_terms(const int nspin, orb_cutoff, wg, gd, - cal_exx + cal_exx, + exx_info #ifdef __EXX , Hexxd, diff --git a/source/source_io/module_hs/write_h_terms.cpp b/source/source_io/module_hs/write_h_terms.cpp index 3a8fdadfa70..f85aa4b97a7 100644 --- a/source/source_io/module_hs/write_h_terms.cpp +++ b/source/source_io/module_hs/write_h_terms.cpp @@ -382,11 +382,12 @@ static void write_h_exx_impl(const UnitCell& ucell, const bool append, const int* iat2iwt, const int nat, - const bool also_hR) + const bool also_hR, + const Exx_Info& exx_info) { const auto& Hexxs = ex->get_Hexxs(); // vector over spin of map> const int nspin_out = (nspin == 2 ? 2 : 1); - const double alpha = GlobalC::exx_info.info_global.hybrid_alpha; + const double alpha = exx_info.info_global.hybrid_alpha; for (int ispin = 0; ispin < nspin_out; ispin++) { @@ -405,7 +406,7 @@ static void write_h_exx_impl(const UnitCell& ucell, } } -void write_h_exx(WriteHParams& params) +void write_h_exx(WriteHParams& params, const Exx_Info& exx_info) { ModuleBase::TITLE("ModuleIO", "write_h_exx"); ModuleBase::timer::start("ModuleIO", "write_h_exx"); @@ -423,18 +424,18 @@ void write_h_exx(WriteHParams& params) const bool also_hR = params.also_hR; // exd (real Hexx) and exc (complex Hexx) are mutually exclusive; pick by real_number. - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info.info_ri.real_number) { if (params.exd != nullptr) { - write_h_exx_impl(ucell, pv, params.exd, kv, nspin, istep, append, iat2iwt, nat, also_hR); + write_h_exx_impl(ucell, pv, params.exd, kv, nspin, istep, append, iat2iwt, nat, also_hR, exx_info); } } else { if (params.exc != nullptr) { - write_h_exx_impl(ucell, pv, params.exc, kv, nspin, istep, append, iat2iwt, nat, also_hR); + write_h_exx_impl(ucell, pv, params.exc, kv, nspin, istep, append, iat2iwt, nat, also_hR, exx_info); } } diff --git a/source/source_io/module_hs/write_h_terms.h b/source/source_io/module_hs/write_h_terms.h index d18244d8638..cff8faee3d2 100644 --- a/source/source_io/module_hs/write_h_terms.h +++ b/source/source_io/module_hs/write_h_terms.h @@ -9,6 +9,7 @@ #include "source_estate/module_pot/potential_new.h" #include "source_lcao/lcao_domain.h" #include "source_hamilt/module_hcontainer/hcontainer.h" +#include "source_hamilt/module_xc/exx_info.h" #include #include @@ -62,7 +63,7 @@ void write_h_vxc(WriteHParams& params); #ifdef __EXX // Build V^EXX(R) into a real HContainer via add_HexxR (from exd/exc->get_Hexxs()) and write it. // exd (real Hexx) and exc (complex Hexx) are mutually exclusive; picked by info_ri.real_number. -void write_h_exx(WriteHParams& params); +void write_h_exx(WriteHParams& params, const Exx_Info& exx_info); #endif } // namespace ModuleIO diff --git a/source/source_io/module_hs/write_vxc.hpp b/source/source_io/module_hs/write_vxc.hpp index bdbcfd30fce..9f8665534b3 100644 --- a/source/source_io/module_hs/write_vxc.hpp +++ b/source/source_io/module_hs/write_vxc.hpp @@ -6,6 +6,7 @@ #include "source_base/module_external/scalapack_connector.h" #include "source_lcao/module_operator_lcao/op_dftu_lcao.h" #include "source_lcao/module_operator_lcao/veff_lcao.h" +#include "source_hamilt/module_xc/exx_info.h" #ifdef __EXX #include "source_lcao/module_operator_lcao/op_exx_lcao.h" #endif @@ -153,7 +154,8 @@ void write_Vxc(const int nspin, const std::vector& orb_cutoff, const ModuleBase::matrix& wg, Grid_Driver& gd, - bool cal_exx + bool cal_exx, + const Exx_Info& exx_info #ifdef __EXX , std::vector>>>* Hexxd = nullptr, @@ -201,10 +203,10 @@ void write_Vxc(const int nspin, std::vector> e_orb_tot; // orbital energy (total) #ifdef __EXX hamilt::OperatorEXX> vexx_op_ao(&vxc_k_ao, - &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, hamilt::Add_Hexx_Type::k); + &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, &exx_info, hamilt::Add_Hexx_Type::k); hamilt::HS_Matrix_K vexxonly_k_ao(pv, 1); // only hk is needed, sk is skipped hamilt::OperatorEXX> vexxonly_op_ao(&vexxonly_k_ao, - &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, hamilt::Add_Hexx_Type::k); + &vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, &exx_info, hamilt::Add_Hexx_Type::k); std::vector> e_orb_exx; // orbital energy (EXX) #endif hamilt::OperatorDFTU> vdftu_op_ao(&vxc_k_ao, kv.kvec_d, nullptr, nullptr, kv.isk, PARAM.globalv.npol); diff --git a/source/source_io/module_parameter/input_conv.cpp b/source/source_io/module_parameter/input_conv.cpp index b3bcf31da11..a0eecbe45a1 100644 --- a/source/source_io/module_parameter/input_conv.cpp +++ b/source/source_io/module_parameter/input_conv.cpp @@ -204,202 +204,27 @@ void Input_Conv::Convert() //---------------------------------------------------------- // about exx, Peize Lin add 2018-06-20 //---------------------------------------------------------- - std::string dft_functional_lower = PARAM.inp.dft_functional; - std::transform(PARAM.inp.dft_functional.begin(), - PARAM.inp.dft_functional.end(), - dft_functional_lower.begin(), - tolower); - bool generate_opt_orb = false; - if (dft_functional_lower == "hf" - || dft_functional_lower == "pbe0" || dft_functional_lower == "b3lyp" || dft_functional_lower == "hse" - || dft_functional_lower == "scan0" - || dft_functional_lower == "muller" || dft_functional_lower == "power" - || dft_functional_lower == "cwp22" || dft_functional_lower == "wp22" - || dft_functional_lower == "lc_pbe" - || dft_functional_lower == "lc_wpbe" - || dft_functional_lower == "lrc_wpbe" - || dft_functional_lower == "lrc_wpbeh" - || dft_functional_lower == "cam_pbeh") - { - GlobalC::exx_info.info_global.cal_exx = true; - - GlobalC::exx_info.info_global.hybrid_alpha = 0; - std::vector fock_alpha(PARAM.inp.exx_fock_alpha.size()); - for(std::size_t i=0; i erfc_alpha(PARAM.inp.exx_erfc_alpha.size()); - for(std::size_t i=0; i0); - for(std::size_t i=0; i::getForceStress(UnitCell& ucell, Setup_DeePKS& deepks, Exx_NAO &exx_nao, ModuleSymmetry::Symmetry* symm, + const Exx_Info& exx_info, const int td_stype, hamilt::Hamilt* p_hamilt) { @@ -488,9 +489,9 @@ void Force_Stress_LCAO::getForceStress(UnitCell& ucell, // } #ifdef __EXX - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - bool real_number = GlobalC::exx_info.info_ri.real_number; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; + bool cal_exx = exx_info.info_global.cal_exx; + bool real_number = exx_info.info_ri.real_number; + double hybrid_alpha = exx_info.info_global.hybrid_alpha; ModuleBase::matrix force_exx; ModuleBase::matrix stress_exx; @@ -557,7 +558,7 @@ void Force_Stress_LCAO::getForceStress(UnitCell& ucell, } #ifdef __EXX // Force contribution from exx - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { fcs(iat, i) += force_exx(iat, i); } @@ -771,7 +772,7 @@ void Force_Stress_LCAO::getForceStress(UnitCell& ucell, } #ifdef __EXX // Stress contribution from exx - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { scs(i, j) += stress_exx(i, j); } diff --git a/source/source_lcao/force_stress_lcao.h b/source/source_lcao/force_stress_lcao.h index efb88640e5a..af89b500bad 100644 --- a/source/source_lcao/force_stress_lcao.h +++ b/source/source_lcao/force_stress_lcao.h @@ -17,6 +17,7 @@ #include "source_lcao/setup_deepks.h" // for deepks, mohan add 20251010 #include "source_lcao/setup_dm.h" // mohan add 2025-11-03 #include "source_lcao/module_dftu/dftu.h" // mohan add 2025-11-07 +#include "source_hamilt/module_xc/exx_info.h" namespace vdw { @@ -60,6 +61,7 @@ class Force_Stress_LCAO Setup_DeePKS &deepks, Exx_NAO &exx_nao, ModuleSymmetry::Symmetry* symm, + const Exx_Info& exx_info, const int td_stype = 0, hamilt::Hamilt* p_hamilt = nullptr); diff --git a/source/source_lcao/hamilt_lcao.cpp b/source/source_lcao/hamilt_lcao.cpp index f108ebd93b4..4b1e465f278 100644 --- a/source/source_lcao/hamilt_lcao.cpp +++ b/source/source_lcao/hamilt_lcao.cpp @@ -84,8 +84,9 @@ HamiltLCAO::HamiltLCAO(const UnitCell& ucell, elecstate::DensityMatrix* DM_in, Plus_U* p_dftu, // mohan add 2025-11-05 Setup_DeePKS &deepks, - const int istep, - Exx_NAO &exx_nao) + const int istep, + Exx_NAO &exx_nao, + const Exx_Info& exx_info) { this->classname = "HamiltLCAO"; @@ -416,7 +417,7 @@ HamiltLCAO::HamiltLCAO(const UnitCell& ucell, } #ifdef __EXX - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { // Peize Lin add 2016-12-03 // set xc type before the first cal of xc in pelec->init_scf @@ -430,6 +431,7 @@ HamiltLCAO::HamiltLCAO(const UnitCell& ucell, *this->kv, exx_nao.exd.get(), exx_nao.exc.get(), + exx_info, Add_Hexx_Type::k, istep, !GlobalC::restart.info_load.restart_exx @@ -443,6 +445,7 @@ HamiltLCAO::HamiltLCAO(const UnitCell& ucell, *kv, exx_nao.exd.get(), exx_nao.exc.get(), + exx_info, Add_Hexx_Type::R, istep, !GlobalC::restart.info_load.restart_exx diff --git a/source/source_lcao/hamilt_lcao.h b/source/source_lcao/hamilt_lcao.h index 0c7a35f2afe..375fa864acd 100644 --- a/source/source_lcao/hamilt_lcao.h +++ b/source/source_lcao/hamilt_lcao.h @@ -28,7 +28,10 @@ class Plus_U; // Exx_NAO forward declaration, full definition in setup_exx.h (moved to .cpp) // mohan add 20260605 -template class Exx_NAO; +template class Exx_NAO; + +/// Exx_Info forward declaration, full definition in exx_info.h +struct Exx_Info; namespace hamilt { @@ -60,8 +63,9 @@ class HamiltLCAO : public Hamilt elecstate::DensityMatrix* DM_in, Plus_U* p_dftu, // mohan add 2025-11-05 Setup_DeePKS &deepks, - const int istep, - Exx_NAO &exx_nao); + const int istep, + Exx_NAO &exx_nao, + const Exx_Info& exx_info); /** * @brief Constructor of vacuum Operators, only HR and SR will be initialed as empty HContainer diff --git a/source/source_lcao/lcao_set.cpp b/source/source_lcao/lcao_set.cpp index 7eb2c31f862..dda20f80580 100644 --- a/source/source_lcao/lcao_set.cpp +++ b/source/source_lcao/lcao_set.cpp @@ -52,19 +52,20 @@ void LCAO_domain::set_psi_occ_dm_chg( template void LCAO_domain::set_pot( UnitCell &ucell, // not const because of dftu - K_Vectors &kv, // not const due to exx - Structure_Factor& sf, // will be modified in potential - const ModulePW::PW_Basis &pw_rho, - const ModulePW::PW_Basis &pw_rhod, + K_Vectors &kv, // not const due to exx + Structure_Factor& sf, // will be modified in potential + const ModulePW::PW_Basis &pw_rho, + const ModulePW::PW_Basis &pw_rhod, elecstate::ElecState* pelec, const LCAO_Orbitals& orb, - Parallel_Orbitals &pv, // not const due to deepks - pseudopot_cell_vl &locpp, + Parallel_Orbitals &pv, // not const due to deepks + pseudopot_cell_vl &locpp, Plus_U &dftu, surchem& solvent, Exx_NAO &exx_nao, Setup_DeePKS &deepks, - const Input_para &inp) + const Input_para &inp, + Exx_Info& exx_info) { //! 1) init local pseudopotentials locpp.init_vloc(ucell, &pw_rho); @@ -97,7 +98,7 @@ void LCAO_domain::set_pot( } //! 4) init exact exchange calculations - exx_nao.before_runner(ucell, kv, orb, pv, inp); + exx_nao.before_runner(ucell, kv, orb, pv, inp, exx_info); //! 5) init deepks deepks.before_runner(ucell, kv.get_nks(), orb, pv, inp); @@ -262,35 +263,37 @@ template void LCAO_domain::set_psi_occ_dm_chg>( template void LCAO_domain::set_pot( UnitCell &ucell, - K_Vectors &kv, - Structure_Factor& sf, - const ModulePW::PW_Basis &pw_rho, - const ModulePW::PW_Basis &pw_rhod, + K_Vectors &kv, + Structure_Factor& sf, + const ModulePW::PW_Basis &pw_rho, + const ModulePW::PW_Basis &pw_rhod, elecstate::ElecState* pelec, const LCAO_Orbitals& orb, - Parallel_Orbitals &pv, - pseudopot_cell_vl &locpp, + Parallel_Orbitals &pv, + pseudopot_cell_vl &locpp, Plus_U &dftu, surchem& solvent, Exx_NAO &exx_nao, Setup_DeePKS &deepks, - const Input_para &inp); + const Input_para &inp, + Exx_Info& exx_info); template void LCAO_domain::set_pot>( UnitCell &ucell, - K_Vectors &kv, - Structure_Factor& sf, - const ModulePW::PW_Basis &pw_rho, - const ModulePW::PW_Basis &pw_rhod, + K_Vectors &kv, + Structure_Factor& sf, + const ModulePW::PW_Basis &pw_rho, + const ModulePW::PW_Basis &pw_rhod, elecstate::ElecState* pelec, const LCAO_Orbitals& orb, - Parallel_Orbitals &pv, - pseudopot_cell_vl &locpp, + Parallel_Orbitals &pv, + pseudopot_cell_vl &locpp, Plus_U &dftu, surchem& solvent, Exx_NAO> &exx_nao, Setup_DeePKS> &deepks, - const Input_para &inp); + const Input_para &inp, + Exx_Info& exx_info); template void LCAO_domain::init_dm_from_file( const std::string& readin_dir, diff --git a/source/source_lcao/lcao_set.h b/source/source_lcao/lcao_set.h index ad949866e9a..f3defdb9823 100644 --- a/source/source_lcao/lcao_set.h +++ b/source/source_lcao/lcao_set.h @@ -40,19 +40,20 @@ void set_psi_occ_dm_chg( template void set_pot( UnitCell &ucell, - K_Vectors &kv, - Structure_Factor& sf, - const ModulePW::PW_Basis &pw_rho, - const ModulePW::PW_Basis &pw_rhod, + K_Vectors &kv, + Structure_Factor& sf, + const ModulePW::PW_Basis &pw_rho, + const ModulePW::PW_Basis &pw_rhod, elecstate::ElecState* pelec, const LCAO_Orbitals& orb, - Parallel_Orbitals &pv, - pseudopot_cell_vl &locpp, + Parallel_Orbitals &pv, + pseudopot_cell_vl &locpp, Plus_U &dftu, surchem& solvent, Exx_NAO &exx_nao, Setup_DeePKS &deepks, - const Input_para &inp); + const Input_para &inp, + Exx_Info& exx_info); /** * @brief read in DMR from file, and save it into dmat diff --git a/source/source_lcao/module_operator_lcao/op_exx_lcao.cpp b/source/source_lcao/module_operator_lcao/op_exx_lcao.cpp index 813e43bd5a1..4e58854efeb 100644 --- a/source/source_lcao/module_operator_lcao/op_exx_lcao.cpp +++ b/source/source_lcao/module_operator_lcao/op_exx_lcao.cpp @@ -136,9 +136,10 @@ OperatorEXX>::OperatorEXX( const K_Vectors& kv_in, std::vector>>>* Hexxd_in, std::vector>>>>* Hexxc_in, + const Exx_Info* exx_info, Add_Hexx_Type add_hexx_type_in) : OperatorLCAO(hsk_in, kv_in.kvec_d, hR_in), ucell(ucell), kv(kv_in), Hexxd(Hexxd_in), Hexxc(Hexxc_in), - add_hexx_type(add_hexx_type_in) + add_hexx_type(add_hexx_type_in), exx_info_ptr(exx_info) { this->cal_type = calculation_type::lcao_exx; // This one-shot constructor never builds cell_nearest, so cal_dH() must not use it: @@ -154,6 +155,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, const K_Vectors& kv_in, Exx_LRI_Interface* exd_in, Exx_LRI_Interface>* exc_in, + const Exx_Info& exx_info, Add_Hexx_Type add_hexx_type_in, const int istep_in, const bool restart_in) @@ -163,6 +165,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, kv_in, exd_in ? &exd_in->get_Hexxs() : nullptr, exc_in ? &exc_in->get_Hexxs() : nullptr, + &exx_info, add_hexx_type_in) { this->exd = exd_in; @@ -172,7 +175,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, ModuleBase::TITLE("OperatorEXX", "OperatorEXX"); const Parallel_Orbitals* const pv = hR_in->get_paraV(); - if (PARAM.inp.calculation == "nscf" && GlobalC::exx_info.info_global.cal_exx) + if (PARAM.inp.calculation == "nscf" && exx_info_ptr->info_global.cal_exx) { // for nscf, calculate HexxR from the read-in DM, or read HexxR in auto file_name_list_csr = []() -> std::vector { std::vector file_name_list; @@ -209,7 +212,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, if (PARAM.inp.init_chg == "dm" || PARAM.inp.init_chg == "dm_no_renormalize") { // 1. cal Cs, Vs - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { this->exd->cal_exx_ions(ucell, PARAM.inp.out_ri_cv); } @@ -232,7 +235,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, // 3. DM->Ds->Hexx (do not use symmetry for nscf) XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func); - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { const auto& Ds = RI_2D_Comm::dm_container_to_Ds(dmR_vec, ucell, *pv, PARAM.inp.nspin); this->exd->cal_exx_elec(Ds, ucell, *pv); @@ -257,7 +260,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, const std::string file_name_exx_csr = PARAM.globalv.global_readin_dir + "HexxR" + std::to_string(PARAM.globalv.myrank); // Read HexxR in CSR format - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { ModuleIO::read_Hexxs_csr(file_name_exx_csr, ucell, PARAM.inp.nspin, PARAM.globalv.nlocal, *Hexxd); } @@ -276,7 +279,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, { ModuleBase::WARNING_QUIT("OperatorEXX", "Can't open EXX file < " + file_name_exx_cereal + " >."); } - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { ModuleIO::read_Hexxs_cereal(file_name_exx_cereal, *Hexxd); } @@ -293,7 +296,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, // reallocate hR according to Hexx(R) if (this->add_hexx_type == Add_Hexx_Type::R) { - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { reallocate_hcontainer(*this->Hexxd, this->hR); } @@ -392,7 +395,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, if (all_exist) { // Read HexxR in CSR format - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { ModuleIO::read_Hexxs_csr(restart_HR_path, ucell, PARAM.inp.nspin, PARAM.globalv.nlocal, *Hexxd); } @@ -418,7 +421,7 @@ OperatorEXX>::OperatorEXX(HS_Matrix_K* hsk_in, } else { - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { ModuleIO::read_Hexxs_cereal(restart_HR_path_cereal, *Hexxd); } @@ -455,7 +458,7 @@ void OperatorEXX>::contributeHR() else if (this->istep == 0) { const int two_level_step - = GlobalC::exx_info.info_ri.real_number ? this->exd->get_two_level_step() : this->exc->get_two_level_step(); + = exx_info_ptr->info_ri.real_number ? this->exd->get_two_level_step() : this->exc->get_two_level_step(); // Check if we are in the pre-convergence stage of the two-level SCF (i.e., the pure GGA loop) bool in_gga_pre_loop = (two_level_step == 0); @@ -479,10 +482,10 @@ void OperatorEXX>::contributeHR() if (XC_Functional::get_func_type() == 4 || XC_Functional::get_func_type() == 5) { // add H(R) normally - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { RI_2D_Comm::add_HexxR(this->current_spin, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info_ptr->info_global.hybrid_alpha, *this->Hexxd, *this->hR->get_paraV(), PARAM.globalv.npol, @@ -492,7 +495,7 @@ void OperatorEXX>::contributeHR() else { RI_2D_Comm::add_HexxR(this->current_spin, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info_ptr->info_global.hybrid_alpha, *this->Hexxc, *this->hR->get_paraV(), PARAM.globalv.npol, @@ -510,12 +513,12 @@ template void OperatorEXX>::contributeHk(int ik) { ModuleBase::TITLE("OperatorEXX", "constributeHk"); - const bool has_workflow = GlobalC::exx_info.info_ri.real_number ? (this->exd != nullptr) : (this->exc != nullptr); + const bool has_workflow = exx_info_ptr->info_ri.real_number ? (this->exd != nullptr) : (this->exc != nullptr); int two_level_step = 0; if (has_workflow) { two_level_step - = GlobalC::exx_info.info_ri.real_number ? this->exd->get_two_level_step() : this->exc->get_two_level_step(); + = exx_info_ptr->info_ri.real_number ? this->exd->get_two_level_step() : this->exc->get_two_level_step(); } // Peize Lin add 2016-12-03 @@ -587,7 +590,7 @@ void OperatorEXX>::contributeHk(int ik) RI_2D_Comm::add_Hexx_td(ucell, this->kv, ik, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info_ptr->info_global.hybrid_alpha, *this->Hexxc, *this->hR->get_paraV(), TD_info::td_vel_op->cart_At, @@ -596,12 +599,12 @@ void OperatorEXX>::contributeHk(int ik) } else { - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info_ptr->info_ri.real_number) { RI_2D_Comm::add_Hexx(ucell, this->kv, ik, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info_ptr->info_global.hybrid_alpha, *this->Hexxd, *this->hR->get_paraV(), this->hsk->get_hk()); @@ -611,7 +614,7 @@ void OperatorEXX>::contributeHk(int ik) RI_2D_Comm::add_Hexx(ucell, this->kv, ik, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info_ptr->info_global.hybrid_alpha, *this->Hexxc, *this->hR->get_paraV(), this->hsk->get_hk()); @@ -639,7 +642,7 @@ void OperatorEXX>::cal_dH( // structure of this per-I container from the exx-form data (same cell mapping). reallocate_hcontainer(dHexxs[idir][iat], dhR[idir][iat], cell_nearest); RI_2D_Comm::add_HexxR(ispin, - GlobalC::exx_info.info_global.hybrid_alpha, + exx_info_ptr->info_global.hybrid_alpha, dHexxs[idir][iat], *paraV, PARAM.globalv.npol, @@ -654,30 +657,36 @@ template OperatorEXX>::OperatorEXX( HS_Matrix_K*, HContainer*, const UnitCell&, const K_Vectors&, std::vector>>>*, std::vector>>>>*, + const Exx_Info*, Add_Hexx_Type); template OperatorEXX, double>>::OperatorEXX( HS_Matrix_K>*, HContainer*, const UnitCell&, const K_Vectors&, std::vector>>>*, std::vector>>>>*, + const Exx_Info*, Add_Hexx_Type); template OperatorEXX, std::complex>>::OperatorEXX( HS_Matrix_K>*, HContainer>*, const UnitCell&, const K_Vectors&, std::vector>>>*, std::vector>>>>*, + const Exx_Info*, Add_Hexx_Type); // explicit member function instantiations for second constructor template OperatorEXX>::OperatorEXX( HS_Matrix_K*, HContainer*, const UnitCell&, const K_Vectors&, Exx_LRI_Interface*, Exx_LRI_Interface>*, + const Exx_Info&, Add_Hexx_Type, const int, const bool); template OperatorEXX, double>>::OperatorEXX( HS_Matrix_K>*, HContainer*, const UnitCell&, const K_Vectors&, Exx_LRI_Interface, double>*, Exx_LRI_Interface, std::complex>*, + const Exx_Info&, Add_Hexx_Type, const int, const bool); template OperatorEXX, std::complex>>::OperatorEXX( HS_Matrix_K>*, HContainer>*, const UnitCell&, const K_Vectors&, Exx_LRI_Interface, double>*, Exx_LRI_Interface, std::complex>*, + const Exx_Info&, Add_Hexx_Type, const int, const bool); // explicit member function instantiations for contributeHR diff --git a/source/source_lcao/module_operator_lcao/op_exx_lcao.h b/source/source_lcao/module_operator_lcao/op_exx_lcao.h index 1340f1f8ff9..43e8e3127b4 100644 --- a/source/source_lcao/module_operator_lcao/op_exx_lcao.h +++ b/source/source_lcao/module_operator_lcao/op_exx_lcao.h @@ -45,6 +45,7 @@ class OperatorEXX> : public OperatorLCAO const K_Vectors& kv_in, Exx_LRI_Interface* exd_in, Exx_LRI_Interface>* exc_in, + const Exx_Info& exx_info, Add_Hexx_Type add_hexx_type_in = Add_Hexx_Type::R, const int istep_in = 0, const bool restart_in = false); @@ -58,6 +59,7 @@ class OperatorEXX> : public OperatorLCAO const K_Vectors& kv_in, std::vector>>>* Hexxd_in = nullptr, std::vector>>>>* Hexxc_in = nullptr, + const Exx_Info* exx_info = nullptr, Add_Hexx_Type add_hexx_type_in = Add_Hexx_Type::R); virtual void contributeHk(int ik) override; @@ -86,6 +88,9 @@ class OperatorEXX> : public OperatorLCAO /// @brief if restart, read and save Hexx, and directly use it during the first outer loop. bool restart = false; + /// @brief EXX info, passed from ESolver + const Exx_Info* exx_info_ptr = nullptr; + const int istep = 0; // the ion step void add_loaded_Hexx(const int ik); diff --git a/source/source_lcao/module_rdmft/rdmft.cpp b/source/source_lcao/module_rdmft/rdmft.cpp index 2499dabbce9..b88440a88f4 100644 --- a/source/source_lcao/module_rdmft/rdmft.cpp +++ b/source/source_lcao/module_rdmft/rdmft.cpp @@ -65,7 +65,8 @@ void RDMFT::init(Parallel_Orbitals& ParaV_in, LCAO_Orbitals& orb_in, TwoCenterBundle& two_center_bundle_in, std::string XC_func_rdmft_in, - double alpha_power_in) + double alpha_power_in, + const Exx_Info& exx_info) { ParaV = &ParaV_in; ucell = &ucell_in; @@ -148,7 +149,8 @@ void RDMFT::init(Parallel_Orbitals& ParaV_in, // HR_local->set_zero(); #ifdef __EXX - if( GlobalC::exx_info.info_global.cal_exx ) + this->exx_info_ = &exx_info; + if( this->exx_info_->info_global.cal_exx ) { // if the irreducible k-points can change with symmetry during cell-relax, it should be moved back to update_ion() exx_spacegroup_symmetry = (PARAM.inp.nspin < 4 && ModuleSymmetry::Symmetry::symm_flag == 1); @@ -160,14 +162,14 @@ void RDMFT::init(Parallel_Orbitals& ParaV_in, this->symrot_exx.cal_Ms(*kv, *ucell, *ParaV); } - if (GlobalC::exx_info.info_ri.real_number) + if (this->exx_info_->info_ri.real_number) { - Vxc_fromRI_d = new Exx_LRI(GlobalC::exx_info.info_ri); + Vxc_fromRI_d = new Exx_LRI(this->exx_info_->info_ri); Vxc_fromRI_d->init(MPI_COMM_WORLD, ucell_in,*kv, *orb); } else { - Vxc_fromRI_c = new Exx_LRI>(GlobalC::exx_info.info_ri); + Vxc_fromRI_c = new Exx_LRI>(this->exx_info_->info_ri); Vxc_fromRI_c->init(MPI_COMM_WORLD, ucell_in,*kv, *orb); } } @@ -216,7 +218,7 @@ void RDMFT::cal_Hk_Hpsi() _diagonal_in_serial( para_Eij, Eij_hartree, &(wfcHwfc_hartree(ik, 0)) ); #ifdef __EXX - if(GlobalC::exx_info.info_global.cal_exx) + if(this->exx_info_->info_global.cal_exx) { hsk_exx_XC->set_zero_hk(); @@ -318,7 +320,7 @@ void RDMFT::cal_Energy(const int cal_type) // for Exc E_RDMFT[2] = 0.0; #ifdef __EXX - if( GlobalC::exx_info.info_global.cal_exx ) + if( this->exx_info_->info_global.cal_exx ) { ModuleBase::matrix Exc_n_k(wg.nr, wg.nc, true); // because we have got wk_fun_occNum, we can use symbol=1 realize it @@ -370,7 +372,7 @@ void RDMFT::cal_Energy(const int cal_type) { GlobalV::ofs_running << "\n\nfrom class RDMFT: \nXC_fun: " << XC_func_rdmft << std::endl; #ifdef __EXX - if( GlobalC::exx_info.info_global.cal_exx ) { GlobalV::ofs_running << "alpha_power: " << alpha_power << std::endl; + if( this->exx_info_->info_global.cal_exx ) { GlobalV::ofs_running << "alpha_power: " << alpha_power << std::endl; } #endif // GlobalV::ofs_running << std::setprecision(12); diff --git a/source/source_lcao/module_rdmft/rdmft.h b/source/source_lcao/module_rdmft/rdmft.h index b3275e12441..b197b0fe44a 100644 --- a/source/source_lcao/module_rdmft/rdmft.h +++ b/source/source_lcao/module_rdmft/rdmft.h @@ -27,6 +27,7 @@ template class Exx_LRI; #include "source_estate/elecstate.h" #include "source_cell/module_neighbor/sltk_grid_driver.h" // use Grid_Driver +#include "source_hamilt/module_xc/exx_info.h" #include #include @@ -88,7 +89,8 @@ class RDMFT LCAO_Orbitals& orb_in, TwoCenterBundle& two_center_bundle_in, std::string XC_func_rdmft_in, - double alpha_power_in); + double alpha_power_in, + const Exx_Info& exx_info); //! update in ion-step and get V_TV void update_ion(UnitCell& ucell_in, ModulePW::PW_Basis& rho_basis_in, @@ -180,6 +182,7 @@ class RDMFT Exx_LRI>* Vxc_fromRI_c = nullptr; ModuleSymmetry::Symmetry_rotation symrot_exx; bool exx_spacegroup_symmetry = false; + const Exx_Info* exx_info_ = nullptr; #endif double etxc = 0.0; diff --git a/source/source_lcao/module_rdmft/rdmft_pot.cpp b/source/source_lcao/module_rdmft/rdmft_pot.cpp index 70c837227d8..1f692833aad 100644 --- a/source/source_lcao/module_rdmft/rdmft_pot.cpp +++ b/source/source_lcao/module_rdmft/rdmft_pot.cpp @@ -232,7 +232,7 @@ void RDMFT::cal_V_XC(const UnitCell& ucell) } #ifdef __EXX - if(GlobalC::exx_info.info_global.cal_exx) + if(this->exx_info_->info_global.cal_exx) { HR_exx_XC->set_zero(); @@ -247,7 +247,7 @@ void RDMFT::cal_V_XC(const UnitCell& ucell) for(int ik=0; ikexx_info_->info_ri.real_number) { // transfer the DM_XC to appropriate format std::vector>,RI::Tensor>>> @@ -256,7 +256,7 @@ void RDMFT::cal_V_XC(const UnitCell& ucell) : RI_2D_Comm::split_m2D_ktoR(ucell,*kv, DM_XC_pointer, *ParaV, nspin, this->exx_spacegroup_symmetry); // provide the Ds_XC to Vxc_fromRI(V_exx_XC) - if (this->exx_spacegroup_symmetry && GlobalC::exx_info.info_ri.exx_symmetry_realspace) + if (this->exx_spacegroup_symmetry && this->exx_info_->info_ri.exx_symmetry_realspace) { Vxc_fromRI_d->cal_exx_elec(Ds_XC_d, ucell,*ParaV, &this->symrot_exx); } @@ -273,6 +273,7 @@ void RDMFT::cal_V_XC(const UnitCell& ucell) *kv, &Vxc_fromRI_d->Hexxs, nullptr, + this->exx_info_, hamilt::Add_Hexx_Type::k ); } @@ -285,7 +286,7 @@ void RDMFT::cal_V_XC(const UnitCell& ucell) : RI_2D_Comm::split_m2D_ktoR>(ucell,*kv, DM_XC_pointer, *ParaV, nspin, this->exx_spacegroup_symmetry); // // provide the Ds_XC to Vxc_fromRI(V_exx_XC) - if (this->exx_spacegroup_symmetry && GlobalC::exx_info.info_ri.exx_symmetry_realspace) + if (this->exx_spacegroup_symmetry && this->exx_info_->info_ri.exx_symmetry_realspace) { Vxc_fromRI_c->cal_exx_elec(Ds_XC_c, ucell,*ParaV, &this->symrot_exx); } @@ -302,6 +303,7 @@ void RDMFT::cal_V_XC(const UnitCell& ucell) *kv, nullptr, &Vxc_fromRI_c->Hexxs, + this->exx_info_, hamilt::Add_Hexx_Type::k ); } diff --git a/source/source_lcao/module_rdmft/update_state_rdmft.cpp b/source/source_lcao/module_rdmft/update_state_rdmft.cpp index 551f0852061..69ca9d2d528 100644 --- a/source/source_lcao/module_rdmft/update_state_rdmft.cpp +++ b/source/source_lcao/module_rdmft/update_state_rdmft.cpp @@ -30,9 +30,9 @@ void RDMFT::update_ion(UnitCell& ucell_in, HR_TV->set_zero(); this->cal_V_TV(); #ifdef __EXX - if( GlobalC::exx_info.info_global.cal_exx ) + if( this->exx_info_->info_global.cal_exx ) { - if (GlobalC::exx_info.info_ri.real_number) + if (this->exx_info_->info_ri.real_number) { Vxc_fromRI_d->cal_exx_ions(ucell_in); } diff --git a/source/source_lcao/module_ri/conv_coulomb_pot_k.h b/source/source_lcao/module_ri/conv_coulomb_pot_k.h index ca3ce4ce40f..5534160a0a5 100644 --- a/source/source_lcao/module_ri/conv_coulomb_pot_k.h +++ b/source/source_lcao/module_ri/conv_coulomb_pot_k.h @@ -1,28 +1,18 @@ #ifndef CONV_COULOMB_POT_K_H #define CONV_COULOMB_POT_K_H -#include -#include -#include +#include "source_hamilt/module_xc/coulomb_config.h" namespace Conv_Coulomb_Pot_K { - enum class Coulomb_Type{Fock, Erfc}; - enum class Ccp_Type{ // parameter: - Ccp, // - Hf, // "hf_Rcut" - Erfc, // "hse_omega" - Erf}; // "hse_omega", "hf_Rcut" - enum class Coulomb_Method{Center2, Ewald}; // Different methods for constructing the Coulomb matrix. - template extern T cal_orbs_ccp( const T &orbs, - const std::map>> &coulomb_param, + const CoulombParam &coulomb_param, const double rmesh_times); template extern T cal_orbs_ccp_spencer( const T &orbs, - const std::map>> &coulomb_param, + const CoulombParam &coulomb_param, const double rmesh_times); //private: @@ -48,8 +38,6 @@ namespace Conv_Coulomb_Pot_K const double rcut); } -using CoulombParam = std::map>>; - #include "conv_coulomb_pot_k.hpp" #endif \ No newline at end of file diff --git a/source/source_lcao/module_ri/rpa_lri.hpp b/source/source_lcao/module_ri/rpa_lri.hpp index 34ecc5f5f44..7a5f7fb5fe0 100644 --- a/source/source_lcao/module_ri/rpa_lri.hpp +++ b/source/source_lcao/module_ri/rpa_lri.hpp @@ -184,9 +184,9 @@ void RPA_LRI::cal_postSCF_exx(const elecstate::DensityMatrix exx_spacegroup_symmetry); // reserve exx_ccp_rmesh_times to calculate full Coulomb - // Note: ccp_type=Hf and hybrid_alpha=1 were previously set on GlobalC::exx_info.info_global + // Note: ccp_type=Hf and hybrid_alpha=1 were previously set on the global Exx_Info // and sync_from_global() was called, but this->info (value copy) already has the correct - // coulomb_param from construction time, so the global writes are redundant and removed. + // coulomb_param from construction time, so those writes are redundant and removed. this->ccp_rmesh_times_ewald = this->info.ccp_rmesh_times; // Using rpa_ccp_rmesh_times to calculate cut Coulomb this->Vs_period Exx_Info_RI local_info = this->info; diff --git a/source/source_lcao/setup_exx.cpp b/source/source_lcao/setup_exx.cpp index 333b4b1ffbf..736b69322ad 100644 --- a/source/source_lcao/setup_exx.cpp +++ b/source/source_lcao/setup_exx.cpp @@ -2,7 +2,6 @@ #ifdef __EXX #include "source_lcao/module_ri/exx_lri_interface.h" -#include "source_hamilt/module_xc/exx_info.h" // use the global Exx_Info #endif template @@ -13,7 +12,7 @@ Exx_NAO::~Exx_NAO(){} template -void Exx_NAO::init(const UnitCell& ucell) +void Exx_NAO::init(const UnitCell& ucell, Exx_Info& exx_info) { #ifdef __EXX // 1. currently this initialization must be put in constructor rather than `before_all_runners()` @@ -26,17 +25,17 @@ void Exx_NAO::init(const UnitCell& ucell) // broadcast with it). Copy them into the EXX info here, before Exx_LRI copies // info_ri below. This keeps the EXX-specific routing (which list feeds info_ri // vs info_opt_abfs) in the LCAO EXX layer, so source_cell stays decoupled. - GlobalC::exx_info.info_ri.files_abfs = ucell.abfs_orbital_files; - GlobalC::exx_info.info_opt_abfs.files_abfs = ucell.abfs_orbital_files; - GlobalC::exx_info.info_opt_abfs.files_jles = ucell.jle_orbital_files; + exx_info.info_ri.files_abfs = ucell.abfs_orbital_files; + exx_info.info_opt_abfs.files_abfs = ucell.abfs_orbital_files; + exx_info.info_opt_abfs.files_jles = ucell.jle_orbital_files; - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info.info_ri.real_number) { - this->exd = std::make_shared>(GlobalC::exx_info.info_ri, GlobalC::exx_info.info_global); + this->exd = std::make_shared>(exx_info.info_ri, exx_info.info_global); } else { - this->exc = std::make_shared>>(GlobalC::exx_info.info_ri, GlobalC::exx_info.info_global); + this->exc = std::make_shared>>(exx_info.info_ri, exx_info.info_global); } #endif } @@ -45,15 +44,16 @@ template void Exx_NAO::before_runner( UnitCell& ucell, // unitcell K_Vectors &kv, // k points - const LCAO_Orbitals &orb, // orbital info + const LCAO_Orbitals &orb, // orbital info const Parallel_Orbitals &pv, // parallel orbitals - const Input_para& inp) + const Input_para& inp, + Exx_Info& exx_info) { #ifdef __EXX if (inp.calculation == "scf" || inp.calculation == "relax" || inp.calculation == "cell-relax" || inp.calculation == "md") { - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { if (inp.init_wfc != "file") { // if init_wfc==file, directly enter the EXX loop @@ -61,7 +61,7 @@ void Exx_NAO::before_runner( } // initialize 2-center radial tables for EXX-LRI - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info.info_ri.real_number) { this->exd->init(MPI_COMM_WORLD, ucell, kv, orb); this->exd->exx_before_all_runners(kv, ucell, pv); @@ -76,9 +76,9 @@ void Exx_NAO::before_runner( else if (inp.calculation == "nscf" && (inp.init_chg == "dm" || inp.init_chg == "dm_no_renormalize")) { // init exx integration tables for Cs/Vs, but not use symmetry for nscf - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info.info_global.cal_exx) { - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info.info_ri.real_number) { this->exd->init(MPI_COMM_WORLD, ucell, kv, orb); } @@ -99,12 +99,13 @@ void Exx_NAO::before_scf( const LCAO_Orbitals &orb, // orbital info Charge_Mixing* p_chgmix, const int istep, - const Input_para& inp) + const Input_para& inp, + Exx_Info& exx_info) { #ifdef __EXX if (PARAM.inp.calculation != "nscf") { - if (GlobalC::exx_info.info_ri.real_number) + if (exx_info.info_ri.real_number) { this->exd->exx_beforescf(istep, kv, *p_chgmix, ucell, orb); } diff --git a/source/source_lcao/setup_exx.h b/source/source_lcao/setup_exx.h index 4718b42c6aa..d91c15b0b91 100644 --- a/source/source_lcao/setup_exx.h +++ b/source/source_lcao/setup_exx.h @@ -7,6 +7,7 @@ #include "source_basis/module_ao/parallel_orbitals.h" // parallel orbitals #include "source_basis/module_ao/orb_read.h" // orb #include "source_estate/module_charge/charge_mixing.h" // use charge mixing +#include "source_hamilt/module_xc/exx_info.h" // for Exx_Info // for EXX #ifdef __EXX @@ -28,14 +29,15 @@ class Exx_NAO std::shared_ptr>> exc = nullptr; #endif - void init(const UnitCell& ucell); + void init(const UnitCell& ucell, Exx_Info& exx_info); void before_runner( UnitCell& ucell, // unitcell K_Vectors &kv, // k points const LCAO_Orbitals &orb, // orbital info const Parallel_Orbitals &pv, // parallel orbitals - const Input_para& inp); + const Input_para& inp, + Exx_Info& exx_info); void before_scf( const UnitCell &ucell, // unitcell @@ -43,7 +45,8 @@ class Exx_NAO const LCAO_Orbitals &orb, // orbital info Charge_Mixing* p_chgmix, const int istep, - const Input_para& inp); + const Input_para& inp, + Exx_Info& exx_info); }; diff --git a/source/source_main/driver_run.cpp b/source/source_main/driver_run.cpp index de1356c56ca..a1d463b5be4 100644 --- a/source/source_main/driver_run.cpp +++ b/source/source_main/driver_run.cpp @@ -2,6 +2,7 @@ #include "source_cell/check_atomic_stru.h" #include "source_cell/module_neighbor/sltk_atom_arrange.h" #include "source_relax/relax_driver.h" +#include "source_esolver/esolver_factory.h" #include "source_io/module_parameter/parameter.h" #include "source_io/module_json/para_json.h" #include "source_io/module_output/print_info.h" diff --git a/source/source_pw/module_pwdft/exx_helper.cpp b/source/source_pw/module_pwdft/exx_helper.cpp index 68ab9d8f9da..3f117482540 100644 --- a/source/source_pw/module_pwdft/exx_helper.cpp +++ b/source/source_pw/module_pwdft/exx_helper.cpp @@ -1,6 +1,6 @@ #include "exx_helper.h" #include "source_io/module_parameter/parameter.h" -#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info +#include "source_hamilt/module_xc/general_exx_info.h" // for General_Exx_Info type #include "source_hamilt/module_xc/xc_functional.h" // use XC_Functional #include "source_pw/module_pwdft/hamilt_pw.h" // use HamiltPW #include "source_estate/update_pot.h" // use elecstate::update_pot @@ -9,20 +9,20 @@ #include // for timing template -void Exx_Helper::init(const UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& wg) +void Exx_Helper::init(const UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& wg, const General_Exx_Info& exx_info) { - if (inp.calculation != "scf" && inp.calculation != "relax" + if (inp.calculation != "scf" && inp.calculation != "relax" && inp.calculation != "cell-relax" && inp.calculation != "md") { return; } - if (!GlobalC::exx_info.info_global.cal_exx) + if (!exx_info.cal_exx) { return; } - if (GlobalC::exx_info.info_global.separate_loop) + if (exx_info.separate_loop) { XC_Functional::set_xc_first_loop(ucell); this->set_firstiter(); @@ -32,7 +32,7 @@ void Exx_Helper::init(const UnitCell& ucell, const Input_para& inp, c } template -void Exx_Helper::before_scf(void* p_hamilt, void* psi, const Input_para& inp) +void Exx_Helper::before_scf(void* p_hamilt, void* psi, const Input_para& inp, const General_Exx_Info& exx_info) { /// Return if not a valid calculation type if (inp.calculation != "scf" && inp.calculation != "relax" @@ -42,7 +42,7 @@ void Exx_Helper::before_scf(void* p_hamilt, void* psi, const Input_pa } /// Return if EXX is not enabled or not PW basis - if (!GlobalC::exx_info.info_global.cal_exx || inp.basis_type != "pw") + if (!exx_info.cal_exx || inp.basis_type != "pw") { return; } diff --git a/source/source_pw/module_pwdft/exx_helper.h b/source/source_pw/module_pwdft/exx_helper.h index 96f0a37a7f3..2adb945b8b6 100644 --- a/source/source_pw/module_pwdft/exx_helper.h +++ b/source/source_pw/module_pwdft/exx_helper.h @@ -20,9 +20,9 @@ struct Exx_Helper : public Exx_HelperBase virtual ~Exx_Helper() = default; OperatorEXX *op_exx = nullptr; - void init(const UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& wg) override; + void init(const UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& wg, const General_Exx_Info& exx_info) override; - void before_scf(void* p_hamilt, void* psi, const Input_para& inp) override; + void before_scf(void* p_hamilt, void* psi, const Input_para& inp, const General_Exx_Info& exx_info) override; bool iter_finish(void* p_elec, Charge* p_charge, void* psi, UnitCell& ucell, const Input_para& inp, diff --git a/source/source_pw/module_pwdft/exx_helper_base.h b/source/source_pw/module_pwdft/exx_helper_base.h index 60eda82b359..7ebab443948 100644 --- a/source/source_pw/module_pwdft/exx_helper_base.h +++ b/source/source_pw/module_pwdft/exx_helper_base.h @@ -6,6 +6,7 @@ class Charge; class UnitCell; struct Input_para; +struct General_Exx_Info; class Exx_HelperBase { @@ -13,9 +14,9 @@ class Exx_HelperBase Exx_HelperBase() = default; virtual ~Exx_HelperBase() = default; - virtual void init(const UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& wg) = 0; + virtual void init(const UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& wg, const General_Exx_Info& exx_info) = 0; - virtual void before_scf(void* p_hamilt, void* psi, const Input_para& inp) = 0; + virtual void before_scf(void* p_hamilt, void* psi, const Input_para& inp, const General_Exx_Info& exx_info) = 0; virtual bool iter_finish(void* p_elec, Charge* p_charge, void* psi, UnitCell& ucell, const Input_para& inp, diff --git a/source/source_pw/module_pwdft/hamilt_lcaopw.h b/source/source_pw/module_pwdft/hamilt_lcaopw.h index a5b2cedb6e5..414c5cddb95 100644 --- a/source/source_pw/module_pwdft/hamilt_lcaopw.h +++ b/source/source_pw/module_pwdft/hamilt_lcaopw.h @@ -18,7 +18,7 @@ namespace hamilt K_Vectors* p_kv, pseudopot_cell_vnl* nlpp, const UnitCell* ucell) - : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell){}; + : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell, nullptr){}; #ifdef __EXX HamiltLIP(elecstate::Potential* pot_in, ModulePW::PW_Basis_K* wfc_basis, @@ -26,7 +26,7 @@ namespace hamilt pseudopot_cell_vnl* nlpp, const UnitCell* ucell, Exx_Lip& exx_lip_in) - : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell), + : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell, nullptr), exx_lip(exx_lip_in){}; Exx_Lip& exx_lip; #endif diff --git a/source/source_pw/module_pwdft/hamilt_pw.cpp b/source/source_pw/module_pwdft/hamilt_pw.cpp index 6b858428f54..e0b309f29ea 100644 --- a/source/source_pw/module_pwdft/hamilt_pw.cpp +++ b/source/source_pw/module_pwdft/hamilt_pw.cpp @@ -9,7 +9,7 @@ #include "source_base/global_function.h" #include "source_base/global_variable.h" #include "source_base/parallel_reduce.h" -#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info +#include "source_hamilt/module_xc/general_exx_info.h" // for General_Exx_Info type #include "source_io/module_parameter/parameter.h" namespace hamilt @@ -21,7 +21,8 @@ HamiltPW::HamiltPW(elecstate::Potential* pot_in, K_Vectors* pkv, pseudopot_cell_vnl* nlpp, Plus_U* p_dftu, // mohan add 2025-11-06 - const UnitCell* ucell) + const UnitCell* ucell, + const General_Exx_Info* exx_info) : ucell(ucell) { this->classname = "HamiltPW"; @@ -130,11 +131,11 @@ HamiltPW::HamiltPW(elecstate::Potential* pot_in, (PARAM.inp.dft_plus_u > 0)); this->ops->add(onsite_proj); } - if (GlobalC::exx_info.info_global.cal_exx) + if (exx_info && exx_info->cal_exx) { - bool separate_loop = GlobalC::exx_info.info_global.separate_loop; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; - auto coulomb_param = GlobalC::exx_info.info_global.coulomb_param; + bool separate_loop = exx_info->separate_loop; + double hybrid_alpha = exx_info->hybrid_alpha; + auto coulomb_param = exx_info->coulomb_param; auto exx = new OperatorEXXPW(isk, wfc_basis, pot_in->get_rho_basis(), pkv, ucell, separate_loop, hybrid_alpha, coulomb_param); if (this->ops == nullptr) { diff --git a/source/source_pw/module_pwdft/hamilt_pw.h b/source/source_pw/module_pwdft/hamilt_pw.h index 898c57a9859..ab5d6fa9611 100644 --- a/source/source_pw/module_pwdft/hamilt_pw.h +++ b/source/source_pw/module_pwdft/hamilt_pw.h @@ -10,6 +10,9 @@ #include "source_pw/module_pwdft/exx_helper.h" #include "source_pw/module_pwdft/vnl_pw.h" +/// General_Exx_Info forward declaration, full definition in general_exx_info.h +struct General_Exx_Info; + namespace hamilt { @@ -29,7 +32,8 @@ class HamiltPW : public Hamilt K_Vectors* p_kv, pseudopot_cell_vnl* nlpp, Plus_U* p_dftu, // mohan add 2025-11-06 - const UnitCell* ucell); + const UnitCell* ucell, + const General_Exx_Info* exx_info); ~HamiltPW(); diff --git a/source/source_pw/module_pwdft/stress_pw.cpp b/source/source_pw/module_pwdft/stress_pw.cpp index dae145c5c48..fa81550434a 100644 --- a/source/source_pw/module_pwdft/stress_pw.cpp +++ b/source/source_pw/module_pwdft/stress_pw.cpp @@ -6,13 +6,13 @@ #include "source_hamilt/module_vdw/vdw.h" #include "source_io/module_output/output_log.h" #include "source_hamilt/module_xc/xc_functional.h" -#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info +#include "source_hamilt/module_xc/general_exx_info.h" // for General_Exx_Info type template void Stress_PW::cal_stress(ModuleBase::matrix& sigmatot, UnitCell& ucell, const vdw::VdwResult* vdw_result, - Plus_U &dftu, // mhan add 2025-11-07 + Plus_U &dftu, // mhan add 2025-11-07 const pseudopot_cell_vl& locpp, const pseudopot_cell_vnl& nlpp, ModulePW::PW_Basis* rho_basis, @@ -20,6 +20,7 @@ void Stress_PW::cal_stress(ModuleBase::matrix& sigmatot, Structure_Factor* p_sf, K_Vectors* p_kv, ModulePW::PW_Basis_K* wfc_basis, + const General_Exx_Info& exx_info, const psi::Psi , Device>* d_psi_in) { ModuleBase::TITLE("Stress_PW", "cal_stress"); @@ -135,9 +136,9 @@ void Stress_PW::cal_stress(ModuleBase::matrix& sigmatot, } // EXX PW stress - bool cal_exx = GlobalC::exx_info.info_global.cal_exx; - double hybrid_alpha = GlobalC::exx_info.info_global.hybrid_alpha; - auto coulomb_param = GlobalC::exx_info.info_global.coulomb_param; + bool cal_exx = exx_info.cal_exx; + double hybrid_alpha = exx_info.hybrid_alpha; + auto coulomb_param = exx_info.coulomb_param; if (cal_exx) { this->stress_exx(sigmaexx, this->pelec->wg, rho_basis, wfc_basis, p_kv, d_psi_in, ucell, hybrid_alpha, coulomb_param); diff --git a/source/source_pw/module_pwdft/stress_pw.h b/source/source_pw/module_pwdft/stress_pw.h index d77665d9163..030a3414233 100644 --- a/source/source_pw/module_pwdft/stress_pw.h +++ b/source/source_pw/module_pwdft/stress_pw.h @@ -5,13 +5,16 @@ #include "source_pw/module_pwdft/vl_pw.h" #include "stress_func.h" #include "source_lcao/module_dftu/dftu.h" // mohan add 2025-11-07 -#include "source_lcao/module_ri/conv_coulomb_pot_k.h" +#include "source_hamilt/module_xc/coulomb_config.h" namespace vdw { struct VdwResult; } +/// General_Exx_Info forward declaration, full definition in general_exx_info.h +struct General_Exx_Info; + template class Stress_PW : public Stress_Func { @@ -22,7 +25,7 @@ class Stress_PW : public Stress_Func void cal_stress(ModuleBase::matrix& smearing_sigmatot, UnitCell& ucell, const vdw::VdwResult* vdw_result, - Plus_U &dftu, // mhan add 2025-11-07 + Plus_U &dftu, // mhan add 2025-11-07 const pseudopot_cell_vl& locpp, const pseudopot_cell_vnl& nlpp, ModulePW::PW_Basis* rho_basis, @@ -30,6 +33,7 @@ class Stress_PW : public Stress_Func Structure_Factor* p_sf, K_Vectors* p_kv, ModulePW::PW_Basis_K* wfc_basis, + const General_Exx_Info& exx_info, const psi::Psi , Device>* d_psi_in = nullptr); protected: diff --git a/source/source_pw/module_stodft/hamilt_sdft_pw.cpp b/source/source_pw/module_stodft/hamilt_sdft_pw.cpp index 91a6d853105..90151972285 100644 --- a/source/source_pw/module_stodft/hamilt_sdft_pw.cpp +++ b/source/source_pw/module_stodft/hamilt_sdft_pw.cpp @@ -14,7 +14,7 @@ HamiltSdftPW::HamiltSdftPW(elecstate::Potential* pot_in, const int& npol, Real* emin_in, Real* emax_in) - : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell), ngk(p_kv->ngk) + : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell, nullptr), ngk(p_kv->ngk) { this->classname = "HamiltSdftPW"; this->npwk_max = wfc_basis->npwk_max; diff --git a/source/source_pw/module_stodft/sto_che.cpp b/source/source_pw/module_stodft/sto_che.cpp index f59cbd08fcf..1a78c41162e 100644 --- a/source/source_pw/module_stodft/sto_che.cpp +++ b/source/source_pw/module_stodft/sto_che.cpp @@ -4,27 +4,28 @@ #include "source_base/module_container/ATen/kernels/blas.h" template -StoChe::~StoChe() +void StoChe::init(const int& nche, const int& method, const REAL& emax_sto, const REAL& emin_sto) { - delete p_che; - delete[] spolyv_cpu; - delmem_var_op()(spolyv); -} + // release old resources first (safe for default-constructed state too) + this->p_che.reset(); + this->spolyv.reset(); + this->spolyv_cpu.clear(); -template -StoChe::StoChe(const int& nche, const int& method, const REAL& emax_sto, const REAL& emin_sto) -{ this->nche = nche; this->method_sto = method; - p_che = new ModuleBase::Chebyshev(nche); + this->p_che.reset(new ModuleBase::Chebyshev(nche)); if (method == 1) { - resmem_var_op()(spolyv, nche); - spolyv_cpu = new REAL[nche]; + REAL* spolyv_ptr = nullptr; + resmem_var_op()(spolyv_ptr, nche); + this->spolyv.reset(spolyv_ptr); + this->spolyv_cpu.resize(nche); } else { - resmem_var_op()(spolyv, nche * nche); + REAL* spolyv_ptr = nullptr; + resmem_var_op()(spolyv_ptr, nche * nche); + this->spolyv.reset(spolyv_ptr); } this->emax_sto = emax_sto; @@ -34,4 +35,4 @@ StoChe::StoChe(const int& nche, const int& method, const REAL& ema template class StoChe; #if ((defined __CUDA) || (defined __ROCM)) template class StoChe; -#endif \ No newline at end of file +#endif diff --git a/source/source_pw/module_stodft/sto_che.h b/source/source_pw/module_stodft/sto_che.h index 15cbd84e9f7..2c142cf375d 100644 --- a/source/source_pw/module_stodft/sto_che.h +++ b/source/source_pw/module_stodft/sto_che.h @@ -4,28 +4,13 @@ #include "source_base/kernels/math_kernel_op.h" #include "source_base/module_container/ATen/kernels/blas.h" +#include +#include + template class StoChe { - public: - StoChe(const int& nche, const int& method, const REAL& emax_sto, const REAL& emin_sto); - ~StoChe(); - - public: - int nche = 0; ///< order of Chebyshev expansion - REAL* spolyv = nullptr; ///< [Device] coefficients of Chebyshev expansion - REAL* spolyv_cpu = nullptr; ///< [CPU] coefficients of Chebyshev expansion - int method_sto = 0; ///< method for the stochastic calculation - - // Chebyshev expansion - // It stores the plan of FFTW and should be initialized at the beginning of the calculation - ModuleBase::Chebyshev* p_che = nullptr; - - REAL emax_sto = 0.0; ///< maximum energy for normalization - REAL emin_sto = 0.0; ///< minimum energy for normalization - private: - Device* ctx = {}; #ifdef __DSP using resmem_var_op = base_device::memory::resize_memory_op_mt; using delmem_var_op = base_device::memory::delete_memory_op_mt; @@ -34,6 +19,44 @@ class StoChe using delmem_var_op = base_device::memory::delete_memory_op; #endif using syncmem_var_d2h_op = base_device::memory::synchronize_memory_op; + + /// @brief deleter for device-side spolyv buffer + struct delmem_var_deleter + { + void operator()(REAL* p) const + { + if (p) + { + delmem_var_op()(p); + } + } + }; + + public: + StoChe() = default; + ~StoChe() = default; + + StoChe(const StoChe&) = delete; + StoChe& operator=(const StoChe&) = delete; + StoChe(StoChe&&) noexcept = default; + StoChe& operator=(StoChe&&) noexcept = default; + + /// @brief (Re)allocate Chebyshev expansion buffers. Safe to call multiple times. + void init(const int& nche, const int& method, const REAL& emax_sto, const REAL& emin_sto); + + int nche = 0; ///< order of Chebyshev expansion + std::unique_ptr spolyv; ///< [Device] coefficients of Chebyshev expansion + std::vector spolyv_cpu; ///< [CPU] coefficients of Chebyshev expansion (method==1 only) + int method_sto = 0; ///< method for the stochastic calculation + + /// Chebyshev expansion. Stores the plan of FFTW and should be initialized at the beginning of the calculation + std::unique_ptr> p_che; + + REAL emax_sto = 0.0; ///< maximum energy for normalization + REAL emin_sto = 0.0; ///< minimum energy for normalization + + private: + Device* ctx = {}; }; /** diff --git a/source/source_pw/module_stodft/sto_iter.cpp b/source/source_pw/module_stodft/sto_iter.cpp index f2fb7cd0e61..dcc2e187a78 100644 --- a/source/source_pw/module_stodft/sto_iter.cpp +++ b/source/source_pw/module_stodft/sto_iter.cpp @@ -41,9 +41,9 @@ void Stochastic_Iter::init(K_Vectors* pkv_in, StoChe& stoche, hamilt::HamiltSdftPW* p_hamilt_sto) { - p_che = stoche.p_che; - spolyv = stoche.spolyv; - spolyv_cpu = stoche.spolyv_cpu; + p_che = stoche.p_che.get(); + spolyv = stoche.spolyv.get(); + spolyv_cpu = stoche.spolyv_cpu.data(); nchip = stowf.nchip; targetne = PARAM.inp.nelec; this->pkv = pkv_in; diff --git a/source/source_pw/module_stodft/test/test_hamilt_sto.cpp b/source/source_pw/module_stodft/test/test_hamilt_sto.cpp index a1937caf056..126ef923fb3 100644 --- a/source/source_pw/module_stodft/test/test_hamilt_sto.cpp +++ b/source/source_pw/module_stodft/test/test_hamilt_sto.cpp @@ -10,12 +10,13 @@ void elecstate::Potential::cal_fixed_v(double*){} template hamilt::HamiltPW::HamiltPW( - elecstate::Potential* pot_in, - ModulePW::PW_Basis_K* wfc_basis, - K_Vectors* p_kv, + elecstate::Potential* pot_in, + ModulePW::PW_Basis_K* wfc_basis, + K_Vectors* p_kv, pseudopot_cell_vnl* ppcell, Plus_U* p_dftu, // mohan add 20251108 - const UnitCell* ucell){} + const UnitCell* ucell, + const General_Exx_Info* exx_info){} template hamilt::HamiltPW::~HamiltPW(){ diff --git a/source/source_pw/module_stodft/test/test_sto_tool.cpp b/source/source_pw/module_stodft/test/test_sto_tool.cpp index 79d4cdcf223..81081f869a5 100644 --- a/source/source_pw/module_stodft/test/test_sto_tool.cpp +++ b/source/source_pw/module_stodft/test/test_sto_tool.cpp @@ -8,12 +8,13 @@ ***********************************************/ template -hamilt::HamiltPW::HamiltPW(elecstate::Potential* pot_in, - ModulePW::PW_Basis_K* wfc_basis, +hamilt::HamiltPW::HamiltPW(elecstate::Potential* pot_in, + ModulePW::PW_Basis_K* wfc_basis, K_Vectors* p_kv, pseudopot_cell_vnl*, Plus_U* p_dftu, // mohan add 20251108 - const UnitCell*){} + const UnitCell*, + const General_Exx_Info*){} template hamilt::HamiltPW::~HamiltPW(){}; @@ -31,7 +32,7 @@ hamilt::HamiltSdftPW::HamiltSdftPW(elecstate::Potential* pot_in, const int& npol, Real* emin_in, Real* emax_in) - : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell), ngk(p_kv->ngk) + : HamiltPW(pot_in, wfc_basis, p_kv, nlpp, nullptr, ucell, nullptr), ngk(p_kv->ngk) { }