Skip to content

Commit cd48c62

Browse files
authored
Feature: binary format of backup charge density (#5782)
* Feature: binary format of backup charge density * Tests: update tests * move backup charge density output to esolver_fp
1 parent 6fadfb9 commit cd48c62

File tree

10 files changed

+67
-74
lines changed

10 files changed

+67
-74
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,10 +1561,8 @@ These variables are used to control the output of properties.
15611561
### out_freq_elec
15621562

15631563
- **Type**: Integer
1564-
- **Description**: The output frequency of the charge density (controlled by [out_chg](#out_chg)), wavefunction (controlled by [out_wfc_pw](#out_wfc_pw) or [out_wfc_r](#out_wfc_r)), and density matrix of localized orbitals (controlled by [out_dm](#out_dm)).
1565-
- \>0: Output them every `out_freq_elec` iteration numbers in electronic iterations.
1566-
- 0: Output them when the electronic iteration is converged or reaches the maximal iteration number.
1567-
- **Default**: 0
1564+
- **Description**: Output the charge density (only binary format, controlled by [out_chg](#out_chg)), wavefunction (controlled by [out_wfc_pw](#out_wfc_pw) or [out_wfc_r](#out_wfc_r)) per `out_freq_elec` electronic iterations. Note that they are always output when converged or reach the maximum iterations [scf_nmax](#scf_nmax).
1565+
- **Default**: [scf_nmax](#scf_nmax)
15681566

15691567
### out_chg
15701568

source/module_esolver/esolver_fp.cpp

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -183,24 +183,6 @@ void ESolver_FP::after_scf(UnitCell& ucell, const int istep)
183183
}
184184
}
185185
}
186-
if (PARAM.inp.out_chg[0] != -1)
187-
{
188-
std::complex<double>** rhog_tot = (PARAM.inp.dm_to_rho)? this->pelec->charge->rhog : this->pelec->charge->rhog_save;
189-
double** rhor_tot = (PARAM.inp.dm_to_rho)? this->pelec->charge->rho : this->pelec->charge->rho_save;
190-
for (int is = 0; is < PARAM.inp.nspin; is++)
191-
{
192-
this->pw_rhod->real2recip(rhor_tot[is], rhog_tot[is]);
193-
}
194-
ModuleIO::write_rhog(PARAM.globalv.global_out_dir + PARAM.inp.suffix + "-CHARGE-DENSITY.restart",
195-
PARAM.globalv.gamma_only_pw || PARAM.globalv.gamma_only_local,
196-
this->pw_rhod,
197-
PARAM.inp.nspin,
198-
ucell.GT,
199-
rhog_tot,
200-
GlobalV::MY_POOL,
201-
GlobalV::RANK_IN_POOL,
202-
GlobalV::NPROC_IN_POOL);
203-
}
204186

205187
// 4) write potential
206188
if (PARAM.inp.out_pot == 1 || PARAM.inp.out_pot == 3)
@@ -304,4 +286,51 @@ void ESolver_FP::before_scf(UnitCell& ucell, const int istep)
304286
return;
305287
}
306288

289+
void ESolver_FP::iter_finish(UnitCell& ucell, const int istep, int& iter)
290+
{
291+
//! output charge density
292+
if (PARAM.inp.out_chg[0] != -1)
293+
{
294+
if (iter % PARAM.inp.out_freq_elec == 0 || iter == PARAM.inp.scf_nmax || this->conv_esolver)
295+
{
296+
std::complex<double>** rhog_tot
297+
= (PARAM.inp.dm_to_rho) ? this->pelec->charge->rhog : this->pelec->charge->rhog_save;
298+
double** rhor_tot = (PARAM.inp.dm_to_rho) ? this->pelec->charge->rho : this->pelec->charge->rho_save;
299+
for (int is = 0; is < PARAM.inp.nspin; is++)
300+
{
301+
this->pw_rhod->real2recip(rhor_tot[is], rhog_tot[is]);
302+
}
303+
ModuleIO::write_rhog(PARAM.globalv.global_out_dir + PARAM.inp.suffix + "-CHARGE-DENSITY.restart",
304+
PARAM.globalv.gamma_only_pw || PARAM.globalv.gamma_only_local,
305+
this->pw_rhod,
306+
PARAM.inp.nspin,
307+
ucell.GT,
308+
rhog_tot,
309+
GlobalV::MY_POOL,
310+
GlobalV::RANK_IN_POOL,
311+
GlobalV::NPROC_IN_POOL);
312+
313+
if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5)
314+
{
315+
std::vector<std::complex<double>> kin_g_space(PARAM.inp.nspin * this->pelec->charge->ngmc, {0.0, 0.0});
316+
std::vector<std::complex<double>*> kin_g;
317+
for (int is = 0; is < PARAM.inp.nspin; is++)
318+
{
319+
kin_g.push_back(kin_g_space.data() + is * this->pelec->charge->ngmc);
320+
this->pw_rhod->real2recip(this->pelec->charge->kin_r_save[is], kin_g[is]);
321+
}
322+
ModuleIO::write_rhog(PARAM.globalv.global_out_dir + PARAM.inp.suffix + "-TAU-DENSITY.restart",
323+
PARAM.globalv.gamma_only_pw || PARAM.globalv.gamma_only_local,
324+
this->pw_rhod,
325+
PARAM.inp.nspin,
326+
ucell.GT,
327+
kin_g.data(),
328+
GlobalV::MY_POOL,
329+
GlobalV::RANK_IN_POOL,
330+
GlobalV::NPROC_IN_POOL);
331+
}
332+
}
333+
}
334+
}
335+
307336
} // namespace ModuleESolver

source/module_esolver/esolver_fp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class ESolver_FP : public ESolver
4141
//! Something to do after SCF iterations when SCF is converged or comes to the max iter step.
4242
virtual void after_scf(UnitCell& ucell, const int istep);
4343

44+
//! Something to do after hamilt2density function in each iter loop.
45+
virtual void iter_finish(UnitCell& ucell, const int istep, int& iter);
46+
4447
//! ------------------------------------------------------------------------------
4548
//! These pointers will be deleted in the free_pointers() function every ion step.
4649
//! ------------------------------------------------------------------------------

source/module_esolver/esolver_ks.cpp

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ ESolver_KS<T, Device>::ESolver_KS()
4646
maxniter = PARAM.inp.scf_nmax;
4747
niter = maxniter;
4848

49-
// should not use GlobalV here, mohan 2024-05-12
50-
out_freq_elec = PARAM.inp.out_freq_elec;
51-
5249
// pw_rho = new ModuleBase::PW_Basis();
5350
// temporary, it will be removed
5451
std::string fft_device = PARAM.inp.device;
@@ -693,45 +690,7 @@ void ESolver_KS<T, Device>::iter_finish(UnitCell& ucell, const int istep, int& i
693690
std::cout << " SCF restart after this step!" << std::endl;
694691
}
695692

696-
//! output charge density and density matrix
697-
if (this->out_freq_elec && iter % this->out_freq_elec == 0)
698-
{
699-
for (int is = 0; is < PARAM.inp.nspin; is++)
700-
{
701-
double* data = nullptr;
702-
if (PARAM.inp.dm_to_rho)
703-
{
704-
data = this->pelec->charge->rho[is];
705-
}
706-
else
707-
{
708-
data = this->pelec->charge->rho_save[is];
709-
}
710-
std::string fn = PARAM.globalv.global_out_dir + "/tmp_SPIN" + std::to_string(is + 1) + "_CHG.cube";
711-
ModuleIO::write_vdata_palgrid(Pgrid,
712-
data,
713-
is,
714-
PARAM.inp.nspin,
715-
0,
716-
fn,
717-
this->pelec->eferm.get_efval(is),
718-
&(ucell),
719-
3,
720-
1);
721-
if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5)
722-
{
723-
fn = PARAM.globalv.global_out_dir + "/tmp_SPIN" + std::to_string(is + 1) + "_TAU.cube";
724-
ModuleIO::write_vdata_palgrid(Pgrid,
725-
this->pelec->charge->kin_r_save[is],
726-
is,
727-
PARAM.inp.nspin,
728-
0,
729-
fn,
730-
this->pelec->eferm.get_efval(is),
731-
&(ucell));
732-
}
733-
}
734-
}
693+
ESolver_FP::iter_finish(ucell, istep, iter);
735694
}
736695

737696
//! Something to do after SCF iterations when SCF is converged or comes to the max iter step.

source/module_esolver/esolver_ks.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ class ESolver_KS : public ESolver_FP
9595
double hsolver_error; //! the error of HSolver
9696
int maxniter; //! maximum iter steps for scf
9797
int niter; //! iter steps actually used in scf
98-
int out_freq_elec; //! frequency for output
9998
};
10099
} // namespace ModuleESolver
101100
#endif

source/module_esolver/esolver_ks_pw.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,10 @@ void ESolver_KS_PW<T, Device>::iter_finish(UnitCell& ucell, const int istep, int
619619
this->ppcell.cal_effective_D(veff, this->pw_rhod, ucell);
620620
}
621621

622-
if (this->out_freq_elec && iter % this->out_freq_elec == 0)
622+
// 4) Print out electronic wavefunctions
623+
if (PARAM.inp.out_wfc_pw == 1 || PARAM.inp.out_wfc_pw == 2)
623624
{
624-
// 4) Print out electronic wavefunctions
625-
if (PARAM.inp.out_wfc_pw == 1 || PARAM.inp.out_wfc_pw == 2)
625+
if (iter % PARAM.inp.out_freq_elec == 0 || iter == PARAM.inp.scf_nmax || this->conv_esolver)
626626
{
627627
std::stringstream ssw;
628628
ssw << PARAM.globalv.global_out_dir << "WAVEFUNC";

source/module_esolver/esolver_of.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ void ESolver_OF::runner(UnitCell& ucell, const int istep)
182182
this->update_rho();
183183

184184
this->iter_++;
185+
186+
ESolver_FP::iter_finish(ucell, istep, this->iter_);
185187
}
186188

187189
this->after_opt(istep, ucell);

source/module_io/read_input_item_output.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ void ReadInput::item_output()
2121
}
2222
{
2323
Input_Item item("out_freq_elec");
24-
item.annotation = "the frequency ( >= 0) of electronic iter to output "
25-
"charge density and wavefunction. 0: "
26-
"output only when converged";
24+
item.annotation = "the frequency of electronic iter to output charge density and wavefunction ";
25+
item.reset_value = [](const Input_Item& item, Parameter& para) {
26+
if (para.input.out_freq_elec <= 0)
27+
{
28+
para.input.out_freq_elec = para.input.scf_nmax;
29+
}
30+
};
2731
read_sync_int(input.out_freq_elec);
2832
this->add_item(item);
2933
}

source/module_io/test/read_input_ptest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ TEST_F(InputParaTest, ParaRead)
184184
EXPECT_EQ(param.inp.printe, 100);
185185
EXPECT_EQ(param.inp.init_chg, "atomic");
186186
EXPECT_EQ(param.inp.chg_extrap, "atomic");
187-
EXPECT_EQ(param.inp.out_freq_elec, 0);
187+
EXPECT_EQ(param.inp.out_freq_elec, 50);
188188
EXPECT_EQ(param.inp.out_freq_ion, 0);
189189
EXPECT_EQ(param.inp.out_chg[0], 0);
190190
EXPECT_EQ(param.inp.out_chg[1], 3);

source/module_parameter/input_parameter.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,7 @@ struct Input_para
316316
std::vector<int> aims_nbasis = {}; ///< the number of basis functions for each atom type used in FHI-aims (for benchmark)
317317
// ============== #Parameters (11.Output) ===========================
318318
bool out_stru = false; ///< outut stru file each ion step
319-
int out_freq_elec = 0; ///< the frequency ( >= 0) of electronic iter to output charge
320-
///< 0: output only when converged
319+
int out_freq_elec = 0; ///< the frequency of electronic iter to output charge and wavefunction
321320
int out_freq_ion = 0; ///< the frequency ( >= 0 ) of ionic step to output charge density;
322321
///< 0: output only when ion steps are finished
323322
std::vector<int> out_chg = {0, 3}; ///< output charge density. 0: no; 1: yes

0 commit comments

Comments
 (0)