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