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