EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatConvert_MPIAIJ_MPISBAIJ" PetscErrorCode MatConvert_MPIAIJ_MPISBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat M; Mat_MPIAIJ *mpimat = (Mat_MPIAIJ*)A->data; Mat_SeqAIJ *Aa = (Mat_SeqAIJ*)mpimat->A->data,*Ba = (Mat_SeqAIJ*)mpimat->B->data; PetscInt *d_nnz,*o_nnz; PetscInt i,j,nz; PetscInt m,n,lm,ln; PetscInt rstart,rend; const PetscScalar *vwork; const PetscInt *cwork; PetscFunctionBegin; if (!A->symmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_USER,"Matrix must be symmetric. Call MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)"); ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&lm,&ln);CHKERRQ(ierr); ierr = PetscMalloc2(lm,PetscInt,&d_nnz,lm,PetscInt,&o_nnz);CHKERRQ(ierr); ierr = MatMarkDiagonal_SeqAIJ(mpimat->A);CHKERRQ(ierr); for (i=0;i<lm;i++){ d_nnz[i] = Aa->i[i+1] - Aa->diag[i]; o_nnz[i] = Ba->i[i+1] - Ba->i[i]; } ierr = MatCreate(((PetscObject)A)->comm,&M);CHKERRQ(ierr); ierr = MatSetSizes(M,lm,ln,m,n);CHKERRQ(ierr); ierr = MatSetType(M,MATMPISBAIJ);CHKERRQ(ierr); ierr = MatSeqSBAIJSetPreallocation(M,1,0,d_nnz);CHKERRQ(ierr); ierr = MatMPISBAIJSetPreallocation(M,1,0,d_nnz,0,o_nnz);CHKERRQ(ierr); ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); for (i=rstart;i<rend;i++){ ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); j = 0; while (cwork[j] < i){ j++; nz--;} ierr = MatSetValues(M,1,&i,nz,cwork+j,vwork+j,INSERT_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); } ierr = MatAssemblyBegin(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (reuse == MAT_REUSE_MATRIX) { ierr = MatHeaderReplace(A,M);CHKERRQ(ierr); } else { *newmat = M; } PetscFunctionReturn(0); }
static PetscErrorCode MatWrapCholmod_seqaij(Mat A,PetscBool values,cholmod_sparse *C,PetscBool *aijalloc) { Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; const PetscInt *ai = aij->i,*aj = aij->j,*adiag; const MatScalar *aa = aij->a; PetscInt m = A->rmap->n,i,j,k,nz,*ci,*cj; PetscScalar *ca; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); adiag = aij->diag; for (i=0,nz=0; i<m; i++) nz += ai[i+1] - adiag[i]; ierr = PetscMalloc3(m+1,&ci,nz,&cj,values ? nz : 0,&ca);CHKERRQ(ierr); for (i=0,k=0; i<m; i++) { ci[i] = k; for (j=adiag[i]; j<ai[i+1]; j++,k++) { cj[k] = aj[j]; if (values) ca[k] = aa[j]; } } ci[i] = k; *aijalloc = PETSC_TRUE; ierr = PetscMemzero(C,sizeof(*C));CHKERRQ(ierr); C->nrow = (size_t)A->cmap->n; C->ncol = (size_t)A->rmap->n; C->nzmax = (size_t)nz; C->p = ci; C->i = cj; C->x = values ? ca : 0; C->stype = -1; C->itype = CHOLMOD_INT_TYPE; C->xtype = values ? CHOLMOD_SCALAR_TYPE : CHOLMOD_PATTERN; C->dtype = CHOLMOD_DOUBLE; C->sorted = 1; C->packed = 1; PetscFunctionReturn(0); }