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