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