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().