<div dir="ltr">Thanks for the tip Jed,<div><br></div><div>I will look into this. I'm currently trying to figure out if there's any way I can get away with using the existing L2 norm, and if not GCR sounds like a good alternative to pursue.</div><div><br></div><div>Cheers, Dave.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jul 5, 2019 at 11:02 PM Jed Brown <<a href="mailto:jed@jedbrown.org">jed@jedbrown.org</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">Dave, have you considered using GCR instead of FGMRES? It's a flexible<br>
method that is equivalent in many circumstances, but provides the<br>
residual and solution at each iteration without needing to "build" it.<br>
<br>
Dave Lee via petsc-users <<a href="mailto:petsc-users@mcs.anl.gov" target="_blank">petsc-users@mcs.anl.gov</a>> writes:<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<br>
> me to this Matt. Unfortunately I really do need to exclude a couple of<br>
> specific degrees of freedom from the norm, and as such I want to make sure<br>
> I can replicate the norm as computed within UpdateHessenberg() before I<br>
> 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>
> Which does not give the same result as the norm for UpdateHessenberg().<br>
> 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<br>
> assembly routine. This routine in turn calls a Navier Stokes solver to run<br>
> for a fixed (long) time period, and so is expensive.<br>
><br>
> Replacing VecNorm() with my own version is indeed what I'm doing elsewhere,<br>
> I'm just not sure of how to replace the UpdateHessenberg() norm right now.<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>
>><br>
>> > On Jul 4, 2019, at 7:29 PM, Dave Lee via petsc-users <<br>
>> <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<br>
>> from the evaluation of the norm as used to monitor the residual in FGMRES<br>
>> (don't ask!). Therefore I would like to replace the existing norm<br>
>> 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<br>
>> 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<br>
>> compute the norm of the residual.<br>
>><br>
>> From KSPMonitorTrueResidualNorm() you can compute the unpreconditioned<br>
>> 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<br>
>> unpreconditioned residual) this should match the value computed internally<br>
>> by FGMRES (subject to roundoff differences)<br>
>><br>
>> To exclude certain values in the residual from the norm calculation you<br>
>> 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<br>
>> as an expansion over the Kyrlov vectors in FGMRES?<br>
>> ><br>
>> > Cheers, Dave.<br>
>><br>
>><br>
</blockquote></div>