Skip to content

Commit d764415

Browse files
Critsium-xyclaude
andcommitted
source_estate: pass Charge its nspin, nelec and verbosity explicitly, and add the two seams charge_test needed elsewhere
charge_test needed the macro for three separate reasons, in three different modules. All three are fixed here; the module-crossing ones are called out below because they touch modules that currently have no access hacks at all. 1) source_estate -- Charge reads three INPUT values (19 test writes, 3 keys) charge.cpp read nspin, nelec and test_charge from the global singleton in five methods. The obvious move -- give renormalize_rho() an nelec parameter -- cascades badly: of its six production call sites, rho_tau_lcao.cpp has no PARAM reference at all, so the value would have to be threaded through LCAO_domain::dm2rho (six more sites) and then ElecStateLCAO::dm2rho into hsolver_lcao.cpp -- about fifteen sites across three modules, and it would put a global read into a file that is clean today. Charge already keeps nspin as state set by allocate(), so nelec is kept the same way. allocate() takes test_charge and nelec_in; renormalize_rho() and check_rho() read this->nelec, so their signatures are untouched and nothing cascades. save_rho_before_sum_band() takes nspin, init_final_scf() takes nspin and test_charge. allocate() has nine production call sites, not the two a grep on guessed object names suggested; the others reach it through chg1_, chr_base, chg_gs, ptemp_rho_, chg_01 and chg_drho[d]. Seven of the nine now pass an injected inp_ or the source Charge's own nspin/nelec, so only veff_dh.cpp adds PARAM references, and it already read PARAM.inp.nspin on the same line. Two const getters, get_allocate_rho() and get_allocate_rho_final_scf(), cover the 14 read-only accesses to the two allocation flags. 2) source_hamilt/module_xc -- XC_Functional::func_type and ked_flag (6 writes) Both are private statics with public getters and no setters. Added set_func_type() and set_ked_flag(), matching the get_func_type() / get_ked_flag() pair and the existing set_hybrid_alpha() / set_hse_omega() style in the same header. The test's out-of-line definitions of the two statics need no seam -- a definition does not require access. 3) source_basis/module_pw -- PW_Basis::distribute_r() and distribute_g() No new API. The test hand-rolled initgrids / distribute_r / initparameters / distribute_g; pw_basis.h documents the public sequence as initgrids / initparameters / setuptransform(), and setuptransform() performs both distribute calls itself. The test now follows the documented order. Three EXPECT_EQ(PARAM.input.nelec, 8) assertions guarded the 8.0 that the renormalize/check assertions below them expect; they now assert the same thing about the value the test configures. The five test_charge/nspin/nelec reads left in charge.cpp are inside atomic_rho(), which charge_test does not call, so injecting them would cost budget without removing a macro. No production logic changed. No expected value changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 688d0c7 commit d764415

13 files changed

Lines changed: 122 additions & 81 deletions

File tree

source/source_esolver/esolver_dfpt_pw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class XC_First_Order_FDM : public ModuleDFPT::XC_First_Order
4545
fdm_ = new elecstate::PotXC_FDM(rho_basis, chg0, ucell);
4646
chg1_ = new Charge();
4747
chg1_->set_rhopw(rho_basis);
48-
chg1_->allocate(chg0->nspin, false);
48+
chg1_->allocate(chg0->nspin, false, /*test_charge=*/0, chg0->nelec);
4949
veff_1_.create(chg0->nspin, chg0->nrxx);
5050
}
5151

source/source_esolver/esolver_double_xc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void ESolver_DoubleXC<TK, TR>::before_all_runners(BaseCell& basecell, const Inpu
9292
// 10) inititlize the charge density
9393
this->chr_base.set_rhopw(this->pw_rhod); // mohan add 20251130
9494
const bool kin_den = this->chr_base.kin_density(); // mohan add 20251202
95-
this->chr_base.allocate(this->inp_->nspin, kin_den);
95+
this->chr_base.allocate(this->inp_->nspin, kin_den, this->inp_->test_charge, this->inp_->nelec);
9696
this->chr_base.init_rho(ucell, this->Pgrid, this->sf.strucFac, ucell.symm, &this->kv);
9797
this->chr_base.check_rho();
9898

source/source_esolver/esolver_fp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ void ESolver_FP::before_all_runners(BaseCell& basecell, const Input_para& inp)
148148
// then we can call chr.allocate()
149149
this->chr.set_rhopw(this->pw_rhod); // mohan add 20251130
150150
const bool kin_den = this->chr.kin_density(); // mohan add 20251202
151-
this->chr.allocate(inp.nspin, kin_den); // mohan move this from setup_estate_pw, 20251128
151+
this->chr.allocate(inp.nspin, kin_den, inp.test_charge, inp.nelec); // mohan move this from setup_estate_pw, 20251128
152152

153153

154154
return;

source/source_esolver/esolver_ks.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ void ESolver_KS::iter_init(UnitCell& ucell, const int istep, const int iter)
210210
}
211211

212212
// save input charge density (rho)
213-
this->chr.save_rho_before_sum_band();
213+
this->chr.save_rho_before_sum_band(this->inp_->nspin);
214214
}
215215

216216
void ESolver_KS::iter_finish(UnitCell& ucell, const int istep, int& iter, bool &conv_esolver)

source/source_esolver/esolver_lr_lcao_tddft.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ void ModuleESolver::ESolver_LR<T, TR>::read_ks_chg(Charge& chg_gs)
823823
{
824824
chg_gs.set_rhopw(this->pw_rho);
825825
const bool kin_den = chg_gs.kin_density(); // mohan add 20251202
826-
chg_gs.allocate(this->nspin, kin_den);
826+
chg_gs.allocate(this->nspin, kin_den, this->inp_->test_charge, this->inp_->nelec);
827827
GlobalV::ofs_running << " try to read charge from file : ";
828828
for (int is = 0; is < this->nspin; ++is)
829829
{

source/source_esolver/esolver_of.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ void ESolver_OF::before_opt(const int istep, UnitCell& ucell)
220220
this->ptemp_rho_ = new Charge();
221221
this->ptemp_rho_->set_rhopw(this->pw_rho);
222222
const bool kin_den = this->ptemp_rho_->kin_density(); // mohan add 20251202
223-
this->ptemp_rho_->allocate(this->inp_->nspin, kin_den);
223+
this->ptemp_rho_->allocate(this->inp_->nspin, kin_den, this->inp_->test_charge, this->inp_->nelec);
224224

225225
for (int is = 0; is < this->inp_->nspin; ++is)
226226
{

source/source_esolver/esolver_of_tool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void ESolver_OF::allocate_array()
9090
this->ptemp_rho_ = new Charge();
9191
this->ptemp_rho_->set_rhopw(this->pw_rho);
9292
const bool kin_den = this->ptemp_rho_->kin_density(); // mohan add 20251202
93-
this->ptemp_rho_->allocate(this->inp_->nspin, kin_den);
93+
this->ptemp_rho_->allocate(this->inp_->nspin, kin_den, this->inp_->test_charge, this->inp_->nelec);
9494

9595
this->theta_ = new double[this->inp_->nspin];
9696
this->pdLdphi_ = new double*[this->inp_->nspin];

source/source_estate/module_charge/charge.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void Charge::destroy()
8686
}
8787
}
8888

89-
void Charge::allocate(const int& nspin_in, const bool kin_den)
89+
void Charge::allocate(const int& nspin_in, const bool kin_den, const int test_charge, const double& nelec_in)
9090
{
9191
ModuleBase::TITLE("Charge", "allocate");
9292

@@ -110,8 +110,9 @@ void Charge::allocate(const int& nspin_in, const bool kin_den)
110110

111111
// mohan add 2021-02-20
112112
this->nspin = nspin_in;
113+
this->nelec = nelec_in;
113114

114-
if (PARAM.inp.test_charge > 1)
115+
if (test_charge > 1)
115116
{
116117
std::cout << "\n spin_number = " << nspin << " real_point_number = " << nrxx << std::endl;
117118
}
@@ -217,7 +218,7 @@ void Charge::renormalize_rho()
217218
const double sr = this->sum_rho();
218219
GlobalV::ofs_warning << std::setprecision(15);
219220
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_warning, "charge before normalized", sr);
220-
const double normalize_factor = PARAM.inp.nelec / sr;
221+
const double normalize_factor = this->nelec / sr;
221222

222223
for (int is = 0; is < nspin; is++)
223224
{
@@ -651,9 +652,9 @@ void Charge::atomic_rho(const int spin_number_need,
651652
return;
652653
}
653654

654-
void Charge::save_rho_before_sum_band()
655+
void Charge::save_rho_before_sum_band(const int nspin)
655656
{
656-
for (int is = 0; is < PARAM.inp.nspin; is++)
657+
for (int is = 0; is < nspin; is++)
657658
{
658659
ModuleBase::GlobalFunc::DCOPY(rho[is], rho_save[is], this->rhopw->nrxx);
659660
if (XC_Functional::get_ked_flag())
@@ -687,7 +688,7 @@ void Charge::check_rho()
687688
{
688689
double ne = 0.0;
689690
ne = this->cal_rho2ne(rho[0]);
690-
if (std::abs(ne - PARAM.inp.nelec) > 1.0e-6)
691+
if (std::abs(ne - this->nelec) > 1.0e-6)
691692
{
692693
ModuleBase::WARNING("Charge", "Charge is not equal to the number of electrons!");
693694
}
@@ -709,31 +710,31 @@ void Charge::check_rho()
709710
ModuleBase::WARNING_QUIT("Charge", "Number of spin-up electrons set in starting magnetization exceeds all available.");
710711
}
711712
// for total charge
712-
if (std::abs(ne_up + ne_dn - PARAM.inp.nelec) > 1.0e-6)
713+
if (std::abs(ne_up + ne_dn - this->nelec) > 1.0e-6)
713714
{
714715
ModuleBase::WARNING("Charge", "Charge is not equal to the number of electrons!");
715716
}
716717
}
717718
}
718719

719720
// LiuXh add 20180619
720-
void Charge::init_final_scf()
721+
void Charge::init_final_scf(const int nspin, const int test_charge)
721722
{
722723
ModuleBase::TITLE("Charge", "init_after_scf");
723724

724725
assert(allocate_rho_final_scf == false);
725-
if (PARAM.inp.test_charge > 1)
726+
if (test_charge > 1)
726727
{
727-
std::cout << "\n spin_number = " << PARAM.inp.nspin << " real_point_number = " << this->rhopw->nrxx << std::endl;
728+
std::cout << "\n spin_number = " << nspin << " real_point_number = " << this->rhopw->nrxx << std::endl;
728729
}
729730

730731
// allocate memory
731-
rho = new double*[PARAM.inp.nspin];
732-
rhog = new std::complex<double>*[PARAM.inp.nspin];
733-
rho_save = new double*[PARAM.inp.nspin];
734-
rhog_save = new std::complex<double>*[PARAM.inp.nspin];
732+
rho = new double*[nspin];
733+
rhog = new std::complex<double>*[nspin];
734+
rho_save = new double*[nspin];
735+
rhog_save = new std::complex<double>*[nspin];
735736

736-
for (int is = 0; is < PARAM.inp.nspin; is++)
737+
for (int is = 0; is < nspin; is++)
737738
{
738739
rho[is] = new double[this->rhopw->nrxx];
739740
rhog[is] = new std::complex<double>[this->rhopw->npw];
@@ -745,10 +746,10 @@ void Charge::init_final_scf()
745746
ModuleBase::GlobalFunc::ZEROS(rhog_save[is], this->rhopw->npw);
746747
}
747748

748-
ModuleBase::Memory::record("Chg::rho", sizeof(double) * PARAM.inp.nspin * this->rhopw->nrxx);
749-
ModuleBase::Memory::record("Chg::rho_save", sizeof(double) * PARAM.inp.nspin * this->rhopw->nrxx);
750-
ModuleBase::Memory::record("Chg::rhog", sizeof(double) * PARAM.inp.nspin * this->rhopw->npw);
751-
ModuleBase::Memory::record("Chg::rhog_save", sizeof(double) * PARAM.inp.nspin * this->rhopw->npw);
749+
ModuleBase::Memory::record("Chg::rho", sizeof(double) * nspin * this->rhopw->nrxx);
750+
ModuleBase::Memory::record("Chg::rho_save", sizeof(double) * nspin * this->rhopw->nrxx);
751+
ModuleBase::Memory::record("Chg::rhog", sizeof(double) * nspin * this->rhopw->npw);
752+
ModuleBase::Memory::record("Chg::rhog_save", sizeof(double) * nspin * this->rhopw->npw);
752753

753754
this->rho_core = new double[this->rhopw->nrxx]; // core charge in real space
754755
ModuleBase::GlobalFunc::ZEROS(rho_core, this->rhopw->nrxx);

source/source_estate/module_charge/charge.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ class Charge
8686
// mohan add 2025-12-02
8787
bool kin_density() const;
8888

89-
void allocate(const int &nspin_in, const bool kin_den);
89+
/// @param test_charge INPUT verbosity for charge diagnostics
90+
/// @param nelec target number of electrons; kept as state, like nspin,
91+
/// because renormalize_rho() and check_rho() need it long after
92+
/// allocate() has returned
93+
void allocate(const int &nspin_in, const bool kin_den, const int test_charge, const double& nelec_in);
9094

9195
void atomic_rho(const int spin_number_need,
9296
const double& omega,
@@ -102,7 +106,8 @@ class Charge
102106

103107
double sum_rho() const;
104108

105-
void save_rho_before_sum_band();
109+
/// @param nspin number of spin channels to copy
110+
void save_rho_before_sum_band(const int nspin);
106111

107112
// for non-linear core correction
108113
void non_linear_core_correction
@@ -121,7 +126,25 @@ class Charge
121126

122127
void check_rho(); // to check whether the charge density is normal
123128

124-
void init_final_scf(); //LiuXh add 20180619
129+
/// @param nspin number of spin channels to allocate
130+
/// @param test_charge INPUT verbosity for charge diagnostics
131+
void init_final_scf(const int nspin, const int test_charge); //LiuXh add 20180619
132+
133+
//====================================================================
134+
// Test seam: the two allocation flags are read-only state that
135+
// charge_test checks after each allocate()/init_final_scf() call.
136+
//====================================================================
137+
138+
/// @brief whether allocate() has claimed the rho arrays
139+
bool get_allocate_rho() const
140+
{
141+
return allocate_rho;
142+
}
143+
/// @brief whether init_final_scf() has claimed the rho arrays
144+
bool get_allocate_rho_final_scf() const
145+
{
146+
return allocate_rho_final_scf;
147+
}
125148

126149
public:
127150
/**
@@ -152,6 +175,7 @@ class Charge
152175
int nxyz = 0; // total number of r vectors
153176
int ngmc=0; // number of g vectors in this processor
154177
int nspin=0; // number of spins
178+
double nelec=0.0; // target number of electrons, set by allocate()
155179
ModulePW::PW_Basis* rhopw = nullptr;// When double_grid is used, rhopw = rhodpw (dense grid)
156180
bool cal_elf = false; // whether to calculate electron localization function (ELF)
157181

source/source_estate/module_pot/pot_xc_fdm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void PotXC_FDM::cal_v_eff(
4949

5050
Charge chg_01;
5151
chg_01.set_rhopw(chg_1->rhopw);
52-
chg_01.allocate(chg_1->nspin, chg_01.kin_density());
52+
chg_01.allocate(chg_1->nspin, chg_01.kin_density(), /*test_charge=*/0, chg_1->nelec);
5353

5454
for(int ir=0; ir<chg_01.nrxx; ++ir)
5555
{

0 commit comments

Comments
 (0)