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