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: }