1af0996ceSBarry Smith #include <petsc/private/matimpl.h> 28b6375c0SLois Curfman McInnes 38b6375c0SLois Curfman McInnes /* 48af18dd8SStefano Zampini MatConvert_Basic - Converts from any input format to another format. 5273d9f13SBarry Smith Does not do preallocation so in general will be slow 68b6375c0SLois Curfman McInnes */ 7239f794eSPierre Jolivet PetscErrorCode MatConvert_Basic(Mat mat, MatType newtype, MatReuse reuse, Mat *newmat) 8d71ae5a4SJacob Faibussowitsch { 9676c34cdSKris Buschelman Mat M; 10b3cc6726SBarry Smith const PetscScalar *vwork; 112c0366f6SLisandro Dalcin PetscInt i, rstart, rend, nz; 12c1ac3661SBarry Smith const PetscInt *cwork; 1398e916f6SBarry Smith PetscBool isSBAIJ; 1425cdf11fSBarry Smith 153a40ed3dSBarry Smith PetscFunctionBegin; 168af18dd8SStefano Zampini if (!mat->ops->getrow) { /* missing get row, use matvecs */ 179566063dSJacob Faibussowitsch PetscCall(MatConvert_Shell(mat, newtype, reuse, newmat)); 183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 198af18dd8SStefano Zampini } 209566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)mat, MATSEQSBAIJ, &isSBAIJ)); 2148a46eb9SPierre Jolivet if (!isSBAIJ) PetscCall(PetscObjectTypeCompare((PetscObject)mat, MATMPISBAIJ, &isSBAIJ)); 2228b400f6SJacob Faibussowitsch PetscCheck(!isSBAIJ, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Cannot convert from SBAIJ matrix since cannot obtain entire rows of matrix"); 2398e916f6SBarry Smith 242c0366f6SLisandro Dalcin if (reuse == MAT_REUSE_MATRIX) { 252c0366f6SLisandro Dalcin M = *newmat; 262c0366f6SLisandro Dalcin } else { 272c0366f6SLisandro Dalcin PetscInt m, n, lm, ln; 289566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &m, &n)); 299566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &lm, &ln)); 309566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &M)); 319566063dSJacob Faibussowitsch PetscCall(MatSetSizes(M, lm, ln, m, n)); 329566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(M, mat, mat)); 339566063dSJacob Faibussowitsch PetscCall(MatSetType(M, newtype)); 349566063dSJacob Faibussowitsch PetscCall(MatSetUp(M)); 352c0366f6SLisandro Dalcin 369566063dSJacob Faibussowitsch PetscCall(MatSetOption(M, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_FALSE)); 379566063dSJacob Faibussowitsch PetscCall(MatSetOption(M, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 38*7bccdc57SPierre Jolivet PetscCall(MatSetOption(M, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); 399566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)M, MATSEQSBAIJ, &isSBAIJ)); 4048a46eb9SPierre Jolivet if (!isSBAIJ) PetscCall(PetscObjectTypeCompare((PetscObject)M, MATMPISBAIJ, &isSBAIJ)); 411baa6e33SBarry Smith if (isSBAIJ) PetscCall(MatSetOption(M, MAT_IGNORE_LOWER_TRIANGULAR, PETSC_TRUE)); 422c0366f6SLisandro Dalcin } 431a0cae60SJed Brown 449566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(mat, &rstart, &rend)); 458b6375c0SLois Curfman McInnes for (i = rstart; i < rend; i++) { 469566063dSJacob Faibussowitsch PetscCall(MatGetRow(mat, i, &nz, &cwork, &vwork)); 479566063dSJacob Faibussowitsch PetscCall(MatSetValues(M, 1, &i, nz, cwork, vwork, INSERT_VALUES)); 489566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(mat, i, &nz, &cwork, &vwork)); 498b6375c0SLois Curfman McInnes } 509566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY)); 519566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY)); 52*7bccdc57SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) PetscCall(MatSetOption(M, MAT_NO_OFF_PROC_ENTRIES, PETSC_FALSE)); 53676c34cdSKris Buschelman 54511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 559566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(mat, &M)); 56c3d102feSKris Buschelman } else { 5718f87311SHong Zhang *newmat = M; 58c3d102feSKris Buschelman } 593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 608b6375c0SLois Curfman McInnes } 61