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