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