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