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