1*7e9d5209SBarry Smith /*$Id: snesmfj.c,v 1.124 2001/07/10 15:01:10 bsmith Exp bsmith $*/ 281e6777dSBarry Smith 39a6cb015SBarry Smith #include "src/snes/snesimpl.h" 4e090d566SSatish Balay #include "src/snes/mf/snesmfj.h" /*I "petscsnes.h" I*/ 5*7e9d5209SBarry Smith #include "src/mat/matimpl.h" 681e6777dSBarry Smith 7b0a32e0cSBarry Smith PetscFList MatSNESMPetscFList = 0; 84c49b128SBarry Smith PetscTruth MatSNESMFRegisterAllCalled = PETSC_FALSE; 9a4d4d686SBarry Smith 104a2ae208SSatish Balay #undef __FUNCT__ 114a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetType" 12fd4bdd07SBarry Smith /*@C 1365f2ba5bSLois Curfman McInnes MatSNESMFSetType - Sets the method that is used to compute the 14b0a32e0cSBarry Smith differencing parameter for finite differene matrix-free formulations. 159a6cb015SBarry Smith 169a6cb015SBarry Smith Input Parameters: 17*7e9d5209SBarry Smith + mat - the "matrix-free" matrix created via MatCreateSNESMF(), or MatCreateMF() 18*7e9d5209SBarry Smith or MatSetType(mat,MATMFFD); 199a6cb015SBarry Smith - ftype - the type requested 209a6cb015SBarry Smith 2115091d37SBarry Smith Level: advanced 2215091d37SBarry Smith 2365f2ba5bSLois Curfman McInnes Notes: 2465f2ba5bSLois Curfman McInnes For example, such routines can compute h for use in 2565f2ba5bSLois Curfman McInnes Jacobian-vector products of the form 2665f2ba5bSLois Curfman McInnes 2765f2ba5bSLois Curfman McInnes F(x+ha) - F(x) 28ef4ad1fdSLois Curfman McInnes F'(u)a ~= ---------------- 2965f2ba5bSLois Curfman McInnes h 3065f2ba5bSLois Curfman McInnes 31f1af5d2fSBarry Smith .seealso: MatCreateSNESMF(), MatSNESMFRegisterDynamic) 329a6cb015SBarry Smith @*/ 33f6a0df18SBarry Smith int MatSNESMFSetType(Mat mat,MatSNESMFType ftype) 34b9fa9cd0SBarry Smith { 355a655dc6SBarry Smith int ierr,(*r)(MatSNESMFCtx); 36*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 376831982aSBarry Smith PetscTruth match; 38a4d4d686SBarry Smith 39a4d4d686SBarry Smith PetscFunctionBegin; 400f5bd95cSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 410f5bd95cSBarry Smith PetscValidCharPointer(ftype); 420f5bd95cSBarry 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; 151*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 152fae171e0SBarry Smith 1533a40ed3dSBarry Smith PetscFunctionBegin; 154b9fa9cd0SBarry Smith ierr = VecDestroy(ctx->w);CHKERRQ(ierr); 1559a6cb015SBarry Smith if (ctx->ops->destroy) {ierr = (*ctx->ops->destroy)(ctx);CHKERRQ(ierr);} 15674637425SBarry Smith if (ctx->sp) {ierr = MatNullSpaceDestroy(ctx->sp);CHKERRQ(ierr);} 1576831982aSBarry Smith PetscHeaderDestroy(ctx); 1583a40ed3dSBarry Smith PetscFunctionReturn(0); 159b9fa9cd0SBarry Smith } 16050361f65SLois Curfman McInnes 1614a2ae208SSatish Balay #undef __FUNCT__ 1624a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFView_Private" 16339e2f89bSBarry Smith /* 1645a655dc6SBarry Smith MatSNESMFView_Private - Views matrix-free parameters. 1658f6e3e37SBarry Smith 16639e2f89bSBarry Smith */ 167b0a32e0cSBarry Smith int MatSNESMFView_Private(Mat J,PetscViewer viewer) 168eb9086c3SLois Curfman McInnes { 169eb9086c3SLois Curfman McInnes int ierr; 170*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)J->data; 1716831982aSBarry Smith PetscTruth isascii; 172eb9086c3SLois Curfman McInnes 1733a40ed3dSBarry Smith PetscFunctionBegin; 174b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 1750f5bd95cSBarry Smith if (isascii) { 176b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," SNES matrix-free approximation:\n");CHKERRQ(ierr); 177b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," err=%g (relative error in function evaluation)\n",ctx->error_rel);CHKERRQ(ierr); 178473c83c3SBarry Smith if (!ctx->type_name) { 179b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," The compute h routine has not yet been set\n");CHKERRQ(ierr); 180473c83c3SBarry Smith } else { 181b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Using %s compute h routine\n",ctx->type_name);CHKERRQ(ierr); 182473c83c3SBarry Smith } 1839a6cb015SBarry Smith if (ctx->ops->view) { 1849a6cb015SBarry Smith ierr = (*ctx->ops->view)(ctx,viewer);CHKERRQ(ierr); 1859a6cb015SBarry Smith } 1865cd90555SBarry Smith } else { 18729bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported for SNES matrix free matrix",((PetscObject)viewer)->type_name); 188eb9086c3SLois Curfman McInnes } 1893a40ed3dSBarry Smith PetscFunctionReturn(0); 190eb9086c3SLois Curfman McInnes } 191eb9086c3SLois Curfman McInnes 1924a2ae208SSatish Balay #undef __FUNCT__ 1934a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFAssemblyEnd_Private" 194be726c96SBarry Smith /* 1955a655dc6SBarry Smith MatSNESMFAssemblyEnd_Private - Resets the ctx->ncurrenth to zero. This 19665f2ba5bSLois Curfman McInnes allows the user to indicate the beginning of a new linear solve by calling 197be726c96SBarry Smith MatAssemblyXXX() on the matrix free matrix. This then allows the 19865f2ba5bSLois Curfman McInnes MatSNESMFCreate_WP() to properly compute ||U|| only the first time 19965f2ba5bSLois Curfman McInnes in the linear solver rather than every time. 200be726c96SBarry Smith */ 201*7e9d5209SBarry Smith int MatSNESMFAssemblyEnd_Private(Mat J,MatAssemblyType mt) 202be726c96SBarry Smith { 203be726c96SBarry Smith int ierr; 204*7e9d5209SBarry Smith MatSNESMFCtx j = (MatSNESMFCtx)J->data; 205be726c96SBarry Smith 206be726c96SBarry Smith PetscFunctionBegin; 2075a655dc6SBarry Smith ierr = MatSNESMFResetHHistory(J);CHKERRQ(ierr); 208b0a32e0cSBarry Smith if (j->usesnes) { 2091d1367b7SBarry Smith ierr = SNESGetSolution(j->snes,&j->current_u);CHKERRQ(ierr); 2101d1367b7SBarry Smith if (j->snes->method_class == SNES_NONLINEAR_EQUATIONS) { 2111d1367b7SBarry Smith ierr = SNESGetFunction(j->snes,&j->current_f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2121d1367b7SBarry Smith } else if (j->snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 2131d1367b7SBarry Smith ierr = SNESGetGradient(j->snes,&j->current_f,PETSC_NULL);CHKERRQ(ierr); 21429bbc08cSBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid method class"); 2151d1367b7SBarry Smith } 216be726c96SBarry Smith PetscFunctionReturn(0); 217be726c96SBarry Smith } 218be726c96SBarry Smith 2194a2ae208SSatish Balay #undef __FUNCT__ 2204a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFMult_Private" 221eb9086c3SLois Curfman McInnes /* 2225a655dc6SBarry Smith MatSNESMFMult_Private - Default matrix-free form for Jacobian-vector 223eb9086c3SLois Curfman McInnes product, y = F'(u)*a: 224a4d4d686SBarry Smith 2259a6cb015SBarry Smith y ~= (F(u + ha) - F(u))/h, 226eb9086c3SLois Curfman McInnes where F = nonlinear function, as set by SNESSetFunction() 227eb9086c3SLois Curfman McInnes u = current iterate 228eb9086c3SLois Curfman McInnes h = difference interval 229eb9086c3SLois Curfman McInnes */ 2305a655dc6SBarry Smith int MatSNESMFMult_Private(Mat mat,Vec a,Vec y) 23139e2f89bSBarry Smith { 232*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 233fae171e0SBarry Smith SNES snes; 234a4d4d686SBarry Smith Scalar h,mone = -1.0; 235fae171e0SBarry Smith Vec w,U,F; 236a305c92eSSatish Balay int ierr,(*eval_fct)(SNES,Vec,Vec)=0; 23739e2f89bSBarry Smith 2383a40ed3dSBarry Smith PetscFunctionBegin; 2399a6cb015SBarry Smith /* We log matrix-free matrix-vector products separately, so that we can 2409a6cb015SBarry Smith separate the performance monitoring from the cases that use conventional 2419a6cb015SBarry Smith storage. We may eventually modify event logging to associate events 2429a6cb015SBarry Smith with particular objects, hence alleviating the more general problem. */ 243b0a32e0cSBarry Smith ierr = PetscLogEventBegin(MAT_MatrixFreeMult,a,y,0,0);CHKERRQ(ierr); 24456cd22aeSBarry Smith 245fae171e0SBarry Smith snes = ctx->snes; 246fae171e0SBarry Smith w = ctx->w; 2471d1367b7SBarry Smith U = ctx->current_u; 24850361f65SLois Curfman McInnes 24985614651SBarry Smith /* 25085614651SBarry Smith Compute differencing parameter 25185614651SBarry Smith */ 2529a6cb015SBarry Smith if (!ctx->ops->compute) { 253b7fd4e64SBarry Smith ierr = MatSNESMFSetType(mat,MATSNESMF_DEFAULT);CHKERRQ(ierr); 2545a655dc6SBarry Smith ierr = MatSNESMFSetFromOptions(mat);CHKERRQ(ierr); 2559a6cb015SBarry Smith } 2569a6cb015SBarry Smith ierr = (*ctx->ops->compute)(ctx,U,a,&h);CHKERRQ(ierr); 257a4d4d686SBarry Smith 258a4d4d686SBarry Smith /* keep a record of the current differencing parameter h */ 259a4d4d686SBarry Smith ctx->currenth = h; 260aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 261b0a32e0cSBarry Smith PetscLogInfo(mat,"MatSNESMFMult_Private:Current differencing parameter: %g + %g i\n",PetscRealPart(h),PetscImaginaryPart(h)); 262a4d4d686SBarry Smith #else 263b0a32e0cSBarry Smith PetscLogInfo(mat,"MatSNESMFMult_Private:Current differencing parameter: %15.12e\n",h); 264a4d4d686SBarry Smith #endif 265a4d4d686SBarry Smith if (ctx->historyh && ctx->ncurrenth < ctx->maxcurrenth) { 26685614651SBarry Smith ctx->historyh[ctx->ncurrenth] = h; 267a4d4d686SBarry Smith } 26885614651SBarry Smith ctx->ncurrenth++; 269a4d4d686SBarry Smith 27085614651SBarry Smith /* w = u + ha */ 271a4d4d686SBarry Smith ierr = VecWAXPY(&h,a,U,w);CHKERRQ(ierr); 27285614651SBarry Smith 273b0a32e0cSBarry Smith if (ctx->usesnes) { 27485614651SBarry Smith if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 27585614651SBarry Smith eval_fct = SNESComputeFunction; 27685614651SBarry Smith } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 27785614651SBarry Smith eval_fct = SNESComputeGradient; 27829bbc08cSBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid method class"); 2791d1367b7SBarry Smith F = ctx->current_f; 28029bbc08cSBarry Smith if (!F) SETERRQ(1,"You must call MatAssembly() even on matrix-free matrices"); 28139903ad8SBarry Smith ierr = (*eval_fct)(snes,w,y);CHKERRQ(ierr); 28285614651SBarry Smith } else { 28385614651SBarry Smith F = ctx->funcvec; 28485614651SBarry Smith /* compute func(U) as base for differencing */ 28585614651SBarry Smith if (ctx->ncurrenth == 1) { 28685614651SBarry Smith ierr = (*ctx->func)(snes,U,F,ctx->funcctx);CHKERRQ(ierr); 28785614651SBarry Smith } 28885614651SBarry Smith ierr = (*ctx->func)(snes,w,y,ctx->funcctx);CHKERRQ(ierr); 28985614651SBarry Smith } 290a4d4d686SBarry Smith 291a4d4d686SBarry Smith ierr = VecAXPY(&mone,F,y);CHKERRQ(ierr); 292a4d4d686SBarry Smith h = 1.0/h; 293a4d4d686SBarry Smith ierr = VecScale(&h,y);CHKERRQ(ierr); 29474637425SBarry Smith if (ctx->sp) {ierr = MatNullSpaceRemove(ctx->sp,y,PETSC_NULL);CHKERRQ(ierr);} 295a4d4d686SBarry Smith 296b0a32e0cSBarry Smith ierr = PetscLogEventEnd(MAT_MatrixFreeMult,a,y,0,0);CHKERRQ(ierr); 297a4d4d686SBarry Smith PetscFunctionReturn(0); 298a4d4d686SBarry Smith } 299a4d4d686SBarry Smith 3004a2ae208SSatish Balay #undef __FUNCT__ 301cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFGetDiagonal_Private" 302cf57b110SBarry Smith /* 303cf57b110SBarry Smith MatSNESMFGetDiagonal_Private - Gets the diagonal for a matrix free matrix 304cf57b110SBarry Smith 305cf57b110SBarry Smith y ~= (F(u + ha) - F(u))/h, 306cf57b110SBarry Smith where F = nonlinear function, as set by SNESSetFunction() 307cf57b110SBarry Smith u = current iterate 308cf57b110SBarry Smith h = difference interval 309cf57b110SBarry Smith */ 310cf57b110SBarry Smith int MatSNESMFGetDiagonal_Private(Mat mat,Vec a) 311cf57b110SBarry Smith { 312*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 313cf57b110SBarry Smith Scalar h,h1,mone = -1.0,*aa,*ww,v,epsilon = 1.e-8,umin = 1.e-6; 314cf57b110SBarry Smith Vec w,U,F; 315cf57b110SBarry Smith int i,ierr,rstart,rend; 316cf57b110SBarry Smith 317cf57b110SBarry Smith PetscFunctionBegin; 318cf57b110SBarry Smith if (!ctx->funci) { 319cf57b110SBarry Smith SETERRQ(1,"Requirers calling MatSNESMFSetFunctioni() first"); 320cf57b110SBarry Smith } 321cf57b110SBarry Smith 322cf57b110SBarry Smith w = ctx->w; 323cf57b110SBarry Smith U = ctx->current_u; 324cf57b110SBarry Smith ierr = (*ctx->func)(0,U,a,ctx->funcctx);CHKERRQ(ierr); 325cf57b110SBarry Smith ierr = (*ctx->funcisetbase)(U,ctx->funcctx);CHKERRQ(ierr); 326cf57b110SBarry Smith ierr = VecCopy(U,w);CHKERRQ(ierr); 327cf57b110SBarry Smith 328cf57b110SBarry Smith ierr = VecGetOwnershipRange(a,&rstart,&rend);CHKERRQ(ierr); 329cf57b110SBarry Smith ierr = VecGetArray(a,&aa);CHKERRQ(ierr); 330cf57b110SBarry Smith for (i=rstart; i<rend; i++) { 331cf57b110SBarry Smith ierr = VecGetArray(w,&ww);CHKERRQ(ierr); 332cf57b110SBarry Smith h = ww[i-rstart]; 333cf57b110SBarry Smith if (h == 0.0) h = 1.0; 334cf57b110SBarry Smith #if !defined(PETSC_USE_COMPLEX) 335cf57b110SBarry Smith if (h < umin && h >= 0.0) h = umin; 336cf57b110SBarry Smith else if (h < 0.0 && h > -umin) h = -umin; 337cf57b110SBarry Smith #else 338cf57b110SBarry Smith if (PetscAbsScalar(h) < umin && PetscRealPart(h) >= 0.0) h = umin; 339cf57b110SBarry Smith else if (PetscRealPart(h) < 0.0 && PetscAbsScalar(h) < umin) h = -umin; 340cf57b110SBarry Smith #endif 341cf57b110SBarry Smith h *= epsilon; 342cf57b110SBarry Smith 343cf57b110SBarry Smith ww[i-rstart] += h; 344cf57b110SBarry Smith ierr = VecRestoreArray(w,&ww);CHKERRQ(ierr); 345cf57b110SBarry Smith ierr = (*ctx->funci)(i,w,&v,ctx->funcctx);CHKERRQ(ierr); 346cf57b110SBarry Smith aa[i-rstart] = (v - aa[i-rstart])/h; 347cf57b110SBarry Smith ierr = VecGetArray(w,&ww);CHKERRQ(ierr); 348cf57b110SBarry Smith ww[i-rstart] -= h; 349cf57b110SBarry Smith ierr = VecRestoreArray(w,&ww);CHKERRQ(ierr); 350cf57b110SBarry Smith } 351cf57b110SBarry Smith ierr = VecRestoreArray(a,&aa);CHKERRQ(ierr); 352cf57b110SBarry Smith PetscFunctionReturn(0); 353cf57b110SBarry Smith } 354cf57b110SBarry Smith 355cf57b110SBarry Smith #undef __FUNCT__ 3564a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF" 357a4d4d686SBarry Smith /*@C 35865f2ba5bSLois Curfman McInnes MatCreateSNESMF - Creates a matrix-free matrix context for use with 35965f2ba5bSLois Curfman McInnes a SNES solver. This matrix can be used as the Jacobian argument for 36065f2ba5bSLois Curfman McInnes the routine SNESSetJacobian(). 361a4d4d686SBarry Smith 362a4d4d686SBarry Smith Collective on SNES and Vec 363a4d4d686SBarry Smith 364a4d4d686SBarry Smith Input Parameters: 365a4d4d686SBarry Smith + snes - the SNES context 366a4d4d686SBarry Smith - x - vector where SNES solution is to be stored. 367a4d4d686SBarry Smith 368a4d4d686SBarry Smith Output Parameter: 369a4d4d686SBarry Smith . J - the matrix-free matrix 370a4d4d686SBarry Smith 37115091d37SBarry Smith Level: advanced 37215091d37SBarry Smith 373a4d4d686SBarry Smith Notes: 374a4d4d686SBarry Smith The matrix-free matrix context merely contains the function pointers 375a4d4d686SBarry Smith and work space for performing finite difference approximations of 37665f2ba5bSLois Curfman McInnes Jacobian-vector products, F'(u)*a, 3779a6cb015SBarry Smith 3789a6cb015SBarry Smith The default code uses the following approach to compute h 379a4d4d686SBarry Smith 380a4d4d686SBarry Smith .vb 38165f2ba5bSLois Curfman McInnes F'(u)*a = [F(u+h*a) - F(u)]/h where 382a4d4d686SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 383a4d4d686SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 otherwise 384a4d4d686SBarry Smith where 385a4d4d686SBarry Smith error_rel = square root of relative error in function evaluation 386a4d4d686SBarry Smith umin = minimum iterate parameter 387a4d4d686SBarry Smith .ve 388a4d4d686SBarry Smith 3895a655dc6SBarry Smith The user can set the error_rel via MatSNESMFSetFunctionError() and 39065f2ba5bSLois Curfman McInnes umin via MatSNESMFDefaultSetUmin(); see the nonlinear solvers chapter 39165f2ba5bSLois Curfman McInnes of the users manual for details. 392a4d4d686SBarry Smith 393a4d4d686SBarry Smith The user should call MatDestroy() when finished with the matrix-free 394a4d4d686SBarry Smith matrix context. 395a4d4d686SBarry Smith 396a4d4d686SBarry Smith Options Database Keys: 397a4d4d686SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 3989a6cb015SBarry Smith . -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only) 399a4d4d686SBarry Smith - -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h 400a4d4d686SBarry Smith 401a4d4d686SBarry Smith .keywords: SNES, default, matrix-free, create, matrix 402a4d4d686SBarry Smith 4035a655dc6SBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError(), MatSNESMFDefaultSetUmin() 4041d1367b7SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), MatCreateMF(), 405fed8bd04SBarry Smith MatSNESMFGetH(),MatSNESMFKSPMonitor(), MatSNESMFRegisterDynamic), MatSNESMFComputeJacobian() 406a4d4d686SBarry Smith 407a4d4d686SBarry Smith @*/ 4085a655dc6SBarry Smith int MatCreateSNESMF(SNES snes,Vec x,Mat *J) 409a4d4d686SBarry Smith { 4101d1367b7SBarry Smith MatSNESMFCtx mfctx; 4111d1367b7SBarry Smith int ierr; 4121d1367b7SBarry Smith 4131d1367b7SBarry Smith PetscFunctionBegin; 4141d1367b7SBarry Smith ierr = MatCreateMF(x,J);CHKERRQ(ierr); 415*7e9d5209SBarry Smith 416*7e9d5209SBarry Smith mfctx = (MatSNESMFCtx)(*J)->data; 4171d1367b7SBarry Smith mfctx->snes = snes; 418b0a32e0cSBarry Smith mfctx->usesnes = PETSC_TRUE; 419b0a32e0cSBarry Smith PetscLogObjectParent(snes,*J); 4201d1367b7SBarry Smith PetscFunctionReturn(0); 4211d1367b7SBarry Smith } 4221d1367b7SBarry Smith 423cf3bea43SBarry Smith EXTERN_C_BEGIN 424cf3bea43SBarry Smith #undef __FUNCT__ 425cf3bea43SBarry Smith #define __FUNCT__ "MatSNESMFSetBase_FD" 426cf3bea43SBarry Smith int MatSNESMFSetBase_FD(Mat J,Vec U) 427cf3bea43SBarry Smith { 428cf3bea43SBarry Smith int ierr; 429*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)J->data; 430cf3bea43SBarry Smith 431cf3bea43SBarry Smith PetscFunctionBegin; 432cf3bea43SBarry Smith ierr = MatSNESMFResetHHistory(J);CHKERRQ(ierr); 433cf3bea43SBarry Smith ctx->current_u = U; 434cf3bea43SBarry Smith ctx->usesnes = PETSC_FALSE; 435cf3bea43SBarry Smith PetscFunctionReturn(0); 436cf3bea43SBarry Smith } 437cf3bea43SBarry Smith EXTERN_C_END 438cf3bea43SBarry Smith 4394a2ae208SSatish Balay #undef __FUNCT__ 440*7e9d5209SBarry Smith #define __FUNCT__ "MatSNESMFSetFromOptions" 441*7e9d5209SBarry Smith /*@ 442*7e9d5209SBarry Smith MatSNESMFSetFromOptions - Sets the MatSNESMF options from the command line 443*7e9d5209SBarry Smith parameter. 444*7e9d5209SBarry Smith 445*7e9d5209SBarry Smith Collective on Mat 446*7e9d5209SBarry Smith 447*7e9d5209SBarry Smith Input Parameters: 448*7e9d5209SBarry Smith . mat - the matrix obtained with MatCreateSNESMF() 449*7e9d5209SBarry Smith 450*7e9d5209SBarry Smith Options Database Keys: 451*7e9d5209SBarry Smith + -snes_mf_type - <default,wp> 452*7e9d5209SBarry Smith - -snes_mf_err - square root of estimated relative error in function evaluation 453*7e9d5209SBarry Smith - -snes_mf_period - how often h is recomputed, defaults to 1, everytime 454*7e9d5209SBarry Smith 455*7e9d5209SBarry Smith Level: advanced 456*7e9d5209SBarry Smith 457*7e9d5209SBarry Smith .keywords: SNES, matrix-free, parameters 458*7e9d5209SBarry Smith 459*7e9d5209SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(), 460*7e9d5209SBarry Smith MatSNESMFResetHHistory(), MatSNESMFKSPMonitor() 461*7e9d5209SBarry Smith @*/ 462*7e9d5209SBarry Smith int MatSNESMFSetFromOptions(Mat mat) 463*7e9d5209SBarry Smith { 464*7e9d5209SBarry Smith MatSNESMFCtx mfctx = (MatSNESMFCtx)mat->data; 465*7e9d5209SBarry Smith int ierr; 466*7e9d5209SBarry Smith PetscTruth flg; 467*7e9d5209SBarry Smith char ftype[256]; 468*7e9d5209SBarry Smith 469*7e9d5209SBarry Smith PetscFunctionBegin; 470*7e9d5209SBarry Smith if (mfctx) { 471*7e9d5209SBarry Smith if (!MatSNESMFRegisterAllCalled) {ierr = MatSNESMFRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 472*7e9d5209SBarry Smith 473*7e9d5209SBarry Smith ierr = PetscOptionsBegin(mfctx->comm,mfctx->prefix,"Set matrix free computation parameters","MatSNESMF");CHKERRQ(ierr); 474*7e9d5209SBarry Smith ierr = PetscOptionsList("-snes_mf_type","Matrix free type","MatSNESMFSetType",MatSNESMPetscFList,mfctx->type_name,ftype,256,&flg);CHKERRQ(ierr); 475*7e9d5209SBarry Smith if (flg) { 476*7e9d5209SBarry Smith ierr = MatSNESMFSetType(mat,ftype);CHKERRQ(ierr); 477*7e9d5209SBarry Smith } 478*7e9d5209SBarry Smith 479*7e9d5209SBarry Smith ierr = PetscOptionsDouble("-snes_mf_err","set sqrt relative error in function","MatSNESMFSetFunctionError",mfctx->error_rel,&mfctx->error_rel,0);CHKERRQ(ierr); 480*7e9d5209SBarry Smith ierr = PetscOptionsInt("-snes_mf_period","how often h is recomputed","MatSNESMFSetPeriod",mfctx->recomputeperiod,&mfctx->recomputeperiod,0);CHKERRQ(ierr); 481*7e9d5209SBarry Smith if (mfctx->snes) { 482*7e9d5209SBarry Smith ierr = PetscOptionsName("-snes_mf_ksp_monitor","Monitor matrix-free parameters","MatSNESMFKSPMonitor",&flg);CHKERRQ(ierr); 483*7e9d5209SBarry Smith if (flg) { 484*7e9d5209SBarry Smith SLES sles; 485*7e9d5209SBarry Smith KSP ksp; 486*7e9d5209SBarry Smith ierr = SNESGetSLES(mfctx->snes,&sles);CHKERRQ(ierr); 487*7e9d5209SBarry Smith ierr = SLESGetKSP(sles,&ksp);CHKERRQ(ierr); 488*7e9d5209SBarry Smith ierr = KSPSetMonitor(ksp,MatSNESMFKSPMonitor,PETSC_NULL,0);CHKERRQ(ierr); 489*7e9d5209SBarry Smith } 490*7e9d5209SBarry Smith } 491*7e9d5209SBarry Smith if (mfctx->ops->setfromoptions) { 492*7e9d5209SBarry Smith ierr = (*mfctx->ops->setfromoptions)(mfctx);CHKERRQ(ierr); 493*7e9d5209SBarry Smith } 494*7e9d5209SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 495*7e9d5209SBarry Smith 496*7e9d5209SBarry Smith } 497*7e9d5209SBarry Smith PetscFunctionReturn(0); 498*7e9d5209SBarry Smith } 499*7e9d5209SBarry Smith 500*7e9d5209SBarry Smith #undef __FUNCT__ 501*7e9d5209SBarry Smith #define __FUNCT__ "MatCreate_MFFD" 502*7e9d5209SBarry Smith EXTERN_C_BEGIN 503*7e9d5209SBarry Smith int MatCreate_MFFD(Mat A) 504*7e9d5209SBarry Smith { 505*7e9d5209SBarry Smith PetscFunctionBegin; 506*7e9d5209SBarry Smith MPI_Comm comm; 507*7e9d5209SBarry Smith MatSNESMFCtx mfctx; 508*7e9d5209SBarry Smith int n,nloc,ierr; 509*7e9d5209SBarry Smith 510*7e9d5209SBarry Smith PetscFunctionBegin; 511*7e9d5209SBarry Smith ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 512*7e9d5209SBarry Smith PetscHeaderCreate(mfctx,_p_MatSNESMFCtx,struct _MFOps,MATSNESMFCTX_COOKIE,0,"SNESMF",comm,MatSNESMFDestroy_Private,MatSNESMFView_Private); 513*7e9d5209SBarry Smith PetscLogObjectCreate(mfctx); 514*7e9d5209SBarry Smith mfctx->sp = 0; 515*7e9d5209SBarry Smith mfctx->snes = 0; 516*7e9d5209SBarry Smith mfctx->error_rel = 1.e-8; /* assumes PetscReal precision */ 517*7e9d5209SBarry Smith mfctx->recomputeperiod = 1; 518*7e9d5209SBarry Smith mfctx->count = 0; 519*7e9d5209SBarry Smith mfctx->currenth = 0.0; 520*7e9d5209SBarry Smith mfctx->historyh = PETSC_NULL; 521*7e9d5209SBarry Smith mfctx->ncurrenth = 0; 522*7e9d5209SBarry Smith mfctx->maxcurrenth = 0; 523*7e9d5209SBarry Smith mfctx->type_name = 0; 524*7e9d5209SBarry Smith mfctx->usesnes = PETSC_FALSE; 525*7e9d5209SBarry Smith 526*7e9d5209SBarry Smith /* 527*7e9d5209SBarry Smith Create the empty data structure to contain compute-h routines. 528*7e9d5209SBarry Smith These will be filled in below from the command line options or 529*7e9d5209SBarry Smith a later call with MatSNESMFSetType() or if that is not called 530*7e9d5209SBarry Smith then it will default in the first use of MatSNESMFMult_private() 531*7e9d5209SBarry Smith */ 532*7e9d5209SBarry Smith mfctx->ops->compute = 0; 533*7e9d5209SBarry Smith mfctx->ops->destroy = 0; 534*7e9d5209SBarry Smith mfctx->ops->view = 0; 535*7e9d5209SBarry Smith mfctx->ops->setfromoptions = 0; 536*7e9d5209SBarry Smith mfctx->hctx = 0; 537*7e9d5209SBarry Smith 538*7e9d5209SBarry Smith mfctx->func = 0; 539*7e9d5209SBarry Smith mfctx->funcctx = 0; 540*7e9d5209SBarry Smith mfctx->funcvec = 0; 541*7e9d5209SBarry Smith 542*7e9d5209SBarry Smith ierr = VecDuplicate(x,&mfctx->w);CHKERRQ(ierr); 543*7e9d5209SBarry Smith ierr = VecGetSize(mfctx->w,&n);CHKERRQ(ierr); 544*7e9d5209SBarry Smith ierr = VecGetLocalSize(mfctx->w,&nloc);CHKERRQ(ierr); 545*7e9d5209SBarry Smith ierr = MatCreate(comm,nloc,nloc,n,n,J);CHKERRQ(ierr); 546*7e9d5209SBarry Smith (*J)->data = mfctx; 547*7e9d5209SBarry Smith 548*7e9d5209SBarry Smith (*J)->ops->mult = MatSNESMFMult_Private; 549*7e9d5209SBarry Smith (*J)->ops->destroy = MatSNESMFDestroy_Private; 550*7e9d5209SBarry Smith (*J)->ops->view = MatSNESMFView_Private; 551*7e9d5209SBarry Smith (*J)->ops->assemblyend = MatSNESMFAssemblyEnd_Private; 552*7e9d5209SBarry Smith (*J)->ops->getdiagonal = MatSNESMFGetDiagonal_Private; 553*7e9d5209SBarry Smith (*J)->ops->setfromoptions = MatSNESMFSetFromOptions; 554*7e9d5209SBarry Smith 555*7e9d5209SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)*J,MATMFFD);CHKERRQ(ierr); 556*7e9d5209SBarry Smith 557*7e9d5209SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatSNESMFSetBase_C","MatSNESMFSetBase_FD",MatSNESMFSetBase_FD);CHKERRQ(ierr); 558*7e9d5209SBarry Smith PetscLogObjectParent(*J,mfctx->w); 559*7e9d5209SBarry Smith 560*7e9d5209SBarry Smith PetscFunctionReturn(0); 561*7e9d5209SBarry Smith } 562*7e9d5209SBarry Smith 563*7e9d5209SBarry Smith EXTERN_C_END 564*7e9d5209SBarry Smith 565*7e9d5209SBarry Smith #undef __FUNCT__ 5664a2ae208SSatish Balay #define __FUNCT__ "MatCreateMF" 5671d1367b7SBarry Smith /*@C 5681d1367b7SBarry Smith MatCreateMF - Creates a matrix-free matrix. See also MatCreateSNESMF() 5691d1367b7SBarry Smith 5701d1367b7SBarry Smith Collective on Vec 5711d1367b7SBarry Smith 5721d1367b7SBarry Smith Input Parameters: 5731d1367b7SBarry Smith . x - vector that defines layout of the vectors and matrices 5741d1367b7SBarry Smith 5751d1367b7SBarry Smith Output Parameter: 5761d1367b7SBarry Smith . J - the matrix-free matrix 5771d1367b7SBarry Smith 5781d1367b7SBarry Smith Level: advanced 5791d1367b7SBarry Smith 5801d1367b7SBarry Smith Notes: 5811d1367b7SBarry Smith The matrix-free matrix context merely contains the function pointers 5821d1367b7SBarry Smith and work space for performing finite difference approximations of 5831d1367b7SBarry Smith Jacobian-vector products, F'(u)*a, 5841d1367b7SBarry Smith 5851d1367b7SBarry Smith The default code uses the following approach to compute h 5861d1367b7SBarry Smith 5871d1367b7SBarry Smith .vb 5881d1367b7SBarry Smith F'(u)*a = [F(u+h*a) - F(u)]/h where 5891d1367b7SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 5901d1367b7SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 otherwise 5911d1367b7SBarry Smith where 5921d1367b7SBarry Smith error_rel = square root of relative error in function evaluation 5931d1367b7SBarry Smith umin = minimum iterate parameter 5941d1367b7SBarry Smith .ve 5951d1367b7SBarry Smith 5961d1367b7SBarry Smith The user can set the error_rel via MatSNESMFSetFunctionError() and 5971d1367b7SBarry Smith umin via MatSNESMFDefaultSetUmin(); see the nonlinear solvers chapter 5981d1367b7SBarry Smith of the users manual for details. 5991d1367b7SBarry Smith 6001d1367b7SBarry Smith The user should call MatDestroy() when finished with the matrix-free 6011d1367b7SBarry Smith matrix context. 6021d1367b7SBarry Smith 6031d1367b7SBarry Smith Options Database Keys: 6041d1367b7SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 6051d1367b7SBarry Smith . -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only) 6061d1367b7SBarry Smith - -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h 6071d1367b7SBarry Smith 6081d1367b7SBarry Smith .keywords: default, matrix-free, create, matrix 6091d1367b7SBarry Smith 6101d1367b7SBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError(), MatSNESMFDefaultSetUmin() 6111d1367b7SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), MatCreateSNESMF(), 612fed8bd04SBarry Smith MatSNESMFGetH(),MatSNESMFKSPMonitor(), MatSNESMFRegisterDynamic),, MatSNESMFComputeJacobian() 6131d1367b7SBarry Smith 6141d1367b7SBarry Smith @*/ 6151d1367b7SBarry Smith int MatCreateMF(Vec x,Mat *J) 6161d1367b7SBarry Smith { 617a4d4d686SBarry Smith MPI_Comm comm; 6185a655dc6SBarry Smith MatSNESMFCtx mfctx; 6199a6cb015SBarry Smith int n,nloc,ierr; 620a4d4d686SBarry Smith 621a4d4d686SBarry Smith PetscFunctionBegin; 6221d1367b7SBarry Smith ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 6231d1367b7SBarry Smith PetscHeaderCreate(mfctx,_p_MatSNESMFCtx,struct _MFOps,MATSNESMFCTX_COOKIE,0,"SNESMF",comm,MatSNESMFDestroy_Private,MatSNESMFView_Private); 624b0a32e0cSBarry Smith PetscLogObjectCreate(mfctx); 625a4d4d686SBarry Smith mfctx->sp = 0; 6261d1367b7SBarry Smith mfctx->snes = 0; 627329f5518SBarry Smith mfctx->error_rel = 1.e-8; /* assumes PetscReal precision */ 628329f5518SBarry Smith mfctx->recomputeperiod = 1; 629329f5518SBarry Smith mfctx->count = 0; 630a4d4d686SBarry Smith mfctx->currenth = 0.0; 631a4d4d686SBarry Smith mfctx->historyh = PETSC_NULL; 632a4d4d686SBarry Smith mfctx->ncurrenth = 0; 633a4d4d686SBarry Smith mfctx->maxcurrenth = 0; 6346831982aSBarry Smith mfctx->type_name = 0; 635b0a32e0cSBarry Smith mfctx->usesnes = PETSC_FALSE; 636a4d4d686SBarry Smith 6379a6cb015SBarry Smith /* 6389a6cb015SBarry Smith Create the empty data structure to contain compute-h routines. 6399a6cb015SBarry Smith These will be filled in below from the command line options or 6405a655dc6SBarry Smith a later call with MatSNESMFSetType() or if that is not called 6415a655dc6SBarry Smith then it will default in the first use of MatSNESMFMult_private() 6429a6cb015SBarry Smith */ 6439a6cb015SBarry Smith mfctx->ops->compute = 0; 6449a6cb015SBarry Smith mfctx->ops->destroy = 0; 6459a6cb015SBarry Smith mfctx->ops->view = 0; 6469a6cb015SBarry Smith mfctx->ops->setfromoptions = 0; 6479a6cb015SBarry Smith mfctx->hctx = 0; 6489a6cb015SBarry Smith 64985614651SBarry Smith mfctx->func = 0; 65085614651SBarry Smith mfctx->funcctx = 0; 65185614651SBarry Smith mfctx->funcvec = 0; 65285614651SBarry Smith 653a4d4d686SBarry Smith ierr = VecDuplicate(x,&mfctx->w);CHKERRQ(ierr); 6541d1367b7SBarry Smith ierr = VecGetSize(mfctx->w,&n);CHKERRQ(ierr); 6551d1367b7SBarry Smith ierr = VecGetLocalSize(mfctx->w,&nloc);CHKERRQ(ierr); 656*7e9d5209SBarry Smith ierr = MatCreate(comm,nloc,nloc,n,n,J);CHKERRQ(ierr); 657*7e9d5209SBarry Smith (*J)->data = mfctx; 658*7e9d5209SBarry Smith 659*7e9d5209SBarry Smith (*J)->ops->mult = MatSNESMFMult_Private; 660*7e9d5209SBarry Smith (*J)->ops->destroy = MatSNESMFDestroy_Private; 661*7e9d5209SBarry Smith (*J)->ops->view = MatSNESMFView_Private; 662*7e9d5209SBarry Smith (*J)->ops->assemblyend = MatSNESMFAssemblyEnd_Private; 663*7e9d5209SBarry Smith (*J)->ops->getdiagonal = MatSNESMFGetDiagonal_Private; 664*7e9d5209SBarry Smith (*J)->ops->setfromoptions = MatSNESMFSetFromOptions; 665*7e9d5209SBarry Smith 666*7e9d5209SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)*J,MATMFFD);CHKERRQ(ierr); 667*7e9d5209SBarry Smith 668cf3bea43SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatSNESMFSetBase_C","MatSNESMFSetBase_FD",MatSNESMFSetBase_FD);CHKERRQ(ierr); 669b0a32e0cSBarry Smith PetscLogObjectParent(*J,mfctx->w); 6709a6cb015SBarry Smith 6719a6cb015SBarry Smith mfctx->mat = *J; 6729a6cb015SBarry Smith PetscFunctionReturn(0); 6739a6cb015SBarry Smith } 6749a6cb015SBarry Smith 675a4d4d686SBarry Smith 6764a2ae208SSatish Balay #undef __FUNCT__ 6774a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFGetH" 678a4d4d686SBarry Smith /*@ 67965f2ba5bSLois Curfman McInnes MatSNESMFGetH - Gets the last value that was used as the differencing 680a4d4d686SBarry Smith parameter. 681a4d4d686SBarry Smith 682a4d4d686SBarry Smith Not Collective 683a4d4d686SBarry Smith 684a4d4d686SBarry Smith Input Parameters: 6855a655dc6SBarry Smith . mat - the matrix obtained with MatCreateSNESMF() 686a4d4d686SBarry Smith 687a4d4d686SBarry Smith Output Paramter: 688a4d4d686SBarry Smith . h - the differencing step size 689a4d4d686SBarry Smith 69015091d37SBarry Smith Level: advanced 69115091d37SBarry Smith 692a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters 693a4d4d686SBarry Smith 6945a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(), 6955a655dc6SBarry Smith MatSNESMFResetHHistory(),MatSNESMFKSPMonitor() 696a4d4d686SBarry Smith @*/ 6975a655dc6SBarry Smith int MatSNESMFGetH(Mat mat,Scalar *h) 698a4d4d686SBarry Smith { 699*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 700a4d4d686SBarry Smith int ierr; 701a4d4d686SBarry Smith 702a4d4d686SBarry Smith PetscFunctionBegin; 703a4d4d686SBarry Smith *h = ctx->currenth; 704a4d4d686SBarry Smith PetscFunctionReturn(0); 705a4d4d686SBarry Smith } 706a4d4d686SBarry Smith 7074a2ae208SSatish Balay #undef __FUNCT__ 7084a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFKSPMonitor" 709a4d4d686SBarry Smith /* 7105a655dc6SBarry Smith MatSNESMFKSPMonitor - A KSP monitor for use with the default PETSc 71165f2ba5bSLois Curfman McInnes SNES matrix free routines. Prints the differencing parameter used at 71265f2ba5bSLois Curfman McInnes each step. 713a4d4d686SBarry Smith */ 714329f5518SBarry Smith int MatSNESMFKSPMonitor(KSP ksp,int n,PetscReal rnorm,void *dummy) 715a4d4d686SBarry Smith { 716a4d4d686SBarry Smith PC pc; 7175a655dc6SBarry Smith MatSNESMFCtx ctx; 718a4d4d686SBarry Smith int ierr; 719a4d4d686SBarry Smith Mat mat; 720a4d4d686SBarry Smith MPI_Comm comm; 721a4d4d686SBarry Smith PetscTruth nonzeroinitialguess; 722a4d4d686SBarry Smith 723a4d4d686SBarry Smith PetscFunctionBegin; 724a4d4d686SBarry Smith ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr); 725a4d4d686SBarry Smith ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 726a4d4d686SBarry Smith ierr = KSPGetInitialGuessNonzero(ksp,&nonzeroinitialguess);CHKERRQ(ierr); 727a4d4d686SBarry Smith ierr = PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 728*7e9d5209SBarry Smith ctx = (MatSNESMFCtx)mat->data; 729*7e9d5209SBarry Smith 730a4d4d686SBarry Smith if (n > 0 || nonzeroinitialguess) { 731aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 732d132466eSBarry Smith ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g + %g i\n",n,rnorm, 733329f5518SBarry Smith PetscRealPart(ctx->currenth),PetscImaginaryPart(ctx->currenth));CHKERRQ(ierr); 734a4d4d686SBarry Smith #else 735d132466eSBarry Smith ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g \n",n,rnorm,ctx->currenth);CHKERRQ(ierr); 736a4d4d686SBarry Smith #endif 737a4d4d686SBarry Smith } else { 738d132466eSBarry Smith ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e\n",n,rnorm);CHKERRQ(ierr); 739a4d4d686SBarry Smith } 740a4d4d686SBarry Smith PetscFunctionReturn(0); 741a4d4d686SBarry Smith } 742a4d4d686SBarry Smith 7434a2ae208SSatish Balay #undef __FUNCT__ 7444a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetFunction" 74585614651SBarry Smith /*@C 74685614651SBarry Smith MatSNESMFSetFunction - Sets the function used in applying the matrix free. 74785614651SBarry Smith 74885614651SBarry Smith Collective on Mat 74985614651SBarry Smith 75085614651SBarry Smith Input Parameters: 75185614651SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 75285614651SBarry Smith . v - workspace vector 75385614651SBarry Smith . func - the function to use 75485614651SBarry Smith - funcctx - optional function context passed to function 75585614651SBarry Smith 75685614651SBarry Smith Level: advanced 75785614651SBarry Smith 75885614651SBarry Smith Notes: 75985614651SBarry Smith If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free 76085614651SBarry Smith matrix inside your compute Jacobian routine 76185614651SBarry Smith 76285614651SBarry Smith If this is not set then it will use the function set with SNESSetFunction() 76385614651SBarry Smith 76485614651SBarry Smith .keywords: SNES, matrix-free, function 76585614651SBarry Smith 76685614651SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 76785614651SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 76885614651SBarry Smith MatSNESMFKSPMonitor(), SNESetFunction() 76985614651SBarry Smith @*/ 77085614651SBarry Smith int MatSNESMFSetFunction(Mat mat,Vec v,int (*func)(SNES,Vec,Vec,void *),void *funcctx) 77185614651SBarry Smith { 772*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 77385614651SBarry Smith int ierr; 77485614651SBarry Smith 77585614651SBarry Smith PetscFunctionBegin; 77685614651SBarry Smith ctx->func = func; 77785614651SBarry Smith ctx->funcctx = funcctx; 77885614651SBarry Smith ctx->funcvec = v; 77985614651SBarry Smith PetscFunctionReturn(0); 78085614651SBarry Smith } 78185614651SBarry Smith 782cf57b110SBarry Smith #undef __FUNCT__ 783cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioni" 784cf57b110SBarry Smith /*@C 785cf57b110SBarry Smith MatSNESMFSetFunctioni - Sets the function for a single component 786cf57b110SBarry Smith 787cf57b110SBarry Smith Collective on Mat 788cf57b110SBarry Smith 789cf57b110SBarry Smith Input Parameters: 790cf57b110SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 791cf57b110SBarry Smith - funci - the function to use 792cf57b110SBarry Smith 793cf57b110SBarry Smith Level: advanced 794cf57b110SBarry Smith 795cf57b110SBarry Smith Notes: 796cf57b110SBarry Smith If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free 797cf57b110SBarry Smith matrix inside your compute Jacobian routine 798cf57b110SBarry Smith 799cf57b110SBarry Smith 800cf57b110SBarry Smith .keywords: SNES, matrix-free, function 801cf57b110SBarry Smith 802cf57b110SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 803cf57b110SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 804cf57b110SBarry Smith MatSNESMFKSPMonitor(), SNESetFunction() 805cf57b110SBarry Smith @*/ 806cf57b110SBarry Smith int MatSNESMFSetFunctioni(Mat mat,int (*funci)(int,Vec,Scalar*,void *)) 807cf57b110SBarry Smith { 808*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 809cf57b110SBarry Smith int ierr; 810cf57b110SBarry Smith 811cf57b110SBarry Smith PetscFunctionBegin; 812cf57b110SBarry Smith ctx->funci = funci; 813cf57b110SBarry Smith PetscFunctionReturn(0); 814cf57b110SBarry Smith } 815cf57b110SBarry Smith 816cf57b110SBarry Smith #undef __FUNCT__ 817cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioniBase" 818cf57b110SBarry Smith /*@C 819cf57b110SBarry Smith MatSNESMFSetFunctioniBase - Sets the base vector for a single component function evaluation 820cf57b110SBarry Smith 821cf57b110SBarry Smith Collective on Mat 822cf57b110SBarry Smith 823cf57b110SBarry Smith Input Parameters: 824cf57b110SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 825cf57b110SBarry Smith - func - the function to use 826cf57b110SBarry Smith 827cf57b110SBarry Smith Level: advanced 828cf57b110SBarry Smith 829cf57b110SBarry Smith Notes: 830cf57b110SBarry Smith If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free 831cf57b110SBarry Smith matrix inside your compute Jacobian routine 832cf57b110SBarry Smith 833cf57b110SBarry Smith 834cf57b110SBarry Smith .keywords: SNES, matrix-free, function 835cf57b110SBarry Smith 836cf57b110SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 837cf57b110SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 838cf57b110SBarry Smith MatSNESMFKSPMonitor(), SNESetFunction() 839cf57b110SBarry Smith @*/ 840cf57b110SBarry Smith int MatSNESMFSetFunctioniBase(Mat mat,int (*func)(Vec,void *)) 841cf57b110SBarry Smith { 842*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 843cf57b110SBarry Smith int ierr; 844cf57b110SBarry Smith 845cf57b110SBarry Smith PetscFunctionBegin; 846cf57b110SBarry Smith ctx->funcisetbase = func; 847cf57b110SBarry Smith PetscFunctionReturn(0); 848cf57b110SBarry Smith } 849cf57b110SBarry Smith 85085614651SBarry Smith 8514a2ae208SSatish Balay #undef __FUNCT__ 8524a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetPeriod" 853329f5518SBarry Smith /*@ 854329f5518SBarry Smith MatSNESMFSetPeriod - Sets how often h is recomputed, by default it is everytime 855329f5518SBarry Smith 856329f5518SBarry Smith Collective on Mat 857329f5518SBarry Smith 858329f5518SBarry Smith Input Parameters: 859329f5518SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 860329f5518SBarry Smith - period - 1 for everytime, 2 for every second etc 861329f5518SBarry Smith 862329f5518SBarry Smith Options Database Keys: 863329f5518SBarry Smith + -snes_mf_period <period> 864329f5518SBarry Smith 865329f5518SBarry Smith Level: advanced 866329f5518SBarry Smith 867329f5518SBarry Smith 868329f5518SBarry Smith .keywords: SNES, matrix-free, parameters 869329f5518SBarry Smith 870329f5518SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 871329f5518SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 872329f5518SBarry Smith MatSNESMFKSPMonitor() 873329f5518SBarry Smith @*/ 874329f5518SBarry Smith int MatSNESMFSetPeriod(Mat mat,int period) 875329f5518SBarry Smith { 876*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 877329f5518SBarry Smith int ierr; 878329f5518SBarry Smith 879329f5518SBarry Smith PetscFunctionBegin; 880329f5518SBarry Smith ctx->recomputeperiod = period; 881329f5518SBarry Smith PetscFunctionReturn(0); 882329f5518SBarry Smith } 883329f5518SBarry Smith 8844a2ae208SSatish Balay #undef __FUNCT__ 8854a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetFunctionError" 886a4d4d686SBarry Smith /*@ 8875a655dc6SBarry Smith MatSNESMFSetFunctionError - Sets the error_rel for the approximation of 888a4d4d686SBarry Smith matrix-vector products using finite differences. 889a4d4d686SBarry Smith 890a4d4d686SBarry Smith Collective on Mat 891a4d4d686SBarry Smith 892a4d4d686SBarry Smith Input Parameters: 8935a655dc6SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 8949a6cb015SBarry Smith - error_rel - relative error (should be set to the square root of 895a4d4d686SBarry Smith the relative error in the function evaluations) 896a4d4d686SBarry Smith 89715091d37SBarry Smith Options Database Keys: 89815091d37SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 89915091d37SBarry Smith 90015091d37SBarry Smith Level: advanced 90115091d37SBarry Smith 902a4d4d686SBarry Smith Notes: 903a4d4d686SBarry Smith The default matrix-free matrix-vector product routine computes 904a4d4d686SBarry Smith .vb 90565f2ba5bSLois Curfman McInnes F'(u)*a = [F(u+h*a) - F(u)]/h where 906a4d4d686SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 907a4d4d686SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 else 908a4d4d686SBarry Smith .ve 909a4d4d686SBarry Smith 910a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters 911a4d4d686SBarry Smith 9125a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 9135a655dc6SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 9145a655dc6SBarry Smith MatSNESMFKSPMonitor() 915a4d4d686SBarry Smith @*/ 916329f5518SBarry Smith int MatSNESMFSetFunctionError(Mat mat,PetscReal error) 917a4d4d686SBarry Smith { 918*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)mat->data; 919a4d4d686SBarry Smith int ierr; 920a4d4d686SBarry Smith 921a4d4d686SBarry Smith PetscFunctionBegin; 922a4d4d686SBarry Smith if (error != PETSC_DEFAULT) ctx->error_rel = error; 923a4d4d686SBarry Smith PetscFunctionReturn(0); 924a4d4d686SBarry Smith } 925a4d4d686SBarry Smith 9264a2ae208SSatish Balay #undef __FUNCT__ 9274a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFAddNullSpace" 928a4d4d686SBarry Smith /*@ 92965f2ba5bSLois Curfman McInnes MatSNESMFAddNullSpace - Provides a null space that an operator is 93065f2ba5bSLois Curfman McInnes supposed to have. Since roundoff will create a small component in 93165f2ba5bSLois Curfman McInnes the null space, if you know the null space you may have it 93265f2ba5bSLois Curfman McInnes automatically removed. 933a4d4d686SBarry Smith 934a4d4d686SBarry Smith Collective on Mat 935a4d4d686SBarry Smith 936a4d4d686SBarry Smith Input Parameters: 937a4d4d686SBarry Smith + J - the matrix-free matrix context 93874637425SBarry Smith - nullsp - object created with MatNullSpaceCreate() 939a4d4d686SBarry Smith 94015091d37SBarry Smith Level: advanced 94115091d37SBarry Smith 942a4d4d686SBarry Smith .keywords: SNES, matrix-free, null space 943a4d4d686SBarry Smith 94474637425SBarry Smith .seealso: MatNullSpaceCreate(), MatSNESMFGetH(), MatCreateSNESMF(), 9455a655dc6SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 9465a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFErrorRel() 947a4d4d686SBarry Smith @*/ 94874637425SBarry Smith int MatSNESMFAddNullSpace(Mat J,MatNullSpace nullsp) 949a4d4d686SBarry Smith { 950a4d4d686SBarry Smith int ierr; 951*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)J->data; 952a4d4d686SBarry Smith MPI_Comm comm; 953a4d4d686SBarry Smith 954a4d4d686SBarry Smith PetscFunctionBegin; 9552d0c0e3bSBarry Smith ierr = PetscObjectGetComm((PetscObject)J,&comm);CHKERRQ(ierr); 956a4d4d686SBarry Smith 95785614651SBarry Smith ctx->sp = nullsp; 95885614651SBarry Smith ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 959a4d4d686SBarry Smith PetscFunctionReturn(0); 960a4d4d686SBarry Smith } 961a4d4d686SBarry Smith 9624a2ae208SSatish Balay #undef __FUNCT__ 9634a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetHHistory" 964a4d4d686SBarry Smith /*@ 96565f2ba5bSLois Curfman McInnes MatSNESMFSetHHistory - Sets an array to collect a history of the 96665f2ba5bSLois Curfman McInnes differencing values (h) computed for the matrix-free product. 967a4d4d686SBarry Smith 968a4d4d686SBarry Smith Collective on Mat 969a4d4d686SBarry Smith 970a4d4d686SBarry Smith Input Parameters: 971a4d4d686SBarry Smith + J - the matrix-free matrix context 97265f2ba5bSLois Curfman McInnes . histroy - space to hold the history 97365f2ba5bSLois Curfman McInnes - nhistory - number of entries in history, if more entries are generated than 97465f2ba5bSLois Curfman McInnes nhistory, then the later ones are discarded 975a4d4d686SBarry Smith 97615091d37SBarry Smith Level: advanced 97715091d37SBarry Smith 978a4d4d686SBarry Smith Notes: 97965f2ba5bSLois Curfman McInnes Use MatSNESMFResetHHistory() to reset the history counter and collect 98065f2ba5bSLois Curfman McInnes a new batch of differencing parameters, h. 981a4d4d686SBarry Smith 982a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history 983a4d4d686SBarry Smith 9845a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(), 9855a655dc6SBarry Smith MatSNESMFResetHHistory(), 9865a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError() 987a4d4d686SBarry Smith 988a4d4d686SBarry Smith @*/ 9895a655dc6SBarry Smith int MatSNESMFSetHHistory(Mat J,Scalar *history,int nhistory) 990a4d4d686SBarry Smith { 991a4d4d686SBarry Smith int ierr; 992*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)J->data; 993a4d4d686SBarry Smith 994a4d4d686SBarry Smith PetscFunctionBegin; 995a4d4d686SBarry Smith ctx->historyh = history; 996a4d4d686SBarry Smith ctx->maxcurrenth = nhistory; 997a4d4d686SBarry Smith ctx->currenth = 0; 998a4d4d686SBarry Smith 999a4d4d686SBarry Smith PetscFunctionReturn(0); 1000a4d4d686SBarry Smith } 1001a4d4d686SBarry Smith 10024a2ae208SSatish Balay #undef __FUNCT__ 10034a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFResetHHistory" 1004a4d4d686SBarry Smith /*@ 10055a655dc6SBarry Smith MatSNESMFResetHHistory - Resets the counter to zero to begin 1006a4d4d686SBarry Smith collecting a new set of differencing histories. 1007a4d4d686SBarry Smith 1008a4d4d686SBarry Smith Collective on Mat 1009a4d4d686SBarry Smith 1010a4d4d686SBarry Smith Input Parameters: 1011a4d4d686SBarry Smith . J - the matrix-free matrix context 1012a4d4d686SBarry Smith 101315091d37SBarry Smith Level: advanced 101415091d37SBarry Smith 1015a4d4d686SBarry Smith Notes: 101665f2ba5bSLois Curfman McInnes Use MatSNESMFSetHHistory() to create the original history counter. 1017a4d4d686SBarry Smith 1018a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history 1019a4d4d686SBarry Smith 10205a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(), 10215a655dc6SBarry Smith MatSNESMFSetHHistory(), 10225a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError() 1023a4d4d686SBarry Smith 1024a4d4d686SBarry Smith @*/ 10255a655dc6SBarry Smith int MatSNESMFResetHHistory(Mat J) 1026a4d4d686SBarry Smith { 1027a4d4d686SBarry Smith int ierr; 1028*7e9d5209SBarry Smith MatSNESMFCtx ctx = (MatSNESMFCtx)J->data; 1029a4d4d686SBarry Smith 1030a4d4d686SBarry Smith PetscFunctionBegin; 1031be726c96SBarry Smith ctx->ncurrenth = 0; 1032a4d4d686SBarry Smith 1033a4d4d686SBarry Smith PetscFunctionReturn(0); 1034a4d4d686SBarry Smith } 1035a4d4d686SBarry Smith 10364a2ae208SSatish Balay #undef __FUNCT__ 1037fed8bd04SBarry Smith #define __FUNCT__ "MatSNESMFComputeJacobian" 1038fed8bd04SBarry Smith int MatSNESMFComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy) 10391d1367b7SBarry Smith { 10401d1367b7SBarry Smith int ierr; 10411d1367b7SBarry Smith PetscFunctionBegin; 10421d1367b7SBarry Smith ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10431d1367b7SBarry Smith ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10441d1367b7SBarry Smith PetscFunctionReturn(0); 10451d1367b7SBarry Smith } 10461d1367b7SBarry Smith 10474a2ae208SSatish Balay #undef __FUNCT__ 10484a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetBase" 10491d1367b7SBarry Smith int MatSNESMFSetBase(Mat J,Vec U) 10501d1367b7SBarry Smith { 10513a7fca6bSBarry Smith int ierr,(*f)(Mat,Vec); 10521d1367b7SBarry Smith 10531d1367b7SBarry Smith PetscFunctionBegin; 10541d1367b7SBarry Smith PetscValidHeaderSpecific(J,MAT_COOKIE); 10551d1367b7SBarry Smith PetscValidHeaderSpecific(U,VEC_COOKIE); 1056cf3bea43SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)J,"MatSNESMFSetBase_C",(void (**)())&f);CHKERRQ(ierr); 1057cf3bea43SBarry Smith if (f) { 1058cf3bea43SBarry Smith ierr = (*f)(J,U);CHKERRQ(ierr); 105949d4803aSBarry Smith } 10601d1367b7SBarry Smith PetscFunctionReturn(0); 10611d1367b7SBarry Smith } 1062cf57b110SBarry Smith 1063cf57b110SBarry Smith 1064cf57b110SBarry Smith 1065cf57b110SBarry Smith 1066cf57b110SBarry Smith 1067cf57b110SBarry Smith 1068cf57b110SBarry Smith 1069cf57b110SBarry Smith 1070cf57b110SBarry Smith 1071