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