#include /* MatConvert_Basic - Converts from any input format to another format. Does not do preallocation so in general will be slow */ PETSC_INTERN PetscErrorCode MatConvert_Basic(Mat mat,MatType newtype,MatReuse reuse,Mat *newmat) { Mat M; const PetscScalar *vwork; PetscInt i,rstart,rend,nz; const PetscInt *cwork; PetscBool isSBAIJ; PetscFunctionBegin; if (!mat->ops->getrow) { /* missing get row, use matvecs */ PetscCall(MatConvert_Shell(mat,newtype,reuse,newmat)); PetscFunctionReturn(0); } PetscCall(PetscObjectTypeCompare((PetscObject)mat,MATSEQSBAIJ,&isSBAIJ)); if (!isSBAIJ) { PetscCall(PetscObjectTypeCompare((PetscObject)mat,MATMPISBAIJ,&isSBAIJ)); } PetscCheck(!isSBAIJ,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot convert from SBAIJ matrix since cannot obtain entire rows of matrix"); if (reuse == MAT_REUSE_MATRIX) { M = *newmat; } else { PetscInt m,n,lm,ln; PetscCall(MatGetSize(mat,&m,&n)); PetscCall(MatGetLocalSize(mat,&lm,&ln)); PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&M)); PetscCall(MatSetSizes(M,lm,ln,m,n)); PetscCall(MatSetBlockSizesFromMats(M,mat,mat)); PetscCall(MatSetType(M,newtype)); PetscCall(MatSetUp(M)); PetscCall(MatSetOption(M,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE)); PetscCall(MatSetOption(M,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE)); PetscCall(PetscObjectTypeCompare((PetscObject)M,MATSEQSBAIJ,&isSBAIJ)); if (!isSBAIJ) { PetscCall(PetscObjectTypeCompare((PetscObject)M,MATMPISBAIJ,&isSBAIJ)); } if (isSBAIJ) PetscCall(MatSetOption(M,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE)); } PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); for (i=rstart; i