Actual source code: convert.c


  2: #include <petsc/private/matimpl.h>

  4: /*
  5:   MatConvert_Basic - Converts from any input format to another format.
  6:   Does not do preallocation so in general will be slow
  7:  */
  8: PETSC_INTERN PetscErrorCode MatConvert_Basic(Mat mat, MatType newtype, MatReuse reuse, Mat *newmat)
  9: {
 10:   Mat                M;
 11:   const PetscScalar *vwork;
 12:   PetscInt           i, rstart, rend, nz;
 13:   const PetscInt    *cwork;
 14:   PetscBool          isSBAIJ;

 16:   if (!mat->ops->getrow) { /* missing get row, use matvecs */
 17:     MatConvert_Shell(mat, newtype, reuse, newmat);
 18:     return 0;
 19:   }
 20:   PetscObjectTypeCompare((PetscObject)mat, MATSEQSBAIJ, &isSBAIJ);
 21:   if (!isSBAIJ) PetscObjectTypeCompare((PetscObject)mat, MATMPISBAIJ, &isSBAIJ);

 24:   if (reuse == MAT_REUSE_MATRIX) {
 25:     M = *newmat;
 26:   } else {
 27:     PetscInt m, n, lm, ln;
 28:     MatGetSize(mat, &m, &n);
 29:     MatGetLocalSize(mat, &lm, &ln);
 30:     MatCreate(PetscObjectComm((PetscObject)mat), &M);
 31:     MatSetSizes(M, lm, ln, m, n);
 32:     MatSetBlockSizesFromMats(M, mat, mat);
 33:     MatSetType(M, newtype);
 34:     MatSetUp(M);

 36:     MatSetOption(M, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_FALSE);
 37:     MatSetOption(M, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
 38:     PetscObjectTypeCompare((PetscObject)M, MATSEQSBAIJ, &isSBAIJ);
 39:     if (!isSBAIJ) PetscObjectTypeCompare((PetscObject)M, MATMPISBAIJ, &isSBAIJ);
 40:     if (isSBAIJ) MatSetOption(M, MAT_IGNORE_LOWER_TRIANGULAR, PETSC_TRUE);
 41:   }

 43:   MatGetOwnershipRange(mat, &rstart, &rend);
 44:   for (i = rstart; i < rend; i++) {
 45:     MatGetRow(mat, i, &nz, &cwork, &vwork);
 46:     MatSetValues(M, 1, &i, nz, cwork, vwork, INSERT_VALUES);
 47:     MatRestoreRow(mat, i, &nz, &cwork, &vwork);
 48:   }
 49:   MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY);
 50:   MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY);

 52:   if (reuse == MAT_INPLACE_MATRIX) {
 53:     MatHeaderReplace(mat, &M);
 54:   } else {
 55:     *newmat = M;
 56:   }
 57:   return 0;
 58: }