Skip to content

Commit eaeab2a

Browse files
committed
Detect linear-solver non-convergence in KSPSolver::solve
KSPSolver::solve always returned true, even if the KSP diverged (max iterations, breakdown, or a failed/singular preconditioner factorization). That silently fed a bad linear step to the hand-written Newton-Raphson solver. Now query KSPGetConvergedReason after the solve: on a negative reason, warn and return false. Converged solves are unchanged (no warning, returns true), so existing results are bit-identical; the SNES path is unaffected (SNES already reports SNES_DIVERGED_LINEAR_SOLVE itself).
1 parent edd515c commit eaeab2a

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

src/LinearSolver/KSPSolver.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ bool KSPSolver::solve(SparseMatrix &A,Vector &b,Vector &x) {
151151
KSPSetOperators(m_KSP,A.getReference(),A.getReference());
152152
KSPSolve(m_KSP,b.getVectorRef(),x.getVectorRef());
153153
KSPGetIterationNumber(m_KSP,&m_Iterations);
154+
// check that the linear solve actually converged; a negative reason means it
155+
// diverged (max-iters/breakdown/singular PC), which would silently feed a bad
156+
// step to the nonlinear solver. Warn and report failure instead of returning ok.
157+
KSPConvergedReason reason;
158+
KSPGetConvergedReason(m_KSP,&reason);
159+
if(reason<0){
160+
MessagePrinter::printWarningTxt("linear solver did not converge (KSPConvergedReason="
161+
+to_string(static_cast<int>(reason))+", iters="
162+
+to_string(m_Iterations)+"); the nonlinear step may be inaccurate");
163+
return false;
164+
}
154165
return true;
155166
}
156167
void KSPSolver::printKSPSolverInfo()const {

0 commit comments

Comments
 (0)