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