Fix(hsolver): add early PW basis-size guard to report npw<nbands clearly#7237
Fix(hsolver): add early PW basis-size guard to report npw<nbands clearly#7237Cstandardlib wants to merge 1 commit intodeepmodeling:developfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an early validation in the PW Hamiltonian solver to fail fast (with a clearer, more actionable error) when the plane-wave basis at a k-point is too small for the requested number of bands, preventing obscure downstream solver failures (Issue #7201).
Changes:
- Add an early guard in
HSolverPW::hamiltSolvePsiKfornpw(dim) < nbands, emitting additional diagnostic context before aborting. - Reuse cached
dim/nbandvalues when calling the CG diagonalizer. - Minor whitespace tweak to an atomic-structure notice message.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
source/source_hsolver/hsolver_pw.cpp |
Introduces the early PW basis-size guard and threads dim/nband through the CG diagonalization call. |
source/source_cell/check_atomic_stru.cpp |
Adjusts formatting of a user-facing “Notice” message (leading space). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const int dim = psi.get_current_ngk(); | ||
| const int nband = psi.get_nbands(); | ||
|
|
||
| // Guard against under-complete PW basis at current k-point. | ||
| // This case is common in highly compressed cells with low ecutwfc, | ||
| // and can otherwise fail later with obscure solver-specific messages. | ||
| if (dim < nband) | ||
| { |
There was a problem hiding this comment.
The guard compares dim = psi.get_current_ngk() (which appears to be the local number of plane waves on the current rank after PW distribution) against nband. In MPI runs it’s common for a rank’s local npw to be < nbands even when the global PW dimension (sum over POOL_WORLD) is sufficient, so this can abort valid parallel calculations. Consider reducing dim over POOL_WORLD (sum) to a global npw_k for the current k-point and compare that against nband (and optionally print both local and global dims).
| std::cout << " solver = " << this->method << std::endl; | ||
| std::cout << " ik (1-based) = " << nk_nums + 1 << std::endl; | ||
| std::cout << " npw(dim) = " << dim << std::endl; |
There was a problem hiding this comment.
ik (1-based) = nk_nums + 1 is misleading: nk_nums is passed as this->wfc_basis->nks (total k-points in the pool) at the call sites, not the current k-point index. Prefer using psi.get_current_k() (after psi.fix_k(ik)) or pass the actual ik into hamiltSolvePsiK, otherwise the reported k-point will be wrong.
| std::cout << "\n ERROR in HSolverPW::hamiltSolvePsiK" << std::endl; | ||
| std::cout << " solver = " << this->method << std::endl; | ||
| std::cout << " ik (1-based) = " << nk_nums + 1 << std::endl; | ||
| std::cout << " npw(dim) = " << dim << std::endl; | ||
| std::cout << " nbands = " << nband << std::endl; | ||
| std::cout << " Suggestion : increase ecutwfc, reduce nbands, or adjust k-mesh." << std::endl; | ||
| ModuleBase::WARNING_QUIT("HSolverPW::hamiltSolvePsiK", "insufficient plane-wave basis dimension for requested nbands"); |
There was a problem hiding this comment.
The detailed diagnostics are printed via multiple std::cout lines, but WARNING_QUIT only records a short message in warning.log (rank 0) and will also print its own standardized NOTICE block. To keep the actionable details in logs and avoid duplicated multi-rank stdout spam, consider composing a single descriptive message (e.g., with std::stringstream) and passing it to WARNING_QUIT, and/or gate extra stdout logging to GlobalV::MY_RANK==0.
| { | ||
| std::stringstream mess; | ||
| mess << "Notice: symbol '" << symbol1 << "' is not an element symbol!!!! "; | ||
| mess << " Notice: symbol '" << symbol1 << "' is not an element symbol!!!! "; |
There was a problem hiding this comment.
This whitespace-only change to the emitted warning text (adding a leading space before "Notice") is unrelated to the PR’s stated purpose (HSolverPW early basis-size guard). If it’s intentional, it should be called out in the PR description; otherwise consider reverting it to keep the change set focused.
| // Guard against under-complete PW basis at current k-point. | ||
| // This case is common in highly compressed cells with low ecutwfc, | ||
| // and can otherwise fail later with obscure solver-specific messages. | ||
| if (dim < nband) |
There was a problem hiding this comment.
The new under-complete-basis guard introduces an important new failure mode/message, but there doesn’t appear to be a unit test exercising HSolverPW::hamiltSolvePsiK for npw_k < nbands. If feasible, add a small gtest that constructs a Psi with ngk[k]=dim<nbands and asserts the code aborts with the expected message (or throws in UT builds) to prevent regressions.
Linked Issue
Fix #7201
Description
HSolverPWbefore iterative diagonalization.psi_norm <= 0.0in under-complete basis cases.