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