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