1*b7fd4e64SBarry Smith /*$Id: snesmfj.c,v 1.102 2000/04/01 04:21:11 bsmith Exp bsmith $*/ 281e6777dSBarry Smith 39a6cb015SBarry Smith #include "src/snes/snesimpl.h" 49a6cb015SBarry Smith #include "src/snes/mf/snesmfj.h" /*I "snes.h" I*/ 581e6777dSBarry Smith 65a655dc6SBarry Smith FList MatSNESMFList = 0; 74c49b128SBarry Smith PetscTruth MatSNESMFRegisterAllCalled = PETSC_FALSE; 8a4d4d686SBarry Smith 95615d1e5SSatish Balay #undef __FUNC__ 105a655dc6SBarry Smith #define __FUNC__ "MatSNESMFSetType" 11fd4bdd07SBarry Smith /*@C 1265f2ba5bSLois Curfman McInnes MatSNESMFSetType - Sets the method that is used to compute the 1365f2ba5bSLois Curfman McInnes differencing parameter for finite difference 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 555a655dc6SBarry Smith ierr = FListFind(ctx->comm,MatSNESMFList,ftype,(int (**)(void *)) &r);CHKERRQ(ierr); 569a6cb015SBarry Smith 575a655dc6SBarry Smith if (!r) SETERRQ(1,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: 70f1af5d2fSBarry Smith MatSNESMFRegisterDynamicchar *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 1049a6cb015SBarry Smith #undef __FUNC__ 105f1af5d2fSBarry Smith #define __FUNC__ "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; 112f1af5d2fSBarry Smith ierr = FListConcat(path,name,fullname);CHKERRQ(ierr); 113f1af5d2fSBarry Smith ierr = FListAdd(&MatSNESMFList,sname,fullname,(int (*)(void*))function);CHKERRQ(ierr); 1149a6cb015SBarry Smith PetscFunctionReturn(0); 1159a6cb015SBarry Smith } 1169a6cb015SBarry Smith 1179a6cb015SBarry Smith 1189a6cb015SBarry Smith #undef __FUNC__ 1195a655dc6SBarry Smith #define __FUNC__ "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; 1375a655dc6SBarry Smith if (MatSNESMFList) { 1385a655dc6SBarry Smith ierr = FListDestroy(MatSNESMFList);CHKERRQ(ierr); 1395a655dc6SBarry Smith MatSNESMFList = 0; 1409a6cb015SBarry Smith } 1414c49b128SBarry Smith MatSNESMFRegisterAllCalled = PETSC_FALSE; 1429a6cb015SBarry Smith PetscFunctionReturn(0); 1439a6cb015SBarry Smith } 1449a6cb015SBarry Smith 1459a6cb015SBarry Smith /* ----------------------------------------------------------------------------------------*/ 146a4d4d686SBarry Smith #undef __FUNC__ 1475a655dc6SBarry Smith #define __FUNC__ "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);} 157b4fd4287SBarry Smith if (ctx->sp) {ierr = PCNullSpaceDestroy(ctx->sp);CHKERRQ(ierr);} 1586831982aSBarry Smith PetscHeaderDestroy(ctx); 1593a40ed3dSBarry Smith PetscFunctionReturn(0); 160b9fa9cd0SBarry Smith } 16150361f65SLois Curfman McInnes 1625615d1e5SSatish Balay #undef __FUNC__ 1635a655dc6SBarry Smith #define __FUNC__ "MatSNESMFView_Private" 16439e2f89bSBarry Smith /* 1655a655dc6SBarry Smith MatSNESMFView_Private - Views matrix-free parameters. 1668f6e3e37SBarry Smith 16739e2f89bSBarry Smith */ 1685a655dc6SBarry Smith int MatSNESMFView_Private(Mat J,Viewer 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); 1766831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 1770f5bd95cSBarry Smith if (isascii) { 1786831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," SNES matrix-free approximation:\n");CHKERRQ(ierr); 1796831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," err=%g (relative error in function evaluation)\n",ctx->error_rel);CHKERRQ(ierr); 1806831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," Using %s compute h routine\n",ctx->type_name);CHKERRQ(ierr); 1819a6cb015SBarry Smith if (ctx->ops->view) { 1829a6cb015SBarry Smith ierr = (*ctx->ops->view)(ctx,viewer);CHKERRQ(ierr); 1839a6cb015SBarry Smith } 1845cd90555SBarry Smith } else { 1850f5bd95cSBarry Smith SETERRQ1(1,1,"Viewer type %s not supported for SNES matrix free matrix",((PetscObject)viewer)->type_name); 186eb9086c3SLois Curfman McInnes } 1873a40ed3dSBarry Smith PetscFunctionReturn(0); 188eb9086c3SLois Curfman McInnes } 189eb9086c3SLois Curfman McInnes 190be726c96SBarry Smith #undef __FUNC__ 1915a655dc6SBarry Smith #define __FUNC__ "MatSNESMFAssemblyEnd_Private" 192be726c96SBarry Smith /* 1935a655dc6SBarry Smith MatSNESMFAssemblyEnd_Private - Resets the ctx->ncurrenth to zero. This 19465f2ba5bSLois Curfman McInnes allows the user to indicate the beginning of a new linear solve by calling 195be726c96SBarry Smith MatAssemblyXXX() on the matrix free matrix. This then allows the 19665f2ba5bSLois Curfman McInnes MatSNESMFCreate_WP() to properly compute ||U|| only the first time 19765f2ba5bSLois Curfman McInnes in the linear solver rather than every time. 198be726c96SBarry Smith */ 1995a655dc6SBarry Smith int MatSNESMFAssemblyEnd_Private(Mat J) 200be726c96SBarry Smith { 201be726c96SBarry Smith int ierr; 202be726c96SBarry Smith 203be726c96SBarry Smith PetscFunctionBegin; 2045a655dc6SBarry Smith ierr = MatSNESMFResetHHistory(J);CHKERRQ(ierr); 205be726c96SBarry Smith PetscFunctionReturn(0); 206be726c96SBarry Smith } 207be726c96SBarry Smith 208c481317fSBarry Smith 2095615d1e5SSatish Balay #undef __FUNC__ 2105a655dc6SBarry Smith #define __FUNC__ "MatSNESMFMult_Private" 211eb9086c3SLois Curfman McInnes /* 2125a655dc6SBarry Smith MatSNESMFMult_Private - Default matrix-free form for Jacobian-vector 213eb9086c3SLois Curfman McInnes product, y = F'(u)*a: 214a4d4d686SBarry Smith 2159a6cb015SBarry Smith y ~= (F(u + ha) - F(u))/h, 216eb9086c3SLois Curfman McInnes where F = nonlinear function, as set by SNESSetFunction() 217eb9086c3SLois Curfman McInnes u = current iterate 218eb9086c3SLois Curfman McInnes h = difference interval 219eb9086c3SLois Curfman McInnes */ 2205a655dc6SBarry Smith int MatSNESMFMult_Private(Mat mat,Vec a,Vec y) 22139e2f89bSBarry Smith { 2225a655dc6SBarry Smith MatSNESMFCtx ctx; 223fae171e0SBarry Smith SNES snes; 224a4d4d686SBarry Smith Scalar h,mone = -1.0; 225fae171e0SBarry Smith Vec w,U,F; 226a305c92eSSatish Balay int ierr,(*eval_fct)(SNES,Vec,Vec)=0; 22739e2f89bSBarry Smith 2283a40ed3dSBarry Smith PetscFunctionBegin; 2299a6cb015SBarry Smith /* We log matrix-free matrix-vector products separately, so that we can 2309a6cb015SBarry Smith separate the performance monitoring from the cases that use conventional 2319a6cb015SBarry Smith storage. We may eventually modify event logging to associate events 2329a6cb015SBarry Smith with particular objects, hence alleviating the more general problem. */ 23356cd22aeSBarry Smith PLogEventBegin(MAT_MatrixFreeMult,a,y,0,0); 23456cd22aeSBarry Smith 2356e38a044SBarry Smith ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 236fae171e0SBarry Smith snes = ctx->snes; 237fae171e0SBarry Smith w = ctx->w; 23878b31e54SBarry Smith ierr = SNESGetSolution(snes,&U);CHKERRQ(ierr); 23950361f65SLois Curfman McInnes 24085614651SBarry Smith /* 24185614651SBarry Smith Compute differencing parameter 24285614651SBarry Smith */ 2439a6cb015SBarry Smith if (!ctx->ops->compute) { 244*b7fd4e64SBarry Smith ierr = MatSNESMFSetType(mat,MATSNESMF_DEFAULT);CHKERRQ(ierr); 2455a655dc6SBarry Smith ierr = MatSNESMFSetFromOptions(mat);CHKERRQ(ierr); 2469a6cb015SBarry Smith } 2479a6cb015SBarry Smith ierr = (*ctx->ops->compute)(ctx,U,a,&h);CHKERRQ(ierr); 248a4d4d686SBarry Smith 249a4d4d686SBarry Smith /* keep a record of the current differencing parameter h */ 250a4d4d686SBarry Smith ctx->currenth = h; 251aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 252329f5518SBarry Smith PLogInfo(mat,"Current differencing parameter: %g + %g i\n",PetscRealPart(h),PetscImaginaryPart(h)); 253a4d4d686SBarry Smith #else 254a4d4d686SBarry Smith PLogInfo(mat,"Current differencing parameter: %g\n",h); 255a4d4d686SBarry Smith #endif 256a4d4d686SBarry Smith if (ctx->historyh && ctx->ncurrenth < ctx->maxcurrenth) { 25785614651SBarry Smith ctx->historyh[ctx->ncurrenth] = h; 258a4d4d686SBarry Smith } 25985614651SBarry Smith ctx->ncurrenth++; 260a4d4d686SBarry Smith 26185614651SBarry Smith /* w = u + ha */ 262a4d4d686SBarry Smith ierr = VecWAXPY(&h,a,U,w);CHKERRQ(ierr); 26385614651SBarry Smith 26485614651SBarry Smith 26585614651SBarry Smith if (!ctx->func) { 26685614651SBarry Smith if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 26785614651SBarry Smith eval_fct = SNESComputeFunction; 268184914b5SBarry Smith ierr = SNESGetFunction(snes,&F,PETSC_NULL);CHKERRQ(ierr); 26985614651SBarry Smith } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 27085614651SBarry Smith eval_fct = SNESComputeGradient; 271184914b5SBarry Smith ierr = SNESGetGradient(snes,&F,PETSC_NULL);CHKERRQ(ierr); 27285614651SBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Invalid method class"); 273a4d4d686SBarry Smith ierr = eval_fct(snes,w,y);CHKERRQ(ierr); 27485614651SBarry Smith } else { 27585614651SBarry Smith F = ctx->funcvec; 27685614651SBarry Smith /* compute func(U) as base for differencing */ 27785614651SBarry Smith if (ctx->ncurrenth == 1) { 27885614651SBarry Smith ierr = (*ctx->func)(snes,U,F,ctx->funcctx);CHKERRQ(ierr); 27985614651SBarry Smith } 28085614651SBarry Smith ierr = (*ctx->func)(snes,w,y,ctx->funcctx);CHKERRQ(ierr); 28185614651SBarry Smith } 282a4d4d686SBarry Smith 283a4d4d686SBarry Smith ierr = VecAXPY(&mone,F,y);CHKERRQ(ierr); 284a4d4d686SBarry Smith h = 1.0/h; 285a4d4d686SBarry Smith ierr = VecScale(&h,y);CHKERRQ(ierr); 286a4d4d686SBarry Smith if (ctx->sp) {ierr = PCNullSpaceRemove(ctx->sp,y);CHKERRQ(ierr);} 287a4d4d686SBarry Smith 288a4d4d686SBarry Smith PLogEventEnd(MAT_MatrixFreeMult,a,y,0,0); 289a4d4d686SBarry Smith PetscFunctionReturn(0); 290a4d4d686SBarry Smith } 291a4d4d686SBarry Smith 292a4d4d686SBarry Smith #undef __FUNC__ 2935a655dc6SBarry Smith #define __FUNC__ "MatCreateSNESMF" 294a4d4d686SBarry Smith /*@C 29565f2ba5bSLois Curfman McInnes MatCreateSNESMF - Creates a matrix-free matrix context for use with 29665f2ba5bSLois Curfman McInnes a SNES solver. This matrix can be used as the Jacobian argument for 29765f2ba5bSLois Curfman McInnes the routine SNESSetJacobian(). 298a4d4d686SBarry Smith 299a4d4d686SBarry Smith Collective on SNES and Vec 300a4d4d686SBarry Smith 301a4d4d686SBarry Smith Input Parameters: 302a4d4d686SBarry Smith + snes - the SNES context 303a4d4d686SBarry Smith - x - vector where SNES solution is to be stored. 304a4d4d686SBarry Smith 305a4d4d686SBarry Smith Output Parameter: 306a4d4d686SBarry Smith . J - the matrix-free matrix 307a4d4d686SBarry Smith 30815091d37SBarry Smith Level: advanced 30915091d37SBarry Smith 310a4d4d686SBarry Smith Notes: 311a4d4d686SBarry Smith The matrix-free matrix context merely contains the function pointers 312a4d4d686SBarry Smith and work space for performing finite difference approximations of 31365f2ba5bSLois Curfman McInnes Jacobian-vector products, F'(u)*a, 3149a6cb015SBarry Smith 3159a6cb015SBarry Smith The default code uses the following approach to compute h 316a4d4d686SBarry Smith 317a4d4d686SBarry Smith .vb 31865f2ba5bSLois Curfman McInnes F'(u)*a = [F(u+h*a) - F(u)]/h where 319a4d4d686SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 320a4d4d686SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 otherwise 321a4d4d686SBarry Smith where 322a4d4d686SBarry Smith error_rel = square root of relative error in function evaluation 323a4d4d686SBarry Smith umin = minimum iterate parameter 324a4d4d686SBarry Smith .ve 325a4d4d686SBarry Smith 3265a655dc6SBarry Smith The user can set the error_rel via MatSNESMFSetFunctionError() and 32765f2ba5bSLois Curfman McInnes umin via MatSNESMFDefaultSetUmin(); see the nonlinear solvers chapter 32865f2ba5bSLois Curfman McInnes of the users manual for details. 329a4d4d686SBarry Smith 330a4d4d686SBarry Smith The user should call MatDestroy() when finished with the matrix-free 331a4d4d686SBarry Smith matrix context. 332a4d4d686SBarry Smith 333a4d4d686SBarry Smith Options Database Keys: 334a4d4d686SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 3359a6cb015SBarry Smith . -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only) 336a4d4d686SBarry Smith - -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h 337a4d4d686SBarry Smith 338a4d4d686SBarry Smith .keywords: SNES, default, matrix-free, create, matrix 339a4d4d686SBarry Smith 3405a655dc6SBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError(), MatSNESMFDefaultSetUmin() 3415a655dc6SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 342f1af5d2fSBarry Smith MatSNESMFGetH(),MatSNESMFKSPMonitor(), MatSNESMFRegisterDynamic) 343a4d4d686SBarry Smith 344a4d4d686SBarry Smith @*/ 3455a655dc6SBarry Smith int MatCreateSNESMF(SNES snes,Vec x,Mat *J) 346a4d4d686SBarry Smith { 347a4d4d686SBarry Smith MPI_Comm comm; 3485a655dc6SBarry Smith MatSNESMFCtx mfctx; 3499a6cb015SBarry Smith int n,nloc,ierr; 350a4d4d686SBarry Smith 351a4d4d686SBarry Smith PetscFunctionBegin; 3526831982aSBarry Smith PetscHeaderCreate(mfctx,_p_MatSNESMFCtx,struct _MFOps,MATSNESMFCTX_COOKIE,0,"SNESMF",snes->comm,MatSNESMFDestroy_Private,MatSNESMFView_Private); 3536831982aSBarry Smith PLogObjectCreate(mfctx); 354a4d4d686SBarry Smith mfctx->sp = 0; 355a4d4d686SBarry Smith mfctx->snes = snes; 356329f5518SBarry Smith mfctx->error_rel = 1.e-8; /* assumes PetscReal precision */ 357329f5518SBarry Smith mfctx->recomputeperiod = 1; 358329f5518SBarry Smith mfctx->count = 0; 359a4d4d686SBarry Smith mfctx->currenth = 0.0; 360a4d4d686SBarry Smith mfctx->historyh = PETSC_NULL; 361a4d4d686SBarry Smith mfctx->ncurrenth = 0; 362a4d4d686SBarry Smith mfctx->maxcurrenth = 0; 3636831982aSBarry Smith mfctx->type_name = 0; 364a4d4d686SBarry Smith 3659a6cb015SBarry Smith /* 3669a6cb015SBarry Smith Create the empty data structure to contain compute-h routines. 3679a6cb015SBarry Smith These will be filled in below from the command line options or 3685a655dc6SBarry Smith a later call with MatSNESMFSetType() or if that is not called 3695a655dc6SBarry Smith then it will default in the first use of MatSNESMFMult_private() 3709a6cb015SBarry Smith */ 3719a6cb015SBarry Smith mfctx->ops->compute = 0; 3729a6cb015SBarry Smith mfctx->ops->destroy = 0; 3739a6cb015SBarry Smith mfctx->ops->view = 0; 3749a6cb015SBarry Smith mfctx->ops->printhelp = 0; 3759a6cb015SBarry Smith mfctx->ops->setfromoptions = 0; 3769a6cb015SBarry Smith mfctx->hctx = 0; 3779a6cb015SBarry Smith 37885614651SBarry Smith mfctx->func = 0; 37985614651SBarry Smith mfctx->funcctx = 0; 38085614651SBarry Smith mfctx->funcvec = 0; 38185614651SBarry Smith 382a4d4d686SBarry Smith ierr = VecDuplicate(x,&mfctx->w);CHKERRQ(ierr); 383a4d4d686SBarry Smith ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 384a4d4d686SBarry Smith ierr = VecGetSize(x,&n);CHKERRQ(ierr); 385a4d4d686SBarry Smith ierr = VecGetLocalSize(x,&nloc);CHKERRQ(ierr); 386ffa0fd9eSBarry Smith ierr = MatCreateShell(comm,nloc,nloc,n,n,mfctx,J);CHKERRQ(ierr); 3875a655dc6SBarry Smith ierr = MatShellSetOperation(*J,MATOP_MULT,(void*)MatSNESMFMult_Private);CHKERRQ(ierr); 3885a655dc6SBarry Smith ierr = MatShellSetOperation(*J,MATOP_DESTROY,(void *)MatSNESMFDestroy_Private);CHKERRQ(ierr); 3895a655dc6SBarry Smith ierr = MatShellSetOperation(*J,MATOP_VIEW,(void *)MatSNESMFView_Private);CHKERRQ(ierr); 3905a655dc6SBarry Smith ierr = MatShellSetOperation(*J,MATOP_ASSEMBLY_END,(void *)MatSNESMFAssemblyEnd_Private);CHKERRQ(ierr); 391a4d4d686SBarry Smith PLogObjectParent(*J,mfctx->w); 392a4d4d686SBarry Smith PLogObjectParent(snes,*J); 3939a6cb015SBarry Smith 3949a6cb015SBarry Smith mfctx->mat = *J; 3959a6cb015SBarry Smith 3969a6cb015SBarry Smith 3979a6cb015SBarry Smith PetscFunctionReturn(0); 3989a6cb015SBarry Smith } 3999a6cb015SBarry Smith 4009a6cb015SBarry Smith #undef __FUNC__ 4015a655dc6SBarry Smith #define __FUNC__ "MatSNESMFSetFromOptions" 4029a6cb015SBarry Smith /*@ 4035a655dc6SBarry Smith MatSNESMFSetFromOptions - Sets the MatSNESMF options from the command line 4049a6cb015SBarry Smith parameter. 4059a6cb015SBarry Smith 4069a6cb015SBarry Smith Collective on Mat 4079a6cb015SBarry Smith 4089a6cb015SBarry Smith Input Parameters: 4095a655dc6SBarry Smith . mat - the matrix obtained with MatCreateSNESMF() 4105a655dc6SBarry Smith 4115a655dc6SBarry Smith Options Database Keys: 4125a655dc6SBarry Smith + -snes_mf_type - <default,wp> 4135a655dc6SBarry Smith - -snes_mf_err - square root of estimated relative error in function evaluation 414329f5518SBarry Smith - -snes_mf_period - how often h is recomputed, defaults to 1, everytime 4159a6cb015SBarry Smith 41615091d37SBarry Smith Level: advanced 41715091d37SBarry Smith 4189a6cb015SBarry Smith .keywords: SNES, matrix-free, parameters 4199a6cb015SBarry Smith 4205a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(), 4215a655dc6SBarry Smith MatSNESMFResetHHistory(), MatSNESMFKSPMonitor() 4229a6cb015SBarry Smith @*/ 4235a655dc6SBarry Smith int MatSNESMFSetFromOptions(Mat mat) 4249a6cb015SBarry Smith { 4255a655dc6SBarry Smith MatSNESMFCtx mfctx; 426f1af5d2fSBarry Smith int ierr; 427f1af5d2fSBarry Smith PetscTruth flg; 4289a6cb015SBarry Smith char ftype[256],p[64]; 4299a6cb015SBarry Smith 4309a6cb015SBarry Smith PetscFunctionBegin; 4319a6cb015SBarry Smith ierr = MatShellGetContext(mat,(void **)&mfctx);CHKERRQ(ierr); 4329a6cb015SBarry Smith if (mfctx) { 4339a6cb015SBarry Smith /* allow user to set the type */ 4349a6cb015SBarry Smith ierr = OptionsGetString(mfctx->snes->prefix,"-snes_mf_type",ftype,256,&flg);CHKERRQ(ierr); 4359a6cb015SBarry Smith if (flg) { 4365a655dc6SBarry Smith ierr = MatSNESMFSetType(mat,ftype);CHKERRQ(ierr); 4379a6cb015SBarry Smith } 4389a6cb015SBarry Smith 439f1af5d2fSBarry Smith ierr = OptionsGetDouble(mfctx->snes->prefix,"-snes_mf_err",&mfctx->error_rel,PETSC_NULL);CHKERRQ(ierr); 440329f5518SBarry Smith ierr = OptionsGetInt(mfctx->snes->prefix,"-snes_mf_period",&mfctx->recomputeperiod,PETSC_NULL);CHKERRQ(ierr); 4419a6cb015SBarry Smith if (mfctx->ops->setfromoptions) { 4429a6cb015SBarry Smith ierr = (*mfctx->ops->setfromoptions)(mfctx);CHKERRQ(ierr); 4439a6cb015SBarry Smith } 4449a6cb015SBarry Smith 4459a6cb015SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 446d132466eSBarry Smith ierr = PetscStrcpy(p,"-");CHKERRQ(ierr); 447d132466eSBarry Smith if (mfctx->snes->prefix) {ierr = PetscStrcat(p,mfctx->snes->prefix);CHKERRQ(ierr);} 4489a6cb015SBarry Smith if (flg) { 449d132466eSBarry Smith ierr = (*PetscHelpPrintf)(mfctx->snes->comm," %ssnes_mf_err <err>: set sqrt rel error in function (default %g)\n",p,mfctx->error_rel);CHKERRQ(ierr); 450329f5518SBarry Smith ierr = (*PetscHelpPrintf)(mfctx->snes->comm," %ssnes_mf_period <p>: how often h is recomputed (default 1, everytime)\n",p);CHKERRQ(ierr); 4519a6cb015SBarry Smith if (mfctx->ops->printhelp) { 452d132466eSBarry Smith ierr = (*mfctx->ops->printhelp)(mfctx);CHKERRQ(ierr); 4539a6cb015SBarry Smith } 4549a6cb015SBarry Smith } 4559a6cb015SBarry Smith } 456a4d4d686SBarry Smith PetscFunctionReturn(0); 457a4d4d686SBarry Smith } 458a4d4d686SBarry Smith 459a4d4d686SBarry Smith #undef __FUNC__ 4605a655dc6SBarry Smith #define __FUNC__ "MatSNESMFGetH" 461a4d4d686SBarry Smith /*@ 46265f2ba5bSLois Curfman McInnes MatSNESMFGetH - Gets the last value that was used as the differencing 463a4d4d686SBarry Smith parameter. 464a4d4d686SBarry Smith 465a4d4d686SBarry Smith Not Collective 466a4d4d686SBarry Smith 467a4d4d686SBarry Smith Input Parameters: 4685a655dc6SBarry Smith . mat - the matrix obtained with MatCreateSNESMF() 469a4d4d686SBarry Smith 470a4d4d686SBarry Smith Output Paramter: 471a4d4d686SBarry Smith . h - the differencing step size 472a4d4d686SBarry Smith 47315091d37SBarry Smith Level: advanced 47415091d37SBarry Smith 475a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters 476a4d4d686SBarry Smith 4775a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(), 4785a655dc6SBarry Smith MatSNESMFResetHHistory(),MatSNESMFKSPMonitor() 479a4d4d686SBarry Smith @*/ 4805a655dc6SBarry Smith int MatSNESMFGetH(Mat mat,Scalar *h) 481a4d4d686SBarry Smith { 4825a655dc6SBarry Smith MatSNESMFCtx ctx; 483a4d4d686SBarry Smith int ierr; 484a4d4d686SBarry Smith 485a4d4d686SBarry Smith PetscFunctionBegin; 486a4d4d686SBarry Smith ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 487a4d4d686SBarry Smith if (ctx) { 488a4d4d686SBarry Smith *h = ctx->currenth; 489a4d4d686SBarry Smith } 490a4d4d686SBarry Smith PetscFunctionReturn(0); 491a4d4d686SBarry Smith } 492a4d4d686SBarry Smith 493a4d4d686SBarry Smith #undef __FUNC__ 4945a655dc6SBarry Smith #define __FUNC__ "MatSNESMFKSPMonitor" 495a4d4d686SBarry Smith /* 4965a655dc6SBarry Smith MatSNESMFKSPMonitor - A KSP monitor for use with the default PETSc 49765f2ba5bSLois Curfman McInnes SNES matrix free routines. Prints the differencing parameter used at 49865f2ba5bSLois Curfman McInnes each step. 499a4d4d686SBarry Smith */ 500329f5518SBarry Smith int MatSNESMFKSPMonitor(KSP ksp,int n,PetscReal rnorm,void *dummy) 501a4d4d686SBarry Smith { 502a4d4d686SBarry Smith PC pc; 5035a655dc6SBarry Smith MatSNESMFCtx ctx; 504a4d4d686SBarry Smith int ierr; 505a4d4d686SBarry Smith Mat mat; 506a4d4d686SBarry Smith MPI_Comm comm; 507a4d4d686SBarry Smith PetscTruth nonzeroinitialguess; 508a4d4d686SBarry Smith 509a4d4d686SBarry Smith PetscFunctionBegin; 510a4d4d686SBarry Smith ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr); 511a4d4d686SBarry Smith ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 512a4d4d686SBarry Smith ierr = KSPGetInitialGuessNonzero(ksp,&nonzeroinitialguess);CHKERRQ(ierr); 513a4d4d686SBarry Smith ierr = PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 514a4d4d686SBarry Smith ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 5159a6cb015SBarry Smith if (!ctx) { 5169a6cb015SBarry Smith SETERRQ(1,1,"Matrix is not a matrix free shell matrix"); 5179a6cb015SBarry Smith } 518a4d4d686SBarry Smith if (n > 0 || nonzeroinitialguess) { 519aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 520d132466eSBarry Smith ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g + %g i\n",n,rnorm, 521329f5518SBarry Smith PetscRealPart(ctx->currenth),PetscImaginaryPart(ctx->currenth));CHKERRQ(ierr); 522a4d4d686SBarry Smith #else 523d132466eSBarry Smith ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g \n",n,rnorm,ctx->currenth);CHKERRQ(ierr); 524a4d4d686SBarry Smith #endif 525a4d4d686SBarry Smith } else { 526d132466eSBarry Smith ierr = PetscPrintf(comm,"%d KSP Residual norm %14.12e\n",n,rnorm);CHKERRQ(ierr); 527a4d4d686SBarry Smith } 528a4d4d686SBarry Smith PetscFunctionReturn(0); 529a4d4d686SBarry Smith } 530a4d4d686SBarry Smith 531a4d4d686SBarry Smith #undef __FUNC__ 53285614651SBarry Smith #define __FUNC__ "MatSNESMFSetFunction" 53385614651SBarry Smith /*@C 53485614651SBarry Smith MatSNESMFSetFunction - Sets the function used in applying the matrix free. 53585614651SBarry Smith 53685614651SBarry Smith Collective on Mat 53785614651SBarry Smith 53885614651SBarry Smith Input Parameters: 53985614651SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 54085614651SBarry Smith . v - workspace vector 54185614651SBarry Smith . func - the function to use 54285614651SBarry Smith - funcctx - optional function context passed to function 54385614651SBarry Smith 54485614651SBarry Smith Level: advanced 54585614651SBarry Smith 54685614651SBarry Smith Notes: 54785614651SBarry Smith If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free 54885614651SBarry Smith matrix inside your compute Jacobian routine 54985614651SBarry Smith 55085614651SBarry Smith If this is not set then it will use the function set with SNESSetFunction() 55185614651SBarry Smith 55285614651SBarry Smith .keywords: SNES, matrix-free, function 55385614651SBarry Smith 55485614651SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 55585614651SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 55685614651SBarry Smith MatSNESMFKSPMonitor(), SNESetFunction() 55785614651SBarry Smith @*/ 55885614651SBarry Smith int MatSNESMFSetFunction(Mat mat,Vec v,int (*func)(SNES,Vec,Vec,void *),void *funcctx) 55985614651SBarry Smith { 56085614651SBarry Smith MatSNESMFCtx ctx; 56185614651SBarry Smith int ierr; 56285614651SBarry Smith 56385614651SBarry Smith PetscFunctionBegin; 56485614651SBarry Smith ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 56585614651SBarry Smith if (ctx) { 56685614651SBarry Smith ctx->func = func; 56785614651SBarry Smith ctx->funcctx = funcctx; 56885614651SBarry Smith ctx->funcvec = v; 56985614651SBarry Smith } 57085614651SBarry Smith PetscFunctionReturn(0); 57185614651SBarry Smith } 57285614651SBarry Smith 57385614651SBarry Smith 57485614651SBarry Smith #undef __FUNC__ 575329f5518SBarry Smith #define __FUNC__ "MatSNESMFSetPeriod" 576329f5518SBarry Smith /*@ 577329f5518SBarry Smith MatSNESMFSetPeriod - Sets how often h is recomputed, by default it is everytime 578329f5518SBarry Smith 579329f5518SBarry Smith Collective on Mat 580329f5518SBarry Smith 581329f5518SBarry Smith Input Parameters: 582329f5518SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 583329f5518SBarry Smith - period - 1 for everytime, 2 for every second etc 584329f5518SBarry Smith 585329f5518SBarry Smith Options Database Keys: 586329f5518SBarry Smith + -snes_mf_period <period> 587329f5518SBarry Smith 588329f5518SBarry Smith Level: advanced 589329f5518SBarry Smith 590329f5518SBarry Smith 591329f5518SBarry Smith .keywords: SNES, matrix-free, parameters 592329f5518SBarry Smith 593329f5518SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 594329f5518SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 595329f5518SBarry Smith MatSNESMFKSPMonitor() 596329f5518SBarry Smith @*/ 597329f5518SBarry Smith int MatSNESMFSetPeriod(Mat mat,int period) 598329f5518SBarry Smith { 599329f5518SBarry Smith MatSNESMFCtx ctx; 600329f5518SBarry Smith int ierr; 601329f5518SBarry Smith 602329f5518SBarry Smith PetscFunctionBegin; 603329f5518SBarry Smith ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 604329f5518SBarry Smith if (ctx) { 605329f5518SBarry Smith ctx->recomputeperiod = period; 606329f5518SBarry Smith } 607329f5518SBarry Smith PetscFunctionReturn(0); 608329f5518SBarry Smith } 609329f5518SBarry Smith 610329f5518SBarry Smith #undef __FUNC__ 6115a655dc6SBarry Smith #define __FUNC__ "MatSNESMFSetFunctionError" 612a4d4d686SBarry Smith /*@ 6135a655dc6SBarry Smith MatSNESMFSetFunctionError - Sets the error_rel for the approximation of 614a4d4d686SBarry Smith matrix-vector products using finite differences. 615a4d4d686SBarry Smith 616a4d4d686SBarry Smith Collective on Mat 617a4d4d686SBarry Smith 618a4d4d686SBarry Smith Input Parameters: 6195a655dc6SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 6209a6cb015SBarry Smith - error_rel - relative error (should be set to the square root of 621a4d4d686SBarry Smith the relative error in the function evaluations) 622a4d4d686SBarry Smith 62315091d37SBarry Smith Options Database Keys: 62415091d37SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 62515091d37SBarry Smith 62615091d37SBarry Smith Level: advanced 62715091d37SBarry Smith 628a4d4d686SBarry Smith Notes: 629a4d4d686SBarry Smith The default matrix-free matrix-vector product routine computes 630a4d4d686SBarry Smith .vb 63165f2ba5bSLois Curfman McInnes F'(u)*a = [F(u+h*a) - F(u)]/h where 632a4d4d686SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 633a4d4d686SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 else 634a4d4d686SBarry Smith .ve 635a4d4d686SBarry Smith 636a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters 637a4d4d686SBarry Smith 6385a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 6395a655dc6SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 6405a655dc6SBarry Smith MatSNESMFKSPMonitor() 641a4d4d686SBarry Smith @*/ 642329f5518SBarry Smith int MatSNESMFSetFunctionError(Mat mat,PetscReal error) 643a4d4d686SBarry Smith { 6445a655dc6SBarry Smith MatSNESMFCtx ctx; 645a4d4d686SBarry Smith int ierr; 646a4d4d686SBarry Smith 647a4d4d686SBarry Smith PetscFunctionBegin; 648a4d4d686SBarry Smith ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 649a4d4d686SBarry Smith if (ctx) { 650a4d4d686SBarry Smith if (error != PETSC_DEFAULT) ctx->error_rel = error; 651a4d4d686SBarry Smith } 652a4d4d686SBarry Smith PetscFunctionReturn(0); 653a4d4d686SBarry Smith } 654a4d4d686SBarry Smith 655a4d4d686SBarry Smith #undef __FUNC__ 6565a655dc6SBarry Smith #define __FUNC__ "MatSNESMFAddNullSpace" 657a4d4d686SBarry Smith /*@ 65865f2ba5bSLois Curfman McInnes MatSNESMFAddNullSpace - Provides a null space that an operator is 65965f2ba5bSLois Curfman McInnes supposed to have. Since roundoff will create a small component in 66065f2ba5bSLois Curfman McInnes the null space, if you know the null space you may have it 66165f2ba5bSLois Curfman McInnes automatically removed. 662a4d4d686SBarry Smith 663a4d4d686SBarry Smith Collective on Mat 664a4d4d686SBarry Smith 665a4d4d686SBarry Smith Input Parameters: 666a4d4d686SBarry Smith + J - the matrix-free matrix context 66785614651SBarry Smith - nullsp - object created with PCNullSpaceCreate() 668a4d4d686SBarry Smith 66915091d37SBarry Smith Level: advanced 67015091d37SBarry Smith 671a4d4d686SBarry Smith .keywords: SNES, matrix-free, null space 672a4d4d686SBarry Smith 67353b79920SLois Curfman McInnes .seealso: PCNullSpaceCreate(), MatSNESMFGetH(), MatCreateSNESMF(), 6745a655dc6SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 6755a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFErrorRel() 676a4d4d686SBarry Smith @*/ 67785614651SBarry Smith int MatSNESMFAddNullSpace(Mat J,PCNullSpace nullsp) 678a4d4d686SBarry Smith { 679a4d4d686SBarry Smith int ierr; 6805a655dc6SBarry Smith MatSNESMFCtx ctx; 681a4d4d686SBarry Smith MPI_Comm comm; 682a4d4d686SBarry Smith 683a4d4d686SBarry Smith PetscFunctionBegin; 6842d0c0e3bSBarry Smith ierr = PetscObjectGetComm((PetscObject)J,&comm);CHKERRQ(ierr); 685a4d4d686SBarry Smith 686a4d4d686SBarry Smith ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr); 687a4d4d686SBarry Smith /* no context indicates that it is not the "matrix free" matrix type */ 688a4d4d686SBarry Smith if (!ctx) PetscFunctionReturn(0); 68985614651SBarry Smith ctx->sp = nullsp; 69085614651SBarry Smith ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 691a4d4d686SBarry Smith PetscFunctionReturn(0); 692a4d4d686SBarry Smith } 693a4d4d686SBarry Smith 694a4d4d686SBarry Smith #undef __FUNC__ 6955a655dc6SBarry Smith #define __FUNC__ "MatSNESMFSetHHistory" 696a4d4d686SBarry Smith /*@ 69765f2ba5bSLois Curfman McInnes MatSNESMFSetHHistory - Sets an array to collect a history of the 69865f2ba5bSLois Curfman McInnes differencing values (h) computed for the matrix-free product. 699a4d4d686SBarry Smith 700a4d4d686SBarry Smith Collective on Mat 701a4d4d686SBarry Smith 702a4d4d686SBarry Smith Input Parameters: 703a4d4d686SBarry Smith + J - the matrix-free matrix context 70465f2ba5bSLois Curfman McInnes . histroy - space to hold the history 70565f2ba5bSLois Curfman McInnes - nhistory - number of entries in history, if more entries are generated than 70665f2ba5bSLois Curfman McInnes nhistory, then the later ones are discarded 707a4d4d686SBarry Smith 70815091d37SBarry Smith Level: advanced 70915091d37SBarry Smith 710a4d4d686SBarry Smith Notes: 71165f2ba5bSLois Curfman McInnes Use MatSNESMFResetHHistory() to reset the history counter and collect 71265f2ba5bSLois Curfman McInnes a new batch of differencing parameters, h. 713a4d4d686SBarry Smith 714a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history 715a4d4d686SBarry Smith 7165a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(), 7175a655dc6SBarry Smith MatSNESMFResetHHistory(), 7185a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError() 719a4d4d686SBarry Smith 720a4d4d686SBarry Smith @*/ 7215a655dc6SBarry Smith int MatSNESMFSetHHistory(Mat J,Scalar *history,int nhistory) 722a4d4d686SBarry Smith { 723a4d4d686SBarry Smith int ierr; 7245a655dc6SBarry Smith MatSNESMFCtx ctx; 725a4d4d686SBarry Smith 726a4d4d686SBarry Smith PetscFunctionBegin; 727a4d4d686SBarry Smith 728a4d4d686SBarry Smith ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr); 729a4d4d686SBarry Smith /* no context indicates that it is not the "matrix free" matrix type */ 730a4d4d686SBarry Smith if (!ctx) PetscFunctionReturn(0); 731a4d4d686SBarry Smith ctx->historyh = history; 732a4d4d686SBarry Smith ctx->maxcurrenth = nhistory; 733a4d4d686SBarry Smith ctx->currenth = 0; 734a4d4d686SBarry Smith 735a4d4d686SBarry Smith PetscFunctionReturn(0); 736a4d4d686SBarry Smith } 737a4d4d686SBarry Smith 738a4d4d686SBarry Smith #undef __FUNC__ 7395a655dc6SBarry Smith #define __FUNC__ "MatSNESMFResetHHistory" 740a4d4d686SBarry Smith /*@ 7415a655dc6SBarry Smith MatSNESMFResetHHistory - Resets the counter to zero to begin 742a4d4d686SBarry Smith collecting a new set of differencing histories. 743a4d4d686SBarry Smith 744a4d4d686SBarry Smith Collective on Mat 745a4d4d686SBarry Smith 746a4d4d686SBarry Smith Input Parameters: 747a4d4d686SBarry Smith . J - the matrix-free matrix context 748a4d4d686SBarry Smith 74915091d37SBarry Smith Level: advanced 75015091d37SBarry Smith 751a4d4d686SBarry Smith Notes: 75265f2ba5bSLois Curfman McInnes Use MatSNESMFSetHHistory() to create the original history counter. 753a4d4d686SBarry Smith 754a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history 755a4d4d686SBarry Smith 7565a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(), 7575a655dc6SBarry Smith MatSNESMFSetHHistory(), 7585a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError() 759a4d4d686SBarry Smith 760a4d4d686SBarry Smith @*/ 7615a655dc6SBarry Smith int MatSNESMFResetHHistory(Mat J) 762a4d4d686SBarry Smith { 763a4d4d686SBarry Smith int ierr; 7645a655dc6SBarry Smith MatSNESMFCtx ctx; 765a4d4d686SBarry Smith 766a4d4d686SBarry Smith PetscFunctionBegin; 767a4d4d686SBarry Smith 768a4d4d686SBarry Smith ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr); 769a4d4d686SBarry Smith /* no context indicates that it is not the "matrix free" matrix type */ 770a4d4d686SBarry Smith if (!ctx) PetscFunctionReturn(0); 771be726c96SBarry Smith ctx->ncurrenth = 0; 772a4d4d686SBarry Smith 773a4d4d686SBarry Smith PetscFunctionReturn(0); 774a4d4d686SBarry Smith } 775a4d4d686SBarry Smith 776