<div dir="ltr">Thanks Barry, good to know that MatMult() is necessary to get a fresh residual estimation.<div><br></div><div>The only thing I don't want to "see" all of the equations is the residual computation. Replacing VecNorm() with a custom version seems to be fine everywhere else, but the UpdateHessenberg() call is problematic. I will have a think about Matt's idea of customising the convergence test.</div><div><br></div><div>Thanks again, Dave.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jul 5, 2019 at 3:24 PM Smith, Barry F. <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
> On Jul 4, 2019, at 11:22 PM, Dave Lee <<a href="mailto:davelee2804@gmail.com" target="_blank">davelee2804@gmail.com</a>> wrote:<br>
> <br>
> Hi Matt and Barry,<br>
> <br>
> thanks for the good ideas.<br>
> <br>
> I wasn't aware of the function KSPSetConvergenceTest(), thanks for alerting me to this Matt. Unfortunately I really do need to exclude a couple of specific degrees of freedom from the norm, and as such I want to make sure I can replicate the norm as computed within UpdateHessenberg() before I replace this.<br>
> <br>
> Apologies Barry, there was a stupid bug in that code, it should have read:<br>
>     KSPFGMRESUpdateHessenberg(ksp,loc_it,hapend,&res_norm);<br>
>     KSPFGMRESBuildSoln(fgmres->nrs,ksp->vec_sol,tmp_sol,ksp,loc_it+1);<br>
>     VecAXPY(tmp_sol,-1.0,ksp->vec_rhs);<br>
>     VecNorm(tmp_sol,NORM_2,&res_tmp);<br>
<br>
  This won't work. <br>
> <br>
> Which does not give the same result as the norm for UpdateHessenberg(). Unfortunately I want to avoid using<br>
> KSPBuildResidual(ksp,NULL,NULL,&resid);<br>
> as this calls KSP_MatMult(), which will in turn call my snes residual assembly routine. This routine in turn calls a Navier Stokes solver to run for a fixed (long) time period, and so is expensive.<br>
<br>
   If you want a "freshly" computed residual you have no choice but to call MatMult()<br>
> <br>
> Replacing VecNorm() with my own version is indeed what I'm doing elsewhere, I'm just not sure of how to replace the UpdateHessenberg() norm right now.<br>
<br>
   It sounds like you don't want FGMRES to "see" some of your equations at all? You could do this by taking the result of your true matrix-vector product and zeroing the values for the equation you don't want FGMRES to "see". This will introduce a null space for your linear operator but that may not matter. Of course since FGMRES doesn't "see" these components it will make no effort to make them small so the residual for those equations will be whatever which means that the solution to your linear system is not the solution to the original system.<br>
<br>
  Barry<br>
<br>
<br>
> <br>
> Cheers, Dave.<br>
> <br>
> On Fri, Jul 5, 2019 at 12:59 PM Smith, Barry F. <<a href="mailto:bsmith@mcs.anl.gov" target="_blank">bsmith@mcs.anl.gov</a>> wrote:<br>
> <br>
> <br>
> > On Jul 4, 2019, at 7:29 PM, Dave Lee via petsc-users <<a href="mailto:petsc-users@mcs.anl.gov" target="_blank">petsc-users@mcs.anl.gov</a>> wrote:<br>
> > <br>
> > Hi PETSc,<br>
> > <br>
> > I have a problem for which I need to exclude certain degrees of freedom from the evaluation of the norm as used to monitor the residual in FGMRES (don't ask!). Therefore I would like to replace the existing norm evaluation with my own version.<br>
> > <br>
> > Currently this is done within:<br>
> > KSPFGMRESUpdateHessenberg(ksp,loc_it,hapend,&res_norm)<br>
> > as:<br>
> > *res = PetscAbsScalar(*RS(it+1));<br>
> > <br>
> > Firstly, I would like to make sure I can replicate the existing residual norm. I tried to do this as:<br>
> > KSPFGMRESUpdateHessenberg(ksp,loc_it,hapend,&res_norm);<br>
> > KSPFGMRESBuildSoln(fgmres->nrs,ksp >vec_sol,tmp_sol,ksp,loc_it);<br>
> <br>
>    I don't understand the lines of code below. I don't see how they could compute the norm of the residual. <br>
> <br>
> From KSPMonitorTrueResidualNorm() you can compute the unpreconditioned residual with <br>
> <br>
>   ierr = KSPBuildResidual(ksp,NULL,NULL,&resid);CHKERRQ(ierr);<br>
>   ierr = VecNorm(resid,NORM_2,&truenorm);CHKERRQ(ierr);<br>
>   ierr = VecDestroy(&resid);CHKERRQ(ierr);<br>
> <br>
> since FGMRES always uses right preconditioning (and hence the unpreconditioned residual) this should match the value computed internally by FGMRES (subject to roundoff differences)<br>
> <br>
> To exclude certain values in the residual from the norm calculation you could write a custom "VecNorm" norm that skipped those entries.<br>
> <br>
>   Barry<br>
> <br>
> <br>
> <br>
> <br>
> <br>
> > VecNorm(tmp_sol,NORM_2,&res_tmp);<br>
> > VecNorm(ksp->vec_rhs,NORM_2,&res_rhs);<br>
> > res_norm = fabs(res_tmp-res_rhs);<br>
> > <br>
> > But this doesn't match the norm that comes out of UpdateHessenberg.<br>
> > <br>
> > Any ideas on how I can re-create the norm derived from UpdateHessenberg as an expansion over the Kyrlov vectors in FGMRES?<br>
> > <br>
> > Cheers, Dave.<br>
> <br>
<br>
</blockquote></div>