When solving a system of nonlinear equations, the user must provide
a vector, f, for storing the function of
Equation (3
), as well as a routine that evaluates this
function at the vector x. This information should be set with
the command
ierr = SNESSetFunction(SNES snes,Vec f, int (*FormFunction)(SNES snes,Vec x,Vec f,void *ctx),void *ctx);The argument ctx is an optional user-defined context, which can store any private, application-specific data required by the function evaluation routine; PETSC_NULL should be used if such information is not needed. In C and C++, a user-defined context is merely a structure in which various objects can be stashed; in Fortran a user context can be an integer array that contains both parameters and pointers to PETSc objects. ${}PETSC_DIR/src/snes/examples/tutorials/ex5.c and ${}PETSC_DIR/src/snes/examples/ex5f.F give examples of user-defined application contexts in C and Fortran, respectively.
The user must also specify a routine to form some approximation of the
Jacobian matrix, A, at the current iterate, x,
as is typically done with
ierr = SNESSetJacobian(SNES snes,Mat A,Mat B,int (*FormJacobian)(SNES snes,Vec x, Mat *A,Mat *B,MatStructure *flag,void *ctx),void *ctx);The arguments of the routine FormJacobian() are the current iterate, x; the Jacobian matrix, A; the preconditioner matrix, B (which is usually the same as A); a flag indicating information about the preconditioner matrix structure; and an optional user-defined Jacobian context, ctx, for application-specific data. The options for flag are identical to those for the flag of SLESSetOperators(), discussed in Section Using SLES . Note that the SNES solvers are all data-structure neutral, so the full range of PETSc matrix formats (including ``matrix-free'' methods) can be used. Chapter Matrices discusses information regarding available matrix formats and options, while Section Matrix-Free Methods focuses on matrix-free methods in SNES. We briefly touch on a few details of matrix usage that are particularly important for efficient use of the nonlinear solvers.
During successive calls to FormJacobian(), the user can either insert new matrix contexts or reuse old ones, depending on the application requirements. For many sparse matrix formats, reusing the old space (and merely changing the matrix elements) is more efficient; however, if the matrix structure completely changes, creating an entirely new matrix context may be preferable. Upon subsequent calls to the FormJacobian() routine, the user may wish to reinitialize the matrix entries to zero by calling MatZeroEntries(). See Section Other Matrix Operations for details on the reuse of the matrix context.
If the preconditioning matrix retains identical nonzero structure during successive nonlinear iterations, setting the parameter, flag, in the FormJacobian() routine to be SAME_NONZERO_PATTERN and reusing the matrix context can save considerable overhead. For example, when one is using a parallel preconditioner such as incomplete factorization in solving the linearized Newton systems for such problems, matrix colorings and communication patterns can be determined a single time and then reused repeatedly throughout the solution process. In addition, if using different matrices for the actual Jacobian and the preconditioner, the user can hold the preconditioner matrix fixed for multiple iterations by setting flag to SAME_PRECONDITIONER. See the discussion of SLESSetOperators() in Section Using SLES for details.
The directory ${}PETSC_DIR/src/snes/examples/tutorials provides a variety of examples.