[petsc-users] Context behind SNESComputeFunction call

Smith, Barry F. bsmith at mcs.anl.gov
Fri Jan 26 16:50:06 CST 2018



  So you are doing something non-standard? Are you not just using -snes_mf or -snes_mf_operator? Can you send me a sample code that has the extra function evaluations? Because if you run through regular usage with the debugger you will see there is no extra evaluation.

   Barry


> On Jan 26, 2018, at 4:32 PM, Kong, Fande <fande.kong at inl.gov> wrote:
> 
> 
> 
> 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
> >
> >



More information about the petsc-users mailing list