163dd3a1aSKris Buschelman #define PETSCSNES_DLL 281e6777dSBarry Smith 3b9147fbbSdalcinl #include "include/private/matimpl.h" 4325e03aeSBarry Smith #include "src/snes/mf/snesmfj.h" /*I "petscsnes.h" I*/ 581e6777dSBarry Smith 6b0a32e0cSBarry Smith PetscFList MatSNESMPetscFList = 0; 74c49b128SBarry Smith PetscTruth MatSNESMFRegisterAllCalled = PETSC_FALSE; 8a4d4d686SBarry Smith 963dd3a1aSKris Buschelman PetscCookie PETSCSNES_DLLEXPORT MATSNESMFCTX_COOKIE = 0; 1046129b97SKris Buschelman PetscEvent MATSNESMF_Mult = 0; 1146129b97SKris Buschelman 124a2ae208SSatish Balay #undef __FUNCT__ 134a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetType" 14fd4bdd07SBarry Smith /*@C 1565f2ba5bSLois Curfman McInnes MatSNESMFSetType - Sets the method that is used to compute the 16b0a32e0cSBarry Smith differencing parameter for finite differene matrix-free formulations. 179a6cb015SBarry Smith 189a6cb015SBarry Smith Input Parameters: 197e9d5209SBarry Smith + mat - the "matrix-free" matrix created via MatCreateSNESMF(), or MatCreateMF() 207e9d5209SBarry Smith or MatSetType(mat,MATMFFD); 21efb30889SBarry Smith - ftype - the type requested, either MATSNESMF_WP or MATSNESMF_DS 229a6cb015SBarry Smith 2315091d37SBarry Smith Level: advanced 2415091d37SBarry Smith 2565f2ba5bSLois Curfman McInnes Notes: 2665f2ba5bSLois Curfman McInnes For example, such routines can compute h for use in 2765f2ba5bSLois Curfman McInnes Jacobian-vector products of the form 2865f2ba5bSLois Curfman McInnes 2965f2ba5bSLois Curfman McInnes F(x+ha) - F(x) 30ef4ad1fdSLois Curfman McInnes F'(u)a ~= ---------------- 3165f2ba5bSLois Curfman McInnes h 3265f2ba5bSLois Curfman McInnes 33f1af5d2fSBarry Smith .seealso: MatCreateSNESMF(), MatSNESMFRegisterDynamic) 349a6cb015SBarry Smith @*/ 352e90c967SHong Zhang PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetType(Mat mat,MatSNESMFType ftype) 36b9fa9cd0SBarry Smith { 3778392ef1SBarry Smith PetscErrorCode ierr,(*r)(MatSNESMF); 3878392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 396831982aSBarry Smith PetscTruth match; 40a4d4d686SBarry Smith 41a4d4d686SBarry Smith PetscFunctionBegin; 424482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 434482741eSBarry Smith PetscValidCharPointer(ftype,2); 440f5bd95cSBarry Smith 459a6cb015SBarry Smith /* already set, so just return */ 466831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)ctx,ftype,&match);CHKERRQ(ierr); 470f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 48a4d4d686SBarry Smith 499a6cb015SBarry Smith /* destroy the old one if it exists */ 509a6cb015SBarry Smith if (ctx->ops->destroy) { 519a6cb015SBarry Smith ierr = (*ctx->ops->destroy)(ctx);CHKERRQ(ierr); 529a6cb015SBarry Smith } 539a6cb015SBarry Smith 54b9617806SBarry Smith ierr = PetscFListFind(ctx->comm,MatSNESMPetscFList,ftype,(void (**)(void)) &r);CHKERRQ(ierr); 55958c9bccSBarry Smith if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown MatSNESMF type %s given",ftype); 569a6cb015SBarry Smith ierr = (*r)(ctx);CHKERRQ(ierr); 576831982aSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)ctx,ftype);CHKERRQ(ierr); 589a6cb015SBarry Smith PetscFunctionReturn(0); 599a6cb015SBarry Smith } 609a6cb015SBarry Smith 616849ba73SBarry Smith typedef PetscErrorCode (*FCN1)(Vec,void*); /* force argument to next function to not be extern C*/ 62c5c390f1SBarry Smith EXTERN_C_BEGIN 6387828ca2SBarry Smith #undef __FUNCT__ 6487828ca2SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioniBase_FD" 6563dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetFunctioniBase_FD(Mat mat,FCN1 func) 6687828ca2SBarry Smith { 6778392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 6887828ca2SBarry Smith 6987828ca2SBarry Smith PetscFunctionBegin; 7087828ca2SBarry Smith ctx->funcisetbase = func; 7187828ca2SBarry Smith PetscFunctionReturn(0); 7287828ca2SBarry Smith } 73c5c390f1SBarry Smith EXTERN_C_END 7487828ca2SBarry Smith 75a7cc72afSBarry Smith typedef PetscErrorCode (*FCN2)(PetscInt,Vec,PetscScalar*,void*); /* force argument to next function to not be extern C*/ 76c5c390f1SBarry Smith EXTERN_C_BEGIN 7787828ca2SBarry Smith #undef __FUNCT__ 7887828ca2SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioni_FD" 7963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetFunctioni_FD(Mat mat,FCN2 funci) 8087828ca2SBarry Smith { 8178392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 8287828ca2SBarry Smith 8387828ca2SBarry Smith PetscFunctionBegin; 8487828ca2SBarry Smith ctx->funci = funci; 8587828ca2SBarry Smith PetscFunctionReturn(0); 8687828ca2SBarry Smith } 87c5c390f1SBarry Smith EXTERN_C_END 8887828ca2SBarry Smith 899a6cb015SBarry Smith 904a2ae208SSatish Balay #undef __FUNCT__ 914a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFRegister" 9278392ef1SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(MatSNESMF)) 939a6cb015SBarry Smith { 94dfbe8321SBarry Smith PetscErrorCode ierr; 95e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 969a6cb015SBarry Smith 979a6cb015SBarry Smith PetscFunctionBegin; 98b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 99c134de8dSSatish Balay ierr = PetscFListAdd(&MatSNESMPetscFList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 1009a6cb015SBarry Smith PetscFunctionReturn(0); 1019a6cb015SBarry Smith } 1029a6cb015SBarry Smith 1039a6cb015SBarry Smith 1044a2ae208SSatish Balay #undef __FUNCT__ 1054a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFRegisterDestroy" 1069a6cb015SBarry Smith /*@C 1075a655dc6SBarry Smith MatSNESMFRegisterDestroy - Frees the list of MatSNESMF methods that were 108f1af5d2fSBarry Smith registered by MatSNESMFRegisterDynamic). 1099a6cb015SBarry Smith 1109a6cb015SBarry Smith Not Collective 1119a6cb015SBarry Smith 11215091d37SBarry Smith Level: developer 11315091d37SBarry Smith 1145a655dc6SBarry Smith .keywords: MatSNESMF, register, destroy 1159a6cb015SBarry Smith 116f1af5d2fSBarry Smith .seealso: MatSNESMFRegisterDynamic), MatSNESMFRegisterAll() 1179a6cb015SBarry Smith @*/ 11863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFRegisterDestroy(void) 1199a6cb015SBarry Smith { 120dfbe8321SBarry Smith PetscErrorCode ierr; 1219a6cb015SBarry Smith 1229a6cb015SBarry Smith PetscFunctionBegin; 123*1441b1d3SBarry Smith ierr = PetscFListDestroy(&MatSNESMPetscFList);CHKERRQ(ierr); 1244c49b128SBarry Smith MatSNESMFRegisterAllCalled = PETSC_FALSE; 1259a6cb015SBarry Smith PetscFunctionReturn(0); 1269a6cb015SBarry Smith } 1279a6cb015SBarry Smith 1289a6cb015SBarry Smith /* ----------------------------------------------------------------------------------------*/ 1294a2ae208SSatish Balay #undef __FUNCT__ 1308a124369SBarry Smith #define __FUNCT__ "MatDestroy_MFFD" 131dfbe8321SBarry Smith PetscErrorCode MatDestroy_MFFD(Mat mat) 132a4d4d686SBarry Smith { 133dfbe8321SBarry Smith PetscErrorCode ierr; 13478392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 135fae171e0SBarry Smith 1363a40ed3dSBarry Smith PetscFunctionBegin; 137abc0a331SBarry Smith if (ctx->w) { 138b9fa9cd0SBarry Smith ierr = VecDestroy(ctx->w);CHKERRQ(ierr); 139ba6a83e5SMatthew Knepley } 1409a6cb015SBarry Smith if (ctx->ops->destroy) {ierr = (*ctx->ops->destroy)(ctx);CHKERRQ(ierr);} 14174637425SBarry Smith if (ctx->sp) {ierr = MatNullSpaceDestroy(ctx->sp);CHKERRQ(ierr);} 142d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(ctx);CHKERRQ(ierr); 143901853e0SKris Buschelman 144901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSNESMFSetBase_C","",PETSC_NULL);CHKERRQ(ierr); 145901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSNESMFSetFunctioniBase_C","",PETSC_NULL);CHKERRQ(ierr); 146901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSNESMFSetFunctioni_C","",PETSC_NULL);CHKERRQ(ierr); 147901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSNESMFSetCheckh_C","",PETSC_NULL);CHKERRQ(ierr); 148901853e0SKris Buschelman 1493a40ed3dSBarry Smith PetscFunctionReturn(0); 150b9fa9cd0SBarry Smith } 15150361f65SLois Curfman McInnes 1524a2ae208SSatish Balay #undef __FUNCT__ 1538a124369SBarry Smith #define __FUNCT__ "MatView_MFFD" 15439e2f89bSBarry Smith /* 1558a124369SBarry Smith MatSNESMFView_MFFD - Views matrix-free parameters. 1568f6e3e37SBarry Smith 15739e2f89bSBarry Smith */ 158dfbe8321SBarry Smith PetscErrorCode MatView_MFFD(Mat J,PetscViewer viewer) 159eb9086c3SLois Curfman McInnes { 160dfbe8321SBarry Smith PetscErrorCode ierr; 16178392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)J->data; 16232077d6dSBarry Smith PetscTruth iascii; 163eb9086c3SLois Curfman McInnes 1643a40ed3dSBarry Smith PetscFunctionBegin; 16532077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 16632077d6dSBarry Smith if (iascii) { 167b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," SNES matrix-free approximation:\n");CHKERRQ(ierr); 168a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," err=%G (relative error in function evaluation)\n",ctx->error_rel);CHKERRQ(ierr); 169473c83c3SBarry Smith if (!ctx->type_name) { 170b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," The compute h routine has not yet been set\n");CHKERRQ(ierr); 171473c83c3SBarry Smith } else { 172b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Using %s compute h routine\n",ctx->type_name);CHKERRQ(ierr); 173473c83c3SBarry Smith } 1749a6cb015SBarry Smith if (ctx->ops->view) { 1759a6cb015SBarry Smith ierr = (*ctx->ops->view)(ctx,viewer);CHKERRQ(ierr); 1769a6cb015SBarry Smith } 1775cd90555SBarry Smith } else { 17879a5c55eSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for SNES matrix free matrix",((PetscObject)viewer)->type_name); 179eb9086c3SLois Curfman McInnes } 1803a40ed3dSBarry Smith PetscFunctionReturn(0); 181eb9086c3SLois Curfman McInnes } 182eb9086c3SLois Curfman McInnes 1834a2ae208SSatish Balay #undef __FUNCT__ 1848a124369SBarry Smith #define __FUNCT__ "MatAssemblyEnd_MFFD" 185be726c96SBarry Smith /* 18632dfb669SBarry Smith MatAssemblyEnd_MFFD - Resets the ctx->ncurrenth to zero. This 18765f2ba5bSLois Curfman McInnes allows the user to indicate the beginning of a new linear solve by calling 188be726c96SBarry Smith MatAssemblyXXX() on the matrix free matrix. This then allows the 18965f2ba5bSLois Curfman McInnes MatSNESMFCreate_WP() to properly compute ||U|| only the first time 19065f2ba5bSLois Curfman McInnes in the linear solver rather than every time. 191be726c96SBarry Smith */ 192dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_MFFD(Mat J,MatAssemblyType mt) 193be726c96SBarry Smith { 194dfbe8321SBarry Smith PetscErrorCode ierr; 19578392ef1SBarry Smith MatSNESMF j = (MatSNESMF)J->data; 196be726c96SBarry Smith 197be726c96SBarry Smith PetscFunctionBegin; 1985a655dc6SBarry Smith ierr = MatSNESMFResetHHistory(J);CHKERRQ(ierr); 199b0a32e0cSBarry Smith if (j->usesnes) { 2001d1367b7SBarry Smith ierr = SNESGetSolution(j->snes,&j->current_u);CHKERRQ(ierr); 2011d1367b7SBarry Smith ierr = SNESGetFunction(j->snes,&j->current_f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 202958c9bccSBarry Smith if (!j->w) { 2032740c1caSMatthew Knepley ierr = VecDuplicate(j->current_u, &j->w);CHKERRQ(ierr); 2042740c1caSMatthew Knepley } 2051d1367b7SBarry Smith } 206c5c390f1SBarry Smith j->vshift = 0.0; 207c5c390f1SBarry Smith j->vscale = 1.0; 208be726c96SBarry Smith PetscFunctionReturn(0); 209be726c96SBarry Smith } 210be726c96SBarry Smith 2114a2ae208SSatish Balay #undef __FUNCT__ 2128a124369SBarry Smith #define __FUNCT__ "MatMult_MFFD" 213eb9086c3SLois Curfman McInnes /* 214adb62b0dSMatthew Knepley MatMult_MFFD - Default matrix-free form for Jacobian-vector product, y = F'(u)*a: 215a4d4d686SBarry Smith 2169a6cb015SBarry Smith y ~= (F(u + ha) - F(u))/h, 217eb9086c3SLois Curfman McInnes where F = nonlinear function, as set by SNESSetFunction() 218eb9086c3SLois Curfman McInnes u = current iterate 219eb9086c3SLois Curfman McInnes h = difference interval 220eb9086c3SLois Curfman McInnes */ 221dfbe8321SBarry Smith PetscErrorCode MatMult_MFFD(Mat mat,Vec a,Vec y) 22239e2f89bSBarry Smith { 22378392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 224fae171e0SBarry Smith SNES snes; 225efb30889SBarry Smith PetscScalar h; 226fae171e0SBarry Smith Vec w,U,F; 227dfbe8321SBarry Smith PetscErrorCode ierr,(*eval_fct)(SNES,Vec,Vec)=0; 2284dc4c822SBarry Smith PetscTruth zeroa; 22939e2f89bSBarry Smith 2303a40ed3dSBarry Smith PetscFunctionBegin; 2319a6cb015SBarry Smith /* We log matrix-free matrix-vector products separately, so that we can 2329a6cb015SBarry Smith separate the performance monitoring from the cases that use conventional 2339a6cb015SBarry Smith storage. We may eventually modify event logging to associate events 2349a6cb015SBarry Smith with particular objects, hence alleviating the more general problem. */ 23546129b97SKris Buschelman ierr = PetscLogEventBegin(MATSNESMF_Mult,a,y,0,0);CHKERRQ(ierr); 23656cd22aeSBarry Smith 237fae171e0SBarry Smith snes = ctx->snes; 238fae171e0SBarry Smith w = ctx->w; 2391d1367b7SBarry Smith U = ctx->current_u; 24050361f65SLois Curfman McInnes 24185614651SBarry Smith /* 24285614651SBarry Smith Compute differencing parameter 24385614651SBarry Smith */ 2449a6cb015SBarry Smith if (!ctx->ops->compute) { 2452f859189SBarry Smith ierr = MatSNESMFSetType(mat,MATSNESMF_WP);CHKERRQ(ierr); 2465a655dc6SBarry Smith ierr = MatSNESMFSetFromOptions(mat);CHKERRQ(ierr); 2479a6cb015SBarry Smith } 2484dc4c822SBarry Smith ierr = (*ctx->ops->compute)(ctx,U,a,&h,&zeroa);CHKERRQ(ierr); 2494dc4c822SBarry Smith if (zeroa) { 25019bdad02SBarry Smith ierr = VecSet(y,0.0);CHKERRQ(ierr); 2514dc4c822SBarry Smith PetscFunctionReturn(0); 2524dc4c822SBarry Smith } 253a4d4d686SBarry Smith 2545b7f0c42SBarry Smith if (ctx->checkh) { 2555b7f0c42SBarry Smith ierr = (*ctx->checkh)(U,a,&h,ctx->checkhctx);CHKERRQ(ierr); 2565b7f0c42SBarry Smith } 2575b7f0c42SBarry Smith 258a4d4d686SBarry Smith /* keep a record of the current differencing parameter h */ 259a4d4d686SBarry Smith ctx->currenth = h; 260aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 261ae15b995SBarry Smith ierr = PetscInfo2(mat,"Current differencing parameter: %G + %G i\n",PetscRealPart(h),PetscImaginaryPart(h));CHKERRQ(ierr); 262a4d4d686SBarry Smith #else 263ae15b995SBarry Smith ierr = PetscInfo1(mat,"Current differencing parameter: %15.12e\n",h);CHKERRQ(ierr); 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 */ 2712dcb1b2aSMatthew Knepley ierr = VecWAXPY(w,h,a,U);CHKERRQ(ierr); 27285614651SBarry Smith 273b0a32e0cSBarry Smith if (ctx->usesnes) { 27485614651SBarry Smith eval_fct = SNESComputeFunction; 2751d1367b7SBarry Smith F = ctx->current_f; 2761302d50aSBarry Smith if (!F) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"You must call MatAssembly() even on matrix-free matrices"); 27739903ad8SBarry Smith ierr = (*eval_fct)(snes,w,y);CHKERRQ(ierr); 27885614651SBarry Smith } else { 27985614651SBarry Smith F = ctx->funcvec; 28085614651SBarry Smith /* compute func(U) as base for differencing */ 28185614651SBarry Smith if (ctx->ncurrenth == 1) { 28285614651SBarry Smith ierr = (*ctx->func)(snes,U,F,ctx->funcctx);CHKERRQ(ierr); 28385614651SBarry Smith } 28485614651SBarry Smith ierr = (*ctx->func)(snes,w,y,ctx->funcctx);CHKERRQ(ierr); 28585614651SBarry Smith } 286a4d4d686SBarry Smith 287efb30889SBarry Smith ierr = VecAXPY(y,-1.0,F);CHKERRQ(ierr); 288efb30889SBarry Smith ierr = VecScale(y,1.0/h);CHKERRQ(ierr); 289c5c390f1SBarry Smith 2902dcb1b2aSMatthew Knepley ierr = VecAXPBY(y,ctx->vshift,ctx->vscale,a);CHKERRQ(ierr); 291c5c390f1SBarry Smith 29274637425SBarry Smith if (ctx->sp) {ierr = MatNullSpaceRemove(ctx->sp,y,PETSC_NULL);CHKERRQ(ierr);} 293a4d4d686SBarry Smith 29446129b97SKris Buschelman ierr = PetscLogEventEnd(MATSNESMF_Mult,a,y,0,0);CHKERRQ(ierr); 295a4d4d686SBarry Smith PetscFunctionReturn(0); 296a4d4d686SBarry Smith } 297a4d4d686SBarry Smith 2984a2ae208SSatish Balay #undef __FUNCT__ 2998a124369SBarry Smith #define __FUNCT__ "MatGetDiagonal_MFFD" 300cf57b110SBarry Smith /* 3018a124369SBarry Smith MatGetDiagonal_MFFD - Gets the diagonal for a matrix free matrix 302cf57b110SBarry Smith 303cf57b110SBarry Smith y ~= (F(u + ha) - F(u))/h, 304cf57b110SBarry Smith where F = nonlinear function, as set by SNESSetFunction() 305cf57b110SBarry Smith u = current iterate 306cf57b110SBarry Smith h = difference interval 307cf57b110SBarry Smith */ 308dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_MFFD(Mat mat,Vec a) 309cf57b110SBarry Smith { 31078392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 311ea709b57SSatish Balay PetscScalar h,*aa,*ww,v; 31277d8c4bbSBarry Smith PetscReal epsilon = PETSC_SQRT_MACHINE_EPSILON,umin = 100.0*PETSC_SQRT_MACHINE_EPSILON; 31365df01d8SBarry Smith Vec w,U; 3146849ba73SBarry Smith PetscErrorCode ierr; 315a7cc72afSBarry Smith PetscInt i,rstart,rend; 316cf57b110SBarry Smith 317cf57b110SBarry Smith PetscFunctionBegin; 318cf57b110SBarry Smith if (!ctx->funci) { 3191302d50aSBarry Smith SETERRQ(PETSC_ERR_ORDER,"Requires 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; 347c5c390f1SBarry Smith 348c5c390f1SBarry Smith /* possibly shift and scale result */ 349c5c390f1SBarry Smith aa[i - rstart] = ctx->vshift + ctx->vscale*aa[i-rstart]; 350c5c390f1SBarry Smith 351cf57b110SBarry Smith ierr = VecGetArray(w,&ww);CHKERRQ(ierr); 352cf57b110SBarry Smith ww[i-rstart] -= h; 353cf57b110SBarry Smith ierr = VecRestoreArray(w,&ww);CHKERRQ(ierr); 354cf57b110SBarry Smith } 355cf57b110SBarry Smith ierr = VecRestoreArray(a,&aa);CHKERRQ(ierr); 356cf57b110SBarry Smith PetscFunctionReturn(0); 357cf57b110SBarry Smith } 358cf57b110SBarry Smith 359cf57b110SBarry Smith #undef __FUNCT__ 360c5c390f1SBarry Smith #define __FUNCT__ "MatShift_MFFD" 361f4df32b1SMatthew Knepley PetscErrorCode MatShift_MFFD(Mat Y,PetscScalar a) 362c5c390f1SBarry Smith { 36378392ef1SBarry Smith MatSNESMF shell = (MatSNESMF)Y->data; 364c5c390f1SBarry Smith PetscFunctionBegin; 365f4df32b1SMatthew Knepley shell->vshift += a; 366c5c390f1SBarry Smith PetscFunctionReturn(0); 367c5c390f1SBarry Smith } 368c5c390f1SBarry Smith 369c5c390f1SBarry Smith #undef __FUNCT__ 370c5c390f1SBarry Smith #define __FUNCT__ "MatScale_MFFD" 371f4df32b1SMatthew Knepley PetscErrorCode MatScale_MFFD(Mat Y,PetscScalar a) 372c5c390f1SBarry Smith { 37378392ef1SBarry Smith MatSNESMF shell = (MatSNESMF)Y->data; 374c5c390f1SBarry Smith PetscFunctionBegin; 375f4df32b1SMatthew Knepley shell->vscale *= a; 376c5c390f1SBarry Smith PetscFunctionReturn(0); 377c5c390f1SBarry Smith } 378c5c390f1SBarry Smith 379c5c390f1SBarry Smith 380c5c390f1SBarry Smith #undef __FUNCT__ 3814a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF" 38252baeb72SSatish Balay /*@ 38365f2ba5bSLois Curfman McInnes MatCreateSNESMF - Creates a matrix-free matrix context for use with 38465f2ba5bSLois Curfman McInnes a SNES solver. This matrix can be used as the Jacobian argument for 38565f2ba5bSLois Curfman McInnes the routine SNESSetJacobian(). 386a4d4d686SBarry Smith 387a4d4d686SBarry Smith Collective on SNES and Vec 388a4d4d686SBarry Smith 389a4d4d686SBarry Smith Input Parameters: 390a4d4d686SBarry Smith + snes - the SNES context 391a4d4d686SBarry Smith - x - vector where SNES solution is to be stored. 392a4d4d686SBarry Smith 393a4d4d686SBarry Smith Output Parameter: 394a4d4d686SBarry Smith . J - the matrix-free matrix 395a4d4d686SBarry Smith 39615091d37SBarry Smith Level: advanced 39715091d37SBarry Smith 398a4d4d686SBarry Smith Notes: 399a4d4d686SBarry Smith The matrix-free matrix context merely contains the function pointers 400a4d4d686SBarry Smith and work space for performing finite difference approximations of 40165f2ba5bSLois Curfman McInnes Jacobian-vector products, F'(u)*a, 4029a6cb015SBarry Smith 4039a6cb015SBarry Smith The default code uses the following approach to compute h 404a4d4d686SBarry Smith 405a4d4d686SBarry Smith .vb 40665f2ba5bSLois Curfman McInnes F'(u)*a = [F(u+h*a) - F(u)]/h where 407a4d4d686SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 408a4d4d686SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 otherwise 409a4d4d686SBarry Smith where 410a4d4d686SBarry Smith error_rel = square root of relative error in function evaluation 411a4d4d686SBarry Smith umin = minimum iterate parameter 412a4d4d686SBarry Smith .ve 413efb30889SBarry Smith (see MATSNESMF_WP or MATSNESMF_DS) 414a4d4d686SBarry Smith 4155a655dc6SBarry Smith The user can set the error_rel via MatSNESMFSetFunctionError() and 41665f2ba5bSLois Curfman McInnes umin via MatSNESMFDefaultSetUmin(); see the nonlinear solvers chapter 41765f2ba5bSLois Curfman McInnes of the users manual for details. 418a4d4d686SBarry Smith 419a4d4d686SBarry Smith The user should call MatDestroy() when finished with the matrix-free 420a4d4d686SBarry Smith matrix context. 421a4d4d686SBarry Smith 422a4d4d686SBarry Smith Options Database Keys: 423a4d4d686SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 424efb30889SBarry Smith + -snes_mf_type - wp or ds (see MATSNESMF_WP or MATSNESMF_DS) 4259a6cb015SBarry Smith . -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only) 426a4d4d686SBarry Smith - -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h 427a4d4d686SBarry Smith 428a4d4d686SBarry Smith .keywords: SNES, default, matrix-free, create, matrix 429a4d4d686SBarry Smith 4305a655dc6SBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError(), MatSNESMFDefaultSetUmin() 4311d1367b7SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), MatCreateMF(), 432fed8bd04SBarry Smith MatSNESMFGetH(),MatSNESMFKSPMonitor(), MatSNESMFRegisterDynamic), MatSNESMFComputeJacobian() 433a4d4d686SBarry Smith 434a4d4d686SBarry Smith @*/ 43563dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatCreateSNESMF(SNES snes,Vec x,Mat *J) 436a4d4d686SBarry Smith { 43778392ef1SBarry Smith MatSNESMF mfctx; 438dfbe8321SBarry Smith PetscErrorCode ierr; 4391d1367b7SBarry Smith 4401d1367b7SBarry Smith PetscFunctionBegin; 4411d1367b7SBarry Smith ierr = MatCreateMF(x,J);CHKERRQ(ierr); 4427e9d5209SBarry Smith 44378392ef1SBarry Smith mfctx = (MatSNESMF)(*J)->data; 4441d1367b7SBarry Smith mfctx->snes = snes; 445b0a32e0cSBarry Smith mfctx->usesnes = PETSC_TRUE; 44652e6d16bSBarry Smith ierr = PetscLogObjectParent(snes,*J);CHKERRQ(ierr); 4471d1367b7SBarry Smith PetscFunctionReturn(0); 4481d1367b7SBarry Smith } 4491d1367b7SBarry Smith 450cf3bea43SBarry Smith EXTERN_C_BEGIN 451cf3bea43SBarry Smith #undef __FUNCT__ 452cf3bea43SBarry Smith #define __FUNCT__ "MatSNESMFSetBase_FD" 45363dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetBase_FD(Mat J,Vec U) 454cf3bea43SBarry Smith { 455dfbe8321SBarry Smith PetscErrorCode ierr; 45678392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)J->data; 457cf3bea43SBarry Smith 458cf3bea43SBarry Smith PetscFunctionBegin; 459cf3bea43SBarry Smith ierr = MatSNESMFResetHHistory(J);CHKERRQ(ierr); 460cf3bea43SBarry Smith ctx->current_u = U; 461cf3bea43SBarry Smith ctx->usesnes = PETSC_FALSE; 462958c9bccSBarry Smith if (!ctx->w) { 463ba6a83e5SMatthew Knepley ierr = VecDuplicate(ctx->current_u, &ctx->w);CHKERRQ(ierr); 464ba6a83e5SMatthew Knepley } 46532dfb669SBarry Smith J->assembled = PETSC_TRUE; 466cf3bea43SBarry Smith PetscFunctionReturn(0); 467cf3bea43SBarry Smith } 468cf3bea43SBarry Smith EXTERN_C_END 4696849ba73SBarry Smith typedef PetscErrorCode (*FCN3)(Vec,Vec,PetscScalar*,void*); /* force argument to next function to not be extern C*/ 4705b7f0c42SBarry Smith EXTERN_C_BEGIN 4715b7f0c42SBarry Smith #undef __FUNCT__ 4725b7f0c42SBarry Smith #define __FUNCT__ "MatSNESMFSetCheckh_FD" 47363dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetCheckh_FD(Mat J,FCN3 fun,void*ectx) 4745b7f0c42SBarry Smith { 47578392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)J->data; 4765b7f0c42SBarry Smith 4775b7f0c42SBarry Smith PetscFunctionBegin; 4785b7f0c42SBarry Smith ctx->checkh = fun; 4795b7f0c42SBarry Smith ctx->checkhctx = ectx; 4805b7f0c42SBarry Smith PetscFunctionReturn(0); 4815b7f0c42SBarry Smith } 4825b7f0c42SBarry Smith EXTERN_C_END 4835b7f0c42SBarry Smith 4844a2ae208SSatish Balay #undef __FUNCT__ 4857e9d5209SBarry Smith #define __FUNCT__ "MatSNESMFSetFromOptions" 4867e9d5209SBarry Smith /*@ 4877e9d5209SBarry Smith MatSNESMFSetFromOptions - Sets the MatSNESMF options from the command line 4887e9d5209SBarry Smith parameter. 4897e9d5209SBarry Smith 4907e9d5209SBarry Smith Collective on Mat 4917e9d5209SBarry Smith 4927e9d5209SBarry Smith Input Parameters: 4937e9d5209SBarry Smith . mat - the matrix obtained with MatCreateSNESMF() 4947e9d5209SBarry Smith 4957e9d5209SBarry Smith Options Database Keys: 496efb30889SBarry Smith + -snes_mf_type - wp or ds (see MATSNESMF_WP or MATSNESMF_DS) 4977e9d5209SBarry Smith - -snes_mf_err - square root of estimated relative error in function evaluation 4987e9d5209SBarry Smith - -snes_mf_period - how often h is recomputed, defaults to 1, everytime 4997e9d5209SBarry Smith 5007e9d5209SBarry Smith Level: advanced 5017e9d5209SBarry Smith 5027e9d5209SBarry Smith .keywords: SNES, matrix-free, parameters 5037e9d5209SBarry Smith 5047e9d5209SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(), 5057e9d5209SBarry Smith MatSNESMFResetHHistory(), MatSNESMFKSPMonitor() 5067e9d5209SBarry Smith @*/ 50763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetFromOptions(Mat mat) 5087e9d5209SBarry Smith { 50978392ef1SBarry Smith MatSNESMF mfctx = (MatSNESMF)mat->data; 510dfbe8321SBarry Smith PetscErrorCode ierr; 5117e9d5209SBarry Smith PetscTruth flg; 5127e9d5209SBarry Smith char ftype[256]; 5137e9d5209SBarry Smith 5147e9d5209SBarry Smith PetscFunctionBegin; 5157e9d5209SBarry Smith if (!MatSNESMFRegisterAllCalled) {ierr = MatSNESMFRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5167e9d5209SBarry Smith 5177e9d5209SBarry Smith ierr = PetscOptionsBegin(mfctx->comm,mfctx->prefix,"Set matrix free computation parameters","MatSNESMF");CHKERRQ(ierr); 5187e9d5209SBarry Smith ierr = PetscOptionsList("-snes_mf_type","Matrix free type","MatSNESMFSetType",MatSNESMPetscFList,mfctx->type_name,ftype,256,&flg);CHKERRQ(ierr); 5197e9d5209SBarry Smith if (flg) { 5207e9d5209SBarry Smith ierr = MatSNESMFSetType(mat,ftype);CHKERRQ(ierr); 5217e9d5209SBarry Smith } 5227e9d5209SBarry Smith 52387828ca2SBarry Smith ierr = PetscOptionsReal("-snes_mf_err","set sqrt relative error in function","MatSNESMFSetFunctionError",mfctx->error_rel,&mfctx->error_rel,0);CHKERRQ(ierr); 5247e9d5209SBarry Smith ierr = PetscOptionsInt("-snes_mf_period","how often h is recomputed","MatSNESMFSetPeriod",mfctx->recomputeperiod,&mfctx->recomputeperiod,0);CHKERRQ(ierr); 5257e9d5209SBarry Smith if (mfctx->snes) { 5267e9d5209SBarry Smith ierr = PetscOptionsName("-snes_mf_ksp_monitor","Monitor matrix-free parameters","MatSNESMFKSPMonitor",&flg);CHKERRQ(ierr); 5277e9d5209SBarry Smith if (flg) { 5287e9d5209SBarry Smith KSP ksp; 52994b7f48cSBarry Smith ierr = SNESGetKSP(mfctx->snes,&ksp);CHKERRQ(ierr); 530a6570f20SBarry Smith ierr = KSPMonitorSet(ksp,MatSNESMFKSPMonitor,PETSC_NULL,0);CHKERRQ(ierr); 5317e9d5209SBarry Smith } 5327e9d5209SBarry Smith } 5335b7f0c42SBarry Smith ierr = PetscOptionsName("-snes_mf_check_positivity","Insure that U + h*a is nonnegative","MatSNESMFSetCheckh",&flg);CHKERRQ(ierr); 5345b7f0c42SBarry Smith if (flg) { 5355b7f0c42SBarry Smith ierr = MatSNESMFSetCheckh(mat,MatSNESMFCheckPositivity,0);CHKERRQ(ierr); 5365b7f0c42SBarry Smith } 5377e9d5209SBarry Smith if (mfctx->ops->setfromoptions) { 5387e9d5209SBarry Smith ierr = (*mfctx->ops->setfromoptions)(mfctx);CHKERRQ(ierr); 5397e9d5209SBarry Smith } 5407e9d5209SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 5417e9d5209SBarry Smith PetscFunctionReturn(0); 5427e9d5209SBarry Smith } 5437e9d5209SBarry Smith 5440bad9183SKris Buschelman /*MC 545fafad747SKris Buschelman MATMFFD - MATMFFD = "mffd" - A matrix free matrix type. 5460bad9183SKris Buschelman 5470bad9183SKris Buschelman Level: advanced 5480bad9183SKris Buschelman 5498bc8193eSBarry Smith .seealso: MatCreateMF(), MatCreateSNESMF() 5500bad9183SKris Buschelman M*/ 551fe93831dSBarry Smith EXTERN_C_BEGIN 5527e9d5209SBarry Smith #undef __FUNCT__ 5537e9d5209SBarry Smith #define __FUNCT__ "MatCreate_MFFD" 55463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatCreate_MFFD(Mat A) 5557e9d5209SBarry Smith { 55678392ef1SBarry Smith MatSNESMF mfctx; 557dfbe8321SBarry Smith PetscErrorCode ierr; 5587e9d5209SBarry Smith 5597e9d5209SBarry Smith PetscFunctionBegin; 5606e087cb5SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 5616e087cb5SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 5626e087cb5SMatthew Knepley #endif 5636e087cb5SMatthew Knepley 56478392ef1SBarry Smith ierr = PetscHeaderCreate(mfctx,_p_MatSNESMF,struct _MFOps,MATSNESMFCTX_COOKIE,0,"SNESMF",A->comm,MatDestroy_MFFD,MatView_MFFD);CHKERRQ(ierr); 5657e9d5209SBarry Smith mfctx->sp = 0; 5667e9d5209SBarry Smith mfctx->snes = 0; 56777d8c4bbSBarry Smith mfctx->error_rel = PETSC_SQRT_MACHINE_EPSILON; 5687e9d5209SBarry Smith mfctx->recomputeperiod = 1; 5697e9d5209SBarry Smith mfctx->count = 0; 5707e9d5209SBarry Smith mfctx->currenth = 0.0; 5717e9d5209SBarry Smith mfctx->historyh = PETSC_NULL; 5727e9d5209SBarry Smith mfctx->ncurrenth = 0; 5737e9d5209SBarry Smith mfctx->maxcurrenth = 0; 5747e9d5209SBarry Smith mfctx->type_name = 0; 5757e9d5209SBarry Smith mfctx->usesnes = PETSC_FALSE; 5767e9d5209SBarry Smith 577c5c390f1SBarry Smith mfctx->vshift = 0.0; 578c5c390f1SBarry Smith mfctx->vscale = 1.0; 579c5c390f1SBarry Smith 5807e9d5209SBarry Smith /* 5817e9d5209SBarry Smith Create the empty data structure to contain compute-h routines. 5827e9d5209SBarry Smith These will be filled in below from the command line options or 5837e9d5209SBarry Smith a later call with MatSNESMFSetType() or if that is not called 5848a124369SBarry Smith then it will default in the first use of MatMult_MFFD() 5857e9d5209SBarry Smith */ 5867e9d5209SBarry Smith mfctx->ops->compute = 0; 5877e9d5209SBarry Smith mfctx->ops->destroy = 0; 5887e9d5209SBarry Smith mfctx->ops->view = 0; 5897e9d5209SBarry Smith mfctx->ops->setfromoptions = 0; 5907e9d5209SBarry Smith mfctx->hctx = 0; 5917e9d5209SBarry Smith 5927e9d5209SBarry Smith mfctx->func = 0; 5937e9d5209SBarry Smith mfctx->funcctx = 0; 5947e9d5209SBarry Smith mfctx->funcvec = 0; 595ba6a83e5SMatthew Knepley mfctx->w = PETSC_NULL; 5967e9d5209SBarry Smith 59765df01d8SBarry Smith A->data = mfctx; 5987e9d5209SBarry Smith 5998a124369SBarry Smith A->ops->mult = MatMult_MFFD; 6008a124369SBarry Smith A->ops->destroy = MatDestroy_MFFD; 6018a124369SBarry Smith A->ops->view = MatView_MFFD; 6028a124369SBarry Smith A->ops->assemblyend = MatAssemblyEnd_MFFD; 6038a124369SBarry Smith A->ops->getdiagonal = MatGetDiagonal_MFFD; 604c5c390f1SBarry Smith A->ops->scale = MatScale_MFFD; 605c5c390f1SBarry Smith A->ops->shift = MatShift_MFFD; 60665df01d8SBarry Smith A->ops->setfromoptions = MatSNESMFSetFromOptions; 60732dfb669SBarry Smith A->assembled = PETSC_TRUE; 6087e9d5209SBarry Smith 60965df01d8SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSNESMFSetBase_C","MatSNESMFSetBase_FD",MatSNESMFSetBase_FD);CHKERRQ(ierr); 610c5c390f1SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSNESMFSetFunctioniBase_C","MatSNESMFSetFunctioniBase_FD",MatSNESMFSetFunctioniBase_FD);CHKERRQ(ierr); 61187828ca2SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSNESMFSetFunctioni_C","MatSNESMFSetFunctioni_FD",MatSNESMFSetFunctioni_FD);CHKERRQ(ierr); 6125b7f0c42SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSNESMFSetCheckh_C","MatSNESMFSetCheckh_FD",MatSNESMFSetCheckh_FD);CHKERRQ(ierr); 61365df01d8SBarry Smith mfctx->mat = A; 61417667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATMFFD);CHKERRQ(ierr); 6157e9d5209SBarry Smith PetscFunctionReturn(0); 6167e9d5209SBarry Smith } 617fe93831dSBarry Smith EXTERN_C_END 6187e9d5209SBarry Smith 6197e9d5209SBarry Smith #undef __FUNCT__ 6204a2ae208SSatish Balay #define __FUNCT__ "MatCreateMF" 62152baeb72SSatish Balay /*@ 6221d1367b7SBarry Smith MatCreateMF - Creates a matrix-free matrix. See also MatCreateSNESMF() 6231d1367b7SBarry Smith 6241d1367b7SBarry Smith Collective on Vec 6251d1367b7SBarry Smith 6261d1367b7SBarry Smith Input Parameters: 6271d1367b7SBarry Smith . x - vector that defines layout of the vectors and matrices 6281d1367b7SBarry Smith 6291d1367b7SBarry Smith Output Parameter: 6301d1367b7SBarry Smith . J - the matrix-free matrix 6311d1367b7SBarry Smith 6321d1367b7SBarry Smith Level: advanced 6331d1367b7SBarry Smith 6341d1367b7SBarry Smith Notes: 6351d1367b7SBarry Smith The matrix-free matrix context merely contains the function pointers 6361d1367b7SBarry Smith and work space for performing finite difference approximations of 6371d1367b7SBarry Smith Jacobian-vector products, F'(u)*a, 6381d1367b7SBarry Smith 6391d1367b7SBarry Smith The default code uses the following approach to compute h 6401d1367b7SBarry Smith 6411d1367b7SBarry Smith .vb 6421d1367b7SBarry Smith F'(u)*a = [F(u+h*a) - F(u)]/h where 6431d1367b7SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 6441d1367b7SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 otherwise 6451d1367b7SBarry Smith where 6461d1367b7SBarry Smith error_rel = square root of relative error in function evaluation 6471d1367b7SBarry Smith umin = minimum iterate parameter 6481d1367b7SBarry Smith .ve 6491d1367b7SBarry Smith 6501d1367b7SBarry Smith The user can set the error_rel via MatSNESMFSetFunctionError() and 6511d1367b7SBarry Smith umin via MatSNESMFDefaultSetUmin(); see the nonlinear solvers chapter 6521d1367b7SBarry Smith of the users manual for details. 6531d1367b7SBarry Smith 6541d1367b7SBarry Smith The user should call MatDestroy() when finished with the matrix-free 6551d1367b7SBarry Smith matrix context. 6561d1367b7SBarry Smith 6571d1367b7SBarry Smith Options Database Keys: 6581d1367b7SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 6591d1367b7SBarry Smith . -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only) 6605b7f0c42SBarry Smith . -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h 6615b7f0c42SBarry Smith - -snes_mf_check_positivity 6621d1367b7SBarry Smith 6631d1367b7SBarry Smith .keywords: default, matrix-free, create, matrix 6641d1367b7SBarry Smith 6656ce558aeSBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError(), MatSNESMFDefaultSetUmin(), MatSNESMFSetFunction() 6661d1367b7SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), MatCreateSNESMF(), 667fed8bd04SBarry Smith MatSNESMFGetH(),MatSNESMFKSPMonitor(), MatSNESMFRegisterDynamic),, MatSNESMFComputeJacobian() 6681d1367b7SBarry Smith 6691d1367b7SBarry Smith @*/ 67063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatCreateMF(Vec x,Mat *J) 6711d1367b7SBarry Smith { 672a4d4d686SBarry Smith MPI_Comm comm; 6736849ba73SBarry Smith PetscErrorCode ierr; 674a7cc72afSBarry Smith PetscInt n,nloc; 675a4d4d686SBarry Smith 676a4d4d686SBarry Smith PetscFunctionBegin; 6771d1367b7SBarry Smith ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 67865df01d8SBarry Smith ierr = VecGetSize(x,&n);CHKERRQ(ierr); 67965df01d8SBarry Smith ierr = VecGetLocalSize(x,&nloc);CHKERRQ(ierr); 680f69a0ea3SMatthew Knepley ierr = MatCreate(comm,J);CHKERRQ(ierr); 681f69a0ea3SMatthew Knepley ierr = MatSetSizes(*J,nloc,nloc,n,n);CHKERRQ(ierr); 682e56c5435SBarry Smith ierr = MatRegisterDynamic(MATMFFD,0,"MatCreate_MFFD",MatCreate_MFFD);CHKERRQ(ierr); 68365df01d8SBarry Smith ierr = MatSetType(*J,MATMFFD);CHKERRQ(ierr); 6849a6cb015SBarry Smith PetscFunctionReturn(0); 6859a6cb015SBarry Smith } 6869a6cb015SBarry Smith 687a4d4d686SBarry Smith 6884a2ae208SSatish Balay #undef __FUNCT__ 6894a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFGetH" 690a4d4d686SBarry Smith /*@ 69165f2ba5bSLois Curfman McInnes MatSNESMFGetH - Gets the last value that was used as the differencing 692a4d4d686SBarry Smith parameter. 693a4d4d686SBarry Smith 694a4d4d686SBarry Smith Not Collective 695a4d4d686SBarry Smith 696a4d4d686SBarry Smith Input Parameters: 6975a655dc6SBarry Smith . mat - the matrix obtained with MatCreateSNESMF() 698a4d4d686SBarry Smith 699a4d4d686SBarry Smith Output Paramter: 700a4d4d686SBarry Smith . h - the differencing step size 701a4d4d686SBarry Smith 70215091d37SBarry Smith Level: advanced 70315091d37SBarry Smith 704a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters 705a4d4d686SBarry Smith 7065a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFSetHHistory(), 7075a655dc6SBarry Smith MatSNESMFResetHHistory(),MatSNESMFKSPMonitor() 708a4d4d686SBarry Smith @*/ 70963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFGetH(Mat mat,PetscScalar *h) 710a4d4d686SBarry Smith { 71178392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 712a4d4d686SBarry Smith 713a4d4d686SBarry Smith PetscFunctionBegin; 714a4d4d686SBarry Smith *h = ctx->currenth; 715a4d4d686SBarry Smith PetscFunctionReturn(0); 716a4d4d686SBarry Smith } 717a4d4d686SBarry Smith 7184a2ae208SSatish Balay #undef __FUNCT__ 7194a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFKSPMonitor" 720906ed7ccSBarry Smith /*@C 721906ed7ccSBarry Smith MatSNESMFKSPMonitor - A KSP monitor for use with the PETSc 72265f2ba5bSLois Curfman McInnes SNES matrix free routines. Prints the differencing parameter used at 72365f2ba5bSLois Curfman McInnes each step. 724906ed7ccSBarry Smith 725906ed7ccSBarry Smith Collective on KSP 726906ed7ccSBarry Smith 727906ed7ccSBarry Smith Input Parameters: 728906ed7ccSBarry Smith + ksp - the Krylov solver object 729906ed7ccSBarry Smith . n - the current iteration 730906ed7ccSBarry Smith . rnorm - the current residual norm (may be preconditioned or not depending on solver and options 731906ed7ccSBarry Smith _ dummy - unused argument 732906ed7ccSBarry Smith 733906ed7ccSBarry Smith Options Database: 734906ed7ccSBarry Smith . -snes_mf_ksp_monitor - turn this monitor on 735906ed7ccSBarry Smith 736a6570f20SBarry Smith Notes: Use KSPMonitorSet(ksp,MatSNESMFKSPMonitor,PETSC_NULL,PETSC_NULL); 737906ed7ccSBarry Smith 738a6570f20SBarry Smith .seealso: KSPMonitorSet() 739906ed7ccSBarry Smith 740906ed7ccSBarry Smith @*/ 74163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFKSPMonitor(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy) 742a4d4d686SBarry Smith { 74378392ef1SBarry Smith MatSNESMF ctx; 744dfbe8321SBarry Smith PetscErrorCode ierr; 745a4d4d686SBarry Smith Mat mat; 746a4d4d686SBarry Smith MPI_Comm comm; 747a4d4d686SBarry Smith PetscTruth nonzeroinitialguess; 748a4d4d686SBarry Smith 749a4d4d686SBarry Smith PetscFunctionBegin; 750a4d4d686SBarry Smith ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr); 751a4d4d686SBarry Smith ierr = KSPGetInitialGuessNonzero(ksp,&nonzeroinitialguess);CHKERRQ(ierr); 752906ed7ccSBarry Smith ierr = KSPGetOperators(ksp,&mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 75378392ef1SBarry Smith ctx = (MatSNESMF)mat->data; 7547e9d5209SBarry Smith 755a4d4d686SBarry Smith if (n > 0 || nonzeroinitialguess) { 756aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 757a83599f4SBarry Smith ierr = PetscPrintf(comm,"%D KSP Residual norm %14.12e h %G + %G i\n",n,rnorm, 758329f5518SBarry Smith PetscRealPart(ctx->currenth),PetscImaginaryPart(ctx->currenth));CHKERRQ(ierr); 759a4d4d686SBarry Smith #else 760a83599f4SBarry Smith ierr = PetscPrintf(comm,"%D KSP Residual norm %14.12e h %G \n",n,rnorm,ctx->currenth);CHKERRQ(ierr); 761a4d4d686SBarry Smith #endif 762a4d4d686SBarry Smith } else { 76377431f27SBarry Smith ierr = PetscPrintf(comm,"%D KSP Residual norm %14.12e\n",n,rnorm);CHKERRQ(ierr); 764a4d4d686SBarry Smith } 765a4d4d686SBarry Smith PetscFunctionReturn(0); 766a4d4d686SBarry Smith } 767a4d4d686SBarry Smith 7684a2ae208SSatish Balay #undef __FUNCT__ 7694a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetFunction" 77085614651SBarry Smith /*@C 77185614651SBarry Smith MatSNESMFSetFunction - Sets the function used in applying the matrix free. 77285614651SBarry Smith 77385614651SBarry Smith Collective on Mat 77485614651SBarry Smith 77585614651SBarry Smith Input Parameters: 77685614651SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 77785614651SBarry Smith . v - workspace vector 77885614651SBarry Smith . func - the function to use 77985614651SBarry Smith - funcctx - optional function context passed to function 78085614651SBarry Smith 78185614651SBarry Smith Level: advanced 78285614651SBarry Smith 78385614651SBarry Smith Notes: 78485614651SBarry Smith If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free 78585614651SBarry Smith matrix inside your compute Jacobian routine 78685614651SBarry Smith 78785614651SBarry Smith If this is not set then it will use the function set with SNESSetFunction() 78885614651SBarry Smith 78985614651SBarry Smith .keywords: SNES, matrix-free, function 79085614651SBarry Smith 79185614651SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 79285614651SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 79385614651SBarry Smith MatSNESMFKSPMonitor(), SNESetFunction() 79485614651SBarry Smith @*/ 79563dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetFunction(Mat mat,Vec v,PetscErrorCode (*func)(SNES,Vec,Vec,void *),void *funcctx) 79685614651SBarry Smith { 79778392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 79885614651SBarry Smith 79985614651SBarry Smith PetscFunctionBegin; 80085614651SBarry Smith ctx->func = func; 80185614651SBarry Smith ctx->funcctx = funcctx; 80285614651SBarry Smith ctx->funcvec = v; 80385614651SBarry Smith PetscFunctionReturn(0); 80485614651SBarry Smith } 80585614651SBarry Smith 806cf57b110SBarry Smith #undef __FUNCT__ 807cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioni" 808cf57b110SBarry Smith /*@C 809cf57b110SBarry Smith MatSNESMFSetFunctioni - Sets the function for a single component 810cf57b110SBarry Smith 811cf57b110SBarry Smith Collective on Mat 812cf57b110SBarry Smith 813cf57b110SBarry Smith Input Parameters: 814cf57b110SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 815cf57b110SBarry Smith - funci - the function to use 816cf57b110SBarry Smith 817cf57b110SBarry Smith Level: advanced 818cf57b110SBarry Smith 819cf57b110SBarry Smith Notes: 820cf57b110SBarry Smith If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free 821cf57b110SBarry Smith matrix inside your compute Jacobian routine 822cf57b110SBarry Smith 823cf57b110SBarry Smith 824cf57b110SBarry Smith .keywords: SNES, matrix-free, function 825cf57b110SBarry Smith 826cf57b110SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 827cf57b110SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 828cf57b110SBarry Smith MatSNESMFKSPMonitor(), SNESetFunction() 829cf57b110SBarry Smith @*/ 83063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetFunctioni(Mat mat,PetscErrorCode (*funci)(PetscInt,Vec,PetscScalar*,void *)) 831cf57b110SBarry Smith { 832a7cc72afSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscErrorCode (*)(PetscInt,Vec,PetscScalar*,void *)); 833cf57b110SBarry Smith 834cf57b110SBarry Smith PetscFunctionBegin; 8354482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 836c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSNESMFSetFunctioni_C",(void (**)(void))&f);CHKERRQ(ierr); 83787828ca2SBarry Smith if (f) { 83887828ca2SBarry Smith ierr = (*f)(mat,funci);CHKERRQ(ierr); 83987828ca2SBarry Smith } 840cf57b110SBarry Smith PetscFunctionReturn(0); 841cf57b110SBarry Smith } 842cf57b110SBarry Smith 84387828ca2SBarry Smith 844cf57b110SBarry Smith #undef __FUNCT__ 845cf57b110SBarry Smith #define __FUNCT__ "MatSNESMFSetFunctioniBase" 846cf57b110SBarry Smith /*@C 847cf57b110SBarry Smith MatSNESMFSetFunctioniBase - Sets the base vector for a single component function evaluation 848cf57b110SBarry Smith 849cf57b110SBarry Smith Collective on Mat 850cf57b110SBarry Smith 851cf57b110SBarry Smith Input Parameters: 852cf57b110SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 853cf57b110SBarry Smith - func - the function to use 854cf57b110SBarry Smith 855cf57b110SBarry Smith Level: advanced 856cf57b110SBarry Smith 857cf57b110SBarry Smith Notes: 858cf57b110SBarry Smith If you use this you MUST call MatAssemblyBegin()/MatAssemblyEnd() on the matrix free 859cf57b110SBarry Smith matrix inside your compute Jacobian routine 860cf57b110SBarry Smith 861cf57b110SBarry Smith 862cf57b110SBarry Smith .keywords: SNES, matrix-free, function 863cf57b110SBarry Smith 864cf57b110SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 865cf57b110SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 866cf57b110SBarry Smith MatSNESMFKSPMonitor(), SNESetFunction() 867cf57b110SBarry Smith @*/ 86863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetFunctioniBase(Mat mat,PetscErrorCode (*func)(Vec,void *)) 869cf57b110SBarry Smith { 8706849ba73SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscErrorCode (*)(Vec,void *)); 871cf57b110SBarry Smith 872cf57b110SBarry Smith PetscFunctionBegin; 8734482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 874c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSNESMFSetFunctioniBase_C",(void (**)(void))&f);CHKERRQ(ierr); 87587828ca2SBarry Smith if (f) { 87687828ca2SBarry Smith ierr = (*f)(mat,func);CHKERRQ(ierr); 87787828ca2SBarry Smith } 878cf57b110SBarry Smith PetscFunctionReturn(0); 879cf57b110SBarry Smith } 880cf57b110SBarry Smith 88185614651SBarry Smith 8824a2ae208SSatish Balay #undef __FUNCT__ 8834a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetPeriod" 884329f5518SBarry Smith /*@ 885329f5518SBarry Smith MatSNESMFSetPeriod - Sets how often h is recomputed, by default it is everytime 886329f5518SBarry Smith 887329f5518SBarry Smith Collective on Mat 888329f5518SBarry Smith 889329f5518SBarry Smith Input Parameters: 890329f5518SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 891329f5518SBarry Smith - period - 1 for everytime, 2 for every second etc 892329f5518SBarry Smith 893329f5518SBarry Smith Options Database Keys: 894329f5518SBarry Smith + -snes_mf_period <period> 895329f5518SBarry Smith 896329f5518SBarry Smith Level: advanced 897329f5518SBarry Smith 898329f5518SBarry Smith 899329f5518SBarry Smith .keywords: SNES, matrix-free, parameters 900329f5518SBarry Smith 901329f5518SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 902329f5518SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 903329f5518SBarry Smith MatSNESMFKSPMonitor() 904329f5518SBarry Smith @*/ 90563dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetPeriod(Mat mat,PetscInt period) 906329f5518SBarry Smith { 90778392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 908329f5518SBarry Smith 909329f5518SBarry Smith PetscFunctionBegin; 910329f5518SBarry Smith ctx->recomputeperiod = period; 911329f5518SBarry Smith PetscFunctionReturn(0); 912329f5518SBarry Smith } 913329f5518SBarry Smith 9144a2ae208SSatish Balay #undef __FUNCT__ 9154a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetFunctionError" 916a4d4d686SBarry Smith /*@ 9175a655dc6SBarry Smith MatSNESMFSetFunctionError - Sets the error_rel for the approximation of 918a4d4d686SBarry Smith matrix-vector products using finite differences. 919a4d4d686SBarry Smith 920a4d4d686SBarry Smith Collective on Mat 921a4d4d686SBarry Smith 922a4d4d686SBarry Smith Input Parameters: 9235a655dc6SBarry Smith + mat - the matrix free matrix created via MatCreateSNESMF() 9249a6cb015SBarry Smith - error_rel - relative error (should be set to the square root of 925a4d4d686SBarry Smith the relative error in the function evaluations) 926a4d4d686SBarry Smith 92715091d37SBarry Smith Options Database Keys: 92815091d37SBarry Smith + -snes_mf_err <error_rel> - Sets error_rel 92915091d37SBarry Smith 93015091d37SBarry Smith Level: advanced 93115091d37SBarry Smith 932a4d4d686SBarry Smith Notes: 933a4d4d686SBarry Smith The default matrix-free matrix-vector product routine computes 934a4d4d686SBarry Smith .vb 93565f2ba5bSLois Curfman McInnes F'(u)*a = [F(u+h*a) - F(u)]/h where 936a4d4d686SBarry Smith h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 937a4d4d686SBarry Smith = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 else 938a4d4d686SBarry Smith .ve 939a4d4d686SBarry Smith 940a4d4d686SBarry Smith .keywords: SNES, matrix-free, parameters 941a4d4d686SBarry Smith 9425a655dc6SBarry Smith .seealso: MatCreateSNESMF(),MatSNESMFGetH(), 9435a655dc6SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 9445a655dc6SBarry Smith MatSNESMFKSPMonitor() 945a4d4d686SBarry Smith @*/ 94663dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetFunctionError(Mat mat,PetscReal error) 947a4d4d686SBarry Smith { 94878392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)mat->data; 949a4d4d686SBarry Smith 950a4d4d686SBarry Smith PetscFunctionBegin; 951a4d4d686SBarry Smith if (error != PETSC_DEFAULT) ctx->error_rel = error; 952a4d4d686SBarry Smith PetscFunctionReturn(0); 953a4d4d686SBarry Smith } 954a4d4d686SBarry Smith 9554a2ae208SSatish Balay #undef __FUNCT__ 9564a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFAddNullSpace" 957a4d4d686SBarry Smith /*@ 95865f2ba5bSLois Curfman McInnes MatSNESMFAddNullSpace - Provides a null space that an operator is 95965f2ba5bSLois Curfman McInnes supposed to have. Since roundoff will create a small component in 96065f2ba5bSLois Curfman McInnes the null space, if you know the null space you may have it 96165f2ba5bSLois Curfman McInnes automatically removed. 962a4d4d686SBarry Smith 963a4d4d686SBarry Smith Collective on Mat 964a4d4d686SBarry Smith 965a4d4d686SBarry Smith Input Parameters: 966a4d4d686SBarry Smith + J - the matrix-free matrix context 96774637425SBarry Smith - nullsp - object created with MatNullSpaceCreate() 968a4d4d686SBarry Smith 96915091d37SBarry Smith Level: advanced 97015091d37SBarry Smith 971a4d4d686SBarry Smith .keywords: SNES, matrix-free, null space 972a4d4d686SBarry Smith 97374637425SBarry Smith .seealso: MatNullSpaceCreate(), MatSNESMFGetH(), MatCreateSNESMF(), 9745a655dc6SBarry Smith MatSNESMFSetHHistory(), MatSNESMFResetHHistory(), 9755a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFErrorRel() 976a4d4d686SBarry Smith @*/ 97763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFAddNullSpace(Mat J,MatNullSpace nullsp) 978a4d4d686SBarry Smith { 979dfbe8321SBarry Smith PetscErrorCode ierr; 98078392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)J->data; 981a4d4d686SBarry Smith 982a4d4d686SBarry Smith PetscFunctionBegin; 98385614651SBarry Smith ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 984c3122656SLisandro Dalcin if (ctx->sp) { ierr = MatNullSpaceDestroy(ctx->sp);CHKERRQ(ierr); } 985c3122656SLisandro Dalcin ctx->sp = nullsp; 986a4d4d686SBarry Smith PetscFunctionReturn(0); 987a4d4d686SBarry Smith } 988a4d4d686SBarry Smith 9894a2ae208SSatish Balay #undef __FUNCT__ 9904a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetHHistory" 991a4d4d686SBarry Smith /*@ 99265f2ba5bSLois Curfman McInnes MatSNESMFSetHHistory - Sets an array to collect a history of the 99365f2ba5bSLois Curfman McInnes differencing values (h) computed for the matrix-free product. 994a4d4d686SBarry Smith 995a4d4d686SBarry Smith Collective on Mat 996a4d4d686SBarry Smith 997a4d4d686SBarry Smith Input Parameters: 998a4d4d686SBarry Smith + J - the matrix-free matrix context 99965f2ba5bSLois Curfman McInnes . histroy - space to hold the history 100065f2ba5bSLois Curfman McInnes - nhistory - number of entries in history, if more entries are generated than 100165f2ba5bSLois Curfman McInnes nhistory, then the later ones are discarded 1002a4d4d686SBarry Smith 100315091d37SBarry Smith Level: advanced 100415091d37SBarry Smith 1005a4d4d686SBarry Smith Notes: 100665f2ba5bSLois Curfman McInnes Use MatSNESMFResetHHistory() to reset the history counter and collect 100765f2ba5bSLois Curfman McInnes a new batch of differencing parameters, h. 1008a4d4d686SBarry Smith 1009a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history 1010a4d4d686SBarry Smith 10115a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(), 10125a655dc6SBarry Smith MatSNESMFResetHHistory(), 10135a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError() 1014a4d4d686SBarry Smith 1015a4d4d686SBarry Smith @*/ 101663dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetHHistory(Mat J,PetscScalar history[],PetscInt nhistory) 1017a4d4d686SBarry Smith { 101878392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)J->data; 1019a4d4d686SBarry Smith 1020a4d4d686SBarry Smith PetscFunctionBegin; 1021a4d4d686SBarry Smith ctx->historyh = history; 1022a4d4d686SBarry Smith ctx->maxcurrenth = nhistory; 1023a4d4d686SBarry Smith ctx->currenth = 0; 1024a4d4d686SBarry Smith PetscFunctionReturn(0); 1025a4d4d686SBarry Smith } 1026a4d4d686SBarry Smith 10274a2ae208SSatish Balay #undef __FUNCT__ 10284a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFResetHHistory" 1029a4d4d686SBarry Smith /*@ 10305a655dc6SBarry Smith MatSNESMFResetHHistory - Resets the counter to zero to begin 1031a4d4d686SBarry Smith collecting a new set of differencing histories. 1032a4d4d686SBarry Smith 1033a4d4d686SBarry Smith Collective on Mat 1034a4d4d686SBarry Smith 1035a4d4d686SBarry Smith Input Parameters: 1036a4d4d686SBarry Smith . J - the matrix-free matrix context 1037a4d4d686SBarry Smith 103815091d37SBarry Smith Level: advanced 103915091d37SBarry Smith 1040a4d4d686SBarry Smith Notes: 104165f2ba5bSLois Curfman McInnes Use MatSNESMFSetHHistory() to create the original history counter. 1042a4d4d686SBarry Smith 1043a4d4d686SBarry Smith .keywords: SNES, matrix-free, h history, differencing history 1044a4d4d686SBarry Smith 10455a655dc6SBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(), 10465a655dc6SBarry Smith MatSNESMFSetHHistory(), 10475a655dc6SBarry Smith MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError() 1048a4d4d686SBarry Smith 1049a4d4d686SBarry Smith @*/ 105063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFResetHHistory(Mat J) 1051a4d4d686SBarry Smith { 105278392ef1SBarry Smith MatSNESMF ctx = (MatSNESMF)J->data; 1053a4d4d686SBarry Smith 1054a4d4d686SBarry Smith PetscFunctionBegin; 1055be726c96SBarry Smith ctx->ncurrenth = 0; 1056a4d4d686SBarry Smith PetscFunctionReturn(0); 1057a4d4d686SBarry Smith } 1058a4d4d686SBarry Smith 10594a2ae208SSatish Balay #undef __FUNCT__ 1060fed8bd04SBarry Smith #define __FUNCT__ "MatSNESMFComputeJacobian" 10613960baedSBarry Smith /*@ 10623960baedSBarry Smith MatSNESMFComputeJacobian - Tells the matrix-free Jacobian object the new location at which 10633960baedSBarry Smith Jacobian matrix vector products will be computed at, i.e. J(x) * a. 10643960baedSBarry Smith 10653960baedSBarry Smith Collective on SNES 10663960baedSBarry Smith 10673960baedSBarry Smith Input Parameters: 10683960baedSBarry Smith + snes - the nonlinear solver context 10693960baedSBarry Smith . x - the point at which the Jacobian vector products will be performed 10703960baedSBarry Smith . jac - the matrix-free Jacobian object 10713960baedSBarry Smith . B - either the same as jac or another matrix type (ignored) 10723960baedSBarry Smith . flag - not relevent for matrix-free form 10733960baedSBarry Smith - dummy - the user context (ignored) 10743960baedSBarry Smith 10753960baedSBarry Smith Level: developer 10763960baedSBarry Smith 10773960baedSBarry Smith Notes: 10783960baedSBarry Smith This can be passed into SNESSetJacobian() when using a completely matrix-free solver, 10793960baedSBarry Smith that is the B matrix is also the same matrix operator. This is used when you select 10803960baedSBarry Smith -snes_mf but rarely used directly by users. 10813960baedSBarry Smith 10823960baedSBarry Smith .seealso: MatSNESMFGetH(), MatCreateSNESMF(), 10833960baedSBarry Smith MatSNESMFSetHHistory(), 10843960baedSBarry Smith MatSNESMFKSPMonitor(), MatSNESMFSetFunctionError(), MatSNESMFCreate(), SNESSetJacobian() 10853960baedSBarry Smith 10863960baedSBarry Smith @*/ 108763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy) 10881d1367b7SBarry Smith { 1089dfbe8321SBarry Smith PetscErrorCode ierr; 10901d1367b7SBarry Smith PetscFunctionBegin; 10911d1367b7SBarry Smith ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10921d1367b7SBarry Smith ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10931d1367b7SBarry Smith PetscFunctionReturn(0); 10941d1367b7SBarry Smith } 10951d1367b7SBarry Smith 10964a2ae208SSatish Balay #undef __FUNCT__ 10974a2ae208SSatish Balay #define __FUNCT__ "MatSNESMFSetBase" 10985b7f0c42SBarry Smith /*@ 10995b7f0c42SBarry Smith MatSNESMFSetBase - Sets the vector U at which matrix vector products of the 11005b7f0c42SBarry Smith Jacobian are computed 11015b7f0c42SBarry Smith 11025b7f0c42SBarry Smith Collective on Mat 11035b7f0c42SBarry Smith 11045b7f0c42SBarry Smith Input Parameters: 11055b7f0c42SBarry Smith + J - the MatSNESMF matrix 11065b7f0c42SBarry Smith - U - the vector 11075b7f0c42SBarry Smith 11085b7f0c42SBarry Smith Notes: This is rarely used directly 11095b7f0c42SBarry Smith 11105b7f0c42SBarry Smith Level: advanced 11115b7f0c42SBarry Smith 11125b7f0c42SBarry Smith @*/ 111363dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetBase(Mat J,Vec U) 11141d1367b7SBarry Smith { 1115dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat,Vec); 11161d1367b7SBarry Smith 11171d1367b7SBarry Smith PetscFunctionBegin; 11184482741eSBarry Smith PetscValidHeaderSpecific(J,MAT_COOKIE,1); 11194482741eSBarry Smith PetscValidHeaderSpecific(U,VEC_COOKIE,2); 1120c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)J,"MatSNESMFSetBase_C",(void (**)(void))&f);CHKERRQ(ierr); 1121cf3bea43SBarry Smith if (f) { 1122cf3bea43SBarry Smith ierr = (*f)(J,U);CHKERRQ(ierr); 112349d4803aSBarry Smith } 11241d1367b7SBarry Smith PetscFunctionReturn(0); 11251d1367b7SBarry Smith } 1126cf57b110SBarry Smith 11275b7f0c42SBarry Smith #undef __FUNCT__ 11285b7f0c42SBarry Smith #define __FUNCT__ "MatSNESMFSetCheckh" 112961860be5SBarry Smith /*@C 11305b7f0c42SBarry Smith MatSNESMFSetCheckh - Sets a function that checks the computed h and adjusts 11315b7f0c42SBarry Smith it to satisfy some criteria 1132cf57b110SBarry Smith 11335b7f0c42SBarry Smith Collective on Mat 11345b7f0c42SBarry Smith 11355b7f0c42SBarry Smith Input Parameters: 11365b7f0c42SBarry Smith + J - the MatSNESMF matrix 11375b7f0c42SBarry Smith . fun - the function that checks h 11385b7f0c42SBarry Smith - ctx - any context needed by the function 11395b7f0c42SBarry Smith 11405b7f0c42SBarry Smith Options Database Keys: 11415b7f0c42SBarry Smith . -snes_mf_check_positivity 11425b7f0c42SBarry Smith 11435b7f0c42SBarry Smith Level: advanced 11445b7f0c42SBarry Smith 11455b7f0c42SBarry Smith Notes: For example, MatSNESMFSetCheckPositivity() insures that all entries 11465b7f0c42SBarry Smith of U + h*a are non-negative 11475b7f0c42SBarry Smith 11485b7f0c42SBarry Smith .seealso: MatSNESMFSetCheckPositivity() 11495b7f0c42SBarry Smith @*/ 115063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFSetCheckh(Mat J,PetscErrorCode (*fun)(Vec,Vec,PetscScalar*,void*),void* ctx) 11515b7f0c42SBarry Smith { 11526849ba73SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscErrorCode (*)(Vec,Vec,PetscScalar*,void*),void*); 11535b7f0c42SBarry Smith 11545b7f0c42SBarry Smith PetscFunctionBegin; 11554482741eSBarry Smith PetscValidHeaderSpecific(J,MAT_COOKIE,1); 11565b7f0c42SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)J,"MatSNESMFSetCheckh_C",(void (**)(void))&f);CHKERRQ(ierr); 11575b7f0c42SBarry Smith if (f) { 11585b7f0c42SBarry Smith ierr = (*f)(J,fun,ctx);CHKERRQ(ierr); 11595b7f0c42SBarry Smith } 11605b7f0c42SBarry Smith PetscFunctionReturn(0); 11615b7f0c42SBarry Smith } 11625b7f0c42SBarry Smith 11635b7f0c42SBarry Smith #undef __FUNCT__ 11645b7f0c42SBarry Smith #define __FUNCT__ "MatSNESMFSetCheckPositivity" 11655b7f0c42SBarry Smith /*@ 11665b7f0c42SBarry Smith MatSNESMFCheckPositivity - Checks that all entries in U + h*a are positive or 11675b7f0c42SBarry Smith zero, decreases h until this is satisfied. 11685b7f0c42SBarry Smith 11695b7f0c42SBarry Smith Collective on Vec 11705b7f0c42SBarry Smith 11715b7f0c42SBarry Smith Input Parameters: 11725b7f0c42SBarry Smith + U - base vector that is added to 11735b7f0c42SBarry Smith . a - vector that is added 11745b7f0c42SBarry Smith . h - scaling factor on a 11755b7f0c42SBarry Smith - dummy - context variable (unused) 11765b7f0c42SBarry Smith 11775b7f0c42SBarry Smith Options Database Keys: 11785b7f0c42SBarry Smith . -snes_mf_check_positivity 11795b7f0c42SBarry Smith 11805b7f0c42SBarry Smith Level: advanced 11815b7f0c42SBarry Smith 11825b7f0c42SBarry Smith Notes: This is rarely used directly, rather it is passed as an argument to 11835b7f0c42SBarry Smith MatSNESMFSetCheckh() 11845b7f0c42SBarry Smith 11855b7f0c42SBarry Smith .seealso: MatSNESMFSetCheckh() 11865b7f0c42SBarry Smith @*/ 118763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatSNESMFCheckPositivity(Vec U,Vec a,PetscScalar *h,void *dummy) 11885b7f0c42SBarry Smith { 11895b7f0c42SBarry Smith PetscReal val, minval; 11905b7f0c42SBarry Smith PetscScalar *u_vec, *a_vec; 1191dfbe8321SBarry Smith PetscErrorCode ierr; 1192a7cc72afSBarry Smith PetscInt i,n; 11935b7f0c42SBarry Smith MPI_Comm comm; 11945b7f0c42SBarry Smith 11955b7f0c42SBarry Smith PetscFunctionBegin; 11965b7f0c42SBarry Smith ierr = PetscObjectGetComm((PetscObject)U,&comm);CHKERRQ(ierr); 11975b7f0c42SBarry Smith ierr = VecGetArray(U,&u_vec);CHKERRQ(ierr); 11985b7f0c42SBarry Smith ierr = VecGetArray(a,&a_vec);CHKERRQ(ierr); 1199a7cc72afSBarry Smith ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 120061860be5SBarry Smith minval = PetscAbsScalar(*h*1.01); 1201a7cc72afSBarry Smith for(i=0;i<n;i++) { 120261860be5SBarry Smith if (PetscRealPart(u_vec[i] + *h*a_vec[i]) <= 0.0) { 120361860be5SBarry Smith val = PetscAbsScalar(u_vec[i]/a_vec[i]); 12045b7f0c42SBarry Smith if (val < minval) minval = val; 12055b7f0c42SBarry Smith } 12065b7f0c42SBarry Smith } 12075b7f0c42SBarry Smith ierr = VecRestoreArray(U,&u_vec);CHKERRQ(ierr); 12085b7f0c42SBarry Smith ierr = VecRestoreArray(a,&a_vec);CHKERRQ(ierr); 12095b7f0c42SBarry Smith ierr = PetscGlobalMin(&minval,&val,comm);CHKERRQ(ierr); 121061860be5SBarry Smith if (val <= PetscAbsScalar(*h)) { 1211ae15b995SBarry Smith ierr = PetscInfo2(U,"Scaling back h from %G to %G\n",PetscRealPart(*h),.99*val);CHKERRQ(ierr); 121261860be5SBarry Smith if (PetscRealPart(*h) > 0.0) *h = 0.99*val; 12135b7f0c42SBarry Smith else *h = -0.99*val; 12145b7f0c42SBarry Smith } 12155b7f0c42SBarry Smith PetscFunctionReturn(0); 12165b7f0c42SBarry Smith } 1217cf57b110SBarry Smith 1218cf57b110SBarry Smith 1219cf57b110SBarry Smith 1220cf57b110SBarry Smith 1221cf57b110SBarry Smith 1222cf57b110SBarry Smith 1223cf57b110SBarry Smith 1224