5.4. Other Matrix Operations

Up: Contents Next: Partitioning Previous: Matrix-Free Matrices

In many iterative calculations (for instance, in a nonlinear equations solver), it is important for efficiency purposes to reuse the nonzero structure of a matrix, rather than determining it anew every time the matrix is generated. To retain a given matrix but reinitialize its contents, one can employ

   ierr = MatZeroEntries(Mat A); 
This routine will zero the matrix entries in the data structure but keep all the data that indicates where the nonzeros are located. In this way a new matrix assembly will be much less expensive, since no memory allocations or copies will be needed. Of course, one can also explicitly set selected matrix elements to zero by calling MatSetValues().

In the numerical solution of elliptic partial differential equations, it can be cumbersome to deal with Dirichlet boundary conditions. In particular, one would like to assemble the matrix without regard to boundary conditions and then at the end apply the Dirichlet boundary conditions. In numerical analysis classes this process is usually presented as moving the known boundary conditions to the right-hand side and then solving a smaller linear system for the interior unknowns. Unfortunately, implementing this requires extracting a large submatrix from the original matrix and creating its corresponding data structures. This process can be expensive in terms of both time and memory.

One simple way to deal with this difficulty is to replace those rows in the matrix associated with known boundary conditions, by rows of the identity matrix (or some scaling of it). This action can be done with the command

   ierr = MatZeroRows(Mat A,IS rows,Scalar *diag_value); 
For sparse matrices this removes the data structures for certain rows of the matrix. If the pointer diag_value is PETSC_NULL, it even removes the diagonal entry. If the pointer is not null, it uses that given value at the pointer location in the diagonal entry of the eliminated rows.

Another matrix routine of interest is

   ierr = MatConvert(Mat mat,MatType newtype,Mat *M) 
which converts the matrix mat to new matrix, M, that has either the same or different format. Set newtype to MATSAME to copy the matrix, keeping the same matrix format. See ${}PETSC_DIR/include/mat.h for other available matrix types; standard ones are MATSEQDENSE, MATSEQAIJ, MATMPIAIJ, MATMPIROWBS, MATSEQBDIAG, MATMPIBDIAG, MATSEQBAIJ, and MATMPIBAIJ.

In certain applications it may be necessary for application codes to directly access elements of a matrix. This may be done by using the the command

   ierr = MatGetRow(Mat A,int row, int *ncols,int **cols,Scalar **vals); 
The argument ncols returns the number of nonzeros in that row, while cols and vals returns the column indices (with indices starting at zero) and values in the row. If only the column indices are needed (and not the corresponding matrix elements), one can use PETSC_NULL for the vals argument. Similarly, one can use PETSC_NULL for the cols argument. The user can only examine the values extracted with MatGetRow(); the values cannot be altered. To change the matrix entries, one must use MatSetValues().

Once the user has finished using a row, he or she must call

   ierr = MatRestoreRow(Mat A,int row,int *ncols,int **cols,Scalar **vals); 
to free any space that was allocated during the call to MatGetRow().


Up: Contents Next: Partitioning Previous: Matrix-Free Matrices