<p dir="ltr"><br>
On Aug 24, 2014 9:40 PM, "Barry Smith" <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>> wrote:<br>
><br>
><br>
> On Aug 24, 2014, at 9:06 PM, Derek Gaston <<a href="mailto:friedmud@gmail.com">friedmud@gmail.com</a>> wrote:<br>
><br>
> > There must be something I'm missing about SNESSetFunctionDomainError().<br>
> ><br>
> > I'm using a matrix free newton solve and I was hoping that calling SNESSetFunctionDomainError() would completely stop the nonlinear solver... but that doesn't appear to be the case.<br>
> ><br>
> > Now - if I call that function during the initial residual computation it appears to work (the solve never starts).  However, if I call it during the _middle_ of a matrix free nonlinear solve during a residual calculation - it appears to do absolutely nothing.<br>

><br>
>    You are not missing anything. The way SNESSetFunctionDomainError() works is it merely sets a flag in the SNES object. The solver code then can check that flag after a function evaluation and generate an if that flag is set (or perhaps do some kind of recovery). So, for example, at the beginning of SNESSolve_NewtonLS() we have<br>

><br>
>  } else {<br>
>     if (!snes->vec_func_init_set) {<br>
>       ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);<br>
>       ierr = SNESGetFunctionDomainError(snes, &domainerror);CHKERRQ(ierr);<br>
>       if (domainerror) {<br>
>         snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;<br>
>         PetscFunctionReturn(0);<br>
><br>
> Now the reason it is not erroring out for you is because<br>
><br>
> 1) our MatMult_MFFD() totally ignores the SNES domain error business because it doesn’t even know about SNES</p>
<p dir="ltr">This could potentially be fixed by letting domain errors be treated as regular PETSc errors. In particular, solvers could push and pop (e.g., before the linear solve) custom error handlers that would set an appropriate converged reason. I think there would be no noticeable performance penalty, since the error handler would only fire when there is an actual domain error, and then the expectation of high performance is out.</p>

<p dir="ltr">><br>
> 2) inside the various nonlinear solvers and many complicated line search codes we may not always be checking the domainerror flag.<br>
><br>
>   Both of these things, of course, should be fixed. We need to add support to the MatMult_MFFD() to indicate domain errors and we need to check all the code to make sure we always handle the domain error flag.<br>
><br>
>   Barry<br>
><br>
><br>
> ><br>
> > Here's my stupid debugging code that's at the top of my residual callback method:<br>
> ><br>
> >     static int count = 0;<br>
> >     count++;<br>
> ><br>
> >     if (count == 5)<br>
> >     {<br>
> >       std::cout<<"stopping solve!"<<std::endl;<br>
> >       SNESSetFunctionDomainError(snes);<br>
> >     }<br>
> ><br>
> ><br>
> > During the solve "stopping solve!" gets printed out after computing the 3rd linear iteration of the first newton step... but the solve just continues without stopping...<br>
> ><br>
> > Is there something more I need to do here?<br>
> ><br>
> > Thanks!<br>
> ><br>
> > Derek<br>
><br>
</p>