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