PetscErrorCode MatBlockMatSetPreallocation_BlockMat(Mat A,PetscInt bs,PetscInt nz,PetscInt *nnz) { Mat_BlockMat *bmat = (Mat_BlockMat*)A->data; PetscErrorCode ierr; PetscInt i; PetscFunctionBegin; ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); ierr = PetscLayoutGetBlockSize(A->rmap,&bs);CHKERRQ(ierr); if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); if (nnz) { for (i=0; i<A->rmap->n/bs; i++) { if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); if (nnz[i] > A->cmap->n/bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],A->cmap->n/bs); } } bmat->mbs = A->rmap->n/bs; ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,bs,NULL,&bmat->right);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,bs,NULL,&bmat->middle);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,bs,&bmat->left);CHKERRQ(ierr); if (!bmat->imax) { ierr = PetscMalloc2(A->rmap->n,&bmat->imax,A->rmap->n,&bmat->ilen);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)A,2*A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); } if (nnz) { nz = 0; for (i=0; i<A->rmap->n/A->rmap->bs; i++) { bmat->imax[i] = nnz[i]; nz += nnz[i]; } } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently requires block row by row preallocation"); /* bmat->ilen will count nonzeros in each row so far. */ for (i=0; i<bmat->mbs; i++) bmat->ilen[i] = 0; /* allocate the matrix space */ ierr = MatSeqXAIJFreeAIJ(A,(PetscScalar**)&bmat->a,&bmat->j,&bmat->i);CHKERRQ(ierr); ierr = PetscMalloc3(nz,&bmat->a,nz,&bmat->j,A->rmap->n+1,&bmat->i);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); bmat->i[0] = 0; for (i=1; i<bmat->mbs+1; i++) { bmat->i[i] = bmat->i[i-1] + bmat->imax[i-1]; } bmat->singlemalloc = PETSC_TRUE; bmat->free_a = PETSC_TRUE; bmat->free_ij = PETSC_TRUE; bmat->nz = 0; bmat->maxnz = nz; A->info.nz_unneeded = (double)bmat->maxnz; ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatDestroy_BlockMat(Mat mat) { PetscErrorCode ierr; Mat_BlockMat *bmat = (Mat_BlockMat*)mat->data; PetscInt i; PetscFunctionBegin; ierr = VecDestroy(&bmat->right);CHKERRQ(ierr); ierr = VecDestroy(&bmat->left);CHKERRQ(ierr); ierr = VecDestroy(&bmat->middle);CHKERRQ(ierr); ierr = VecDestroy(&bmat->workb);CHKERRQ(ierr); if (bmat->diags) { for (i=0; i<mat->rmap->n/mat->rmap->bs; i++) { ierr = MatDestroy(&bmat->diags[i]);CHKERRQ(ierr); } } if (bmat->a) { for (i=0; i<bmat->nz; i++) { ierr = MatDestroy(&bmat->a[i]);CHKERRQ(ierr); } } ierr = MatSeqXAIJFreeAIJ(mat,(PetscScalar**)&bmat->a,&bmat->j,&bmat->i);CHKERRQ(ierr); ierr = PetscFree(mat->data);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C MatSeqAIJFromMatlab - Given a MATLAB sparse matrix, fills a SeqAIJ matrix with its transpose. Not Collective Input Parameters: + mmat - a MATLAB sparse matris - mat - an already created MATSEQAIJ Level: intermediate @*/ PETSC_EXTERN PetscErrorCode MatSeqAIJFromMatlab(mxArray *mmat,Mat mat) { PetscErrorCode ierr; PetscInt nz,n,m,*i,*j,k; mwIndex nnz,nn,nm,*ii,*jj; Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; PetscFunctionBegin; nn = mxGetN(mmat); /* rows of transpose of matrix */ nm = mxGetM(mmat); nnz = (mxGetJc(mmat))[nn]; ii = mxGetJc(mmat); jj = mxGetIr(mmat); n = (PetscInt) nn; m = (PetscInt) nm; nz = (PetscInt) nnz; if (mat->rmap->n < 0 && mat->cmap->n < 0) { /* matrix has not yet had its size set */ ierr = MatSetSizes(mat,n,m,PETSC_DETERMINE,PETSC_DETERMINE); CHKERRQ(ierr); ierr = MatSetUp(mat); CHKERRQ(ierr); } else { if (mat->rmap->n != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->rmap->n,n); if (mat->cmap->n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->cmap->n,m); } if (nz != aij->nz) { /* number of nonzeros in matrix has changed, so need new data structure */ ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i); CHKERRQ(ierr); aij->nz = nz; ierr = PetscMalloc3(aij->nz,&aij->a,aij->nz,&aij->j,mat->rmap->n+1,&aij->i); CHKERRQ(ierr); aij->singlemalloc = PETSC_TRUE; } ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar)); CHKERRQ(ierr); /* MATLAB stores by column, not row so we pass in the transpose of the matrix */ i = aij->i; for (k=0; k<n+1; k++) i[k] = (PetscInt) ii[k]; j = aij->j; for (k=0; k<nz; k++) j[k] = (PetscInt) jj[k]; for (k=0; k<mat->rmap->n; k++) aij->ilen[k] = aij->imax[k] = aij->i[k+1] - aij->i[k]; ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_END EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatSeqAIJFromMatlab" /*@C MatSeqAIJFromMatlab - Given a MATLAB sparse matrix, fills a SeqAIJ matrix with its transpose. Not Collective Input Parameters: + mmat - a MATLAB sparse matris - mat - a already created MATSEQAIJ Level: intermediate @*/ PetscErrorCode MatSeqAIJFromMatlab(mxArray *mmat,Mat mat) { PetscErrorCode ierr; PetscInt nz,n,m,*i,*j,k; mwIndex nnz,nn,nm,*ii,*jj; Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; PetscFunctionBegin; nn = mxGetN(mmat); /* rows of transpose of matrix */ nm = mxGetM(mmat); nnz = (mxGetJc(mmat))[nn]; ii = mxGetJc(mmat); jj = mxGetIr(mmat); n = (PetscInt) nn; m = (PetscInt) nm; nz = (PetscInt) nnz; if (mat->rmap->n < 0 && mat->cmap->n < 0) { /* matrix has not yet had its size set */ ierr = MatSetSizes(mat,n,m,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetUp(mat);CHKERRQ(ierr); } else { if (mat->rmap->n != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->rmap->n,n); if (mat->cmap->n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->cmap->n,m); } if (nz != aij->nz) { /* number of nonzeros in matrix has changed, so need new data structure */ ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); aij->nz = nz; ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr); aij->singlemalloc = PETSC_TRUE; } ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); /* MATLAB stores by column, not row so we pass in the transpose of the matrix */ i = aij->i; for (k=0; k<n+1; k++) { i[k] = (PetscInt) ii[k]; } j = aij->j; for (k=0; k<nz; k++) { j[k] = (PetscInt) jj[k]; } for (k=0; k<mat->rmap->n; k++) { aij->ilen[k] = aij->imax[k] = aij->i[k+1] - aij->i[k]; } ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }