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