163c07aadSStefano Zampini 263c07aadSStefano Zampini /* 363c07aadSStefano Zampini Creates hypre ijmatrix from PETSc matrix 463c07aadSStefano Zampini */ 5225daaf8SStefano Zampini 6225daaf8SStefano Zampini /*MC 7225daaf8SStefano Zampini MATHYPRE - MATHYPRE = "hypre" - A matrix type to be used for sequential and parallel sparse matrices 8225daaf8SStefano Zampini based on the hypre IJ interface. 9225daaf8SStefano Zampini 10225daaf8SStefano Zampini Level: intermediate 11225daaf8SStefano Zampini 12225daaf8SStefano Zampini .seealso: MatCreate() 13225daaf8SStefano Zampini M*/ 14225daaf8SStefano Zampini 1563c07aadSStefano Zampini #include <petscsys.h> 1663c07aadSStefano Zampini #include <petsc/private/matimpl.h> 1763c07aadSStefano Zampini #include <../src/mat/impls/hypre/mhypre.h> 1863c07aadSStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 1958968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h> 2058968eb6SStefano Zampini #include <HYPRE.h> 21c1a070e6SStefano Zampini #include <HYPRE_utilities.h> 22cd8bc7baSStefano Zampini #include <_hypre_parcsr_ls.h> 2363c07aadSStefano Zampini 2463c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat,Mat_HYPRE*); 2563c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat,Mat,HYPRE_IJMatrix); 2663c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat,HYPRE_IJMatrix); 2763c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat,HYPRE_IJMatrix); 2863c07aadSStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat,Vec,Vec,PetscBool); 29225daaf8SStefano Zampini static PetscErrorCode hypre_array_destroy(void*); 3063c07aadSStefano Zampini 3163c07aadSStefano Zampini #undef __FUNCT__ 3263c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixPreallocate" 3363c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat A_d, Mat A_o, HYPRE_IJMatrix ij) 3463c07aadSStefano Zampini { 3563c07aadSStefano Zampini PetscErrorCode ierr; 3663c07aadSStefano Zampini PetscInt i,n_d,n_o; 3763c07aadSStefano Zampini const PetscInt *ia_d,*ia_o; 3863c07aadSStefano Zampini PetscBool done_d=PETSC_FALSE,done_o=PETSC_FALSE; 3963c07aadSStefano Zampini PetscInt *nnz_d=NULL,*nnz_o=NULL; 4063c07aadSStefano Zampini 4163c07aadSStefano Zampini PetscFunctionBegin; 4263c07aadSStefano Zampini if (A_d) { /* determine number of nonzero entries in local diagonal part */ 4363c07aadSStefano Zampini ierr = MatGetRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,&n_d,&ia_d,NULL,&done_d);CHKERRQ(ierr); 4463c07aadSStefano Zampini if (done_d) { 4563c07aadSStefano Zampini ierr = PetscMalloc1(n_d,&nnz_d);CHKERRQ(ierr); 4663c07aadSStefano Zampini for (i=0; i<n_d; i++) { 4763c07aadSStefano Zampini nnz_d[i] = ia_d[i+1] - ia_d[i]; 4863c07aadSStefano Zampini } 4963c07aadSStefano Zampini } 5063c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,NULL,&ia_d,NULL,&done_d);CHKERRQ(ierr); 5163c07aadSStefano Zampini } 5263c07aadSStefano Zampini if (A_o) { /* determine number of nonzero entries in local off-diagonal part */ 5363c07aadSStefano Zampini ierr = MatGetRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 5463c07aadSStefano Zampini if (done_o) { 5563c07aadSStefano Zampini ierr = PetscMalloc1(n_o,&nnz_o);CHKERRQ(ierr); 5663c07aadSStefano Zampini for (i=0; i<n_o; i++) { 5763c07aadSStefano Zampini nnz_o[i] = ia_o[i+1] - ia_o[i]; 5863c07aadSStefano Zampini } 5963c07aadSStefano Zampini } 6063c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 6163c07aadSStefano Zampini } 6263c07aadSStefano Zampini if (done_d) { /* set number of nonzeros in HYPRE IJ matrix */ 6363c07aadSStefano Zampini if (!done_o) { /* only diagonal part */ 6463c07aadSStefano Zampini ierr = PetscMalloc1(n_d,&nnz_o);CHKERRQ(ierr); 6563c07aadSStefano Zampini for (i=0; i<n_d; i++) { 6663c07aadSStefano Zampini nnz_o[i] = 0; 6763c07aadSStefano Zampini } 6863c07aadSStefano Zampini } 6963c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(ij,(HYPRE_Int *)nnz_d,(HYPRE_Int *)nnz_o)); 7063c07aadSStefano Zampini ierr = PetscFree(nnz_d);CHKERRQ(ierr); 7163c07aadSStefano Zampini ierr = PetscFree(nnz_o);CHKERRQ(ierr); 7263c07aadSStefano Zampini } 7363c07aadSStefano Zampini PetscFunctionReturn(0); 7463c07aadSStefano Zampini } 7563c07aadSStefano Zampini 7663c07aadSStefano Zampini #undef __FUNCT__ 7763c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_CreateFromMat" 7863c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat A, Mat_HYPRE *hA) 7963c07aadSStefano Zampini { 8063c07aadSStefano Zampini PetscErrorCode ierr; 8163c07aadSStefano Zampini PetscInt rstart,rend,cstart,cend; 8263c07aadSStefano Zampini 8363c07aadSStefano Zampini PetscFunctionBegin; 8463c07aadSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 8563c07aadSStefano Zampini rstart = A->rmap->rstart; 8663c07aadSStefano Zampini rend = A->rmap->rend; 8763c07aadSStefano Zampini cstart = A->cmap->rstart; 8863c07aadSStefano Zampini cend = A->cmap->rend; 8963c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 9063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 9163c07aadSStefano Zampini { 9263c07aadSStefano Zampini PetscBool same; 9363c07aadSStefano Zampini Mat A_d,A_o; 9463c07aadSStefano Zampini const PetscInt *colmap; 9563c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&same);CHKERRQ(ierr); 9663c07aadSStefano Zampini if (same) { 9763c07aadSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 9863c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 9963c07aadSStefano Zampini PetscFunctionReturn(0); 10063c07aadSStefano Zampini } 10163c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&same);CHKERRQ(ierr); 10263c07aadSStefano Zampini if (same) { 10363c07aadSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 10463c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 10563c07aadSStefano Zampini PetscFunctionReturn(0); 10663c07aadSStefano Zampini } 10763c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&same);CHKERRQ(ierr); 10863c07aadSStefano Zampini if (same) { 10963c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A,NULL,hA->ij);CHKERRQ(ierr); 11063c07aadSStefano Zampini PetscFunctionReturn(0); 11163c07aadSStefano Zampini } 11263c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&same);CHKERRQ(ierr); 11363c07aadSStefano Zampini if (same) { 11463c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A,NULL,hA->ij);CHKERRQ(ierr); 11563c07aadSStefano Zampini PetscFunctionReturn(0); 11663c07aadSStefano Zampini } 11763c07aadSStefano Zampini } 11863c07aadSStefano Zampini PetscFunctionReturn(0); 11963c07aadSStefano Zampini } 12063c07aadSStefano Zampini 12163c07aadSStefano Zampini #undef __FUNCT__ 12263c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixCopy" 12363c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopy(Mat A, HYPRE_IJMatrix ij) 12463c07aadSStefano Zampini { 12563c07aadSStefano Zampini PetscErrorCode ierr; 12663c07aadSStefano Zampini PetscInt i,rstart,rend,ncols,nr,nc; 12763c07aadSStefano Zampini const PetscScalar *values; 12863c07aadSStefano Zampini const PetscInt *cols; 12963c07aadSStefano Zampini PetscBool flg; 13063c07aadSStefano Zampini 13163c07aadSStefano Zampini PetscFunctionBegin; 13263c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr); 13363c07aadSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 13463c07aadSStefano Zampini if (flg && nr == nc) { 13563c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_MPIAIJ(A,ij);CHKERRQ(ierr); 13663c07aadSStefano Zampini PetscFunctionReturn(0); 13763c07aadSStefano Zampini } 13863c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr); 13963c07aadSStefano Zampini if (flg) { 14063c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_SeqAIJ(A,ij);CHKERRQ(ierr); 14163c07aadSStefano Zampini PetscFunctionReturn(0); 14263c07aadSStefano Zampini } 14363c07aadSStefano Zampini 14463c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 14563c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 14663c07aadSStefano Zampini for (i=rstart; i<rend; i++) { 14763c07aadSStefano Zampini ierr = MatGetRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 14863c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetValues,(ij,1,(HYPRE_Int *)&ncols,(HYPRE_Int *)&i,(HYPRE_Int *)cols,values)); 14963c07aadSStefano Zampini ierr = MatRestoreRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 15063c07aadSStefano Zampini } 15163c07aadSStefano Zampini PetscFunctionReturn(0); 15263c07aadSStefano Zampini } 15363c07aadSStefano Zampini 15463c07aadSStefano Zampini #undef __FUNCT__ 15563c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixFastCopy_SeqAIJ" 15663c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat A, HYPRE_IJMatrix ij) 15763c07aadSStefano Zampini { 15863c07aadSStefano Zampini PetscErrorCode ierr; 15963c07aadSStefano Zampini Mat_SeqAIJ *pdiag = (Mat_SeqAIJ*)A->data; 16058968eb6SStefano Zampini HYPRE_Int type; 16163c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 16263c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 16363c07aadSStefano Zampini hypre_CSRMatrix *hdiag; 16463c07aadSStefano Zampini 16563c07aadSStefano Zampini PetscFunctionBegin; 16663c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 167ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 168ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 169ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 17063c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 17163c07aadSStefano Zampini /* 17263c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 17363c07aadSStefano Zampini */ 17463c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->i,pdiag->i,(A->rmap->n + 1)*sizeof(PetscInt)); 17563c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->j,pdiag->j,pdiag->nz*sizeof(PetscInt)); 17663c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar)); 177ea9daf28SStefano Zampini 178ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 17963c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 18063c07aadSStefano Zampini PetscFunctionReturn(0); 18163c07aadSStefano Zampini } 18263c07aadSStefano Zampini 18363c07aadSStefano Zampini #undef __FUNCT__ 18463c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixFastCopy_MPIAIJ" 18563c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat A, HYPRE_IJMatrix ij) 18663c07aadSStefano Zampini { 18763c07aadSStefano Zampini PetscErrorCode ierr; 18863c07aadSStefano Zampini Mat_MPIAIJ *pA = (Mat_MPIAIJ*)A->data; 18963c07aadSStefano Zampini Mat_SeqAIJ *pdiag,*poffd; 19063c07aadSStefano Zampini PetscInt i,*garray = pA->garray,*jj,cstart,*pjj; 19158968eb6SStefano Zampini HYPRE_Int type; 19263c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 19363c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 19463c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 19563c07aadSStefano Zampini 19663c07aadSStefano Zampini PetscFunctionBegin; 19763c07aadSStefano Zampini pdiag = (Mat_SeqAIJ*) pA->A->data; 19863c07aadSStefano Zampini poffd = (Mat_SeqAIJ*) pA->B->data; 19963c07aadSStefano Zampini /* cstart is only valid for square MPIAIJ layed out in the usual way */ 20063c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&cstart,NULL);CHKERRQ(ierr); 20163c07aadSStefano Zampini 20263c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 203ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 204ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 205ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 20663c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 20763c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(par_matrix); 20863c07aadSStefano Zampini 20963c07aadSStefano Zampini /* 21063c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 21163c07aadSStefano Zampini */ 21263c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->i,pdiag->i,(pA->A->rmap->n + 1)*sizeof(PetscInt)); 21363c07aadSStefano Zampini /* need to shift the diag column indices (hdiag->j) back to global numbering since hypre is expecting this */ 21463c07aadSStefano Zampini jj = (PetscInt*)hdiag->j; 21563c07aadSStefano Zampini pjj = (PetscInt*)pdiag->j; 21663c07aadSStefano Zampini for (i=0; i<pdiag->nz; i++) jj[i] = cstart + pjj[i]; 21763c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar)); 21863c07aadSStefano Zampini ierr = PetscMemcpy(hoffd->i,poffd->i,(pA->A->rmap->n + 1)*sizeof(PetscInt)); 21963c07aadSStefano Zampini /* need to move the offd column indices (hoffd->j) back to global numbering since hypre is expecting this 22063c07aadSStefano Zampini If we hacked a hypre a bit more we might be able to avoid this step */ 22163c07aadSStefano Zampini jj = (PetscInt*) hoffd->j; 22263c07aadSStefano Zampini pjj = (PetscInt*) poffd->j; 22363c07aadSStefano Zampini for (i=0; i<poffd->nz; i++) jj[i] = garray[pjj[i]]; 22463c07aadSStefano Zampini ierr = PetscMemcpy(hoffd->data,poffd->a,poffd->nz*sizeof(PetscScalar)); 22563c07aadSStefano Zampini 226ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 22763c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 22863c07aadSStefano Zampini PetscFunctionReturn(0); 22963c07aadSStefano Zampini } 23063c07aadSStefano Zampini 23163c07aadSStefano Zampini #undef __FUNCT__ 2322df22349SStefano Zampini #define __FUNCT__ "MatConvert_HYPRE_IS" 2332df22349SStefano Zampini static PetscErrorCode MatConvert_HYPRE_IS(Mat A, MatType mtype, MatReuse reuse, Mat* B) 2342df22349SStefano Zampini { 2352df22349SStefano Zampini Mat_HYPRE* mhA = (Mat_HYPRE*)(A->data); 2362df22349SStefano Zampini Mat lA; 2372df22349SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2382df22349SStefano Zampini IS is; 2392df22349SStefano Zampini hypre_ParCSRMatrix *hA; 2402df22349SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 2412df22349SStefano Zampini MPI_Comm comm; 2422df22349SStefano Zampini PetscScalar *hdd,*hod,*aa,*data; 2432df22349SStefano Zampini PetscInt *col_map_offd,*hdi,*hdj,*hoi,*hoj; 2442df22349SStefano Zampini PetscInt *ii,*jj,*iptr,*jptr; 2452df22349SStefano Zampini PetscInt cum,dr,dc,oc,str,stc,nnz,i,jd,jo,M,N; 24658968eb6SStefano Zampini HYPRE_Int type; 2472df22349SStefano Zampini PetscErrorCode ierr; 2482df22349SStefano Zampini 2492df22349SStefano Zampini PetscFunctionBegin; 250a1787963SStefano Zampini comm = PetscObjectComm((PetscObject)A); 2512df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(mhA->ij,&type)); 2522df22349SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 2532df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(mhA->ij,(void**)&hA)); 2542df22349SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(hA); 2552df22349SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(hA); 2562df22349SStefano Zampini str = hypre_ParCSRMatrixFirstRowIndex(hA); 2572df22349SStefano Zampini stc = hypre_ParCSRMatrixFirstColDiag(hA); 2582df22349SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(hA); 2592df22349SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(hA); 2602df22349SStefano Zampini dr = hypre_CSRMatrixNumRows(hdiag); 2612df22349SStefano Zampini dc = hypre_CSRMatrixNumCols(hdiag); 2622df22349SStefano Zampini nnz = hypre_CSRMatrixNumNonzeros(hdiag); 2632df22349SStefano Zampini hdi = hypre_CSRMatrixI(hdiag); 2642df22349SStefano Zampini hdj = hypre_CSRMatrixJ(hdiag); 2652df22349SStefano Zampini hdd = hypre_CSRMatrixData(hdiag); 2662df22349SStefano Zampini oc = hypre_CSRMatrixNumCols(hoffd); 2672df22349SStefano Zampini nnz += hypre_CSRMatrixNumNonzeros(hoffd); 2682df22349SStefano Zampini hoi = hypre_CSRMatrixI(hoffd); 2692df22349SStefano Zampini hoj = hypre_CSRMatrixJ(hoffd); 2702df22349SStefano Zampini hod = hypre_CSRMatrixData(hoffd); 2712df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2722df22349SStefano Zampini PetscInt *aux; 2732df22349SStefano Zampini 2742df22349SStefano Zampini /* generate l2g maps for rows and cols */ 2752df22349SStefano Zampini ierr = ISCreateStride(comm,dr,str,1,&is);CHKERRQ(ierr); 2762df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2772df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2782df22349SStefano Zampini col_map_offd = hypre_ParCSRMatrixColMapOffd(hA); 2792df22349SStefano Zampini ierr = PetscMalloc1(dc+oc,&aux);CHKERRQ(ierr); 2802df22349SStefano Zampini for (i=0; i<dc; i++) aux[i] = i+stc; 2812df22349SStefano Zampini for (i=0; i<oc; i++) aux[i+dc] = col_map_offd[i]; 2822df22349SStefano Zampini ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2832df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2842df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2852df22349SStefano Zampini /* create MATIS object */ 2862df22349SStefano Zampini ierr = MatCreate(comm,B);CHKERRQ(ierr); 2872df22349SStefano Zampini ierr = MatSetSizes(*B,dr,dc,M,N);CHKERRQ(ierr); 2882df22349SStefano Zampini ierr = MatSetType(*B,MATIS);CHKERRQ(ierr); 2892df22349SStefano Zampini ierr = MatSetLocalToGlobalMapping(*B,rl2g,cl2g);CHKERRQ(ierr); 2902df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2912df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2922df22349SStefano Zampini 2932df22349SStefano Zampini /* allocate CSR for local matrix */ 2942df22349SStefano Zampini ierr = PetscMalloc1(dr+1,&iptr);CHKERRQ(ierr); 2952df22349SStefano Zampini ierr = PetscMalloc1(nnz,&jptr);CHKERRQ(ierr); 2962df22349SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 2972df22349SStefano Zampini } else { 2982df22349SStefano Zampini PetscInt nr; 2992df22349SStefano Zampini PetscBool done; 3002df22349SStefano Zampini ierr = MatISGetLocalMat(*B,&lA);CHKERRQ(ierr); 3012df22349SStefano Zampini ierr = MatGetRowIJ(lA,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&iptr,(const PetscInt**)&jptr,&done);CHKERRQ(ierr); 3022df22349SStefano Zampini if (nr != dr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of rows in local mat! %D != %D",nr,dr); 3032df22349SStefano Zampini if (iptr[nr] < nnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros in local mat! reuse %D requested %D",iptr[nr],nnz); 3042df22349SStefano Zampini ierr = MatSeqAIJGetArray(lA,&data);CHKERRQ(ierr); 3052df22349SStefano Zampini } 3062df22349SStefano Zampini /* merge local matrices */ 3072df22349SStefano Zampini ii = iptr; 3082df22349SStefano Zampini jj = jptr; 3092df22349SStefano Zampini aa = data; 3102df22349SStefano Zampini *ii = *(hdi++) + *(hoi++); 3112df22349SStefano Zampini for (jd=0,jo=0,cum=0; *ii<nnz; cum++) { 3122df22349SStefano Zampini PetscScalar *aold = aa; 3132df22349SStefano Zampini PetscInt *jold = jj,nc = jd+jo; 3142df22349SStefano Zampini for (; jd<*hdi; jd++) { *jj++ = *hdj++; *aa++ = *hdd++; } 3152df22349SStefano Zampini for (; jo<*hoi; jo++) { *jj++ = *hoj++ + dc; *aa++ = *hod++; } 3162df22349SStefano Zampini *(++ii) = *(hdi++) + *(hoi++); 3172df22349SStefano Zampini ierr = PetscSortIntWithScalarArray(jd+jo-nc,jold,aold);CHKERRQ(ierr); 3182df22349SStefano Zampini } 3192df22349SStefano Zampini for (; cum<dr; cum++) *(++ii) = nnz; 3202df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 321a033916dSStefano Zampini Mat_SeqAIJ* a; 322a033916dSStefano Zampini 3232df22349SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,dc+oc,iptr,jptr,data,&lA);CHKERRQ(ierr); 3242df22349SStefano Zampini ierr = MatISSetLocalMat(*B,lA);CHKERRQ(ierr); 325a033916dSStefano Zampini /* hack SeqAIJ */ 326a033916dSStefano Zampini a = (Mat_SeqAIJ*)(lA->data); 327a033916dSStefano Zampini a->free_a = PETSC_TRUE; 328a033916dSStefano Zampini a->free_ij = PETSC_TRUE; 3292df22349SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 3302df22349SStefano Zampini } 3312df22349SStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3322df22349SStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3332df22349SStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 3342df22349SStefano Zampini ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); 3352df22349SStefano Zampini } 3362df22349SStefano Zampini PetscFunctionReturn(0); 3372df22349SStefano Zampini } 3382df22349SStefano Zampini 3392df22349SStefano Zampini #undef __FUNCT__ 34063c07aadSStefano Zampini #define __FUNCT__ "MatConvert_AIJ_HYPRE" 34163c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A, MatType type, MatReuse reuse, Mat *B) 34263c07aadSStefano Zampini { 34363c07aadSStefano Zampini Mat_HYPRE *hB; 34463c07aadSStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 34563c07aadSStefano Zampini PetscErrorCode ierr; 34663c07aadSStefano Zampini 34763c07aadSStefano Zampini PetscFunctionBegin; 34863c07aadSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) SETERRQ(comm,PETSC_ERR_SUP,"Unsupported MAT_INPLACE_MATRIX"); 34963c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 35063c07aadSStefano Zampini /* always destroy the old matrix and create a new memory; 35163c07aadSStefano Zampini hope this does not churn the memory too much. The problem 35263c07aadSStefano Zampini is I do not know if it is possible to put the matrix back to 35363c07aadSStefano Zampini its initial state so that we can directly copy the values 35463c07aadSStefano Zampini the second time through. */ 35563c07aadSStefano Zampini hB = (Mat_HYPRE*)((*B)->data); 35663c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hB->ij)); 35763c07aadSStefano Zampini } else { 35863c07aadSStefano Zampini ierr = MatCreate(comm,B);CHKERRQ(ierr); 35963c07aadSStefano Zampini ierr = MatSetType(*B,MATHYPRE);CHKERRQ(ierr); 36063c07aadSStefano Zampini ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 36163c07aadSStefano Zampini ierr = MatSetUp(*B);CHKERRQ(ierr); 36263c07aadSStefano Zampini hB = (Mat_HYPRE*)((*B)->data); 36363c07aadSStefano Zampini } 36463c07aadSStefano Zampini ierr = MatHYPRE_CreateFromMat(A,hB);CHKERRQ(ierr); 36563c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,hB->ij);CHKERRQ(ierr); 36663c07aadSStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 36763c07aadSStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 36863c07aadSStefano Zampini PetscFunctionReturn(0); 36963c07aadSStefano Zampini } 37063c07aadSStefano Zampini 37163c07aadSStefano Zampini #undef __FUNCT__ 37263c07aadSStefano Zampini #define __FUNCT__ "MatConvert_HYPRE_AIJ" 373ea9daf28SStefano Zampini static PetscErrorCode MatConvert_HYPRE_AIJ(Mat A, MatType mtype, MatReuse reuse, Mat *B) 37463c07aadSStefano Zampini { 37563c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 37663c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 37763c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 37863c07aadSStefano Zampini MPI_Comm comm; 37963c07aadSStefano Zampini PetscScalar *da,*oa,*aptr; 38063c07aadSStefano Zampini PetscInt *dii,*djj,*oii,*ojj,*iptr; 38163c07aadSStefano Zampini PetscInt i,dnnz,onnz,m,n; 38258968eb6SStefano Zampini HYPRE_Int type; 38363c07aadSStefano Zampini PetscMPIInt size; 38463c07aadSStefano Zampini PetscErrorCode ierr; 38563c07aadSStefano Zampini 38663c07aadSStefano Zampini PetscFunctionBegin; 38763c07aadSStefano Zampini comm = PetscObjectComm((PetscObject)A); 38863c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 38963c07aadSStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 39063c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 39163c07aadSStefano Zampini PetscBool ismpiaij,isseqaij; 39263c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 39363c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 39463c07aadSStefano Zampini if (!ismpiaij && !isseqaij) SETERRQ(comm,PETSC_ERR_SUP,"Only MATMPIAIJ or MATSEQAIJ are supported"); 39563c07aadSStefano Zampini } 39663c07aadSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 39763c07aadSStefano Zampini 39863c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 39963c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 40063c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 40163c07aadSStefano Zampini m = hypre_CSRMatrixNumRows(hdiag); 40263c07aadSStefano Zampini n = hypre_CSRMatrixNumCols(hdiag); 40363c07aadSStefano Zampini dnnz = hypre_CSRMatrixNumNonzeros(hdiag); 40463c07aadSStefano Zampini onnz = hypre_CSRMatrixNumNonzeros(hoffd); 405225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 40663c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&dii);CHKERRQ(ierr); 40763c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&djj);CHKERRQ(ierr); 40863c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&da);CHKERRQ(ierr); 409225daaf8SStefano Zampini } else if (reuse == MAT_REUSE_MATRIX) { 41063c07aadSStefano Zampini PetscInt nr; 41163c07aadSStefano Zampini PetscBool done; 41263c07aadSStefano Zampini if (size > 1) { 41363c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 41463c07aadSStefano Zampini 41563c07aadSStefano Zampini ierr = MatGetRowIJ(b->A,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 41663c07aadSStefano Zampini if (nr != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows in diag part! %D != %D",nr,m); 41763c07aadSStefano Zampini if (dii[nr] < dnnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros in diag part! reuse %D hypre %D",dii[nr],dnnz); 41863c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->A,&da);CHKERRQ(ierr); 41963c07aadSStefano Zampini } else { 42063c07aadSStefano Zampini ierr = MatGetRowIJ(*B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 42163c07aadSStefano Zampini if (nr != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows! %D != %D",nr,m); 42263c07aadSStefano Zampini if (dii[nr] < dnnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros! reuse %D hypre %D",dii[nr],dnnz); 42363c07aadSStefano Zampini ierr = MatSeqAIJGetArray(*B,&da);CHKERRQ(ierr); 42463c07aadSStefano Zampini } 425225daaf8SStefano Zampini } else { /* MAT_INPLACE_MATRIX */ 426225daaf8SStefano Zampini dii = hypre_CSRMatrixI(hdiag); 427225daaf8SStefano Zampini djj = hypre_CSRMatrixJ(hdiag); 428225daaf8SStefano Zampini da = hypre_CSRMatrixData(hdiag); 42963c07aadSStefano Zampini } 43063c07aadSStefano Zampini ierr = PetscMemcpy(dii,hypre_CSRMatrixI(hdiag),(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 43163c07aadSStefano Zampini ierr = PetscMemcpy(djj,hypre_CSRMatrixJ(hdiag),dnnz*sizeof(PetscInt));CHKERRQ(ierr); 43263c07aadSStefano Zampini ierr = PetscMemcpy(da,hypre_CSRMatrixData(hdiag),dnnz*sizeof(PetscScalar));CHKERRQ(ierr); 43363c07aadSStefano Zampini iptr = djj; 43463c07aadSStefano Zampini aptr = da; 43563c07aadSStefano Zampini for (i=0; i<m; i++) { 43663c07aadSStefano Zampini PetscInt nc = dii[i+1]-dii[i]; 43763c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 43863c07aadSStefano Zampini iptr += nc; 43963c07aadSStefano Zampini aptr += nc; 44063c07aadSStefano Zampini } 44163c07aadSStefano Zampini if (size > 1) { 44263c07aadSStefano Zampini PetscInt *offdj,*coffd; 44363c07aadSStefano Zampini 444225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 44563c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&oii);CHKERRQ(ierr); 44663c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&ojj);CHKERRQ(ierr); 44763c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&oa);CHKERRQ(ierr); 448225daaf8SStefano Zampini } else if (reuse == MAT_REUSE_MATRIX) { 44963c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 45063c07aadSStefano Zampini PetscInt nr,hr = hypre_CSRMatrixNumRows(hoffd); 45163c07aadSStefano Zampini PetscBool done; 45263c07aadSStefano Zampini 45363c07aadSStefano Zampini ierr = MatGetRowIJ(b->B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&oii,(const PetscInt**)&ojj,&done);CHKERRQ(ierr); 45463c07aadSStefano Zampini if (nr != hr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows in offdiag part! %D != %D",nr,hr); 45563c07aadSStefano Zampini if (oii[nr] < onnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros in offdiag part! reuse %D hypre %D",oii[nr],onnz); 45663c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->B,&oa);CHKERRQ(ierr); 457225daaf8SStefano Zampini } else { /* MAT_INPLACE_MATRIX */ 458225daaf8SStefano Zampini oii = hypre_CSRMatrixI(hoffd); 459225daaf8SStefano Zampini ojj = hypre_CSRMatrixJ(hoffd); 460225daaf8SStefano Zampini oa = hypre_CSRMatrixData(hoffd); 46163c07aadSStefano Zampini } 46263c07aadSStefano Zampini ierr = PetscMemcpy(oii,hypre_CSRMatrixI(hoffd),(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 46363c07aadSStefano Zampini offdj = hypre_CSRMatrixJ(hoffd); 46463c07aadSStefano Zampini coffd = hypre_ParCSRMatrixColMapOffd(parcsr); 46563c07aadSStefano Zampini for (i=0; i<onnz; i++) ojj[i] = coffd[offdj[i]]; 46663c07aadSStefano Zampini ierr = PetscMemcpy(oa,hypre_CSRMatrixData(hoffd),onnz*sizeof(PetscScalar));CHKERRQ(ierr); 46763c07aadSStefano Zampini iptr = ojj; 46863c07aadSStefano Zampini aptr = oa; 46963c07aadSStefano Zampini for (i=0; i<m; i++) { 47063c07aadSStefano Zampini PetscInt nc = oii[i+1]-oii[i]; 47163c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 47263c07aadSStefano Zampini iptr += nc; 47363c07aadSStefano Zampini aptr += nc; 47463c07aadSStefano Zampini } 475225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 47663c07aadSStefano Zampini Mat_MPIAIJ *b; 47763c07aadSStefano Zampini Mat_SeqAIJ *d,*o; 478225daaf8SStefano Zampini 479*41073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,B);CHKERRQ(ierr); 48063c07aadSStefano Zampini /* hack MPIAIJ */ 48163c07aadSStefano Zampini b = (Mat_MPIAIJ*)((*B)->data); 48263c07aadSStefano Zampini d = (Mat_SeqAIJ*)b->A->data; 48363c07aadSStefano Zampini o = (Mat_SeqAIJ*)b->B->data; 48463c07aadSStefano Zampini d->free_a = PETSC_TRUE; 48563c07aadSStefano Zampini d->free_ij = PETSC_TRUE; 48663c07aadSStefano Zampini o->free_a = PETSC_TRUE; 48763c07aadSStefano Zampini o->free_ij = PETSC_TRUE; 488225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 489225daaf8SStefano Zampini Mat T; 490*41073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,&T);CHKERRQ(ierr); 491225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 492225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 493225daaf8SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 494225daaf8SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 495225daaf8SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 496225daaf8SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 497225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 49863c07aadSStefano Zampini } 499225daaf8SStefano Zampini } else { 500225daaf8SStefano Zampini oii = NULL; 501225daaf8SStefano Zampini ojj = NULL; 502225daaf8SStefano Zampini oa = NULL; 503225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 50463c07aadSStefano Zampini Mat_SeqAIJ* b; 50563c07aadSStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,B);CHKERRQ(ierr); 50663c07aadSStefano Zampini /* hack SeqAIJ */ 50763c07aadSStefano Zampini b = (Mat_SeqAIJ*)((*B)->data); 50863c07aadSStefano Zampini b->free_a = PETSC_TRUE; 50963c07aadSStefano Zampini b->free_ij = PETSC_TRUE; 510225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 511225daaf8SStefano Zampini Mat T; 512225daaf8SStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,&T);CHKERRQ(ierr); 513225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 514225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 515225daaf8SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 516225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 51763c07aadSStefano Zampini } 518225daaf8SStefano Zampini } 519225daaf8SStefano Zampini 520225daaf8SStefano Zampini /* we have to use hypre_Tfree to free the arrays */ 52163c07aadSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 522225daaf8SStefano Zampini void *ptrs[6] = {dii,djj,da,oii,ojj,oa}; 523225daaf8SStefano Zampini const char *names[6] = {"_hypre_csr_dii", 524225daaf8SStefano Zampini "_hypre_csr_djj", 525225daaf8SStefano Zampini "_hypre_csr_da", 526225daaf8SStefano Zampini "_hypre_csr_oii", 527225daaf8SStefano Zampini "_hypre_csr_ojj", 528225daaf8SStefano Zampini "_hypre_csr_oa"}; 529225daaf8SStefano Zampini for (i=0; i<6; i++) { 530225daaf8SStefano Zampini PetscContainer c; 531225daaf8SStefano Zampini 532225daaf8SStefano Zampini ierr = PetscContainerCreate(comm,&c);CHKERRQ(ierr); 533225daaf8SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 534225daaf8SStefano Zampini ierr = PetscContainerSetUserDestroy(c,hypre_array_destroy);CHKERRQ(ierr); 535225daaf8SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*B),names[i],(PetscObject)c);CHKERRQ(ierr); 536225daaf8SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 537225daaf8SStefano Zampini } 53863c07aadSStefano Zampini } 53963c07aadSStefano Zampini PetscFunctionReturn(0); 54063c07aadSStefano Zampini } 54163c07aadSStefano Zampini 54263c07aadSStefano Zampini #undef __FUNCT__ 543c1a070e6SStefano Zampini #define __FUNCT__ "MatPtAP_AIJ_HYPRE" 544c1a070e6SStefano Zampini static PetscErrorCode MatPtAP_AIJ_HYPRE(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 545c1a070e6SStefano Zampini { 546c1a070e6SStefano Zampini Mat_HYPRE *hP = (Mat_HYPRE*)P->data; 547c1a070e6SStefano Zampini hypre_ParCSRMatrix *tA,*Pparcsr,*ptapparcsr; 548c1a070e6SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 549c1a070e6SStefano Zampini Mat_SeqAIJ *diag,*offd; 550c1a070e6SStefano Zampini PetscInt *garray,noffd,dnnz,onnz,*row_starts,*col_starts; 551c1a070e6SStefano Zampini HYPRE_Int type,P_owns_col_starts; 552c1a070e6SStefano Zampini PetscBool ismpiaij,isseqaij; 553c1a070e6SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 554225daaf8SStefano Zampini char mtype[256]; 555c1a070e6SStefano Zampini PetscErrorCode ierr; 556c1a070e6SStefano Zampini 557c1a070e6SStefano Zampini PetscFunctionBegin; 558c1a070e6SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 559c1a070e6SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 560c1a070e6SStefano Zampini if (scall == MAT_REUSE_MATRIX) SETERRQ(comm,PETSC_ERR_SUP,"Unsupported MAT_REUSE_MATRIX"); 561c1a070e6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 562c1a070e6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 563c1a070e6SStefano Zampini if (!ismpiaij && !isseqaij) SETERRQ1(comm,PETSC_ERR_SUP,"Unsupported type %s",((PetscObject)A)->type); 564225daaf8SStefano Zampini 565225daaf8SStefano Zampini /* It looks like we don't need to have the diagonal entries 566225daaf8SStefano Zampini ordered first in the rows of the diagonal part 567225daaf8SStefano Zampini for boomerAMGBuildCoarseOperator to work */ 568c1a070e6SStefano Zampini if (ismpiaij) { 569c1a070e6SStefano Zampini Mat_MPIAIJ *a = (Mat_MPIAIJ*)(A->data); 570c1a070e6SStefano Zampini 571c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)a->A->data; 572c1a070e6SStefano Zampini offd = (Mat_SeqAIJ*)a->B->data; 573c1a070e6SStefano Zampini garray = a->garray; 574c1a070e6SStefano Zampini noffd = a->B->cmap->N; 575c1a070e6SStefano Zampini dnnz = diag->nz; 576c1a070e6SStefano Zampini onnz = offd->nz; 577c1a070e6SStefano Zampini } else { 578c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)A->data; 579c1a070e6SStefano Zampini offd = NULL; 580c1a070e6SStefano Zampini garray = NULL; 581c1a070e6SStefano Zampini noffd = 0; 582c1a070e6SStefano Zampini dnnz = diag->nz; 583c1a070e6SStefano Zampini onnz = 0; 584c1a070e6SStefano Zampini } 585225daaf8SStefano Zampini 586c1a070e6SStefano Zampini /* create a temporary ParCSR */ 587c1a070e6SStefano Zampini if (HYPRE_AssumedPartitionCheck()) { 588c1a070e6SStefano Zampini PetscMPIInt myid; 589c1a070e6SStefano Zampini 590c1a070e6SStefano Zampini ierr = MPI_Comm_rank(comm,&myid);CHKERRQ(ierr); 591c1a070e6SStefano Zampini row_starts = A->rmap->range + myid; 592c1a070e6SStefano Zampini col_starts = A->cmap->range + myid; 593c1a070e6SStefano Zampini } else { 594c1a070e6SStefano Zampini row_starts = A->rmap->range; 595c1a070e6SStefano Zampini col_starts = A->cmap->range; 596c1a070e6SStefano Zampini } 597c1a070e6SStefano Zampini tA = hypre_ParCSRMatrixCreate(comm,A->rmap->N,A->cmap->N,row_starts,col_starts,noffd,dnnz,onnz); 598c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(tA,0); 599c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(tA,0); 600c1a070e6SStefano Zampini 601225daaf8SStefano Zampini /* set diagonal part */ 602c1a070e6SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(tA); 603c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = diag->i; 604c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = diag->j; 605c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = diag->a; 606c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hdiag) = diag->nz; 607c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hdiag); 608c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hdiag,0); 609c1a070e6SStefano Zampini 610225daaf8SStefano Zampini /* set offdiagonal part */ 611c1a070e6SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(tA); 612c1a070e6SStefano Zampini if (offd) { 613c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = offd->i; 614c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = offd->j; 615c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = offd->a; 616c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hoffd) = offd->nz; 617c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hoffd); 618c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hoffd,0); 619c1a070e6SStefano Zampini hypre_ParCSRMatrixSetNumNonzeros(tA); 620c1a070e6SStefano Zampini hypre_ParCSRMatrixColMapOffd(tA) = garray; 621c1a070e6SStefano Zampini } 622c1a070e6SStefano Zampini 623c1a070e6SStefano Zampini /* call RAP from BoomerAMG */ 624c1a070e6SStefano Zampini /* Warning: hypre_BoomerAMGBuildCoarseOperator steals the col_starts 625c1a070e6SStefano Zampini from Pparcsr (even if it does not own them)! */ 626c1a070e6SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 627c1a070e6SStefano Zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(Pparcsr); 628c1a070e6SStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 629c1a070e6SStefano Zampini PetscStackCallStandard(hypre_BoomerAMGBuildCoarseOperator,(Pparcsr,tA,Pparcsr,&ptapparcsr)); 630c1a070e6SStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 631c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(ptapparcsr,0); 632c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(ptapparcsr,0); 633c1a070e6SStefano Zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(Pparcsr, 1); 634c1a070e6SStefano Zampini 635c1a070e6SStefano Zampini /* set pointers to NULL before destroying tA */ 636c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 637c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 638c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 639c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 640c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 641c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 642c1a070e6SStefano Zampini hypre_ParCSRMatrixColMapOffd(tA) = NULL; 643c1a070e6SStefano Zampini hypre_ParCSRMatrixDestroy(tA); 644225daaf8SStefano Zampini 645225daaf8SStefano Zampini /* create C depending on mtype */ 646225daaf8SStefano Zampini sprintf(mtype,MATAIJ); 647225daaf8SStefano Zampini ierr = PetscOptionsGetString(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_hypre_outtype",mtype,256,NULL);CHKERRQ(ierr); 648225daaf8SStefano Zampini ierr = MatCreateFromParCSR(ptapparcsr,mtype,PETSC_OWN_POINTER,C);CHKERRQ(ierr); 649c1a070e6SStefano Zampini PetscFunctionReturn(0); 650c1a070e6SStefano Zampini } 651c1a070e6SStefano Zampini 652c1a070e6SStefano Zampini #undef __FUNCT__ 653cd8bc7baSStefano Zampini #define __FUNCT__ "MatPtAP_HYPRE_HYPRE" 654cd8bc7baSStefano Zampini static PetscErrorCode MatPtAP_HYPRE_HYPRE(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 655cd8bc7baSStefano Zampini { 656cd8bc7baSStefano Zampini hypre_ParCSRMatrix *Aparcsr,*Pparcsr,*ptapparcsr; 657cd8bc7baSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data, *hP = (Mat_HYPRE*)P->data; 658c1a070e6SStefano Zampini HYPRE_Int type,P_owns_col_starts; 659cd8bc7baSStefano Zampini PetscErrorCode ierr; 660cd8bc7baSStefano Zampini 661cd8bc7baSStefano Zampini PetscFunctionBegin; 662cd8bc7baSStefano Zampini if (scall == MAT_REUSE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unsupported MAT_REUSE_MATRIX"); 663cd8bc7baSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 664cd8bc7baSStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 665cd8bc7baSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 666cd8bc7baSStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)P),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 667cd8bc7baSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&Aparcsr)); 668cd8bc7baSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 669c1a070e6SStefano Zampini 670c1a070e6SStefano Zampini /* call RAP from BoomerAMG */ 671c1a070e6SStefano Zampini /* Warning: hypre_BoomerAMGBuildCoarseOperator steals the col_starts 672c1a070e6SStefano Zampini from Pparcsr (even if it does not own them)! */ 673c1a070e6SStefano Zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(Pparcsr); 674c1a070e6SStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 675cd8bc7baSStefano Zampini PetscStackCallStandard(hypre_BoomerAMGBuildCoarseOperator,(Pparcsr,Aparcsr,Pparcsr,&ptapparcsr)); 676cd8bc7baSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 677c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(ptapparcsr,0); 678c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(ptapparcsr,0); 679c1a070e6SStefano Zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(Pparcsr, 1); 680c1a070e6SStefano Zampini 681c1a070e6SStefano Zampini /* create MatHYPRE */ 682225daaf8SStefano Zampini ierr = MatCreateFromParCSR(ptapparcsr,MATHYPRE,PETSC_OWN_POINTER,C);CHKERRQ(ierr); 683cd8bc7baSStefano Zampini PetscFunctionReturn(0); 684cd8bc7baSStefano Zampini } 685cd8bc7baSStefano Zampini 686cd8bc7baSStefano Zampini #undef __FUNCT__ 68763c07aadSStefano Zampini #define __FUNCT__ "MatMultTranspose_HYPRE" 688ea9daf28SStefano Zampini static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 68963c07aadSStefano Zampini { 69063c07aadSStefano Zampini PetscErrorCode ierr; 69163c07aadSStefano Zampini 69263c07aadSStefano Zampini PetscFunctionBegin; 69363c07aadSStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 69463c07aadSStefano Zampini PetscFunctionReturn(0); 69563c07aadSStefano Zampini } 69663c07aadSStefano Zampini 69763c07aadSStefano Zampini #undef __FUNCT__ 69863c07aadSStefano Zampini #define __FUNCT__ "MatMult_HYPRE" 699ea9daf28SStefano Zampini static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 70063c07aadSStefano Zampini { 70163c07aadSStefano Zampini PetscErrorCode ierr; 70263c07aadSStefano Zampini 70363c07aadSStefano Zampini PetscFunctionBegin; 70463c07aadSStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 70563c07aadSStefano Zampini PetscFunctionReturn(0); 70663c07aadSStefano Zampini } 70763c07aadSStefano Zampini 70863c07aadSStefano Zampini #undef __FUNCT__ 70963c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_MultKernel_Private" 710ea9daf28SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, Vec x, Vec y, PetscBool trans) 71163c07aadSStefano Zampini { 71263c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 71363c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 71463c07aadSStefano Zampini hypre_ParVector *hx,*hy; 71563c07aadSStefano Zampini PetscScalar *ax,*ay,*sax,*say; 71663c07aadSStefano Zampini PetscErrorCode ierr; 71763c07aadSStefano Zampini 71863c07aadSStefano Zampini PetscFunctionBegin; 71963c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 72063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->x,(void**)&hx)); 72163c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->b,(void**)&hy)); 72263c07aadSStefano Zampini ierr = VecGetArrayRead(x,(const PetscScalar**)&ax);CHKERRQ(ierr); 72363c07aadSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 72463c07aadSStefano Zampini if (trans) { 72558968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,ay,say); 72658968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,ax,sax); 72763c07aadSStefano Zampini hypre_ParCSRMatrixMatvecT(1.,parcsr,hy,0.,hx); 72858968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,say,ay); 72958968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,sax,ax); 73063c07aadSStefano Zampini } else { 73158968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,ax,sax); 73258968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,ay,say); 73363c07aadSStefano Zampini hypre_ParCSRMatrixMatvec(1.,parcsr,hx,0.,hy); 73458968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,sax,ax); 73558968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,say,ay); 73663c07aadSStefano Zampini } 73763c07aadSStefano Zampini ierr = VecRestoreArrayRead(x,(const PetscScalar**)&ax);CHKERRQ(ierr); 73863c07aadSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 73963c07aadSStefano Zampini PetscFunctionReturn(0); 74063c07aadSStefano Zampini } 74163c07aadSStefano Zampini 74263c07aadSStefano Zampini #undef __FUNCT__ 74363c07aadSStefano Zampini #define __FUNCT__ "MatDestroy_HYPRE" 744ea9daf28SStefano Zampini static PetscErrorCode MatDestroy_HYPRE(Mat A) 74563c07aadSStefano Zampini { 74663c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 74763c07aadSStefano Zampini PetscErrorCode ierr; 74863c07aadSStefano Zampini 74963c07aadSStefano Zampini PetscFunctionBegin; 75063c07aadSStefano Zampini if (hA->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(hA->x)); 75163c07aadSStefano Zampini if (hA->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(hA->b)); 752978814f1SStefano Zampini if (hA->ij) { 753978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 754978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hA->ij)); 755978814f1SStefano Zampini } 75663c07aadSStefano Zampini if (hA->comm) { ierr = MPI_Comm_free(&hA->comm);CHKERRQ(ierr); } 75763c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_aij_C",NULL);CHKERRQ(ierr); 7582df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_is_C",NULL);CHKERRQ(ierr); 759c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatPtAP_seqaij_hypre_C",NULL);CHKERRQ(ierr); 760c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatPtAP_mpiaij_hypre_C",NULL);CHKERRQ(ierr); 76163c07aadSStefano Zampini ierr = PetscFree(A->data);CHKERRQ(ierr); 76263c07aadSStefano Zampini PetscFunctionReturn(0); 76363c07aadSStefano Zampini } 76463c07aadSStefano Zampini 76563c07aadSStefano Zampini #undef __FUNCT__ 76663c07aadSStefano Zampini #define __FUNCT__ "MatSetUp_HYPRE" 767ea9daf28SStefano Zampini static PetscErrorCode MatSetUp_HYPRE(Mat A) 76863c07aadSStefano Zampini { 76963c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 77063c07aadSStefano Zampini Vec x,b; 77163c07aadSStefano Zampini PetscErrorCode ierr; 77263c07aadSStefano Zampini 77363c07aadSStefano Zampini PetscFunctionBegin; 77463c07aadSStefano Zampini if (hA->x) PetscFunctionReturn(0); 77563c07aadSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 77663c07aadSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 77763c07aadSStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)A),1,A->cmap->n,A->cmap->N,NULL,&x);CHKERRQ(ierr); 77863c07aadSStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)A),1,A->rmap->n,A->rmap->N,NULL,&b);CHKERRQ(ierr); 77963c07aadSStefano Zampini ierr = VecHYPRE_IJVectorCreate(x,&hA->x);CHKERRQ(ierr); 78063c07aadSStefano Zampini ierr = VecHYPRE_IJVectorCreate(b,&hA->b);CHKERRQ(ierr); 78163c07aadSStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 78263c07aadSStefano Zampini ierr = VecDestroy(&b);CHKERRQ(ierr); 78363c07aadSStefano Zampini PetscFunctionReturn(0); 78463c07aadSStefano Zampini } 78563c07aadSStefano Zampini 78663c07aadSStefano Zampini #undef __FUNCT__ 78763c07aadSStefano Zampini #define __FUNCT__ "MatAssemblyEnd_HYPRE" 788ea9daf28SStefano Zampini static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 78963c07aadSStefano Zampini { 79063c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 79163c07aadSStefano Zampini PetscErrorCode ierr; 79263c07aadSStefano Zampini 79363c07aadSStefano Zampini PetscFunctionBegin; 79463c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixAssemble,(hA->ij)); 79563c07aadSStefano Zampini PetscFunctionReturn(0); 79663c07aadSStefano Zampini } 79763c07aadSStefano Zampini 798225daaf8SStefano Zampini /* 799225daaf8SStefano Zampini MatCreateFromParCSR - Creates a matrix from a hypre_ParCSRMatrix 800225daaf8SStefano Zampini 801225daaf8SStefano Zampini Collective 802225daaf8SStefano Zampini 803225daaf8SStefano Zampini Input Parameters: 804225daaf8SStefano Zampini + vparcsr - the pointer to the hypre_ParCSRMatrix 805bb4689ddSStefano Zampini . mtype - matrix type to be created. Currently MATAIJ, MATIS and MATHYPRE are supported. 806225daaf8SStefano Zampini - copymode - PETSc copying options 807225daaf8SStefano Zampini 808225daaf8SStefano Zampini Output Parameter: 809225daaf8SStefano Zampini . A - the matrix 810225daaf8SStefano Zampini 811225daaf8SStefano Zampini Level: intermediate 812225daaf8SStefano Zampini 813225daaf8SStefano Zampini .seealso: MatHYPRE, PetscCopyMode 814225daaf8SStefano Zampini */ 815978814f1SStefano Zampini #undef __FUNCT__ 816225daaf8SStefano Zampini #define __FUNCT__ "MatCreateFromParCSR" 817225daaf8SStefano Zampini PETSC_EXTERN PetscErrorCode MatCreateFromParCSR(void *vparcsr, MatType mtype, PetscCopyMode copymode, Mat* A) 818978814f1SStefano Zampini { 819225daaf8SStefano Zampini Mat T; 820978814f1SStefano Zampini Mat_HYPRE *hA; 82163c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 822978814f1SStefano Zampini MPI_Comm comm; 823978814f1SStefano Zampini PetscInt rstart,rend,cstart,cend,M,N; 824bb4689ddSStefano Zampini PetscBool isseqaij,ismpiaij,isaij,ishyp,isis; 825978814f1SStefano Zampini PetscErrorCode ierr; 826978814f1SStefano Zampini 827978814f1SStefano Zampini PetscFunctionBegin; 828978814f1SStefano Zampini parcsr = (hypre_ParCSRMatrix *)vparcsr; 829978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 830225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 831225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 832225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATAIJ,&isaij);CHKERRQ(ierr); 833225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATHYPRE,&ishyp);CHKERRQ(ierr); 8348cfe8d00SStefano Zampini ierr = PetscStrcmp(mtype,MATIS,&isis);CHKERRQ(ierr); 835225daaf8SStefano Zampini isaij = (PetscBool)(isseqaij || ismpiaij || isaij); 836bb4689ddSStefano Zampini if (!isaij && !ishyp && !isis) SETERRQ6(comm,PETSC_ERR_SUP,"Unsupported MatType %s! Supported types are %s, %s, %s, %s, and %s",mtype,MATAIJ,MATSEQAIJ,MATMPIAIJ,MATIS,MATHYPRE); 837225daaf8SStefano Zampini if (ishyp && copymode == PETSC_COPY_VALUES) SETERRQ(comm,PETSC_ERR_SUP,"Unsupported copymode PETSC_COPY_VALUES"); 838978814f1SStefano Zampini 839978814f1SStefano Zampini /* access ParCSRMatrix */ 840978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 841978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 842978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 843978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 844978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 845978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 846978814f1SStefano Zampini 847978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 848225daaf8SStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 849225daaf8SStefano Zampini ierr = MatSetSizes(T,rend-rstart+1,cend-cstart+1,M,N);CHKERRQ(ierr); 850225daaf8SStefano Zampini ierr = MatSetType(T,MATHYPRE);CHKERRQ(ierr); 851225daaf8SStefano Zampini ierr = MatSetUp(T);CHKERRQ(ierr); 852225daaf8SStefano Zampini hA = (Mat_HYPRE*)(T->data); 853978814f1SStefano Zampini 854978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 855978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 856978814f1SStefano Zampini 857978814f1SStefano Zampini /* set ParCSR object */ 858978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 859978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 860978814f1SStefano Zampini 861978814f1SStefano Zampini /* set assembled flag */ 862978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 863978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 864225daaf8SStefano Zampini if (ishyp) { 865978814f1SStefano Zampini /* prevent from freeing the pointer */ 866978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 867225daaf8SStefano Zampini *A = T; 868978814f1SStefano Zampini ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 869978814f1SStefano Zampini ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 870bb4689ddSStefano Zampini } else if (isaij) { 871bb4689ddSStefano Zampini if (copymode != PETSC_OWN_POINTER) { 872225daaf8SStefano Zampini /* prevent from freeing the pointer */ 873225daaf8SStefano Zampini hA->inner_free = PETSC_FALSE; 874225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 875225daaf8SStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 876225daaf8SStefano Zampini } else { /* AIJ return type with PETSC_OWN_POINTER */ 877225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INPLACE_MATRIX,&T);CHKERRQ(ierr); 878225daaf8SStefano Zampini *A = T; 879225daaf8SStefano Zampini } 880bb4689ddSStefano Zampini } else if (isis) { 8818cfe8d00SStefano Zampini ierr = MatConvert_HYPRE_IS(T,MATIS,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 8828cfe8d00SStefano Zampini if (copymode != PETSC_OWN_POINTER) hA->inner_free = PETSC_FALSE; 883bb4689ddSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 884bb4689ddSStefano Zampini } 885978814f1SStefano Zampini PetscFunctionReturn(0); 886978814f1SStefano Zampini } 887978814f1SStefano Zampini 88863c07aadSStefano Zampini #undef __FUNCT__ 88963c07aadSStefano Zampini #define __FUNCT__ "MatCreate_HYPRE" 89063c07aadSStefano Zampini PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 89163c07aadSStefano Zampini { 89263c07aadSStefano Zampini Mat_HYPRE *hB; 89363c07aadSStefano Zampini PetscErrorCode ierr; 89463c07aadSStefano Zampini 89563c07aadSStefano Zampini PetscFunctionBegin; 89663c07aadSStefano Zampini ierr = PetscNewLog(B,&hB);CHKERRQ(ierr); 897978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 898978814f1SStefano Zampini 89963c07aadSStefano Zampini B->data = (void*)hB; 90063c07aadSStefano Zampini B->rmap->bs = 1; 90163c07aadSStefano Zampini B->assembled = PETSC_FALSE; 90263c07aadSStefano Zampini 90363c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 90463c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 90563c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 90663c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 90763c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 908cd8bc7baSStefano Zampini B->ops->ptap = MatPtAP_HYPRE_HYPRE; 90963c07aadSStefano Zampini 91063c07aadSStefano Zampini ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)B),&hB->comm);CHKERRQ(ierr); 91163c07aadSStefano Zampini ierr = PetscObjectChangeTypeName((PetscObject)B,MATHYPRE);CHKERRQ(ierr); 91263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_aij_C",MatConvert_HYPRE_AIJ);CHKERRQ(ierr); 9132df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_is_C",MatConvert_HYPRE_IS);CHKERRQ(ierr); 914c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_hypre_C",MatPtAP_AIJ_HYPRE);CHKERRQ(ierr); 915c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_mpiaij_hypre_C",MatPtAP_AIJ_HYPRE);CHKERRQ(ierr); 91663c07aadSStefano Zampini PetscFunctionReturn(0); 91763c07aadSStefano Zampini } 91863c07aadSStefano Zampini 919225daaf8SStefano Zampini #undef __FUNCT__ 920225daaf8SStefano Zampini #define __FUNCT__ "hypre_array_destroy" 921225daaf8SStefano Zampini static PetscErrorCode hypre_array_destroy(void *ptr) 922225daaf8SStefano Zampini { 923225daaf8SStefano Zampini PetscFunctionBegin; 924225daaf8SStefano Zampini hypre_TFree(ptr); 925225daaf8SStefano Zampini PetscFunctionReturn(0); 926225daaf8SStefano Zampini } 927225daaf8SStefano Zampini 92863c07aadSStefano Zampini #if 0 92963c07aadSStefano Zampini /* 93063c07aadSStefano Zampini Does NOT copy the data over, instead uses DIRECTLY the pointers from the PETSc MPIAIJ format 93163c07aadSStefano Zampini 93263c07aadSStefano Zampini This is UNFINISHED and does NOT work! The problem is that hypre puts the diagonal entry first 93363c07aadSStefano Zampini which will corrupt the PETSc data structure if we did this. Need a work around to this problem. 93463c07aadSStefano Zampini */ 93563c07aadSStefano Zampini #include <_hypre_IJ_mv.h> 93663c07aadSStefano Zampini #include <HYPRE_IJ_mv.h> 93763c07aadSStefano Zampini 93863c07aadSStefano Zampini #undef __FUNCT__ 93963c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixLink" 94063c07aadSStefano Zampini PetscErrorCode MatHYPRE_IJMatrixLink(Mat A, HYPRE_IJMatrix *ij) 94163c07aadSStefano Zampini { 94263c07aadSStefano Zampini PetscErrorCode ierr; 94363c07aadSStefano Zampini PetscInt rstart,rend,cstart,cend; 94463c07aadSStefano Zampini PetscBool flg; 94563c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 94663c07aadSStefano Zampini 94763c07aadSStefano Zampini PetscFunctionBegin; 94863c07aadSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 94963c07aadSStefano Zampini PetscValidType(A,1); 95063c07aadSStefano Zampini PetscValidPointer(ij,2); 95163c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr); 95263c07aadSStefano Zampini if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Can only use with PETSc MPIAIJ matrices"); 95363c07aadSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 95463c07aadSStefano Zampini 95563c07aadSStefano Zampini ierr = PetscLogEventBegin(MAT_Convert,A,0,0,0);CHKERRQ(ierr); 95663c07aadSStefano Zampini rstart = A->rmap->rstart; 95763c07aadSStefano Zampini rend = A->rmap->rend; 95863c07aadSStefano Zampini cstart = A->cmap->rstart; 95963c07aadSStefano Zampini cend = A->cmap->rend; 96063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(PetscObjectComm((PetscObject)A),rstart,rend-1,cstart,cend-1,ij)); 96163c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(*ij,HYPRE_PARCSR)); 96263c07aadSStefano Zampini 96363c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(*ij)); 96463c07aadSStefano Zampini PetscStackCall("hypre_IJMatrixTranslator",aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(*ij)); 96563c07aadSStefano Zampini 96663c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 96763c07aadSStefano Zampini 96863c07aadSStefano Zampini /* this is the Hack part where we monkey directly with the hypre datastructures */ 96963c07aadSStefano Zampini 97063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixAssemble,(*ij)); 97163c07aadSStefano Zampini ierr = PetscLogEventEnd(MAT_Convert,A,0,0,0);CHKERRQ(ierr); 97263c07aadSStefano Zampini PetscFunctionReturn(0); 97363c07aadSStefano Zampini } 97463c07aadSStefano Zampini #endif 975