1d2dddef7SLois Curfman McInnes 20a835dfdSSatish Balay #include "src/snes/snesimpl.h" /*I "petscsnes.h" I*/ 3d2dddef7SLois Curfman McInnes 4dfbe8321SBarry Smith EXTERN PetscErrorCode DiffParameterCreate_More(SNES,Vec,void**); 5dfbe8321SBarry Smith EXTERN PetscErrorCode DiffParameterCompute_More(SNES,void*,Vec,Vec,PetscReal*,PetscReal*); 6dfbe8321SBarry Smith EXTERN PetscErrorCode DiffParameterDestroy_More(void*); 7d2dddef7SLois Curfman McInnes 8d2dddef7SLois Curfman McInnes typedef struct { /* default context for matrix-free SNES */ 9d2dddef7SLois Curfman McInnes SNES snes; /* SNES context */ 10d2dddef7SLois Curfman McInnes Vec w; /* work vector */ 1174637425SBarry Smith MatNullSpace sp; /* null space context */ 12145595abSSatish Balay PetscReal error_rel; /* square root of relative error in computing function */ 13145595abSSatish Balay PetscReal umin; /* minimum allowable u'a value relative to |u|_1 */ 14d2dddef7SLois Curfman McInnes int jorge; /* flag indicating use of Jorge's method for determining 15d2dddef7SLois Curfman McInnes the differencing parameter */ 16145595abSSatish Balay PetscReal h; /* differencing parameter */ 17d2dddef7SLois Curfman McInnes int need_h; /* flag indicating whether we must compute h */ 18295f7fbbSLois Curfman McInnes int need_err; /* flag indicating whether we must currently compute error_rel */ 19295f7fbbSLois Curfman McInnes int compute_err; /* flag indicating whether we must ever compute error_rel */ 20295f7fbbSLois Curfman McInnes int compute_err_iter; /* last iter where we've computer error_rel */ 21295f7fbbSLois Curfman McInnes int compute_err_freq; /* frequency of computing error_rel */ 22d2dddef7SLois Curfman McInnes void *data; /* implementation-specific data */ 23d2dddef7SLois Curfman McInnes } MFCtx_Private; 24d2dddef7SLois Curfman McInnes 254a2ae208SSatish Balay #undef __FUNCT__ 264a2ae208SSatish Balay #define __FUNCT__ "SNESMatrixFreeDestroy2_Private" /* ADIC Ignore */ 27dfbe8321SBarry Smith PetscErrorCode SNESMatrixFreeDestroy2_Private(Mat mat) 28d2dddef7SLois Curfman McInnes { 29dfbe8321SBarry Smith PetscErrorCode ierr; 30d2dddef7SLois Curfman McInnes MFCtx_Private *ctx; 31d2dddef7SLois Curfman McInnes 3207a3eed9SLois Curfman McInnes PetscFunctionBegin; 33d2dddef7SLois Curfman McInnes ierr = MatShellGetContext(mat,(void **)&ctx); 34d2dddef7SLois Curfman McInnes ierr = VecDestroy(ctx->w);CHKERRQ(ierr); 3574637425SBarry Smith if (ctx->sp) {ierr = MatNullSpaceDestroy(ctx->sp);CHKERRQ(ierr);} 36295f7fbbSLois Curfman McInnes if (ctx->jorge || ctx->compute_err) {ierr = DiffParameterDestroy_More(ctx->data);CHKERRQ(ierr);} 37606d414cSSatish Balay ierr = PetscFree(ctx);CHKERRQ(ierr); 3807a3eed9SLois Curfman McInnes PetscFunctionReturn(0); 39d2dddef7SLois Curfman McInnes } 40d2dddef7SLois Curfman McInnes 414a2ae208SSatish Balay #undef __FUNCT__ 424a2ae208SSatish Balay #define __FUNCT__ "SNESMatrixFreeView2_Private" /* ADIC Ignore */ 43d2dddef7SLois Curfman McInnes /* 44d2dddef7SLois Curfman McInnes SNESMatrixFreeView2_Private - Views matrix-free parameters. 45d2dddef7SLois Curfman McInnes */ 46dfbe8321SBarry Smith PetscErrorCode SNESMatrixFreeView2_Private(Mat J,PetscViewer viewer) 47d2dddef7SLois Curfman McInnes { 48dfbe8321SBarry Smith PetscErrorCode ierr; 49d2dddef7SLois Curfman McInnes MFCtx_Private *ctx; 5032077d6dSBarry Smith PetscTruth iascii; 51d2dddef7SLois Curfman McInnes 5207a3eed9SLois Curfman McInnes PetscFunctionBegin; 53d2dddef7SLois Curfman McInnes ierr = MatShellGetContext(J,(void **)&ctx);CHKERRQ(ierr); 5432077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 5532077d6dSBarry Smith if (iascii) { 56b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," SNES matrix-free approximation:\n");CHKERRQ(ierr); 57758f395bSBarry Smith if (ctx->jorge) { 58b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," using Jorge's method of determining differencing parameter\n");CHKERRQ(ierr); 59758f395bSBarry Smith } 60b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," err=%g (relative error in function evaluation)\n",ctx->error_rel);CHKERRQ(ierr); 61b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," umin=%g (minimum iterate parameter)\n",ctx->umin);CHKERRQ(ierr); 62758f395bSBarry Smith if (ctx->compute_err) { 63b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," freq_err=%d (frequency for computing err)\n",ctx->compute_err_freq);CHKERRQ(ierr); 64d2dddef7SLois Curfman McInnes } 65758f395bSBarry Smith } else { 6629bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SNES matrix free Jorge",((PetscObject)viewer)->type_name); 67758f395bSBarry Smith } 6807a3eed9SLois Curfman McInnes PetscFunctionReturn(0); 69d2dddef7SLois Curfman McInnes } 70d2dddef7SLois Curfman McInnes 714a2ae208SSatish Balay #undef __FUNCT__ 724a2ae208SSatish Balay #define __FUNCT__ "SNESMatrixFreeMult2_Private" 73d2dddef7SLois Curfman McInnes /* 74d2dddef7SLois Curfman McInnes SNESMatrixFreeMult2_Private - Default matrix-free form for Jacobian-vector 75d2dddef7SLois Curfman McInnes product, y = F'(u)*a: 76d2dddef7SLois Curfman McInnes y = (F(u + ha) - F(u)) /h, 77d2dddef7SLois Curfman McInnes where F = nonlinear function, as set by SNESSetFunction() 78d2dddef7SLois Curfman McInnes u = current iterate 79d2dddef7SLois Curfman McInnes h = difference interval 80d2dddef7SLois Curfman McInnes */ 81dfbe8321SBarry Smith PetscErrorCode SNESMatrixFreeMult2_Private(Mat mat,Vec a,Vec y) 82d2dddef7SLois Curfman McInnes { 83d2dddef7SLois Curfman McInnes MFCtx_Private *ctx; 84d2dddef7SLois Curfman McInnes SNES snes; 85145595abSSatish Balay PetscReal h,norm,sum,umin,noise; 86ea709b57SSatish Balay PetscScalar hs,dot,mone = -1.0; 87d2dddef7SLois Curfman McInnes Vec w,U,F; 88dfbe8321SBarry Smith PetscErrorCode ierr,(*eval_fct)(SNES,Vec,Vec); 89e6ed2b1fSLois Curfman McInnes MPI_Comm comm; 90dfbe8321SBarry Smith int iter; 91d2dddef7SLois Curfman McInnes 9207a3eed9SLois Curfman McInnes PetscFunctionBegin; 9307a3eed9SLois Curfman McInnes 94d2dddef7SLois Curfman McInnes /* We log matrix-free matrix-vector products separately, so that we can 95d2dddef7SLois Curfman McInnes separate the performance monitoring from the cases that use conventional 96d2dddef7SLois Curfman McInnes storage. We may eventually modify event logging to associate events 97d2dddef7SLois Curfman McInnes with particular objects, hence alleviating the more general problem. */ 9852ed857cSBarry Smith ierr = PetscLogEventBegin(MAT_MultMatrixFree,a,y,0,0);CHKERRQ(ierr); 99d2dddef7SLois Curfman McInnes 1002d0c0e3bSBarry Smith ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 101e6ed2b1fSLois Curfman McInnes ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 102e6ed2b1fSLois Curfman McInnes snes = ctx->snes; 103e6ed2b1fSLois Curfman McInnes w = ctx->w; 104e6ed2b1fSLois Curfman McInnes umin = ctx->umin; 105e6ed2b1fSLois Curfman McInnes 106d2dddef7SLois Curfman McInnes ierr = SNESGetSolution(snes,&U);CHKERRQ(ierr); 107d2dddef7SLois Curfman McInnes eval_fct = SNESComputeFunction; 10874637425SBarry Smith ierr = SNESGetFunction(snes,&F,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 109295f7fbbSLois Curfman McInnes 110d2dddef7SLois Curfman McInnes /* Determine a "good" step size, h */ 111d2dddef7SLois Curfman McInnes if (ctx->need_h) { 112d2dddef7SLois Curfman McInnes 113d2dddef7SLois Curfman McInnes /* Use Jorge's method to compute h */ 114d2dddef7SLois Curfman McInnes if (ctx->jorge) { 115d2dddef7SLois Curfman McInnes ierr = DiffParameterCompute_More(snes,ctx->data,U,a,&noise,&h);CHKERRQ(ierr); 116d2dddef7SLois Curfman McInnes 117d2dddef7SLois Curfman McInnes /* Use the Brown/Saad method to compute h */ 118d2dddef7SLois Curfman McInnes } else { 119295f7fbbSLois Curfman McInnes /* Compute error if desired */ 120295f7fbbSLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&iter);CHKERRQ(ierr); 121145595abSSatish Balay if ((ctx->need_err) || ((ctx->compute_err_freq) && (ctx->compute_err_iter != iter) && (!((iter-1)%ctx->compute_err_freq)))) { 122d2dddef7SLois Curfman McInnes /* Use Jorge's method to compute noise */ 123d2dddef7SLois Curfman McInnes ierr = DiffParameterCompute_More(snes,ctx->data,U,a,&noise,&h);CHKERRQ(ierr); 124d2dddef7SLois Curfman McInnes ctx->error_rel = sqrt(noise); 125b0a32e0cSBarry Smith PetscLogInfo(snes,"SNESMatrixFreeMult2_Private: Using Jorge's noise: noise=%g, sqrt(noise)=%g, h_more=%g\n",noise,ctx->error_rel,h); 126295f7fbbSLois Curfman McInnes ctx->compute_err_iter = iter; 127d2dddef7SLois Curfman McInnes ctx->need_err = 0; 128d2dddef7SLois Curfman McInnes } 129e6ed2b1fSLois Curfman McInnes 130691598edSBarry Smith ierr = VecDotBegin(U,a,&dot);CHKERRQ(ierr); 131691598edSBarry Smith ierr = VecNormBegin(a,NORM_1,&sum);CHKERRQ(ierr); 132691598edSBarry Smith ierr = VecNormBegin(a,NORM_2,&norm);CHKERRQ(ierr); 133691598edSBarry Smith ierr = VecDotEnd(U,a,&dot);CHKERRQ(ierr); 134691598edSBarry Smith ierr = VecNormEnd(a,NORM_1,&sum);CHKERRQ(ierr); 135691598edSBarry Smith ierr = VecNormEnd(a,NORM_2,&norm);CHKERRQ(ierr); 136e6ed2b1fSLois Curfman McInnes 137d2dddef7SLois Curfman McInnes 138d2dddef7SLois Curfman McInnes /* Safeguard for step sizes too small */ 139d2dddef7SLois Curfman McInnes if (sum == 0.0) {dot = 1.0; norm = 1.0;} 140aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 141145595abSSatish Balay else if (PetscAbsScalar(dot) < umin*sum && PetscRealPart(dot) >= 0.0) dot = umin*sum; 142145595abSSatish Balay else if (PetscAbsScalar(dot) < 0.0 && PetscRealPart(dot) > -umin*sum) dot = -umin*sum; 143d2dddef7SLois Curfman McInnes #else 144d2dddef7SLois Curfman McInnes else if (dot < umin*sum && dot >= 0.0) dot = umin*sum; 145d2dddef7SLois Curfman McInnes else if (dot < 0.0 && dot > -umin*sum) dot = -umin*sum; 146d2dddef7SLois Curfman McInnes #endif 147145595abSSatish Balay h = PetscRealPart(ctx->error_rel*dot/(norm*norm)); 148d2dddef7SLois Curfman McInnes } 149d2dddef7SLois Curfman McInnes } else { 150d2dddef7SLois Curfman McInnes h = ctx->h; 151d2dddef7SLois Curfman McInnes } 152b0a32e0cSBarry Smith if (!ctx->jorge || !ctx->need_h) PetscLogInfo(snes,"SNESMatrixFreeMult2_Private: h = %g\n",h); 153d2dddef7SLois Curfman McInnes 154d2dddef7SLois Curfman McInnes /* Evaluate function at F(u + ha) */ 155db0b4b35SLois Curfman McInnes hs = h; 156db0b4b35SLois Curfman McInnes ierr = VecWAXPY(&hs,a,U,w);CHKERRQ(ierr); 157d2dddef7SLois Curfman McInnes ierr = eval_fct(snes,w,y);CHKERRQ(ierr); 158d2dddef7SLois Curfman McInnes ierr = VecAXPY(&mone,F,y);CHKERRQ(ierr); 159db0b4b35SLois Curfman McInnes hs = 1.0/hs; 160db0b4b35SLois Curfman McInnes ierr = VecScale(&hs,y);CHKERRQ(ierr); 16174637425SBarry Smith if (ctx->sp) {ierr = MatNullSpaceRemove(ctx->sp,y,PETSC_NULL);CHKERRQ(ierr);} 162d2dddef7SLois Curfman McInnes 16352ed857cSBarry Smith ierr = PetscLogEventEnd(MAT_MultMatrixFree,a,y,0,0);CHKERRQ(ierr); 16407a3eed9SLois Curfman McInnes PetscFunctionReturn(0); 165d2dddef7SLois Curfman McInnes } 166d2dddef7SLois Curfman McInnes 1674a2ae208SSatish Balay #undef __FUNCT__ 1684a2ae208SSatish Balay #define __FUNCT__ "SNESMatrixFreeMatCreate2" 169d2dddef7SLois Curfman McInnes /*@C 170d2dddef7SLois Curfman McInnes SNESMatrixFreeMatCreate2 - Creates a matrix-free matrix 171d2dddef7SLois Curfman McInnes context for use with a SNES solver. This matrix can be used as 172d2dddef7SLois Curfman McInnes the Jacobian argument for the routine SNESSetJacobian(). 173d2dddef7SLois Curfman McInnes 174d2dddef7SLois Curfman McInnes Input Parameters: 175d2dddef7SLois Curfman McInnes . snes - the SNES context 176d2dddef7SLois Curfman McInnes . x - vector where SNES solution is to be stored. 177d2dddef7SLois Curfman McInnes 178d2dddef7SLois Curfman McInnes Output Parameter: 179d2dddef7SLois Curfman McInnes . J - the matrix-free matrix 180d2dddef7SLois Curfman McInnes 18190c26489SBarry Smith Level: advanced 18290c26489SBarry Smith 183d2dddef7SLois Curfman McInnes Notes: 184d2dddef7SLois Curfman McInnes The matrix-free matrix context merely contains the function pointers 185d2dddef7SLois Curfman McInnes and work space for performing finite difference approximations of 186d2dddef7SLois Curfman McInnes Jacobian-vector products, J(u)*a, via 187d2dddef7SLois Curfman McInnes 188d2dddef7SLois Curfman McInnes $ J(u)*a = [J(u+h*a) - J(u)]/h, 189d2dddef7SLois Curfman McInnes $ where by default 190d2dddef7SLois Curfman McInnes $ h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 191d2dddef7SLois Curfman McInnes $ = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 otherwise 192d2dddef7SLois Curfman McInnes $ where 193d2dddef7SLois Curfman McInnes $ error_rel = square root of relative error in 194d2dddef7SLois Curfman McInnes $ function evaluation 195d2dddef7SLois Curfman McInnes $ umin = minimum iterate parameter 196d2dddef7SLois Curfman McInnes $ Alternatively, the differencing parameter, h, can be set using 197e6ed2b1fSLois Curfman McInnes $ Jorge's nifty new strategy if one specifies the option 198e6ed2b1fSLois Curfman McInnes $ -snes_mf_jorge 199d2dddef7SLois Curfman McInnes 2005a655dc6SBarry Smith The user can set these parameters via MatSNESMFSetFunctionError(). 201d2dddef7SLois Curfman McInnes See the nonlinear solvers chapter of the users manual for details. 202d2dddef7SLois Curfman McInnes 203d2dddef7SLois Curfman McInnes The user should call MatDestroy() when finished with the matrix-free 204d2dddef7SLois Curfman McInnes matrix context. 205d2dddef7SLois Curfman McInnes 206d2dddef7SLois Curfman McInnes Options Database Keys: 207d2dddef7SLois Curfman McInnes $ -snes_mf_err <error_rel> 208d2dddef7SLois Curfman McInnes $ -snes_mf_unim <umin> 209295f7fbbSLois Curfman McInnes $ -snes_mf_compute_err 210295f7fbbSLois Curfman McInnes $ -snes_mf_freq_err <freq> 211e6ed2b1fSLois Curfman McInnes $ -snes_mf_jorge 212d2dddef7SLois Curfman McInnes 213d2dddef7SLois Curfman McInnes .keywords: SNES, default, matrix-free, create, matrix 214d2dddef7SLois Curfman McInnes 2155a655dc6SBarry Smith .seealso: MatDestroy(), MatSNESMFSetFunctionError() 216d2dddef7SLois Curfman McInnes @*/ 217dfbe8321SBarry Smith PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES snes,Vec x,Mat *J) 218d2dddef7SLois Curfman McInnes { 219d2dddef7SLois Curfman McInnes MPI_Comm comm; 220d2dddef7SLois Curfman McInnes MFCtx_Private *mfctx; 221*6849ba73SBarry Smith PetscErrorCode ierr; 222*6849ba73SBarry Smith int n,nloc; 223145595abSSatish Balay PetscTruth flg; 224d2dddef7SLois Curfman McInnes char p[64]; 225d2dddef7SLois Curfman McInnes 22607a3eed9SLois Curfman McInnes PetscFunctionBegin; 22782502324SSatish Balay ierr = PetscNew(MFCtx_Private,&mfctx);CHKERRQ(ierr); 228549d3d68SSatish Balay ierr = PetscMemzero(mfctx,sizeof(MFCtx_Private));CHKERRQ(ierr); 229b0a32e0cSBarry Smith PetscLogObjectMemory(snes,sizeof(MFCtx_Private)); 230d2dddef7SLois Curfman McInnes mfctx->sp = 0; 231d2dddef7SLois Curfman McInnes mfctx->snes = snes; 23277d8c4bbSBarry Smith mfctx->error_rel = PETSC_SQRT_MACHINE_EPSILON; 233d2dddef7SLois Curfman McInnes mfctx->umin = 1.e-6; 234d2dddef7SLois Curfman McInnes mfctx->h = 0.0; 235d2dddef7SLois Curfman McInnes mfctx->need_h = 1; 236d2dddef7SLois Curfman McInnes mfctx->need_err = 0; 237295f7fbbSLois Curfman McInnes mfctx->compute_err = 0; 238295f7fbbSLois Curfman McInnes mfctx->compute_err_freq = 0; 239295f7fbbSLois Curfman McInnes mfctx->compute_err_iter = -1; 24087828ca2SBarry Smith ierr = PetscOptionsGetReal(snes->prefix,"-snes_mf_err",&mfctx->error_rel,PETSC_NULL);CHKERRQ(ierr); 24187828ca2SBarry Smith ierr = PetscOptionsGetReal(snes->prefix,"-snes_mf_umin",&mfctx->umin,PETSC_NULL);CHKERRQ(ierr); 24252ed857cSBarry Smith ierr = PetscOptionsHasName(snes->prefix,"-snes_mf_jorge",(PetscTruth*)&mfctx->jorge);CHKERRQ(ierr); 24352ed857cSBarry Smith ierr = PetscOptionsHasName(snes->prefix,"-snes_mf_compute_err",(PetscTruth*)&mfctx->compute_err);CHKERRQ(ierr); 244b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(snes->prefix,"-snes_mf_freq_err",&mfctx->compute_err_freq,&flg);CHKERRQ(ierr); 245295f7fbbSLois Curfman McInnes if (flg) { 246295f7fbbSLois Curfman McInnes if (mfctx->compute_err_freq < 0) mfctx->compute_err_freq = 0; 247295f7fbbSLois Curfman McInnes mfctx->compute_err = 1; 248295f7fbbSLois Curfman McInnes } 249295f7fbbSLois Curfman McInnes if (mfctx->compute_err == 1) mfctx->need_err = 1; 250295f7fbbSLois Curfman McInnes if (mfctx->jorge || mfctx->compute_err) { 251d2dddef7SLois Curfman McInnes ierr = DiffParameterCreate_More(snes,x,&mfctx->data);CHKERRQ(ierr); 252d2dddef7SLois Curfman McInnes } else mfctx->data = 0; 253d2dddef7SLois Curfman McInnes 254b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 255549d3d68SSatish Balay ierr = PetscStrcpy(p,"-");CHKERRQ(ierr); 256d2dddef7SLois Curfman McInnes if (snes->prefix) PetscStrcat(p,snes->prefix); 257d2dddef7SLois Curfman McInnes if (flg) { 258d132466eSBarry Smith ierr = PetscPrintf(snes->comm," Matrix-free Options (via SNES):\n");CHKERRQ(ierr); 259d132466eSBarry Smith ierr = PetscPrintf(snes->comm," %ssnes_mf_err <err>: set sqrt of relative error in function (default %g)\n",p,mfctx->error_rel);CHKERRQ(ierr); 260d132466eSBarry Smith ierr = PetscPrintf(snes->comm," %ssnes_mf_umin <umin>: see users manual (default %g)\n",p,mfctx->umin);CHKERRQ(ierr); 261d132466eSBarry Smith ierr = PetscPrintf(snes->comm," %ssnes_mf_jorge: use Jorge More's method\n",p);CHKERRQ(ierr); 262d132466eSBarry Smith ierr = PetscPrintf(snes->comm," %ssnes_mf_compute_err: compute sqrt or relative error in function\n",p);CHKERRQ(ierr); 263d132466eSBarry Smith ierr = PetscPrintf(snes->comm," %ssnes_mf_freq_err <freq>: frequency to recompute this (default only once)\n",p);CHKERRQ(ierr); 264d132466eSBarry Smith ierr = PetscPrintf(snes->comm," %ssnes_mf_noise_file <file>: set file for printing noise info\n",p);CHKERRQ(ierr); 265d2dddef7SLois Curfman McInnes } 266d2dddef7SLois Curfman McInnes ierr = VecDuplicate(x,&mfctx->w);CHKERRQ(ierr); 267d2dddef7SLois Curfman McInnes ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 268d2dddef7SLois Curfman McInnes ierr = VecGetSize(x,&n);CHKERRQ(ierr); 269d2dddef7SLois Curfman McInnes ierr = VecGetLocalSize(x,&nloc);CHKERRQ(ierr); 270f204ca49SKris Buschelman ierr = MatCreate(comm,nloc,n,n,n,J);CHKERRQ(ierr); 271f204ca49SKris Buschelman ierr = MatSetType(*J,MATSHELL);CHKERRQ(ierr); 272f204ca49SKris Buschelman ierr = MatShellSetContext(*J,mfctx);CHKERRQ(ierr); 273c134de8dSSatish Balay ierr = MatShellSetOperation(*J,MATOP_MULT,(void(*)(void))SNESMatrixFreeMult2_Private);CHKERRQ(ierr); 274c134de8dSSatish Balay ierr = MatShellSetOperation(*J,MATOP_DESTROY,(void(*)(void))SNESMatrixFreeDestroy2_Private);CHKERRQ(ierr); 275c134de8dSSatish Balay ierr = MatShellSetOperation(*J,MATOP_VIEW,(void(*)(void))SNESMatrixFreeView2_Private);CHKERRQ(ierr); 276d2dddef7SLois Curfman McInnes 277b0a32e0cSBarry Smith PetscLogObjectParent(*J,mfctx->w); 278b0a32e0cSBarry Smith PetscLogObjectParent(snes,*J); 27907a3eed9SLois Curfman McInnes PetscFunctionReturn(0); 280d2dddef7SLois Curfman McInnes } 281d2dddef7SLois Curfman McInnes 2824a2ae208SSatish Balay #undef __FUNCT__ 2834a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultMatrixFreeSetParameters2" 28490c26489SBarry Smith /*@C 285758f395bSBarry Smith SNESDefaultMatrixFreeSetParameters2 - Sets the parameters for the approximation of 286d2dddef7SLois Curfman McInnes matrix-vector products using finite differences. 287d2dddef7SLois Curfman McInnes 288d2dddef7SLois Curfman McInnes $ J(u)*a = [J(u+h*a) - J(u)]/h where 289d2dddef7SLois Curfman McInnes 290d2dddef7SLois Curfman McInnes either the user sets h directly here, or this parameter is computed via 291d2dddef7SLois Curfman McInnes 292d2dddef7SLois Curfman McInnes $ h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 293d2dddef7SLois Curfman McInnes $ = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 else 294d2dddef7SLois Curfman McInnes $ 295d2dddef7SLois Curfman McInnes 296d2dddef7SLois Curfman McInnes Input Parameters: 297758f395bSBarry Smith + mat - the matrix 298d2dddef7SLois Curfman McInnes . error_rel - relative error (should be set to the square root of 299d2dddef7SLois Curfman McInnes the relative error in the function evaluations) 300d2dddef7SLois Curfman McInnes . umin - minimum allowable u-value 301758f395bSBarry Smith - h - differencing parameter 302d2dddef7SLois Curfman McInnes 30390c26489SBarry Smith Level: advanced 30490c26489SBarry Smith 305d2dddef7SLois Curfman McInnes Notes: 306d2dddef7SLois Curfman McInnes If the user sets the parameter h directly, then this value will be used 307d2dddef7SLois Curfman McInnes instead of the default computation indicated above. 308d2dddef7SLois Curfman McInnes 309d2dddef7SLois Curfman McInnes .keywords: SNES, matrix-free, parameters 310d2dddef7SLois Curfman McInnes 3115a655dc6SBarry Smith .seealso: MatCreateSNESMF() 312d2dddef7SLois Curfman McInnes @*/ 313dfbe8321SBarry Smith PetscErrorCode SNESDefaultMatrixFreeSetParameters2(Mat mat,PetscReal error,PetscReal umin,PetscReal h) 314d2dddef7SLois Curfman McInnes { 315d2dddef7SLois Curfman McInnes MFCtx_Private *ctx; 316dfbe8321SBarry Smith PetscErrorCode ierr; 317d2dddef7SLois Curfman McInnes 31807a3eed9SLois Curfman McInnes PetscFunctionBegin; 319d2dddef7SLois Curfman McInnes ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 320d2dddef7SLois Curfman McInnes if (ctx) { 321d2dddef7SLois Curfman McInnes if (error != PETSC_DEFAULT) ctx->error_rel = error; 322d2dddef7SLois Curfman McInnes if (umin != PETSC_DEFAULT) ctx->umin = umin; 323d2dddef7SLois Curfman McInnes if (h != PETSC_DEFAULT) { 324d2dddef7SLois Curfman McInnes ctx->h = h; 325d2dddef7SLois Curfman McInnes ctx->need_h = 0; 326d2dddef7SLois Curfman McInnes } 327d2dddef7SLois Curfman McInnes } 32807a3eed9SLois Curfman McInnes PetscFunctionReturn(0); 329d2dddef7SLois Curfman McInnes } 330d2dddef7SLois Curfman McInnes 331dfbe8321SBarry Smith PetscErrorCode SNESUnSetMatrixFreeParameter(SNES snes) 332d2dddef7SLois Curfman McInnes { 333d2dddef7SLois Curfman McInnes MFCtx_Private *ctx; 334dfbe8321SBarry Smith PetscErrorCode ierr; 335d2dddef7SLois Curfman McInnes Mat mat; 336d2dddef7SLois Curfman McInnes 33707a3eed9SLois Curfman McInnes PetscFunctionBegin; 33874637425SBarry Smith ierr = SNESGetJacobian(snes,&mat,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 339d2dddef7SLois Curfman McInnes ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 340d2dddef7SLois Curfman McInnes if (ctx) ctx->need_h = 1; 34107a3eed9SLois Curfman McInnes PetscFunctionReturn(0); 342d2dddef7SLois Curfman McInnes } 343d2dddef7SLois Curfman McInnes 344