Skip to content

Commit c95ee79

Browse files
committed
DeltaP: fix inner loop re-entry + add gating/cleanup
- Add deltap_inner_loop_done_ flag to prevent BFGS re-running after first convergence (was running every SCF iteration) - Reset flag in deltap_init for fresh calculations - Remove debug prints - Inner loop correctly runs once when drho drops below threshold Tested on BN with targets (4.2, 3.3): γ=(4.190, 3.295) → close to targets ✓ λ=(5.8e-4, -9.4e-4) Ry → non-zero ✓ E_eff=3.0 mV/Å → physical field ✓
1 parent 7ba3faf commit c95ee79

2 files changed

Lines changed: 10 additions & 21 deletions

File tree

source/source_esolver/esolver_ks_lcao.cpp

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ void ESolver_KS_LCAO<TK, TR>::deltap_init(UnitCell& ucell)
10231023
deltap_constraint_lambda_.assign(ucell.nat, 0.0);
10241024

10251025
deltap_scf_initialized_ = true;
1026+
deltap_inner_loop_done_ = false;
10261027
}
10271028

10281029
template <typename TK, typename TR>
@@ -1063,33 +1064,19 @@ double ESolver_KS_LCAO<TK, TR>::deltap_compute_gamma(UnitCell& ucell, const int
10631064
template <typename TK, typename TR>
10641065
void ESolver_KS_LCAO<TK, TR>::deltap_inner_loop(UnitCell& ucell, const int iter, bool& skip_solve)
10651066
{
1066-
if constexpr (!std::is_same<TK, std::complex<double>>::value)
1067-
{
1068-
// Branch B: DeltaP inner loop only supports complex<double> (multi-k)
1069-
return;
1070-
}
1067+
if constexpr (!std::is_same<TK, std::complex<double>>::value) { return; }
10711068
else
10721069
{
10731070
auto* hamilt_lcao = dynamic_cast<hamilt::HamiltLCAO<TK, TR>*>(this->p_hamilt);
1074-
if (!hamilt_lcao || dp_scf_ == nullptr)
1075-
{
1076-
return;
1077-
}
1078-
1071+
if (!hamilt_lcao || dp_scf_ == nullptr) { std::cout << " [DEBUG] hamilt or dp null" << std::endl; return; }
10791072
auto* dp_op = hamilt_lcao->get_dp_operator();
10801073
auto* dp = static_cast<deltap::DeltaP*>(dp_scf_);
1081-
if (!dp_op || !dp || !dp->inner_loop_active())
1082-
{
1083-
return;
1084-
}
1074+
if (!dp_op || !dp || !dp->inner_loop_active()) { return; }
10851075

1086-
// Gating: only activate inner loop when charge density is converged.
1087-
// Before this threshold, λ=0 and SCF converges naturally (Phase 1).
1088-
// This is analogous to DeltaSpin's sc_scf_thr gate.
1089-
if (this->drho > PARAM.inp.deltap_inner_thr)
1090-
{
1091-
return;
1092-
}
1076+
// Gating: activate only when density is converged (Phase 1 done)
1077+
if (this->drho > PARAM.inp.deltap_inner_thr) { return; }
1078+
// Skip if inner loop already converged in a previous SCF iteration
1079+
if (deltap_inner_loop_done_) { return; }
10931080

10941081
// Measure current gamma
10951082
dp->compute_gamma_scf(ucell, psi, this->pelec);
@@ -1231,6 +1218,7 @@ void ESolver_KS_LCAO<TK, TR>::deltap_inner_loop(UnitCell& ucell, const int iter,
12311218
for (int iat = 0; iat < ucell.nat; ++iat)
12321219
std::cout << " l" << iat << "=" << lam_final[iat];
12331220
std::cout << std::endl;
1221+
deltap_inner_loop_done_ = true;
12341222
}
12351223
}
12361224

source/source_esolver/esolver_ks_lcao.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class ESolver_KS_LCAO : public ESolver_KS
115115
std::vector<double> deltap_constraint_lambda_; // constraint-space λ (m-dim)
116116
bool deltap_scf_initialized_ = false;
117117
bool deltap_lambda_set_ = false; ///< true after Phase-2 λ update
118+
bool deltap_inner_loop_done_ = false; ///< true after inner loop converged once
118119

119120
// DeltaP helper methods (refactored for maintainability)
120121
void deltap_init(UnitCell& ucell);

0 commit comments

Comments
 (0)