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