[petsc-users] SNESSetFunctionDomainError

Dmitry Karpeyev karpeev at mcs.anl.gov
Sun Aug 24 22:49:38 CDT 2014


On Aug 24, 2014 10:45 PM, "Barry Smith" <bsmith at mcs.anl.gov> wrote:
>
>
> On Aug 24, 2014, at 10:37 PM, Dmitry Karpeyev <karpeev at mcs.anl.gov> wrote:
>
> >
> > On Aug 24, 2014 9:40 PM, "Barry Smith" <bsmith at mcs.anl.gov> wrote:
> > >
> > >
> > > On Aug 24, 2014, at 9:06 PM, Derek Gaston <friedmud at gmail.com> wrote:
> > >
> > > > There must be something I'm missing about
SNESSetFunctionDomainError().
> > > >
> > > > 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.
> > > >
> > > > 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.
> > >
> > >    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
> > >
> > >  } else {
> > >     if (!snes->vec_func_init_set) {
> > >       ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
> > >       ierr = SNESGetFunctionDomainError(snes,
&domainerror);CHKERRQ(ierr);
> > >       if (domainerror) {
> > >         snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
> > >         PetscFunctionReturn(0);
> > >
> > > Now the reason it is not erroring out for you is because
> > >
> > > 1) our MatMult_MFFD() totally ignores the SNES domain error business
because it doesn’t even know about SNES
> >
> > 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.
>
>    I tried once to convert PETSc errors to be more “exception like” and
let them be caught and handled. It worked but was kind of clunky so I gave
up on it and decided that anything we wanted to be “handled” instead of
just passed up as an error would be code instead of errors. This may even
be when the SNESFunctionDomainError was introduced. The simplest fix is for
MatMult_MFFD() to generate a regular error when it sees a domain error

Since, as you point out, MatMFFD doesn't know anything about SNES, it has
nowhere to check for the domain error. Unless it becomes a regular PETSc
error, in which case MatMFFD will abort automatically as part of the
default error handling procedure.

which will stop the code; in the longer run we may want to propagate it up
without generating a full error.
>
>    Derek,
>
>      What are your current needs? Do you want the program to just end in
this case or do you want some kind of recovery when the matrix-free
multiply causes a domain error?
>
>   Barry
>
> >
> > >
> > > 2) inside the various nonlinear solvers and many complicated line
search codes we may not always be checking the domainerror flag.
> > >
> > >   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.
> > >
> > >   Barry
> > >
> > >
> > > >
> > > > Here's my stupid debugging code that's at the top of my residual
callback method:
> > > >
> > > >     static int count = 0;
> > > >     count++;
> > > >
> > > >     if (count == 5)
> > > >     {
> > > >       std::cout<<"stopping solve!"<<std::endl;
> > > >       SNESSetFunctionDomainError(snes);
> > > >     }
> > > >
> > > >
> > > > 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...
> > > >
> > > > Is there something more I need to do here?
> > > >
> > > > Thanks!
> > > >
> > > > Derek
> > >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20140824/3e6be47f/attachment.html>


More information about the petsc-users mailing list