xref: /petsc/src/snes/mf/snesmfj.c (revision cf57b110e07bfa955d9485b52a653c33881751b6)
1*cf57b110SBarry Smith /*$Id: snesmfj.c,v 1.123 2001/06/21 21:18:42 bsmith Exp bsmith $*/
281e6777dSBarry Smith 
39a6cb015SBarry Smith #include "src/snes/snesimpl.h"
4e090d566SSatish Balay #include "src/snes/mf/snesmfj.h"   /*I  "petscsnes.h"   I*/
581e6777dSBarry Smith 
6b0a32e0cSBarry Smith PetscFList      MatSNESMPetscFList              = 0;
74c49b128SBarry Smith PetscTruth MatSNESMFRegisterAllCalled = PETSC_FALSE;
8a4d4d686SBarry Smith 
94a2ae208SSatish Balay #undef __FUNCT__
104a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetType"
11fd4bdd07SBarry Smith /*@C
1265f2ba5bSLois Curfman McInnes     MatSNESMFSetType - Sets the method that is used to compute the
13b0a32e0cSBarry Smith     differencing parameter for finite differene matrix-free formulations.
149a6cb015SBarry Smith 
159a6cb015SBarry Smith     Input Parameters:
16ef4ad1fdSLois Curfman McInnes +   mat - the "matrix-free" matrix created via MatCreateSNESMF()
179a6cb015SBarry Smith -   ftype - the type requested
189a6cb015SBarry Smith 
1915091d37SBarry Smith     Level: advanced
2015091d37SBarry Smith 
2165f2ba5bSLois Curfman McInnes     Notes:
2265f2ba5bSLois Curfman McInnes     For example, such routines can compute h for use in
2365f2ba5bSLois Curfman McInnes     Jacobian-vector products of the form
2465f2ba5bSLois Curfman McInnes 
2565f2ba5bSLois Curfman McInnes                         F(x+ha) - F(x)
26ef4ad1fdSLois Curfman McInnes           F'(u)a  ~=  ----------------
2765f2ba5bSLois Curfman McInnes                               h
2865f2ba5bSLois Curfman McInnes 
29f1af5d2fSBarry Smith .seealso: MatCreateSNESMF(), MatSNESMFRegisterDynamic)
309a6cb015SBarry Smith @*/
31f6a0df18SBarry Smith int MatSNESMFSetType(Mat mat,MatSNESMFType ftype)
32b9fa9cd0SBarry Smith {
335a655dc6SBarry Smith   int          ierr,(*r)(MatSNESMFCtx);
345a655dc6SBarry Smith   MatSNESMFCtx ctx;
356831982aSBarry Smith   PetscTruth   match;
36a4d4d686SBarry Smith 
37a4d4d686SBarry Smith   PetscFunctionBegin;
380f5bd95cSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
390f5bd95cSBarry Smith   PetscValidCharPointer(ftype);
400f5bd95cSBarry Smith 
41a4d4d686SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
42a4d4d686SBarry Smith 
439a6cb015SBarry Smith   /* already set, so just return */
446831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)ctx,ftype,&match);CHKERRQ(ierr);
450f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
46a4d4d686SBarry Smith 
479a6cb015SBarry Smith   /* destroy the old one if it exists */
489a6cb015SBarry Smith   if (ctx->ops->destroy) {
499a6cb015SBarry Smith     ierr = (*ctx->ops->destroy)(ctx);CHKERRQ(ierr);
509a6cb015SBarry Smith   }
519a6cb015SBarry Smith 
5265f2ba5bSLois Curfman McInnes   /* Get the function pointers for the requrested method */
535a655dc6SBarry Smith   if (!MatSNESMFRegisterAllCalled) {ierr = MatSNESMFRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
549a6cb015SBarry Smith 
55b9617806SBarry Smith   ierr =  PetscFListFind(ctx->comm,MatSNESMPetscFList,ftype,(void (**)(void)) &r);CHKERRQ(ierr);
569a6cb015SBarry Smith 
5729bbc08cSBarry Smith   if (!r) SETERRQ(1,"Unknown MatSNESMF type given");
589a6cb015SBarry Smith 
599a6cb015SBarry Smith   ierr = (*r)(ctx);CHKERRQ(ierr);
606831982aSBarry Smith 
616831982aSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)ctx,ftype);CHKERRQ(ierr);
629a6cb015SBarry Smith 
639a6cb015SBarry Smith   PetscFunctionReturn(0);
649a6cb015SBarry Smith }
659a6cb015SBarry Smith 
669a6cb015SBarry Smith /*MC
67f1af5d2fSBarry Smith    MatSNESMFRegisterDynamic - Adds a method to the MatSNESMF registry.
689a6cb015SBarry Smith 
699a6cb015SBarry Smith    Synopsis:
70fed8bd04SBarry Smith    int MatSNESMFRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(MatSNESMF))
719a6cb015SBarry Smith 
729a6cb015SBarry Smith    Not Collective
739a6cb015SBarry Smith 
749a6cb015SBarry Smith    Input Parameters:
759a6cb015SBarry Smith +  name_solver - name of a new user-defined compute-h module
769a6cb015SBarry Smith .  path - path (either absolute or relative) the library containing this solver
779a6cb015SBarry Smith .  name_create - name of routine to create method context
789a6cb015SBarry Smith -  routine_create - routine to create method context
799a6cb015SBarry Smith 
8015091d37SBarry Smith    Level: developer
8115091d37SBarry Smith 
829a6cb015SBarry Smith    Notes:
83f1af5d2fSBarry Smith    MatSNESMFRegisterDynamic) may be called multiple times to add several user-defined solvers.
849a6cb015SBarry Smith 
859a6cb015SBarry Smith    If dynamic libraries are used, then the fourth input argument (routine_create)
869a6cb015SBarry Smith    is ignored.
879a6cb015SBarry Smith 
889a6cb015SBarry Smith    Sample usage:
899a6cb015SBarry Smith .vb
90f1af5d2fSBarry Smith    MatSNESMFRegisterDynamic"my_h",/home/username/my_lib/lib/libO/solaris/mylib.a,
919a6cb015SBarry Smith                "MyHCreate",MyHCreate);
929a6cb015SBarry Smith .ve
939a6cb015SBarry Smith 
949a6cb015SBarry Smith    Then, your solver can be chosen with the procedural interface via
955a655dc6SBarry Smith $     MatSNESMFSetType(mfctx,"my_h")
969a6cb015SBarry Smith    or at runtime via the option
979a6cb015SBarry Smith $     -snes_mf_type my_h
989a6cb015SBarry Smith 
995a655dc6SBarry Smith .keywords: MatSNESMF, register
1009a6cb015SBarry Smith 
1015a655dc6SBarry Smith .seealso: MatSNESMFRegisterAll(), MatSNESMFRegisterDestroy()
1029a6cb015SBarry Smith M*/
1039a6cb015SBarry Smith 
1044a2ae208SSatish Balay #undef __FUNCT__
1054a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFRegister"
106f1af5d2fSBarry Smith int MatSNESMFRegister(char *sname,char *path,char *name,int (*function)(MatSNESMFCtx))
1079a6cb015SBarry Smith {
1089a6cb015SBarry Smith   int ierr;
1099a6cb015SBarry Smith   char fullname[256];
1109a6cb015SBarry Smith 
1119a6cb015SBarry Smith   PetscFunctionBegin;
112b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
113b9617806SBarry Smith   ierr = PetscFListAdd(&MatSNESMPetscFList,sname,fullname,(void (*)())function);CHKERRQ(ierr);
1149a6cb015SBarry Smith   PetscFunctionReturn(0);
1159a6cb015SBarry Smith }
1169a6cb015SBarry Smith 
1179a6cb015SBarry Smith 
1184a2ae208SSatish Balay #undef __FUNCT__
1194a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFRegisterDestroy"
1209a6cb015SBarry Smith /*@C
1215a655dc6SBarry Smith    MatSNESMFRegisterDestroy - Frees the list of MatSNESMF methods that were
122f1af5d2fSBarry Smith    registered by MatSNESMFRegisterDynamic).
1239a6cb015SBarry Smith 
1249a6cb015SBarry Smith    Not Collective
1259a6cb015SBarry Smith 
12615091d37SBarry Smith    Level: developer
12715091d37SBarry Smith 
1285a655dc6SBarry Smith .keywords: MatSNESMF, register, destroy
1299a6cb015SBarry Smith 
130f1af5d2fSBarry Smith .seealso: MatSNESMFRegisterDynamic), MatSNESMFRegisterAll()
1319a6cb015SBarry Smith @*/
1325a655dc6SBarry Smith int MatSNESMFRegisterDestroy(void)
1339a6cb015SBarry Smith {
1349a6cb015SBarry Smith   int ierr;
1359a6cb015SBarry Smith 
1369a6cb015SBarry Smith   PetscFunctionBegin;
137b0a32e0cSBarry Smith   if (MatSNESMPetscFList) {
138b0a32e0cSBarry Smith     ierr = PetscFListDestroy(&MatSNESMPetscFList);CHKERRQ(ierr);
139b0a32e0cSBarry Smith     MatSNESMPetscFList = 0;
1409a6cb015SBarry Smith   }
1414c49b128SBarry Smith   MatSNESMFRegisterAllCalled = PETSC_FALSE;
1429a6cb015SBarry Smith   PetscFunctionReturn(0);
1439a6cb015SBarry Smith }
1449a6cb015SBarry Smith 
1459a6cb015SBarry Smith /* ----------------------------------------------------------------------------------------*/
1464a2ae208SSatish Balay #undef __FUNCT__
1474a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFDestroy_Private"
1485a655dc6SBarry Smith int MatSNESMFDestroy_Private(Mat mat)
149a4d4d686SBarry Smith {
150a4d4d686SBarry Smith   int          ierr;
1515a655dc6SBarry Smith   MatSNESMFCtx ctx;
152fae171e0SBarry Smith 
1533a40ed3dSBarry Smith   PetscFunctionBegin;
1540a25c783SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
155b9fa9cd0SBarry Smith   ierr = VecDestroy(ctx->w);CHKERRQ(ierr);
1569a6cb015SBarry Smith   if (ctx->ops->destroy) {ierr = (*ctx->ops->destroy)(ctx);CHKERRQ(ierr);}
15774637425SBarry Smith   if (ctx->sp) {ierr = MatNullSpaceDestroy(ctx->sp);CHKERRQ(ierr);}
1586831982aSBarry Smith   PetscHeaderDestroy(ctx);
1593a40ed3dSBarry Smith   PetscFunctionReturn(0);
160b9fa9cd0SBarry Smith }
16150361f65SLois Curfman McInnes 
1624a2ae208SSatish Balay #undef __FUNCT__
1634a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFView_Private"
16439e2f89bSBarry Smith /*
1655a655dc6SBarry Smith    MatSNESMFView_Private - Views matrix-free parameters.
1668f6e3e37SBarry Smith 
16739e2f89bSBarry Smith */
168b0a32e0cSBarry Smith int MatSNESMFView_Private(Mat J,PetscViewer viewer)
169eb9086c3SLois Curfman McInnes {
170eb9086c3SLois Curfman McInnes   int          ierr;
1715a655dc6SBarry Smith   MatSNESMFCtx ctx;
1726831982aSBarry Smith   PetscTruth   isascii;
173eb9086c3SLois Curfman McInnes 
1743a40ed3dSBarry Smith   PetscFunctionBegin;
175eb9086c3SLois Curfman McInnes   ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr);
176b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
1770f5bd95cSBarry Smith   if (isascii) {
178b0a32e0cSBarry Smith      ierr = PetscViewerASCIIPrintf(viewer,"  SNES matrix-free approximation:\n");CHKERRQ(ierr);
179b0a32e0cSBarry Smith      ierr = PetscViewerASCIIPrintf(viewer,"    err=%g (relative error in function evaluation)\n",ctx->error_rel);CHKERRQ(ierr);
180473c83c3SBarry Smith      if (!ctx->type_name) {
181b0a32e0cSBarry Smith        ierr = PetscViewerASCIIPrintf(viewer,"    The compute h routine has not yet been set\n");CHKERRQ(ierr);
182473c83c3SBarry Smith      } else {
183b0a32e0cSBarry Smith        ierr = PetscViewerASCIIPrintf(viewer,"    Using %s compute h routine\n",ctx->type_name);CHKERRQ(ierr);
184473c83c3SBarry Smith      }
1859a6cb015SBarry Smith      if (ctx->ops->view) {
1869a6cb015SBarry Smith        ierr = (*ctx->ops->view)(ctx,viewer);CHKERRQ(ierr);
1879a6cb015SBarry Smith      }
1885cd90555SBarry Smith   } else {
18929bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported for SNES matrix free matrix",((PetscObject)viewer)->type_name);
190eb9086c3SLois Curfman McInnes   }
1913a40ed3dSBarry Smith   PetscFunctionReturn(0);
192eb9086c3SLois Curfman McInnes }
193eb9086c3SLois Curfman McInnes 
1944a2ae208SSatish Balay #undef __FUNCT__
1954a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFAssemblyEnd_Private"
196be726c96SBarry Smith /*
1975a655dc6SBarry Smith    MatSNESMFAssemblyEnd_Private - Resets the ctx->ncurrenth to zero. This
19865f2ba5bSLois Curfman McInnes    allows the user to indicate the beginning of a new linear solve by calling
199be726c96SBarry Smith    MatAssemblyXXX() on the matrix free matrix. This then allows the
20065f2ba5bSLois Curfman McInnes    MatSNESMFCreate_WP() to properly compute ||U|| only the first time
20165f2ba5bSLois Curfman McInnes    in the linear solver rather than every time.
202be726c96SBarry Smith */
2035a655dc6SBarry Smith int MatSNESMFAssemblyEnd_Private(Mat J)
204be726c96SBarry Smith {
205be726c96SBarry Smith   int          ierr;
2061d1367b7SBarry Smith   MatSNESMFCtx j;
207be726c96SBarry Smith 
208be726c96SBarry Smith   PetscFunctionBegin;
2095a655dc6SBarry Smith   ierr = MatSNESMFResetHHistory(J);CHKERRQ(ierr);
2101d1367b7SBarry Smith   ierr = MatShellGetContext(J,(void **)&j);CHKERRQ(ierr);
211b0a32e0cSBarry Smith   if (j->usesnes) {
2121d1367b7SBarry Smith     ierr = SNESGetSolution(j->snes,&j->current_u);CHKERRQ(ierr);
2131d1367b7SBarry Smith     if (j->snes->method_class == SNES_NONLINEAR_EQUATIONS) {
2141d1367b7SBarry Smith       ierr = SNESGetFunction(j->snes,&j->current_f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2151d1367b7SBarry Smith     } else if (j->snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
2161d1367b7SBarry Smith       ierr = SNESGetGradient(j->snes,&j->current_f,PETSC_NULL);CHKERRQ(ierr);
21729bbc08cSBarry Smith     } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid method class");
2181d1367b7SBarry Smith   }
219be726c96SBarry Smith   PetscFunctionReturn(0);
220be726c96SBarry Smith }
221be726c96SBarry Smith 
2224a2ae208SSatish Balay #undef __FUNCT__
2234a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFMult_Private"
224eb9086c3SLois Curfman McInnes /*
2255a655dc6SBarry Smith   MatSNESMFMult_Private - Default matrix-free form for Jacobian-vector
226eb9086c3SLois Curfman McInnes   product, y = F'(u)*a:
227a4d4d686SBarry Smith 
2289a6cb015SBarry Smith         y ~= (F(u + ha) - F(u))/h,
229eb9086c3SLois Curfman McInnes   where F = nonlinear function, as set by SNESSetFunction()
230eb9086c3SLois Curfman McInnes         u = current iterate
231eb9086c3SLois Curfman McInnes         h = difference interval
232eb9086c3SLois Curfman McInnes */
2335a655dc6SBarry Smith int MatSNESMFMult_Private(Mat mat,Vec a,Vec y)
23439e2f89bSBarry Smith {
2355a655dc6SBarry Smith   MatSNESMFCtx ctx;
236fae171e0SBarry Smith   SNES         snes;
237a4d4d686SBarry Smith   Scalar       h,mone = -1.0;
238fae171e0SBarry Smith   Vec          w,U,F;
239a305c92eSSatish Balay   int          ierr,(*eval_fct)(SNES,Vec,Vec)=0;
24039e2f89bSBarry Smith 
2413a40ed3dSBarry Smith   PetscFunctionBegin;
2429a6cb015SBarry Smith   /* We log matrix-free matrix-vector products separately, so that we can
2439a6cb015SBarry Smith      separate the performance monitoring from the cases that use conventional
2449a6cb015SBarry Smith      storage.  We may eventually modify event logging to associate events
2459a6cb015SBarry Smith      with particular objects, hence alleviating the more general problem. */
246b0a32e0cSBarry Smith   ierr = PetscLogEventBegin(MAT_MatrixFreeMult,a,y,0,0);CHKERRQ(ierr);
24756cd22aeSBarry Smith 
2486e38a044SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
249fae171e0SBarry Smith   snes = ctx->snes;
250fae171e0SBarry Smith   w    = ctx->w;
2511d1367b7SBarry Smith   U    = ctx->current_u;
25250361f65SLois Curfman McInnes 
25385614651SBarry Smith   /*
25485614651SBarry Smith       Compute differencing parameter
25585614651SBarry Smith   */
2569a6cb015SBarry Smith   if (!ctx->ops->compute) {
257b7fd4e64SBarry Smith     ierr = MatSNESMFSetType(mat,MATSNESMF_DEFAULT);CHKERRQ(ierr);
2585a655dc6SBarry Smith     ierr = MatSNESMFSetFromOptions(mat);CHKERRQ(ierr);
2599a6cb015SBarry Smith   }
2609a6cb015SBarry Smith   ierr = (*ctx->ops->compute)(ctx,U,a,&h);CHKERRQ(ierr);
261a4d4d686SBarry Smith 
262a4d4d686SBarry Smith   /* keep a record of the current differencing parameter h */
263a4d4d686SBarry Smith   ctx->currenth = h;
264aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
265b0a32e0cSBarry Smith   PetscLogInfo(mat,"MatSNESMFMult_Private:Current differencing parameter: %g + %g i\n",PetscRealPart(h),PetscImaginaryPart(h));
266a4d4d686SBarry Smith #else
267b0a32e0cSBarry Smith   PetscLogInfo(mat,"MatSNESMFMult_Private:Current differencing parameter: %15.12e\n",h);
268a4d4d686SBarry Smith #endif
269a4d4d686SBarry Smith   if (ctx->historyh && ctx->ncurrenth < ctx->maxcurrenth) {
27085614651SBarry Smith     ctx->historyh[ctx->ncurrenth] = h;
271a4d4d686SBarry Smith   }
27285614651SBarry Smith   ctx->ncurrenth++;
273a4d4d686SBarry Smith 
27485614651SBarry Smith   /* w = u + ha */
275a4d4d686SBarry Smith   ierr = VecWAXPY(&h,a,U,w);CHKERRQ(ierr);
27685614651SBarry Smith 
277b0a32e0cSBarry Smith   if (ctx->usesnes) {
27885614651SBarry Smith     if (snes->method_class == SNES_NONLINEAR_EQUATIONS) {
27985614651SBarry Smith       eval_fct = SNESComputeFunction;
28085614651SBarry Smith     } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
28185614651SBarry Smith       eval_fct = SNESComputeGradient;
28229bbc08cSBarry Smith     } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid method class");
2831d1367b7SBarry Smith     F    = ctx->current_f;
28429bbc08cSBarry Smith     if (!F) SETERRQ(1,"You must call MatAssembly() even on matrix-free matrices");
28539903ad8SBarry Smith     ierr = (*eval_fct)(snes,w,y);CHKERRQ(ierr);
28685614651SBarry Smith   } else {
28785614651SBarry Smith     F = ctx->funcvec;
28885614651SBarry Smith     /* compute func(U) as base for differencing */
28985614651SBarry Smith     if (ctx->ncurrenth == 1) {
29085614651SBarry Smith       ierr = (*ctx->func)(snes,U,F,ctx->funcctx);CHKERRQ(ierr);
29185614651SBarry Smith     }
29285614651SBarry Smith     ierr = (*ctx->func)(snes,w,y,ctx->funcctx);CHKERRQ(ierr);
29385614651SBarry Smith   }
294a4d4d686SBarry Smith 
295a4d4d686SBarry Smith   ierr = VecAXPY(&mone,F,y);CHKERRQ(ierr);
296a4d4d686SBarry Smith   h    = 1.0/h;
297a4d4d686SBarry Smith   ierr = VecScale(&h,y);CHKERRQ(ierr);
29874637425SBarry Smith   if (ctx->sp) {ierr = MatNullSpaceRemove(ctx->sp,y,PETSC_NULL);CHKERRQ(ierr);}
299a4d4d686SBarry Smith 
300b0a32e0cSBarry Smith   ierr = PetscLogEventEnd(MAT_MatrixFreeMult,a,y,0,0);CHKERRQ(ierr);
301a4d4d686SBarry Smith   PetscFunctionReturn(0);
302a4d4d686SBarry Smith }
303a4d4d686SBarry Smith 
3044a2ae208SSatish Balay #undef __FUNCT__
305*cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFGetDiagonal_Private"
306*cf57b110SBarry Smith /*
307*cf57b110SBarry Smith   MatSNESMFGetDiagonal_Private - Gets the diagonal for a matrix free matrix
308*cf57b110SBarry Smith 
309*cf57b110SBarry Smith         y ~= (F(u + ha) - F(u))/h,
310*cf57b110SBarry Smith   where F = nonlinear function, as set by SNESSetFunction()
311*cf57b110SBarry Smith         u = current iterate
312*cf57b110SBarry Smith         h = difference interval
313*cf57b110SBarry Smith */
314*cf57b110SBarry Smith int MatSNESMFGetDiagonal_Private(Mat mat,Vec a)
315*cf57b110SBarry Smith {
316*cf57b110SBarry Smith   MatSNESMFCtx ctx;
317*cf57b110SBarry Smith   Scalar       h,h1,mone = -1.0,*aa,*ww,v,epsilon = 1.e-8,umin = 1.e-6;
318*cf57b110SBarry Smith   Vec          w,U,F;
319*cf57b110SBarry Smith   int          i,ierr,rstart,rend;
320*cf57b110SBarry Smith 
321*cf57b110SBarry Smith   PetscFunctionBegin;
322*cf57b110SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
323*cf57b110SBarry Smith   if (!ctx->funci) {
324*cf57b110SBarry Smith     SETERRQ(1,"Requirers calling MatSNESMFSetFunctioni() first");
325*cf57b110SBarry Smith   }
326*cf57b110SBarry Smith 
327*cf57b110SBarry Smith   w    = ctx->w;
328*cf57b110SBarry Smith   U    = ctx->current_u;
329*cf57b110SBarry Smith   ierr = (*ctx->func)(0,U,a,ctx->funcctx);CHKERRQ(ierr);
330*cf57b110SBarry Smith   ierr = (*ctx->funcisetbase)(U,ctx->funcctx);CHKERRQ(ierr);
331*cf57b110SBarry Smith   ierr = VecCopy(U,w);CHKERRQ(ierr);
332*cf57b110SBarry Smith 
333*cf57b110SBarry Smith   ierr = VecGetOwnershipRange(a,&rstart,&rend);CHKERRQ(ierr);
334*cf57b110SBarry Smith   ierr = VecGetArray(a,&aa);CHKERRQ(ierr);
335*cf57b110SBarry Smith   for (i=rstart; i<rend; i++) {
336*cf57b110SBarry Smith     ierr = VecGetArray(w,&ww);CHKERRQ(ierr);
337*cf57b110SBarry Smith     h  = ww[i-rstart];
338*cf57b110SBarry Smith     if (h == 0.0) h = 1.0;
339*cf57b110SBarry Smith #if !defined(PETSC_USE_COMPLEX)
340*cf57b110SBarry Smith     if (h < umin && h >= 0.0)      h = umin;
341*cf57b110SBarry Smith     else if (h < 0.0 && h > -umin) h = -umin;
342*cf57b110SBarry Smith #else
343*cf57b110SBarry Smith     if (PetscAbsScalar(h) < umin && PetscRealPart(h) >= 0.0)     h = umin;
344*cf57b110SBarry Smith     else if (PetscRealPart(h) < 0.0 && PetscAbsScalar(h) < umin) h = -umin;
345*cf57b110SBarry Smith #endif
346*cf57b110SBarry Smith     h     *= epsilon;
347*cf57b110SBarry Smith 
348*cf57b110SBarry Smith     ww[i-rstart] += h;
349*cf57b110SBarry Smith     ierr = VecRestoreArray(w,&ww);CHKERRQ(ierr);
350*cf57b110SBarry Smith     ierr          = (*ctx->funci)(i,w,&v,ctx->funcctx);CHKERRQ(ierr);
351*cf57b110SBarry Smith     aa[i-rstart]  = (v - aa[i-rstart])/h;
352*cf57b110SBarry Smith     ierr = VecGetArray(w,&ww);CHKERRQ(ierr);
353*cf57b110SBarry Smith     ww[i-rstart] -= h;
354*cf57b110SBarry Smith     ierr = VecRestoreArray(w,&ww);CHKERRQ(ierr);
355*cf57b110SBarry Smith   }
356*cf57b110SBarry Smith   ierr = VecRestoreArray(a,&aa);CHKERRQ(ierr);
357*cf57b110SBarry Smith   PetscFunctionReturn(0);
358*cf57b110SBarry Smith }
359*cf57b110SBarry Smith 
360*cf57b110SBarry Smith #undef __FUNCT__
3614a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF"
362a4d4d686SBarry Smith /*@C
36365f2ba5bSLois Curfman McInnes    MatCreateSNESMF - Creates a matrix-free matrix context for use with
36465f2ba5bSLois Curfman McInnes    a SNES solver.  This matrix can be used as the Jacobian argument for
36565f2ba5bSLois Curfman McInnes    the routine SNESSetJacobian().
366a4d4d686SBarry Smith 
367a4d4d686SBarry Smith    Collective on SNES and Vec
368a4d4d686SBarry Smith 
369a4d4d686SBarry Smith    Input Parameters:
370a4d4d686SBarry Smith +  snes - the SNES context
371a4d4d686SBarry Smith -  x - vector where SNES solution is to be stored.
372a4d4d686SBarry Smith 
373a4d4d686SBarry Smith    Output Parameter:
374a4d4d686SBarry Smith .  J - the matrix-free matrix
375a4d4d686SBarry Smith 
37615091d37SBarry Smith    Level: advanced
37715091d37SBarry Smith 
378a4d4d686SBarry Smith    Notes:
379a4d4d686SBarry Smith    The matrix-free matrix context merely contains the function pointers
380a4d4d686SBarry Smith    and work space for performing finite difference approximations of
38165f2ba5bSLois Curfman McInnes    Jacobian-vector products, F'(u)*a,
3829a6cb015SBarry Smith 
3839a6cb015SBarry Smith    The default code uses the following approach to compute h
384a4d4d686SBarry Smith 
385a4d4d686SBarry Smith .vb
38665f2ba5bSLois Curfman McInnes      F'(u)*a = [F(u+h*a) - F(u)]/h where
387a4d4d686SBarry Smith      h = error_rel*u'a/||a||^2                        if  |u'a| > umin*||a||_{1}
388a4d4d686SBarry Smith        = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2   otherwise
389a4d4d686SBarry Smith  where
390a4d4d686SBarry Smith      error_rel = square root of relative error in function evaluation
391a4d4d686SBarry Smith      umin = minimum iterate parameter
392a4d4d686SBarry Smith .ve
393a4d4d686SBarry Smith 
3945a655dc6SBarry Smith    The user can set the error_rel via MatSNESMFSetFunctionError() and
39565f2ba5bSLois Curfman McInnes    umin via MatSNESMFDefaultSetUmin(); see the nonlinear solvers chapter
39665f2ba5bSLois Curfman McInnes    of the users manual for details.
397a4d4d686SBarry Smith 
398a4d4d686SBarry Smith    The user should call MatDestroy() when finished with the matrix-free
399a4d4d686SBarry Smith    matrix context.
400a4d4d686SBarry Smith 
401a4d4d686SBarry Smith    Options Database Keys:
402a4d4d686SBarry Smith +  -snes_mf_err <error_rel> - Sets error_rel
4039a6cb015SBarry Smith .  -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only)
404a4d4d686SBarry Smith -  -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h
405a4d4d686SBarry Smith 
406a4d4d686SBarry Smith .keywords: SNES, default, matrix-free, create, matrix
407a4d4d686SBarry Smith 
4085a655dc6SBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError(), MatSNESMFDefaultSetUmin()
4091d1367b7SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), MatCreateMF(),
410fed8bd04SBarry Smith           MatSNESMFGetH(),MatSNESMFKSPMonitor(), MatSNESMFRegisterDynamic), MatSNESMFComputeJacobian()
411a4d4d686SBarry Smith 
412a4d4d686SBarry Smith @*/
4135a655dc6SBarry Smith int MatCreateSNESMF(SNES snes,Vec x,Mat *J)
414a4d4d686SBarry Smith {
4151d1367b7SBarry Smith   MatSNESMFCtx mfctx;
4161d1367b7SBarry Smith   int          ierr;
4171d1367b7SBarry Smith 
4181d1367b7SBarry Smith   PetscFunctionBegin;
4191d1367b7SBarry Smith   ierr = MatCreateMF(x,J);CHKERRQ(ierr);
4201d1367b7SBarry Smith   ierr = MatShellGetContext(*J,(void **)&mfctx);CHKERRQ(ierr);
4211d1367b7SBarry Smith   mfctx->snes    = snes;
422b0a32e0cSBarry Smith   mfctx->usesnes = PETSC_TRUE;
423b0a32e0cSBarry Smith   PetscLogObjectParent(snes,*J);
4241d1367b7SBarry Smith   PetscFunctionReturn(0);
4251d1367b7SBarry Smith }
4261d1367b7SBarry Smith 
427cf3bea43SBarry Smith EXTERN_C_BEGIN
428cf3bea43SBarry Smith #undef __FUNCT__
429cf3bea43SBarry Smith #define __FUNCT__ "MatSNESMFSetBase_FD"
430cf3bea43SBarry Smith int MatSNESMFSetBase_FD(Mat J,Vec U)
431cf3bea43SBarry Smith {
432cf3bea43SBarry Smith   int          ierr;
433cf3bea43SBarry Smith   MatSNESMFCtx ctx;
434cf3bea43SBarry Smith 
435cf3bea43SBarry Smith   PetscFunctionBegin;
436cf3bea43SBarry Smith   ierr = MatSNESMFResetHHistory(J);CHKERRQ(ierr);
437cf3bea43SBarry Smith   ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr);
438cf3bea43SBarry Smith   ctx->current_u = U;
439cf3bea43SBarry Smith   ctx->usesnes   = PETSC_FALSE;
440cf3bea43SBarry Smith   PetscFunctionReturn(0);
441cf3bea43SBarry Smith }
442cf3bea43SBarry Smith EXTERN_C_END
443cf3bea43SBarry Smith 
4444a2ae208SSatish Balay #undef __FUNCT__
4454a2ae208SSatish Balay #define __FUNCT__ "MatCreateMF"
4461d1367b7SBarry Smith /*@C
4471d1367b7SBarry Smith    MatCreateMF - Creates a matrix-free matrix. See also MatCreateSNESMF()
4481d1367b7SBarry Smith 
4491d1367b7SBarry Smith    Collective on Vec
4501d1367b7SBarry Smith 
4511d1367b7SBarry Smith    Input Parameters:
4521d1367b7SBarry Smith .  x - vector that defines layout of the vectors and matrices
4531d1367b7SBarry Smith 
4541d1367b7SBarry Smith    Output Parameter:
4551d1367b7SBarry Smith .  J - the matrix-free matrix
4561d1367b7SBarry Smith 
4571d1367b7SBarry Smith    Level: advanced
4581d1367b7SBarry Smith 
4591d1367b7SBarry Smith    Notes:
4601d1367b7SBarry Smith    The matrix-free matrix context merely contains the function pointers
4611d1367b7SBarry Smith    and work space for performing finite difference approximations of
4621d1367b7SBarry Smith    Jacobian-vector products, F'(u)*a,
4631d1367b7SBarry Smith 
4641d1367b7SBarry Smith    The default code uses the following approach to compute h
4651d1367b7SBarry Smith 
4661d1367b7SBarry Smith .vb
4671d1367b7SBarry Smith      F'(u)*a = [F(u+h*a) - F(u)]/h where
4681d1367b7SBarry Smith      h = error_rel*u'a/||a||^2                        if  |u'a| > umin*||a||_{1}
4691d1367b7SBarry Smith        = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2   otherwise
4701d1367b7SBarry Smith  where
4711d1367b7SBarry Smith      error_rel = square root of relative error in function evaluation
4721d1367b7SBarry Smith      umin = minimum iterate parameter
4731d1367b7SBarry Smith .ve
4741d1367b7SBarry Smith 
4751d1367b7SBarry Smith    The user can set the error_rel via MatSNESMFSetFunctionError() and
4761d1367b7SBarry Smith    umin via MatSNESMFDefaultSetUmin(); see the nonlinear solvers chapter
4771d1367b7SBarry Smith    of the users manual for details.
4781d1367b7SBarry Smith 
4791d1367b7SBarry Smith    The user should call MatDestroy() when finished with the matrix-free
4801d1367b7SBarry Smith    matrix context.
4811d1367b7SBarry Smith 
4821d1367b7SBarry Smith    Options Database Keys:
4831d1367b7SBarry Smith +  -snes_mf_err <error_rel> - Sets error_rel
4841d1367b7SBarry Smith .  -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only)
4851d1367b7SBarry Smith -  -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h
4861d1367b7SBarry Smith 
4871d1367b7SBarry Smith .keywords: default, matrix-free, create, matrix
4881d1367b7SBarry Smith 
4891d1367b7SBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError(), MatSNESMFDefaultSetUmin()
4901d1367b7SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), MatCreateSNESMF(),
491fed8bd04SBarry Smith           MatSNESMFGetH(),MatSNESMFKSPMonitor(), MatSNESMFRegisterDynamic),, MatSNESMFComputeJacobian()
4921d1367b7SBarry Smith 
4931d1367b7SBarry Smith @*/
4941d1367b7SBarry Smith int MatCreateMF(Vec x,Mat *J)
4951d1367b7SBarry Smith {
496a4d4d686SBarry Smith   MPI_Comm     comm;
4975a655dc6SBarry Smith   MatSNESMFCtx mfctx;
4989a6cb015SBarry Smith   int          n,nloc,ierr;
499a4d4d686SBarry Smith 
500a4d4d686SBarry Smith   PetscFunctionBegin;
5011d1367b7SBarry Smith   ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
5021d1367b7SBarry Smith   PetscHeaderCreate(mfctx,_p_MatSNESMFCtx,struct _MFOps,MATSNESMFCTX_COOKIE,0,"SNESMF",comm,MatSNESMFDestroy_Private,MatSNESMFView_Private);
503b0a32e0cSBarry Smith   PetscLogObjectCreate(mfctx);
504a4d4d686SBarry Smith   mfctx->sp              = 0;
5051d1367b7SBarry Smith   mfctx->snes            = 0;
506329f5518SBarry Smith   mfctx->error_rel       = 1.e-8; /* assumes PetscReal precision */
507329f5518SBarry Smith   mfctx->recomputeperiod = 1;
508329f5518SBarry Smith   mfctx->count           = 0;
509a4d4d686SBarry Smith   mfctx->currenth        = 0.0;
510a4d4d686SBarry Smith   mfctx->historyh        = PETSC_NULL;
511a4d4d686SBarry Smith   mfctx->ncurrenth       = 0;
512a4d4d686SBarry Smith   mfctx->maxcurrenth     = 0;
5136831982aSBarry Smith   mfctx->type_name       = 0;
514b0a32e0cSBarry Smith   mfctx->usesnes         = PETSC_FALSE;
515a4d4d686SBarry Smith 
5169a6cb015SBarry Smith   /*
5179a6cb015SBarry Smith      Create the empty data structure to contain compute-h routines.
5189a6cb015SBarry Smith      These will be filled in below from the command line options or
5195a655dc6SBarry Smith      a later call with MatSNESMFSetType() or if that is not called
5205a655dc6SBarry Smith      then it will default in the first use of MatSNESMFMult_private()
5219a6cb015SBarry Smith   */
5229a6cb015SBarry Smith   mfctx->ops->compute        = 0;
5239a6cb015SBarry Smith   mfctx->ops->destroy        = 0;
5249a6cb015SBarry Smith   mfctx->ops->view           = 0;
5259a6cb015SBarry Smith   mfctx->ops->setfromoptions = 0;
5269a6cb015SBarry Smith   mfctx->hctx                = 0;
5279a6cb015SBarry Smith 
52885614651SBarry Smith   mfctx->func                = 0;
52985614651SBarry Smith   mfctx->funcctx             = 0;
53085614651SBarry Smith   mfctx->funcvec             = 0;
53185614651SBarry Smith 
532a4d4d686SBarry Smith   ierr = VecDuplicate(x,&mfctx->w);CHKERRQ(ierr);
5331d1367b7SBarry Smith   ierr = VecGetSize(mfctx->w,&n);CHKERRQ(ierr);
5341d1367b7SBarry Smith   ierr = VecGetLocalSize(mfctx->w,&nloc);CHKERRQ(ierr);
535ffa0fd9eSBarry Smith   ierr = MatCreateShell(comm,nloc,nloc,n,n,mfctx,J);CHKERRQ(ierr);
53637bd1cefSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_MULT,(void(*)())MatSNESMFMult_Private);CHKERRQ(ierr);
53737bd1cefSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_DESTROY,(void(*)())MatSNESMFDestroy_Private);CHKERRQ(ierr);
53837bd1cefSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_VIEW,(void(*)())MatSNESMFView_Private);CHKERRQ(ierr);
53937bd1cefSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_ASSEMBLY_END,(void(*)())MatSNESMFAssemblyEnd_Private);CHKERRQ(ierr);
540*cf57b110SBarry Smith   ierr = MatShellSetOperation(*J,MATOP_GET_DIAGONAL,(void(*)())MatSNESMFGetDiagonal_Private);CHKERRQ(ierr);
541cf3bea43SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatSNESMFSetBase_C","MatSNESMFSetBase_FD",MatSNESMFSetBase_FD);CHKERRQ(ierr);
542b0a32e0cSBarry Smith   PetscLogObjectParent(*J,mfctx->w);
5439a6cb015SBarry Smith 
5449a6cb015SBarry Smith   mfctx->mat = *J;
5459a6cb015SBarry Smith   PetscFunctionReturn(0);
5469a6cb015SBarry Smith }
5479a6cb015SBarry Smith 
5484a2ae208SSatish Balay #undef __FUNCT__
5494a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetFromOptions"
5509a6cb015SBarry Smith /*@
5515a655dc6SBarry Smith    MatSNESMFSetFromOptions - Sets the MatSNESMF options from the command line
5529a6cb015SBarry Smith    parameter.
5539a6cb015SBarry Smith 
5549a6cb015SBarry Smith    Collective on Mat
5559a6cb015SBarry Smith 
5569a6cb015SBarry Smith    Input Parameters:
5575a655dc6SBarry Smith .  mat - the matrix obtained with MatCreateSNESMF()
5585a655dc6SBarry Smith 
5595a655dc6SBarry Smith    Options Database Keys:
5605a655dc6SBarry Smith +  -snes_mf_type - <default,wp>
5615a655dc6SBarry Smith -  -snes_mf_err - square root of estimated relative error in function evaluation
562329f5518SBarry Smith -  -snes_mf_period - how often h is recomputed, defaults to 1, everytime
5639a6cb015SBarry Smith 
56415091d37SBarry Smith    Level: advanced
56515091d37SBarry Smith 
5669a6cb015SBarry Smith .keywords: SNES, matrix-free, parameters
5679a6cb015SBarry Smith 
5685a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(),
5695a655dc6SBarry Smith           MatSNESMFResetHHistory(), MatSNESMFKSPMonitor()
5709a6cb015SBarry Smith @*/
5715a655dc6SBarry Smith int MatSNESMFSetFromOptions(Mat mat)
5729a6cb015SBarry Smith {
5735a655dc6SBarry Smith   MatSNESMFCtx mfctx;
574f1af5d2fSBarry Smith   int          ierr;
575f1af5d2fSBarry Smith   PetscTruth   flg;
576186905e3SBarry Smith   char         ftype[256];
5779a6cb015SBarry Smith 
5789a6cb015SBarry Smith   PetscFunctionBegin;
5799a6cb015SBarry Smith   ierr = MatShellGetContext(mat,(void **)&mfctx);CHKERRQ(ierr);
5809a6cb015SBarry Smith   if (mfctx) {
581186905e3SBarry Smith     if (!MatSNESMFRegisterAllCalled) {ierr = MatSNESMFRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
582186905e3SBarry Smith 
583b0a32e0cSBarry Smith     ierr = PetscOptionsBegin(mfctx->comm,mfctx->prefix,"Set matrix free computation parameters","MatSNESMF");CHKERRQ(ierr);
584b0a32e0cSBarry Smith       ierr = PetscOptionsList("-snes_mf_type","Matrix free type","MatSNESMFSetType",MatSNESMPetscFList,mfctx->type_name,ftype,256,&flg);CHKERRQ(ierr);
5859a6cb015SBarry Smith       if (flg) {
5865a655dc6SBarry Smith         ierr = MatSNESMFSetType(mat,ftype);CHKERRQ(ierr);
5879a6cb015SBarry Smith       }
5889a6cb015SBarry Smith 
589b0a32e0cSBarry Smith       ierr = PetscOptionsDouble("-snes_mf_err","set sqrt relative error in function","MatSNESMFSetFunctionError",mfctx->error_rel,&mfctx->error_rel,0);CHKERRQ(ierr);
590b0a32e0cSBarry Smith       ierr = PetscOptionsInt("-snes_mf_period","how often h is recomputed","MatSNESMFSetPeriod",mfctx->recomputeperiod,&mfctx->recomputeperiod,0);CHKERRQ(ierr);
591186905e3SBarry Smith       if (mfctx->snes) {
592b0a32e0cSBarry Smith         ierr = PetscOptionsName("-snes_mf_ksp_monitor","Monitor matrix-free parameters","MatSNESMFKSPMonitor",&flg);CHKERRQ(ierr);
593186905e3SBarry Smith         if (flg) {
594186905e3SBarry Smith           SLES sles;
595186905e3SBarry Smith           KSP  ksp;
596186905e3SBarry Smith           ierr = SNESGetSLES(mfctx->snes,&sles);CHKERRQ(ierr);
597186905e3SBarry Smith           ierr = SLESGetKSP(sles,&ksp);CHKERRQ(ierr);
598186905e3SBarry Smith           ierr = KSPSetMonitor(ksp,MatSNESMFKSPMonitor,PETSC_NULL,0);CHKERRQ(ierr);
599186905e3SBarry Smith         }
600186905e3SBarry Smith       }
6019a6cb015SBarry Smith       if (mfctx->ops->setfromoptions) {
6029a6cb015SBarry Smith         ierr = (*mfctx->ops->setfromoptions)(mfctx);CHKERRQ(ierr);
6039a6cb015SBarry Smith       }
604b0a32e0cSBarry Smith     ierr = PetscOptionsEnd();CHKERRQ(ierr);
6054bbc92c1SBarry Smith 
6069a6cb015SBarry Smith   }
607a4d4d686SBarry Smith   PetscFunctionReturn(0);
608a4d4d686SBarry Smith }
609a4d4d686SBarry Smith 
6104a2ae208SSatish Balay #undef __FUNCT__
6114a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFGetH"
612a4d4d686SBarry Smith /*@
61365f2ba5bSLois Curfman McInnes    MatSNESMFGetH - Gets the last value that was used as the differencing
614a4d4d686SBarry Smith    parameter.
615a4d4d686SBarry Smith 
616a4d4d686SBarry Smith    Not Collective
617a4d4d686SBarry Smith 
618a4d4d686SBarry Smith    Input Parameters:
6195a655dc6SBarry Smith .  mat - the matrix obtained with MatCreateSNESMF()
620a4d4d686SBarry Smith 
621a4d4d686SBarry Smith    Output Paramter:
622a4d4d686SBarry Smith .  h - the differencing step size
623a4d4d686SBarry Smith 
62415091d37SBarry Smith    Level: advanced
62515091d37SBarry Smith 
626a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters
627a4d4d686SBarry Smith 
6285a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(),
6295a655dc6SBarry Smith           MatSNESMFResetHHistory(),MatSNESMFKSPMonitor()
630a4d4d686SBarry Smith @*/
6315a655dc6SBarry Smith int MatSNESMFGetH(Mat mat,Scalar *h)
632a4d4d686SBarry Smith {
6335a655dc6SBarry Smith   MatSNESMFCtx ctx;
634a4d4d686SBarry Smith   int          ierr;
635a4d4d686SBarry Smith 
636a4d4d686SBarry Smith   PetscFunctionBegin;
637a4d4d686SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
638a4d4d686SBarry Smith   if (ctx) {
639a4d4d686SBarry Smith     *h = ctx->currenth;
640a4d4d686SBarry Smith   }
641a4d4d686SBarry Smith   PetscFunctionReturn(0);
642a4d4d686SBarry Smith }
643a4d4d686SBarry Smith 
6444a2ae208SSatish Balay #undef __FUNCT__
6454a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFKSPMonitor"
646a4d4d686SBarry Smith /*
6475a655dc6SBarry Smith    MatSNESMFKSPMonitor - A KSP monitor for use with the default PETSc
64865f2ba5bSLois Curfman McInnes    SNES matrix free routines. Prints the differencing parameter used at
64965f2ba5bSLois Curfman McInnes    each step.
650a4d4d686SBarry Smith */
651329f5518SBarry Smith int MatSNESMFKSPMonitor(KSP ksp,int n,PetscReal rnorm,void *dummy)
652a4d4d686SBarry Smith {
653a4d4d686SBarry Smith   PC             pc;
6545a655dc6SBarry Smith   MatSNESMFCtx   ctx;
655a4d4d686SBarry Smith   int            ierr;
656a4d4d686SBarry Smith   Mat            mat;
657a4d4d686SBarry Smith   MPI_Comm       comm;
658a4d4d686SBarry Smith   PetscTruth     nonzeroinitialguess;
659a4d4d686SBarry Smith 
660a4d4d686SBarry Smith   PetscFunctionBegin;
661a4d4d686SBarry Smith   ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr);
662a4d4d686SBarry Smith   ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
663a4d4d686SBarry Smith   ierr = KSPGetInitialGuessNonzero(ksp,&nonzeroinitialguess);CHKERRQ(ierr);
664a4d4d686SBarry Smith   ierr = PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
665a4d4d686SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
6669a6cb015SBarry Smith   if (!ctx) {
66729bbc08cSBarry Smith     SETERRQ(1,"Matrix is not a matrix free shell matrix");
6689a6cb015SBarry Smith   }
669a4d4d686SBarry Smith   if (n > 0 || nonzeroinitialguess) {
670aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
671d132466eSBarry Smith     ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g + %g i\n",n,rnorm,
672329f5518SBarry Smith                 PetscRealPart(ctx->currenth),PetscImaginaryPart(ctx->currenth));CHKERRQ(ierr);
673a4d4d686SBarry Smith #else
674d132466eSBarry Smith     ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g \n",n,rnorm,ctx->currenth);CHKERRQ(ierr);
675a4d4d686SBarry Smith #endif
676a4d4d686SBarry Smith   } else {
677d132466eSBarry Smith     ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e\n",n,rnorm);CHKERRQ(ierr);
678a4d4d686SBarry Smith   }
679a4d4d686SBarry Smith   PetscFunctionReturn(0);
680a4d4d686SBarry Smith }
681a4d4d686SBarry Smith 
6824a2ae208SSatish Balay #undef __FUNCT__
6834a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetFunction"
68485614651SBarry Smith /*@C
68585614651SBarry Smith    MatSNESMFSetFunction - Sets the function used in applying the matrix free.
68685614651SBarry Smith 
68785614651SBarry Smith    Collective on Mat
68885614651SBarry Smith 
68985614651SBarry Smith    Input Parameters:
69085614651SBarry Smith +  mat - the matrix free matrix created via MatCreateSNESMF()
69185614651SBarry Smith .  v   - workspace vector
69285614651SBarry Smith .  func - the function to use
69385614651SBarry Smith -  funcctx - optional function context passed to function
69485614651SBarry Smith 
69585614651SBarry Smith    Level: advanced
69685614651SBarry Smith 
69785614651SBarry Smith    Notes:
69885614651SBarry Smith     If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free
69985614651SBarry Smith     matrix inside your compute Jacobian routine
70085614651SBarry Smith 
70185614651SBarry Smith     If this is not set then it will use the function set with SNESSetFunction()
70285614651SBarry Smith 
70385614651SBarry Smith .keywords: SNES, matrix-free, function
70485614651SBarry Smith 
70585614651SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(),
70685614651SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(),
70785614651SBarry Smith           MatSNESMFKSPMonitor(), SNESetFunction()
70885614651SBarry Smith @*/
70985614651SBarry Smith int MatSNESMFSetFunction(Mat mat,Vec v,int (*func)(SNES,Vec,Vec,void *),void *funcctx)
71085614651SBarry Smith {
71185614651SBarry Smith   MatSNESMFCtx ctx;
71285614651SBarry Smith   int          ierr;
71385614651SBarry Smith 
71485614651SBarry Smith   PetscFunctionBegin;
71585614651SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
71685614651SBarry Smith   if (ctx) {
71785614651SBarry Smith     ctx->func    = func;
71885614651SBarry Smith     ctx->funcctx = funcctx;
71985614651SBarry Smith     ctx->funcvec = v;
72085614651SBarry Smith   }
72185614651SBarry Smith   PetscFunctionReturn(0);
72285614651SBarry Smith }
72385614651SBarry Smith 
724*cf57b110SBarry Smith #undef __FUNCT__
725*cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioni"
726*cf57b110SBarry Smith /*@C
727*cf57b110SBarry Smith    MatSNESMFSetFunctioni - Sets the function for a single component
728*cf57b110SBarry Smith 
729*cf57b110SBarry Smith    Collective on Mat
730*cf57b110SBarry Smith 
731*cf57b110SBarry Smith    Input Parameters:
732*cf57b110SBarry Smith +  mat - the matrix free matrix created via MatCreateSNESMF()
733*cf57b110SBarry Smith -  funci - the function to use
734*cf57b110SBarry Smith 
735*cf57b110SBarry Smith    Level: advanced
736*cf57b110SBarry Smith 
737*cf57b110SBarry Smith    Notes:
738*cf57b110SBarry Smith     If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free
739*cf57b110SBarry Smith     matrix inside your compute Jacobian routine
740*cf57b110SBarry Smith 
741*cf57b110SBarry Smith 
742*cf57b110SBarry Smith .keywords: SNES, matrix-free, function
743*cf57b110SBarry Smith 
744*cf57b110SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(),
745*cf57b110SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(),
746*cf57b110SBarry Smith           MatSNESMFKSPMonitor(), SNESetFunction()
747*cf57b110SBarry Smith @*/
748*cf57b110SBarry Smith int MatSNESMFSetFunctioni(Mat mat,int (*funci)(int,Vec,Scalar*,void *))
749*cf57b110SBarry Smith {
750*cf57b110SBarry Smith   MatSNESMFCtx ctx;
751*cf57b110SBarry Smith   int          ierr;
752*cf57b110SBarry Smith 
753*cf57b110SBarry Smith   PetscFunctionBegin;
754*cf57b110SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
755*cf57b110SBarry Smith   if (ctx) {
756*cf57b110SBarry Smith     ctx->funci   = funci;
757*cf57b110SBarry Smith   }
758*cf57b110SBarry Smith   PetscFunctionReturn(0);
759*cf57b110SBarry Smith }
760*cf57b110SBarry Smith 
761*cf57b110SBarry Smith #undef __FUNCT__
762*cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioniBase"
763*cf57b110SBarry Smith /*@C
764*cf57b110SBarry Smith    MatSNESMFSetFunctioniBase - Sets the base vector for a single component function evaluation
765*cf57b110SBarry Smith 
766*cf57b110SBarry Smith    Collective on Mat
767*cf57b110SBarry Smith 
768*cf57b110SBarry Smith    Input Parameters:
769*cf57b110SBarry Smith +  mat - the matrix free matrix created via MatCreateSNESMF()
770*cf57b110SBarry Smith -  func - the function to use
771*cf57b110SBarry Smith 
772*cf57b110SBarry Smith    Level: advanced
773*cf57b110SBarry Smith 
774*cf57b110SBarry Smith    Notes:
775*cf57b110SBarry Smith     If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free
776*cf57b110SBarry Smith     matrix inside your compute Jacobian routine
777*cf57b110SBarry Smith 
778*cf57b110SBarry Smith 
779*cf57b110SBarry Smith .keywords: SNES, matrix-free, function
780*cf57b110SBarry Smith 
781*cf57b110SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(),
782*cf57b110SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(),
783*cf57b110SBarry Smith           MatSNESMFKSPMonitor(), SNESetFunction()
784*cf57b110SBarry Smith @*/
785*cf57b110SBarry Smith int MatSNESMFSetFunctioniBase(Mat mat,int (*func)(Vec,void *))
786*cf57b110SBarry Smith {
787*cf57b110SBarry Smith   MatSNESMFCtx ctx;
788*cf57b110SBarry Smith   int          ierr;
789*cf57b110SBarry Smith 
790*cf57b110SBarry Smith   PetscFunctionBegin;
791*cf57b110SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
792*cf57b110SBarry Smith   if (ctx) {
793*cf57b110SBarry Smith     ctx->funcisetbase   = func;
794*cf57b110SBarry Smith   }
795*cf57b110SBarry Smith   PetscFunctionReturn(0);
796*cf57b110SBarry Smith }
797*cf57b110SBarry Smith 
79885614651SBarry Smith 
7994a2ae208SSatish Balay #undef __FUNCT__
8004a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetPeriod"
801329f5518SBarry Smith /*@
802329f5518SBarry Smith    MatSNESMFSetPeriod - Sets how often h is recomputed, by default it is everytime
803329f5518SBarry Smith 
804329f5518SBarry Smith    Collective on Mat
805329f5518SBarry Smith 
806329f5518SBarry Smith    Input Parameters:
807329f5518SBarry Smith +  mat - the matrix free matrix created via MatCreateSNESMF()
808329f5518SBarry Smith -  period - 1 for everytime, 2 for every second etc
809329f5518SBarry Smith 
810329f5518SBarry Smith    Options Database Keys:
811329f5518SBarry Smith +  -snes_mf_period <period>
812329f5518SBarry Smith 
813329f5518SBarry Smith    Level: advanced
814329f5518SBarry Smith 
815329f5518SBarry Smith 
816329f5518SBarry Smith .keywords: SNES, matrix-free, parameters
817329f5518SBarry Smith 
818329f5518SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(),
819329f5518SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(),
820329f5518SBarry Smith           MatSNESMFKSPMonitor()
821329f5518SBarry Smith @*/
822329f5518SBarry Smith int MatSNESMFSetPeriod(Mat mat,int period)
823329f5518SBarry Smith {
824329f5518SBarry Smith   MatSNESMFCtx ctx;
825329f5518SBarry Smith   int          ierr;
826329f5518SBarry Smith 
827329f5518SBarry Smith   PetscFunctionBegin;
828329f5518SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
829329f5518SBarry Smith   if (ctx) {
830329f5518SBarry Smith     ctx->recomputeperiod = period;
831329f5518SBarry Smith   }
832329f5518SBarry Smith   PetscFunctionReturn(0);
833329f5518SBarry Smith }
834329f5518SBarry Smith 
8354a2ae208SSatish Balay #undef __FUNCT__
8364a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetFunctionError"
837a4d4d686SBarry Smith /*@
8385a655dc6SBarry Smith    MatSNESMFSetFunctionError - Sets the error_rel for the approximation of
839a4d4d686SBarry Smith    matrix-vector products using finite differences.
840a4d4d686SBarry Smith 
841a4d4d686SBarry Smith    Collective on Mat
842a4d4d686SBarry Smith 
843a4d4d686SBarry Smith    Input Parameters:
8445a655dc6SBarry Smith +  mat - the matrix free matrix created via MatCreateSNESMF()
8459a6cb015SBarry Smith -  error_rel - relative error (should be set to the square root of
846a4d4d686SBarry Smith                the relative error in the function evaluations)
847a4d4d686SBarry Smith 
84815091d37SBarry Smith    Options Database Keys:
84915091d37SBarry Smith +  -snes_mf_err <error_rel> - Sets error_rel
85015091d37SBarry Smith 
85115091d37SBarry Smith    Level: advanced
85215091d37SBarry Smith 
853a4d4d686SBarry Smith    Notes:
854a4d4d686SBarry Smith    The default matrix-free matrix-vector product routine computes
855a4d4d686SBarry Smith .vb
85665f2ba5bSLois Curfman McInnes      F'(u)*a = [F(u+h*a) - F(u)]/h where
857a4d4d686SBarry Smith      h = error_rel*u'a/||a||^2                        if  |u'a| > umin*||a||_{1}
858a4d4d686SBarry Smith        = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2   else
859a4d4d686SBarry Smith .ve
860a4d4d686SBarry Smith 
861a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters
862a4d4d686SBarry Smith 
8635a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(),
8645a655dc6SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(),
8655a655dc6SBarry Smith           MatSNESMFKSPMonitor()
866a4d4d686SBarry Smith @*/
867329f5518SBarry Smith int MatSNESMFSetFunctionError(Mat mat,PetscReal error)
868a4d4d686SBarry Smith {
8695a655dc6SBarry Smith   MatSNESMFCtx ctx;
870a4d4d686SBarry Smith   int          ierr;
871a4d4d686SBarry Smith 
872a4d4d686SBarry Smith   PetscFunctionBegin;
873a4d4d686SBarry Smith   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
874a4d4d686SBarry Smith   if (ctx) {
875a4d4d686SBarry Smith     if (error != PETSC_DEFAULT) ctx->error_rel = error;
876a4d4d686SBarry Smith   }
877a4d4d686SBarry Smith   PetscFunctionReturn(0);
878a4d4d686SBarry Smith }
879a4d4d686SBarry Smith 
8804a2ae208SSatish Balay #undef __FUNCT__
8814a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFAddNullSpace"
882a4d4d686SBarry Smith /*@
88365f2ba5bSLois Curfman McInnes    MatSNESMFAddNullSpace - Provides a null space that an operator is
88465f2ba5bSLois Curfman McInnes    supposed to have.  Since roundoff will create a small component in
88565f2ba5bSLois Curfman McInnes    the null space, if you know the null space you may have it
88665f2ba5bSLois Curfman McInnes    automatically removed.
887a4d4d686SBarry Smith 
888a4d4d686SBarry Smith    Collective on Mat
889a4d4d686SBarry Smith 
890a4d4d686SBarry Smith    Input Parameters:
891a4d4d686SBarry Smith +  J - the matrix-free matrix context
89274637425SBarry Smith -  nullsp - object created with MatNullSpaceCreate()
893a4d4d686SBarry Smith 
89415091d37SBarry Smith    Level: advanced
89515091d37SBarry Smith 
896a4d4d686SBarry Smith .keywords: SNES, matrix-free, null space
897a4d4d686SBarry Smith 
89874637425SBarry Smith .seealso: MatNullSpaceCreate(), MatSNESMFGetH(), MatCreateSNESMF(),
8995a655dc6SBarry Smith           MatSNESMFSetHHistory(), MatSNESMFResetHHistory(),
9005a655dc6SBarry Smith           MatSNESMFKSPMonitor(), MatSNESMFErrorRel()
901a4d4d686SBarry Smith @*/
90274637425SBarry Smith int MatSNESMFAddNullSpace(Mat J,MatNullSpace nullsp)
903a4d4d686SBarry Smith {
904a4d4d686SBarry Smith   int          ierr;
9055a655dc6SBarry Smith   MatSNESMFCtx ctx;
906a4d4d686SBarry Smith   MPI_Comm     comm;
907a4d4d686SBarry Smith 
908a4d4d686SBarry Smith   PetscFunctionBegin;
9092d0c0e3bSBarry Smith   ierr = PetscObjectGetComm((PetscObject)J,&comm);CHKERRQ(ierr);
910a4d4d686SBarry Smith 
911a4d4d686SBarry Smith   ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr);
912a4d4d686SBarry Smith   /* no context indicates that it is not the "matrix free" matrix type */
913a4d4d686SBarry Smith   if (!ctx) PetscFunctionReturn(0);
91485614651SBarry Smith   ctx->sp = nullsp;
91585614651SBarry Smith   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
916a4d4d686SBarry Smith   PetscFunctionReturn(0);
917a4d4d686SBarry Smith }
918a4d4d686SBarry Smith 
9194a2ae208SSatish Balay #undef __FUNCT__
9204a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetHHistory"
921a4d4d686SBarry Smith /*@
92265f2ba5bSLois Curfman McInnes    MatSNESMFSetHHistory - Sets an array to collect a history of the
92365f2ba5bSLois Curfman McInnes    differencing values (h) computed for the matrix-free product.
924a4d4d686SBarry Smith 
925a4d4d686SBarry Smith    Collective on Mat
926a4d4d686SBarry Smith 
927a4d4d686SBarry Smith    Input Parameters:
928a4d4d686SBarry Smith +  J - the matrix-free matrix context
92965f2ba5bSLois Curfman McInnes .  histroy - space to hold the history
93065f2ba5bSLois Curfman McInnes -  nhistory - number of entries in history, if more entries are generated than
93165f2ba5bSLois Curfman McInnes               nhistory, then the later ones are discarded
932a4d4d686SBarry Smith 
93315091d37SBarry Smith    Level: advanced
93415091d37SBarry Smith 
935a4d4d686SBarry Smith    Notes:
93665f2ba5bSLois Curfman McInnes    Use MatSNESMFResetHHistory() to reset the history counter and collect
93765f2ba5bSLois Curfman McInnes    a new batch of differencing parameters, h.
938a4d4d686SBarry Smith 
939a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history
940a4d4d686SBarry Smith 
9415a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(),
9425a655dc6SBarry Smith           MatSNESMFResetHHistory(),
9435a655dc6SBarry Smith           MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError()
944a4d4d686SBarry Smith 
945a4d4d686SBarry Smith @*/
9465a655dc6SBarry Smith int MatSNESMFSetHHistory(Mat J,Scalar *history,int nhistory)
947a4d4d686SBarry Smith {
948a4d4d686SBarry Smith   int          ierr;
9495a655dc6SBarry Smith   MatSNESMFCtx ctx;
950a4d4d686SBarry Smith 
951a4d4d686SBarry Smith   PetscFunctionBegin;
952a4d4d686SBarry Smith 
953a4d4d686SBarry Smith   ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr);
954a4d4d686SBarry Smith   /* no context indicates that it is not the "matrix free" matrix type */
955a4d4d686SBarry Smith   if (!ctx) PetscFunctionReturn(0);
956a4d4d686SBarry Smith   ctx->historyh    = history;
957a4d4d686SBarry Smith   ctx->maxcurrenth = nhistory;
958a4d4d686SBarry Smith   ctx->currenth    = 0;
959a4d4d686SBarry Smith 
960a4d4d686SBarry Smith   PetscFunctionReturn(0);
961a4d4d686SBarry Smith }
962a4d4d686SBarry Smith 
9634a2ae208SSatish Balay #undef __FUNCT__
9644a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFResetHHistory"
965a4d4d686SBarry Smith /*@
9665a655dc6SBarry Smith    MatSNESMFResetHHistory - Resets the counter to zero to begin
967a4d4d686SBarry Smith    collecting a new set of differencing histories.
968a4d4d686SBarry Smith 
969a4d4d686SBarry Smith    Collective on Mat
970a4d4d686SBarry Smith 
971a4d4d686SBarry Smith    Input Parameters:
972a4d4d686SBarry Smith .  J - the matrix-free matrix context
973a4d4d686SBarry Smith 
97415091d37SBarry Smith    Level: advanced
97515091d37SBarry Smith 
976a4d4d686SBarry Smith    Notes:
97765f2ba5bSLois Curfman McInnes    Use MatSNESMFSetHHistory() to create the original history counter.
978a4d4d686SBarry Smith 
979a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history
980a4d4d686SBarry Smith 
9815a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(),
9825a655dc6SBarry Smith           MatSNESMFSetHHistory(),
9835a655dc6SBarry Smith           MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError()
984a4d4d686SBarry Smith 
985a4d4d686SBarry Smith @*/
9865a655dc6SBarry Smith int MatSNESMFResetHHistory(Mat J)
987a4d4d686SBarry Smith {
988a4d4d686SBarry Smith   int          ierr;
9895a655dc6SBarry Smith   MatSNESMFCtx ctx;
990a4d4d686SBarry Smith 
991a4d4d686SBarry Smith   PetscFunctionBegin;
992a4d4d686SBarry Smith 
993a4d4d686SBarry Smith   ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr);
994a4d4d686SBarry Smith   /* no context indicates that it is not the "matrix free" matrix type */
995a4d4d686SBarry Smith   if (!ctx) PetscFunctionReturn(0);
996be726c96SBarry Smith   ctx->ncurrenth    = 0;
997a4d4d686SBarry Smith 
998a4d4d686SBarry Smith   PetscFunctionReturn(0);
999a4d4d686SBarry Smith }
1000a4d4d686SBarry Smith 
10014a2ae208SSatish Balay #undef __FUNCT__
1002fed8bd04SBarry Smith #define __FUNCT__ "MatSNESMFComputeJacobian"
1003fed8bd04SBarry Smith int MatSNESMFComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
10041d1367b7SBarry Smith {
10051d1367b7SBarry Smith   int ierr;
10061d1367b7SBarry Smith   PetscFunctionBegin;
10071d1367b7SBarry Smith   ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10081d1367b7SBarry Smith   ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10091d1367b7SBarry Smith   PetscFunctionReturn(0);
10101d1367b7SBarry Smith }
10111d1367b7SBarry Smith 
10124a2ae208SSatish Balay #undef __FUNCT__
10134a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetBase"
10141d1367b7SBarry Smith int MatSNESMFSetBase(Mat J,Vec U)
10151d1367b7SBarry Smith {
10163a7fca6bSBarry Smith   int  ierr,(*f)(Mat,Vec);
10171d1367b7SBarry Smith 
10181d1367b7SBarry Smith   PetscFunctionBegin;
10191d1367b7SBarry Smith   PetscValidHeaderSpecific(J,MAT_COOKIE);
10201d1367b7SBarry Smith   PetscValidHeaderSpecific(U,VEC_COOKIE);
1021cf3bea43SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)J,"MatSNESMFSetBase_C",(void (**)())&f);CHKERRQ(ierr);
1022cf3bea43SBarry Smith   if (f) {
1023cf3bea43SBarry Smith     ierr = (*f)(J,U);CHKERRQ(ierr);
102449d4803aSBarry Smith   }
10251d1367b7SBarry Smith   PetscFunctionReturn(0);
10261d1367b7SBarry Smith }
1027*cf57b110SBarry Smith 
1028*cf57b110SBarry Smith 
1029*cf57b110SBarry Smith 
1030*cf57b110SBarry Smith 
1031*cf57b110SBarry Smith 
1032*cf57b110SBarry Smith 
1033*cf57b110SBarry Smith 
1034*cf57b110SBarry Smith 
1035*cf57b110SBarry Smith 
1036