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