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