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 PetscInt num; 4045 PetscBool flg; 4046 static PetscBool incall = PETSC_FALSE; 4047 4048 if (!incall) { 4049 /* Estimate the convergence rate of the discretization */ 4050 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes), ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 4051 if (flg) { 4052 PetscConvEst conv; 4053 PetscReal alpha; /* Convergence rate of the solution error in the L_2 norm */ 4054 4055 incall = PETSC_TRUE; 4056 ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 4057 ierr = PetscConvEstSetSolver(conv, snes);CHKERRQ(ierr); 4058 ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 4059 ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 4060 ierr = PetscConvEstGetConvRate(conv, &alpha);CHKERRQ(ierr); 4061 ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 4062 ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 4063 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4064 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4065 ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 4066 incall = PETSC_FALSE; 4067 } 4068 /* Adaptively refine the initial grid */ 4069 flg = PETSC_FALSE; 4070 ierr = PetscOptionsGetBool(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &flg, NULL);CHKERRQ(ierr); 4071 if (flg) { 4072 DMAdaptor adaptor; 4073 4074 incall = PETSC_TRUE; 4075 ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 4076 ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4077 ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 4078 ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 4079 ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr); 4080 ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 4081 incall = PETSC_FALSE; 4082 } 4083 /* Use grid sequencing to adapt */ 4084 num = 0; 4085 ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr); 4086 if (num) { 4087 DMAdaptor adaptor; 4088 4089 incall = PETSC_TRUE; 4090 ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 4091 ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4092 ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 4093 ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 4094 ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 4095 ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr); 4096 ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 4097 incall = PETSC_FALSE; 4098 } 4099 } 4100 } 4101 if (!x) { 4102 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4103 ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4104 x = xcreated; 4105 } 4106 ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4107 4108 for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4109 for (grid=0; grid<snes->gridsequence+1; grid++) { 4110 4111 /* set solution vector */ 4112 if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 4113 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 4114 snes->vec_sol = x; 4115 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4116 4117 /* set affine vector if provided */ 4118 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 4119 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 4120 snes->vec_rhs = b; 4121 4122 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4123 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 4124 if (!snes->vec_sol_update /* && snes->vec_sol */) { 4125 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4126 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4127 } 4128 ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 4129 ierr = SNESSetUp(snes);CHKERRQ(ierr); 4130 4131 if (!grid) { 4132 if (snes->ops->computeinitialguess) { 4133 ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4134 } 4135 } 4136 4137 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4138 if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4139 4140 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 4141 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 4142 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 4143 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4144 snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 4145 4146 if (snes->lagjac_persist) snes->jac_iter += snes->iter; 4147 if (snes->lagpre_persist) snes->pre_iter += snes->iter; 4148 4149 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4150 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 4151 ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr); 4152 4153 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 4154 if (snes->reason < 0) break; 4155 if (grid < snes->gridsequence) { 4156 DM fine; 4157 Vec xnew; 4158 Mat interp; 4159 4160 ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4161 if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 4162 ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4163 ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4164 ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4165 ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4166 ierr = MatDestroy(&interp);CHKERRQ(ierr); 4167 x = xnew; 4168 4169 ierr = SNESReset(snes);CHKERRQ(ierr); 4170 ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4171 ierr = DMDestroy(&fine);CHKERRQ(ierr); 4172 ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4173 } 4174 } 4175 ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4176 ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 4177 4178 ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4179 ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 4180 PetscFunctionReturn(0); 4181 } 4182 4183 /* --------- Internal routines for SNES Package --------- */ 4184 4185 /*@C 4186 SNESSetType - Sets the method for the nonlinear solver. 4187 4188 Collective on SNES 4189 4190 Input Parameters: 4191 + snes - the SNES context 4192 - type - a known method 4193 4194 Options Database Key: 4195 . -snes_type <type> - Sets the method; use -help for a list 4196 of available methods (for instance, newtonls or newtontr) 4197 4198 Notes: 4199 See "petsc/include/petscsnes.h" for available methods (for instance) 4200 + SNESNEWTONLS - Newton's method with line search 4201 (systems of nonlinear equations) 4202 . SNESNEWTONTR - Newton's method with trust region 4203 (systems of nonlinear equations) 4204 4205 Normally, it is best to use the SNESSetFromOptions() command and then 4206 set the SNES solver type from the options database rather than by using 4207 this routine. Using the options database provides the user with 4208 maximum flexibility in evaluating the many nonlinear solvers. 4209 The SNESSetType() routine is provided for those situations where it 4210 is necessary to set the nonlinear solver independently of the command 4211 line or options database. This might be the case, for example, when 4212 the choice of solver changes during the execution of the program, 4213 and the user's application is taking responsibility for choosing the 4214 appropriate method. 4215 4216 Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 4217 the constructor in that list and calls it to create the spexific object. 4218 4219 Level: intermediate 4220 4221 .keywords: SNES, set, type 4222 4223 .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4224 4225 @*/ 4226 PetscErrorCode SNESSetType(SNES snes,SNESType type) 4227 { 4228 PetscErrorCode ierr,(*r)(SNES); 4229 PetscBool match; 4230 4231 PetscFunctionBegin; 4232 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4233 PetscValidCharPointer(type,2); 4234 4235 ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 4236 if (match) PetscFunctionReturn(0); 4237 4238 ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4239 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 4240 /* Destroy the previous private SNES context */ 4241 if (snes->ops->destroy) { 4242 ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 4243 snes->ops->destroy = NULL; 4244 } 4245 /* Reinitialize function pointers in SNESOps structure */ 4246 snes->ops->setup = 0; 4247 snes->ops->solve = 0; 4248 snes->ops->view = 0; 4249 snes->ops->setfromoptions = 0; 4250 snes->ops->destroy = 0; 4251 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 4252 snes->setupcalled = PETSC_FALSE; 4253 4254 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 4255 ierr = (*r)(snes);CHKERRQ(ierr); 4256 PetscFunctionReturn(0); 4257 } 4258 4259 /*@C 4260 SNESGetType - Gets the SNES method type and name (as a string). 4261 4262 Not Collective 4263 4264 Input Parameter: 4265 . snes - nonlinear solver context 4266 4267 Output Parameter: 4268 . type - SNES method (a character string) 4269 4270 Level: intermediate 4271 4272 .keywords: SNES, nonlinear, get, type, name 4273 @*/ 4274 PetscErrorCode SNESGetType(SNES snes,SNESType *type) 4275 { 4276 PetscFunctionBegin; 4277 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4278 PetscValidPointer(type,2); 4279 *type = ((PetscObject)snes)->type_name; 4280 PetscFunctionReturn(0); 4281 } 4282 4283 /*@ 4284 SNESSetSolution - Sets the solution vector for use by the SNES routines. 4285 4286 Logically Collective on SNES and Vec 4287 4288 Input Parameters: 4289 + snes - the SNES context obtained from SNESCreate() 4290 - u - the solution vector 4291 4292 Level: beginner 4293 4294 .keywords: SNES, set, solution 4295 @*/ 4296 PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4297 { 4298 DM dm; 4299 PetscErrorCode ierr; 4300 4301 PetscFunctionBegin; 4302 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4303 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 4304 ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 4305 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 4306 4307 snes->vec_sol = u; 4308 4309 ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 4310 ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 4311 PetscFunctionReturn(0); 4312 } 4313 4314 /*@ 4315 SNESGetSolution - Returns the vector where the approximate solution is 4316 stored. This is the fine grid solution when using SNESSetGridSequence(). 4317 4318 Not Collective, but Vec is parallel if SNES is parallel 4319 4320 Input Parameter: 4321 . snes - the SNES context 4322 4323 Output Parameter: 4324 . x - the solution 4325 4326 Level: intermediate 4327 4328 .keywords: SNES, nonlinear, get, solution 4329 4330 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 4331 @*/ 4332 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 4333 { 4334 PetscFunctionBegin; 4335 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4336 PetscValidPointer(x,2); 4337 *x = snes->vec_sol; 4338 PetscFunctionReturn(0); 4339 } 4340 4341 /*@ 4342 SNESGetSolutionUpdate - Returns the vector where the solution update is 4343 stored. 4344 4345 Not Collective, but Vec is parallel if SNES is parallel 4346 4347 Input Parameter: 4348 . snes - the SNES context 4349 4350 Output Parameter: 4351 . x - the solution update 4352 4353 Level: advanced 4354 4355 .keywords: SNES, nonlinear, get, solution, update 4356 4357 .seealso: SNESGetSolution(), SNESGetFunction() 4358 @*/ 4359 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 4360 { 4361 PetscFunctionBegin; 4362 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4363 PetscValidPointer(x,2); 4364 *x = snes->vec_sol_update; 4365 PetscFunctionReturn(0); 4366 } 4367 4368 /*@C 4369 SNESGetFunction - Returns the vector where the function is stored. 4370 4371 Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4372 4373 Input Parameter: 4374 . snes - the SNES context 4375 4376 Output Parameter: 4377 + r - the vector that is used to store residuals (or NULL if you don't want it) 4378 . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 4379 - ctx - the function context (or NULL if you don't want it) 4380 4381 Level: advanced 4382 4383 .keywords: SNES, nonlinear, get, function 4384 4385 .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 4386 @*/ 4387 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 4388 { 4389 PetscErrorCode ierr; 4390 DM dm; 4391 4392 PetscFunctionBegin; 4393 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4394 if (r) { 4395 if (!snes->vec_func) { 4396 if (snes->vec_rhs) { 4397 ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4398 } else if (snes->vec_sol) { 4399 ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4400 } else if (snes->dm) { 4401 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4402 } 4403 } 4404 *r = snes->vec_func; 4405 } 4406 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4407 ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 4408 PetscFunctionReturn(0); 4409 } 4410 4411 /*@C 4412 SNESGetNGS - Returns the NGS function and context. 4413 4414 Input Parameter: 4415 . snes - the SNES context 4416 4417 Output Parameter: 4418 + f - the function (or NULL) see SNESNGSFunction for details 4419 - ctx - the function context (or NULL) 4420 4421 Level: advanced 4422 4423 .keywords: SNES, nonlinear, get, function 4424 4425 .seealso: SNESSetNGS(), SNESGetFunction() 4426 @*/ 4427 4428 PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4429 { 4430 PetscErrorCode ierr; 4431 DM dm; 4432 4433 PetscFunctionBegin; 4434 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4435 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4436 ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4437 PetscFunctionReturn(0); 4438 } 4439 4440 /*@C 4441 SNESSetOptionsPrefix - Sets the prefix used for searching for all 4442 SNES options in the database. 4443 4444 Logically Collective on SNES 4445 4446 Input Parameter: 4447 + snes - the SNES context 4448 - prefix - the prefix to prepend to all option names 4449 4450 Notes: 4451 A hyphen (-) must NOT be given at the beginning of the prefix name. 4452 The first character of all runtime options is AUTOMATICALLY the hyphen. 4453 4454 Level: advanced 4455 4456 .keywords: SNES, set, options, prefix, database 4457 4458 .seealso: SNESSetFromOptions() 4459 @*/ 4460 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 4461 { 4462 PetscErrorCode ierr; 4463 4464 PetscFunctionBegin; 4465 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4466 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4467 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 4468 if (snes->linesearch) { 4469 ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 4470 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 4471 } 4472 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 4473 PetscFunctionReturn(0); 4474 } 4475 4476 /*@C 4477 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4478 SNES options in the database. 4479 4480 Logically Collective on SNES 4481 4482 Input Parameters: 4483 + snes - the SNES context 4484 - prefix - the prefix to prepend to all option names 4485 4486 Notes: 4487 A hyphen (-) must NOT be given at the beginning of the prefix name. 4488 The first character of all runtime options is AUTOMATICALLY the hyphen. 4489 4490 Level: advanced 4491 4492 .keywords: SNES, append, options, prefix, database 4493 4494 .seealso: SNESGetOptionsPrefix() 4495 @*/ 4496 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 4497 { 4498 PetscErrorCode ierr; 4499 4500 PetscFunctionBegin; 4501 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4502 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4503 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 4504 if (snes->linesearch) { 4505 ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 4506 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 4507 } 4508 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 4509 PetscFunctionReturn(0); 4510 } 4511 4512 /*@C 4513 SNESGetOptionsPrefix - Sets the prefix used for searching for all 4514 SNES options in the database. 4515 4516 Not Collective 4517 4518 Input Parameter: 4519 . snes - the SNES context 4520 4521 Output Parameter: 4522 . prefix - pointer to the prefix string used 4523 4524 Notes: On the fortran side, the user should pass in a string 'prefix' of 4525 sufficient length to hold the prefix. 4526 4527 Level: advanced 4528 4529 .keywords: SNES, get, options, prefix, database 4530 4531 .seealso: SNESAppendOptionsPrefix() 4532 @*/ 4533 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 4534 { 4535 PetscErrorCode ierr; 4536 4537 PetscFunctionBegin; 4538 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4539 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4540 PetscFunctionReturn(0); 4541 } 4542 4543 4544 /*@C 4545 SNESRegister - Adds a method to the nonlinear solver package. 4546 4547 Not collective 4548 4549 Input Parameters: 4550 + name_solver - name of a new user-defined solver 4551 - routine_create - routine to create method context 4552 4553 Notes: 4554 SNESRegister() may be called multiple times to add several user-defined solvers. 4555 4556 Sample usage: 4557 .vb 4558 SNESRegister("my_solver",MySolverCreate); 4559 .ve 4560 4561 Then, your solver can be chosen with the procedural interface via 4562 $ SNESSetType(snes,"my_solver") 4563 or at runtime via the option 4564 $ -snes_type my_solver 4565 4566 Level: advanced 4567 4568 Note: If your function is not being put into a shared library then use SNESRegister() instead 4569 4570 .keywords: SNES, nonlinear, register 4571 4572 .seealso: SNESRegisterAll(), SNESRegisterDestroy() 4573 4574 Level: advanced 4575 @*/ 4576 PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4577 { 4578 PetscErrorCode ierr; 4579 4580 PetscFunctionBegin; 4581 ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 4582 PetscFunctionReturn(0); 4583 } 4584 4585 PetscErrorCode SNESTestLocalMin(SNES snes) 4586 { 4587 PetscErrorCode ierr; 4588 PetscInt N,i,j; 4589 Vec u,uh,fh; 4590 PetscScalar value; 4591 PetscReal norm; 4592 4593 PetscFunctionBegin; 4594 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4595 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4596 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4597 4598 /* currently only works for sequential */ 4599 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr); 4600 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4601 for (i=0; i<N; i++) { 4602 ierr = VecCopy(u,uh);CHKERRQ(ierr); 4603 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4604 for (j=-10; j<11; j++) { 4605 value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 4606 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4607 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4608 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 4609 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4610 value = -value; 4611 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4612 } 4613 } 4614 ierr = VecDestroy(&uh);CHKERRQ(ierr); 4615 ierr = VecDestroy(&fh);CHKERRQ(ierr); 4616 PetscFunctionReturn(0); 4617 } 4618 4619 /*@ 4620 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 4621 computing relative tolerance for linear solvers within an inexact 4622 Newton method. 4623 4624 Logically Collective on SNES 4625 4626 Input Parameters: 4627 + snes - SNES context 4628 - flag - PETSC_TRUE or PETSC_FALSE 4629 4630 Options Database: 4631 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4632 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 4633 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 4634 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 4635 . -snes_ksp_ew_gamma <gamma> - Sets gamma 4636 . -snes_ksp_ew_alpha <alpha> - Sets alpha 4637 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 4638 - -snes_ksp_ew_threshold <threshold> - Sets threshold 4639 4640 Notes: 4641 Currently, the default is to use a constant relative tolerance for 4642 the inner linear solvers. Alternatively, one can use the 4643 Eisenstat-Walker method, where the relative convergence tolerance 4644 is reset at each Newton iteration according progress of the nonlinear 4645 solver. 4646 4647 Level: advanced 4648 4649 Reference: 4650 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4651 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 4652 4653 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 4654 4655 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 4656 @*/ 4657 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 4658 { 4659 PetscFunctionBegin; 4660 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4661 PetscValidLogicalCollectiveBool(snes,flag,2); 4662 snes->ksp_ewconv = flag; 4663 PetscFunctionReturn(0); 4664 } 4665 4666 /*@ 4667 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 4668 for computing relative tolerance for linear solvers within an 4669 inexact Newton method. 4670 4671 Not Collective 4672 4673 Input Parameter: 4674 . snes - SNES context 4675 4676 Output Parameter: 4677 . flag - PETSC_TRUE or PETSC_FALSE 4678 4679 Notes: 4680 Currently, the default is to use a constant relative tolerance for 4681 the inner linear solvers. Alternatively, one can use the 4682 Eisenstat-Walker method, where the relative convergence tolerance 4683 is reset at each Newton iteration according progress of the nonlinear 4684 solver. 4685 4686 Level: advanced 4687 4688 Reference: 4689 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4690 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 4691 4692 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 4693 4694 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 4695 @*/ 4696 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 4697 { 4698 PetscFunctionBegin; 4699 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4700 PetscValidPointer(flag,2); 4701 *flag = snes->ksp_ewconv; 4702 PetscFunctionReturn(0); 4703 } 4704 4705 /*@ 4706 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 4707 convergence criteria for the linear solvers within an inexact 4708 Newton method. 4709 4710 Logically Collective on SNES 4711 4712 Input Parameters: 4713 + snes - SNES context 4714 . version - version 1, 2 (default is 2) or 3 4715 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 4716 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4717 . gamma - multiplicative factor for version 2 rtol computation 4718 (0 <= gamma2 <= 1) 4719 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 4720 . alpha2 - power for safeguard 4721 - threshold - threshold for imposing safeguard (0 < threshold < 1) 4722 4723 Note: 4724 Version 3 was contributed by Luis Chacon, June 2006. 4725 4726 Use PETSC_DEFAULT to retain the default for any of the parameters. 4727 4728 Level: advanced 4729 4730 Reference: 4731 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4732 inexact Newton method", Utah State University Math. Stat. Dept. Res. 4733 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 4734 4735 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 4736 4737 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 4738 @*/ 4739 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 4740 { 4741 SNESKSPEW *kctx; 4742 4743 PetscFunctionBegin; 4744 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4745 kctx = (SNESKSPEW*)snes->kspconvctx; 4746 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4747 PetscValidLogicalCollectiveInt(snes,version,2); 4748 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4749 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4750 PetscValidLogicalCollectiveReal(snes,gamma,5); 4751 PetscValidLogicalCollectiveReal(snes,alpha,6); 4752 PetscValidLogicalCollectiveReal(snes,alpha2,7); 4753 PetscValidLogicalCollectiveReal(snes,threshold,8); 4754 4755 if (version != PETSC_DEFAULT) kctx->version = version; 4756 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 4757 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 4758 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 4759 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 4760 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 4761 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 4762 4763 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); 4764 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); 4765 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); 4766 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); 4767 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); 4768 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); 4769 PetscFunctionReturn(0); 4770 } 4771 4772 /*@ 4773 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 4774 convergence criteria for the linear solvers within an inexact 4775 Newton method. 4776 4777 Not Collective 4778 4779 Input Parameters: 4780 snes - SNES context 4781 4782 Output Parameters: 4783 + version - version 1, 2 (default is 2) or 3 4784 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 4785 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4786 . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 4787 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 4788 . alpha2 - power for safeguard 4789 - threshold - threshold for imposing safeguard (0 < threshold < 1) 4790 4791 Level: advanced 4792 4793 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 4794 4795 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 4796 @*/ 4797 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 4798 { 4799 SNESKSPEW *kctx; 4800 4801 PetscFunctionBegin; 4802 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4803 kctx = (SNESKSPEW*)snes->kspconvctx; 4804 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4805 if (version) *version = kctx->version; 4806 if (rtol_0) *rtol_0 = kctx->rtol_0; 4807 if (rtol_max) *rtol_max = kctx->rtol_max; 4808 if (gamma) *gamma = kctx->gamma; 4809 if (alpha) *alpha = kctx->alpha; 4810 if (alpha2) *alpha2 = kctx->alpha2; 4811 if (threshold) *threshold = kctx->threshold; 4812 PetscFunctionReturn(0); 4813 } 4814 4815 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 4816 { 4817 PetscErrorCode ierr; 4818 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 4819 PetscReal rtol = PETSC_DEFAULT,stol; 4820 4821 PetscFunctionBegin; 4822 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 4823 if (!snes->iter) { 4824 rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 4825 ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 4826 } 4827 else { 4828 if (kctx->version == 1) { 4829 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 4830 if (rtol < 0.0) rtol = -rtol; 4831 stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 4832 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 4833 } else if (kctx->version == 2) { 4834 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 4835 stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 4836 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 4837 } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 4838 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 4839 /* safeguard: avoid sharp decrease of rtol */ 4840 stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 4841 stol = PetscMax(rtol,stol); 4842 rtol = PetscMin(kctx->rtol_0,stol); 4843 /* safeguard: avoid oversolving */ 4844 stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 4845 stol = PetscMax(rtol,stol); 4846 rtol = PetscMin(kctx->rtol_0,stol); 4847 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 4848 } 4849 /* safeguard: avoid rtol greater than one */ 4850 rtol = PetscMin(rtol,kctx->rtol_max); 4851 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 4852 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 4853 PetscFunctionReturn(0); 4854 } 4855 4856 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 4857 { 4858 PetscErrorCode ierr; 4859 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 4860 PCSide pcside; 4861 Vec lres; 4862 4863 PetscFunctionBegin; 4864 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 4865 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 4866 kctx->norm_last = snes->norm; 4867 if (kctx->version == 1) { 4868 PC pc; 4869 PetscBool isNone; 4870 4871 ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 4872 ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 4873 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 4874 if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 4875 /* KSP residual is true linear residual */ 4876 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 4877 } else { 4878 /* KSP residual is preconditioned residual */ 4879 /* compute true linear residual norm */ 4880 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 4881 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 4882 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 4883 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 4884 ierr = VecDestroy(&lres);CHKERRQ(ierr); 4885 } 4886 } 4887 PetscFunctionReturn(0); 4888 } 4889 4890 /*@ 4891 SNESGetKSP - Returns the KSP context for a SNES solver. 4892 4893 Not Collective, but if SNES object is parallel, then KSP object is parallel 4894 4895 Input Parameter: 4896 . snes - the SNES context 4897 4898 Output Parameter: 4899 . ksp - the KSP context 4900 4901 Notes: 4902 The user can then directly manipulate the KSP context to set various 4903 options, etc. Likewise, the user can then extract and manipulate the 4904 PC contexts as well. 4905 4906 Level: beginner 4907 4908 .keywords: SNES, nonlinear, get, KSP, context 4909 4910 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 4911 @*/ 4912 PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 4913 { 4914 PetscErrorCode ierr; 4915 4916 PetscFunctionBegin; 4917 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4918 PetscValidPointer(ksp,2); 4919 4920 if (!snes->ksp) { 4921 PetscBool monitor = PETSC_FALSE; 4922 4923 ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 4924 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 4925 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 4926 4927 ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 4928 ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 4929 4930 ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 4931 if (monitor) { 4932 ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 4933 } 4934 monitor = PETSC_FALSE; 4935 ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 4936 if (monitor) { 4937 PetscObject *objs; 4938 ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 4939 objs[0] = (PetscObject) snes; 4940 ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 4941 } 4942 } 4943 *ksp = snes->ksp; 4944 PetscFunctionReturn(0); 4945 } 4946 4947 4948 #include <petsc/private/dmimpl.h> 4949 /*@ 4950 SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 4951 4952 Logically Collective on SNES 4953 4954 Input Parameters: 4955 + snes - the nonlinear solver context 4956 - dm - the dm, cannot be NULL 4957 4958 Level: intermediate 4959 4960 .seealso: SNESGetDM(), SNESHasDM(), KSPSetDM(), KSPGetDM() 4961 @*/ 4962 PetscErrorCode SNESSetDM(SNES snes,DM dm) 4963 { 4964 PetscErrorCode ierr; 4965 KSP ksp; 4966 DMSNES sdm; 4967 4968 PetscFunctionBegin; 4969 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4970 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4971 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4972 if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 4973 if (snes->dm->dmsnes && !dm->dmsnes) { 4974 ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 4975 ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 4976 if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 4977 } 4978 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 4979 } 4980 snes->dm = dm; 4981 snes->dmAuto = PETSC_FALSE; 4982 4983 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4984 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4985 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 4986 if (snes->npc) { 4987 ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 4988 ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 4989 } 4990 PetscFunctionReturn(0); 4991 } 4992 4993 /*@ 4994 SNESGetDM - Gets the DM that may be used by some preconditioners 4995 4996 Not Collective but DM obtained is parallel on SNES 4997 4998 Input Parameter: 4999 . snes - the preconditioner context 5000 5001 Output Parameter: 5002 . dm - the dm 5003 5004 Level: intermediate 5005 5006 .seealso: SNESSetDM(), SNESHasDM(), KSPSetDM(), KSPGetDM() 5007 @*/ 5008 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 5009 { 5010 PetscErrorCode ierr; 5011 5012 PetscFunctionBegin; 5013 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5014 if (!snes->dm) { 5015 ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 5016 snes->dmAuto = PETSC_TRUE; 5017 } 5018 *dm = snes->dm; 5019 PetscFunctionReturn(0); 5020 } 5021 5022 5023 /*@ 5024 SNESHasDM - Whether snes has dm 5025 5026 Not collective but all processes must return the same value 5027 5028 Input Parameter: 5029 . snes - the nonlinear solver object 5030 5031 Output Parameter: 5032 . hasdm - a flag indicates whether there is dm in snes 5033 5034 Level: intermediate 5035 5036 .seealso: SNESGetDM(), SNESSetDM(), KSPSetDM(), KSPGetDM() 5037 @*/ 5038 PetscErrorCode SNESHasDM(SNES snes,PetscBool *hasdm) 5039 { 5040 PetscFunctionBegin; 5041 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5042 PetscValidPointer(hasdm,2); 5043 if (snes->dm) *hasdm = PETSC_TRUE; 5044 else *hasdm = PETSC_FALSE; 5045 PetscFunctionReturn(0); 5046 } 5047 5048 /*@ 5049 SNESSetNPC - Sets the nonlinear preconditioner to be used. 5050 5051 Collective on SNES 5052 5053 Input Parameters: 5054 + snes - iterative context obtained from SNESCreate() 5055 - pc - the preconditioner object 5056 5057 Notes: 5058 Use SNESGetNPC() to retrieve the preconditioner context (for example, 5059 to configure it using the API). 5060 5061 Level: developer 5062 5063 .keywords: SNES, set, precondition 5064 .seealso: SNESGetNPC(), SNESHasNPC() 5065 @*/ 5066 PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 5067 { 5068 PetscErrorCode ierr; 5069 5070 PetscFunctionBegin; 5071 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5072 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 5073 PetscCheckSameComm(snes, 1, pc, 2); 5074 ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5075 ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5076 snes->npc = pc; 5077 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 5078 PetscFunctionReturn(0); 5079 } 5080 5081 /*@ 5082 SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 5083 5084 Not Collective 5085 5086 Input Parameter: 5087 . snes - iterative context obtained from SNESCreate() 5088 5089 Output Parameter: 5090 . pc - preconditioner context 5091 5092 Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned. 5093 5094 Level: developer 5095 5096 .keywords: SNES, get, preconditioner 5097 .seealso: SNESSetNPC(), SNESHasNPC() 5098 @*/ 5099 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5100 { 5101 PetscErrorCode ierr; 5102 const char *optionsprefix; 5103 5104 PetscFunctionBegin; 5105 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5106 PetscValidPointer(pc, 2); 5107 if (!snes->npc) { 5108 ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5109 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5110 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5111 ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5112 ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5113 ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5114 ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 5115 } 5116 *pc = snes->npc; 5117 PetscFunctionReturn(0); 5118 } 5119 5120 /*@ 5121 SNESHasNPC - Returns whether a nonlinear preconditioner exists 5122 5123 Not Collective 5124 5125 Input Parameter: 5126 . snes - iterative context obtained from SNESCreate() 5127 5128 Output Parameter: 5129 . has_npc - whether the SNES has an NPC or not 5130 5131 Level: developer 5132 5133 .keywords: SNES, has, preconditioner 5134 .seealso: SNESSetNPC(), SNESGetNPC() 5135 @*/ 5136 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5137 { 5138 PetscFunctionBegin; 5139 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5140 *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 5141 PetscFunctionReturn(0); 5142 } 5143 5144 /*@ 5145 SNESSetNPCSide - Sets the preconditioning side. 5146 5147 Logically Collective on SNES 5148 5149 Input Parameter: 5150 . snes - iterative context obtained from SNESCreate() 5151 5152 Output Parameter: 5153 . side - the preconditioning side, where side is one of 5154 .vb 5155 PC_LEFT - left preconditioning 5156 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5157 .ve 5158 5159 Options Database Keys: 5160 . -snes_pc_side <right,left> 5161 5162 Notes: SNESNRICHARDSON and SNESNCG only support left preconditioning. 5163 5164 Level: intermediate 5165 5166 .keywords: SNES, set, right, left, side, preconditioner, flag 5167 5168 .seealso: SNESGetNPCSide(), KSPSetPCSide() 5169 @*/ 5170 PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5171 { 5172 PetscFunctionBegin; 5173 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5174 PetscValidLogicalCollectiveEnum(snes,side,2); 5175 snes->npcside= side; 5176 PetscFunctionReturn(0); 5177 } 5178 5179 /*@ 5180 SNESGetNPCSide - Gets the preconditioning side. 5181 5182 Not Collective 5183 5184 Input Parameter: 5185 . snes - iterative context obtained from SNESCreate() 5186 5187 Output Parameter: 5188 . side - the preconditioning side, where side is one of 5189 .vb 5190 PC_LEFT - left preconditioning 5191 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5192 .ve 5193 5194 Level: intermediate 5195 5196 .keywords: SNES, get, right, left, side, preconditioner, flag 5197 5198 .seealso: SNESSetNPCSide(), KSPGetPCSide() 5199 @*/ 5200 PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5201 { 5202 PetscFunctionBegin; 5203 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5204 PetscValidPointer(side,2); 5205 *side = snes->npcside; 5206 PetscFunctionReturn(0); 5207 } 5208 5209 /*@ 5210 SNESSetLineSearch - Sets the linesearch on the SNES instance. 5211 5212 Collective on SNES 5213 5214 Input Parameters: 5215 + snes - iterative context obtained from SNESCreate() 5216 - linesearch - the linesearch object 5217 5218 Notes: 5219 Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 5220 to configure it using the API). 5221 5222 Level: developer 5223 5224 .keywords: SNES, set, linesearch 5225 .seealso: SNESGetLineSearch() 5226 @*/ 5227 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5228 { 5229 PetscErrorCode ierr; 5230 5231 PetscFunctionBegin; 5232 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5233 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 5234 PetscCheckSameComm(snes, 1, linesearch, 2); 5235 ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5236 ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5237 5238 snes->linesearch = linesearch; 5239 5240 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 5241 PetscFunctionReturn(0); 5242 } 5243 5244 /*@ 5245 SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 5246 or creates a default line search instance associated with the SNES and returns it. 5247 5248 Not Collective 5249 5250 Input Parameter: 5251 . snes - iterative context obtained from SNESCreate() 5252 5253 Output Parameter: 5254 . linesearch - linesearch context 5255 5256 Level: beginner 5257 5258 .keywords: SNES, get, linesearch 5259 .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 5260 @*/ 5261 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5262 { 5263 PetscErrorCode ierr; 5264 const char *optionsprefix; 5265 5266 PetscFunctionBegin; 5267 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5268 PetscValidPointer(linesearch, 2); 5269 if (!snes->linesearch) { 5270 ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 5271 ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5272 ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5273 ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 5274 ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 5275 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 5276 } 5277 *linesearch = snes->linesearch; 5278 PetscFunctionReturn(0); 5279 } 5280 5281 #if defined(PETSC_HAVE_MATLAB_ENGINE) 5282 #include <mex.h> 5283 5284 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 5285 5286 /* 5287 SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab(). 5288 5289 Collective on SNES 5290 5291 Input Parameters: 5292 + snes - the SNES context 5293 - x - input vector 5294 5295 Output Parameter: 5296 . y - function vector, as set by SNESSetFunction() 5297 5298 Notes: 5299 SNESComputeFunction() is typically used within nonlinear solvers 5300 implementations, so most users would not generally call this routine 5301 themselves. 5302 5303 Level: developer 5304 5305 .keywords: SNES, nonlinear, compute, function 5306 5307 .seealso: SNESSetFunction(), SNESGetFunction() 5308 */ 5309 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 5310 { 5311 PetscErrorCode ierr; 5312 SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5313 int nlhs = 1,nrhs = 5; 5314 mxArray *plhs[1],*prhs[5]; 5315 long long int lx = 0,ly = 0,ls = 0; 5316 5317 PetscFunctionBegin; 5318 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5319 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 5320 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 5321 PetscCheckSameComm(snes,1,x,2); 5322 PetscCheckSameComm(snes,1,y,3); 5323 5324 /* call Matlab function in ctx with arguments x and y */ 5325 5326 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5327 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5328 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 5329 prhs[0] = mxCreateDoubleScalar((double)ls); 5330 prhs[1] = mxCreateDoubleScalar((double)lx); 5331 prhs[2] = mxCreateDoubleScalar((double)ly); 5332 prhs[3] = mxCreateString(sctx->funcname); 5333 prhs[4] = sctx->ctx; 5334 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 5335 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5336 mxDestroyArray(prhs[0]); 5337 mxDestroyArray(prhs[1]); 5338 mxDestroyArray(prhs[2]); 5339 mxDestroyArray(prhs[3]); 5340 mxDestroyArray(plhs[0]); 5341 PetscFunctionReturn(0); 5342 } 5343 5344 /* 5345 SNESSetFunctionMatlab - Sets the function evaluation routine and function 5346 vector for use by the SNES routines in solving systems of nonlinear 5347 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 5348 5349 Logically Collective on SNES 5350 5351 Input Parameters: 5352 + snes - the SNES context 5353 . r - vector to store function value 5354 - f - function evaluation routine 5355 5356 Notes: 5357 The Newton-like methods typically solve linear systems of the form 5358 $ f'(x) x = -f(x), 5359 where f'(x) denotes the Jacobian matrix and f(x) is the function. 5360 5361 Level: beginner 5362 5363 Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5364 5365 .keywords: SNES, nonlinear, set, function 5366 5367 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5368 */ 5369 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx) 5370 { 5371 PetscErrorCode ierr; 5372 SNESMatlabContext *sctx; 5373 5374 PetscFunctionBegin; 5375 /* currently sctx is memory bleed */ 5376 ierr = PetscNew(&sctx);CHKERRQ(ierr); 5377 ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5378 /* 5379 This should work, but it doesn't 5380 sctx->ctx = ctx; 5381 mexMakeArrayPersistent(sctx->ctx); 5382 */ 5383 sctx->ctx = mxDuplicateArray(ctx); 5384 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 5385 PetscFunctionReturn(0); 5386 } 5387 5388 /* 5389 SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab(). 5390 5391 Collective on SNES 5392 5393 Input Parameters: 5394 + snes - the SNES context 5395 . x - input vector 5396 . A, B - the matrices 5397 - ctx - user context 5398 5399 Level: developer 5400 5401 .keywords: SNES, nonlinear, compute, function 5402 5403 .seealso: SNESSetFunction(), SNESGetFunction() 5404 @*/ 5405 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx) 5406 { 5407 PetscErrorCode ierr; 5408 SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5409 int nlhs = 2,nrhs = 6; 5410 mxArray *plhs[2],*prhs[6]; 5411 long long int lx = 0,lA = 0,ls = 0, lB = 0; 5412 5413 PetscFunctionBegin; 5414 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5415 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 5416 5417 /* call Matlab function in ctx with arguments x and y */ 5418 5419 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5420 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5421 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 5422 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 5423 prhs[0] = mxCreateDoubleScalar((double)ls); 5424 prhs[1] = mxCreateDoubleScalar((double)lx); 5425 prhs[2] = mxCreateDoubleScalar((double)lA); 5426 prhs[3] = mxCreateDoubleScalar((double)lB); 5427 prhs[4] = mxCreateString(sctx->funcname); 5428 prhs[5] = sctx->ctx; 5429 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 5430 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5431 mxDestroyArray(prhs[0]); 5432 mxDestroyArray(prhs[1]); 5433 mxDestroyArray(prhs[2]); 5434 mxDestroyArray(prhs[3]); 5435 mxDestroyArray(prhs[4]); 5436 mxDestroyArray(plhs[0]); 5437 mxDestroyArray(plhs[1]); 5438 PetscFunctionReturn(0); 5439 } 5440 5441 /* 5442 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 5443 vector for use by the SNES routines in solving systems of nonlinear 5444 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 5445 5446 Logically Collective on SNES 5447 5448 Input Parameters: 5449 + snes - the SNES context 5450 . A,B - Jacobian matrices 5451 . J - function evaluation routine 5452 - ctx - user context 5453 5454 Level: developer 5455 5456 Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5457 5458 .keywords: SNES, nonlinear, set, function 5459 5460 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J 5461 */ 5462 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx) 5463 { 5464 PetscErrorCode ierr; 5465 SNESMatlabContext *sctx; 5466 5467 PetscFunctionBegin; 5468 /* currently sctx is memory bleed */ 5469 ierr = PetscNew(&sctx);CHKERRQ(ierr); 5470 ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr); 5471 /* 5472 This should work, but it doesn't 5473 sctx->ctx = ctx; 5474 mexMakeArrayPersistent(sctx->ctx); 5475 */ 5476 sctx->ctx = mxDuplicateArray(ctx); 5477 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 5478 PetscFunctionReturn(0); 5479 } 5480 5481 /* 5482 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 5483 5484 Collective on SNES 5485 5486 .seealso: SNESSetFunction(), SNESGetFunction() 5487 @*/ 5488 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 5489 { 5490 PetscErrorCode ierr; 5491 SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5492 int nlhs = 1,nrhs = 6; 5493 mxArray *plhs[1],*prhs[6]; 5494 long long int lx = 0,ls = 0; 5495 Vec x = snes->vec_sol; 5496 5497 PetscFunctionBegin; 5498 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5499 5500 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5501 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5502 prhs[0] = mxCreateDoubleScalar((double)ls); 5503 prhs[1] = mxCreateDoubleScalar((double)it); 5504 prhs[2] = mxCreateDoubleScalar((double)fnorm); 5505 prhs[3] = mxCreateDoubleScalar((double)lx); 5506 prhs[4] = mxCreateString(sctx->funcname); 5507 prhs[5] = sctx->ctx; 5508 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 5509 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5510 mxDestroyArray(prhs[0]); 5511 mxDestroyArray(prhs[1]); 5512 mxDestroyArray(prhs[2]); 5513 mxDestroyArray(prhs[3]); 5514 mxDestroyArray(prhs[4]); 5515 mxDestroyArray(plhs[0]); 5516 PetscFunctionReturn(0); 5517 } 5518 5519 /* 5520 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 5521 5522 Level: developer 5523 5524 Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5525 5526 .keywords: SNES, nonlinear, set, function 5527 5528 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5529 */ 5530 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx) 5531 { 5532 PetscErrorCode ierr; 5533 SNESMatlabContext *sctx; 5534 5535 PetscFunctionBegin; 5536 /* currently sctx is memory bleed */ 5537 ierr = PetscNew(&sctx);CHKERRQ(ierr); 5538 ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5539 /* 5540 This should work, but it doesn't 5541 sctx->ctx = ctx; 5542 mexMakeArrayPersistent(sctx->ctx); 5543 */ 5544 sctx->ctx = mxDuplicateArray(ctx); 5545 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5546 PetscFunctionReturn(0); 5547 } 5548 5549 #endif 5550