[petsc-users] norm of KSPBuildResidual does not match norm computed from KSPBuildSolution

Barry Smith bsmith at petsc.dev
Tue Nov 4 20:58:40 CST 2025


https://urldefense.us/v3/__https://gitlab.com/petsc/petsc/-/merge_requests/8826__;!!G_uCfscf7eWS!esBVCjPHQrWOYQ6R1FZoyTB6d0lnQTWmypXz8_Fm14V7nZmgyIP_3WFXO9tJU3-lEhzeqt_xIZOD2yALOJf1d5c$ 
Fix terminology for Pmat in KSPView output. (!8826) · Merge requests · PETSc / petsc · GitLab
gitlab.com


> On Nov 4, 2025, at 11:14 AM, Moral Sanchez, Elena <Elena.Moral.Sanchez at ipp.mpg.de> wrote:
> 
> Dear Barry,
> Thank you for the clear answer. Indeed, it would be useful to know that they are both stored in PC, that PCSetOperators may overwrite KSPSetOperators and that the order (1 for A, 2 for PC) is the order that appears in KSPView.
> 
> In any case, it is clear to me now. Thanks for the help!
> Cheers,
> Elena
> From: Barry Smith <bsmith at petsc.dev <mailto:bsmith at petsc.dev>>
> Sent: 04 November 2025 16:08:21
> To: Moral Sanchez, Elena
> Cc: PETSc
> Subject: Re: [petsc-users] norm of KSPBuildResidual does not match norm computed from KSPBuildSolution
>  
>   The preconditioner is always built from the second of the two matrices passed in KSPSetOperators() or PCSetOperators(). In the first case below both matrices are the same (the nest matrix) and so diagonal is extracted from the nest matrix (which is the only matrix). In the second case below the first matrix is custom and the second is the next matrix, again the preconditioner is constructed from the second one. 
> 
>       linear system matrix = precond matrix:
>       Mat Object: 1 MPI process
>         type: nest
>         rows=524, cols=524
>           Matrix object:
>         type=nest, rows=3, cols=3
>         MatNest structure:
>         (0,0) : type=mpiaij, rows=176, cols=176
>         (0,1) : NULL
>         (0,2) : NULL
>         (1,0) : NULL
>         (1,1) : type=mpiaij, rows=172, cols=172
>         (1,2) : NULL
>         (2,0) : NULL
>         (2,1) : NULL
>         (2,2) : type=mpiaij, rows=176, cols=176
>         
> Mat Object: 1 MPI process
>       type: python
>         Python: __main__.LHSOperator
>     Mat Object: 1 MPI process
>       type: nest
>       Matrix object:
>         type=nest, rows=3, cols=3
>         MatNest structure:
>         (0,0) : type=mpiaij, rows=176, cols=176
>         (0,1) : NULL
>         (0,2) : NULL
>         (1,0) : NULL
>         (1,1) : type=mpiaij, rows=172, cols=172
>         (1,2) : NULL
>         (2,0) : NULL
>         (2,1) : NULL
>         (2,2) : type=mpiaij, rows=176, cols=176
>         
> 
> The arguments to KSPSetOperators() and PCSetOperators() are stored in the same place (inside the PC) 
> 
> In fact,
> 
> PetscErrorCode KSPSetOperators(KSP ksp, Mat Amat, Mat Pmat)
> {
>  ....
>   PetscCall(PCSetOperators(ksp->pc, Amat, Pmat));
> 
> 
> 
> so when you call
> 
>    precond.setOperators(A=nest_mass_matrix, P=None)
>    ksp.setPC(precond)
> 
> you are overwriting the A = lhs that you passed into  ksp.setOperators(ksp, lhs, None).
> 
> Given the names  ksp.setOperators() and precond.setOperators() I can see how this can be confusing. It is reasonable to conclude that ksp.setOperators is providing the linear system and that pc.setOperators() is providing the matrix with which to build the preconditioner, but that is not the case. 
> 
> But the code has been this way for 31 years. I am not sure what we can change with the documentation. Perhaps in KSPSetOperators it can say that it sets them into the PC.
> 
> Barry
> 
> 
> 
> 
>> On Nov 4, 2025, at 4:06 AM, Moral Sanchez, Elena <Elena.Moral.Sanchez at ipp.mpg.de <mailto:Elena.Moral.Sanchez at ipp.mpg.de>> wrote:
>> 
>> Dear Barry,
>> Thanks for the fast answer. Unfortunately in my case the discrepancy is huge. With the flags
>>  -ksp_monitor_true_residual -ksp_norm_type unpreconditioned
>> this is the output:
>>   0 KSP unpreconditioned resid norm 5.568889644229e-01 true resid norm 5.568889644229e-01 ||r(i)||/||b|| 1.000000000000e+00
>>   1 KSP unpreconditioned resid norm 2.831772665189e-01 true resid norm 2.831772665189e-01 ||r(i)||/||b|| 5.084986139245e-01
>>   2 KSP unpreconditioned resid norm 1.875950094147e-01 true resid norm 1.875950094147e-01 ||r(i)||/||b|| 3.368625011435e-01
>> and this is the output of my own monitor function:
>> Iter 0/10 | res = 5.57e-01/1.00e-08 | 0.0 s
>> difference KSPBuildSolution and u: 0.0
>> UNPRECONDITIONED norm:  0.5568889644229376
>> PRECONDITIONED norm:  2.049041078011257
>> KSPBuildResidual 2-norm: 0.5568889644229299
>> difference KSPBuildResidual and b-A(KSPBuildSolution): 6.573603152700697e-13
>> 
>> Iter 1/10 | res = 2.83e-01/1.00e-08 | 0.0 s
>> difference KSPBuildSolution and u: 0.0
>> UNPRECONDITIONED norm:  0.7661983589104541
>> PRECONDITIONED norm:  2.7387602134717137
>> KSPBuildResidual 2-norm: 0.2831772665189212
>> difference KSPBuildResidual and b-A(KSPBuildSolution): 0.1700718741085172
>> 
>> Iter 2/10 | res = 1.88e-01/1.00e-08 | 0.0 s
>> difference KSPBuildSolution and u: 0.0
>> UNPRECONDITIONED norm:  0.7050518160900253
>> PRECONDITIONED norm:  2.421773833445645
>> KSPBuildResidual 2-norm: 0.18759500941469456
>> difference KSPBuildResidual and b-A(KSPBuildSolution): 0.19327058976599623
>> Here u is the vector in the KSPSolve. 
>> After the first iteration, the residual computed from KSPBuildSolution and the residual from KSPBuildResidual diverge. They are the same when I run the same code without preconditioner.
>> Another observation is that after convergence (wrt. unpreconditioned norm == 2-norm of KSPBuildResidual) the solution with and without preconditioner looks quite different. How is this possible if my preconditioner is SPD?
>> 
>> By the way, where can I find your implementation of "My monitor" in src/snes/tutorials/ex5.c? I tried to look at the Gitlab repository but could not find it.
>> Thanks for the help.
>> Cheers,
>> Elena
>> 
>> 
>> 
>> 
>> 
>> On 11/4/25 03:01, Barry Smith wrote:
>>>     0 KSP unpreconditioned resid norm 1.265943996096e+00 true resid norm 1.265943996096e+00 ||r(i)||/||b|| 1.000000000000e+00
>>> My monitor 0 1.265943996096e+00

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20251104/4dc20439/attachment-0003.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PETSc_RBG-logo.png
Type: image/png
Size: 7210 bytes
Desc: not available
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20251104/4dc20439/attachment-0003.png>


More information about the petsc-users mailing list