Skip to content

Commit 632e4d5

Browse files
committed
Code cleanup
1 parent f0ebe40 commit 632e4d5

16 files changed

Lines changed: 146 additions & 237 deletions

File tree

docs/advanced/input_files/input-main.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -856,11 +856,14 @@
856856
- **Type**: String
857857
- **Description**: Wavefunction extrapolation method for LCAO calculations.
858858

859-
- none: Disable wavefunction-based extrapolation.
860-
- use_prev_wf: Use the previous ionic step wavefunctions as the initial guess.
859+
- none: Disable wavefunction-based extrapolation and use chg_extrap instead.
860+
- use_prev_wf: Restore the previous converged ionic-step wavefunctions,
861+
reorthonormalize their occupied subspace in the current AO metric, and rebuild rho.
861862

863+
The first ionic step uses the normal init_wfc/init_chg initialization because no
864+
history exists yet. From the second ionic step onward, the selected WFN method
865+
must succeed; ABACUS does not silently fall back to charge-density extrapolation.
862866
This option is currently limited to Gamma-only LCAO calculations.
863-
The k-point, ASPC, and GExt_PROJ paths will be enabled by later updates.
864867
- **Default**: none
865868

866869
### nb2d

docs/parameters.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,14 @@ parameters:
339339
description: |
340340
Wavefunction extrapolation method for LCAO calculations.
341341
342-
* none: Disable wavefunction-based extrapolation.
343-
* use_prev_wf: Use the previous ionic step wavefunctions as the initial guess.
342+
* none: Disable wavefunction-based extrapolation and use chg_extrap instead.
343+
* use_prev_wf: Restore the previous converged ionic-step wavefunctions,
344+
reorthonormalize their occupied subspace in the current AO metric, and rebuild rho.
344345
346+
The first ionic step uses the normal init_wfc/init_chg initialization because no
347+
history exists yet. From the second ionic step onward, the selected WFN method
348+
must succeed; ABACUS does not silently fall back to charge-density extrapolation.
345349
This option is currently limited to Gamma-only LCAO calculations.
346-
The k-point, ASPC, and GExt_PROJ paths will be enabled by later updates.
347350
default_value: none
348351
unit: ""
349352
availability: ""

source/source_esolver/esolver_fp.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ void ESolver_FP::before_all_runners(BaseCell& basecell, const Input_para& inp)
7373
this->sf.set(this->pw_rhod, inp.nbspline);
7474

7575
//! 4) init charge extrapolation
76-
this->CE.Init_CE(inp.nspin, ucell.nat, this->pw_rhod->nrxx, inp.chg_extrap);
76+
this->use_wfc_extrapolation_ = inp.wfc_extrap != "none";
77+
this->CE.Init_CE(inp.nspin, ucell.nat, this->pw_rhod->nrxx,
78+
this->use_wfc_extrapolation_ ? "none" : inp.chg_extrap);
7779

7880
//! 5) symmetry analysis should be performed every time the cell is changed
7981
if (ModuleSymmetry::Symmetry::symm_flag == 1)
@@ -180,19 +182,13 @@ void ESolver_FP::before_scf(UnitCell& ucell, const int istep)
180182
// charge extrapolation
181183
if (ucell.ionic_position_updated)
182184
{
183-
this->CE.update_all_dis(ucell);
184-
185-
const bool skip_charge_extrap_for_wfc = PARAM.inp.basis_type == "lcao"
186-
&& PARAM.inp.wfc_extrap != "none"
187-
&& istep > 0;
188-
if (skip_charge_extrap_for_wfc)
185+
if (this->use_wfc_extrapolation_)
189186
{
190187
this->sf.setup(&ucell, this->Pgrid, this->pw_rhod);
191-
GlobalV::ofs_running << " charge density extrapolation is skipped because wfc_extrap = "
192-
<< PARAM.inp.wfc_extrap << "." << std::endl;
193188
}
194189
else
195190
{
191+
this->CE.update_all_dis(ucell);
196192
this->CE.extrapolate_charge(&this->Pgrid, ucell, &this->chr, &this->sf,
197193
GlobalV::ofs_running, GlobalV::ofs_warning);
198194
}

source/source_esolver/esolver_fp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class ESolver_FP : public ESolver
8282

8383
//! charge extrapolation method
8484
Charge_Extra CE;
85+
bool use_wfc_extrapolation_ = false;
8586

8687
//! solvent model
8788
surchem solvent;

source/source_esolver/esolver_ks_lcao.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ void ESolver_KS_LCAO<TK, TR>::before_all_runners(BaseCell& basecell, const Input
9090
LCAO_domain::set_psi_occ_dm_chg<TK>(this->kv, this->psi, this->pv, this->pelec,
9191
this->dmat, this->chr, inp);
9292

93-
this->wf_history_lcao_.set_method(ModuleExtrap::wfc_extrap_method_from_string(inp.wfc_extrap));
94-
9593
LCAO_domain::set_pot<TK>(ucell, this->kv, this->sf, *this->pw_rho, *this->pw_rhod,
9694
this->pelec, this->orb_, this->pv, this->locpp, this->dftu,
9795
this->solvent, this->exx_nao, this->deepks, inp);
@@ -205,13 +203,13 @@ void ESolver_KS_LCAO<TK, TR>::before_scf(UnitCell& ucell, const int istep)
205203
}
206204
else if(PARAM.inp.esolver_type!="tddft")//initialize DMR from WFN history if required
207205
{
208-
if (!this->wf_history_lcao_.initialize_gamma_density(
209-
*hamilt_lcao, this->pv, *(this->psi), this->pelec->wg, *(this->dmat.dm), this->chr,
210-
PARAM.inp.nspin, PARAM.inp.ks_solver))
206+
if (this->use_wfc_extrapolation_)
207+
{
208+
this->wf_history_lcao_.initialize_gamma_density(
209+
*hamilt_lcao, this->pv, *(this->psi), this->pelec->wg, *(this->dmat.dm), this->chr);
210+
}
211+
else
211212
{
212-
// 13.1.2) two cases are considered:
213-
// 1. DMK in DensityMatrix is not empty (istep > 0), then DMR is initialized by DMK
214-
// 2. DMK in DensityMatrix is empty (istep == 0), then DMR is initialized by zeros
215213
this->dmat.dm->cal_DMR();
216214
}
217215
}
@@ -579,7 +577,7 @@ void ESolver_KS_LCAO<TK, TR>::after_scf(UnitCell& ucell, const int istep, const
579577
this->rdmft_solver, this->deepks, this->exx_nao,
580578
this->conv_esolver, this->scf_nmax_flag, istep);
581579

582-
if (conv_esolver && this->psi != nullptr)
580+
if (conv_esolver && this->psi != nullptr && this->use_wfc_extrapolation_)
583581
{
584582
this->wf_history_lcao_.update_after_scf(istep, *(this->psi), this->pelec->wg);
585583
}

source/source_io/module_parameter/read_input_item_system.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -927,11 +927,14 @@ Available options are:
927927
item.type = "String";
928928
item.description = R"(Wavefunction extrapolation method for LCAO calculations.
929929
930-
* none: Disable wavefunction-based extrapolation.
931-
* use_prev_wf: Use the previous ionic step wavefunctions as the initial guess.
930+
* none: Disable wavefunction-based extrapolation and use chg_extrap instead.
931+
* use_prev_wf: Restore the previous converged ionic-step wavefunctions,
932+
reorthonormalize their occupied subspace in the current AO metric, and rebuild rho.
932933
933-
This option is currently limited to Gamma-only LCAO calculations.
934-
The k-point, ASPC, and GExt_PROJ paths will be enabled by later updates.)";
934+
The first ionic step uses the normal init_wfc/init_chg initialization because no
935+
history exists yet. From the second ionic step onward, the selected WFN method
936+
must succeed; ABACUS does not silently fall back to charge-density extrapolation.
937+
This option is currently limited to Gamma-only LCAO calculations.)";
935938
item.default_value = "none";
936939
read_sync_string(input.wfc_extrap);
937940
item.check_value = [](const Input_Item& item, const Parameter& para) {

source/source_io/test/read_input_ptest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ TEST_F(InputParaTest, ParaRead)
182182
EXPECT_EQ(param.inp.mem_saver, 0);
183183
EXPECT_EQ(param.inp.init_chg, "atomic");
184184
EXPECT_EQ(param.inp.chg_extrap, "atomic");
185+
EXPECT_EQ(param.inp.wfc_extrap, "use_prev_wf");
185186
EXPECT_EQ(param.inp.out_freq_elec, 50);
186187
EXPECT_EQ(param.inp.out_freq_ion, 0);
187188
EXPECT_EQ(param.inp.out_freq_td, 0);

source/source_io/test/support/INPUT

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ scf_thr_type 2 #type of the criterion of scf_thr, 1: reci drho
5757
init_wfc atomic #start wave functions are from 'atomic', 'atomic+random', 'random' or 'file'
5858
init_chg atomic #start charge is from 'atomic' or file
5959
chg_extrap atomic #atomic; first-order; second-order; dm:coefficients of SIA
60+
wfc_extrap use_prev_wf #Gamma-only LCAO wavefunction initialization
6061
out_chg 0 #>0 output charge density for selected electron steps
6162
out_pot 2 #output realspace potential
6263
out_wfc_pw 0 #output wave functions

source/source_lcao/module_extrap/test/wf_extrap_test.cpp

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ namespace
1414
constexpr int nstate = 1;
1515
constexpr int nbands = 3;
1616
constexpr int nbasis = 3;
17+
constexpr double occupation_threshold = 1.0e-12;
18+
constexpr double pivot_threshold = 1.0e-14;
19+
constexpr double check_tolerance = 1.0e-8;
1720

1821
void initialize_serial_orbitals(Parallel_Orbitals& pv)
1922
{
@@ -72,6 +75,14 @@ const std::vector<double> coeff = {
7275
7.0, 8.0, 9.0,
7376
};
7477

78+
ModuleExtrap::WfOrthonormalizeResult reorthonormalize(const Parallel_Orbitals& pv,
79+
psi::Psi<double>& wfc,
80+
const ModuleBase::matrix& occupations)
81+
{
82+
return ModuleExtrap::reorthonormalize_gamma_lcao(overlap.data(), pv, wfc, occupations,
83+
occupation_threshold, pivot_threshold, check_tolerance);
84+
}
85+
7586
} // namespace
7687

7788
TEST(WfSnapshotLCAO, OwnsAndRestoresData)
@@ -102,8 +113,7 @@ TEST(WfOrthonormalizeLCAO, ReorthonormalizesOccupiedSubspace)
102113
psi::Psi<double> wfc = make_psi(coeff);
103114
const ModuleBase::matrix occupations = make_occupations();
104115

105-
const ModuleExtrap::WfOrthonormalizeResult result
106-
= ModuleExtrap::reorthonormalize_gamma_lcao(overlap.data(), pv, wfc, occupations);
116+
const ModuleExtrap::WfOrthonormalizeResult result = reorthonormalize(pv, wfc, occupations);
107117

108118
ASSERT_TRUE(result.ok());
109119
EXPECT_EQ(result.nstate, nstate);
@@ -133,8 +143,7 @@ TEST(WfOrthonormalizeLCAO, DoesNotModifyPsiOnFailure)
133143
psi::Psi<double> wfc = make_psi(rank_deficient_coeff);
134144
const ModuleBase::matrix occupations = make_occupations();
135145

136-
const ModuleExtrap::WfOrthonormalizeResult result
137-
= ModuleExtrap::reorthonormalize_gamma_lcao(overlap.data(), pv, wfc, occupations);
146+
const ModuleExtrap::WfOrthonormalizeResult result = reorthonormalize(pv, wfc, occupations);
138147

139148
EXPECT_EQ(result.status, ModuleExtrap::WfcExtrapStatus::OrthogonalizationFailed);
140149
for (std::size_t i = 0; i < rank_deficient_coeff.size(); ++i)
@@ -143,12 +152,45 @@ TEST(WfOrthonormalizeLCAO, DoesNotModifyPsiOnFailure)
143152
}
144153
}
145154

155+
TEST(WfOrthonormalizeLCAO, HandlesBandDistributedCoefficients)
156+
{
157+
Parallel_Orbitals pv;
158+
initialize_serial_orbitals(pv);
159+
pv.ncol_bands = 2;
160+
pv.nbands = 2;
161+
#ifdef __MPI
162+
pv.desc_wfc[3] = 2;
163+
#endif
164+
psi::Psi<double> wfc(nstate, 2, nbasis, nbasis, true);
165+
wfc.set_all_psi(coeff.data(), 2 * nbasis);
166+
167+
const ModuleExtrap::WfOrthonormalizeResult result = reorthonormalize(pv, wfc, make_occupations());
168+
EXPECT_TRUE(result.ok());
169+
}
170+
171+
TEST(WfHistoryLCAO, ReportsMissingHistory)
172+
{
173+
Parallel_Orbitals pv;
174+
initialize_serial_orbitals(pv);
175+
ModuleExtrap::WfHistoryLCAO<double> history;
176+
psi::Psi<double> predicted = make_psi(coeff);
177+
178+
const ModuleExtrap::WfExtrapApplyResult result
179+
= history.try_use_prev_wf_gamma(overlap.data(),
180+
pv,
181+
predicted,
182+
make_occupations(),
183+
pivot_threshold,
184+
check_tolerance);
185+
EXPECT_EQ(result.status, ModuleExtrap::WfcExtrapStatus::EmptyHistory);
186+
}
187+
146188
TEST(WfHistoryLCAO, UsesLatestOwnedSnapshot)
147189
{
148190
Parallel_Orbitals pv;
149191
initialize_serial_orbitals(pv);
150192
const ModuleBase::matrix occupations = make_occupations();
151-
ModuleExtrap::WfHistoryLCAO<double> history(ModuleExtrap::WfcExtrapMethod::UsePrevWf, 2);
193+
ModuleExtrap::WfHistoryLCAO<double> history;
152194

153195
psi::Psi<double> first = make_psi(coeff);
154196
history.update_after_scf(3, first, occupations);
@@ -164,15 +206,16 @@ TEST(WfHistoryLCAO, UsesLatestOwnedSnapshot)
164206

165207
psi::Psi<double> predicted(nstate, nbands, nbasis, nbasis, true);
166208
const ModuleExtrap::WfExtrapApplyResult result
167-
= history.try_use_prev_wf_gamma(overlap.data(), pv, predicted, occupations);
209+
= history.try_use_prev_wf_gamma(overlap.data(),
210+
pv,
211+
predicted,
212+
occupations,
213+
pivot_threshold,
214+
check_tolerance);
168215

169216
ASSERT_TRUE(result.ok());
170217
EXPECT_EQ(result.snapshot_istep, 4);
171-
EXPECT_EQ(history.size(), 2U);
172218
EXPECT_NEAR(metric_element(predicted, overlap, 0, 0), 1.0, 1.0e-10);
173219
EXPECT_NEAR(metric_element(predicted, overlap, 1, 1), 1.0, 1.0e-10);
174220
EXPECT_NEAR(metric_element(predicted, overlap, 0, 1), 0.0, 1.0e-10);
175-
176-
history.set_max_depth(1);
177-
EXPECT_EQ(history.size(), 1U);
178221
}

source/source_lcao/module_extrap/wf_density_init_lcao.cpp

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "source_lcao/module_extrap/wf_history_lcao.h"
22

3-
#include "source_base/global_function.h"
4-
#include "source_base/global_variable.h"
53
#include "source_base/timer.h"
64
#include "source_base/tool_quit.h"
75
#include "source_estate/module_dm/cal_dm_psi.h"
@@ -35,44 +33,45 @@ std::string wfc_extrapolation_failure_message(const WfExtrapApplyResult& result)
3533
<< " max_metric_diag=" << result.max_metric_diag << "\n"
3634
<< " max_metric_abs=" << result.max_metric_abs << "\n"
3735
<< " max_metric_asymmetry=" << result.max_metric_asymmetry << "\n"
38-
<< " max_orthonormality_deviation=" << result.max_orthonormality_deviation << "\n";
36+
<< " max_orthonormality_deviation=" << result.max_orthonormality_deviation << "\n"
37+
<< "No fallback was attempted; set wfc_extrap to none to use chg_extrap.\n";
3938
return oss.str();
4039
}
4140

4241
} // namespace
4342

4443
template <typename TK>
45-
bool WfHistoryLCAO<TK>::initialize_gamma_density(hamilt::Hamilt<TK>&,
44+
void WfHistoryLCAO<TK>::initialize_gamma_density(hamilt::Hamilt<TK>&,
4645
const Parallel_Orbitals&,
4746
psi::Psi<TK>&,
4847
const ModuleBase::matrix&,
4948
elecstate::DensityMatrix<TK, double>&,
50-
Charge&,
51-
const int,
52-
const std::string&)
49+
Charge&)
5350
{
54-
if (!this->enabled() || this->empty())
51+
if (!this->has_snapshot_)
5552
{
56-
return false;
53+
ModuleBase::WARNING_QUIT("WfHistoryLCAO::initialize_gamma_density",
54+
"wfc_extrap was selected, but no converged wavefunction history is available. "
55+
"No fallback was attempted; set wfc_extrap to none to use chg_extrap.");
5756
}
5857
ModuleBase::WARNING_QUIT("WfHistoryLCAO::initialize_gamma_density",
59-
"WFN extrapolation is currently supported only for the real Gamma-only NAO path.");
60-
return false;
58+
"WFN extrapolation is supported only for the real Gamma-only NAO path. "
59+
"No fallback was attempted; set wfc_extrap to none to use chg_extrap.");
6160
}
6261

6362
template <>
64-
bool WfHistoryLCAO<double>::initialize_gamma_density(hamilt::Hamilt<double>& hamiltonian,
63+
void WfHistoryLCAO<double>::initialize_gamma_density(hamilt::Hamilt<double>& hamiltonian,
6564
const Parallel_Orbitals& pv,
6665
psi::Psi<double>& psi,
6766
const ModuleBase::matrix& wg_now,
6867
elecstate::DensityMatrix<double, double>& dmat,
69-
Charge& charge,
70-
const int nspin,
71-
const std::string& ks_solver)
68+
Charge& charge)
7269
{
73-
if (!this->enabled() || this->empty())
70+
if (!this->has_snapshot_)
7471
{
75-
return false;
72+
ModuleBase::WARNING_QUIT("WfHistoryLCAO::initialize_gamma_density",
73+
"wfc_extrap was selected, but no converged wavefunction history is available. "
74+
"No fallback was attempted; set wfc_extrap to none to use chg_extrap.");
7675
}
7776

7877
auto* hamilt_lcao = dynamic_cast<hamilt::HamiltLCAO<double, double>*>(&hamiltonian);
@@ -91,12 +90,12 @@ bool WfHistoryLCAO<double>::initialize_gamma_density(hamilt::Hamilt<double>& ham
9190

9291
ModuleBase::timer::start("WFN_Extrap", "prepare_overlap");
9392
lcao_op->contributeHR();
94-
const int sk_layout = ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(ks_solver) ? 1 : 0;
95-
hamilt_lcao->updateSk(0, sk_layout);
93+
hamilt_lcao->updateSk(0, 1);
9694
ModuleBase::timer::end("WFN_Extrap", "prepare_overlap");
9795

9896
ModuleBase::timer::start("WFN_Extrap", "apply");
99-
const WfExtrapApplyResult result = this->try_use_prev_wf_gamma(hamilt_lcao->getSk(), pv, psi, wg_now);
97+
const WfExtrapApplyResult result
98+
= this->try_use_prev_wf_gamma(hamilt_lcao->getSk(), pv, psi, wg_now, 1.0e-14, 1.0e-8);
10099
ModuleBase::timer::end("WFN_Extrap", "apply");
101100
if (!result.ok())
102101
{
@@ -107,18 +106,12 @@ bool WfHistoryLCAO<double>::initialize_gamma_density(hamilt::Hamilt<double>& ham
107106
ModuleBase::timer::start("WFN_Extrap", "rebuild_density");
108107
elecstate::cal_dm_psi(dmat.get_paraV_pointer(), wg_now, psi, dmat);
109108
dmat.cal_DMR();
110-
LCAO_domain::dm2rho(dmat.get_DMR_vector(), nspin, &charge);
109+
LCAO_domain::dm2rho(dmat.get_DMR_vector(), charge.nspin, &charge);
111110
ModuleBase::timer::end("WFN_Extrap", "rebuild_density");
112-
113-
GlobalV::ofs_running << " WFN extrapolation: use_prev_wf from ionic step " << result.snapshot_istep
114-
<< ", active bands = " << result.nactive_bands
115-
<< ", max |C^T S C - I| = " << result.max_orthonormality_deviation << std::endl;
116-
return true;
117111
}
118112

119-
template bool WfHistoryLCAO<std::complex<double>>::initialize_gamma_density(
113+
template void WfHistoryLCAO<std::complex<double>>::initialize_gamma_density(
120114
hamilt::Hamilt<std::complex<double>>&, const Parallel_Orbitals&, psi::Psi<std::complex<double>>&,
121-
const ModuleBase::matrix&, elecstate::DensityMatrix<std::complex<double>, double>&, Charge&, int,
122-
const std::string&);
115+
const ModuleBase::matrix&, elecstate::DensityMatrix<std::complex<double>, double>&, Charge&);
123116

124117
} // namespace ModuleExtrap

0 commit comments

Comments
 (0)