From e511122e1ad9b8ffc34ca6e4ca9899590df039f4 Mon Sep 17 00:00:00 2001 From: linpz Date: Sat, 21 Mar 2026 05:26:40 +0800 Subject: [PATCH 1/4] Refactor: add class potential_factory --- source/Makefile.Objects | 2 +- source/source_esolver/esolver_double_xc.cpp | 10 +- source/source_esolver/esolver_of_tool.cpp | 28 +-- source/source_estate/CMakeLists.txt | 2 +- source/source_estate/module_pot/pot_local.h | 4 +- .../module_pot/potential_factory.cpp | 165 ++++++++++++++++++ .../module_pot/potential_factory.h | 59 +++++++ .../module_pot/potential_new.cpp | 49 ++---- .../source_estate/module_pot/potential_new.h | 42 ++--- .../module_pot/potential_types.cpp | 78 --------- source/source_estate/setup_estate_pw.cpp | 5 +- .../module_energy/write_eband_terms.hpp | 14 +- source/source_io/module_hs/write_vxc.hpp | 8 +- source/source_io/module_hs/write_vxc_lip.hpp | 7 +- source/source_io/module_hs/write_vxc_r.hpp | 8 +- source/source_lcao/LCAO_set.cpp | 5 +- .../source_lcao/module_rdmft/rdmft_tools.cpp | 4 +- 17 files changed, 303 insertions(+), 187 deletions(-) create mode 100644 source/source_estate/module_pot/potential_factory.cpp create mode 100644 source/source_estate/module_pot/potential_factory.h delete mode 100644 source/source_estate/module_pot/potential_types.cpp diff --git a/source/Makefile.Objects b/source/Makefile.Objects index 9f5785664f..afb414db90 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -237,7 +237,7 @@ OBJS_ELECSTAT=elecstate.o\ efield.o\ gatefield.o\ potential_new.o\ - potential_types.o\ + potential_factory.o\ pot_sep.o\ pot_local.o\ H_Hartree_pw.o\ diff --git a/source/source_esolver/esolver_double_xc.cpp b/source/source_esolver/esolver_double_xc.cpp index db65655e0b..c3b072999e 100644 --- a/source/source_esolver/esolver_double_xc.cpp +++ b/source/source_esolver/esolver_double_xc.cpp @@ -11,6 +11,7 @@ //-----HSolver ElecState Hamilt-------- #include "source_estate/elecstate_lcao.h" #include "source_estate/elecstate_tools.h" +#include "source_estate/module_pot/potential_new.h" #include "source_lcao/hamilt_lcao.h" #include "source_hsolver/hsolver_lcao.h" #include "source_io/module_parameter/parameter.h" @@ -95,14 +96,7 @@ void ESolver_DoubleXC::before_all_runners(UnitCell& ucell, const Input_p // 11) initialize the potential if (this->pelec_base->pot == nullptr) { - this->pelec_base->pot = new elecstate::Potential(this->pw_rhod, - this->pw_rho, - &ucell, - &(this->locpp.vloc), - &(this->sf), - &(this->solvent), - &(this->pelec_base->f_en.etxc), - &(this->pelec_base->f_en.vtxc)); + this->pelec_base->pot = new elecstate::Potential(this->pw_rhod, this->pw_rho, &ucell); } ModuleBase::timer::tick("ESolver_DoubleXC", "before_all_runners"); diff --git a/source/source_esolver/esolver_of_tool.cpp b/source/source_esolver/esolver_of_tool.cpp index b54f4de53a..7b1e0f0314 100644 --- a/source/source_esolver/esolver_of_tool.cpp +++ b/source/source_esolver/esolver_of_tool.cpp @@ -5,6 +5,8 @@ #include "source_estate/module_pot/gatefield.h" #include "source_io/module_parameter/parameter.h" #include "source_estate/cal_ux.h" +#include "source_estate/module_pot/potential_new.h" +#include "source_estate/module_pot/potential_factory.h" namespace ModuleESolver { @@ -22,15 +24,8 @@ void ESolver_OF::init_elecstate(UnitCell& ucell) } delete this->pelec->pot; - this->pelec->pot = new elecstate::Potential(this->pw_rhod, - this->pw_rho, - &ucell, - &(this->locpp.vloc), - &(this->sf), - &(this->solvent), - &(this->pelec->f_en.etxc), - &(this->pelec->f_en.vtxc)); - // There is no Operator in ESolver_OF, register Potentials here! + this->pelec->pot = new elecstate::Potential(this->pw_rhod, this->pw_rho); + std::vector pot_register_in; if (PARAM.inp.vion_in_h) { @@ -58,11 +53,20 @@ void ESolver_OF::init_elecstate(UnitCell& ucell) { pot_register_in.push_back("ml_exx"); } - // only Potential is not empty, Veff and Meta are available + if (pot_register_in.size() > 0) { - // register Potential by gathered operator - this->pelec->pot->pot_register(pot_register_in); + elecstate::PotentialFactory factory(&this->locpp.vloc, + &this->sf, + this->pw_rhod, + &(this->pelec->f_en.etxc), + &(this->pelec->f_en.vtxc), + this->pelec->pot->get_eff_vofk(), + &this->solvent, + nullptr, + &ucell); + auto components = factory.create_components(pot_register_in); + this->pelec->pot->set_components(std::move(components)); } } diff --git a/source/source_estate/CMakeLists.txt b/source/source_estate/CMakeLists.txt index 361df41c8b..c12ef026f5 100644 --- a/source/source_estate/CMakeLists.txt +++ b/source/source_estate/CMakeLists.txt @@ -14,7 +14,7 @@ list(APPEND objects module_pot/pot_xc.cpp module_pot/pot_local.cpp module_pot/potential_new.cpp - module_pot/potential_types.cpp + module_pot/potential_factory.cpp module_pot/pot_ml_exx.cpp module_pot/pot_ml_exx_label.cpp module_pot/pot_sep.cpp diff --git a/source/source_estate/module_pot/pot_local.h b/source/source_estate/module_pot/pot_local.h index 923e962a11..4fa93038b6 100644 --- a/source/source_estate/module_pot/pot_local.h +++ b/source/source_estate/module_pot/pot_local.h @@ -13,8 +13,8 @@ class PotLocal : public PotBase PotLocal(const ModuleBase::matrix* vloc_in, // local pseduopotentials const ModuleBase::ComplexMatrix* sf_in, const ModulePW::PW_Basis* rho_basis_in, - double& vl_of_0) - : vloc_(vloc_in), sf_(sf_in), vl_of_0_(&vl_of_0) + double* vl_of_0_ptr) + : vloc_(vloc_in), sf_(sf_in), vl_of_0_(vl_of_0_ptr) { assert(this->vloc_->nr == this->sf_->nr); this->rho_basis_ = rho_basis_in; diff --git a/source/source_estate/module_pot/potential_factory.cpp b/source/source_estate/module_pot/potential_factory.cpp new file mode 100644 index 0000000000..2f67a383f9 --- /dev/null +++ b/source/source_estate/module_pot/potential_factory.cpp @@ -0,0 +1,165 @@ +#include "potential_factory.h" +#include "H_Hartree_pw.h" +#include "efield.h" +#include "gatefield.h" +#include "pot_local.h" +#include "pot_surchem.hpp" +#include "pot_xc.h" +#include "pot_sep.h" +#include "source_base/global_function.h" +#include "source_base/global_variable.h" +#include "source_base/tool_quit.h" +#include "source_io/module_parameter/parameter.h" +#ifdef __LCAO +#include "H_TDDFT_pw.h" +#endif +#ifdef __MLALGO +#include "pot_ml_exx.h" +#endif + +namespace elecstate +{ + +PotentialFactory::PotentialFactory(const ModuleBase::matrix* vloc_in, + Structure_Factor* structure_factors_in, + const ModulePW::PW_Basis* rho_basis_in, + double* etxc_in, + double* vtxc_in, + ModuleBase::matrix& vofk_eff_out, + surchem* solvent_in, + VSep* vsep_cell_in, + const UnitCell* ucell_in) + : vloc_(vloc_in), + structure_factors_(structure_factors_in), + rho_basis_(rho_basis_in), + etxc_(etxc_in), + vtxc_(vtxc_in), + vofk_eff_(vofk_eff_out), + solvent_(solvent_in), + vsep_cell_(vsep_cell_in), + ucell_(ucell_in) +{ +} + +std::vector PotentialFactory::create_components(const std::vector& components_list) +{ + ModuleBase::TITLE("PotentialFactory", "create_components"); + std::vector components; + + for (const auto& pot_type : components_list) + { + PotBase* tmp = nullptr; + if (pot_type == "local") + { + tmp = create_pot_local(); + } + else if (pot_type == "hartree") + { + tmp = create_pot_hartree(); + } + else if (pot_type == "xc") + { + tmp = create_pot_xc(); + } + else if (pot_type == "surchem") + { + tmp = create_pot_surchem(); + } + else if (pot_type == "efield") + { + tmp = create_pot_efield(); + } + else if (pot_type == "gatefield") + { + tmp = create_pot_gatefield(); + } +#ifdef __LCAO + else if (pot_type == "tddft") + { + tmp = create_pot_tddft(); + } +#endif +#ifdef __MLALGO + else if (pot_type == "ml_exx") + { + tmp = create_pot_ml_exx(); + } +#endif + else if (pot_type == "dfthalf") + { + tmp = create_pot_dfthalf(); + } + else + { + ModuleBase::WARNING_QUIT("PotentialFactory::create_components", + "Unknown potential type: " + pot_type); + } + + if (tmp != nullptr) + { + components.push_back(tmp); + } + } + + return components; +} + +PotBase* PotentialFactory::create_pot_local() +{ + return new PotLocal(this->vloc_, + &(this->structure_factors_->strucFac), + this->rho_basis_, + nullptr); +} + +PotBase* PotentialFactory::create_pot_hartree() +{ + return new PotHartree(this->rho_basis_); +} + +PotBase* PotentialFactory::create_pot_xc() +{ + return new PotXC(this->rho_basis_, this->etxc_, this->vtxc_, &(this->vofk_eff_)); +} + +PotBase* PotentialFactory::create_pot_surchem() +{ + return new PotSurChem(this->rho_basis_, + this->structure_factors_, + nullptr, + this->solvent_); +} + +PotBase* PotentialFactory::create_pot_efield() +{ + return new PotEfield(this->rho_basis_, + this->ucell_, + this->solvent_, + PARAM.inp.dip_cor_flag); +} + +PotBase* PotentialFactory::create_pot_gatefield() +{ + return new PotGate(this->rho_basis_, this->ucell_); +} + +#ifdef __LCAO +PotBase* PotentialFactory::create_pot_tddft() +{ + return new H_TDDFT_pw(this->rho_basis_, this->ucell_); +} +#endif + +#ifdef __MLALGO +PotBase* PotentialFactory::create_pot_ml_exx() +{ + return new PotML_EXX(this->rho_basis_, this->ucell_); +} +#endif + +PotBase* PotentialFactory::create_pot_dfthalf() +{ + return new PotSep(&(this->structure_factors_->strucFac), this->rho_basis_, this->vsep_cell_); +} + +} // namespace elecstate diff --git a/source/source_estate/module_pot/potential_factory.h b/source/source_estate/module_pot/potential_factory.h new file mode 100644 index 0000000000..1987130b2e --- /dev/null +++ b/source/source_estate/module_pot/potential_factory.h @@ -0,0 +1,59 @@ +#ifndef POTENTIAL_FACTORY_H +#define POTENTIAL_FACTORY_H + +#include +#include +#include "pot_base.h" +#include "source_pw/module_pwdft/structure_factor.h" + +class UnitCell; +class surchem; +class VSep; + +namespace elecstate +{ + +class PotentialFactory +{ + public: + PotentialFactory(const ModuleBase::matrix* vloc_in, + Structure_Factor* structure_factors_in, + const ModulePW::PW_Basis* rho_basis_in, + double* etxc_in, + double* vtxc_in, + ModuleBase::matrix& vofk_eff_out, + surchem* solvent_in, + VSep* vsep_cell_in, + const UnitCell* ucell_in); + + std::vector create_components(const std::vector& components_list); + + private: + PotBase* create_pot_local(); + PotBase* create_pot_hartree(); + PotBase* create_pot_xc(); + PotBase* create_pot_surchem(); + PotBase* create_pot_efield(); + PotBase* create_pot_gatefield(); +#ifdef __LCAO + PotBase* create_pot_tddft(); +#endif +#ifdef __MLALGO + PotBase* create_pot_ml_exx(); +#endif + PotBase* create_pot_dfthalf(); + + const ModuleBase::matrix* vloc_ = nullptr; + Structure_Factor* structure_factors_ = nullptr; + const ModulePW::PW_Basis* rho_basis_ = nullptr; + double* etxc_ = nullptr; + double* vtxc_ = nullptr; + ModuleBase::matrix& vofk_eff_; + surchem* solvent_ = nullptr; + VSep* vsep_cell_ = nullptr; + const UnitCell* ucell_ = nullptr; +}; + +} // namespace elecstate + +#endif diff --git a/source/source_estate/module_pot/potential_new.cpp b/source/source_estate/module_pot/potential_new.cpp index dceab85c0b..4f0a8dedbc 100644 --- a/source/source_estate/module_pot/potential_new.cpp +++ b/source/source_estate/module_pot/potential_new.cpp @@ -16,17 +16,9 @@ namespace elecstate { Potential::Potential(const ModulePW::PW_Basis* rho_basis_in, - const ModulePW::PW_Basis* rho_basis_smooth_in, - const UnitCell* ucell_in, - const ModuleBase::matrix* vloc_in, - Structure_Factor* structure_factors_in, - surchem* solvent_in, - double* etxc_in, - double* vtxc_in, - VSep* vsep_cell_in) - : ucell_(ucell_in), vloc_(vloc_in), structure_factors_(structure_factors_in), - solvent_(solvent_in), vsep_cell(vsep_cell_in), etxc_(etxc_in), - vtxc_(vtxc_in) + const ModulePW::PW_Basis* rho_basis_smooth_in, + const UnitCell* ucell_in) + : ucell_(ucell_in) { this->rho_basis_ = rho_basis_in; this->rho_basis_smooth_ = rho_basis_smooth_in; @@ -62,10 +54,8 @@ Potential::~Potential() } } -void Potential::pot_register(const std::vector& components_list) +void Potential::set_components(std::vector components_in) { - ModuleBase::TITLE("Potential", "pot_register"); - // delete old components first. if (this->components.size() > 0) { for (auto comp: this->components) @@ -75,20 +65,8 @@ void Potential::pot_register(const std::vector& components_list) this->components.clear(); } - // register components - //--------------------------- - // mapping for register - //--------------------------- - for (auto comp: components_list) - { - PotBase* tmp = this->get_pot_type(comp); - this->components.push_back(tmp); - } - - // after register, reset fixed_done to false + this->components = std::move(components_in); this->fixed_done = false; - - return; } void Potential::allocate() @@ -102,13 +80,13 @@ void Potential::allocate() const int nrxx_smooth = this->rho_basis_smooth_->nrxx; if (nrxx == 0) - { - return; - } - if (nrxx_smooth == 0) - { - return; - } + { + return; + } + if (nrxx_smooth == 0) + { + return; + } this->v_eff_fixed.resize(nrxx); ModuleBase::Memory::record("Pot::veff_fix", sizeof(double) * nrxx); @@ -259,7 +237,6 @@ void Potential::init_pot(const Charge*const chg) this->update_from_charge(chg, this->ucell_); ModuleBase::timer::tick("Potential", "init_pot"); - return; } void Potential::get_vnew(const Charge* chg, ModuleBase::matrix& vnew) @@ -274,8 +251,6 @@ void Potential::get_vnew(const Charge* chg, ModuleBase::matrix& vnew) { vnew.c[iter] = this->v_eff.c[iter] - vnew.c[iter]; } - - return; } void Potential::interpolate_vrs(void) diff --git a/source/source_estate/module_pot/potential_new.h b/source/source_estate/module_pot/potential_new.h index 5b888e7d8b..a332824224 100644 --- a/source/source_estate/module_pot/potential_new.h +++ b/source/source_estate/module_pot/potential_new.h @@ -8,6 +8,7 @@ #include "source_pw/module_pwdft/structure_factor.h" #include "pot_base.h" +#include #include namespace elecstate @@ -21,14 +22,9 @@ namespace elecstate * c. it will reset fixed_done to false, v_eff_fixed will be calculated; * d. it should be called after Charge is initialized; * e. it can only be called once in one SCF loop - * 3. Func pot_register() and components - * a. need vector for choose target potentials - * b. "local", PotLocal introduces local pseudopotential part of potentials; - * c. "hartree", PotHartree introduces Coulombic interaction of electrons part of potentials; - * d. "xc", PotXC introduces exchange-correlation including meta-gga part of potentials; - * e. "surchem", PotSurChem introduces surface chemistry part of potentials; - * f. "efield", PotEfield introduces electronic field including dipole correction part of potentials; - * g. "gatefield", PotGate introduces gate field part of potentials; + * 3. Func set_components() + * a. set potential components created by PotentialFactory + * b. takes ownership of the components * 4. Func update_from_charge() * a. regenerate v_eff * b. if Meta-GGA is choosed, it will regenerate vofk_eff @@ -57,19 +53,13 @@ class Potential : public PotBase // Note: rho_basis_in and rho_basis_smooth_in are the same in NCPP Potential(const ModulePW::PW_Basis* rho_basis_in, const ModulePW::PW_Basis* rho_basis_smooth_in, - const UnitCell* ucell_in, - const ModuleBase::matrix* vloc_in, - Structure_Factor* structure_factors_in, - surchem* solvent_in, - double* etxc_in, - double* vtxc_in, - VSep* vsep_cell_in = nullptr); + const UnitCell* ucell_in); ~Potential(); // initialize potential when SCF begin void init_pot(const Charge*const chg); - // initialize potential components before SCF - void pot_register(const std::vector& components_list); + void set_components(std::vector components); + // update potential from current charge void update_from_charge(const Charge*const chg, const UnitCell*const ucell); // interface for SCF-converged, etxc vtxc for Energy, vnew for force_scc @@ -191,6 +181,8 @@ class Potential : public PotBase /// @return E_ML-EXX double get_ml_exx_energy() const; + double vl_of_0 = 0.0; + private: void cal_v_eff(const Charge*const chg, const UnitCell*const ucell, ModuleBase::matrix& v_eff) override; void cal_fixed_v(double* vl_pseudo) override; @@ -199,6 +191,8 @@ class Potential : public PotBase void allocate(); + const UnitCell* ucell_ = nullptr; + std::vector v_eff_fixed; ModuleBase::matrix v_eff; @@ -215,21 +209,9 @@ class Potential : public PotBase ModuleBase::matrix vofk_eff; bool fixed_done = false; - - // gather etxc and vtxc in Potential, will be used in ESolver - double* etxc_ = nullptr; - double* vtxc_ = nullptr; - - double vl_of_0 = 0.0; + bool use_gpu_ = false; std::vector components; - - const UnitCell* ucell_ = nullptr; - const ModuleBase::matrix* vloc_ = nullptr; - Structure_Factor* structure_factors_ = nullptr; - surchem* solvent_ = nullptr; - VSep* vsep_cell = nullptr; - bool use_gpu_ = false; }; } // namespace elecstate diff --git a/source/source_estate/module_pot/potential_types.cpp b/source/source_estate/module_pot/potential_types.cpp deleted file mode 100644 index f8f1315d8e..0000000000 --- a/source/source_estate/module_pot/potential_types.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "H_Hartree_pw.h" -#include "efield.h" -#include "source_io/module_parameter/parameter.h" -#include "gatefield.h" -#include "source_base/global_function.h" -#include "source_base/global_variable.h" -#include "source_base/memory.h" -#include "source_base/timer.h" -#include "source_base/tool_quit.h" -#include "source_base/tool_title.h" -#include "pot_local.h" -#include "pot_surchem.hpp" -#include "pot_xc.h" -#include "potential_new.h" -#include "pot_sep.h" -#ifdef __LCAO -#include "H_TDDFT_pw.h" -#endif -#ifdef __MLALGO -#include "pot_ml_exx.h" -#endif - -namespace elecstate -{ - -PotBase* Potential::get_pot_type(const std::string& pot_type) -{ - ModuleBase::TITLE("Potential", "get_pot_type"); - if (pot_type == "local") - { - return new PotLocal(this->vloc_, &(this->structure_factors_->strucFac), this->rho_basis_, this->vl_of_0); - } - else if (pot_type == "hartree") - { - return new PotHartree(this->rho_basis_); - } - else if (pot_type == "xc") - { - return new PotXC(this->rho_basis_, this->etxc_, this->vtxc_, &(this->vofk_eff)); - } - else if (pot_type == "surchem") - { - return new PotSurChem(this->rho_basis_, - this->structure_factors_, - this->v_eff_fixed.data(), - this->solvent_); - } - else if (pot_type == "efield") - { - return new PotEfield(this->rho_basis_, this->ucell_, this->solvent_, PARAM.inp.dip_cor_flag); - } - else if (pot_type == "gatefield") - { - return new PotGate(this->rho_basis_, this->ucell_); - } -#ifdef __LCAO - else if (pot_type == "tddft") - { - return new H_TDDFT_pw(this->rho_basis_, this->ucell_); - } -#endif -#ifdef __MLALGO - else if (pot_type == "ml_exx") - { - return new PotML_EXX(this->rho_basis_, this->ucell_); - } -#endif - else if (pot_type == "dfthalf") { - return new PotSep(&(this->structure_factors_->strucFac), this->rho_basis_, this->vsep_cell); - } - else - { - ModuleBase::WARNING_QUIT("Potential::get_pot_type", "Please input correct component of potential!"); - __builtin_unreachable(); - } -} - -} // namespace elecstate diff --git a/source/source_estate/setup_estate_pw.cpp b/source/source_estate/setup_estate_pw.cpp index 3ca02d79e6..c72504855c 100644 --- a/source/source_estate/setup_estate_pw.cpp +++ b/source/source_estate/setup_estate_pw.cpp @@ -2,6 +2,7 @@ #include "source_estate/elecstate_pw.h" #include "source_estate/elecstate_pw_sdft.h" #include "source_estate/elecstate_tools.h" +#include "source_estate/module_pot/potential_new.h" namespace elecstate { @@ -100,9 +101,7 @@ void setup_estate_pw_impl( if (pelec->pot == nullptr) { - pelec->pot = new elecstate::Potential(pw_rhod, - pw_rho, &ucell, &locpp.vloc, &sf, - &solvent, &(pelec->f_en.etxc), &(pelec->f_en.vtxc), vsep_cell); + pelec->pot = new elecstate::Potential(pw_rhod, pw_rho, &ucell); } locpp.init_vloc(ucell, pw_rhod); diff --git a/source/source_io/module_energy/write_eband_terms.hpp b/source/source_io/module_energy/write_eband_terms.hpp index 8732c9c0f8..edf480cead 100644 --- a/source/source_io/module_energy/write_eband_terms.hpp +++ b/source/source_io/module_energy/write_eband_terms.hpp @@ -5,6 +5,8 @@ #include "source_lcao/module_operator_lcao/ekinetic.h" #include "source_lcao/module_operator_lcao/nonlocal.h" #include "source_basis/module_nao/two_center_bundle.h" +#include "source_estate/module_pot/potential_new.h" +#include "source_estate/module_pot/potential_factory.h" namespace ModuleIO { @@ -96,8 +98,10 @@ void write_eband_terms(const int nspin, // 2. pp: local if (PARAM.inp.vl_in_h) { - elecstate::Potential pot_local(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc); - pot_local.pot_register({ "local" }); + elecstate::Potential pot_local(&rhod_basis, &rho_basis); + elecstate::PotentialFactory factory(&vloc, &sf, &rhod_basis, &etxc, &vtxc, pot_local.get_eff_vofk(), &solvent, nullptr, &ucell); + auto components = factory.create_components({ "local" }); + pot_local.set_components(std::move(components)); pot_local.update_from_charge(&chg, &ucell); hamilt::HS_Matrix_K v_pp_local_k_ao(pv, 1); hamilt::HContainer v_pp_local_R_ao(pv); @@ -148,8 +152,10 @@ void write_eband_terms(const int nspin, // 4. hartree if (PARAM.inp.vh_in_h) { - elecstate::Potential pot_hartree(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc); - pot_hartree.pot_register({ "hartree" }); + elecstate::Potential pot_hartree(&rhod_basis, &rho_basis); + elecstate::PotentialFactory factory(&vloc, &sf, &rhod_basis, &etxc, &vtxc, pot_hartree.get_eff_vofk(), &solvent, nullptr, &ucell); + auto components = factory.create_components({ "hartree" }); + pot_hartree.set_components(std::move(components)); pot_hartree.update_from_charge(&chg, &ucell); std::vector> v_hartree_R_ao(nspin0, hamilt::HContainer(pv)); for (int is = 0; is < nspin0; ++is) diff --git a/source/source_io/module_hs/write_vxc.hpp b/source/source_io/module_hs/write_vxc.hpp index 6b820c149a..8c95019513 100644 --- a/source/source_io/module_hs/write_vxc.hpp +++ b/source/source_io/module_hs/write_vxc.hpp @@ -9,6 +9,8 @@ #include "source_psi/psi.h" #include "source_io/module_hs/write_HS.h" #include "source_io/module_output/filename.h" // use filename_output function +#include "source_estate/module_pot/potential_new.h" +#include "source_estate/module_pot/potential_factory.h" namespace ModuleIO { @@ -166,9 +168,11 @@ void write_Vxc(const int nspin, // elecstate::PotXC* potxc(&rho_basis, &etxc, vtxc, nullptr); // potxc.cal_v_eff(&chg, &ucell, vr_xc); elecstate::Potential* potxc - = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc); + = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell); std::vector compnents_list = {"xc"}; - potxc->pot_register(compnents_list); + elecstate::PotentialFactory factory(&vloc, &sf, &rhod_basis, &etxc, &vtxc, potxc->get_eff_vofk(), &solvent, nullptr, &ucell); + auto components = factory.create_components(compnents_list); + potxc->set_components(std::move(components)); potxc->update_from_charge(&chg, &ucell); // 2. allocate AO-matrix diff --git a/source/source_io/module_hs/write_vxc_lip.hpp b/source/source_io/module_hs/write_vxc_lip.hpp index 30a7e043d0..3ba5d170c2 100644 --- a/source/source_io/module_hs/write_vxc_lip.hpp +++ b/source/source_io/module_hs/write_vxc_lip.hpp @@ -8,6 +8,7 @@ #include "source_cell/unitcell.h" #include "source_cell/klist.h" #include "source_estate/module_pot/potential_new.h" +#include "source_estate/module_pot/potential_factory.h" #include "source_io/module_hs/write_HS.h" #include "source_io/module_output/filename.h" // use filename_output function #include @@ -132,10 +133,12 @@ namespace ModuleIO // elecstate::PotXC* potxc(&rho_basis, &etxc, vtxc, nullptr); // potxc.cal_v_eff(&chg, &ucell, vr_xc); elecstate::Potential* potxc - = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc); + = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell); std::vector compnents_list = { "xc" }; - potxc->pot_register(compnents_list); + elecstate::PotentialFactory factory(&vloc, &sf, &rhod_basis, &etxc, &vtxc, potxc->get_eff_vofk(), &solvent, nullptr, &ucell); + auto components = factory.create_components(compnents_list); + potxc->set_components(std::move(components)); potxc->update_from_charge(&chg, &ucell); // const ModuleBase::matrix vr_localxc = potxc->get_veff_smooth(); diff --git a/source/source_io/module_hs/write_vxc_r.hpp b/source/source_io/module_hs/write_vxc_r.hpp index 4fe994d44a..2687a0692d 100644 --- a/source/source_io/module_hs/write_vxc_r.hpp +++ b/source/source_io/module_hs/write_vxc_r.hpp @@ -5,6 +5,8 @@ #include "source_lcao/module_operator_lcao/op_dftu_lcao.h" #include "source_lcao/module_operator_lcao/veff_lcao.h" #include "source_lcao/spar_hsr.h" +#include "source_estate/module_pot/potential_new.h" +#include "source_estate/module_pot/potential_factory.h" #ifdef __EXX #include "source_lcao/module_operator_lcao/op_exx_lcao.h" #include "source_lcao/module_ri/RI_2D_Comm.h" @@ -58,9 +60,11 @@ void write_Vxc_R(const int nspin, // elecstate::PotXC* potxc(&rho_basis, &etxc, vtxc, nullptr); // potxc.cal_v_eff(&chg, &ucell, vr_xc); elecstate::Potential* potxc - = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell, &vloc, &sf, &solvent, &etxc, &vtxc); + = new elecstate::Potential(&rhod_basis, &rho_basis, &ucell); std::vector compnents_list = {"xc"}; - potxc->pot_register(compnents_list); + elecstate::PotentialFactory factory(&vloc, &sf, &rhod_basis, &etxc, &vtxc, potxc->get_eff_vofk(), &solvent, nullptr, &ucell); + auto components = factory.create_components(compnents_list); + potxc->set_components(std::move(components)); potxc->update_from_charge(&chg, &ucell); // 2. allocate H(R) diff --git a/source/source_lcao/LCAO_set.cpp b/source/source_lcao/LCAO_set.cpp index 2b38f94f93..7ea23b4844 100644 --- a/source/source_lcao/LCAO_set.cpp +++ b/source/source_lcao/LCAO_set.cpp @@ -7,6 +7,7 @@ #include "source_lcao/rho_tau_lcao.h" // use dm2rho #include "source_lcao/hamilt_lcao.h" // use HamiltLCAO for init_chg_hr #include "source_hsolver/hsolver_lcao.h" // use HSolverLCAO for init_chg_hr +#include "source_estate/module_pot/potential_new.h" template void LCAO_domain::set_psi_occ_dm_chg( @@ -73,9 +74,7 @@ void LCAO_domain::set_pot( if (pelec->pot == nullptr) { // where is the pot deleted? - pelec->pot = new elecstate::Potential(&pw_rhod, &pw_rho, - &ucell, &locpp.vloc, &sf, &solvent, - &(pelec->f_en.etxc), &(pelec->f_en.vtxc)); + pelec->pot = new elecstate::Potential(&pw_rhod, &pw_rho, &ucell); } //! 3) initialize DFT+U diff --git a/source/source_lcao/module_rdmft/rdmft_tools.cpp b/source/source_lcao/module_rdmft/rdmft_tools.cpp index 845ffea162..71dd4664e3 100644 --- a/source/source_lcao/module_rdmft/rdmft_tools.cpp +++ b/source/source_lcao/module_rdmft/rdmft_tools.cpp @@ -265,7 +265,7 @@ void Veff_rdmft, double>::contributeHR() { double vlocal_of_0 = 0.0; ModuleBase::matrix v_matrix_local(1, charge_->nrxx); - elecstate::PotLocal potL(vloc_, sf_, rho_basis_, vlocal_of_0); + elecstate::PotLocal potL(vloc_, sf_, rho_basis_, &vlocal_of_0); potL.cal_fixed_v( &v_matrix_local(0, 0) ); // use pointer to attach v(r) @@ -347,7 +347,7 @@ void Veff_rdmft::contributeHR() { double vlocal_of_0 = 0.0; ModuleBase::matrix v_matrix_local(1, charge_->nrxx); - elecstate::PotLocal potL(vloc_, sf_, rho_basis_, vlocal_of_0); + elecstate::PotLocal potL(vloc_, sf_, rho_basis_, &vlocal_of_0); potL.cal_fixed_v( &v_matrix_local(0, 0) ); // use pointer to attach v(r) From 6e957d4d2bdaae4cc62c8034538332e148dab66a Mon Sep 17 00:00:00 2001 From: linpz Date: Sat, 21 Mar 2026 05:27:33 +0800 Subject: [PATCH 2/4] update of potential --- source/source_esolver/esolver_of_tool.cpp | 2 +- source/source_estate/setup_estate_pw.cpp | 44 ++++++++++ .../module_energy/write_eband_terms.hpp | 4 +- source/source_lcao/LCAO_set.cpp | 47 ++++++++++- source/source_lcao/hamilt_lcao.cpp | 83 ++++--------------- source/source_pw/module_pwdft/hamilt_pw.cpp | 69 ++++----------- 6 files changed, 126 insertions(+), 123 deletions(-) diff --git a/source/source_esolver/esolver_of_tool.cpp b/source/source_esolver/esolver_of_tool.cpp index 7b1e0f0314..6064ac61aa 100644 --- a/source/source_esolver/esolver_of_tool.cpp +++ b/source/source_esolver/esolver_of_tool.cpp @@ -24,7 +24,7 @@ void ESolver_OF::init_elecstate(UnitCell& ucell) } delete this->pelec->pot; - this->pelec->pot = new elecstate::Potential(this->pw_rhod, this->pw_rho); + this->pelec->pot = new elecstate::Potential(this->pw_rhod, this->pw_rho, &ucell); std::vector pot_register_in; if (PARAM.inp.vion_in_h) diff --git a/source/source_estate/setup_estate_pw.cpp b/source/source_estate/setup_estate_pw.cpp index c72504855c..90a5c10385 100644 --- a/source/source_estate/setup_estate_pw.cpp +++ b/source/source_estate/setup_estate_pw.cpp @@ -3,6 +3,7 @@ #include "source_estate/elecstate_pw_sdft.h" #include "source_estate/elecstate_tools.h" #include "source_estate/module_pot/potential_new.h" +#include "source_estate/module_pot/potential_factory.h" namespace elecstate { @@ -102,6 +103,49 @@ void setup_estate_pw_impl( if (pelec->pot == nullptr) { pelec->pot = new elecstate::Potential(pw_rhod, pw_rho, &ucell); + + std::vector pot_register_in; + if (inp.vion_in_h) + { + pot_register_in.push_back("local"); + } + if (inp.vh_in_h) + { + pot_register_in.push_back("hartree"); + } + pot_register_in.push_back("xc"); + if (inp.imp_sol) + { + pot_register_in.push_back("surchem"); + } + if (inp.efield_flag) + { + pot_register_in.push_back("efield"); + } + if (inp.gate_flag) + { + pot_register_in.push_back("gatefield"); + } + if (inp.ml_exx) + { + pot_register_in.push_back("ml_exx"); + } + if (inp.dfthalf_type == 1) + { + pot_register_in.push_back("dfthalf"); + } + + elecstate::PotentialFactory factory(&locpp.vloc, + &sf, + pw_rhod, + &pelec->f_en.etxc, + &pelec->f_en.vtxc, + pelec->pot->get_eff_vofk(), + &solvent, + vsep_cell, + &ucell); + auto components = factory.create_components(pot_register_in); + pelec->pot->set_components(std::move(components)); } locpp.init_vloc(ucell, pw_rhod); diff --git a/source/source_io/module_energy/write_eband_terms.hpp b/source/source_io/module_energy/write_eband_terms.hpp index edf480cead..56bf6853c7 100644 --- a/source/source_io/module_energy/write_eband_terms.hpp +++ b/source/source_io/module_energy/write_eband_terms.hpp @@ -98,7 +98,7 @@ void write_eband_terms(const int nspin, // 2. pp: local if (PARAM.inp.vl_in_h) { - elecstate::Potential pot_local(&rhod_basis, &rho_basis); + elecstate::Potential pot_local(&rhod_basis, &rho_basis, &ucell); elecstate::PotentialFactory factory(&vloc, &sf, &rhod_basis, &etxc, &vtxc, pot_local.get_eff_vofk(), &solvent, nullptr, &ucell); auto components = factory.create_components({ "local" }); pot_local.set_components(std::move(components)); @@ -152,7 +152,7 @@ void write_eband_terms(const int nspin, // 4. hartree if (PARAM.inp.vh_in_h) { - elecstate::Potential pot_hartree(&rhod_basis, &rho_basis); + elecstate::Potential pot_hartree(&rhod_basis, &rho_basis, &ucell); elecstate::PotentialFactory factory(&vloc, &sf, &rhod_basis, &etxc, &vtxc, pot_hartree.get_eff_vofk(), &solvent, nullptr, &ucell); auto components = factory.create_components({ "hartree" }); pot_hartree.set_components(std::move(components)); diff --git a/source/source_lcao/LCAO_set.cpp b/source/source_lcao/LCAO_set.cpp index 7ea23b4844..243f7df528 100644 --- a/source/source_lcao/LCAO_set.cpp +++ b/source/source_lcao/LCAO_set.cpp @@ -8,6 +8,7 @@ #include "source_lcao/hamilt_lcao.h" // use HamiltLCAO for init_chg_hr #include "source_hsolver/hsolver_lcao.h" // use HSolverLCAO for init_chg_hr #include "source_estate/module_pot/potential_new.h" +#include "source_estate/module_pot/potential_factory.h" template void LCAO_domain::set_psi_occ_dm_chg( @@ -73,8 +74,52 @@ void LCAO_domain::set_pot( //! 2) init potentials if (pelec->pot == nullptr) { - // where is the pot deleted? pelec->pot = new elecstate::Potential(&pw_rhod, &pw_rho, &ucell); + + std::vector pot_register_in; + if (inp.vion_in_h) + { + pot_register_in.push_back("local"); + } + if (inp.vh_in_h) + { + pot_register_in.push_back("hartree"); + } + pot_register_in.push_back("xc"); + if (inp.imp_sol) + { + pot_register_in.push_back("surchem"); + } + if (inp.efield_flag) + { + pot_register_in.push_back("efield"); + } + if (inp.gate_flag) + { + pot_register_in.push_back("gatefield"); + } +#ifdef __LCAO + if (inp.esolver_type == "tddft") + { + pot_register_in.push_back("tddft"); + } +#endif + if (inp.ml_exx) + { + pot_register_in.push_back("ml_exx"); + } + + elecstate::PotentialFactory factory(&locpp.vloc, + &sf, + &pw_rhod, + &pelec->f_en.etxc, + &pelec->f_en.vtxc, + pelec->pot->get_eff_vofk(), + &solvent, + nullptr, + &ucell); + auto components = factory.create_components(pot_register_in); + pelec->pot->set_components(std::move(components)); } //! 3) initialize DFT+U diff --git a/source/source_lcao/hamilt_lcao.cpp b/source/source_lcao/hamilt_lcao.cpp index 3850f636bd..20b61a2cdb 100644 --- a/source/source_lcao/hamilt_lcao.cpp +++ b/source/source_lcao/hamilt_lcao.cpp @@ -92,41 +92,6 @@ HamiltLCAO::HamiltLCAO(const UnitCell& ucell, this->sR = new HContainer(paraV); this->hsk = new HS_Matrix_K(paraV); - // Effective potential term (\sum_r ) is registered without template - std::vector pot_register_in; - if (PARAM.inp.vl_in_h) - { - if (PARAM.inp.vion_in_h) - { - pot_register_in.push_back("local"); - } - if (PARAM.inp.vh_in_h) - { - pot_register_in.push_back("hartree"); - } - pot_register_in.push_back("xc"); - if (PARAM.inp.imp_sol) - { - pot_register_in.push_back("surchem"); - } - if (PARAM.inp.efield_flag) - { - pot_register_in.push_back("efield"); - } - if (PARAM.inp.gate_flag) - { - pot_register_in.push_back("gatefield"); - } - if (PARAM.inp.esolver_type == "tddft") - { - pot_register_in.push_back("tddft"); - } - if (PARAM.inp.ml_exx) // sunliang - { - pot_register_in.push_back("ml_exx"); - } - } - // Gamma_only case to initialize HamiltLCAO // // code block to construct Operator Chains @@ -177,22 +142,15 @@ HamiltLCAO::HamiltLCAO(const UnitCell& ucell, // in general case, target HR is Gint::hRGint, while target HK is this->hsk->get_hk() if (PARAM.inp.vl_in_h) { - // only Potential is not empty, Veff and Meta are available - if (pot_register_in.size() > 0) - { - // register Potential by gathered operator - pot_in->pot_register(pot_register_in); - // effective potential term - Operator* veff = new Veff>(this->hsk, - this->kv->kvec_d, - pot_in, - this->hR, // no explicit call yet - &ucell, - orb.cutoffs(), - &grid_d, - PARAM.inp.nspin); - this->getOperator()->add(veff); - } + Operator* veff = new Veff>(this->hsk, + this->kv->kvec_d, + pot_in, + this->hR, + &ucell, + orb.cutoffs(), + &grid_d, + PARAM.inp.nspin); + this->getOperator()->add(veff); } #ifdef __MLALGO @@ -247,21 +205,14 @@ HamiltLCAO::HamiltLCAO(const UnitCell& ucell, // in general case, target HR is Gint::pvpR_reduced, while target HK is this->hsk->get_hk() if (PARAM.inp.vl_in_h) { - // only Potential is not empty, Veff and Meta are available - if (pot_register_in.size() > 0) - { - // register Potential by gathered operator - pot_in->pot_register(pot_register_in); - // Veff term - this->getOperator() = new Veff>(this->hsk, - this->kv->kvec_d, - pot_in, - this->hR, - &ucell, - orb.cutoffs(), - &grid_d, - PARAM.inp.nspin); - } + this->getOperator() = new Veff>(this->hsk, + this->kv->kvec_d, + pot_in, + this->hR, + &ucell, + orb.cutoffs(), + &grid_d, + PARAM.inp.nspin); } // initial operator for multi-k case diff --git a/source/source_pw/module_pwdft/hamilt_pw.cpp b/source/source_pw/module_pwdft/hamilt_pw.cpp index 27a56cbe11..77fb9e43a5 100644 --- a/source/source_pw/module_pwdft/hamilt_pw.cpp +++ b/source/source_pw/module_pwdft/hamilt_pw.cpp @@ -49,63 +49,26 @@ HamiltPW::HamiltPW(elecstate::Potential* pot_in, } if (PARAM.inp.vl_in_h) { - std::vector pot_register_in; - if (PARAM.inp.vion_in_h) - { - pot_register_in.push_back("local"); - } - if (PARAM.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) - { - pot_register_in.push_back("surchem"); - } - if (PARAM.inp.efield_flag) - { - pot_register_in.push_back("efield"); - } - if (PARAM.inp.gate_flag) - { - pot_register_in.push_back("gatefield"); - } - if (PARAM.inp.ml_exx) // sunliang + Operator* veff = new Veff>(isk, + pot_in->get_veff_smooth_data(), + pot_in->get_veff_smooth().nr, + pot_in->get_veff_smooth().nc, + wfc_basis); + if(this->ops == nullptr) { - pot_register_in.push_back("ml_exx"); - } - // DFT-1/2 - if (PARAM.inp.dfthalf_type == 1) { - pot_register_in.push_back("dfthalf"); + this->ops = veff; } - //only Potential is not empty, Veff and Meta are available - if(pot_register_in.size()>0) + else { - //register Potential by gathered operator - pot_in->pot_register(pot_register_in); - Operator* veff = new Veff>(isk, - pot_in->get_veff_smooth_data(), - pot_in->get_veff_smooth().nr, - pot_in->get_veff_smooth().nc, - wfc_basis); - if(this->ops == nullptr) - { - this->ops = veff; - } - else - { - this->ops->add(veff); - } - Operator* meta = new Meta>(tpiba, - isk, - pot_in->get_vofk_smooth_data(), - pot_in->get_vofk_smooth().nr, - pot_in->get_vofk_smooth().nc, - wfc_basis); - this->ops->add(meta); + this->ops->add(veff); } + Operator* meta = new Meta>(tpiba, + isk, + pot_in->get_vofk_smooth_data(), + pot_in->get_vofk_smooth().nr, + pot_in->get_vofk_smooth().nc, + wfc_basis); + this->ops->add(meta); } if (PARAM.inp.vnl_in_h) { From 7b153450e852d11c1924c979d088cd1163bb8020 Mon Sep 17 00:00:00 2001 From: linpz Date: Sun, 22 Mar 2026 23:57:30 +0800 Subject: [PATCH 3/4] update potential_new_test --- source/source_estate/test/CMakeLists.txt | 2 +- .../source_estate/test/potential_new_test.cpp | 123 ++++++++++-------- 2 files changed, 68 insertions(+), 57 deletions(-) diff --git a/source/source_estate/test/CMakeLists.txt b/source/source_estate/test/CMakeLists.txt index ba33037bc5..244d0a51e5 100644 --- a/source/source_estate/test/CMakeLists.txt +++ b/source/source_estate/test/CMakeLists.txt @@ -74,7 +74,7 @@ AddTest( AddTest( TARGET MODULE_ESTATE_potentials_new - LIBS parameter ${math_libs} base device planewave_serial + LIBS parameter ${math_libs} base device planewave_serial SOURCES potential_new_test.cpp ../module_pot/potential_new.cpp ) diff --git a/source/source_estate/test/potential_new_test.cpp b/source/source_estate/test/potential_new_test.cpp index f91f473efa..c34cd5d869 100644 --- a/source/source_estate/test/potential_new_test.cpp +++ b/source/source_estate/test/potential_new_test.cpp @@ -53,10 +53,30 @@ bool XC_Functional::ked_flag = false; namespace elecstate { -PotBase* Potential::get_pot_type(const std::string& pot_type) -{ - return new PotBase; -} +class MockPotentialFactory +{ + public: + MockPotentialFactory(const ModuleBase::matrix*, + Structure_Factor*, + const ModulePW::PW_Basis*, + double*, + double*, + ModuleBase::matrix&, + surchem*, + VSep*, + const UnitCell*) + { + } + std::vector create_components(const std::vector& components_list) + { + std::vector components; + for (size_t i = 0; i < components_list.size(); i++) + { + components.push_back(new PotBase); + } + return components; + } +}; void Set_GlobalV_Default() { @@ -167,7 +187,7 @@ class PotentialNewTest : public ::testing::Test TEST_F(PotentialNewTest, ConstructorCPUDouble) { rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); EXPECT_TRUE(pot->fixed_mode); EXPECT_TRUE(pot->dynamic_mode); EXPECT_EQ(pot->v_eff_fixed.size(), 100); @@ -179,7 +199,7 @@ TEST_F(PotentialNewTest, ConstructorCPUSingle) { rhopw->nrxx = 100; PARAM.input.precision = "single"; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); EXPECT_TRUE(pot->fixed_mode); EXPECT_TRUE(pot->dynamic_mode); EXPECT_EQ(pot->v_eff_fixed.size(), 100); @@ -190,7 +210,7 @@ TEST_F(PotentialNewTest, ConstructorCPUSingle) TEST_F(PotentialNewTest, ConstructorNRXX0) { rhopw->nrxx = 0; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); EXPECT_TRUE(pot->fixed_mode); EXPECT_TRUE(pot->dynamic_mode); } @@ -200,7 +220,7 @@ TEST_F(PotentialNewTest, ConstructorXC3) XC_Functional::func_type = 3; XC_Functional::ked_flag = true; rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); EXPECT_TRUE(pot->fixed_mode); EXPECT_TRUE(pot->dynamic_mode); EXPECT_EQ(pot->v_eff_fixed.size(), 100); @@ -215,7 +235,7 @@ TEST_F(PotentialNewTest, ConstructorGPUDouble) // this is just a trivial call to the GPU code rhopw->nrxx = 100; PARAM.input.device = "gpu"; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); EXPECT_TRUE(pot->fixed_mode); EXPECT_TRUE(pot->dynamic_mode); EXPECT_EQ(pot->v_eff_fixed.size(), 100); @@ -229,7 +249,7 @@ TEST_F(PotentialNewTest, ConstructorGPUSingle) rhopw->nrxx = 100; PARAM.input.device = "gpu"; PARAM.input.precision = "single"; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); EXPECT_TRUE(pot->fixed_mode); EXPECT_TRUE(pot->dynamic_mode); EXPECT_EQ(pot->v_eff_fixed.size(), 100); @@ -256,24 +276,25 @@ TEST_F(PotentialNewTest, Getters) delete doo; } -TEST_F(PotentialNewTest, PotRegister) +TEST_F(PotentialNewTest, SetComponents) { - pot = new elecstate::Potential; + rhopw->nrxx = 100; + pot = new elecstate::Potential(rhopw, rhopw, ucell); elecstate::PotBase* pot0 = new elecstate::PotBase; - pot->components.push_back(pot0); + pot->set_components({pot0}); EXPECT_EQ(pot->components.size(), 1); std::vector compnents_list = {"hartree", "xc"}; - pot->pot_register(compnents_list); + elecstate::MockPotentialFactory factory(vloc, structure_factors, rhopw, etxc, vtxc, pot->get_eff_vofk(), solvent, nullptr, ucell); + auto components = factory.create_components(compnents_list); + pot->set_components(std::move(components)); EXPECT_EQ(pot->components.size(), 2); EXPECT_FALSE(pot->fixed_done); } TEST_F(PotentialNewTest, CalFixedV) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); std::vector compnents_list = { "local", "hartree", @@ -282,7 +303,9 @@ TEST_F(PotentialNewTest, CalFixedV) "gatefield" }; std::vector fixed = {true, false, false, false, true}; - pot->pot_register(compnents_list); + elecstate::MockPotentialFactory factory(vloc, structure_factors, rhopw, etxc, vtxc, pot->get_eff_vofk(), solvent, nullptr, ucell); + auto components = factory.create_components(compnents_list); + pot->set_components(std::move(components)); for (int i = 0; icomponents[i]->fixed_mode = fixed[i]; @@ -298,10 +321,8 @@ TEST_F(PotentialNewTest, CalFixedV) TEST_F(PotentialNewTest, CalVeff) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); std::vector compnents_list = { "local", "hartree", @@ -310,7 +331,9 @@ TEST_F(PotentialNewTest, CalVeff) "gatefield" }; std::vector dynamic = {false, true, true, true, false}; - pot->pot_register(compnents_list); + elecstate::MockPotentialFactory factory(vloc, structure_factors, rhopw, etxc, vtxc, pot->get_eff_vofk(), solvent, nullptr, ucell); + auto components = factory.create_components(compnents_list); + pot->set_components(std::move(components)); for (int i = 0; icomponents[i]->dynamic_mode = dynamic[i]; @@ -328,10 +351,8 @@ TEST_F(PotentialNewTest, CalVeff) TEST_F(PotentialNewTest, UpdateFromCharge) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); std::vector compnents_list = { "local", "hartree", @@ -341,7 +362,9 @@ TEST_F(PotentialNewTest, UpdateFromCharge) }; std::vector fixed = {true, false, false, false, true}; std::vector dynamic = {false, true, true, true, false}; - pot->pot_register(compnents_list); + elecstate::MockPotentialFactory factory(vloc, structure_factors, rhopw, etxc, vtxc, pot->get_eff_vofk(), solvent, nullptr, ucell); + auto components = factory.create_components(compnents_list); + pot->set_components(std::move(components)); for (int i = 0; icomponents[i]->fixed_mode = fixed[i]; @@ -356,10 +379,8 @@ TEST_F(PotentialNewTest, UpdateFromCharge) TEST_F(PotentialNewTest, InitPot) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); std::vector compnents_list = { "local", "hartree", @@ -369,7 +390,9 @@ TEST_F(PotentialNewTest, InitPot) }; std::vector fixed = {true, false, false, false, true}; std::vector dynamic = {false, true, true, true, false}; - pot->pot_register(compnents_list); + elecstate::MockPotentialFactory factory(vloc, structure_factors, rhopw, etxc, vtxc, pot->get_eff_vofk(), solvent, nullptr, ucell); + auto components = factory.create_components(compnents_list); + pot->set_components(std::move(components)); for (int i = 0; icomponents[i]->fixed_mode = fixed[i]; @@ -384,10 +407,8 @@ TEST_F(PotentialNewTest, InitPot) TEST_F(PotentialNewTest, GetVnew) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); std::vector compnents_list = { "local", "hartree", @@ -397,7 +418,9 @@ TEST_F(PotentialNewTest, GetVnew) }; std::vector fixed = {true, false, false, false, true}; std::vector dynamic = {false, true, true, true, false}; - pot->pot_register(compnents_list); + elecstate::MockPotentialFactory factory(vloc, structure_factors, rhopw, etxc, vtxc, pot->get_eff_vofk(), solvent, nullptr, ucell); + auto components = factory.create_components(compnents_list); + pot->set_components(std::move(components)); for (int i = 0; icomponents[i]->fixed_mode = fixed[i]; @@ -413,10 +436,8 @@ TEST_F(PotentialNewTest, GetVnew) TEST_F(PotentialNewTest, GetEffectiveVmatrix) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); ModuleBase::matrix v_eff_tmp = pot->get_eff_v(); const ModuleBase::matrix v_eff_tmp_const = pot->get_eff_v(); EXPECT_EQ(v_eff_tmp.nr, PARAM.input.nspin); @@ -435,10 +456,8 @@ TEST_F(PotentialNewTest, GetEffectiveVmatrix) TEST_F(PotentialNewTest, GetEffectiveVarray) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); double* v_eff_tmp = pot->get_eff_v(0); const double* v_eff_tmp_const = pot->get_eff_v(0); for (int ic = 0; ic < rhopw->nrxx; ic++) @@ -463,12 +482,10 @@ TEST_F(PotentialNewTest, GetEffectiveVarrayNullptr) TEST_F(PotentialNewTest, GetEffectiveVofkmatrix) { - // construct potential XC_Functional::func_type = 3; XC_Functional::ked_flag = true; rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); ModuleBase::matrix vofk_eff_tmp = pot->get_eff_vofk(); const ModuleBase::matrix vofk_eff_tmp_const = pot->get_eff_vofk(); EXPECT_EQ(vofk_eff_tmp.nr, PARAM.input.nspin); @@ -487,10 +504,8 @@ TEST_F(PotentialNewTest, GetEffectiveVofkmatrix) TEST_F(PotentialNewTest, GetEffectiveVofkarray) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); double* vofk_eff_tmp = pot->get_eff_vofk(0); const double* vofk_eff_tmp_const = pot->get_eff_vofk(0); for (int ic = 0; ic < rhopw->nrxx; ic++) @@ -516,7 +531,7 @@ TEST_F(PotentialNewTest, GetEffectiveVofkarrayNullptr) TEST_F(PotentialNewTest, GetFixedV) { rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); EXPECT_TRUE(pot->fixed_mode); EXPECT_TRUE(pot->dynamic_mode); EXPECT_EQ(pot->v_eff_fixed.size(), 100); @@ -532,12 +547,10 @@ TEST_F(PotentialNewTest, GetFixedV) TEST_F(PotentialNewTest, GetVeffSmooth) { - // construct potential rhopw->nrxx = 100; XC_Functional::func_type = 3; XC_Functional::ked_flag = true; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); ModuleBase::matrix veff_smooth_tmp = pot->get_veff_smooth(); const ModuleBase::matrix veff_smooth_const_tmp = pot->get_veff_smooth(); EXPECT_EQ(veff_smooth_tmp.nr, PARAM.input.nspin); @@ -556,10 +569,8 @@ TEST_F(PotentialNewTest, GetVeffSmooth) TEST_F(PotentialNewTest, GetVofkSmooth) { - // construct potential rhopw->nrxx = 100; - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); - // + pot = new elecstate::Potential(rhopw, rhopw, ucell); ModuleBase::matrix vofk_smooth_tmp = pot->get_veff_smooth(); const ModuleBase::matrix vofk_smooth_const_tmp = pot->get_veff_smooth(); EXPECT_EQ(vofk_smooth_tmp.nr, PARAM.input.nspin); @@ -592,7 +603,7 @@ TEST_F(PotentialNewTest, InterpolateVrsDoubleGrids) static_cast(rhodpw)->setuptransform(rhopw); rhodpw->collect_local_pw(); - pot = new elecstate::Potential(rhodpw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhodpw, rhopw, ucell); for (int ir = 0; ir < pot->v_eff.nr; ir++) { @@ -637,7 +648,7 @@ TEST_F(PotentialNewTest, InterpolateVrsWarningQuit) rhodpw->collect_local_pw(); rhodpw->gamma_only = true; - pot = new elecstate::Potential(rhodpw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhodpw, rhopw, ucell); EXPECT_EXIT(pot->interpolate_vrs(), ::testing::ExitedWithCode(1), ""); } @@ -653,7 +664,7 @@ TEST_F(PotentialNewTest, InterpolateVrsSingleGrids) rhopw->setuptransform(); rhopw->collect_local_pw(); - pot = new elecstate::Potential(rhopw, rhopw, ucell, vloc, structure_factors, solvent, etxc, vtxc); + pot = new elecstate::Potential(rhopw, rhopw, ucell); for (int ir = 0; ir < pot->v_eff.nr; ir++) { From 547d723616f6f3aa7f6a71dc264e258e362f9e23 Mon Sep 17 00:00:00 2001 From: linpz Date: Mon, 23 Mar 2026 01:11:15 +0800 Subject: [PATCH 4/4] fix bug --- source/source_estate/setup_estate_pw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/source_estate/setup_estate_pw.cpp b/source/source_estate/setup_estate_pw.cpp index 90a5c10385..79d2f35692 100644 --- a/source/source_estate/setup_estate_pw.cpp +++ b/source/source_estate/setup_estate_pw.cpp @@ -100,6 +100,8 @@ void setup_estate_pw_impl( vsep_cell->init_vsep(*pw_rhod, ucell.sep_cell); } + locpp.init_vloc(ucell, pw_rhod); + if (pelec->pot == nullptr) { pelec->pot = new elecstate::Potential(pw_rhod, pw_rho, &ucell); @@ -148,7 +150,6 @@ void setup_estate_pw_impl( pelec->pot->set_components(std::move(components)); } - locpp.init_vloc(ucell, pw_rhod); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "LOCAL POTENTIAL"); ppcell.init(ucell, &sf, pw_wfc);