Actual source code: shellcnv.c
2: #include src/mat/matimpl.h
3: #include vecimpl.h
4:
7: PetscErrorCode MatConvert_Shell(Mat oldmat,const MatType newtype,Mat *newmat)
8: {
9: Mat mat;
10: Vec in,out;
12: PetscInt i,M,m,*rows,start,end;
13: MPI_Comm comm;
14: PetscScalar *array,zero = 0.0,one = 1.0;
17: comm = oldmat->comm;
19: MatGetOwnershipRange(oldmat,&start,&end);
20: VecCreateMPI(comm,end-start,PETSC_DECIDE,&in);
21: VecDuplicate(in,&out);
22: VecGetSize(in,&M);
23: VecGetLocalSize(in,&m);
24: PetscMalloc((m+1)*sizeof(int),&rows);
25: for (i=0; i<m; i++) {rows[i] = start + i;}
27: MatCreate(comm,m,M,M,M,&mat);
28: MatSetType(mat,newtype);
29: MatSetBlockSize(mat,oldmat->bs);
31: for (i=0; i<M; i++) {
32: VecSet(&zero,in);
33: VecSetValues(in,1,&i,&one,INSERT_VALUES);
34: VecAssemblyBegin(in);
35: VecAssemblyEnd(in);
37: MatMult(oldmat,in,out);
38:
39: VecGetArray(out,&array);
40: MatSetValues(mat,m,rows,1,&i,array,INSERT_VALUES);
41: VecRestoreArray(out,&array);
43: }
44: PetscFree(rows);
45: VecDestroy(in);
46: VecDestroy(out);
47: MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);
48: MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);
50: /* Fake support for "inplace" convert. */
51: if (*newmat == oldmat) {
52: MatDestroy(oldmat);
53: }
54: *newmat = mat;
55: return(0);
56: }