Skip to content

Commit c1840ef

Browse files
committed
fix: revert BLOCK_SUBSPACE to use_p=false to avoid M singularity
The 3-block [psi, w, p] subspace generalized eigenproblem becomes ill-conditioned when residuals are small (near convergence). The [w, p] Gram block shrinks, the M matrix approaches singularity, and dsygvd produces garbage eigenvectors that drive eigenvalues to catastrophic values (e.g., -137775 instead of 0.081). The p-bad H·w Krylov fallback fixes p~w collinearity but does not address the small-residual ill-conditioning, which is fundamental to the 3-block construction. Keep use_p=false for robust convergence.
1 parent 187c1f0 commit c1840ef

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

source/source_hsolver/diago_ppcg.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,13 +1168,15 @@ double DiagoPPCG<T, Device>::diag(const HPsiFunc& hpsi_func,
11681168

11691169
avg_iter += static_cast<double>(nact) / static_cast<double>(ncol);
11701170

1171-
// Use the 3-block [psi, w, p] subspace for faster convergence.
1172-
// When p is nearly collinear with w (p ~ w), the subspace Gram
1173-
// matrix becomes nearly singular, causing the generalized
1174-
// eigenvalue solver to fail. The p-bad detection below catches
1175-
// this and replaces p with H·w (a genuinely independent Krylov
1176-
// direction), keeping the subspace full-rank.
1177-
const bool use_p = true;
1171+
// Use the 2-block [psi, w] subspace (preconditioned Davidson).
1172+
// The 3-block [psi, w, p] subspace can become ill-conditioned
1173+
// when residuals are small: the [w, p] block of the Gram matrix
1174+
// shrinks, making M nearly singular and causing sygvd to produce
1175+
// garbage eigenvectors. The p-bad detection + H·w Krylov fallback
1176+
// (below, currently disabled) addresses p~w collinearity but not
1177+
// the small-residual ill-conditioning. Without p the method
1178+
// converges robustly with slightly more iterations.
1179+
const bool use_p = false;
11781180
if (use_p)
11791181
{
11801182
apply_s_current(p_.data(), sp_.data(), ncol);

0 commit comments

Comments
 (0)