1 2 #ifdef PETSC_RCS_HEADER 3 static char vcid[] = "$Id: snesmfj.c,v 1.72 1998/11/05 04:28:55 bsmith Exp bsmith $"; 4 #endif 5 6 #include "src/snes/snesimpl.h" 7 #include "src/snes/mf/snesmfj.h" /*I "snes.h" I*/ 8 9 FList MatSNESFDMFList = 0; 10 int MatSNESFDMFRegisterAllCalled = 0; 11 12 13 #undef __FUNC__ 14 #define __FUNC__ "MatSNESFDMFSetType" 15 /*@ 16 MatSNESFDMFSetType - Sets the method that is used to compute the h in the 17 finite difference matrix free formulation. 18 19 Input Parameters: 20 + mat - the matrix free matrix created via MatCreateSNESFDMF() 21 - ftype - the type requested 22 23 .seealso: MatCreateSNESFDMF(), MatSNESFDMFRegister() 24 @*/ 25 int MatSNESFDMFSetType(Mat mat,char *ftype) 26 { 27 int ierr, (*r)(MatSNESFDMFCtx); 28 MatSNESFDMFCtx ctx; 29 30 PetscFunctionBegin; 31 ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 32 33 /* already set, so just return */ 34 if (!PetscStrcmp(ctx->type_name,ftype)) PetscFunctionReturn(0); 35 36 /* destroy the old one if it exists */ 37 if (ctx->ops->destroy) { 38 ierr = (*ctx->ops->destroy)(ctx);CHKERRQ(ierr); 39 } 40 41 /* Get the function pointers for the iterative method requested */ 42 if (!MatSNESFDMFRegisterAllCalled) {ierr = MatSNESFDMFRegisterAll(PETSC_NULL); CHKERRQ(ierr);} 43 44 ierr = FListFind(ctx->comm, MatSNESFDMFList, ftype,(int (**)(void *)) &r );CHKERRQ(ierr); 45 46 if (!r) SETERRQ(1,1,"Unknown MatSNESFDMF type given"); 47 48 ierr = (*r)(ctx); CHKERRQ(ierr); 49 ierr = PetscStrncpy(ctx->type_name,ftype,256);CHKERRQ(ierr); 50 51 PetscFunctionReturn(0); 52 } 53 54 /*MC 55 MatSNESFDMFRegister - Adds a method to the MatSNESFDMF registry 56 57 Synopsis: 58 MatSNESFDMFRegister(char *name_solver,char *path,char *name_create,int (*routine_create)(MatSNESFDMF)) 59 60 Not Collective 61 62 Input Parameters: 63 + name_solver - name of a new user-defined compute-h module 64 . path - path (either absolute or relative) the library containing this solver 65 . name_create - name of routine to create method context 66 - routine_create - routine to create method context 67 68 Notes: 69 MatSNESFDMFRegister() may be called multiple times to add several user-defined solvers. 70 71 If dynamic libraries are used, then the fourth input argument (routine_create) 72 is ignored. 73 74 Sample usage: 75 .vb 76 MatSNESFDMFRegister("my_h",/home/username/my_lib/lib/libO/solaris/mylib.a, 77 "MyHCreate",MyHCreate); 78 .ve 79 80 Then, your solver can be chosen with the procedural interface via 81 $ MatSNESFDMFSetType(mfctx,"my_h") 82 or at runtime via the option 83 $ -snes_mf_type my_h 84 85 .keywords: MatSNESFDMF, register 86 87 .seealso: MatSNESFDMFRegisterAll(), MatSNESFDMFRegisterDestroy() 88 M*/ 89 90 #undef __FUNC__ 91 #define __FUNC__ "MatSNESFDMFRegister_Private" 92 int MatSNESFDMFRegister_Private(char *sname,char *path,char *name,int (*function)(MatSNESFDMFCtx)) 93 { 94 int ierr; 95 char fullname[256]; 96 97 PetscFunctionBegin; 98 PetscStrcpy(fullname,path); PetscStrcat(fullname,":");PetscStrcat(fullname,name); 99 ierr = FListAdd_Private(&MatSNESFDMFList,sname,fullname,(int (*)(void*))function);CHKERRQ(ierr); 100 PetscFunctionReturn(0); 101 } 102 103 104 #undef __FUNC__ 105 #define __FUNC__ "MatSNESFDMFRegisterDestroy" 106 /*@C 107 MatSNESFDMFRegisterDestroy - Frees the list of MatSNESFDMF methods that were 108 registered by MatSNESFDMFRegister(). 109 110 Not Collective 111 112 .keywords: MatSNESFDMF, register, destroy 113 114 .seealso: MatSNESFDMFRegister(), MatSNESFDMFRegisterAll() 115 @*/ 116 int MatSNESFDMFRegisterDestroy(void) 117 { 118 int ierr; 119 120 PetscFunctionBegin; 121 if (MatSNESFDMFList) { 122 ierr = FListDestroy( MatSNESFDMFList );CHKERRQ(ierr); 123 MatSNESFDMFList = 0; 124 } 125 MatSNESFDMFRegisterAllCalled = 0; 126 PetscFunctionReturn(0); 127 } 128 129 /* ----------------------------------------------------------------------------------------*/ 130 #undef __FUNC__ 131 #define __FUNC__ "MatSNESFDMFDestroy_Private" 132 int MatSNESFDMFDestroy_Private(Mat mat) 133 { 134 int ierr; 135 MatSNESFDMFCtx ctx; 136 137 PetscFunctionBegin; 138 ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 139 ierr = VecDestroy(ctx->w); CHKERRQ(ierr); 140 if (ctx->ops->destroy) {ierr = (*ctx->ops->destroy)(ctx);CHKERRQ(ierr);} 141 if (ctx->sp) {ierr = PCNullSpaceDestroy(ctx->sp);CHKERRQ(ierr);} 142 PetscFree(ctx->ops); 143 PetscFree(ctx); 144 PetscFunctionReturn(0); 145 } 146 147 #undef __FUNC__ 148 #define __FUNC__ "MatSNESFDMFView_Private" 149 /* 150 MatSNESFDMFView_Private - Views matrix-free parameters. 151 152 */ 153 int MatSNESFDMFView_Private(Mat J,Viewer viewer) 154 { 155 int ierr; 156 MatSNESFDMFCtx ctx; 157 MPI_Comm comm; 158 FILE *fd; 159 ViewerType vtype; 160 161 PetscFunctionBegin; 162 PetscObjectGetComm((PetscObject)J,&comm); 163 ierr = MatShellGetContext(J,(void **)&ctx); CHKERRQ(ierr); 164 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 165 ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 166 if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER) { 167 PetscFPrintf(comm,fd," SNES matrix-free approximation:\n"); 168 PetscFPrintf(comm,fd," err=%g (relative error in function evaluation)\n",ctx->error_rel); 169 PetscFPrintf(ctx->comm,fd," Using %s compute h routine \n",ctx->type_name); 170 if (ctx->ops->view) { 171 ierr = (*ctx->ops->view)(ctx,viewer);CHKERRQ(ierr); 172 } 173 } else { 174 SETERRQ(1,1,"Viewer type not supported for this object"); 175 } 176 PetscFunctionReturn(0); 177 } 178 179 180 #undef __FUNC__ 181 #define __FUNC__ "MatSNESFDMFMult_Private" 182 /* 183 MatSNESFDMFMult_Private - Default matrix-free form for Jacobian-vector 184 product, y = F'(u)*a: 185 186 y ~= ( F(u + ha) - F(u) )/h, 187 where F = nonlinear function, as set by SNESSetFunction() 188 u = current iterate 189 h = difference interval 190 */ 191 int MatSNESFDMFMult_Private(Mat mat,Vec a,Vec y) 192 { 193 MatSNESFDMFCtx ctx; 194 SNES snes; 195 Scalar h, mone = -1.0; 196 Vec w,U,F; 197 int ierr, (*eval_fct)(SNES,Vec,Vec); 198 199 PetscFunctionBegin; 200 /* We log matrix-free matrix-vector products separately, so that we can 201 separate the performance monitoring from the cases that use conventional 202 storage. We may eventually modify event logging to associate events 203 with particular objects, hence alleviating the more general problem. */ 204 PLogEventBegin(MAT_MatrixFreeMult,a,y,0,0); 205 206 ierr = MatShellGetContext(mat,(void **)&ctx); CHKERRQ(ierr); 207 snes = ctx->snes; 208 w = ctx->w; 209 210 ierr = SNESGetSolution(snes,&U); CHKERRQ(ierr); 211 if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 212 eval_fct = SNESComputeFunction; 213 ierr = SNESGetFunction(snes,&F); CHKERRQ(ierr); 214 } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 215 eval_fct = SNESComputeGradient; 216 ierr = SNESGetGradient(snes,&F); CHKERRQ(ierr); 217 } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Invalid method class"); 218 219 if (!ctx->ops->compute) { 220 ierr = MatSNESFDMFSetType(mat,"default");CHKERRQ(ierr); 221 ierr = MatSNESFDMFSetFromOptions(mat);CHKERRQ(ierr); 222 } 223 ierr = (*ctx->ops->compute)(ctx,U,a,&h); CHKERRQ(ierr); 224 225 /* keep a record of the current differencing parameter h */ 226 ctx->currenth = h; 227 #if defined(USE_PETSC_COMPLEX) 228 PLogInfo(mat,"Current differencing parameter: %g + %g i\n",PetscReal(h),PetscImaginary(h)); 229 #else 230 PLogInfo(mat,"Current differencing parameter: %g\n",h); 231 #endif 232 if (ctx->historyh && ctx->ncurrenth < ctx->maxcurrenth) { 233 ctx->historyh[ctx->ncurrenth++] = h; 234 } 235 236 /* Evaluate function at F(u + ha) */ 237 ierr = VecWAXPY(&h,a,U,w); CHKERRQ(ierr); 238 ierr = eval_fct(snes,w,y); CHKERRQ(ierr); 239 240 ierr = VecAXPY(&mone,F,y); CHKERRQ(ierr); 241 h = 1.0/h; 242 ierr = VecScale(&h,y); CHKERRQ(ierr); 243 if (ctx->sp) {ierr = PCNullSpaceRemove(ctx->sp,y); CHKERRQ(ierr);} 244 245 PLogEventEnd(MAT_MatrixFreeMult,a,y,0,0); 246 PetscFunctionReturn(0); 247 } 248 249 #undef __FUNC__ 250 #define __FUNC__ "MatCreateSNESFDMF" 251 /*@C 252 MatCreateSNESFDMF - Creates a matrix-free matrix 253 context for use with a SNES solver. This matrix can be used as 254 the Jacobian argument for the routine SNESSetJacobian(). 255 256 Collective on SNES and Vec 257 258 Input Parameters: 259 + snes - the SNES context 260 - x - vector where SNES solution is to be stored. 261 262 Output Parameter: 263 . J - the matrix-free matrix 264 265 Notes: 266 The matrix-free matrix context merely contains the function pointers 267 and work space for performing finite difference approximations of 268 Jacobian-vector products, J(u)*a, 269 270 The default code uses the following approach to compute h 271 272 .vb 273 J(u)*a = [J(u+h*a) - J(u)]/h where 274 h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 275 = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 otherwise 276 where 277 error_rel = square root of relative error in function evaluation 278 umin = minimum iterate parameter 279 .ve 280 281 The user can set the error_rel via MatSNESFDMFSetFunctionError() and 282 umin via MatSNESFDMFDefaultSetUmin() 283 See the nonlinear solvers chapter of the users manual for details. 284 285 The user should call MatDestroy() when finished with the matrix-free 286 matrix context. 287 288 Options Database Keys: 289 + -snes_mf_err <error_rel> - Sets error_rel 290 . -snes_mf_unim <umin> - Sets umin (for default PETSc routine that computes h only) 291 - -snes_mf_ksp_monitor - KSP monitor routine that prints differencing h 292 293 .keywords: SNES, default, matrix-free, create, matrix 294 295 .seealso: MatDestroy(), MatSNESFDMFSetFunctionError(), MatSNESFDMFDefaultSetUmin() 296 MatSNESFDMFSetHHistory(), MatSNESFDMFResetHHistory(), 297 MatSNESFDMFGetH(),MatSNESFDMFKSPMonitor(), MatSNESFDMFRegister() 298 299 @*/ 300 int MatCreateSNESFDMF(SNES snes,Vec x, Mat *J) 301 { 302 MPI_Comm comm; 303 MatSNESFDMFCtx mfctx; 304 int n, nloc, ierr; 305 306 PetscFunctionBegin; 307 mfctx = (MatSNESFDMFCtx) PetscMalloc(sizeof(struct _p_MatSNESFDMFCtx)); CHKPTRQ(mfctx); 308 PLogObjectMemory(snes,sizeof(MatSNESFDMFCtx)); 309 mfctx->comm = snes->comm; 310 mfctx->sp = 0; 311 mfctx->snes = snes; 312 mfctx->error_rel = 1.e-8; /* assumes double precision */ 313 mfctx->currenth = 0.0; 314 mfctx->historyh = PETSC_NULL; 315 mfctx->ncurrenth = 0; 316 mfctx->maxcurrenth = 0; 317 318 /* 319 Create the empty data structure to contain compute-h routines. 320 These will be filled in below from the command line options or 321 a later call with MatSNESFDMFSetType() or if that is not called 322 then it will default in the first use of MatSNESFDMFMult_private() 323 */ 324 mfctx->ops = (MFOps *)PetscMalloc(sizeof(MFOps)); CHKPTRQ(mfctx->ops); 325 mfctx->ops->compute = 0; 326 mfctx->ops->destroy = 0; 327 mfctx->ops->view = 0; 328 mfctx->ops->printhelp = 0; 329 mfctx->ops->setfromoptions = 0; 330 mfctx->hctx = 0; 331 332 ierr = VecDuplicate(x,&mfctx->w); CHKERRQ(ierr); 333 ierr = PetscObjectGetComm((PetscObject)x,&comm); CHKERRQ(ierr); 334 ierr = VecGetSize(x,&n); CHKERRQ(ierr); 335 ierr = VecGetLocalSize(x,&nloc); CHKERRQ(ierr); 336 ierr = MatCreateShell(comm,nloc,n,n,n,mfctx,J); CHKERRQ(ierr); 337 ierr = MatShellSetOperation(*J,MATOP_MULT,(void*)MatSNESFDMFMult_Private);CHKERRQ(ierr); 338 ierr = MatShellSetOperation(*J,MATOP_DESTROY,(void *)MatSNESFDMFDestroy_Private);CHKERRQ(ierr); 339 ierr = MatShellSetOperation(*J,MATOP_VIEW,(void *)MatSNESFDMFView_Private); CHKERRQ(ierr); 340 PLogObjectParent(*J,mfctx->w); 341 PLogObjectParent(snes,*J); 342 343 mfctx->mat = *J; 344 345 346 PetscFunctionReturn(0); 347 } 348 349 #undef __FUNC__ 350 #define __FUNC__ "MatSNESFDMFGetH" 351 /*@ 352 MatSNESFDMFSetFromOptions - Sets the MatSNESFDMF options from the command line 353 parameter. 354 355 Collective on Mat 356 357 Input Parameters: 358 . mat - the matrix obtained with MatCreateSNESFDMF() 359 360 .keywords: SNES, matrix-free, parameters 361 362 .seealso: MatCreateSNESFDMF(),MatSNESFDMFSetHHistory(), 363 MatSNESFDMFResetHHistory(),MatSNESFDMFKSPMonitor() 364 @*/ 365 int MatSNESFDMFSetFromOptions(Mat mat) 366 { 367 MatSNESFDMFCtx mfctx; 368 int ierr,flg; 369 char ftype[256],p[64]; 370 371 PetscFunctionBegin; 372 ierr = MatShellGetContext(mat,(void **)&mfctx); CHKERRQ(ierr); 373 if (mfctx) { 374 /* allow user to set the type */ 375 ierr = OptionsGetString(mfctx->snes->prefix,"-snes_mf_type",ftype,256,&flg);CHKERRQ(ierr); 376 if (flg) { 377 ierr = MatSNESFDMFSetType(mat,ftype);CHKERRQ(ierr); 378 } 379 380 ierr = OptionsGetDouble(mfctx->snes->prefix,"-snes_mf_err",&mfctx->error_rel,&flg);CHKERRQ(ierr); 381 if (mfctx->ops->setfromoptions) { 382 ierr = (*mfctx->ops->setfromoptions)(mfctx);CHKERRQ(ierr); 383 } 384 385 ierr = OptionsHasName(PETSC_NULL,"-help",&flg); CHKERRQ(ierr); 386 PetscStrcpy(p,"-"); 387 if (mfctx->snes->prefix) PetscStrcat(p,mfctx->snes->prefix); 388 if (flg) { 389 (*PetscHelpPrintf)(mfctx->snes->comm," %ssnes_mf_err <err>: set sqrt rel error in function (default %g)\n",p,mfctx->error_rel); 390 if (mfctx->ops->printhelp) { 391 (*mfctx->ops->printhelp)(mfctx);CHKERRQ(ierr); 392 } 393 } 394 } 395 PetscFunctionReturn(0); 396 } 397 398 #undef __FUNC__ 399 #define __FUNC__ "MatSNESFDMFGetH" 400 /*@ 401 MatSNESFDMFGetH - Gets the last h that was used as the differencing 402 parameter. 403 404 Not Collective 405 406 Input Parameters: 407 . mat - the matrix obtained with MatCreateSNESFDMF() 408 409 Output Paramter: 410 . h - the differencing step size 411 412 .keywords: SNES, matrix-free, parameters 413 414 .seealso: MatCreateSNESFDMF(),MatSNESFDMFSetHHistory(), 415 MatSNESFDMFResetHHistory(),MatSNESFDMFKSPMonitor() 416 @*/ 417 int MatSNESFDMFGetH(Mat mat,Scalar *h) 418 { 419 MatSNESFDMFCtx ctx; 420 int ierr; 421 422 PetscFunctionBegin; 423 ierr = MatShellGetContext(mat,(void **)&ctx); CHKERRQ(ierr); 424 if (ctx) { 425 *h = ctx->currenth; 426 } 427 PetscFunctionReturn(0); 428 } 429 430 #undef __FUNC__ 431 #define __FUNC__ "MatSNESFDMFKSPMonitor" 432 /* 433 MatSNESFDMFKSPMonitor - A KSP monitor for use with the default PETSc 434 SNES matrix free routines. Prints the h differencing parameter used at each 435 timestep. 436 437 */ 438 int MatSNESFDMFKSPMonitor(KSP ksp,int n,double rnorm,void *dummy) 439 { 440 PC pc; 441 MatSNESFDMFCtx ctx; 442 int ierr; 443 Mat mat; 444 MPI_Comm comm; 445 PetscTruth nonzeroinitialguess; 446 447 PetscFunctionBegin; 448 ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr); 449 ierr = KSPGetPC(ksp,&pc); CHKERRQ(ierr); 450 ierr = KSPGetInitialGuessNonzero(ksp,&nonzeroinitialguess);CHKERRQ(ierr); 451 ierr = PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); 452 ierr = MatShellGetContext(mat,(void **)&ctx); CHKERRQ(ierr); 453 if (!ctx) { 454 SETERRQ(1,1,"Matrix is not a matrix free shell matrix"); 455 } 456 if (n > 0 || nonzeroinitialguess) { 457 #if defined(USE_PETSC_COMPLEX) 458 PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g + %g i\n",n,rnorm, 459 PetscReal(ctx->currenth),PetscImaginary(ctx->currenth)); 460 #else 461 PetscPrintf(comm,"%d KSP Residual norm %14.12e h %g \n",n,rnorm,ctx->currenth); 462 #endif 463 } else { 464 PetscPrintf(comm,"%d KSP Residual norm %14.12e\n",n,rnorm); 465 } 466 PetscFunctionReturn(0); 467 } 468 469 #undef __FUNC__ 470 #define __FUNC__ "MatSNESFDMFSetFunctionError" 471 /*@ 472 MatSNESFDMFSetFunctionError - Sets the error_rel for the approximation of 473 matrix-vector products using finite differences. 474 475 Collective on Mat 476 477 Input Parameters: 478 + mat - the matrix free matrix created via MatCreateSNESFDMF() 479 - error_rel - relative error (should be set to the square root of 480 the relative error in the function evaluations) 481 482 Notes: 483 The default matrix-free matrix-vector product routine computes 484 .vb 485 J(u)*a = [J(u+h*a) - J(u)]/h where 486 h = error_rel*u'a/||a||^2 if |u'a| > umin*||a||_{1} 487 = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2 else 488 .ve 489 490 Options Database Keys: 491 + -snes_mf_err <error_rel> - Sets error_rel 492 493 .keywords: SNES, matrix-free, parameters 494 495 .seealso: MatCreateSNESFDMF(),MatSNESFDMFGetH(), 496 MatSNESFDMFSetHHistory(), MatSNESFDMFResetHHistory(), 497 MatSNESFDMFKSPMonitor() 498 @*/ 499 int MatSNESFDMFSetFunctionError(Mat mat,double error) 500 { 501 MatSNESFDMFCtx ctx; 502 int ierr; 503 504 PetscFunctionBegin; 505 ierr = MatShellGetContext(mat,(void **)&ctx); CHKERRQ(ierr); 506 if (ctx) { 507 if (error != PETSC_DEFAULT) ctx->error_rel = error; 508 } 509 PetscFunctionReturn(0); 510 } 511 512 #undef __FUNC__ 513 #define __FUNC__ "MatSNESFDMFAddNullSpace" 514 /*@ 515 MatSNESFDMFAddNullSpace - Provides a null space that 516 an operator is supposed to have. Since roundoff will create a 517 small component in the null space, if you know the null space 518 you may have it automatically removed. 519 520 Collective on Mat 521 522 Input Parameters: 523 + J - the matrix-free matrix context 524 . has_cnst - PETSC_TRUE or PETSC_FALSE, indicating if null space has constants 525 . n - number of vectors (excluding constant vector) in null space 526 - vecs - the vectors that span the null space (excluding the constant vector); 527 these vectors must be orthonormal 528 529 .keywords: SNES, matrix-free, null space 530 531 .seealso: MatSNESFDMFGetH(), MatCreateSNESFDMF(), 532 MatSNESFDMFSetHHistory(), MatSNESFDMFResetHHistory(), 533 MatSNESFDMFKSPMonitor(), MatSNESFDMFErrorRel() 534 535 @*/ 536 int MatSNESFDMFAddNullSpace(Mat J,int has_cnst,int n,Vec *vecs) 537 { 538 int ierr; 539 MatSNESFDMFCtx ctx; 540 MPI_Comm comm; 541 542 PetscFunctionBegin; 543 PetscObjectGetComm((PetscObject)J,&comm); 544 545 ierr = MatShellGetContext(J,(void **)&ctx); CHKERRQ(ierr); 546 /* no context indicates that it is not the "matrix free" matrix type */ 547 if (!ctx) PetscFunctionReturn(0); 548 ierr = PCNullSpaceCreate(comm,has_cnst,n,vecs,&ctx->sp); CHKERRQ(ierr); 549 PetscFunctionReturn(0); 550 } 551 552 #undef __FUNC__ 553 #define __FUNC__ "MatSNESFDMFSetHHistory" 554 /*@ 555 MatSNESFDMFSetHHistory - Sets an array to collect a history 556 of the differencing values h computed for the matrix free product 557 558 Collective on Mat 559 560 Input Parameters: 561 + J - the matrix-free matrix context 562 . histroy - space to hold the h history 563 - nhistory - number of entries in history, if more h are generated than 564 nhistory the later ones are discarded 565 566 Notes: 567 Use MatSNESFDMFResetHHistory() to reset the history counter 568 and collect a new batch of h. 569 570 .keywords: SNES, matrix-free, h history, differencing history 571 572 .seealso: MatSNESFDMFGetH(), MatCreateSNESFDMF(), 573 MatSNESFDMFResetHHistory(), 574 MatSNESFDMFKSPMonitor(), MatSNESFDMFSetFunctionError() 575 576 @*/ 577 int MatSNESFDMFSetHHistory(Mat J,Scalar *history,int nhistory) 578 { 579 int ierr; 580 MatSNESFDMFCtx ctx; 581 582 PetscFunctionBegin; 583 584 ierr = MatShellGetContext(J,(void **)&ctx); CHKERRQ(ierr); 585 /* no context indicates that it is not the "matrix free" matrix type */ 586 if (!ctx) PetscFunctionReturn(0); 587 ctx->historyh = history; 588 ctx->maxcurrenth = nhistory; 589 ctx->currenth = 0; 590 591 PetscFunctionReturn(0); 592 } 593 594 #undef __FUNC__ 595 #define __FUNC__ "MatSNESFDMFResetHHistory" 596 /*@ 597 MatSNESFDMFResetHHistory - Resets the counter to zero to begin 598 collecting a new set of differencing histories. 599 600 Collective on Mat 601 602 Input Parameters: 603 . J - the matrix-free matrix context 604 605 Notes: 606 Use MatSNESFDMFSetHHistory() to create the original history counter 607 608 .keywords: SNES, matrix-free, h history, differencing history 609 610 .seealso: MatSNESFDMFGetH(), MatCreateSNESFDMF(), 611 MatSNESFDMFSetHHistory(), 612 MatSNESFDMFKSPMonitor(), MatSNESFDMFSetFunctionError() 613 614 @*/ 615 int MatSNESFDMFResetHHistory(Mat J) 616 { 617 int ierr; 618 MatSNESFDMFCtx ctx; 619 620 PetscFunctionBegin; 621 622 ierr = MatShellGetContext(J,(void **)&ctx); CHKERRQ(ierr); 623 /* no context indicates that it is not the "matrix free" matrix type */ 624 if (!ctx) PetscFunctionReturn(0); 625 ctx->currenth = 0; 626 627 PetscFunctionReturn(0); 628 } 629 630