[petsc-users] Context behind SNESComputeFunction call

Kong, Fande fande.kong at inl.gov
Fri Jan 26 16:32:18 CST 2018


On Fri, Jan 26, 2018 at 3:10 PM, Smith, Barry F. <bsmith at mcs.anl.gov> wrote:

>
>
> > On Jan 26, 2018, at 2:15 PM, Kong, Fande <fande.kong at inl.gov> wrote:
> >
> >
> >
> > On Mon, Jan 8, 2018 at 2:15 PM, Smith, Barry F. <bsmith at mcs.anl.gov>
> wrote:
> >
> >
> > > On Jan 8, 2018, at 2:59 PM, Alexander Lindsay <
> alexlindsay239 at gmail.com> wrote:
> > >
> > > Is there any elegant way to tell whether SNESComputeFunction is being
> called under different conceptual contexts?
> > >
> > > E.g. non-linear residual evaluation vs. Jacobian formation from finite
> differencing vs. Jacobian-vector products from finite differencing?
> >
> >   Under normal usage with the options database no.
> >
> > Hi Barry,
> >
> > How difficult to provide an API? Is it possible?
> >
> >
> >
> >   If you have some reason to know you could write three functions and
> provide them to SNESSetFunction(), MatMFFDSetFunction(), and
> MatFDColoringSetFunction(). Note that these functions have slightly
> different calling sequences but you can have all of them call the same
> underlying common function if you are only interested in, for example, how
> many times the function is used for each purpose.
> >
> > If we use this way for the Jacobian-free Newton, the function evaluation
> will be called twice at the first linear iteration because the computed
> residual vector at the nonlinear step  is not reused. Any way to reuse the
> function residual of the Newton step instead of recomputing a new residual
> at the first linear iteration?
>
>    It does reuse the function evaluation. Why do you think it does not? If
> you look at MatMult_MFFD() you will see the lines of code
>
>   /* compute func(U) as base for differencing; only needed first time in
> and not when provided by user */
>   if (ctx->ncurrenth == 1 && ctx->current_f_allocated) {
>     ierr = (*ctx->func)(ctx->funcctx,U,F);CHKERRQ(ierr);
>   }
>
> since the if is satisfied it does not compute the function at the base
> location.  To double check I ran src/snes/examples/tutorials/ex19 with
> -snes_mf in the debugger and verified that the "extra" function evaluations
> are not done.
>

In MatAssemblyEnd_SNESMF,

  if (j->func == (PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction) {
    ierr = SNESGetFunction(snes,&f,NULL,NULL);CHKERRQ(ierr);
    ierr = MatMFFDSetBase_MFFD(J,u,f);CHKERRQ(ierr);
  } else {
    /* f value known by SNES is not correct for other differencing function
*/
    ierr = MatMFFDSetBase_MFFD(J,u,NULL);CHKERRQ(ierr);
  }


Will hit ierr = MatMFFDSetBase_MFFD(J,u,NULL);CHKERRQ(ierr), because SNES
and MAT have different function pointers.

In MatMFFDSetBase_MFFD(Mat J,Vec U,Vec F),

  if (F) {
    if (ctx->current_f_allocated) {ierr =
VecDestroy(&ctx->current_f);CHKERRQ(ierr);}
    ctx->current_f           = F;
    ctx->current_f_allocated = PETSC_FALSE;
  } else if (!ctx->current_f_allocated) {
    ierr = MatCreateVecs(J,NULL,&ctx->current_f);CHKERRQ(ierr);

    ctx->current_f_allocated = PETSC_TRUE;
  }

Because F=NULL, we then have ctx->current_f_allocated = PETSC_TRUE.

Then, the following if statement is true:

  if (ctx->ncurrenth == 1 && ctx->current_f_allocated) {
    ierr = (*ctx->func)(ctx->funcctx,U,F);CHKERRQ(ierr);
  }


Fande,



>
>   Barry
>
>
> >
> > Fande,
> >
> >
> >
> >    Barry
> >
> >
> >
> > >
> > > Alex
> >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20180126/c6c138f1/attachment.html>


More information about the petsc-users mailing list