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