<html aria-label="message body"><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div><div> then the output becomes</div><div><br></div><div><div>   32 KSP unpreconditioned resid norm 5.638897702486e-04 true resid norm 5.638897702486e-04 ||r(i)||/||b|| 4.454302654678e-04</div><div>My monitor 32 5.638897702486e-04</div><div>   33 KSP unpreconditioned resid norm 2.557920120698e-04 true resid norm 2.557920120698e-04 ||r(i)||/||b|| 2.020563412431e-04</div><div>My monitor 33 2.557920120698e-04</div><div>   34 KSP unpreconditioned resid norm 1.249567288163e-04 true resid norm 1.249567288163e-04 ||r(i)||/||b|| 9.870636394784e-05</div><div>My monitor 34 1.249567288163e-04</div><div>   35 KSP unpreconditioned resid norm 6.554146400720e-05 true resid norm 6.554146400720e-05 ||r(i)||/||b|| 5.177279896212e-05</div><div>My monitor 35 6.554146400720e-05</div><div>   36 KSP unpreconditioned resid norm 3.360138566157e-05 true resid norm 3.360138566157e-05 ||r(i)||/||b|| 2.654255303962e-05</div><div>My monitor 36 3.360138566157e-05</div><div>   37 KSP unpreconditioned resid norm 1.963635751099e-05 true resid norm 1.963635751099e-05 ||r(i)||/||b|| 1.551123712545e-05</div><div>My monitor 37 1.963635751099e-05</div><div>   38 KSP unpreconditioned resid norm 1.111922577015e-05 true resid norm 1.111922577015e-05 ||r(i)||/||b|| 8.783347292168e-06</div></div><div>My monitor 38 1.111922577015e-05</div><div><br></div><div>Now the residual norm printed by -ksp_monitor and MyMonitor are the same to all digits for all iterations.</div><div><br></div><div>KSPSolve_CG() uses R = R - a W = R - a (A * P) instead of R = B - A*X because it saves a matrix-vector multiply per iteration (generally, for CG the matrix-vector multiply dominates the solution time).</div><div><br></div><div>One final note. How come "<span style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">The convergence test is consistent with the 2-norm of KSPBuildResidual" but not computed explicitly from KSPBuildSolution()? That is because the </span><span style="font-family: Calibri, Helvetica, sans-serif; font-size: 16px;">KSPBuildResidual() routine cheats</span></div><div><span style="font-family: Calibri, Helvetica, sans-serif; font-size: 16px;"><br></span></div><div><div>PETSC_INTERN PetscErrorCode KSPBuildResidual_CG(KSP ksp, Vec t, Vec v, Vec *V)</div><div>{</div><div>  PetscFunctionBegin;</div><div>  PetscCall(VecCopy(ksp->work[0], v));</div><div>  *V = v;</div></div><div><br></div><div>It knows from the KSPSolve_CG() code where the computed residual is stored and gives you that (slightly incorrect :-) one. Now some Krylov methods do not explicitly store (or even compute) the residual vector so they explicitly compute it with</div><div><br></div><div><div>PetscErrorCode KSPBuildResidualDefault(KSP ksp, Vec t, Vec v, Vec *V)</div><div>{</div><div>  Mat Amat, Pmat;</div><div><br></div><div>  PetscFunctionBegin;</div><div>  if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));</div><div>  PetscCall(PCGetOperators(ksp->pc, &Amat, &Pmat));</div><div>  PetscCall(KSPBuildSolution(ksp, t, NULL));</div><div>  PetscCall(KSP_MatMult(ksp, Amat, t, v));</div><div>  PetscCall(VecAYPX(v, -1.0, ksp->vec_rhs));</div><div>  *V = v;</div><div>  PetscFunctionReturn(PETSC_SUCCESS);</div><div>}</div></div><div><br></div><div><br></div><div>Barry</div><div><br></div><div>This is an interesting phenomenon that often is not discussed in elementary introductions to Krylov methods (or even in advanced discussions), so I think I will write an FAQ that explains it for <a href="https://urldefense.us/v3/__http://petsc.org__;!!G_uCfscf7eWS!bQiljmFzCDPj21dA6X6eDr47PLi0lUIaziJfBnNVcO5E7N-sNhdUyjXxrGx4bcYiZj1xbKIYBUWdvDHFMm6j54o$">petsc.org</a></div><div><br></div><div><br></div><div><br></div><div><br><blockquote type="cite"><div>On Nov 3, 2025, at 12:39 PM, Moral Sanchez, Elena <Elena.Moral.Sanchez@ipp.mpg.de> wrote:</div><br class="Apple-interchange-newline"><div><meta charset="UTF-8"><div id="divtagdefaultwrapper" dir="ltr" style="font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-size: 12pt; font-family: Calibri, Helvetica, sans-serif;"><p style="margin-top: 0px; margin-bottom: 0px;"></p><div>Hi,<br>I am running CG with a Jacobi preconditioner. I have a monitor function that prints the residual and saves the solution at every iteration. To get the solution at every iteration, I am using the function KSPBuildSolution. I am setting the KSP norm as UNPRECONDITIONED.<br><br>The convergence test is consistent with the 2-norm of KSPBuildResidual. However this norm does not match the 2-norm of the residual computed explicitly from the solution (obtained with KSPBuildSolution). It also does not match the preconditioned norm. What norm is it computing?<br><br>When the CG is not preconditioned, the norm of KSPBuildResidual and the norm of the residual computed from the solution match, as I expected.<br><br>This is KSPView():<br><br>    KSP Object: 1 MPI process<br>      type: cg<br>        variant HERMITIAN<br>      maximum iterations=100, nonzero initial guess<br>      tolerances: relative=1e-08, absolute=1e-08, divergence=10000.<br>      left preconditioning<br>      using UNPRECONDITIONED norm type for convergence test<br>    PC Object: 1 MPI process<br>      type: jacobi<br>        type DIAGONAL<br>      linear system matrix = precond matrix:<br>      Mat Object: 1 MPI process<br>        type: nest<br>        rows=524, cols=524<br>          Matrix object:<br>        type=nest, rows=3, cols=3<br>        MatNest structure:<br>        (0,0) : type=mpiaij, rows=176, cols=176<br>        (0,1) : NULL<br>        (0,2) : NULL<br>        (1,0) : NULL<br>        (1,1) : type=mpiaij, rows=172, cols=172<br>        (1,2) : NULL<br>        (2,0) : NULL<br>        (2,1) : NULL<br>        (2,2) : type=mpiaij, rows=176, cols=176<br>        <br>Cheers,<br>Elena Moral Sánchez</div></div></div></blockquote></div><br></div></body></html>