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