Actual source code: shellcnv.c
petsc-3.11.4 2019-09-28
2: #include <petsc/private/matimpl.h>
4: PetscErrorCode MatConvert_Shell(Mat oldmat, MatType newtype,MatReuse reuse,Mat *newmat)
5: {
6: Mat mat;
7: Vec in,out;
9: PetscInt i,m,n,M,N,*rows,start;
10: MPI_Comm comm;
11: PetscScalar *array;
14: PetscObjectGetComm((PetscObject)oldmat,&comm);
16: MatGetOwnershipRange(oldmat,&start,NULL);
17: MatCreateVecs(oldmat,&in,&out);
18: MatGetLocalSize(oldmat,&m,&n);
19: MatGetSize(oldmat,&M,&N);
20: PetscMalloc1(m,&rows);
21: for (i=0; i<m; i++) rows[i] = start + i;
23: MatCreate(comm,&mat);
24: MatSetSizes(mat,m,n,M,N);
25: MatSetType(mat,newtype);
26: MatSetBlockSizesFromMats(mat,oldmat,oldmat);
27: MatSetUp(mat);
28: VecSetOption(in,VEC_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);
30: for (i=0; i<N; i++) {
31: VecZeroEntries(in);
32: VecSetValue(in,i,1.,INSERT_VALUES);
33: VecAssemblyBegin(in);
34: VecAssemblyEnd(in);
36: MatMult(oldmat,in,out);
38: VecGetArray(out,&array);
39: MatSetValues(mat,m,rows,1,&i,array,INSERT_VALUES);
40: VecRestoreArray(out,&array);
42: }
43: PetscFree(rows);
44: VecDestroy(&in);
45: VecDestroy(&out);
46: MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);
47: MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);
49: if (reuse == MAT_INPLACE_MATRIX) {
50: MatHeaderReplace(oldmat,&mat);
51: } else {
52: *newmat = mat;
53: }
54: return(0);
55: }