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