5.1. Creating and Assembling Matrices

Up: Contents Next: Sparse Matrices Previous: Matrices

The simplest routine for forming a PETSc matrix, A, is

   ierr = MatCreate(MPI_Comm comm,int M,int N,Mat *A) 
This routine generates a sequential matrix when running on one processor and a parallel matrix for two or more processors; the particular matrix format is set by the user via options database commands. The user specifies only the global matrix dimensions, given by M and N, while PETSc determines the appropriate local dimensions and completely controls memory allocation. This routine facilitates switching among various matrix types, for example, to determine the format that is most efficient for a certain application. By default, MatCreate() employs the sparse AIJ format, which is discussed in detail Section Sparse Matrices . See the manual pages for further information about available matrix formats.

To insert or add entries to a matrix, one can call a variant of MatSetValues, either

   ierr = MatSetValues(Mat A,int m,int *im,int n,int *in,Scalar *values,INSERT_VALUES); 
or
   ierr = MatSetValues(Mat A,int m,int *im,int n,int *in,Scalar *values,ADD_VALUES); 
This routine inserts or adds a logically dense subblock of dimension m*n into the matrix. The integer indices im and in, respectively, indicate the global row and column numbers to be inserted. MatSetValues() uses the standard C convention, where the row and column matrix indices begin with zero regardless of the storage format employed. The array values is logically two-dimensional, containing the values that are to be inserted. By default the values are given in row major order, which is the opposite of the Fortran convention. To allow the insertion of values in column major order, one can call the command
   ierr = MatSetOption(Mat A,MAT_COLUMN_ORIENTED); 
Warning: Several of the sparse implementations do not currently support the column-oriented option!

This notation should not be a mystery to anyone. For example, to insert one matrix into another when using Matlab, one uses the command A(im,in) = B; where im and in contain the indices for the rows and columns. This action is identical to the calls above to MatSetValues().

When using the block compressed sparse row matrix format ( MATSEQBAIJ or MATMPIBAIJ), one can insert elements more efficiently using the block variant, MatSetValuesBlocked().

The function MatSetOption() accepts several other inputs; see the manual page for details. We discuss two of these options, which are related to the efficiency of the assembly process. To indicate to PETSc that the row ( im) or column ( in) indices set with MatSetValues() are sorted, one uses the command

   ierr = MatSetOption(Mat A,MAT_ROWS_SORTED); 
or
   ierr = MatSetOption(Mat A,MAT_COLUMNS_SORTED); 
Note that these flags indicate the format of the data passed in with MatSetValues(); they do not have anything to do with how the sparse matrix data is stored internally in PETSc.

After the matrix elements have been inserted or added into the matrix, they must be processed before they can be used. The routines for matrix processing are

   ierr = MatAssemblyBegin(Mat A,MAT_FINAL_ASSEMBLY); 
   ierr = MatAssemblyEnd(Mat A,MAT_FINAL_ASSEMBLY); 
By placing other code between these two calls, the user can perform computations while messages are in transition. Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES options cannot be mixed without intervening calls to the assembly routines. For such intermediate assembly calls the second routine argument typically should be MAT_FLUSH_ASSEMBLY, which omits some of the work of the full assembly process. MAT_FINAL_ASSEMBLY is required only in the last matrix assembly before a matrix is used.

Even though one may insert values into PETSc matrices without regard to which processor eventually stores them, for efficiency reasons we usually recommend generating most entries on the processor where they are destined to be stored. To help the application programmer with this task for matrices that are distributed across the processors by ranges, the routine

   ierr = MatGetOwnershipRange(Mat A,int *first_row,int *last_row); 
informs the user that all rows from first_row to last_row-1 will be stored on the local processor.

In the sparse matrix implementations, once the assembly routines have been called, the matrices are compressed and can be used for matrix-vector multiplication, etc. Inserting new values into the matrix at this point will be expensive, since it requires copies and possible memory allocation. Thus, whenever possible one should completely set the values in the matrices before calling the final assembly routines.

If one wishes to repeatedly assemble matrices that retain the same nonzero pattern (such as within a nonlinear or time-dependent problem), the option

   ierr = MatSetOption(Mat mat,MAT_NO_NEW_NONZERO_LOCATIONS); 
should be specified after the first matrix has been fully assembled. This option ensures that certain data structures and communication information will be reused (instead of regenerated) during successive steps, thereby increasing efficiency. See ${}PETSC_DIR/src/sles/examples/tutorials/ex5.c for a simple example of solving two linear systems that use the same matrix data structure.


Up: Contents Next: Sparse Matrices Previous: Matrices