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