Some people like to use matrix-free methods, which do not require
explicit storage of the matrix, for the numerical solution of partial
differential equations. To support matrix-free methods in PETSc, one
can use the following command to create a Mat structure without
ever actually generating the matrix:
ierr = MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *mat);Here M and N are the global matrix dimensions (rows and columns), m and n are the local matrix dimensions, and ctx is a pointer to data needed by any user-defined shell matrix operations; the manual page has additional details about these parameters. Most matrix-free algorithms require only the application of the linear operator to a vector. To provide this action, the user must write a routine with the calling sequence
ierr = UserMult(Mat mat,Vec x,Vec y);and then associate it with the matrix, mat, by using the command
ierr = MatShellSetOperation(Mat mat,MatOperation MATOP_MULT, (void *) int (*UserMult)(Mat,Vec,Vec));Here MATOP_MULT is the name of the operation for matrix-vector multiplication. Within each user-defined routine (such as UserMult()), the user should call MatShellGetContext() to obtain the user-defined context, ctx, that was set by MatCreateShell(). This shell matrix can be used with the iterative linear equation solvers discussed in the following chapters.
The routine MatShellSetOperation() can be used to set any other
matrix operations as well. The file
${}PETSC_DIR/include/mat.h provides a complete list of matrix
operations, which have the form MATOP_<OPERATION>, where
<OPERATION> is the name (in all capital letters) of the user
interface routine (for example, MatMult()
MATOP_MULT). All
user-provided functions have the same calling sequence as the
usual matrix interface routines, since the user-defined functions are
intended to be accessed through interface, e.g.,
MatMult(Mat,Vec,Vec)
UserMult(Mat,Vec,Vec).
The final argument for MatShellSetOperation() needs to be cast
to a void *, since the final argument could (depending on the
MatOperation be a variety of different functions.
Note that MatShellSetOperation() can also be used as a ``backdoor'' means of introducing user-defined changes in matrix operations for other storage formats (for example, to override the default LU factorization routine supplied within PETSc for the MATSEQAIJ format). However, we urge anyone who introduces such changes to use caution, since it would be very easy to accidentally create a bug in the new routine that could affect other routines as well.
See also Section Matrix-Free Methods for details on one set of helpful utilities for using the matrix-free approach for nonlinear solvers.