Actual source code: shellcnv.c
2: #include <private/matimpl.h> /*I "petscmat.h" I*/
3: #include <private/vecimpl.h>
4:
7: PetscErrorCode MatConvert_Shell(Mat oldmat, const MatType newtype,MatReuse reuse,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 = ((PetscObject)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(PetscInt),&rows);
25: for (i=0; i<m; i++) {rows[i] = start + i;}
27: MatCreate(comm,&mat);
28: MatSetSizes(mat,m,M,M,M);
29: MatSetType(mat,MATSHELL);
30: MatSetBlockSize(mat,oldmat->rmap->bs);
32: for (i=0; i<M; i++) {
33: VecSet(in,zero);
34: VecSetValues(in,1,&i,&one,INSERT_VALUES);
35: VecAssemblyBegin(in);
36: VecAssemblyEnd(in);
38: MatMult(oldmat,in,out);
39:
40: VecGetArray(out,&array);
41: MatSetValues(mat,m,rows,1,&i,array,INSERT_VALUES);
42: VecRestoreArray(out,&array);
44: }
45: PetscFree(rows);
46: VecDestroy(&in);
47: VecDestroy(&out);
48: MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);
49: MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);
51: if (reuse == MAT_REUSE_MATRIX) {
52: MatHeaderReplace(oldmat,mat);
53: } else {
54: *newmat = mat;
55: }
56: return(0);
57: }