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