1 2 #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 3 #include <petscdmshell.h> 4 #include <petscdraw.h> 5 #include <petscds.h> 6 #include <petscdmadaptor.h> 7 #include <petscconvest.h> 8 9 PetscBool SNESRegisterAllCalled = PETSC_FALSE; 10 PetscFunctionList SNESList = NULL; 11 12 /* Logging support */ 13 PetscClassId SNES_CLASSID, DMSNES_CLASSID; 14 PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 15 16 /*@ 17 SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 18 19 Logically Collective on SNES 20 21 Input Parameters: 22 + snes - iterative context obtained from SNESCreate() 23 - flg - PETSC_TRUE indicates you want the error generated 24 25 Options database keys: 26 . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 27 28 Level: intermediate 29 30 Notes: 31 Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 32 to determine if it has converged. 33 34 .keywords: SNES, set, initial guess, nonzero 35 36 .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 37 @*/ 38 PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 39 { 40 PetscFunctionBegin; 41 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42 PetscValidLogicalCollectiveBool(snes,flg,2); 43 snes->errorifnotconverged = flg; 44 PetscFunctionReturn(0); 45 } 46 47 /*@ 48 SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 49 50 Not Collective 51 52 Input Parameter: 53 . snes - iterative context obtained from SNESCreate() 54 55 Output Parameter: 56 . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 57 58 Level: intermediate 59 60 .keywords: SNES, set, initial guess, nonzero 61 62 .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 63 @*/ 64 PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 65 { 66 PetscFunctionBegin; 67 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 68 PetscValidPointer(flag,2); 69 *flag = snes->errorifnotconverged; 70 PetscFunctionReturn(0); 71 } 72 73 /*@ 74 SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 75 76 Logically Collective on SNES 77 78 Input Parameters: 79 + snes - the shell SNES 80 - flg - is the residual computed? 81 82 Level: advanced 83 84 .seealso: SNESGetAlwaysComputesFinalResidual() 85 @*/ 86 PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 87 { 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 90 snes->alwayscomputesfinalresidual = flg; 91 PetscFunctionReturn(0); 92 } 93 94 /*@ 95 SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 96 97 Logically Collective on SNES 98 99 Input Parameter: 100 . snes - the shell SNES 101 102 Output Parameter: 103 . flg - is the residual computed? 104 105 Level: advanced 106 107 .seealso: SNESSetAlwaysComputesFinalResidual() 108 @*/ 109 PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 110 { 111 PetscFunctionBegin; 112 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 113 *flg = snes->alwayscomputesfinalresidual; 114 PetscFunctionReturn(0); 115 } 116 117 /*@ 118 SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 119 in the functions domain. For example, negative pressure. 120 121 Logically Collective on SNES 122 123 Input Parameters: 124 . snes - the SNES context 125 126 Level: advanced 127 128 .keywords: SNES, view 129 130 .seealso: SNESCreate(), SNESSetFunction(), SNESFunction 131 @*/ 132 PetscErrorCode SNESSetFunctionDomainError(SNES snes) 133 { 134 PetscFunctionBegin; 135 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 136 if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain"); 137 snes->domainerror = PETSC_TRUE; 138 PetscFunctionReturn(0); 139 } 140 141 /*@ 142 SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 143 144 Logically Collective on SNES 145 146 Input Parameters: 147 . snes - the SNES context 148 149 Output Parameters: 150 . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 151 152 Level: advanced 153 154 .keywords: SNES, view 155 156 .seealso: SNESSetFunctionDomainError(), SNESComputeFunction() 157 @*/ 158 PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 159 { 160 PetscFunctionBegin; 161 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 162 PetscValidPointer(domainerror, 2); 163 *domainerror = snes->domainerror; 164 PetscFunctionReturn(0); 165 } 166 167 /*@C 168 SNESLoad - Loads a SNES that has been stored in binary with SNESView(). 169 170 Collective on PetscViewer 171 172 Input Parameters: 173 + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or 174 some related function before a call to SNESLoad(). 175 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 176 177 Level: intermediate 178 179 Notes: 180 The type is determined by the data in the file, any type set into the SNES before this call is ignored. 181 182 Notes for advanced users: 183 Most users should not need to know the details of the binary storage 184 format, since SNESLoad() and TSView() completely hide these details. 185 But for anyone who's interested, the standard binary matrix storage 186 format is 187 .vb 188 has not yet been determined 189 .ve 190 191 .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad() 192 @*/ 193 PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 194 { 195 PetscErrorCode ierr; 196 PetscBool isbinary; 197 PetscInt classid; 198 char type[256]; 199 KSP ksp; 200 DM dm; 201 DMSNES dmsnes; 202 203 PetscFunctionBegin; 204 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 205 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 206 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 207 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 208 209 ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 210 if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file"); 211 ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 212 ierr = SNESSetType(snes, type);CHKERRQ(ierr); 213 if (snes->ops->load) { 214 ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr); 215 } 216 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 217 ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr); 218 ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr); 219 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 220 ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr); 221 PetscFunctionReturn(0); 222 } 223 224 #include <petscdraw.h> 225 #if defined(PETSC_HAVE_SAWS) 226 #include <petscviewersaws.h> 227 #endif 228 229 /*@C 230 SNESView - Prints the SNES data structure. 231 232 Collective on SNES 233 234 Input Parameters: 235 + SNES - the SNES context 236 - viewer - visualization context 237 238 Options Database Key: 239 . -snes_view - Calls SNESView() at end of SNESSolve() 240 241 Notes: 242 The available visualization contexts include 243 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 244 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 245 output where only the first processor opens 246 the file. All other processors send their 247 data to the first processor to print. 248 249 The user can open an alternative visualization context with 250 PetscViewerASCIIOpen() - output to a specified file. 251 252 Level: beginner 253 254 .keywords: SNES, view 255 256 .seealso: PetscViewerASCIIOpen() 257 @*/ 258 PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 259 { 260 SNESKSPEW *kctx; 261 PetscErrorCode ierr; 262 KSP ksp; 263 SNESLineSearch linesearch; 264 PetscBool iascii,isstring,isbinary,isdraw; 265 DMSNES dmsnes; 266 #if defined(PETSC_HAVE_SAWS) 267 PetscBool issaws; 268 #endif 269 270 PetscFunctionBegin; 271 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 272 if (!viewer) { 273 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr); 274 } 275 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 276 PetscCheckSameComm(snes,1,viewer,2); 277 278 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 279 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 280 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 281 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 282 #if defined(PETSC_HAVE_SAWS) 283 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 284 #endif 285 if (iascii) { 286 SNESNormSchedule normschedule; 287 DM dm; 288 PetscErrorCode (*cJ)(SNES,Vec,Mat,Mat,void*); 289 void *ctx; 290 PetscInt tabs; 291 292 ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 293 ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr); 294 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr); 295 if (!snes->setupcalled) { 296 ierr = PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr); 297 } 298 if (snes->ops->view) { 299 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 300 ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 301 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 302 } 303 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 304 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr); 305 if (snes->usesksp) { 306 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 307 } 308 ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 309 ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr); 310 if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);} 311 if (snes->gridsequence) { 312 ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 313 } 314 if (snes->ksp_ewconv) { 315 kctx = (SNESKSPEW*)snes->kspconvctx; 316 if (kctx) { 317 ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 318 ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold);CHKERRQ(ierr); 319 ierr = PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr); 320 } 321 } 322 if (snes->lagpreconditioner == -1) { 323 ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 324 } else if (snes->lagpreconditioner > 1) { 325 ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 326 } 327 if (snes->lagjacobian == -1) { 328 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 329 } else if (snes->lagjacobian > 1) { 330 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 331 } 332 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 333 ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr); 334 if (cJ == SNESComputeJacobianDefault) { 335 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is built using finite differences one column at a time\n");CHKERRQ(ierr); 336 } else if (cJ == SNESComputeJacobianDefaultColor) { 337 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is built using finite differences with coloring\n");CHKERRQ(ierr); 338 } 339 ierr = PetscViewerASCIISetTab(viewer, tabs);CHKERRQ(ierr); 340 } else if (isstring) { 341 const char *type; 342 ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 343 ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 344 } else if (isbinary) { 345 PetscInt classid = SNES_FILE_CLASSID; 346 MPI_Comm comm; 347 PetscMPIInt rank; 348 char type[256]; 349 350 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 351 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 352 if (!rank) { 353 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 354 ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr); 355 ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 356 } 357 if (snes->ops->view) { 358 ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 359 } 360 } else if (isdraw) { 361 PetscDraw draw; 362 char str[36]; 363 PetscReal x,y,bottom,h; 364 365 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 366 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 367 ierr = PetscStrncpy(str,"SNES: ",sizeof(str));CHKERRQ(ierr); 368 ierr = PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));CHKERRQ(ierr); 369 ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 370 bottom = y - h; 371 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 372 if (snes->ops->view) { 373 ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 374 } 375 #if defined(PETSC_HAVE_SAWS) 376 } else if (issaws) { 377 PetscMPIInt rank; 378 const char *name; 379 380 ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr); 381 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 382 if (!((PetscObject)snes)->amsmem && !rank) { 383 char dir[1024]; 384 385 ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr); 386 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr); 387 PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 388 if (!snes->conv_hist) { 389 ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr); 390 } 391 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr); 392 PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 393 } 394 #endif 395 } 396 if (snes->linesearch) { 397 ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 398 ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 399 } 400 if (snes->npc && snes->usesnpc) { 401 ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr); 402 } 403 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 404 ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr); 405 ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr); 406 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 407 if (snes->usesksp) { 408 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 409 ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 410 } 411 if (isdraw) { 412 PetscDraw draw; 413 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 414 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 415 } 416 PetscFunctionReturn(0); 417 } 418 419 /* 420 We retain a list of functions that also take SNES command 421 line options. These are called at the end SNESSetFromOptions() 422 */ 423 #define MAXSETFROMOPTIONS 5 424 static PetscInt numberofsetfromoptions; 425 static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 426 427 /*@C 428 SNESAddOptionsChecker - Adds an additional function to check for SNES options. 429 430 Not Collective 431 432 Input Parameter: 433 . snescheck - function that checks for options 434 435 Level: developer 436 437 .seealso: SNESSetFromOptions() 438 @*/ 439 PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 440 { 441 PetscFunctionBegin; 442 if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 443 othersetfromoptions[numberofsetfromoptions++] = snescheck; 444 PetscFunctionReturn(0); 445 } 446 447 extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 448 449 static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 450 { 451 Mat J; 452 KSP ksp; 453 PC pc; 454 PetscBool match; 455 PetscErrorCode ierr; 456 MatNullSpace nullsp; 457 458 PetscFunctionBegin; 459 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 460 461 if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 462 Mat A = snes->jacobian, B = snes->jacobian_pre; 463 ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr); 464 } 465 466 if (version == 1) { 467 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 468 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 469 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 470 } else if (version == 2) { 471 if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 472 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 473 ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 474 #else 475 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 476 #endif 477 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 478 479 /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 480 if (snes->jacobian) { 481 ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr); 482 if (nullsp) { 483 ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr); 484 } 485 } 486 487 ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 488 if (hasOperator) { 489 490 /* This version replaces the user provided Jacobian matrix with a 491 matrix-free version but still employs the user-provided preconditioner matrix. */ 492 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 493 } else { 494 /* This version replaces both the user-provided Jacobian and the user- 495 provided preconditioner Jacobian with the default matrix free version. */ 496 if ((snes->npcside== PC_LEFT) && snes->npc) { 497 if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);} 498 } else { 499 ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr); 500 } 501 /* Force no preconditioner */ 502 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 503 ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 504 ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 505 if (!match) { 506 ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 507 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 508 } 509 } 510 ierr = MatDestroy(&J);CHKERRQ(ierr); 511 PetscFunctionReturn(0); 512 } 513 514 static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 515 { 516 SNES snes = (SNES)ctx; 517 PetscErrorCode ierr; 518 Vec Xfine,Xfine_named = NULL,Xcoarse; 519 520 PetscFunctionBegin; 521 if (PetscLogPrintInfo) { 522 PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 523 ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr); 524 ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr); 525 ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr); 526 ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr); 527 ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr); 528 } 529 if (dmfine == snes->dm) Xfine = snes->vec_sol; 530 else { 531 ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 532 Xfine = Xfine_named; 533 } 534 ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 535 if (Inject) { 536 ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr); 537 } else { 538 ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 539 ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 540 } 541 ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 542 if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 543 PetscFunctionReturn(0); 544 } 545 546 static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 547 { 548 PetscErrorCode ierr; 549 550 PetscFunctionBegin; 551 ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr); 552 PetscFunctionReturn(0); 553 } 554 555 /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 556 * safely call SNESGetDM() in their residual evaluation routine. */ 557 static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 558 { 559 SNES snes = (SNES)ctx; 560 PetscErrorCode ierr; 561 Mat Asave = A,Bsave = B; 562 Vec X,Xnamed = NULL; 563 DM dmsave; 564 void *ctxsave; 565 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; 566 567 PetscFunctionBegin; 568 dmsave = snes->dm; 569 ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 570 if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 571 else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 572 ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 573 X = Xnamed; 574 ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr); 575 /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 576 if (jac == SNESComputeJacobianDefaultColor) { 577 ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 578 } 579 } 580 /* put the previous context back */ 581 582 ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr); 583 if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 584 ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr); 585 } 586 587 if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time"); 588 if (Xnamed) { 589 ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 590 } 591 snes->dm = dmsave; 592 PetscFunctionReturn(0); 593 } 594 595 /*@ 596 SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 597 598 Collective 599 600 Input Arguments: 601 . snes - snes to configure 602 603 Level: developer 604 605 .seealso: SNESSetUp() 606 @*/ 607 PetscErrorCode SNESSetUpMatrices(SNES snes) 608 { 609 PetscErrorCode ierr; 610 DM dm; 611 DMSNES sdm; 612 613 PetscFunctionBegin; 614 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 615 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 616 if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured"); 617 else if (!snes->jacobian && snes->mf) { 618 Mat J; 619 void *functx; 620 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 621 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 622 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 623 ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 624 ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr); 625 ierr = MatDestroy(&J);CHKERRQ(ierr); 626 } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 627 Mat J,B; 628 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 629 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 630 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 631 ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 632 /* sdm->computejacobian was already set to reach here */ 633 ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr); 634 ierr = MatDestroy(&J);CHKERRQ(ierr); 635 ierr = MatDestroy(&B);CHKERRQ(ierr); 636 } else if (!snes->jacobian_pre) { 637 PetscDS prob; 638 Mat J, B; 639 PetscBool hasPrec = PETSC_FALSE; 640 641 J = snes->jacobian; 642 ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 643 if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);} 644 if (J) {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);} 645 else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);} 646 ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr); 647 ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr); 648 ierr = MatDestroy(&J);CHKERRQ(ierr); 649 ierr = MatDestroy(&B);CHKERRQ(ierr); 650 } 651 { 652 KSP ksp; 653 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 654 ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 655 ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 656 } 657 PetscFunctionReturn(0); 658 } 659 660 /*@C 661 SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 662 663 Collective on SNES 664 665 Input Parameters: 666 + snes - SNES object you wish to monitor 667 . name - the monitor type one is seeking 668 . help - message indicating what monitoring is done 669 . manual - manual page for the monitor 670 . monitor - the monitor function 671 - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects 672 673 Level: developer 674 675 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 676 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 677 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 678 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 679 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 680 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 681 PetscOptionsFList(), PetscOptionsEList() 682 @*/ 683 PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 684 { 685 PetscErrorCode ierr; 686 PetscViewer viewer; 687 PetscViewerFormat format; 688 PetscBool flg; 689 690 PetscFunctionBegin; 691 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 692 if (flg) { 693 PetscViewerAndFormat *vf; 694 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 695 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 696 if (monitorsetup) { 697 ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr); 698 } 699 ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 700 } 701 PetscFunctionReturn(0); 702 } 703 704 /*@ 705 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 706 707 Collective on SNES 708 709 Input Parameter: 710 . snes - the SNES context 711 712 Options Database Keys: 713 + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 714 . -snes_stol - convergence tolerance in terms of the norm 715 of the change in the solution between steps 716 . -snes_atol <abstol> - absolute tolerance of residual norm 717 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 718 . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 719 . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 720 . -snes_max_it <max_it> - maximum number of iterations 721 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 722 . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 723 . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 724 . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 725 . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 726 . -snes_trtol <trtol> - trust region tolerance 727 . -snes_no_convergence_test - skip convergence test in nonlinear 728 solver; hence iterations will continue until max_it 729 or some other criterion is reached. Saves expense 730 of convergence test 731 . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 732 . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 733 . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 734 . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 735 . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 736 . -snes_monitor_lg_range - plots residual norm at each iteration 737 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 738 . -snes_fd_color - use finite differences with coloring to compute Jacobian 739 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 740 - -snes_converged_reason - print the reason for convergence/divergence after each solve 741 742 Options Database for Eisenstat-Walker method: 743 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 744 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 745 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 746 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 747 . -snes_ksp_ew_gamma <gamma> - Sets gamma 748 . -snes_ksp_ew_alpha <alpha> - Sets alpha 749 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 750 - -snes_ksp_ew_threshold <threshold> - Sets threshold 751 752 Notes: 753 To see all options, run your program with the -help option or consult 754 Users-Manual: ch_snes 755 756 Level: beginner 757 758 .keywords: SNES, nonlinear, set, options, database 759 760 .seealso: SNESSetOptionsPrefix() 761 @*/ 762 PetscErrorCode SNESSetFromOptions(SNES snes) 763 { 764 PetscBool flg,pcset,persist,set; 765 PetscInt i,indx,lag,grids; 766 const char *deft = SNESNEWTONLS; 767 const char *convtests[] = {"default","skip"}; 768 SNESKSPEW *kctx = NULL; 769 char type[256], monfilename[PETSC_MAX_PATH_LEN]; 770 PetscErrorCode ierr; 771 PCSide pcside; 772 const char *optionsprefix; 773 774 PetscFunctionBegin; 775 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 776 ierr = SNESRegisterAll();CHKERRQ(ierr); 777 ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 778 if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 779 ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 780 if (flg) { 781 ierr = SNESSetType(snes,type);CHKERRQ(ierr); 782 } else if (!((PetscObject)snes)->type_name) { 783 ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 784 } 785 ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr); 786 ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr); 787 788 ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr); 789 ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr); 790 ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr); 791 ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr); 792 ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr); 793 ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr); 794 ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr); 795 ierr = PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL);CHKERRQ(ierr); 796 797 ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 798 if (flg) { 799 ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 800 } 801 ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 802 if (flg) { 803 ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr); 804 } 805 ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 806 if (flg) { 807 ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 808 } 809 ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 810 if (flg) { 811 ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr); 812 } 813 814 ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 815 if (flg) { 816 ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 817 } 818 819 ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 820 if (flg) { 821 switch (indx) { 822 case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break; 823 case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; 824 } 825 } 826 827 ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr); 828 if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); } 829 830 ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr); 831 if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); } 832 833 kctx = (SNESKSPEW*)snes->kspconvctx; 834 835 ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr); 836 837 ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr); 838 ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr); 839 ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr); 840 ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr); 841 ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr); 842 ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr); 843 ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr); 844 845 flg = PETSC_FALSE; 846 ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr); 847 if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 848 849 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr); 850 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr); 851 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr); 852 853 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr); 854 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr); 855 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr); 856 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 857 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr); 858 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr); 859 ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr); 860 861 ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 862 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 863 864 865 flg = PETSC_FALSE; 866 ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr); 867 if (flg) { 868 PetscDrawLG ctx; 869 870 ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 871 ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); 872 } 873 flg = PETSC_FALSE; 874 ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr); 875 if (flg) { 876 PetscViewer ctx; 877 878 ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 879 ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 880 } 881 882 883 884 flg = PETSC_FALSE; 885 ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr); 886 if (flg) { 887 void *functx; 888 DM dm; 889 DMSNES sdm; 890 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 891 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 892 sdm->jacobianctx = NULL; 893 ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 894 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr); 895 ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 896 } 897 898 flg = PETSC_FALSE; 899 ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr); 900 if (flg) { 901 ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr); 902 } 903 904 flg = PETSC_FALSE; 905 ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr); 906 if (flg) { 907 DM dm; 908 DMSNES sdm; 909 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 910 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 911 sdm->jacobianctx = NULL; 912 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 913 ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 914 } 915 916 flg = PETSC_FALSE; 917 ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr); 918 if (flg && snes->mf_operator) { 919 snes->mf_operator = PETSC_TRUE; 920 snes->mf = PETSC_TRUE; 921 } 922 flg = PETSC_FALSE; 923 ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 924 if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 925 ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr); 926 927 flg = PETSC_FALSE; 928 ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr); 929 ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 930 if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);} 931 932 #if defined(PETSC_HAVE_SAWS) 933 /* 934 Publish convergence information using SAWs 935 */ 936 flg = PETSC_FALSE; 937 ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); 938 if (flg) { 939 void *ctx; 940 ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr); 941 ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr); 942 } 943 #endif 944 #if defined(PETSC_HAVE_SAWS) 945 { 946 PetscBool set; 947 flg = PETSC_FALSE; 948 ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr); 949 if (set) { 950 ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr); 951 } 952 } 953 #endif 954 955 for (i = 0; i < numberofsetfromoptions; i++) { 956 ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 957 } 958 959 if (snes->ops->setfromoptions) { 960 ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr); 961 } 962 963 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 964 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr); 965 ierr = PetscOptionsEnd();CHKERRQ(ierr); 966 967 if (!snes->linesearch) { 968 ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 969 } 970 ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 971 972 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 973 ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 974 ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 975 976 /* if someone has set the SNES NPC type, create it. */ 977 ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 978 ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 979 if (pcset && (!snes->npc)) { 980 ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr); 981 } 982 PetscFunctionReturn(0); 983 } 984 985 /*@C 986 SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 987 the nonlinear solvers. 988 989 Logically Collective on SNES 990 991 Input Parameters: 992 + snes - the SNES context 993 . compute - function to compute the context 994 - destroy - function to destroy the context 995 996 Level: intermediate 997 998 Notes: 999 This function is currently not available from Fortran. 1000 1001 .keywords: SNES, nonlinear, set, application, context 1002 1003 .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 1004 @*/ 1005 PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 1006 { 1007 PetscFunctionBegin; 1008 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1009 snes->ops->usercompute = compute; 1010 snes->ops->userdestroy = destroy; 1011 PetscFunctionReturn(0); 1012 } 1013 1014 /*@ 1015 SNESSetApplicationContext - Sets the optional user-defined context for 1016 the nonlinear solvers. 1017 1018 Logically Collective on SNES 1019 1020 Input Parameters: 1021 + snes - the SNES context 1022 - usrP - optional user context 1023 1024 Level: intermediate 1025 1026 Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 1027 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1028 1029 .keywords: SNES, nonlinear, set, application, context 1030 1031 .seealso: SNESGetApplicationContext() 1032 @*/ 1033 PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 1034 { 1035 PetscErrorCode ierr; 1036 KSP ksp; 1037 1038 PetscFunctionBegin; 1039 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1040 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1041 ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 1042 snes->user = usrP; 1043 PetscFunctionReturn(0); 1044 } 1045 1046 /*@ 1047 SNESGetApplicationContext - Gets the user-defined context for the 1048 nonlinear solvers. 1049 1050 Not Collective 1051 1052 Input Parameter: 1053 . snes - SNES context 1054 1055 Output Parameter: 1056 . usrP - user context 1057 1058 Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 1059 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1060 1061 Level: intermediate 1062 1063 .keywords: SNES, nonlinear, get, application, context 1064 1065 .seealso: SNESSetApplicationContext() 1066 @*/ 1067 PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 1068 { 1069 PetscFunctionBegin; 1070 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1071 *(void**)usrP = snes->user; 1072 PetscFunctionReturn(0); 1073 } 1074 1075 /*@ 1076 SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply 1077 the Jacobian. 1078 1079 Collective on SNES 1080 1081 Input Parameters: 1082 + snes - SNES context 1083 . mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 1084 - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 1085 1086 Options Database: 1087 + -snes_mf - use matrix free for both the mat and pmat operator 1088 - -snes_mf_operator - use matrix free only for the mat operator 1089 1090 Level: intermediate 1091 1092 .keywords: SNES, nonlinear, get, iteration, number, 1093 1094 .seealso: SNESGetUseMatrixFree(), MatCreateSNESMF() 1095 @*/ 1096 PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 1097 { 1098 PetscFunctionBegin; 1099 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1100 PetscValidLogicalCollectiveBool(snes,mf_operator,2); 1101 PetscValidLogicalCollectiveBool(snes,mf,3); 1102 if (mf && !mf_operator) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"If using mf must also use mf_operator"); 1103 snes->mf = mf; 1104 snes->mf_operator = mf_operator; 1105 PetscFunctionReturn(0); 1106 } 1107 1108 /*@ 1109 SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply 1110 the Jacobian. 1111 1112 Collective on SNES 1113 1114 Input Parameter: 1115 . snes - SNES context 1116 1117 Output Parameters: 1118 + mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 1119 - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 1120 1121 Options Database: 1122 + -snes_mf - use matrix free for both the mat and pmat operator 1123 - -snes_mf_operator - use matrix free only for the mat operator 1124 1125 Level: intermediate 1126 1127 .keywords: SNES, nonlinear, get, iteration, number, 1128 1129 .seealso: SNESSetUseMatrixFree(), MatCreateSNESMF() 1130 @*/ 1131 PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 1132 { 1133 PetscFunctionBegin; 1134 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1135 if (mf) *mf = snes->mf; 1136 if (mf_operator) *mf_operator = snes->mf_operator; 1137 PetscFunctionReturn(0); 1138 } 1139 1140 /*@ 1141 SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1142 at this time. 1143 1144 Not Collective 1145 1146 Input Parameter: 1147 . snes - SNES context 1148 1149 Output Parameter: 1150 . iter - iteration number 1151 1152 Notes: 1153 For example, during the computation of iteration 2 this would return 1. 1154 1155 This is useful for using lagged Jacobians (where one does not recompute the 1156 Jacobian at each SNES iteration). For example, the code 1157 .vb 1158 ierr = SNESGetIterationNumber(snes,&it); 1159 if (!(it % 2)) { 1160 [compute Jacobian here] 1161 } 1162 .ve 1163 can be used in your ComputeJacobian() function to cause the Jacobian to be 1164 recomputed every second SNES iteration. 1165 1166 After the SNES solve is complete this will return the number of nonlinear iterations used. 1167 1168 Level: intermediate 1169 1170 .keywords: SNES, nonlinear, get, iteration, number, 1171 1172 .seealso: SNESGetLinearSolveIterations() 1173 @*/ 1174 PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 1175 { 1176 PetscFunctionBegin; 1177 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1178 PetscValidIntPointer(iter,2); 1179 *iter = snes->iter; 1180 PetscFunctionReturn(0); 1181 } 1182 1183 /*@ 1184 SNESSetIterationNumber - Sets the current iteration number. 1185 1186 Not Collective 1187 1188 Input Parameter: 1189 . snes - SNES context 1190 . iter - iteration number 1191 1192 Level: developer 1193 1194 .keywords: SNES, nonlinear, set, iteration, number, 1195 1196 .seealso: SNESGetLinearSolveIterations() 1197 @*/ 1198 PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1199 { 1200 PetscErrorCode ierr; 1201 1202 PetscFunctionBegin; 1203 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1204 ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 1205 snes->iter = iter; 1206 ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 1207 PetscFunctionReturn(0); 1208 } 1209 1210 /*@ 1211 SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 1212 attempted by the nonlinear solver. 1213 1214 Not Collective 1215 1216 Input Parameter: 1217 . snes - SNES context 1218 1219 Output Parameter: 1220 . nfails - number of unsuccessful steps attempted 1221 1222 Notes: 1223 This counter is reset to zero for each successive call to SNESSolve(). 1224 1225 Level: intermediate 1226 1227 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 1228 1229 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 1230 SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 1231 @*/ 1232 PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 1233 { 1234 PetscFunctionBegin; 1235 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1236 PetscValidIntPointer(nfails,2); 1237 *nfails = snes->numFailures; 1238 PetscFunctionReturn(0); 1239 } 1240 1241 /*@ 1242 SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1243 attempted by the nonlinear solver before it gives up. 1244 1245 Not Collective 1246 1247 Input Parameters: 1248 + snes - SNES context 1249 - maxFails - maximum of unsuccessful steps 1250 1251 Level: intermediate 1252 1253 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 1254 1255 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 1256 SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 1257 @*/ 1258 PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 1259 { 1260 PetscFunctionBegin; 1261 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1262 snes->maxFailures = maxFails; 1263 PetscFunctionReturn(0); 1264 } 1265 1266 /*@ 1267 SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1268 attempted by the nonlinear solver before it gives up. 1269 1270 Not Collective 1271 1272 Input Parameter: 1273 . snes - SNES context 1274 1275 Output Parameter: 1276 . maxFails - maximum of unsuccessful steps 1277 1278 Level: intermediate 1279 1280 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 1281 1282 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 1283 SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 1284 1285 @*/ 1286 PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 1287 { 1288 PetscFunctionBegin; 1289 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1290 PetscValidIntPointer(maxFails,2); 1291 *maxFails = snes->maxFailures; 1292 PetscFunctionReturn(0); 1293 } 1294 1295 /*@ 1296 SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1297 done by SNES. 1298 1299 Not Collective 1300 1301 Input Parameter: 1302 . snes - SNES context 1303 1304 Output Parameter: 1305 . nfuncs - number of evaluations 1306 1307 Level: intermediate 1308 1309 Notes: Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1310 1311 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 1312 1313 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset() 1314 @*/ 1315 PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 1316 { 1317 PetscFunctionBegin; 1318 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1319 PetscValidIntPointer(nfuncs,2); 1320 *nfuncs = snes->nfuncs; 1321 PetscFunctionReturn(0); 1322 } 1323 1324 /*@ 1325 SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 1326 linear solvers. 1327 1328 Not Collective 1329 1330 Input Parameter: 1331 . snes - SNES context 1332 1333 Output Parameter: 1334 . nfails - number of failed solves 1335 1336 Level: intermediate 1337 1338 Options Database Keys: 1339 . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 1340 1341 Notes: 1342 This counter is reset to zero for each successive call to SNESSolve(). 1343 1344 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 1345 1346 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 1347 @*/ 1348 PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 1349 { 1350 PetscFunctionBegin; 1351 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1352 PetscValidIntPointer(nfails,2); 1353 *nfails = snes->numLinearSolveFailures; 1354 PetscFunctionReturn(0); 1355 } 1356 1357 /*@ 1358 SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1359 allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 1360 1361 Logically Collective on SNES 1362 1363 Input Parameters: 1364 + snes - SNES context 1365 - maxFails - maximum allowed linear solve failures 1366 1367 Level: intermediate 1368 1369 Options Database Keys: 1370 . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 1371 1372 Notes: By default this is 0; that is SNES returns on the first failed linear solve 1373 1374 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 1375 1376 .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 1377 @*/ 1378 PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 1379 { 1380 PetscFunctionBegin; 1381 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1382 PetscValidLogicalCollectiveInt(snes,maxFails,2); 1383 snes->maxLinearSolveFailures = maxFails; 1384 PetscFunctionReturn(0); 1385 } 1386 1387 /*@ 1388 SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1389 are allowed before SNES terminates 1390 1391 Not Collective 1392 1393 Input Parameter: 1394 . snes - SNES context 1395 1396 Output Parameter: 1397 . maxFails - maximum of unsuccessful solves allowed 1398 1399 Level: intermediate 1400 1401 Notes: By default this is 1; that is SNES returns on the first failed linear solve 1402 1403 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 1404 1405 .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 1406 @*/ 1407 PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 1408 { 1409 PetscFunctionBegin; 1410 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1411 PetscValidIntPointer(maxFails,2); 1412 *maxFails = snes->maxLinearSolveFailures; 1413 PetscFunctionReturn(0); 1414 } 1415 1416 /*@ 1417 SNESGetLinearSolveIterations - Gets the total number of linear iterations 1418 used by the nonlinear solver. 1419 1420 Not Collective 1421 1422 Input Parameter: 1423 . snes - SNES context 1424 1425 Output Parameter: 1426 . lits - number of linear iterations 1427 1428 Notes: 1429 This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1430 1431 If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them 1432 then call KSPGetIterationNumber() after the failed solve. 1433 1434 Level: intermediate 1435 1436 .keywords: SNES, nonlinear, get, number, linear, iterations 1437 1438 .seealso: SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset() 1439 @*/ 1440 PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1441 { 1442 PetscFunctionBegin; 1443 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1444 PetscValidIntPointer(lits,2); 1445 *lits = snes->linear_its; 1446 PetscFunctionReturn(0); 1447 } 1448 1449 /*@ 1450 SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1451 are reset every time SNESSolve() is called. 1452 1453 Logically Collective on SNES 1454 1455 Input Parameter: 1456 + snes - SNES context 1457 - reset - whether to reset the counters or not 1458 1459 Notes: 1460 This defaults to PETSC_TRUE 1461 1462 Level: developer 1463 1464 .keywords: SNES, nonlinear, set, reset, number, linear, iterations 1465 1466 .seealso: SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC() 1467 @*/ 1468 PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1469 { 1470 PetscFunctionBegin; 1471 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1472 PetscValidLogicalCollectiveBool(snes,reset,2); 1473 snes->counters_reset = reset; 1474 PetscFunctionReturn(0); 1475 } 1476 1477 1478 /*@ 1479 SNESSetKSP - Sets a KSP context for the SNES object to use 1480 1481 Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 1482 1483 Input Parameters: 1484 + snes - the SNES context 1485 - ksp - the KSP context 1486 1487 Notes: 1488 The SNES object already has its KSP object, you can obtain with SNESGetKSP() 1489 so this routine is rarely needed. 1490 1491 The KSP object that is already in the SNES object has its reference count 1492 decreased by one. 1493 1494 Level: developer 1495 1496 .keywords: SNES, nonlinear, get, KSP, context 1497 1498 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 1499 @*/ 1500 PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 1501 { 1502 PetscErrorCode ierr; 1503 1504 PetscFunctionBegin; 1505 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1506 PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 1507 PetscCheckSameComm(snes,1,ksp,2); 1508 ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1509 if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 1510 snes->ksp = ksp; 1511 PetscFunctionReturn(0); 1512 } 1513 1514 /* -----------------------------------------------------------*/ 1515 /*@ 1516 SNESCreate - Creates a nonlinear solver context. 1517 1518 Collective on MPI_Comm 1519 1520 Input Parameters: 1521 . comm - MPI communicator 1522 1523 Output Parameter: 1524 . outsnes - the new SNES context 1525 1526 Options Database Keys: 1527 + -snes_mf - Activates default matrix-free Jacobian-vector products, 1528 and no preconditioning matrix 1529 . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1530 products, and a user-provided preconditioning matrix 1531 as set by SNESSetJacobian() 1532 - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1533 1534 Level: beginner 1535 1536 Developer Notes: SNES always creates a KSP object even though many SNES methods do not use it. This is 1537 unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1538 particular method does use KSP and regulates if the information about the KSP is printed 1539 in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1540 by help messages about meaningless SNES options. 1541 1542 SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1543 be fixed. 1544 1545 .keywords: SNES, nonlinear, create, context 1546 1547 .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1548 1549 @*/ 1550 PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 1551 { 1552 PetscErrorCode ierr; 1553 SNES snes; 1554 SNESKSPEW *kctx; 1555 1556 PetscFunctionBegin; 1557 PetscValidPointer(outsnes,2); 1558 *outsnes = NULL; 1559 ierr = SNESInitializePackage();CHKERRQ(ierr); 1560 1561 ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 1562 1563 snes->ops->converged = SNESConvergedDefault; 1564 snes->usesksp = PETSC_TRUE; 1565 snes->tolerancesset = PETSC_FALSE; 1566 snes->max_its = 50; 1567 snes->max_funcs = 10000; 1568 snes->norm = 0.0; 1569 snes->normschedule = SNES_NORM_ALWAYS; 1570 snes->functype = SNES_FUNCTION_DEFAULT; 1571 #if defined(PETSC_USE_REAL_SINGLE) 1572 snes->rtol = 1.e-5; 1573 #else 1574 snes->rtol = 1.e-8; 1575 #endif 1576 snes->ttol = 0.0; 1577 #if defined(PETSC_USE_REAL_SINGLE) 1578 snes->abstol = 1.e-25; 1579 #else 1580 snes->abstol = 1.e-50; 1581 #endif 1582 #if defined(PETSC_USE_REAL_SINGLE) 1583 snes->stol = 1.e-5; 1584 #else 1585 snes->stol = 1.e-8; 1586 #endif 1587 #if defined(PETSC_USE_REAL_SINGLE) 1588 snes->deltatol = 1.e-6; 1589 #else 1590 snes->deltatol = 1.e-12; 1591 #endif 1592 snes->divtol = 1.e4; 1593 snes->rnorm0 = 0; 1594 snes->nfuncs = 0; 1595 snes->numFailures = 0; 1596 snes->maxFailures = 1; 1597 snes->linear_its = 0; 1598 snes->lagjacobian = 1; 1599 snes->jac_iter = 0; 1600 snes->lagjac_persist = PETSC_FALSE; 1601 snes->lagpreconditioner = 1; 1602 snes->pre_iter = 0; 1603 snes->lagpre_persist = PETSC_FALSE; 1604 snes->numbermonitors = 0; 1605 snes->data = 0; 1606 snes->setupcalled = PETSC_FALSE; 1607 snes->ksp_ewconv = PETSC_FALSE; 1608 snes->nwork = 0; 1609 snes->work = 0; 1610 snes->nvwork = 0; 1611 snes->vwork = 0; 1612 snes->conv_hist_len = 0; 1613 snes->conv_hist_max = 0; 1614 snes->conv_hist = NULL; 1615 snes->conv_hist_its = NULL; 1616 snes->conv_hist_reset = PETSC_TRUE; 1617 snes->counters_reset = PETSC_TRUE; 1618 snes->vec_func_init_set = PETSC_FALSE; 1619 snes->reason = SNES_CONVERGED_ITERATING; 1620 snes->npcside = PC_RIGHT; 1621 1622 snes->mf = PETSC_FALSE; 1623 snes->mf_operator = PETSC_FALSE; 1624 snes->mf_version = 1; 1625 1626 snes->numLinearSolveFailures = 0; 1627 snes->maxLinearSolveFailures = 1; 1628 1629 snes->vizerotolerance = 1.e-8; 1630 1631 /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 1632 snes->alwayscomputesfinalresidual = PETSC_FALSE; 1633 1634 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1635 ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1636 1637 snes->kspconvctx = (void*)kctx; 1638 kctx->version = 2; 1639 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 1640 this was too large for some test cases */ 1641 kctx->rtol_last = 0.0; 1642 kctx->rtol_max = .9; 1643 kctx->gamma = 1.0; 1644 kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 1645 kctx->alpha2 = kctx->alpha; 1646 kctx->threshold = .1; 1647 kctx->lresid_last = 0.0; 1648 kctx->norm_last = 0.0; 1649 1650 *outsnes = snes; 1651 PetscFunctionReturn(0); 1652 } 1653 1654 /*MC 1655 SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 1656 1657 Synopsis: 1658 #include "petscsnes.h" 1659 PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 1660 1661 Input Parameters: 1662 + snes - the SNES context 1663 . x - state at which to evaluate residual 1664 - ctx - optional user-defined function context, passed in with SNESSetFunction() 1665 1666 Output Parameter: 1667 . f - vector to put residual (function value) 1668 1669 Level: intermediate 1670 1671 .seealso: SNESSetFunction(), SNESGetFunction() 1672 M*/ 1673 1674 /*@C 1675 SNESSetFunction - Sets the function evaluation routine and function 1676 vector for use by the SNES routines in solving systems of nonlinear 1677 equations. 1678 1679 Logically Collective on SNES 1680 1681 Input Parameters: 1682 + snes - the SNES context 1683 . r - vector to store function value 1684 . f - function evaluation routine; see SNESFunction for calling sequence details 1685 - ctx - [optional] user-defined context for private data for the 1686 function evaluation routine (may be NULL) 1687 1688 Notes: 1689 The Newton-like methods typically solve linear systems of the form 1690 $ f'(x) x = -f(x), 1691 where f'(x) denotes the Jacobian matrix and f(x) is the function. 1692 1693 Level: beginner 1694 1695 .keywords: SNES, nonlinear, set, function 1696 1697 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 1698 @*/ 1699 PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 1700 { 1701 PetscErrorCode ierr; 1702 DM dm; 1703 1704 PetscFunctionBegin; 1705 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1706 if (r) { 1707 PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1708 PetscCheckSameComm(snes,1,r,2); 1709 ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 1710 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1711 1712 snes->vec_func = r; 1713 } 1714 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1715 ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 1716 PetscFunctionReturn(0); 1717 } 1718 1719 1720 /*@C 1721 SNESSetInitialFunction - Sets the function vector to be used as the 1722 function norm at the initialization of the method. In some 1723 instances, the user has precomputed the function before calling 1724 SNESSolve. This function allows one to avoid a redundant call 1725 to SNESComputeFunction in that case. 1726 1727 Logically Collective on SNES 1728 1729 Input Parameters: 1730 + snes - the SNES context 1731 - f - vector to store function value 1732 1733 Notes: 1734 This should not be modified during the solution procedure. 1735 1736 This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1737 1738 Level: developer 1739 1740 .keywords: SNES, nonlinear, set, function 1741 1742 .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1743 @*/ 1744 PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1745 { 1746 PetscErrorCode ierr; 1747 Vec vec_func; 1748 1749 PetscFunctionBegin; 1750 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1751 PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1752 PetscCheckSameComm(snes,1,f,2); 1753 if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1754 snes->vec_func_init_set = PETSC_FALSE; 1755 PetscFunctionReturn(0); 1756 } 1757 ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr); 1758 ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1759 1760 snes->vec_func_init_set = PETSC_TRUE; 1761 PetscFunctionReturn(0); 1762 } 1763 1764 /*@ 1765 SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring 1766 of the SNES method. 1767 1768 Logically Collective on SNES 1769 1770 Input Parameters: 1771 + snes - the SNES context 1772 - normschedule - the frequency of norm computation 1773 1774 Options Database Key: 1775 . -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly> 1776 1777 Notes: 1778 Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1779 of the nonlinear function and the taking of its norm at every iteration to 1780 even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1781 (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 1782 may either be monitored for convergence or not. As these are often used as nonlinear 1783 preconditioners, monitoring the norm of their error is not a useful enterprise within 1784 their solution. 1785 1786 Level: developer 1787 1788 .keywords: SNES, nonlinear, set, function, norm, type 1789 1790 .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1791 @*/ 1792 PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1793 { 1794 PetscFunctionBegin; 1795 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1796 snes->normschedule = normschedule; 1797 PetscFunctionReturn(0); 1798 } 1799 1800 1801 /*@ 1802 SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring 1803 of the SNES method. 1804 1805 Logically Collective on SNES 1806 1807 Input Parameters: 1808 + snes - the SNES context 1809 - normschedule - the type of the norm used 1810 1811 Level: advanced 1812 1813 .keywords: SNES, nonlinear, set, function, norm, type 1814 1815 .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1816 @*/ 1817 PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1818 { 1819 PetscFunctionBegin; 1820 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1821 *normschedule = snes->normschedule; 1822 PetscFunctionReturn(0); 1823 } 1824 1825 1826 /*@ 1827 SNESSetFunctionNorm - Sets the last computed residual norm. 1828 1829 Logically Collective on SNES 1830 1831 Input Parameters: 1832 + snes - the SNES context 1833 1834 - normschedule - the frequency of norm computation 1835 1836 Level: developer 1837 1838 .keywords: SNES, nonlinear, set, function, norm, type 1839 .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1840 @*/ 1841 PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1842 { 1843 PetscFunctionBegin; 1844 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1845 snes->norm = norm; 1846 PetscFunctionReturn(0); 1847 } 1848 1849 /*@ 1850 SNESGetFunctionNorm - Gets the last computed norm of the residual 1851 1852 Not Collective 1853 1854 Input Parameter: 1855 . snes - the SNES context 1856 1857 Output Parameter: 1858 . norm - the last computed residual norm 1859 1860 Level: developer 1861 1862 .keywords: SNES, nonlinear, set, function, norm, type 1863 .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1864 @*/ 1865 PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1866 { 1867 PetscFunctionBegin; 1868 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1869 PetscValidPointer(norm, 2); 1870 *norm = snes->norm; 1871 PetscFunctionReturn(0); 1872 } 1873 1874 /*@C 1875 SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring 1876 of the SNES method. 1877 1878 Logically Collective on SNES 1879 1880 Input Parameters: 1881 + snes - the SNES context 1882 - normschedule - the frequency of norm computation 1883 1884 Notes: 1885 Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1886 of the nonlinear function and the taking of its norm at every iteration to 1887 even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1888 (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 1889 may either be monitored for convergence or not. As these are often used as nonlinear 1890 preconditioners, monitoring the norm of their error is not a useful enterprise within 1891 their solution. 1892 1893 Level: developer 1894 1895 .keywords: SNES, nonlinear, set, function, norm, type 1896 1897 .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1898 @*/ 1899 PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 1900 { 1901 PetscFunctionBegin; 1902 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1903 snes->functype = type; 1904 PetscFunctionReturn(0); 1905 } 1906 1907 1908 /*@C 1909 SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring 1910 of the SNES method. 1911 1912 Logically Collective on SNES 1913 1914 Input Parameters: 1915 + snes - the SNES context 1916 - normschedule - the type of the norm used 1917 1918 Level: advanced 1919 1920 .keywords: SNES, nonlinear, set, function, norm, type 1921 1922 .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1923 @*/ 1924 PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 1925 { 1926 PetscFunctionBegin; 1927 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1928 *type = snes->functype; 1929 PetscFunctionReturn(0); 1930 } 1931 1932 /*MC 1933 SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 1934 1935 Synopsis: 1936 #include <petscsnes.h> 1937 $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 1938 1939 + X - solution vector 1940 . B - RHS vector 1941 - ctx - optional user-defined Gauss-Seidel context 1942 1943 Level: intermediate 1944 1945 .seealso: SNESSetNGS(), SNESGetNGS() 1946 M*/ 1947 1948 /*@C 1949 SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 1950 use with composed nonlinear solvers. 1951 1952 Input Parameters: 1953 + snes - the SNES context 1954 . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 1955 - ctx - [optional] user-defined context for private data for the 1956 smoother evaluation routine (may be NULL) 1957 1958 Notes: 1959 The NGS routines are used by the composed nonlinear solver to generate 1960 a problem appropriate update to the solution, particularly FAS. 1961 1962 Level: intermediate 1963 1964 .keywords: SNES, nonlinear, set, Gauss-Seidel 1965 1966 .seealso: SNESGetFunction(), SNESComputeNGS() 1967 @*/ 1968 PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 1969 { 1970 PetscErrorCode ierr; 1971 DM dm; 1972 1973 PetscFunctionBegin; 1974 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1975 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1976 ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr); 1977 PetscFunctionReturn(0); 1978 } 1979 1980 PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 1981 { 1982 PetscErrorCode ierr; 1983 DM dm; 1984 DMSNES sdm; 1985 1986 PetscFunctionBegin; 1987 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1988 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 1989 /* A(x)*x - b(x) */ 1990 if (sdm->ops->computepfunction) { 1991 ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 1992 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function."); 1993 1994 if (sdm->ops->computepjacobian) { 1995 ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 1996 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix."); 1997 ierr = VecScale(f,-1.0);CHKERRQ(ierr); 1998 ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr); 1999 PetscFunctionReturn(0); 2000 } 2001 2002 PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 2003 { 2004 PetscFunctionBegin; 2005 /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2006 PetscFunctionReturn(0); 2007 } 2008 2009 /*@C 2010 SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 2011 2012 Logically Collective on SNES 2013 2014 Input Parameters: 2015 + snes - the SNES context 2016 . r - vector to store function value 2017 . b - function evaluation routine 2018 . Amat - matrix with which A(x) x - b(x) is to be computed 2019 . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 2020 . J - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence 2021 - ctx - [optional] user-defined context for private data for the 2022 function evaluation routine (may be NULL) 2023 2024 Notes: 2025 We do not recomemend using this routine. It is far better to provide the nonlinear function F() and some approximation to the Jacobian and use 2026 an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton. 2027 2028 One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 2029 2030 $ Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n} 2031 $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration. 2032 2033 Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 2034 2035 We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 2036 the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 2037 2038 There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 2039 believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 2040 different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 2041 2042 Level: intermediate 2043 2044 .keywords: SNES, nonlinear, set, function 2045 2046 .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 2047 @*/ 2048 PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*b)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 2049 { 2050 PetscErrorCode ierr; 2051 DM dm; 2052 2053 PetscFunctionBegin; 2054 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2055 ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 2056 ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr); 2057 ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 2058 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 2059 PetscFunctionReturn(0); 2060 } 2061 2062 /*@C 2063 SNESGetPicard - Returns the context for the Picard iteration 2064 2065 Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 2066 2067 Input Parameter: 2068 . snes - the SNES context 2069 2070 Output Parameter: 2071 + r - the function (or NULL) 2072 . f - the function (or NULL); see SNESFunction for calling sequence details 2073 . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2074 . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2075 . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 2076 - ctx - the function context (or NULL) 2077 2078 Level: advanced 2079 2080 .keywords: SNES, nonlinear, get, function 2081 2082 .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 2083 @*/ 2084 PetscErrorCode SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2085 { 2086 PetscErrorCode ierr; 2087 DM dm; 2088 2089 PetscFunctionBegin; 2090 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2091 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2092 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 2093 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2094 ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 2095 PetscFunctionReturn(0); 2096 } 2097 2098 /*@C 2099 SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2100 2101 Logically Collective on SNES 2102 2103 Input Parameters: 2104 + snes - the SNES context 2105 . func - function evaluation routine 2106 - ctx - [optional] user-defined context for private data for the 2107 function evaluation routine (may be NULL) 2108 2109 Calling sequence of func: 2110 $ func (SNES snes,Vec x,void *ctx); 2111 2112 . f - function vector 2113 - ctx - optional user-defined function context 2114 2115 Level: intermediate 2116 2117 .keywords: SNES, nonlinear, set, function 2118 2119 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2120 @*/ 2121 PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2122 { 2123 PetscFunctionBegin; 2124 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2125 if (func) snes->ops->computeinitialguess = func; 2126 if (ctx) snes->initialguessP = ctx; 2127 PetscFunctionReturn(0); 2128 } 2129 2130 /* --------------------------------------------------------------- */ 2131 /*@C 2132 SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 2133 it assumes a zero right hand side. 2134 2135 Logically Collective on SNES 2136 2137 Input Parameter: 2138 . snes - the SNES context 2139 2140 Output Parameter: 2141 . rhs - the right hand side vector or NULL if the right hand side vector is null 2142 2143 Level: intermediate 2144 2145 .keywords: SNES, nonlinear, get, function, right hand side 2146 2147 .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 2148 @*/ 2149 PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 2150 { 2151 PetscFunctionBegin; 2152 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2153 PetscValidPointer(rhs,2); 2154 *rhs = snes->vec_rhs; 2155 PetscFunctionReturn(0); 2156 } 2157 2158 /*@ 2159 SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 2160 2161 Collective on SNES 2162 2163 Input Parameters: 2164 + snes - the SNES context 2165 - x - input vector 2166 2167 Output Parameter: 2168 . y - function vector, as set by SNESSetFunction() 2169 2170 Notes: 2171 SNESComputeFunction() is typically used within nonlinear solvers 2172 implementations, so most users would not generally call this routine 2173 themselves. 2174 2175 Level: developer 2176 2177 .keywords: SNES, nonlinear, compute, function 2178 2179 .seealso: SNESSetFunction(), SNESGetFunction() 2180 @*/ 2181 PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 2182 { 2183 PetscErrorCode ierr; 2184 DM dm; 2185 DMSNES sdm; 2186 2187 PetscFunctionBegin; 2188 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2189 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2190 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2191 PetscCheckSameComm(snes,1,x,2); 2192 PetscCheckSameComm(snes,1,y,3); 2193 ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2194 2195 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2196 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2197 if (sdm->ops->computefunction) { 2198 if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2199 ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 2200 } 2201 ierr = VecLockPush(x);CHKERRQ(ierr); 2202 PetscStackPush("SNES user function"); 2203 ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2204 PetscStackPop; 2205 ierr = VecLockPop(x);CHKERRQ(ierr); 2206 if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2207 ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 2208 } 2209 } else if (snes->vec_rhs) { 2210 ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2211 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 2212 if (snes->vec_rhs) { 2213 ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 2214 } 2215 snes->nfuncs++; 2216 /* 2217 domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2218 propagate the value to all processes 2219 */ 2220 if (snes->domainerror) { 2221 ierr = VecSetInf(y);CHKERRQ(ierr); 2222 } 2223 PetscFunctionReturn(0); 2224 } 2225 2226 /*@ 2227 SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2228 2229 Collective on SNES 2230 2231 Input Parameters: 2232 + snes - the SNES context 2233 . x - input vector 2234 - b - rhs vector 2235 2236 Output Parameter: 2237 . x - new solution vector 2238 2239 Notes: 2240 SNESComputeNGS() is typically used within composed nonlinear solver 2241 implementations, so most users would not generally call this routine 2242 themselves. 2243 2244 Level: developer 2245 2246 .keywords: SNES, nonlinear, compute, function 2247 2248 .seealso: SNESSetNGS(), SNESComputeFunction() 2249 @*/ 2250 PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2251 { 2252 PetscErrorCode ierr; 2253 DM dm; 2254 DMSNES sdm; 2255 2256 PetscFunctionBegin; 2257 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2258 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2259 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 2260 PetscCheckSameComm(snes,1,x,2); 2261 if (b) PetscCheckSameComm(snes,1,b,3); 2262 if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2263 ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2264 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2265 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2266 if (sdm->ops->computegs) { 2267 if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);} 2268 PetscStackPush("SNES user NGS"); 2269 ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2270 PetscStackPop; 2271 if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);} 2272 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2273 ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2274 PetscFunctionReturn(0); 2275 } 2276 2277 PetscErrorCode SNESTestJacobian(SNES snes) 2278 { 2279 Mat A = snes->jacobian,B,C; 2280 Vec x = snes->vec_sol,f = snes->vec_func; 2281 PetscErrorCode ierr; 2282 PetscReal nrm,gnorm; 2283 PetscReal threshold = 1.e-5; 2284 PetscInt m,n,M,N; 2285 void *functx; 2286 PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE; 2287 PetscViewer viewer; 2288 MPI_Comm comm; 2289 PetscInt tabs; 2290 2291 PetscFunctionBegin; 2292 ierr = PetscObjectOptionsBegin((PetscObject)snes); 2293 ierr = PetscOptionsBool("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",test,&test,NULL);CHKERRQ(ierr); 2294 ierr = PetscOptionsBool("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",complete_print,&complete_print,NULL);CHKERRQ(ierr); 2295 ierr = PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print);CHKERRQ(ierr); 2296 ierr = PetscOptionsEnd();CHKERRQ(ierr); 2297 if (!test) PetscFunctionReturn(0); 2298 2299 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2300 ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 2301 ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 2302 ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr); 2303 if (A != snes->jacobian_pre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot test with alternative preconditioner"); 2304 2305 ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if the ratio is\n");CHKERRQ(ierr); 2306 ierr = PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr); 2307 if (!complete_print) { 2308 ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_display to show difference\n");CHKERRQ(ierr); 2309 ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian.\n");CHKERRQ(ierr); 2310 ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_display_threshold to show difference\n");CHKERRQ(ierr); 2311 ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries great than threshold.\n");CHKERRQ(ierr); 2312 } 2313 2314 /* evaluate the function at this point because SNESComputeJacobianDefaultColor() assumes that the function has been evaluated and put into snes->vec_func */ 2315 ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr); 2316 A = snes->jacobian_pre; 2317 2318 ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 2319 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2320 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 2321 ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 2322 ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2323 ierr = MatSetUp(B);CHKERRQ(ierr); 2324 ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2325 2326 ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 2327 ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr); 2328 if (complete_print) { 2329 ierr = PetscViewerASCIIPrintf(viewer," Finite difference Jacobian\n");CHKERRQ(ierr); 2330 ierr = MatView(B,viewer);CHKERRQ(ierr); 2331 } 2332 /* compare */ 2333 ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2334 ierr = MatNorm(B,NORM_FROBENIUS,&nrm);CHKERRQ(ierr); 2335 ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr); 2336 if (complete_print) { 2337 ierr = PetscViewerASCIIPrintf(viewer,"Hand-coded Jacobian\n");CHKERRQ(ierr); 2338 ierr = PetscObjectGetComm((PetscObject)B,&comm);CHKERRQ(ierr); 2339 ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 2340 ierr = MatView(A,viewer);CHKERRQ(ierr); 2341 ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian\n");CHKERRQ(ierr); 2342 ierr = MatView(B,viewer);CHKERRQ(ierr); 2343 } 2344 2345 if (threshold_print) { 2346 PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2347 PetscScalar *cvals; 2348 const PetscInt *bcols; 2349 const PetscScalar *bvals; 2350 2351 ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2352 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 2353 ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2354 ierr = MatSetUp(C);CHKERRQ(ierr); 2355 ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2356 ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr); 2357 2358 for (row = Istart; row < Iend; row++) { 2359 ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2360 ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr); 2361 for (j = 0, cncols = 0; j < bncols; j++) { 2362 if (PetscAbsScalar(bvals[j]) > threshold) { 2363 ccols[cncols] = bcols[j]; 2364 cvals[cncols] = bvals[j]; 2365 cncols += 1; 2366 } 2367 } 2368 if(cncols) { 2369 ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr); 2370 } 2371 ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2372 ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr); 2373 } 2374 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2375 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2376 2377 ierr = PetscViewerASCIIPrintf(viewer," Entries where difference is over threshold\n");CHKERRQ(ierr); 2378 ierr = MatView(C,viewer);CHKERRQ(ierr); 2379 ierr = MatDestroy(&C);CHKERRQ(ierr); 2380 } 2381 2382 if (!gnorm) gnorm = 1; /* just in case */ 2383 ierr = PetscViewerASCIIPrintf(viewer,"||J - Jfd||_F/||J||_F %g, ||J - Jfd||_F %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr); 2384 ierr = MatDestroy(&B);CHKERRQ(ierr); 2385 ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 2386 PetscFunctionReturn(0); 2387 } 2388 2389 /*@ 2390 SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 2391 2392 Collective on SNES and Mat 2393 2394 Input Parameters: 2395 + snes - the SNES context 2396 - x - input vector 2397 2398 Output Parameters: 2399 + A - Jacobian matrix 2400 - B - optional preconditioning matrix 2401 2402 Options Database Keys: 2403 + -snes_lag_preconditioner <lag> 2404 . -snes_lag_jacobian <lag> 2405 . -snes_test_jacobian - compare the user provided Jacobian with one compute via finite differences to check for errors 2406 . -snes_test_jacobian_display - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian 2407 . -snes_test_jacobian_display_threshold <numerical value> - display entries in the difference between the user provided Jacobian and finite difference Jacobian that are greater than a certain value to help users detect errors 2408 . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2409 . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2410 . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 2411 . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 2412 . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2413 . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2414 . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2415 . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2416 . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2417 . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2418 - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2419 2420 2421 Notes: 2422 Most users should not need to explicitly call this routine, as it 2423 is used internally within the nonlinear solvers. 2424 2425 Developer Notes: This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used 2426 for with the SNESType of test that has been removed. 2427 2428 Level: developer 2429 2430 .keywords: SNES, compute, Jacobian, matrix 2431 2432 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 2433 @*/ 2434 PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 2435 { 2436 PetscErrorCode ierr; 2437 PetscBool flag; 2438 DM dm; 2439 DMSNES sdm; 2440 KSP ksp; 2441 2442 PetscFunctionBegin; 2443 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2444 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2445 PetscCheckSameComm(snes,1,X,2); 2446 ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 2447 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2448 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2449 2450 if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2451 2452 /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2453 2454 if (snes->lagjacobian == -2) { 2455 snes->lagjacobian = -1; 2456 2457 ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2458 } else if (snes->lagjacobian == -1) { 2459 ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 2460 ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2461 if (flag) { 2462 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2463 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2464 } 2465 PetscFunctionReturn(0); 2466 } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2467 ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2468 ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2469 if (flag) { 2470 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2471 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2472 } 2473 PetscFunctionReturn(0); 2474 } 2475 if (snes->npc && snes->npcside== PC_LEFT) { 2476 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2477 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2478 PetscFunctionReturn(0); 2479 } 2480 2481 ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2482 ierr = VecLockPush(X);CHKERRQ(ierr); 2483 PetscStackPush("SNES user Jacobian function"); 2484 ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2485 PetscStackPop; 2486 ierr = VecLockPop(X);CHKERRQ(ierr); 2487 ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2488 2489 /* the next line ensures that snes->ksp exists */ 2490 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 2491 if (snes->lagpreconditioner == -2) { 2492 ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2493 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2494 snes->lagpreconditioner = -1; 2495 } else if (snes->lagpreconditioner == -1) { 2496 ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2497 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2498 } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2499 ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2500 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2501 } else { 2502 ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2503 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2504 } 2505 2506 ierr = SNESTestJacobian(snes);CHKERRQ(ierr); 2507 /* make sure user returned a correct Jacobian and preconditioner */ 2508 /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 2509 PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2510 { 2511 PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2512 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 2513 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 2514 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 2515 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2516 if (flag || flag_draw || flag_contour) { 2517 Mat Bexp_mine = NULL,Bexp,FDexp; 2518 PetscViewer vdraw,vstdout; 2519 PetscBool flg; 2520 if (flag_operator) { 2521 ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr); 2522 Bexp = Bexp_mine; 2523 } else { 2524 /* See if the preconditioning matrix can be viewed and added directly */ 2525 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2526 if (flg) Bexp = B; 2527 else { 2528 /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2529 ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr); 2530 Bexp = Bexp_mine; 2531 } 2532 } 2533 ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2534 ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2535 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2536 if (flag_draw || flag_contour) { 2537 ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2538 if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2539 } else vdraw = NULL; 2540 ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2541 if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2542 if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2543 ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2544 if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2545 if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2546 ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2547 ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2548 if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2549 if (vdraw) { /* Always use contour for the difference */ 2550 ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2551 ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2552 ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2553 } 2554 if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2555 ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2556 ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2557 ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2558 } 2559 } 2560 { 2561 PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 2562 PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 2563 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 2564 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 2565 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 2566 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 2567 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 2568 if (flag_threshold) { 2569 ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2570 ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 2571 } 2572 if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 2573 Mat Bfd; 2574 PetscViewer vdraw,vstdout; 2575 MatColoring coloring; 2576 ISColoring iscoloring; 2577 MatFDColoring matfdcoloring; 2578 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2579 void *funcctx; 2580 PetscReal norm1,norm2,normmax; 2581 2582 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2583 ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2584 ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2585 ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2586 ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2587 ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 2588 ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2589 ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2590 ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 2591 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 2592 2593 /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 2594 ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 2595 ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 2596 ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2597 ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 2598 ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2599 ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 2600 ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 2601 2602 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2603 if (flag_draw || flag_contour) { 2604 ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2605 if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2606 } else vdraw = NULL; 2607 ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 2608 if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 2609 if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 2610 ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 2611 if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 2612 if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 2613 ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2614 ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 2615 ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 2616 ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 2617 ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax);CHKERRQ(ierr); 2618 if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 2619 if (vdraw) { /* Always use contour for the difference */ 2620 ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2621 ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 2622 ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2623 } 2624 if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2625 2626 if (flag_threshold) { 2627 PetscInt bs,rstart,rend,i; 2628 ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 2629 ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 2630 for (i=rstart; i<rend; i++) { 2631 const PetscScalar *ba,*ca; 2632 const PetscInt *bj,*cj; 2633 PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 2634 PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 2635 ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 2636 ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 2637 if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 2638 for (j=0; j<bn; j++) { 2639 PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 2640 if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 2641 maxentrycol = bj[j]; 2642 maxentry = PetscRealPart(ba[j]); 2643 } 2644 if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 2645 maxdiffcol = bj[j]; 2646 maxdiff = PetscRealPart(ca[j]); 2647 } 2648 if (rdiff > maxrdiff) { 2649 maxrdiffcol = bj[j]; 2650 maxrdiff = rdiff; 2651 } 2652 } 2653 if (maxrdiff > 1) { 2654 ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%g at %D, maxdiff=%g at %D, maxrdiff=%g at %D):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol);CHKERRQ(ierr); 2655 for (j=0; j<bn; j++) { 2656 PetscReal rdiff; 2657 rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 2658 if (rdiff > 1) { 2659 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 2660 } 2661 } 2662 ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 2663 } 2664 ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 2665 ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 2666 } 2667 } 2668 ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2669 ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 2670 } 2671 } 2672 PetscFunctionReturn(0); 2673 } 2674 2675 /*MC 2676 SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2677 2678 Synopsis: 2679 #include "petscsnes.h" 2680 PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2681 2682 + x - input vector 2683 . Amat - the matrix that defines the (approximate) Jacobian 2684 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2685 - ctx - [optional] user-defined Jacobian context 2686 2687 Level: intermediate 2688 2689 .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 2690 M*/ 2691 2692 /*@C 2693 SNESSetJacobian - Sets the function to compute Jacobian as well as the 2694 location to store the matrix. 2695 2696 Logically Collective on SNES and Mat 2697 2698 Input Parameters: 2699 + snes - the SNES context 2700 . Amat - the matrix that defines the (approximate) Jacobian 2701 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2702 . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2703 - ctx - [optional] user-defined context for private data for the 2704 Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 2705 2706 Notes: 2707 If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 2708 each matrix. 2709 2710 If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2711 space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2712 2713 If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2714 must be a MatFDColoring. 2715 2716 Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2717 example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2718 2719 Level: beginner 2720 2721 .keywords: SNES, nonlinear, set, Jacobian, matrix 2722 2723 .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 2724 SNESSetPicard(), SNESJacobianFunction 2725 @*/ 2726 PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 2727 { 2728 PetscErrorCode ierr; 2729 DM dm; 2730 2731 PetscFunctionBegin; 2732 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2733 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2734 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 2735 if (Amat) PetscCheckSameComm(snes,1,Amat,2); 2736 if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 2737 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2738 ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 2739 if (Amat) { 2740 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 2741 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2742 2743 snes->jacobian = Amat; 2744 } 2745 if (Pmat) { 2746 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 2747 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2748 2749 snes->jacobian_pre = Pmat; 2750 } 2751 PetscFunctionReturn(0); 2752 } 2753 2754 /*@C 2755 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2756 provided context for evaluating the Jacobian. 2757 2758 Not Collective, but Mat object will be parallel if SNES object is 2759 2760 Input Parameter: 2761 . snes - the nonlinear solver context 2762 2763 Output Parameters: 2764 + Amat - location to stash (approximate) Jacobian matrix (or NULL) 2765 . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 2766 . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 2767 - ctx - location to stash Jacobian ctx (or NULL) 2768 2769 Level: advanced 2770 2771 .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 2772 @*/ 2773 PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2774 { 2775 PetscErrorCode ierr; 2776 DM dm; 2777 DMSNES sdm; 2778 2779 PetscFunctionBegin; 2780 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2781 if (Amat) *Amat = snes->jacobian; 2782 if (Pmat) *Pmat = snes->jacobian_pre; 2783 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2784 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2785 if (J) *J = sdm->ops->computejacobian; 2786 if (ctx) *ctx = sdm->jacobianctx; 2787 PetscFunctionReturn(0); 2788 } 2789 2790 /*@ 2791 SNESSetUp - Sets up the internal data structures for the later use 2792 of a nonlinear solver. 2793 2794 Collective on SNES 2795 2796 Input Parameters: 2797 . snes - the SNES context 2798 2799 Notes: 2800 For basic use of the SNES solvers the user need not explicitly call 2801 SNESSetUp(), since these actions will automatically occur during 2802 the call to SNESSolve(). However, if one wishes to control this 2803 phase separately, SNESSetUp() should be called after SNESCreate() 2804 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2805 2806 Level: advanced 2807 2808 .keywords: SNES, nonlinear, setup 2809 2810 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 2811 @*/ 2812 PetscErrorCode SNESSetUp(SNES snes) 2813 { 2814 PetscErrorCode ierr; 2815 DM dm; 2816 DMSNES sdm; 2817 SNESLineSearch linesearch, pclinesearch; 2818 void *lsprectx,*lspostctx; 2819 PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 2820 PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 2821 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2822 Vec f,fpc; 2823 void *funcctx; 2824 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 2825 void *jacctx,*appctx; 2826 Mat j,jpre; 2827 2828 PetscFunctionBegin; 2829 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2830 if (snes->setupcalled) PetscFunctionReturn(0); 2831 2832 if (!((PetscObject)snes)->type_name) { 2833 ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 2834 } 2835 2836 ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 2837 2838 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2839 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2840 if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 2841 if (!sdm->ops->computejacobian) { 2842 ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 2843 } 2844 if (!snes->vec_func) { 2845 ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2846 } 2847 2848 if (!snes->ksp) { 2849 ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 2850 } 2851 2852 if (!snes->linesearch) { 2853 ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 2854 } 2855 ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 2856 2857 if (snes->npc && (snes->npcside== PC_LEFT)) { 2858 snes->mf = PETSC_TRUE; 2859 snes->mf_operator = PETSC_FALSE; 2860 } 2861 2862 if (snes->npc) { 2863 /* copy the DM over */ 2864 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2865 ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr); 2866 2867 ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 2868 ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 2869 ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr); 2870 ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 2871 ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr); 2872 ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 2873 ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr); 2874 ierr = VecDestroy(&fpc);CHKERRQ(ierr); 2875 2876 /* copy the function pointers over */ 2877 ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 2878 2879 /* default to 1 iteration */ 2880 ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr); 2881 if (snes->npcside==PC_RIGHT) { 2882 ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 2883 } else { 2884 ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr); 2885 } 2886 ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 2887 2888 /* copy the line search context over */ 2889 ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2890 ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr); 2891 ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 2892 ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 2893 ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 2894 ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 2895 ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 2896 } 2897 if (snes->mf) { 2898 ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 2899 } 2900 if (snes->ops->usercompute && !snes->user) { 2901 ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2902 } 2903 2904 snes->jac_iter = 0; 2905 snes->pre_iter = 0; 2906 2907 if (snes->ops->setup) { 2908 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2909 } 2910 2911 if (snes->npc && (snes->npcside== PC_LEFT)) { 2912 if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 2913 ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2914 ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 2915 } 2916 } 2917 2918 snes->setupcalled = PETSC_TRUE; 2919 PetscFunctionReturn(0); 2920 } 2921 2922 /*@ 2923 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 2924 2925 Collective on SNES 2926 2927 Input Parameter: 2928 . snes - iterative context obtained from SNESCreate() 2929 2930 Level: intermediate 2931 2932 Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 2933 2934 .keywords: SNES, destroy 2935 2936 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 2937 @*/ 2938 PetscErrorCode SNESReset(SNES snes) 2939 { 2940 PetscErrorCode ierr; 2941 2942 PetscFunctionBegin; 2943 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2944 if (snes->ops->userdestroy && snes->user) { 2945 ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2946 snes->user = NULL; 2947 } 2948 if (snes->npc) { 2949 ierr = SNESReset(snes->npc);CHKERRQ(ierr); 2950 } 2951 2952 if (snes->ops->reset) { 2953 ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 2954 } 2955 if (snes->ksp) { 2956 ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 2957 } 2958 2959 if (snes->linesearch) { 2960 ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 2961 } 2962 2963 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 2964 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 2965 ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 2966 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 2967 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2968 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2969 ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2970 ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 2971 2972 snes->alwayscomputesfinalresidual = PETSC_FALSE; 2973 2974 snes->nwork = snes->nvwork = 0; 2975 snes->setupcalled = PETSC_FALSE; 2976 PetscFunctionReturn(0); 2977 } 2978 2979 /*@ 2980 SNESDestroy - Destroys the nonlinear solver context that was created 2981 with SNESCreate(). 2982 2983 Collective on SNES 2984 2985 Input Parameter: 2986 . snes - the SNES context 2987 2988 Level: beginner 2989 2990 .keywords: SNES, nonlinear, destroy 2991 2992 .seealso: SNESCreate(), SNESSolve() 2993 @*/ 2994 PetscErrorCode SNESDestroy(SNES *snes) 2995 { 2996 PetscErrorCode ierr; 2997 2998 PetscFunctionBegin; 2999 if (!*snes) PetscFunctionReturn(0); 3000 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 3001 if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 3002 3003 ierr = SNESReset((*snes));CHKERRQ(ierr); 3004 ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr); 3005 3006 /* if memory was published with SAWs then destroy it */ 3007 ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 3008 if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 3009 3010 if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);} 3011 ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 3012 ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 3013 ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 3014 3015 ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 3016 if ((*snes)->ops->convergeddestroy) { 3017 ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 3018 } 3019 if ((*snes)->conv_malloc) { 3020 ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 3021 ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 3022 } 3023 ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 3024 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 3025 PetscFunctionReturn(0); 3026 } 3027 3028 /* ----------- Routines to set solver parameters ---------- */ 3029 3030 /*@ 3031 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3032 3033 Logically Collective on SNES 3034 3035 Input Parameters: 3036 + snes - the SNES context 3037 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3038 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3039 3040 Options Database Keys: 3041 . -snes_lag_preconditioner <lag> 3042 3043 Notes: 3044 The default is 1 3045 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3046 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 3047 3048 Level: intermediate 3049 3050 .keywords: SNES, nonlinear, set, convergence, tolerances 3051 3052 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 3053 3054 @*/ 3055 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3056 { 3057 PetscFunctionBegin; 3058 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3059 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3060 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3061 PetscValidLogicalCollectiveInt(snes,lag,2); 3062 snes->lagpreconditioner = lag; 3063 PetscFunctionReturn(0); 3064 } 3065 3066 /*@ 3067 SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3068 3069 Logically Collective on SNES 3070 3071 Input Parameters: 3072 + snes - the SNES context 3073 - steps - the number of refinements to do, defaults to 0 3074 3075 Options Database Keys: 3076 . -snes_grid_sequence <steps> 3077 3078 Level: intermediate 3079 3080 Notes: 3081 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3082 3083 .keywords: SNES, nonlinear, set, convergence, tolerances 3084 3085 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 3086 3087 @*/ 3088 PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3089 { 3090 PetscFunctionBegin; 3091 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3092 PetscValidLogicalCollectiveInt(snes,steps,2); 3093 snes->gridsequence = steps; 3094 PetscFunctionReturn(0); 3095 } 3096 3097 /*@ 3098 SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3099 3100 Logically Collective on SNES 3101 3102 Input Parameter: 3103 . snes - the SNES context 3104 3105 Output Parameter: 3106 . steps - the number of refinements to do, defaults to 0 3107 3108 Options Database Keys: 3109 . -snes_grid_sequence <steps> 3110 3111 Level: intermediate 3112 3113 Notes: 3114 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3115 3116 .keywords: SNES, nonlinear, set, convergence, tolerances 3117 3118 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3119 3120 @*/ 3121 PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3122 { 3123 PetscFunctionBegin; 3124 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3125 *steps = snes->gridsequence; 3126 PetscFunctionReturn(0); 3127 } 3128 3129 /*@ 3130 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3131 3132 Not Collective 3133 3134 Input Parameter: 3135 . snes - the SNES context 3136 3137 Output Parameter: 3138 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3139 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3140 3141 Options Database Keys: 3142 . -snes_lag_preconditioner <lag> 3143 3144 Notes: 3145 The default is 1 3146 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3147 3148 Level: intermediate 3149 3150 .keywords: SNES, nonlinear, set, convergence, tolerances 3151 3152 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 3153 3154 @*/ 3155 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3156 { 3157 PetscFunctionBegin; 3158 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3159 *lag = snes->lagpreconditioner; 3160 PetscFunctionReturn(0); 3161 } 3162 3163 /*@ 3164 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3165 often the preconditioner is rebuilt. 3166 3167 Logically Collective on SNES 3168 3169 Input Parameters: 3170 + snes - the SNES context 3171 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3172 the Jacobian is built etc. -2 means rebuild at next chance but then never again 3173 3174 Options Database Keys: 3175 . -snes_lag_jacobian <lag> 3176 3177 Notes: 3178 The default is 1 3179 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3180 If -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed 3181 at the next Newton step but never again (unless it is reset to another value) 3182 3183 Level: intermediate 3184 3185 .keywords: SNES, nonlinear, set, convergence, tolerances 3186 3187 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 3188 3189 @*/ 3190 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3191 { 3192 PetscFunctionBegin; 3193 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3194 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3195 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3196 PetscValidLogicalCollectiveInt(snes,lag,2); 3197 snes->lagjacobian = lag; 3198 PetscFunctionReturn(0); 3199 } 3200 3201 /*@ 3202 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3203 3204 Not Collective 3205 3206 Input Parameter: 3207 . snes - the SNES context 3208 3209 Output Parameter: 3210 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3211 the Jacobian is built etc. 3212 3213 Options Database Keys: 3214 . -snes_lag_jacobian <lag> 3215 3216 Notes: 3217 The default is 1 3218 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3219 3220 Level: intermediate 3221 3222 .keywords: SNES, nonlinear, set, convergence, tolerances 3223 3224 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 3225 3226 @*/ 3227 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3228 { 3229 PetscFunctionBegin; 3230 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3231 *lag = snes->lagjacobian; 3232 PetscFunctionReturn(0); 3233 } 3234 3235 /*@ 3236 SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 3237 3238 Logically collective on SNES 3239 3240 Input Parameter: 3241 + snes - the SNES context 3242 - flg - jacobian lagging persists if true 3243 3244 Options Database Keys: 3245 . -snes_lag_jacobian_persists <flg> 3246 3247 Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 3248 several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 3249 timesteps may present huge efficiency gains. 3250 3251 Level: developer 3252 3253 .keywords: SNES, nonlinear, lag 3254 3255 .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 3256 3257 @*/ 3258 PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 3259 { 3260 PetscFunctionBegin; 3261 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3262 PetscValidLogicalCollectiveBool(snes,flg,2); 3263 snes->lagjac_persist = flg; 3264 PetscFunctionReturn(0); 3265 } 3266 3267 /*@ 3268 SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves 3269 3270 Logically Collective on SNES 3271 3272 Input Parameter: 3273 + snes - the SNES context 3274 - flg - preconditioner lagging persists if true 3275 3276 Options Database Keys: 3277 . -snes_lag_jacobian_persists <flg> 3278 3279 Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 3280 by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 3281 several timesteps may present huge efficiency gains. 3282 3283 Level: developer 3284 3285 .keywords: SNES, nonlinear, lag 3286 3287 .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 3288 3289 @*/ 3290 PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 3291 { 3292 PetscFunctionBegin; 3293 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3294 PetscValidLogicalCollectiveBool(snes,flg,2); 3295 snes->lagpre_persist = flg; 3296 PetscFunctionReturn(0); 3297 } 3298 3299 /*@ 3300 SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3301 3302 Logically Collective on SNES 3303 3304 Input Parameters: 3305 + snes - the SNES context 3306 - force - PETSC_TRUE require at least one iteration 3307 3308 Options Database Keys: 3309 . -snes_force_iteration <force> - Sets forcing an iteration 3310 3311 Notes: 3312 This is used sometimes with TS to prevent TS from detecting a false steady state solution 3313 3314 Level: intermediate 3315 3316 .keywords: SNES, nonlinear, set, convergence, tolerances 3317 3318 .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3319 @*/ 3320 PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3321 { 3322 PetscFunctionBegin; 3323 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3324 snes->forceiteration = force; 3325 PetscFunctionReturn(0); 3326 } 3327 3328 /*@ 3329 SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 3330 3331 Logically Collective on SNES 3332 3333 Input Parameters: 3334 . snes - the SNES context 3335 3336 Output Parameter: 3337 . force - PETSC_TRUE requires at least one iteration. 3338 3339 .keywords: SNES, nonlinear, set, convergence, tolerances 3340 3341 .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3342 @*/ 3343 PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 3344 { 3345 PetscFunctionBegin; 3346 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3347 *force = snes->forceiteration; 3348 PetscFunctionReturn(0); 3349 } 3350 3351 /*@ 3352 SNESSetTolerances - Sets various parameters used in convergence tests. 3353 3354 Logically Collective on SNES 3355 3356 Input Parameters: 3357 + snes - the SNES context 3358 . abstol - absolute convergence tolerance 3359 . rtol - relative convergence tolerance 3360 . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3361 . maxit - maximum number of iterations 3362 - maxf - maximum number of function evaluations 3363 3364 Options Database Keys: 3365 + -snes_atol <abstol> - Sets abstol 3366 . -snes_rtol <rtol> - Sets rtol 3367 . -snes_stol <stol> - Sets stol 3368 . -snes_max_it <maxit> - Sets maxit 3369 - -snes_max_funcs <maxf> - Sets maxf 3370 3371 Notes: 3372 The default maximum number of iterations is 50. 3373 The default maximum number of function evaluations is 1000. 3374 3375 Level: intermediate 3376 3377 .keywords: SNES, nonlinear, set, convergence, tolerances 3378 3379 .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration() 3380 @*/ 3381 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 3382 { 3383 PetscFunctionBegin; 3384 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3385 PetscValidLogicalCollectiveReal(snes,abstol,2); 3386 PetscValidLogicalCollectiveReal(snes,rtol,3); 3387 PetscValidLogicalCollectiveReal(snes,stol,4); 3388 PetscValidLogicalCollectiveInt(snes,maxit,5); 3389 PetscValidLogicalCollectiveInt(snes,maxf,6); 3390 3391 if (abstol != PETSC_DEFAULT) { 3392 if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3393 snes->abstol = abstol; 3394 } 3395 if (rtol != PETSC_DEFAULT) { 3396 if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol); 3397 snes->rtol = rtol; 3398 } 3399 if (stol != PETSC_DEFAULT) { 3400 if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3401 snes->stol = stol; 3402 } 3403 if (maxit != PETSC_DEFAULT) { 3404 if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3405 snes->max_its = maxit; 3406 } 3407 if (maxf != PETSC_DEFAULT) { 3408 if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 3409 snes->max_funcs = maxf; 3410 } 3411 snes->tolerancesset = PETSC_TRUE; 3412 PetscFunctionReturn(0); 3413 } 3414 3415 /*@ 3416 SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3417 3418 Logically Collective on SNES 3419 3420 Input Parameters: 3421 + snes - the SNES context 3422 - divtol - the divergence tolerance. Use -1 to deactivate the test. 3423 3424 Options Database Keys: 3425 + -snes_divergence_tolerance <divtol> - Sets divtol 3426 3427 Notes: 3428 The default divergence tolerance is 1e4. 3429 3430 Level: intermediate 3431 3432 .keywords: SNES, nonlinear, set, divergence, tolerance 3433 3434 .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3435 @*/ 3436 PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3437 { 3438 PetscFunctionBegin; 3439 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3440 PetscValidLogicalCollectiveReal(snes,divtol,2); 3441 3442 if (divtol != PETSC_DEFAULT) { 3443 snes->divtol = divtol; 3444 } 3445 else { 3446 snes->divtol = 1.0e4; 3447 } 3448 PetscFunctionReturn(0); 3449 } 3450 3451 /*@ 3452 SNESGetTolerances - Gets various parameters used in convergence tests. 3453 3454 Not Collective 3455 3456 Input Parameters: 3457 + snes - the SNES context 3458 . atol - absolute convergence tolerance 3459 . rtol - relative convergence tolerance 3460 . stol - convergence tolerance in terms of the norm 3461 of the change in the solution between steps 3462 . maxit - maximum number of iterations 3463 - maxf - maximum number of function evaluations 3464 3465 Notes: 3466 The user can specify NULL for any parameter that is not needed. 3467 3468 Level: intermediate 3469 3470 .keywords: SNES, nonlinear, get, convergence, tolerances 3471 3472 .seealso: SNESSetTolerances() 3473 @*/ 3474 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 3475 { 3476 PetscFunctionBegin; 3477 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3478 if (atol) *atol = snes->abstol; 3479 if (rtol) *rtol = snes->rtol; 3480 if (stol) *stol = snes->stol; 3481 if (maxit) *maxit = snes->max_its; 3482 if (maxf) *maxf = snes->max_funcs; 3483 PetscFunctionReturn(0); 3484 } 3485 3486 /*@ 3487 SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3488 3489 Not Collective 3490 3491 Input Parameters: 3492 + snes - the SNES context 3493 - divtol - divergence tolerance 3494 3495 Level: intermediate 3496 3497 .keywords: SNES, nonlinear, get, divergence, tolerance 3498 3499 .seealso: SNESSetDivergenceTolerance() 3500 @*/ 3501 PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3502 { 3503 PetscFunctionBegin; 3504 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3505 if (divtol) *divtol = snes->divtol; 3506 PetscFunctionReturn(0); 3507 } 3508 3509 /*@ 3510 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 3511 3512 Logically Collective on SNES 3513 3514 Input Parameters: 3515 + snes - the SNES context 3516 - tol - tolerance 3517 3518 Options Database Key: 3519 . -snes_trtol <tol> - Sets tol 3520 3521 Level: intermediate 3522 3523 .keywords: SNES, nonlinear, set, trust region, tolerance 3524 3525 .seealso: SNESSetTolerances() 3526 @*/ 3527 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 3528 { 3529 PetscFunctionBegin; 3530 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3531 PetscValidLogicalCollectiveReal(snes,tol,2); 3532 snes->deltatol = tol; 3533 PetscFunctionReturn(0); 3534 } 3535 3536 /* 3537 Duplicate the lg monitors for SNES from KSP; for some reason with 3538 dynamic libraries things don't work under Sun4 if we just use 3539 macros instead of functions 3540 */ 3541 PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 3542 { 3543 PetscErrorCode ierr; 3544 3545 PetscFunctionBegin; 3546 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3547 ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 3548 PetscFunctionReturn(0); 3549 } 3550 3551 PetscErrorCode SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) 3552 { 3553 PetscErrorCode ierr; 3554 3555 PetscFunctionBegin; 3556 ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr); 3557 PetscFunctionReturn(0); 3558 } 3559 3560 PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 3561 3562 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3563 { 3564 PetscDrawLG lg; 3565 PetscErrorCode ierr; 3566 PetscReal x,y,per; 3567 PetscViewer v = (PetscViewer)monctx; 3568 static PetscReal prev; /* should be in the context */ 3569 PetscDraw draw; 3570 3571 PetscFunctionBegin; 3572 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3573 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3574 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3575 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3576 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3577 x = (PetscReal)n; 3578 if (rnorm > 0.0) y = PetscLog10Real(rnorm); 3579 else y = -15.0; 3580 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3581 if (n < 20 || !(n % 5) || snes->reason) { 3582 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3583 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3584 } 3585 3586 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3587 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3588 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3589 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3590 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3591 x = (PetscReal)n; 3592 y = 100.0*per; 3593 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3594 if (n < 20 || !(n % 5) || snes->reason) { 3595 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3596 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3597 } 3598 3599 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3600 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3601 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3602 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3603 x = (PetscReal)n; 3604 y = (prev - rnorm)/prev; 3605 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3606 if (n < 20 || !(n % 5) || snes->reason) { 3607 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3608 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3609 } 3610 3611 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3612 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3613 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3614 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3615 x = (PetscReal)n; 3616 y = (prev - rnorm)/(prev*per); 3617 if (n > 2) { /*skip initial crazy value */ 3618 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3619 } 3620 if (n < 20 || !(n % 5) || snes->reason) { 3621 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3622 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3623 } 3624 prev = rnorm; 3625 PetscFunctionReturn(0); 3626 } 3627 3628 /*@ 3629 SNESMonitor - runs the user provided monitor routines, if they exist 3630 3631 Collective on SNES 3632 3633 Input Parameters: 3634 + snes - nonlinear solver context obtained from SNESCreate() 3635 . iter - iteration number 3636 - rnorm - relative norm of the residual 3637 3638 Notes: 3639 This routine is called by the SNES implementations. 3640 It does not typically need to be called by the user. 3641 3642 Level: developer 3643 3644 .seealso: SNESMonitorSet() 3645 @*/ 3646 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 3647 { 3648 PetscErrorCode ierr; 3649 PetscInt i,n = snes->numbermonitors; 3650 3651 PetscFunctionBegin; 3652 ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr); 3653 for (i=0; i<n; i++) { 3654 ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 3655 } 3656 ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr); 3657 PetscFunctionReturn(0); 3658 } 3659 3660 /* ------------ Routines to set performance monitoring options ----------- */ 3661 3662 /*MC 3663 SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3664 3665 Synopsis: 3666 #include <petscsnes.h> 3667 $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3668 3669 + snes - the SNES context 3670 . its - iteration number 3671 . norm - 2-norm function value (may be estimated) 3672 - mctx - [optional] monitoring context 3673 3674 Level: advanced 3675 3676 .seealso: SNESMonitorSet(), SNESMonitorGet() 3677 M*/ 3678 3679 /*@C 3680 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 3681 iteration of the nonlinear solver to display the iteration's 3682 progress. 3683 3684 Logically Collective on SNES 3685 3686 Input Parameters: 3687 + snes - the SNES context 3688 . f - the monitor function, see SNESMonitorFunction for the calling sequence 3689 . mctx - [optional] user-defined context for private data for the 3690 monitor routine (use NULL if no context is desired) 3691 - monitordestroy - [optional] routine that frees monitor context 3692 (may be NULL) 3693 3694 Options Database Keys: 3695 + -snes_monitor - sets SNESMonitorDefault() 3696 . -snes_monitor_lg_residualnorm - sets line graph monitor, 3697 uses SNESMonitorLGCreate() 3698 - -snes_monitor_cancel - cancels all monitors that have 3699 been hardwired into a code by 3700 calls to SNESMonitorSet(), but 3701 does not cancel those set via 3702 the options database. 3703 3704 Notes: 3705 Several different monitoring routines may be set by calling 3706 SNESMonitorSet() multiple times; all will be called in the 3707 order in which they were set. 3708 3709 Fortran notes: Only a single monitor function can be set for each SNES object 3710 3711 Level: intermediate 3712 3713 .keywords: SNES, nonlinear, set, monitor 3714 3715 .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 3716 @*/ 3717 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 3718 { 3719 PetscInt i; 3720 PetscErrorCode ierr; 3721 PetscBool identical; 3722 3723 PetscFunctionBegin; 3724 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3725 for (i=0; i<snes->numbermonitors;i++) { 3726 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr); 3727 if (identical) PetscFunctionReturn(0); 3728 } 3729 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3730 snes->monitor[snes->numbermonitors] = f; 3731 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3732 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 3733 PetscFunctionReturn(0); 3734 } 3735 3736 /*@ 3737 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 3738 3739 Logically Collective on SNES 3740 3741 Input Parameters: 3742 . snes - the SNES context 3743 3744 Options Database Key: 3745 . -snes_monitor_cancel - cancels all monitors that have been hardwired 3746 into a code by calls to SNESMonitorSet(), but does not cancel those 3747 set via the options database 3748 3749 Notes: 3750 There is no way to clear one specific monitor from a SNES object. 3751 3752 Level: intermediate 3753 3754 .keywords: SNES, nonlinear, set, monitor 3755 3756 .seealso: SNESMonitorDefault(), SNESMonitorSet() 3757 @*/ 3758 PetscErrorCode SNESMonitorCancel(SNES snes) 3759 { 3760 PetscErrorCode ierr; 3761 PetscInt i; 3762 3763 PetscFunctionBegin; 3764 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3765 for (i=0; i<snes->numbermonitors; i++) { 3766 if (snes->monitordestroy[i]) { 3767 ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3768 } 3769 } 3770 snes->numbermonitors = 0; 3771 PetscFunctionReturn(0); 3772 } 3773 3774 /*MC 3775 SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3776 3777 Synopsis: 3778 #include <petscsnes.h> 3779 $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3780 3781 + snes - the SNES context 3782 . it - current iteration (0 is the first and is before any Newton step) 3783 . cctx - [optional] convergence context 3784 . reason - reason for convergence/divergence 3785 . xnorm - 2-norm of current iterate 3786 . gnorm - 2-norm of current step 3787 - f - 2-norm of function 3788 3789 Level: intermediate 3790 3791 .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 3792 M*/ 3793 3794 /*@C 3795 SNESSetConvergenceTest - Sets the function that is to be used 3796 to test for convergence of the nonlinear iterative solution. 3797 3798 Logically Collective on SNES 3799 3800 Input Parameters: 3801 + snes - the SNES context 3802 . SNESConvergenceTestFunction - routine to test for convergence 3803 . cctx - [optional] context for private data for the convergence routine (may be NULL) 3804 - destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran) 3805 3806 Level: advanced 3807 3808 .keywords: SNES, nonlinear, set, convergence, test 3809 3810 .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 3811 @*/ 3812 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 3813 { 3814 PetscErrorCode ierr; 3815 3816 PetscFunctionBegin; 3817 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3818 if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 3819 if (snes->ops->convergeddestroy) { 3820 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 3821 } 3822 snes->ops->converged = SNESConvergenceTestFunction; 3823 snes->ops->convergeddestroy = destroy; 3824 snes->cnvP = cctx; 3825 PetscFunctionReturn(0); 3826 } 3827 3828 /*@ 3829 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3830 3831 Not Collective 3832 3833 Input Parameter: 3834 . snes - the SNES context 3835 3836 Output Parameter: 3837 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3838 manual pages for the individual convergence tests for complete lists 3839 3840 Options Database: 3841 . -snes_converged_reason - prints the reason to standard out 3842 3843 Level: intermediate 3844 3845 Notes: Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 3846 3847 .keywords: SNES, nonlinear, set, convergence, test 3848 3849 .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 3850 @*/ 3851 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3852 { 3853 PetscFunctionBegin; 3854 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3855 PetscValidPointer(reason,2); 3856 *reason = snes->reason; 3857 PetscFunctionReturn(0); 3858 } 3859 3860 /*@ 3861 SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 3862 3863 Not Collective 3864 3865 Input Parameters: 3866 + snes - the SNES context 3867 - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3868 manual pages for the individual convergence tests for complete lists 3869 3870 Level: intermediate 3871 3872 .keywords: SNES, nonlinear, set, convergence, test 3873 .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 3874 @*/ 3875 PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 3876 { 3877 PetscFunctionBegin; 3878 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3879 snes->reason = reason; 3880 PetscFunctionReturn(0); 3881 } 3882 3883 /*@ 3884 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3885 3886 Logically Collective on SNES 3887 3888 Input Parameters: 3889 + snes - iterative context obtained from SNESCreate() 3890 . a - array to hold history, this array will contain the function norms computed at each step 3891 . its - integer array holds the number of linear iterations for each solve. 3892 . na - size of a and its 3893 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3894 else it continues storing new values for new nonlinear solves after the old ones 3895 3896 Notes: 3897 If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3898 default array of length 10000 is allocated. 3899 3900 This routine is useful, e.g., when running a code for purposes 3901 of accurate performance monitoring, when no I/O should be done 3902 during the section of code that is being timed. 3903 3904 Level: intermediate 3905 3906 .keywords: SNES, set, convergence, history 3907 3908 .seealso: SNESGetConvergenceHistory() 3909 3910 @*/ 3911 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3912 { 3913 PetscErrorCode ierr; 3914 3915 PetscFunctionBegin; 3916 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3917 if (a) PetscValidScalarPointer(a,2); 3918 if (its) PetscValidIntPointer(its,3); 3919 if (!a) { 3920 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3921 ierr = PetscCalloc1(na,&a);CHKERRQ(ierr); 3922 ierr = PetscCalloc1(na,&its);CHKERRQ(ierr); 3923 3924 snes->conv_malloc = PETSC_TRUE; 3925 } 3926 snes->conv_hist = a; 3927 snes->conv_hist_its = its; 3928 snes->conv_hist_max = na; 3929 snes->conv_hist_len = 0; 3930 snes->conv_hist_reset = reset; 3931 PetscFunctionReturn(0); 3932 } 3933 3934 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3935 #include <engine.h> /* MATLAB include file */ 3936 #include <mex.h> /* MATLAB include file */ 3937 3938 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3939 { 3940 mxArray *mat; 3941 PetscInt i; 3942 PetscReal *ar; 3943 3944 PetscFunctionBegin; 3945 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3946 ar = (PetscReal*) mxGetData(mat); 3947 for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 3948 PetscFunctionReturn(mat); 3949 } 3950 #endif 3951 3952 /*@C 3953 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3954 3955 Not Collective 3956 3957 Input Parameter: 3958 . snes - iterative context obtained from SNESCreate() 3959 3960 Output Parameters: 3961 . a - array to hold history 3962 . its - integer array holds the number of linear iterations (or 3963 negative if not converged) for each solve. 3964 - na - size of a and its 3965 3966 Notes: 3967 The calling sequence for this routine in Fortran is 3968 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3969 3970 This routine is useful, e.g., when running a code for purposes 3971 of accurate performance monitoring, when no I/O should be done 3972 during the section of code that is being timed. 3973 3974 Level: intermediate 3975 3976 .keywords: SNES, get, convergence, history 3977 3978 .seealso: SNESSetConvergencHistory() 3979 3980 @*/ 3981 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3982 { 3983 PetscFunctionBegin; 3984 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3985 if (a) *a = snes->conv_hist; 3986 if (its) *its = snes->conv_hist_its; 3987 if (na) *na = snes->conv_hist_len; 3988 PetscFunctionReturn(0); 3989 } 3990 3991 /*@C 3992 SNESSetUpdate - Sets the general-purpose update function called 3993 at the beginning of every iteration of the nonlinear solve. Specifically 3994 it is called just before the Jacobian is "evaluated". 3995 3996 Logically Collective on SNES 3997 3998 Input Parameters: 3999 . snes - The nonlinear solver context 4000 . func - The function 4001 4002 Calling sequence of func: 4003 . func (SNES snes, PetscInt step); 4004 4005 . step - The current step of the iteration 4006 4007 Level: advanced 4008 4009 Note: This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction() 4010 This is not used by most users. 4011 4012 .keywords: SNES, update 4013 4014 .seealso SNESSetJacobian(), SNESSolve() 4015 @*/ 4016 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4017 { 4018 PetscFunctionBegin; 4019 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4020 snes->ops->update = func; 4021 PetscFunctionReturn(0); 4022 } 4023 4024 /* 4025 SNESScaleStep_Private - Scales a step so that its length is less than the 4026 positive parameter delta. 4027 4028 Input Parameters: 4029 + snes - the SNES context 4030 . y - approximate solution of linear system 4031 . fnorm - 2-norm of current function 4032 - delta - trust region size 4033 4034 Output Parameters: 4035 + gpnorm - predicted function norm at the new point, assuming local 4036 linearization. The value is zero if the step lies within the trust 4037 region, and exceeds zero otherwise. 4038 - ynorm - 2-norm of the step 4039 4040 Note: 4041 For non-trust region methods such as SNESNEWTONLS, the parameter delta 4042 is set to be the maximum allowable step size. 4043 4044 .keywords: SNES, nonlinear, scale, step 4045 */ 4046 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 4047 { 4048 PetscReal nrm; 4049 PetscScalar cnorm; 4050 PetscErrorCode ierr; 4051 4052 PetscFunctionBegin; 4053 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4054 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4055 PetscCheckSameComm(snes,1,y,2); 4056 4057 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 4058 if (nrm > *delta) { 4059 nrm = *delta/nrm; 4060 *gpnorm = (1.0 - nrm)*(*fnorm); 4061 cnorm = nrm; 4062 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 4063 *ynorm = *delta; 4064 } else { 4065 *gpnorm = 0.0; 4066 *ynorm = nrm; 4067 } 4068 PetscFunctionReturn(0); 4069 } 4070 4071 /*@ 4072 SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer 4073 4074 Collective on SNES 4075 4076 Parameter: 4077 + snes - iterative context obtained from SNESCreate() 4078 - viewer - the viewer to display the reason 4079 4080 4081 Options Database Keys: 4082 . -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4083 4084 Level: beginner 4085 4086 .keywords: SNES, solve, linear system 4087 4088 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault() 4089 4090 @*/ 4091 PetscErrorCode SNESReasonView(SNES snes,PetscViewer viewer) 4092 { 4093 PetscViewerFormat format; 4094 PetscBool isAscii; 4095 PetscErrorCode ierr; 4096 4097 PetscFunctionBegin; 4098 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 4099 if (isAscii) { 4100 ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 4101 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4102 if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 4103 DM dm; 4104 Vec u; 4105 PetscDS prob; 4106 PetscInt Nf, f; 4107 PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 4108 PetscReal error; 4109 4110 ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 4111 ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); 4112 ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 4113 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 4114 ierr = PetscMalloc1(Nf, &exactFuncs);CHKERRQ(ierr); 4115 for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactFuncs[f]);CHKERRQ(ierr);} 4116 ierr = DMComputeL2Diff(dm, 0.0, exactFuncs, NULL, u, &error);CHKERRQ(ierr); 4117 ierr = PetscFree(exactFuncs);CHKERRQ(ierr); 4118 if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} 4119 else {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);} 4120 } 4121 if (snes->reason > 0) { 4122 if (((PetscObject) snes)->prefix) { 4123 ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 4124 } else { 4125 ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 4126 } 4127 } else { 4128 if (((PetscObject) snes)->prefix) { 4129 ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 4130 } else { 4131 ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 4132 } 4133 } 4134 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4135 } 4136 PetscFunctionReturn(0); 4137 } 4138 4139 /*@C 4140 SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4141 4142 Collective on SNES 4143 4144 Input Parameters: 4145 . snes - the SNES object 4146 4147 Level: intermediate 4148 4149 @*/ 4150 PetscErrorCode SNESReasonViewFromOptions(SNES snes) 4151 { 4152 PetscErrorCode ierr; 4153 PetscViewer viewer; 4154 PetscBool flg; 4155 static PetscBool incall = PETSC_FALSE; 4156 PetscViewerFormat format; 4157 4158 PetscFunctionBegin; 4159 if (incall) PetscFunctionReturn(0); 4160 incall = PETSC_TRUE; 4161 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 4162 if (flg) { 4163 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 4164 ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr); 4165 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4166 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4167 } 4168 incall = PETSC_FALSE; 4169 PetscFunctionReturn(0); 4170 } 4171 4172 /*@C 4173 SNESSolve - Solves a nonlinear system F(x) = b. 4174 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 4175 4176 Collective on SNES 4177 4178 Input Parameters: 4179 + snes - the SNES context 4180 . b - the constant part of the equation F(x) = b, or NULL to use zero. 4181 - x - the solution vector. 4182 4183 Notes: 4184 The user should initialize the vector,x, with the initial guess 4185 for the nonlinear solve prior to calling SNESSolve. In particular, 4186 to employ an initial guess of zero, the user should explicitly set 4187 this vector to zero by calling VecSet(). 4188 4189 Level: beginner 4190 4191 .keywords: SNES, nonlinear, solve 4192 4193 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 4194 @*/ 4195 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 4196 { 4197 PetscErrorCode ierr; 4198 PetscBool flg; 4199 PetscInt grid; 4200 Vec xcreated = NULL; 4201 DM dm; 4202 4203 PetscFunctionBegin; 4204 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4205 if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4206 if (x) PetscCheckSameComm(snes,1,x,3); 4207 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4208 if (b) PetscCheckSameComm(snes,1,b,2); 4209 4210 /* High level operations using the nonlinear solver */ 4211 { 4212 PetscViewer viewer; 4213 PetscViewerFormat format; 4214 PetscInt num; 4215 PetscBool flg; 4216 static PetscBool incall = PETSC_FALSE; 4217 4218 if (!incall) { 4219 /* Estimate the convergence rate of the discretization */ 4220 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes), ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 4221 if (flg) { 4222 PetscConvEst conv; 4223 PetscReal alpha; /* Convergence rate of the solution error in the L_2 norm */ 4224 4225 incall = PETSC_TRUE; 4226 ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 4227 ierr = PetscConvEstSetSolver(conv, snes);CHKERRQ(ierr); 4228 ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 4229 ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 4230 ierr = PetscConvEstGetConvRate(conv, &alpha);CHKERRQ(ierr); 4231 ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 4232 ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 4233 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4234 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4235 ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 4236 incall = PETSC_FALSE; 4237 } 4238 /* Adaptively refine the initial grid */ 4239 num = 1; 4240 ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr); 4241 if (flg) { 4242 DMAdaptor adaptor; 4243 4244 incall = PETSC_TRUE; 4245 ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 4246 ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4247 ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 4248 ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 4249 ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 4250 ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr); 4251 ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 4252 incall = PETSC_FALSE; 4253 } 4254 /* Use grid sequencing to adapt */ 4255 num = 0; 4256 ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr); 4257 if (num) { 4258 DMAdaptor adaptor; 4259 4260 incall = PETSC_TRUE; 4261 ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 4262 ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4263 ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 4264 ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 4265 ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 4266 ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr); 4267 ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 4268 incall = PETSC_FALSE; 4269 } 4270 } 4271 } 4272 if (!x) { 4273 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4274 ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4275 x = xcreated; 4276 } 4277 ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4278 4279 for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4280 for (grid=0; grid<snes->gridsequence+1; grid++) { 4281 4282 /* set solution vector */ 4283 if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 4284 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 4285 snes->vec_sol = x; 4286 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4287 4288 /* set affine vector if provided */ 4289 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 4290 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 4291 snes->vec_rhs = b; 4292 4293 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4294 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 4295 if (!snes->vec_sol_update /* && snes->vec_sol */) { 4296 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4297 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4298 } 4299 ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 4300 ierr = SNESSetUp(snes);CHKERRQ(ierr); 4301 4302 if (!grid) { 4303 if (snes->ops->computeinitialguess) { 4304 ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4305 } 4306 } 4307 4308 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4309 if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4310 4311 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 4312 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 4313 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 4314 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4315 snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 4316 4317 if (snes->lagjac_persist) snes->jac_iter += snes->iter; 4318 if (snes->lagpre_persist) snes->pre_iter += snes->iter; 4319 4320 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4321 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 4322 ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr); 4323 4324 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 4325 if (snes->reason < 0) break; 4326 if (grid < snes->gridsequence) { 4327 DM fine; 4328 Vec xnew; 4329 Mat interp; 4330 4331 ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4332 if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 4333 ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4334 ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4335 ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4336 ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4337 ierr = MatDestroy(&interp);CHKERRQ(ierr); 4338 x = xnew; 4339 4340 ierr = SNESReset(snes);CHKERRQ(ierr); 4341 ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4342 ierr = DMDestroy(&fine);CHKERRQ(ierr); 4343 ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4344 } 4345 } 4346 ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4347 ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 4348 4349 ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4350 ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 4351 PetscFunctionReturn(0); 4352 } 4353 4354 /* --------- Internal routines for SNES Package --------- */ 4355 4356 /*@C 4357 SNESSetType - Sets the method for the nonlinear solver. 4358 4359 Collective on SNES 4360 4361 Input Parameters: 4362 + snes - the SNES context 4363 - type - a known method 4364 4365 Options Database Key: 4366 . -snes_type <type> - Sets the method; use -help for a list 4367 of available methods (for instance, newtonls or newtontr) 4368 4369 Notes: 4370 See "petsc/include/petscsnes.h" for available methods (for instance) 4371 + SNESNEWTONLS - Newton's method with line search 4372 (systems of nonlinear equations) 4373 . SNESNEWTONTR - Newton's method with trust region 4374 (systems of nonlinear equations) 4375 4376 Normally, it is best to use the SNESSetFromOptions() command and then 4377 set the SNES solver type from the options database rather than by using 4378 this routine. Using the options database provides the user with 4379 maximum flexibility in evaluating the many nonlinear solvers. 4380 The SNESSetType() routine is provided for those situations where it 4381 is necessary to set the nonlinear solver independently of the command 4382 line or options database. This might be the case, for example, when 4383 the choice of solver changes during the execution of the program, 4384 and the user's application is taking responsibility for choosing the 4385 appropriate method. 4386 4387 Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 4388 the constructor in that list and calls it to create the spexific object. 4389 4390 Level: intermediate 4391 4392 .keywords: SNES, set, type 4393 4394 .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4395 4396 @*/ 4397 PetscErrorCode SNESSetType(SNES snes,SNESType type) 4398 { 4399 PetscErrorCode ierr,(*r)(SNES); 4400 PetscBool match; 4401 4402 PetscFunctionBegin; 4403 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4404 PetscValidCharPointer(type,2); 4405 4406 ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 4407 if (match) PetscFunctionReturn(0); 4408 4409 ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4410 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 4411 /* Destroy the previous private SNES context */ 4412 if (snes->ops->destroy) { 4413 ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 4414 snes->ops->destroy = NULL; 4415 } 4416 /* Reinitialize function pointers in SNESOps structure */ 4417 snes->ops->setup = 0; 4418 snes->ops->solve = 0; 4419 snes->ops->view = 0; 4420 snes->ops->setfromoptions = 0; 4421 snes->ops->destroy = 0; 4422 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 4423 snes->setupcalled = PETSC_FALSE; 4424 4425 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 4426 ierr = (*r)(snes);CHKERRQ(ierr); 4427 PetscFunctionReturn(0); 4428 } 4429 4430 /*@C 4431 SNESGetType - Gets the SNES method type and name (as a string). 4432 4433 Not Collective 4434 4435 Input Parameter: 4436 . snes - nonlinear solver context 4437 4438 Output Parameter: 4439 . type - SNES method (a character string) 4440 4441 Level: intermediate 4442 4443 .keywords: SNES, nonlinear, get, type, name 4444 @*/ 4445 PetscErrorCode SNESGetType(SNES snes,SNESType *type) 4446 { 4447 PetscFunctionBegin; 4448 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4449 PetscValidPointer(type,2); 4450 *type = ((PetscObject)snes)->type_name; 4451 PetscFunctionReturn(0); 4452 } 4453 4454 /*@ 4455 SNESSetSolution - Sets the solution vector for use by the SNES routines. 4456 4457 Logically Collective on SNES and Vec 4458 4459 Input Parameters: 4460 + snes - the SNES context obtained from SNESCreate() 4461 - u - the solution vector 4462 4463 Level: beginner 4464 4465 .keywords: SNES, set, solution 4466 @*/ 4467 PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4468 { 4469 DM dm; 4470 PetscErrorCode ierr; 4471 4472 PetscFunctionBegin; 4473 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4474 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 4475 ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 4476 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 4477 4478 snes->vec_sol = u; 4479 4480 ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 4481 ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 4482 PetscFunctionReturn(0); 4483 } 4484 4485 /*@ 4486 SNESGetSolution - Returns the vector where the approximate solution is 4487 stored. This is the fine grid solution when using SNESSetGridSequence(). 4488 4489 Not Collective, but Vec is parallel if SNES is parallel 4490 4491 Input Parameter: 4492 . snes - the SNES context 4493 4494 Output Parameter: 4495 . x - the solution 4496 4497 Level: intermediate 4498 4499 .keywords: SNES, nonlinear, get, solution 4500 4501 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 4502 @*/ 4503 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 4504 { 4505 PetscFunctionBegin; 4506 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4507 PetscValidPointer(x,2); 4508 *x = snes->vec_sol; 4509 PetscFunctionReturn(0); 4510 } 4511 4512 /*@ 4513 SNESGetSolutionUpdate - Returns the vector where the solution update is 4514 stored. 4515 4516 Not Collective, but Vec is parallel if SNES is parallel 4517 4518 Input Parameter: 4519 . snes - the SNES context 4520 4521 Output Parameter: 4522 . x - the solution update 4523 4524 Level: advanced 4525 4526 .keywords: SNES, nonlinear, get, solution, update 4527 4528 .seealso: SNESGetSolution(), SNESGetFunction() 4529 @*/ 4530 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 4531 { 4532 PetscFunctionBegin; 4533 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4534 PetscValidPointer(x,2); 4535 *x = snes->vec_sol_update; 4536 PetscFunctionReturn(0); 4537 } 4538 4539 /*@C 4540 SNESGetFunction - Returns the vector where the function is stored. 4541 4542 Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4543 4544 Input Parameter: 4545 . snes - the SNES context 4546 4547 Output Parameter: 4548 + r - the vector that is used to store residuals (or NULL if you don't want it) 4549 . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 4550 - ctx - the function context (or NULL if you don't want it) 4551 4552 Level: advanced 4553 4554 .keywords: SNES, nonlinear, get, function 4555 4556 .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 4557 @*/ 4558 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 4559 { 4560 PetscErrorCode ierr; 4561 DM dm; 4562 4563 PetscFunctionBegin; 4564 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4565 if (r) { 4566 if (!snes->vec_func) { 4567 if (snes->vec_rhs) { 4568 ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4569 } else if (snes->vec_sol) { 4570 ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4571 } else if (snes->dm) { 4572 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4573 } 4574 } 4575 *r = snes->vec_func; 4576 } 4577 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4578 ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 4579 PetscFunctionReturn(0); 4580 } 4581 4582 /*@C 4583 SNESGetNGS - Returns the NGS function and context. 4584 4585 Input Parameter: 4586 . snes - the SNES context 4587 4588 Output Parameter: 4589 + f - the function (or NULL) see SNESNGSFunction for details 4590 - ctx - the function context (or NULL) 4591 4592 Level: advanced 4593 4594 .keywords: SNES, nonlinear, get, function 4595 4596 .seealso: SNESSetNGS(), SNESGetFunction() 4597 @*/ 4598 4599 PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4600 { 4601 PetscErrorCode ierr; 4602 DM dm; 4603 4604 PetscFunctionBegin; 4605 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4606 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4607 ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4608 PetscFunctionReturn(0); 4609 } 4610 4611 /*@C 4612 SNESSetOptionsPrefix - Sets the prefix used for searching for all 4613 SNES options in the database. 4614 4615 Logically Collective on SNES 4616 4617 Input Parameter: 4618 + snes - the SNES context 4619 - prefix - the prefix to prepend to all option names 4620 4621 Notes: 4622 A hyphen (-) must NOT be given at the beginning of the prefix name. 4623 The first character of all runtime options is AUTOMATICALLY the hyphen. 4624 4625 Level: advanced 4626 4627 .keywords: SNES, set, options, prefix, database 4628 4629 .seealso: SNESSetFromOptions() 4630 @*/ 4631 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 4632 { 4633 PetscErrorCode ierr; 4634 4635 PetscFunctionBegin; 4636 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4637 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4638 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 4639 if (snes->linesearch) { 4640 ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 4641 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 4642 } 4643 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 4644 PetscFunctionReturn(0); 4645 } 4646 4647 /*@C 4648 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4649 SNES options in the database. 4650 4651 Logically Collective on SNES 4652 4653 Input Parameters: 4654 + snes - the SNES context 4655 - prefix - the prefix to prepend to all option names 4656 4657 Notes: 4658 A hyphen (-) must NOT be given at the beginning of the prefix name. 4659 The first character of all runtime options is AUTOMATICALLY the hyphen. 4660 4661 Level: advanced 4662 4663 .keywords: SNES, append, options, prefix, database 4664 4665 .seealso: SNESGetOptionsPrefix() 4666 @*/ 4667 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 4668 { 4669 PetscErrorCode ierr; 4670 4671 PetscFunctionBegin; 4672 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4673 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4674 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 4675 if (snes->linesearch) { 4676 ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 4677 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 4678 } 4679 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 4680 PetscFunctionReturn(0); 4681 } 4682 4683 /*@C 4684 SNESGetOptionsPrefix - Sets the prefix used for searching for all 4685 SNES options in the database. 4686 4687 Not Collective 4688 4689 Input Parameter: 4690 . snes - the SNES context 4691 4692 Output Parameter: 4693 . prefix - pointer to the prefix string used 4694 4695 Notes: On the fortran side, the user should pass in a string 'prefix' of 4696 sufficient length to hold the prefix. 4697 4698 Level: advanced 4699 4700 .keywords: SNES, get, options, prefix, database 4701 4702 .seealso: SNESAppendOptionsPrefix() 4703 @*/ 4704 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 4705 { 4706 PetscErrorCode ierr; 4707 4708 PetscFunctionBegin; 4709 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4710 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4711 PetscFunctionReturn(0); 4712 } 4713 4714 4715 /*@C 4716 SNESRegister - Adds a method to the nonlinear solver package. 4717 4718 Not collective 4719 4720 Input Parameters: 4721 + name_solver - name of a new user-defined solver 4722 - routine_create - routine to create method context 4723 4724 Notes: 4725 SNESRegister() may be called multiple times to add several user-defined solvers. 4726 4727 Sample usage: 4728 .vb 4729 SNESRegister("my_solver",MySolverCreate); 4730 .ve 4731 4732 Then, your solver can be chosen with the procedural interface via 4733 $ SNESSetType(snes,"my_solver") 4734 or at runtime via the option 4735 $ -snes_type my_solver 4736 4737 Level: advanced 4738 4739 Note: If your function is not being put into a shared library then use SNESRegister() instead 4740 4741 .keywords: SNES, nonlinear, register 4742 4743 .seealso: SNESRegisterAll(), SNESRegisterDestroy() 4744 4745 Level: advanced 4746 @*/ 4747 PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4748 { 4749 PetscErrorCode ierr; 4750 4751 PetscFunctionBegin; 4752 ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 4753 PetscFunctionReturn(0); 4754 } 4755 4756 PetscErrorCode SNESTestLocalMin(SNES snes) 4757 { 4758 PetscErrorCode ierr; 4759 PetscInt N,i,j; 4760 Vec u,uh,fh; 4761 PetscScalar value; 4762 PetscReal norm; 4763 4764 PetscFunctionBegin; 4765 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4766 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4767 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4768 4769 /* currently only works for sequential */ 4770 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr); 4771 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4772 for (i=0; i<N; i++) { 4773 ierr = VecCopy(u,uh);CHKERRQ(ierr); 4774 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4775 for (j=-10; j<11; j++) { 4776 value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 4777 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4778 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4779 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 4780 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4781 value = -value; 4782 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4783 } 4784 } 4785 ierr = VecDestroy(&uh);CHKERRQ(ierr); 4786 ierr = VecDestroy(&fh);CHKERRQ(ierr); 4787 PetscFunctionReturn(0); 4788 } 4789 4790 /*@ 4791 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 4792 computing relative tolerance for linear solvers within an inexact 4793 Newton method. 4794 4795 Logically Collective on SNES 4796 4797 Input Parameters: 4798 + snes - SNES context 4799 - flag - PETSC_TRUE or PETSC_FALSE 4800 4801 Options Database: 4802 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4803 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 4804 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 4805 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 4806 . -snes_ksp_ew_gamma <gamma> - Sets gamma 4807 . -snes_ksp_ew_alpha <alpha> - Sets alpha 4808 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 4809 - -snes_ksp_ew_threshold <threshold> - Sets threshold 4810 4811 Notes: 4812 Currently, the default is to use a constant relative tolerance for 4813 the inner linear solvers. Alternatively, one can use the 4814 Eisenstat-Walker method, where the relative convergence tolerance 4815 is reset at each Newton iteration according progress of the nonlinear 4816 solver. 4817 4818 Level: advanced 4819 4820 Reference: 4821 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4822 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 4823 4824 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 4825 4826 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 4827 @*/ 4828 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 4829 { 4830 PetscFunctionBegin; 4831 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4832 PetscValidLogicalCollectiveBool(snes,flag,2); 4833 snes->ksp_ewconv = flag; 4834 PetscFunctionReturn(0); 4835 } 4836 4837 /*@ 4838 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 4839 for computing relative tolerance for linear solvers within an 4840 inexact Newton method. 4841 4842 Not Collective 4843 4844 Input Parameter: 4845 . snes - SNES context 4846 4847 Output Parameter: 4848 . flag - PETSC_TRUE or PETSC_FALSE 4849 4850 Notes: 4851 Currently, the default is to use a constant relative tolerance for 4852 the inner linear solvers. Alternatively, one can use the 4853 Eisenstat-Walker method, where the relative convergence tolerance 4854 is reset at each Newton iteration according progress of the nonlinear 4855 solver. 4856 4857 Level: advanced 4858 4859 Reference: 4860 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4861 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 4862 4863 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 4864 4865 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 4866 @*/ 4867 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 4868 { 4869 PetscFunctionBegin; 4870 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4871 PetscValidPointer(flag,2); 4872 *flag = snes->ksp_ewconv; 4873 PetscFunctionReturn(0); 4874 } 4875 4876 /*@ 4877 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 4878 convergence criteria for the linear solvers within an inexact 4879 Newton method. 4880 4881 Logically Collective on SNES 4882 4883 Input Parameters: 4884 + snes - SNES context 4885 . version - version 1, 2 (default is 2) or 3 4886 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 4887 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4888 . gamma - multiplicative factor for version 2 rtol computation 4889 (0 <= gamma2 <= 1) 4890 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 4891 . alpha2 - power for safeguard 4892 - threshold - threshold for imposing safeguard (0 < threshold < 1) 4893 4894 Note: 4895 Version 3 was contributed by Luis Chacon, June 2006. 4896 4897 Use PETSC_DEFAULT to retain the default for any of the parameters. 4898 4899 Level: advanced 4900 4901 Reference: 4902 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4903 inexact Newton method", Utah State University Math. Stat. Dept. Res. 4904 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 4905 4906 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 4907 4908 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 4909 @*/ 4910 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 4911 { 4912 SNESKSPEW *kctx; 4913 4914 PetscFunctionBegin; 4915 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4916 kctx = (SNESKSPEW*)snes->kspconvctx; 4917 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4918 PetscValidLogicalCollectiveInt(snes,version,2); 4919 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4920 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4921 PetscValidLogicalCollectiveReal(snes,gamma,5); 4922 PetscValidLogicalCollectiveReal(snes,alpha,6); 4923 PetscValidLogicalCollectiveReal(snes,alpha2,7); 4924 PetscValidLogicalCollectiveReal(snes,threshold,8); 4925 4926 if (version != PETSC_DEFAULT) kctx->version = version; 4927 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 4928 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 4929 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 4930 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 4931 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 4932 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 4933 4934 if (kctx->version < 1 || kctx->version > 3) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 4935 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0); 4936 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",(double)kctx->rtol_max); 4937 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",(double)kctx->gamma); 4938 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",(double)kctx->alpha); 4939 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",(double)kctx->threshold); 4940 PetscFunctionReturn(0); 4941 } 4942 4943 /*@ 4944 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 4945 convergence criteria for the linear solvers within an inexact 4946 Newton method. 4947 4948 Not Collective 4949 4950 Input Parameters: 4951 snes - SNES context 4952 4953 Output Parameters: 4954 + version - version 1, 2 (default is 2) or 3 4955 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 4956 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4957 . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 4958 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 4959 . alpha2 - power for safeguard 4960 - threshold - threshold for imposing safeguard (0 < threshold < 1) 4961 4962 Level: advanced 4963 4964 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 4965 4966 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 4967 @*/ 4968 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 4969 { 4970 SNESKSPEW *kctx; 4971 4972 PetscFunctionBegin; 4973 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4974 kctx = (SNESKSPEW*)snes->kspconvctx; 4975 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4976 if (version) *version = kctx->version; 4977 if (rtol_0) *rtol_0 = kctx->rtol_0; 4978 if (rtol_max) *rtol_max = kctx->rtol_max; 4979 if (gamma) *gamma = kctx->gamma; 4980 if (alpha) *alpha = kctx->alpha; 4981 if (alpha2) *alpha2 = kctx->alpha2; 4982 if (threshold) *threshold = kctx->threshold; 4983 PetscFunctionReturn(0); 4984 } 4985 4986 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 4987 { 4988 PetscErrorCode ierr; 4989 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 4990 PetscReal rtol = PETSC_DEFAULT,stol; 4991 4992 PetscFunctionBegin; 4993 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 4994 if (!snes->iter) { 4995 rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 4996 ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 4997 } 4998 else { 4999 if (kctx->version == 1) { 5000 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 5001 if (rtol < 0.0) rtol = -rtol; 5002 stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 5003 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5004 } else if (kctx->version == 2) { 5005 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5006 stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 5007 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5008 } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 5009 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5010 /* safeguard: avoid sharp decrease of rtol */ 5011 stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 5012 stol = PetscMax(rtol,stol); 5013 rtol = PetscMin(kctx->rtol_0,stol); 5014 /* safeguard: avoid oversolving */ 5015 stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 5016 stol = PetscMax(rtol,stol); 5017 rtol = PetscMin(kctx->rtol_0,stol); 5018 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 5019 } 5020 /* safeguard: avoid rtol greater than one */ 5021 rtol = PetscMin(rtol,kctx->rtol_max); 5022 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 5023 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 5024 PetscFunctionReturn(0); 5025 } 5026 5027 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5028 { 5029 PetscErrorCode ierr; 5030 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 5031 PCSide pcside; 5032 Vec lres; 5033 5034 PetscFunctionBegin; 5035 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 5036 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 5037 kctx->norm_last = snes->norm; 5038 if (kctx->version == 1) { 5039 PC pc; 5040 PetscBool isNone; 5041 5042 ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 5043 ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 5044 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 5045 if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 5046 /* KSP residual is true linear residual */ 5047 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 5048 } else { 5049 /* KSP residual is preconditioned residual */ 5050 /* compute true linear residual norm */ 5051 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 5052 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 5053 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 5054 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 5055 ierr = VecDestroy(&lres);CHKERRQ(ierr); 5056 } 5057 } 5058 PetscFunctionReturn(0); 5059 } 5060 5061 /*@ 5062 SNESGetKSP - Returns the KSP context for a SNES solver. 5063 5064 Not Collective, but if SNES object is parallel, then KSP object is parallel 5065 5066 Input Parameter: 5067 . snes - the SNES context 5068 5069 Output Parameter: 5070 . ksp - the KSP context 5071 5072 Notes: 5073 The user can then directly manipulate the KSP context to set various 5074 options, etc. Likewise, the user can then extract and manipulate the 5075 PC contexts as well. 5076 5077 Level: beginner 5078 5079 .keywords: SNES, nonlinear, get, KSP, context 5080 5081 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 5082 @*/ 5083 PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 5084 { 5085 PetscErrorCode ierr; 5086 5087 PetscFunctionBegin; 5088 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5089 PetscValidPointer(ksp,2); 5090 5091 if (!snes->ksp) { 5092 PetscBool monitor = PETSC_FALSE; 5093 5094 ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 5095 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 5096 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 5097 5098 ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 5099 ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 5100 5101 ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 5102 if (monitor) { 5103 ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 5104 } 5105 monitor = PETSC_FALSE; 5106 ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 5107 if (monitor) { 5108 PetscObject *objs; 5109 ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 5110 objs[0] = (PetscObject) snes; 5111 ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 5112 } 5113 } 5114 *ksp = snes->ksp; 5115 PetscFunctionReturn(0); 5116 } 5117 5118 5119 #include <petsc/private/dmimpl.h> 5120 /*@ 5121 SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 5122 5123 Logically Collective on SNES 5124 5125 Input Parameters: 5126 + snes - the nonlinear solver context 5127 - dm - the dm, cannot be NULL 5128 5129 Level: intermediate 5130 5131 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 5132 @*/ 5133 PetscErrorCode SNESSetDM(SNES snes,DM dm) 5134 { 5135 PetscErrorCode ierr; 5136 KSP ksp; 5137 DMSNES sdm; 5138 5139 PetscFunctionBegin; 5140 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5141 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 5142 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5143 if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 5144 if (snes->dm->dmsnes && !dm->dmsnes) { 5145 ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 5146 ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 5147 if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 5148 } 5149 ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 5150 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 5151 } 5152 snes->dm = dm; 5153 snes->dmAuto = PETSC_FALSE; 5154 5155 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 5156 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 5157 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 5158 if (snes->npc) { 5159 ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 5160 ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 5161 } 5162 PetscFunctionReturn(0); 5163 } 5164 5165 /*@ 5166 SNESGetDM - Gets the DM that may be used by some preconditioners 5167 5168 Not Collective but DM obtained is parallel on SNES 5169 5170 Input Parameter: 5171 . snes - the preconditioner context 5172 5173 Output Parameter: 5174 . dm - the dm 5175 5176 Level: intermediate 5177 5178 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 5179 @*/ 5180 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 5181 { 5182 PetscErrorCode ierr; 5183 5184 PetscFunctionBegin; 5185 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5186 if (!snes->dm) { 5187 ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 5188 snes->dmAuto = PETSC_TRUE; 5189 } 5190 *dm = snes->dm; 5191 PetscFunctionReturn(0); 5192 } 5193 5194 /*@ 5195 SNESSetNPC - Sets the nonlinear preconditioner to be used. 5196 5197 Collective on SNES 5198 5199 Input Parameters: 5200 + snes - iterative context obtained from SNESCreate() 5201 - pc - the preconditioner object 5202 5203 Notes: 5204 Use SNESGetNPC() to retrieve the preconditioner context (for example, 5205 to configure it using the API). 5206 5207 Level: developer 5208 5209 .keywords: SNES, set, precondition 5210 .seealso: SNESGetNPC(), SNESHasNPC() 5211 @*/ 5212 PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 5213 { 5214 PetscErrorCode ierr; 5215 5216 PetscFunctionBegin; 5217 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5218 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 5219 PetscCheckSameComm(snes, 1, pc, 2); 5220 ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5221 ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5222 snes->npc = pc; 5223 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 5224 PetscFunctionReturn(0); 5225 } 5226 5227 /*@ 5228 SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 5229 5230 Not Collective 5231 5232 Input Parameter: 5233 . snes - iterative context obtained from SNESCreate() 5234 5235 Output Parameter: 5236 . pc - preconditioner context 5237 5238 Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned. 5239 5240 Level: developer 5241 5242 .keywords: SNES, get, preconditioner 5243 .seealso: SNESSetNPC(), SNESHasNPC() 5244 @*/ 5245 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5246 { 5247 PetscErrorCode ierr; 5248 const char *optionsprefix; 5249 5250 PetscFunctionBegin; 5251 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5252 PetscValidPointer(pc, 2); 5253 if (!snes->npc) { 5254 ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5255 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5256 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5257 ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5258 ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5259 ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5260 ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 5261 } 5262 *pc = snes->npc; 5263 PetscFunctionReturn(0); 5264 } 5265 5266 /*@ 5267 SNESHasNPC - Returns whether a nonlinear preconditioner exists 5268 5269 Not Collective 5270 5271 Input Parameter: 5272 . snes - iterative context obtained from SNESCreate() 5273 5274 Output Parameter: 5275 . has_npc - whether the SNES has an NPC or not 5276 5277 Level: developer 5278 5279 .keywords: SNES, has, preconditioner 5280 .seealso: SNESSetNPC(), SNESGetNPC() 5281 @*/ 5282 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5283 { 5284 PetscFunctionBegin; 5285 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5286 *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 5287 PetscFunctionReturn(0); 5288 } 5289 5290 /*@ 5291 SNESSetNPCSide - Sets the preconditioning side. 5292 5293 Logically Collective on SNES 5294 5295 Input Parameter: 5296 . snes - iterative context obtained from SNESCreate() 5297 5298 Output Parameter: 5299 . side - the preconditioning side, where side is one of 5300 .vb 5301 PC_LEFT - left preconditioning 5302 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5303 .ve 5304 5305 Options Database Keys: 5306 . -snes_pc_side <right,left> 5307 5308 Notes: SNESNRICHARDSON and SNESNCG only support left preconditioning. 5309 5310 Level: intermediate 5311 5312 .keywords: SNES, set, right, left, side, preconditioner, flag 5313 5314 .seealso: SNESGetNPCSide(), KSPSetPCSide() 5315 @*/ 5316 PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5317 { 5318 PetscFunctionBegin; 5319 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5320 PetscValidLogicalCollectiveEnum(snes,side,2); 5321 snes->npcside= side; 5322 PetscFunctionReturn(0); 5323 } 5324 5325 /*@ 5326 SNESGetNPCSide - Gets the preconditioning side. 5327 5328 Not Collective 5329 5330 Input Parameter: 5331 . snes - iterative context obtained from SNESCreate() 5332 5333 Output Parameter: 5334 . side - the preconditioning side, where side is one of 5335 .vb 5336 PC_LEFT - left preconditioning 5337 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5338 .ve 5339 5340 Level: intermediate 5341 5342 .keywords: SNES, get, right, left, side, preconditioner, flag 5343 5344 .seealso: SNESSetNPCSide(), KSPGetPCSide() 5345 @*/ 5346 PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5347 { 5348 PetscFunctionBegin; 5349 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5350 PetscValidPointer(side,2); 5351 *side = snes->npcside; 5352 PetscFunctionReturn(0); 5353 } 5354 5355 /*@ 5356 SNESSetLineSearch - Sets the linesearch on the SNES instance. 5357 5358 Collective on SNES 5359 5360 Input Parameters: 5361 + snes - iterative context obtained from SNESCreate() 5362 - linesearch - the linesearch object 5363 5364 Notes: 5365 Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 5366 to configure it using the API). 5367 5368 Level: developer 5369 5370 .keywords: SNES, set, linesearch 5371 .seealso: SNESGetLineSearch() 5372 @*/ 5373 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5374 { 5375 PetscErrorCode ierr; 5376 5377 PetscFunctionBegin; 5378 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5379 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 5380 PetscCheckSameComm(snes, 1, linesearch, 2); 5381 ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5382 ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5383 5384 snes->linesearch = linesearch; 5385 5386 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 5387 PetscFunctionReturn(0); 5388 } 5389 5390 /*@ 5391 SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 5392 or creates a default line search instance associated with the SNES and returns it. 5393 5394 Not Collective 5395 5396 Input Parameter: 5397 . snes - iterative context obtained from SNESCreate() 5398 5399 Output Parameter: 5400 . linesearch - linesearch context 5401 5402 Level: beginner 5403 5404 .keywords: SNES, get, linesearch 5405 .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 5406 @*/ 5407 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5408 { 5409 PetscErrorCode ierr; 5410 const char *optionsprefix; 5411 5412 PetscFunctionBegin; 5413 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5414 PetscValidPointer(linesearch, 2); 5415 if (!snes->linesearch) { 5416 ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 5417 ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5418 ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5419 ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 5420 ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 5421 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 5422 } 5423 *linesearch = snes->linesearch; 5424 PetscFunctionReturn(0); 5425 } 5426 5427 #if defined(PETSC_HAVE_MATLAB_ENGINE) 5428 #include <mex.h> 5429 5430 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 5431 5432 /* 5433 SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab(). 5434 5435 Collective on SNES 5436 5437 Input Parameters: 5438 + snes - the SNES context 5439 - x - input vector 5440 5441 Output Parameter: 5442 . y - function vector, as set by SNESSetFunction() 5443 5444 Notes: 5445 SNESComputeFunction() is typically used within nonlinear solvers 5446 implementations, so most users would not generally call this routine 5447 themselves. 5448 5449 Level: developer 5450 5451 .keywords: SNES, nonlinear, compute, function 5452 5453 .seealso: SNESSetFunction(), SNESGetFunction() 5454 */ 5455 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 5456 { 5457 PetscErrorCode ierr; 5458 SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5459 int nlhs = 1,nrhs = 5; 5460 mxArray *plhs[1],*prhs[5]; 5461 long long int lx = 0,ly = 0,ls = 0; 5462 5463 PetscFunctionBegin; 5464 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5465 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 5466 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 5467 PetscCheckSameComm(snes,1,x,2); 5468 PetscCheckSameComm(snes,1,y,3); 5469 5470 /* call Matlab function in ctx with arguments x and y */ 5471 5472 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5473 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5474 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 5475 prhs[0] = mxCreateDoubleScalar((double)ls); 5476 prhs[1] = mxCreateDoubleScalar((double)lx); 5477 prhs[2] = mxCreateDoubleScalar((double)ly); 5478 prhs[3] = mxCreateString(sctx->funcname); 5479 prhs[4] = sctx->ctx; 5480 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 5481 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5482 mxDestroyArray(prhs[0]); 5483 mxDestroyArray(prhs[1]); 5484 mxDestroyArray(prhs[2]); 5485 mxDestroyArray(prhs[3]); 5486 mxDestroyArray(plhs[0]); 5487 PetscFunctionReturn(0); 5488 } 5489 5490 /* 5491 SNESSetFunctionMatlab - Sets the function evaluation routine and function 5492 vector for use by the SNES routines in solving systems of nonlinear 5493 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 5494 5495 Logically Collective on SNES 5496 5497 Input Parameters: 5498 + snes - the SNES context 5499 . r - vector to store function value 5500 - f - function evaluation routine 5501 5502 Notes: 5503 The Newton-like methods typically solve linear systems of the form 5504 $ f'(x) x = -f(x), 5505 where f'(x) denotes the Jacobian matrix and f(x) is the function. 5506 5507 Level: beginner 5508 5509 Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5510 5511 .keywords: SNES, nonlinear, set, function 5512 5513 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5514 */ 5515 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx) 5516 { 5517 PetscErrorCode ierr; 5518 SNESMatlabContext *sctx; 5519 5520 PetscFunctionBegin; 5521 /* currently sctx is memory bleed */ 5522 ierr = PetscNew(&sctx);CHKERRQ(ierr); 5523 ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5524 /* 5525 This should work, but it doesn't 5526 sctx->ctx = ctx; 5527 mexMakeArrayPersistent(sctx->ctx); 5528 */ 5529 sctx->ctx = mxDuplicateArray(ctx); 5530 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 5531 PetscFunctionReturn(0); 5532 } 5533 5534 /* 5535 SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab(). 5536 5537 Collective on SNES 5538 5539 Input Parameters: 5540 + snes - the SNES context 5541 . x - input vector 5542 . A, B - the matrices 5543 - ctx - user context 5544 5545 Level: developer 5546 5547 .keywords: SNES, nonlinear, compute, function 5548 5549 .seealso: SNESSetFunction(), SNESGetFunction() 5550 @*/ 5551 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx) 5552 { 5553 PetscErrorCode ierr; 5554 SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5555 int nlhs = 2,nrhs = 6; 5556 mxArray *plhs[2],*prhs[6]; 5557 long long int lx = 0,lA = 0,ls = 0, lB = 0; 5558 5559 PetscFunctionBegin; 5560 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5561 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 5562 5563 /* call Matlab function in ctx with arguments x and y */ 5564 5565 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5566 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5567 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 5568 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 5569 prhs[0] = mxCreateDoubleScalar((double)ls); 5570 prhs[1] = mxCreateDoubleScalar((double)lx); 5571 prhs[2] = mxCreateDoubleScalar((double)lA); 5572 prhs[3] = mxCreateDoubleScalar((double)lB); 5573 prhs[4] = mxCreateString(sctx->funcname); 5574 prhs[5] = sctx->ctx; 5575 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 5576 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5577 mxDestroyArray(prhs[0]); 5578 mxDestroyArray(prhs[1]); 5579 mxDestroyArray(prhs[2]); 5580 mxDestroyArray(prhs[3]); 5581 mxDestroyArray(prhs[4]); 5582 mxDestroyArray(plhs[0]); 5583 mxDestroyArray(plhs[1]); 5584 PetscFunctionReturn(0); 5585 } 5586 5587 /* 5588 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 5589 vector for use by the SNES routines in solving systems of nonlinear 5590 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 5591 5592 Logically Collective on SNES 5593 5594 Input Parameters: 5595 + snes - the SNES context 5596 . A,B - Jacobian matrices 5597 . J - function evaluation routine 5598 - ctx - user context 5599 5600 Level: developer 5601 5602 Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5603 5604 .keywords: SNES, nonlinear, set, function 5605 5606 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J 5607 */ 5608 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx) 5609 { 5610 PetscErrorCode ierr; 5611 SNESMatlabContext *sctx; 5612 5613 PetscFunctionBegin; 5614 /* currently sctx is memory bleed */ 5615 ierr = PetscNew(&sctx);CHKERRQ(ierr); 5616 ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr); 5617 /* 5618 This should work, but it doesn't 5619 sctx->ctx = ctx; 5620 mexMakeArrayPersistent(sctx->ctx); 5621 */ 5622 sctx->ctx = mxDuplicateArray(ctx); 5623 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 5624 PetscFunctionReturn(0); 5625 } 5626 5627 /* 5628 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 5629 5630 Collective on SNES 5631 5632 .seealso: SNESSetFunction(), SNESGetFunction() 5633 @*/ 5634 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 5635 { 5636 PetscErrorCode ierr; 5637 SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5638 int nlhs = 1,nrhs = 6; 5639 mxArray *plhs[1],*prhs[6]; 5640 long long int lx = 0,ls = 0; 5641 Vec x = snes->vec_sol; 5642 5643 PetscFunctionBegin; 5644 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5645 5646 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5647 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5648 prhs[0] = mxCreateDoubleScalar((double)ls); 5649 prhs[1] = mxCreateDoubleScalar((double)it); 5650 prhs[2] = mxCreateDoubleScalar((double)fnorm); 5651 prhs[3] = mxCreateDoubleScalar((double)lx); 5652 prhs[4] = mxCreateString(sctx->funcname); 5653 prhs[5] = sctx->ctx; 5654 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 5655 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5656 mxDestroyArray(prhs[0]); 5657 mxDestroyArray(prhs[1]); 5658 mxDestroyArray(prhs[2]); 5659 mxDestroyArray(prhs[3]); 5660 mxDestroyArray(prhs[4]); 5661 mxDestroyArray(plhs[0]); 5662 PetscFunctionReturn(0); 5663 } 5664 5665 /* 5666 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 5667 5668 Level: developer 5669 5670 Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5671 5672 .keywords: SNES, nonlinear, set, function 5673 5674 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5675 */ 5676 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx) 5677 { 5678 PetscErrorCode ierr; 5679 SNESMatlabContext *sctx; 5680 5681 PetscFunctionBegin; 5682 /* currently sctx is memory bleed */ 5683 ierr = PetscNew(&sctx);CHKERRQ(ierr); 5684 ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5685 /* 5686 This should work, but it doesn't 5687 sctx->ctx = ctx; 5688 mexMakeArrayPersistent(sctx->ctx); 5689 */ 5690 sctx->ctx = mxDuplicateArray(ctx); 5691 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5692 PetscFunctionReturn(0); 5693 } 5694 5695 #endif 5696