1 /* 2 User interface for the nonlinear solvers package. 3 */ 4 #if !defined(__PETSCSNES_H) 5 #define __PETSCSNES_H 6 #include "petscksp.h" 7 PETSC_EXTERN_CXX_BEGIN 8 9 /*S 10 SNES - Abstract PETSc object that manages all nonlinear solves 11 12 Level: beginner 13 14 Concepts: nonlinear solvers 15 16 .seealso: SNESCreate(), SNESSetType(), SNESType, TS, KSP, KSP, PC 17 S*/ 18 typedef struct _p_SNES* SNES; 19 20 /*E 21 SNESType - String with the name of a PETSc SNES method or the creation function 22 with an optional dynamic library name, for example 23 http://www.mcs.anl.gov/petsc/lib.a:mysnescreate() 24 25 Level: beginner 26 27 .seealso: SNESSetType(), SNES 28 E*/ 29 #define SNESType char* 30 #define SNESLS "ls" 31 #define SNESTR "tr" 32 #define SNESPYTHON "python" 33 #define SNESTEST "test" 34 #define SNESPICARD "picard" 35 #define SNESKSPONLY "ksponly" 36 #define SNESVI "vi" 37 #define SNESNGMRES "ngmres" 38 39 /* Logging support */ 40 extern PetscClassId SNES_CLASSID; 41 42 extern PetscErrorCode SNESInitializePackage(const char[]); 43 44 extern PetscErrorCode SNESCreate(MPI_Comm,SNES*); 45 extern PetscErrorCode SNESReset(SNES); 46 extern PetscErrorCode SNESDestroy(SNES*); 47 extern PetscErrorCode SNESSetType(SNES,const SNESType); 48 extern PetscErrorCode SNESMonitorSet(SNES,PetscErrorCode(*)(SNES,PetscInt,PetscReal,void*),void *,PetscErrorCode (*)(void**)); 49 extern PetscErrorCode SNESMonitorCancel(SNES); 50 extern PetscErrorCode SNESSetConvergenceHistory(SNES,PetscReal[],PetscInt[],PetscInt,PetscBool ); 51 extern PetscErrorCode SNESGetConvergenceHistory(SNES,PetscReal*[],PetscInt *[],PetscInt *); 52 extern PetscErrorCode SNESSetUp(SNES); 53 extern PetscErrorCode SNESSolve(SNES,Vec,Vec); 54 extern PetscErrorCode SNESSetErrorIfNotConverged(SNES,PetscBool ); 55 extern PetscErrorCode SNESGetErrorIfNotConverged(SNES,PetscBool *); 56 57 58 extern PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*)(SNES)); 59 60 extern PetscErrorCode SNESSetUpdate(SNES, PetscErrorCode (*)(SNES, PetscInt)); 61 extern PetscErrorCode SNESDefaultUpdate(SNES, PetscInt); 62 63 extern PetscFList SNESList; 64 extern PetscErrorCode SNESRegisterDestroy(void); 65 extern PetscErrorCode SNESRegisterAll(const char[]); 66 67 extern PetscErrorCode SNESRegister(const char[],const char[],const char[],PetscErrorCode (*)(SNES)); 68 69 /*MC 70 SNESRegisterDynamic - Adds a method to the nonlinear solver package. 71 72 Synopsis: 73 PetscErrorCode SNESRegisterDynamic(const char *name_solver,const char *path,const char *name_create,PetscErrorCode (*routine_create)(SNES)) 74 75 Not collective 76 77 Input Parameters: 78 + name_solver - name of a new user-defined solver 79 . path - path (either absolute or relative) the library containing this solver 80 . name_create - name of routine to create method context 81 - routine_create - routine to create method context 82 83 Notes: 84 SNESRegisterDynamic() may be called multiple times to add several user-defined solvers. 85 86 If dynamic libraries are used, then the fourth input argument (routine_create) 87 is ignored. 88 89 Environmental variables such as ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, 90 and others of the form ${any_environmental_variable} occuring in pathname will be 91 replaced with appropriate values. 92 93 Sample usage: 94 .vb 95 SNESRegisterDynamic("my_solver",/home/username/my_lib/lib/libg/solaris/mylib.a, 96 "MySolverCreate",MySolverCreate); 97 .ve 98 99 Then, your solver can be chosen with the procedural interface via 100 $ SNESSetType(snes,"my_solver") 101 or at runtime via the option 102 $ -snes_type my_solver 103 104 Level: advanced 105 106 Note: If your function is not being put into a shared library then use SNESRegister() instead 107 108 .keywords: SNES, nonlinear, register 109 110 .seealso: SNESRegisterAll(), SNESRegisterDestroy() 111 M*/ 112 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 113 #define SNESRegisterDynamic(a,b,c,d) SNESRegister(a,b,c,0) 114 #else 115 #define SNESRegisterDynamic(a,b,c,d) SNESRegister(a,b,c,d) 116 #endif 117 118 extern PetscErrorCode SNESGetKSP(SNES,KSP*); 119 extern PetscErrorCode SNESSetKSP(SNES,KSP); 120 extern PetscErrorCode SNESGetSolution(SNES,Vec*); 121 extern PetscErrorCode SNESGetSolutionUpdate(SNES,Vec*); 122 extern PetscErrorCode SNESGetRhs(SNES,Vec*); 123 extern PetscErrorCode SNESView(SNES,PetscViewer); 124 125 extern PetscErrorCode SNESSetOptionsPrefix(SNES,const char[]); 126 extern PetscErrorCode SNESAppendOptionsPrefix(SNES,const char[]); 127 extern PetscErrorCode SNESGetOptionsPrefix(SNES,const char*[]); 128 extern PetscErrorCode SNESSetFromOptions(SNES); 129 extern PetscErrorCode SNESDefaultGetWork(SNES,PetscInt); 130 131 extern PetscErrorCode MatCreateSNESMF(SNES,Mat*); 132 extern PetscErrorCode MatMFFDComputeJacobian(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 133 134 extern PetscErrorCode MatDAADSetSNES(Mat,SNES); 135 136 extern PetscErrorCode SNESGetType(SNES,const SNESType*); 137 extern PetscErrorCode SNESMonitorDefault(SNES,PetscInt,PetscReal,void *); 138 extern PetscErrorCode SNESMonitorRange(SNES,PetscInt,PetscReal,void *); 139 extern PetscErrorCode SNESMonitorRatio(SNES,PetscInt,PetscReal,void *); 140 extern PetscErrorCode SNESMonitorSetRatio(SNES,PetscViewer); 141 extern PetscErrorCode SNESMonitorSolution(SNES,PetscInt,PetscReal,void *); 142 extern PetscErrorCode SNESMonitorResidual(SNES,PetscInt,PetscReal,void *); 143 extern PetscErrorCode SNESMonitorSolutionUpdate(SNES,PetscInt,PetscReal,void *); 144 extern PetscErrorCode SNESMonitorDefaultShort(SNES,PetscInt,PetscReal,void *); 145 extern PetscErrorCode SNESSetTolerances(SNES,PetscReal,PetscReal,PetscReal,PetscInt,PetscInt); 146 extern PetscErrorCode SNESGetTolerances(SNES,PetscReal*,PetscReal*,PetscReal*,PetscInt*,PetscInt*); 147 extern PetscErrorCode SNESSetTrustRegionTolerance(SNES,PetscReal); 148 extern PetscErrorCode SNESGetFunctionNorm(SNES,PetscReal*); 149 extern PetscErrorCode SNESGetIterationNumber(SNES,PetscInt*); 150 151 extern PetscErrorCode SNESGetNonlinearStepFailures(SNES,PetscInt*); 152 extern PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES,PetscInt); 153 extern PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES,PetscInt*); 154 extern PetscErrorCode SNESGetNumberFunctionEvals(SNES,PetscInt*); 155 156 extern PetscErrorCode SNESSetLagPreconditioner(SNES,PetscInt); 157 extern PetscErrorCode SNESGetLagPreconditioner(SNES,PetscInt*); 158 extern PetscErrorCode SNESSetLagJacobian(SNES,PetscInt); 159 extern PetscErrorCode SNESGetLagJacobian(SNES,PetscInt*); 160 extern PetscErrorCode SNESSetGridSequence(SNES,PetscInt); 161 162 extern PetscErrorCode SNESGetLinearSolveIterations(SNES,PetscInt*); 163 extern PetscErrorCode SNESGetLinearSolveFailures(SNES,PetscInt*); 164 extern PetscErrorCode SNESSetMaxLinearSolveFailures(SNES,PetscInt); 165 extern PetscErrorCode SNESGetMaxLinearSolveFailures(SNES,PetscInt*); 166 167 extern PetscErrorCode SNESKSPSetUseEW(SNES,PetscBool ); 168 extern PetscErrorCode SNESKSPGetUseEW(SNES,PetscBool *); 169 extern PetscErrorCode SNESKSPSetParametersEW(SNES,PetscInt,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal); 170 extern PetscErrorCode SNESKSPGetParametersEW(SNES,PetscInt*,PetscReal*,PetscReal*,PetscReal*,PetscReal*,PetscReal*,PetscReal*); 171 172 extern PetscErrorCode SNESMonitorLGCreate(const char[],const char[],int,int,int,int,PetscDrawLG*); 173 extern PetscErrorCode SNESMonitorLG(SNES,PetscInt,PetscReal,void*); 174 extern PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG*); 175 extern PetscErrorCode SNESMonitorLGRangeCreate(const char[],const char[],int,int,int,int,PetscDrawLG*); 176 extern PetscErrorCode SNESMonitorLGRange(SNES,PetscInt,PetscReal,void*); 177 extern PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG*); 178 179 extern PetscErrorCode SNESSetApplicationContext(SNES,void *); 180 extern PetscErrorCode SNESGetApplicationContext(SNES,void *); 181 extern PetscErrorCode SNESSetComputeApplicationContext(SNES,PetscErrorCode (*)(SNES,void**),PetscErrorCode (*)(void**)); 182 183 extern PetscErrorCode SNESPythonSetType(SNES,const char[]); 184 185 extern PetscErrorCode SNESSetFunctionDomainError(SNES); 186 /*E 187 SNESConvergedReason - reason a SNES method was said to 188 have converged or diverged 189 190 Level: beginner 191 192 The two most common reasons for divergence are 193 $ 1) an incorrectly coded or computed Jacobian or 194 $ 2) failure or lack of convergence in the linear system (in this case we recommend 195 $ testing with -pc_type lu to eliminate the linear solver as the cause of the problem). 196 197 Diverged Reasons: 198 . SNES_DIVERGED_LOCAL_MIN - this can only occur when using the line-search variant of SNES. 199 The line search wants to minimize Q(alpha) = 1/2 || F(x + alpha s) ||^2_2 this occurs 200 at Q'(alpha) = s^T F'(x+alpha s)^T F(x+alpha s) = 0. If s is the Newton direction - F'(x)^(-1)F(x) then 201 you get Q'(alpha) = -F(x)^T F'(x)^(-1)^T F'(x+alpha s)F(x+alpha s); when alpha = 0 202 Q'(0) = - ||F(x)||^2_2 which is always NEGATIVE if F'(x) is invertible. This means the Newton 203 direction is a descent direction and the line search should succeed if alpha is small enough. 204 205 If F'(x) is NOT invertible AND F'(x)^T F(x) = 0 then Q'(0) = 0 and the Newton direction 206 is NOT a descent direction so the line search will fail. All one can do at this point 207 is change the initial guess and try again. 208 209 An alternative explanation: Newton's method can be regarded as replacing the function with 210 its linear approximation and minimizing the 2-norm of that. That is F(x+s) approx F(x) + F'(x)s 211 so we minimize || F(x) + F'(x) s ||^2_2; do this using Least Squares. If F'(x) is invertible then 212 s = - F'(x)^(-1)F(x) otherwise F'(x)^T F'(x) s = -F'(x)^T F(x). If F'(x)^T F(x) is NOT zero then there 213 exists a nontrival (that is F'(x)s != 0) solution to the equation and this direction is 214 s = - [F'(x)^T F'(x)]^(-1) F'(x)^T F(x) so Q'(0) = - F(x)^T F'(x) [F'(x)^T F'(x)]^(-T) F'(x)^T F(x) 215 = - (F'(x)^T F(x)) [F'(x)^T F'(x)]^(-T) (F'(x)^T F(x)). Since we are assuming (F'(x)^T F(x)) != 0 216 and F'(x)^T F'(x) has no negative eigenvalues Q'(0) < 0 so s is a descent direction and the line 217 search should succeed for small enough alpha. 218 219 Note that this RARELY happens in practice. Far more likely the linear system is not being solved 220 (well enough?) or the Jacobian is wrong. 221 222 SNES_DIVERGED_MAX_IT means that the solver reached the maximum number of iterations without satisfying any 223 convergence criteria. SNES_CONVERGED_ITS means that SNESSkipConverged() was chosen as the convergence test; 224 thus the usual convergence criteria have not been checked and may or may not be satisfied. 225 226 Developer Notes: this must match finclude/petscsnes.h 227 228 The string versions of these are in SNESConvergedReason, if you change any value here you must 229 also adjust that array. 230 231 Each reason has its own manual page. 232 233 .seealso: SNESSolve(), SNESGetConvergedReason(), KSPConvergedReason, SNESSetConvergenceTest() 234 E*/ 235 typedef enum {/* converged */ 236 SNES_CONVERGED_FNORM_ABS = 2, /* ||F|| < atol */ 237 SNES_CONVERGED_FNORM_RELATIVE = 3, /* ||F|| < rtol*||F_initial|| */ 238 SNES_CONVERGED_PNORM_RELATIVE = 4, /* Newton computed step size small; || delta x || < stol */ 239 SNES_CONVERGED_ITS = 5, /* maximum iterations reached */ 240 SNES_CONVERGED_TR_DELTA = 7, 241 /* diverged */ 242 SNES_DIVERGED_FUNCTION_DOMAIN = -1, /* the new x location passed the function is not in the domain of F */ 243 SNES_DIVERGED_FUNCTION_COUNT = -2, 244 SNES_DIVERGED_LINEAR_SOLVE = -3, /* the linear solve failed */ 245 SNES_DIVERGED_FNORM_NAN = -4, 246 SNES_DIVERGED_MAX_IT = -5, 247 SNES_DIVERGED_LINE_SEARCH = -6, /* the line search failed */ 248 SNES_DIVERGED_LOCAL_MIN = -8, /* || J^T b || is small, implies converged to local minimum of F() */ 249 SNES_CONVERGED_ITERATING = 0} SNESConvergedReason; 250 extern const char *const*SNESConvergedReasons; 251 252 /*MC 253 SNES_CONVERGED_FNORM_ABS - 2-norm(F) <= abstol 254 255 Level: beginner 256 257 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 258 259 M*/ 260 261 /*MC 262 SNES_CONVERGED_FNORM_RELATIVE - 2-norm(F) <= rtol*2-norm(F(x_0)) where x_0 is the initial guess 263 264 Level: beginner 265 266 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 267 268 M*/ 269 270 /*MC 271 SNES_CONVERGED_PNORM_RELATIVE - The 2-norm of the last step <= stol * 2-norm(x) where x is the current 272 solution and stol is the 4th argument to SNESSetTolerances() 273 274 Level: beginner 275 276 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 277 278 M*/ 279 280 /*MC 281 SNES_DIVERGED_FUNCTION_COUNT - The user provided function has been called more times then the final 282 argument to SNESSetTolerances() 283 284 Level: beginner 285 286 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 287 288 M*/ 289 290 /*MC 291 SNES_DIVERGED_FNORM_NAN - the 2-norm of the current function evaluation is not-a-number (NaN), this 292 is usually caused by a division of 0 by 0. 293 294 Level: beginner 295 296 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 297 298 M*/ 299 300 /*MC 301 SNES_DIVERGED_MAX_IT - SNESSolve() has reached the maximum number of iterations requested 302 303 Level: beginner 304 305 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 306 307 M*/ 308 309 /*MC 310 SNES_DIVERGED_LINE_SEARCH - The line search has failed. This only occurs for a SNESType of SNESLS 311 312 Level: beginner 313 314 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 315 316 M*/ 317 318 /*MC 319 SNES_DIVERGED_LOCAL_MIN - the algorithm seems to have stagnated at a local minimum that is not zero. 320 See the manual page for SNESConvergedReason for more details 321 322 Level: beginner 323 324 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 325 326 M*/ 327 328 /*MC 329 SNES_CONERGED_ITERATING - this only occurs if SNESGetConvergedReason() is called during the SNESSolve() 330 331 Level: beginner 332 333 .seealso: SNESSolve(), SNESGetConvergedReason(), SNESConvergedReason, SNESSetTolerances() 334 335 M*/ 336 337 extern PetscErrorCode SNESSetConvergenceTest(SNES,PetscErrorCode (*)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void*,PetscErrorCode (*)(void*)); 338 extern PetscErrorCode SNESDefaultConverged(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*); 339 extern PetscErrorCode SNESSkipConverged(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*); 340 extern PetscErrorCode SNESGetConvergedReason(SNES,SNESConvergedReason*); 341 342 extern PetscErrorCode SNESDAFormFunction(SNES,Vec,Vec,void*); 343 extern PetscErrorCode SNESDAComputeJacobianWithAdic(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 344 extern PetscErrorCode SNESDAComputeJacobianWithAdifor(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 345 extern PetscErrorCode SNESDAComputeJacobian(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 346 347 extern PetscErrorCode SNESMeshFormFunction(SNES,Vec,Vec,void*); 348 extern PetscErrorCode SNESMeshFormJacobian(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 349 350 /* --------- Solving systems of nonlinear equations --------------- */ 351 typedef PetscErrorCode (*SNESFunction)(SNES,Vec,Vec,void*); 352 typedef PetscErrorCode (*SNESJacobian)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 353 extern PetscErrorCode SNESSetFunction(SNES,Vec,SNESFunction,void*); 354 extern PetscErrorCode SNESGetFunction(SNES,Vec*,SNESFunction*,void**); 355 extern PetscErrorCode SNESComputeFunction(SNES,Vec,Vec); 356 extern PetscErrorCode SNESSetJacobian(SNES,Mat,Mat,SNESJacobian,void*); 357 extern PetscErrorCode SNESGetJacobian(SNES,Mat*,Mat*,SNESJacobian*,void**); 358 extern PetscErrorCode SNESDefaultComputeJacobian(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 359 extern PetscErrorCode SNESDefaultComputeJacobianColor(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 360 extern PetscErrorCode SNESSetComputeInitialGuess(SNES,PetscErrorCode (*)(SNES,Vec,void*),void*); 361 362 /* --------- Routines specifically for line search methods --------------- */ 363 extern PetscErrorCode SNESLineSearchSet(SNES,PetscErrorCode(*)(SNES,void*,Vec,Vec,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal*,PetscReal*,PetscBool *),void*); 364 extern PetscErrorCode SNESLineSearchNo(SNES,void*,Vec,Vec,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal*,PetscReal*,PetscBool *); 365 extern PetscErrorCode SNESLineSearchNoNorms(SNES,void*,Vec,Vec,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal*,PetscReal*,PetscBool *); 366 extern PetscErrorCode SNESLineSearchCubic(SNES,void*,Vec,Vec,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal*,PetscReal*,PetscBool *); 367 extern PetscErrorCode SNESLineSearchQuadratic(SNES,void*,Vec,Vec,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal*,PetscReal*,PetscBool *); 368 369 extern PetscErrorCode SNESLineSearchSetPostCheck(SNES,PetscErrorCode(*)(SNES,Vec,Vec,Vec,void*,PetscBool *,PetscBool *),void*); 370 extern PetscErrorCode SNESLineSearchSetPreCheck(SNES,PetscErrorCode(*)(SNES,Vec,Vec,void*,PetscBool *),void*); 371 extern PetscErrorCode SNESLineSearchSetParams(SNES,PetscReal,PetscReal,PetscReal); 372 extern PetscErrorCode SNESLineSearchGetParams(SNES,PetscReal*,PetscReal*,PetscReal*); 373 extern PetscErrorCode SNESLineSearchSetMonitor(SNES,PetscBool ); 374 375 /* Routines for VI solver */ 376 extern PetscErrorCode SNESVISetVariableBounds(SNES,Vec,Vec); 377 extern PetscErrorCode SNESVISetComputeVariableBounds(SNES, PetscErrorCode (*)(SNES,Vec,Vec)); 378 extern PetscErrorCode SNESVIGetInactiveSet(SNES,IS*); 379 extern PetscErrorCode SNESVISetRedundancyCheck(SNES,PetscErrorCode(*)(SNES,IS,IS*,void*),void*); 380 #define SNES_VI_INF 1.0e20 381 #define SNES_VI_NINF -1.0e20 382 383 extern PetscErrorCode SNESTestLocalMin(SNES); 384 385 /* Should this routine be private? */ 386 extern PetscErrorCode SNESComputeJacobian(SNES,Vec,Mat*,Mat*,MatStructure*); 387 388 extern PetscErrorCode SNESSetDM(SNES,DM); 389 extern PetscErrorCode SNESGetDM(SNES,DM*); 390 extern PetscErrorCode SNESSetPC(SNES,SNES); 391 extern PetscErrorCode SNESGetPC(SNES,SNES*); 392 393 /* Routines for Multiblock solver */ 394 PetscErrorCode SNESMultiblockSetFields(SNES, const char [], PetscInt, const PetscInt *); 395 PetscErrorCode SNESMultiblockSetIS(SNES, const char [], IS); 396 PetscErrorCode SNESMultiblockSetBlockSize(SNES, PetscInt); 397 PetscErrorCode SNESMultiblockSetType(SNES, PCCompositeType); 398 399 PETSC_EXTERN_CXX_END 400 #endif 401