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