163c07aadSStefano Zampini 263c07aadSStefano Zampini /* 363c07aadSStefano Zampini Creates hypre ijmatrix from PETSc matrix 463c07aadSStefano Zampini */ 5225daaf8SStefano Zampini 6*c6698e78SStefano Zampini #include <petscpkg_version.h> 7dd9c0a25Sstefano_zampini #include <petscmathypre.h> 863c07aadSStefano Zampini #include <petsc/private/matimpl.h> 963c07aadSStefano Zampini #include <../src/mat/impls/hypre/mhypre.h> 1063c07aadSStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 1158968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h> 1258968eb6SStefano Zampini #include <HYPRE.h> 13c1a070e6SStefano Zampini #include <HYPRE_utilities.h> 14cd8bc7baSStefano Zampini #include <_hypre_parcsr_ls.h> 1568ec7858SStefano Zampini #include <_hypre_sstruct_ls.h> 1663c07aadSStefano Zampini 1775d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat,Mat,MatReuse,PetscReal,Mat*); 1875d48cdbSStefano Zampini 1963c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat,Mat_HYPRE*); 2063c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat,Mat,HYPRE_IJMatrix); 2163c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat,HYPRE_IJMatrix); 2263c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat,HYPRE_IJMatrix); 23414bd5c3SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat,PetscScalar,Vec,PetscScalar,Vec,PetscBool); 24225daaf8SStefano Zampini static PetscErrorCode hypre_array_destroy(void*); 25c69f721fSFande Kong PetscErrorCode MatSetValues_HYPRE(Mat, PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],InsertMode ins); 2663c07aadSStefano Zampini 2763c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat A_d, Mat A_o, HYPRE_IJMatrix ij) 2863c07aadSStefano Zampini { 2963c07aadSStefano Zampini PetscErrorCode ierr; 3063c07aadSStefano Zampini PetscInt i,n_d,n_o; 3163c07aadSStefano Zampini const PetscInt *ia_d,*ia_o; 3263c07aadSStefano Zampini PetscBool done_d=PETSC_FALSE,done_o=PETSC_FALSE; 3363c07aadSStefano Zampini PetscInt *nnz_d=NULL,*nnz_o=NULL; 3463c07aadSStefano Zampini 3563c07aadSStefano Zampini PetscFunctionBegin; 3663c07aadSStefano Zampini if (A_d) { /* determine number of nonzero entries in local diagonal part */ 3763c07aadSStefano Zampini ierr = MatGetRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,&n_d,&ia_d,NULL,&done_d);CHKERRQ(ierr); 3863c07aadSStefano Zampini if (done_d) { 3963c07aadSStefano Zampini ierr = PetscMalloc1(n_d,&nnz_d);CHKERRQ(ierr); 4063c07aadSStefano Zampini for (i=0; i<n_d; i++) { 4163c07aadSStefano Zampini nnz_d[i] = ia_d[i+1] - ia_d[i]; 4263c07aadSStefano Zampini } 4363c07aadSStefano Zampini } 4463c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,NULL,&ia_d,NULL,&done_d);CHKERRQ(ierr); 4563c07aadSStefano Zampini } 4663c07aadSStefano Zampini if (A_o) { /* determine number of nonzero entries in local off-diagonal part */ 4763c07aadSStefano Zampini ierr = MatGetRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 4863c07aadSStefano Zampini if (done_o) { 4963c07aadSStefano Zampini ierr = PetscMalloc1(n_o,&nnz_o);CHKERRQ(ierr); 5063c07aadSStefano Zampini for (i=0; i<n_o; i++) { 5163c07aadSStefano Zampini nnz_o[i] = ia_o[i+1] - ia_o[i]; 5263c07aadSStefano Zampini } 5363c07aadSStefano Zampini } 5463c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 5563c07aadSStefano Zampini } 5663c07aadSStefano Zampini if (done_d) { /* set number of nonzeros in HYPRE IJ matrix */ 5763c07aadSStefano Zampini if (!done_o) { /* only diagonal part */ 5863c07aadSStefano Zampini ierr = PetscMalloc1(n_d,&nnz_o);CHKERRQ(ierr); 5963c07aadSStefano Zampini for (i=0; i<n_d; i++) { 6063c07aadSStefano Zampini nnz_o[i] = 0; 6163c07aadSStefano Zampini } 6263c07aadSStefano Zampini } 63*c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,16,0) 64*c6698e78SStefano Zampini { /* If we don't do this, the columns of the matrix will be all zeros! */ 65*c6698e78SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 66*c6698e78SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 67*c6698e78SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 68*c6698e78SStefano Zampini hypre_IJMatrixTranslator(ij) = NULL; 6963c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(ij,(HYPRE_Int *)nnz_d,(HYPRE_Int *)nnz_o)); 70*c6698e78SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 71*c6698e78SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; 72*c6698e78SStefano Zampini } 73*c6698e78SStefano Zampini #else 74*c6698e78SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(ij,(HYPRE_Int *)nnz_d,(HYPRE_Int *)nnz_o)); 75*c6698e78SStefano Zampini #endif 7663c07aadSStefano Zampini ierr = PetscFree(nnz_d);CHKERRQ(ierr); 7763c07aadSStefano Zampini ierr = PetscFree(nnz_o);CHKERRQ(ierr); 7863c07aadSStefano Zampini } 7963c07aadSStefano Zampini PetscFunctionReturn(0); 8063c07aadSStefano Zampini } 8163c07aadSStefano Zampini 8263c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat A, Mat_HYPRE *hA) 8363c07aadSStefano Zampini { 8463c07aadSStefano Zampini PetscErrorCode ierr; 8563c07aadSStefano Zampini PetscInt rstart,rend,cstart,cend; 8663c07aadSStefano Zampini 8763c07aadSStefano Zampini PetscFunctionBegin; 88d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 89d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 9063c07aadSStefano Zampini rstart = A->rmap->rstart; 9163c07aadSStefano Zampini rend = A->rmap->rend; 9263c07aadSStefano Zampini cstart = A->cmap->rstart; 9363c07aadSStefano Zampini cend = A->cmap->rend; 9463c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 9563c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 9663c07aadSStefano Zampini { 9763c07aadSStefano Zampini PetscBool same; 9863c07aadSStefano Zampini Mat A_d,A_o; 9963c07aadSStefano Zampini const PetscInt *colmap; 10063c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&same);CHKERRQ(ierr); 10163c07aadSStefano Zampini if (same) { 10263c07aadSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 10363c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 10463c07aadSStefano Zampini PetscFunctionReturn(0); 10563c07aadSStefano Zampini } 10663c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&same);CHKERRQ(ierr); 10763c07aadSStefano Zampini if (same) { 10863c07aadSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 10963c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 11063c07aadSStefano Zampini PetscFunctionReturn(0); 11163c07aadSStefano Zampini } 11263c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&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 ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&same);CHKERRQ(ierr); 11863c07aadSStefano Zampini if (same) { 11963c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A,NULL,hA->ij);CHKERRQ(ierr); 12063c07aadSStefano Zampini PetscFunctionReturn(0); 12163c07aadSStefano Zampini } 12263c07aadSStefano Zampini } 12363c07aadSStefano Zampini PetscFunctionReturn(0); 12463c07aadSStefano Zampini } 12563c07aadSStefano Zampini 12663c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopy(Mat A, HYPRE_IJMatrix ij) 12763c07aadSStefano Zampini { 12863c07aadSStefano Zampini PetscErrorCode ierr; 12963c07aadSStefano Zampini PetscInt i,rstart,rend,ncols,nr,nc; 13063c07aadSStefano Zampini const PetscScalar *values; 13163c07aadSStefano Zampini const PetscInt *cols; 13263c07aadSStefano Zampini PetscBool flg; 13363c07aadSStefano Zampini 13463c07aadSStefano Zampini PetscFunctionBegin; 13563c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr); 13663c07aadSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 13763c07aadSStefano Zampini if (flg && nr == nc) { 13863c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_MPIAIJ(A,ij);CHKERRQ(ierr); 13963c07aadSStefano Zampini PetscFunctionReturn(0); 14063c07aadSStefano Zampini } 14163c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr); 14263c07aadSStefano Zampini if (flg) { 14363c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_SeqAIJ(A,ij);CHKERRQ(ierr); 14463c07aadSStefano Zampini PetscFunctionReturn(0); 14563c07aadSStefano Zampini } 14663c07aadSStefano Zampini 14763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 14863c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 14963c07aadSStefano Zampini for (i=rstart; i<rend; i++) { 15063c07aadSStefano Zampini ierr = MatGetRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 151e3977e59Sstefano_zampini if (ncols) { 15263c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetValues,(ij,1,(HYPRE_Int *)&ncols,(HYPRE_Int *)&i,(HYPRE_Int *)cols,values)); 153e3977e59Sstefano_zampini } 15463c07aadSStefano Zampini ierr = MatRestoreRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 15563c07aadSStefano Zampini } 15663c07aadSStefano Zampini PetscFunctionReturn(0); 15763c07aadSStefano Zampini } 15863c07aadSStefano Zampini 15963c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat A, HYPRE_IJMatrix ij) 16063c07aadSStefano Zampini { 16163c07aadSStefano Zampini PetscErrorCode ierr; 16263c07aadSStefano Zampini Mat_SeqAIJ *pdiag = (Mat_SeqAIJ*)A->data; 16358968eb6SStefano Zampini HYPRE_Int type; 16463c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 16563c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 16663c07aadSStefano Zampini hypre_CSRMatrix *hdiag; 16763c07aadSStefano Zampini 16863c07aadSStefano Zampini PetscFunctionBegin; 16963c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 170ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 171ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 172ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 17363c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 17463c07aadSStefano Zampini /* 17563c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 17663c07aadSStefano Zampini */ 1771d4906efSStefano Zampini ierr = PetscMemcpy(hdiag->i,pdiag->i,(A->rmap->n + 1)*sizeof(PetscInt));CHKERRQ(ierr); 1781d4906efSStefano Zampini ierr = PetscMemcpy(hdiag->j,pdiag->j,pdiag->nz*sizeof(PetscInt));CHKERRQ(ierr); 1791d4906efSStefano Zampini ierr = PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar));CHKERRQ(ierr); 180ea9daf28SStefano Zampini 181ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 18263c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 18363c07aadSStefano Zampini PetscFunctionReturn(0); 18463c07aadSStefano Zampini } 18563c07aadSStefano Zampini 18663c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat A, HYPRE_IJMatrix ij) 18763c07aadSStefano Zampini { 18863c07aadSStefano Zampini PetscErrorCode ierr; 18963c07aadSStefano Zampini Mat_MPIAIJ *pA = (Mat_MPIAIJ*)A->data; 19063c07aadSStefano Zampini Mat_SeqAIJ *pdiag,*poffd; 19163c07aadSStefano Zampini PetscInt i,*garray = pA->garray,*jj,cstart,*pjj; 19258968eb6SStefano Zampini HYPRE_Int type; 19363c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 19463c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 19563c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 19663c07aadSStefano Zampini 19763c07aadSStefano Zampini PetscFunctionBegin; 19863c07aadSStefano Zampini pdiag = (Mat_SeqAIJ*) pA->A->data; 19963c07aadSStefano Zampini poffd = (Mat_SeqAIJ*) pA->B->data; 20063c07aadSStefano Zampini /* cstart is only valid for square MPIAIJ layed out in the usual way */ 20163c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&cstart,NULL);CHKERRQ(ierr); 20263c07aadSStefano Zampini 20363c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 204ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 205ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 206ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 20763c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 20863c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(par_matrix); 20963c07aadSStefano Zampini 21063c07aadSStefano Zampini /* 21163c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 21263c07aadSStefano Zampini */ 21363c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->i,pdiag->i,(pA->A->rmap->n + 1)*sizeof(PetscInt)); 21463c07aadSStefano Zampini /* need to shift the diag column indices (hdiag->j) back to global numbering since hypre is expecting this */ 21563c07aadSStefano Zampini jj = (PetscInt*)hdiag->j; 21663c07aadSStefano Zampini pjj = (PetscInt*)pdiag->j; 217*c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,16,0) 218*c6698e78SStefano Zampini for (i=0; i<pdiag->nz; i++) jj[i] = pjj[i]; 219*c6698e78SStefano Zampini #else 22063c07aadSStefano Zampini for (i=0; i<pdiag->nz; i++) jj[i] = cstart + pjj[i]; 221*c6698e78SStefano Zampini #endif 22263c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar)); 22363c07aadSStefano Zampini ierr = PetscMemcpy(hoffd->i,poffd->i,(pA->A->rmap->n + 1)*sizeof(PetscInt)); 22463c07aadSStefano Zampini /* need to move the offd column indices (hoffd->j) back to global numbering since hypre is expecting this 22563c07aadSStefano Zampini If we hacked a hypre a bit more we might be able to avoid this step */ 226*c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,16,0) 227*c6698e78SStefano Zampini PetscStackCallStandard(hypre_CSRMatrixBigInitialize,(hoffd)); 228*c6698e78SStefano Zampini jj = (PetscInt*) hoffd->big_j; 229*c6698e78SStefano Zampini #else 23063c07aadSStefano Zampini jj = (PetscInt*) hoffd->j; 231*c6698e78SStefano Zampini #endif 23263c07aadSStefano Zampini pjj = (PetscInt*) poffd->j; 23363c07aadSStefano Zampini for (i=0; i<poffd->nz; i++) jj[i] = garray[pjj[i]]; 234*c6698e78SStefano Zampini 23563c07aadSStefano Zampini ierr = PetscMemcpy(hoffd->data,poffd->a,poffd->nz*sizeof(PetscScalar)); 23663c07aadSStefano Zampini 237ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 23863c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 23963c07aadSStefano Zampini PetscFunctionReturn(0); 24063c07aadSStefano Zampini } 24163c07aadSStefano Zampini 2422df22349SStefano Zampini static PetscErrorCode MatConvert_HYPRE_IS(Mat A, MatType mtype, MatReuse reuse, Mat* B) 2432df22349SStefano Zampini { 2442df22349SStefano Zampini Mat_HYPRE* mhA = (Mat_HYPRE*)(A->data); 2452df22349SStefano Zampini Mat lA; 2462df22349SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2472df22349SStefano Zampini IS is; 2482df22349SStefano Zampini hypre_ParCSRMatrix *hA; 2492df22349SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 2502df22349SStefano Zampini MPI_Comm comm; 2512df22349SStefano Zampini PetscScalar *hdd,*hod,*aa,*data; 2527d968826Sstefano_zampini HYPRE_Int *col_map_offd,*hdi,*hdj,*hoi,*hoj; 2532df22349SStefano Zampini PetscInt *ii,*jj,*iptr,*jptr; 2542df22349SStefano Zampini PetscInt cum,dr,dc,oc,str,stc,nnz,i,jd,jo,M,N; 25558968eb6SStefano Zampini HYPRE_Int type; 2562df22349SStefano Zampini PetscErrorCode ierr; 2572df22349SStefano Zampini 2582df22349SStefano Zampini PetscFunctionBegin; 259a1787963SStefano Zampini comm = PetscObjectComm((PetscObject)A); 2602df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(mhA->ij,&type)); 2612df22349SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 2622df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(mhA->ij,(void**)&hA)); 2632df22349SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(hA); 2642df22349SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(hA); 2652df22349SStefano Zampini str = hypre_ParCSRMatrixFirstRowIndex(hA); 2662df22349SStefano Zampini stc = hypre_ParCSRMatrixFirstColDiag(hA); 2672df22349SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(hA); 2682df22349SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(hA); 2692df22349SStefano Zampini dr = hypre_CSRMatrixNumRows(hdiag); 2702df22349SStefano Zampini dc = hypre_CSRMatrixNumCols(hdiag); 2712df22349SStefano Zampini nnz = hypre_CSRMatrixNumNonzeros(hdiag); 2722df22349SStefano Zampini hdi = hypre_CSRMatrixI(hdiag); 2732df22349SStefano Zampini hdj = hypre_CSRMatrixJ(hdiag); 2742df22349SStefano Zampini hdd = hypre_CSRMatrixData(hdiag); 2752df22349SStefano Zampini oc = hypre_CSRMatrixNumCols(hoffd); 2762df22349SStefano Zampini nnz += hypre_CSRMatrixNumNonzeros(hoffd); 2772df22349SStefano Zampini hoi = hypre_CSRMatrixI(hoffd); 2782df22349SStefano Zampini hoj = hypre_CSRMatrixJ(hoffd); 2792df22349SStefano Zampini hod = hypre_CSRMatrixData(hoffd); 2802df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2812df22349SStefano Zampini PetscInt *aux; 2822df22349SStefano Zampini 2832df22349SStefano Zampini /* generate l2g maps for rows and cols */ 2842df22349SStefano Zampini ierr = ISCreateStride(comm,dr,str,1,&is);CHKERRQ(ierr); 2852df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2862df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2872df22349SStefano Zampini col_map_offd = hypre_ParCSRMatrixColMapOffd(hA); 2882df22349SStefano Zampini ierr = PetscMalloc1(dc+oc,&aux);CHKERRQ(ierr); 2892df22349SStefano Zampini for (i=0; i<dc; i++) aux[i] = i+stc; 2902df22349SStefano Zampini for (i=0; i<oc; i++) aux[i+dc] = col_map_offd[i]; 2912df22349SStefano Zampini ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2922df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2932df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2942df22349SStefano Zampini /* create MATIS object */ 2952df22349SStefano Zampini ierr = MatCreate(comm,B);CHKERRQ(ierr); 2962df22349SStefano Zampini ierr = MatSetSizes(*B,dr,dc,M,N);CHKERRQ(ierr); 2972df22349SStefano Zampini ierr = MatSetType(*B,MATIS);CHKERRQ(ierr); 2982df22349SStefano Zampini ierr = MatSetLocalToGlobalMapping(*B,rl2g,cl2g);CHKERRQ(ierr); 2992df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3002df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3012df22349SStefano Zampini 3022df22349SStefano Zampini /* allocate CSR for local matrix */ 3032df22349SStefano Zampini ierr = PetscMalloc1(dr+1,&iptr);CHKERRQ(ierr); 3042df22349SStefano Zampini ierr = PetscMalloc1(nnz,&jptr);CHKERRQ(ierr); 3052df22349SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 3062df22349SStefano Zampini } else { 3072df22349SStefano Zampini PetscInt nr; 3082df22349SStefano Zampini PetscBool done; 3092df22349SStefano Zampini ierr = MatISGetLocalMat(*B,&lA);CHKERRQ(ierr); 3102df22349SStefano Zampini ierr = MatGetRowIJ(lA,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&iptr,(const PetscInt**)&jptr,&done);CHKERRQ(ierr); 3112df22349SStefano 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); 3122df22349SStefano 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); 3132df22349SStefano Zampini ierr = MatSeqAIJGetArray(lA,&data);CHKERRQ(ierr); 3142df22349SStefano Zampini } 3152df22349SStefano Zampini /* merge local matrices */ 3162df22349SStefano Zampini ii = iptr; 3172df22349SStefano Zampini jj = jptr; 3182df22349SStefano Zampini aa = data; 3192df22349SStefano Zampini *ii = *(hdi++) + *(hoi++); 3202df22349SStefano Zampini for (jd=0,jo=0,cum=0; *ii<nnz; cum++) { 3212df22349SStefano Zampini PetscScalar *aold = aa; 3222df22349SStefano Zampini PetscInt *jold = jj,nc = jd+jo; 3232df22349SStefano Zampini for (; jd<*hdi; jd++) { *jj++ = *hdj++; *aa++ = *hdd++; } 3242df22349SStefano Zampini for (; jo<*hoi; jo++) { *jj++ = *hoj++ + dc; *aa++ = *hod++; } 3252df22349SStefano Zampini *(++ii) = *(hdi++) + *(hoi++); 3262df22349SStefano Zampini ierr = PetscSortIntWithScalarArray(jd+jo-nc,jold,aold);CHKERRQ(ierr); 3272df22349SStefano Zampini } 3282df22349SStefano Zampini for (; cum<dr; cum++) *(++ii) = nnz; 3292df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 330a033916dSStefano Zampini Mat_SeqAIJ* a; 331a033916dSStefano Zampini 3322df22349SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,dc+oc,iptr,jptr,data,&lA);CHKERRQ(ierr); 3332df22349SStefano Zampini ierr = MatISSetLocalMat(*B,lA);CHKERRQ(ierr); 334a033916dSStefano Zampini /* hack SeqAIJ */ 335a033916dSStefano Zampini a = (Mat_SeqAIJ*)(lA->data); 336a033916dSStefano Zampini a->free_a = PETSC_TRUE; 337a033916dSStefano Zampini a->free_ij = PETSC_TRUE; 3382df22349SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 3392df22349SStefano Zampini } 3402df22349SStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3412df22349SStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3422df22349SStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 3432df22349SStefano Zampini ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); 3442df22349SStefano Zampini } 3452df22349SStefano Zampini PetscFunctionReturn(0); 3462df22349SStefano Zampini } 3472df22349SStefano Zampini 34863c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A, MatType type, MatReuse reuse, Mat *B) 34963c07aadSStefano Zampini { 35084d4e069SStefano Zampini Mat M = NULL; 35163c07aadSStefano Zampini Mat_HYPRE *hB; 35263c07aadSStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 35363c07aadSStefano Zampini PetscErrorCode ierr; 35463c07aadSStefano Zampini 35563c07aadSStefano Zampini PetscFunctionBegin; 35663c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 35763c07aadSStefano Zampini /* always destroy the old matrix and create a new memory; 35863c07aadSStefano Zampini hope this does not churn the memory too much. The problem 35963c07aadSStefano Zampini is I do not know if it is possible to put the matrix back to 36063c07aadSStefano Zampini its initial state so that we can directly copy the values 36163c07aadSStefano Zampini the second time through. */ 36263c07aadSStefano Zampini hB = (Mat_HYPRE*)((*B)->data); 36363c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hB->ij)); 36463c07aadSStefano Zampini } else { 36584d4e069SStefano Zampini ierr = MatCreate(comm,&M);CHKERRQ(ierr); 36684d4e069SStefano Zampini ierr = MatSetType(M,MATHYPRE);CHKERRQ(ierr); 36784d4e069SStefano Zampini ierr = MatSetSizes(M,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 36884d4e069SStefano Zampini hB = (Mat_HYPRE*)(M->data); 36984d4e069SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 37063c07aadSStefano Zampini } 37163c07aadSStefano Zampini ierr = MatHYPRE_CreateFromMat(A,hB);CHKERRQ(ierr); 37263c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,hB->ij);CHKERRQ(ierr); 37384d4e069SStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 37484d4e069SStefano Zampini ierr = MatHeaderReplace(A,&M);CHKERRQ(ierr); 37584d4e069SStefano Zampini } 3764ec6421dSstefano_zampini (*B)->preallocated = PETSC_TRUE; 37763c07aadSStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 37863c07aadSStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 37963c07aadSStefano Zampini PetscFunctionReturn(0); 38063c07aadSStefano Zampini } 38163c07aadSStefano Zampini 382ea9daf28SStefano Zampini static PetscErrorCode MatConvert_HYPRE_AIJ(Mat A, MatType mtype, MatReuse reuse, Mat *B) 38363c07aadSStefano Zampini { 38463c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 38563c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 38663c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 38763c07aadSStefano Zampini MPI_Comm comm; 38863c07aadSStefano Zampini PetscScalar *da,*oa,*aptr; 38963c07aadSStefano Zampini PetscInt *dii,*djj,*oii,*ojj,*iptr; 39063c07aadSStefano Zampini PetscInt i,dnnz,onnz,m,n; 39158968eb6SStefano Zampini HYPRE_Int type; 39263c07aadSStefano Zampini PetscMPIInt size; 39363c07aadSStefano Zampini PetscErrorCode ierr; 39463c07aadSStefano Zampini 39563c07aadSStefano Zampini PetscFunctionBegin; 39663c07aadSStefano Zampini comm = PetscObjectComm((PetscObject)A); 39763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 39863c07aadSStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 39963c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 40063c07aadSStefano Zampini PetscBool ismpiaij,isseqaij; 40163c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 4024099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)*B,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 40363c07aadSStefano Zampini if (!ismpiaij && !isseqaij) SETERRQ(comm,PETSC_ERR_SUP,"Only MATMPIAIJ or MATSEQAIJ are supported"); 40463c07aadSStefano Zampini } 40563c07aadSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 40663c07aadSStefano Zampini 40763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 40863c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 40963c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 41063c07aadSStefano Zampini m = hypre_CSRMatrixNumRows(hdiag); 41163c07aadSStefano Zampini n = hypre_CSRMatrixNumCols(hdiag); 41263c07aadSStefano Zampini dnnz = hypre_CSRMatrixNumNonzeros(hdiag); 41363c07aadSStefano Zampini onnz = hypre_CSRMatrixNumNonzeros(hoffd); 414225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 41563c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&dii);CHKERRQ(ierr); 41663c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&djj);CHKERRQ(ierr); 41763c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&da);CHKERRQ(ierr); 418225daaf8SStefano Zampini } else if (reuse == MAT_REUSE_MATRIX) { 41963c07aadSStefano Zampini PetscInt nr; 42063c07aadSStefano Zampini PetscBool done; 42163c07aadSStefano Zampini if (size > 1) { 42263c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 42363c07aadSStefano Zampini 42463c07aadSStefano Zampini ierr = MatGetRowIJ(b->A,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 42563c07aadSStefano 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); 42663c07aadSStefano 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); 42763c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->A,&da);CHKERRQ(ierr); 42863c07aadSStefano Zampini } else { 42963c07aadSStefano Zampini ierr = MatGetRowIJ(*B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 43063c07aadSStefano Zampini if (nr != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows! %D != %D",nr,m); 43163c07aadSStefano 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); 43263c07aadSStefano Zampini ierr = MatSeqAIJGetArray(*B,&da);CHKERRQ(ierr); 43363c07aadSStefano Zampini } 434225daaf8SStefano Zampini } else { /* MAT_INPLACE_MATRIX */ 4357d968826Sstefano_zampini dii = (PetscInt*)hypre_CSRMatrixI(hdiag); 4367d968826Sstefano_zampini djj = (PetscInt*)hypre_CSRMatrixJ(hdiag); 437225daaf8SStefano Zampini da = hypre_CSRMatrixData(hdiag); 43863c07aadSStefano Zampini } 43963c07aadSStefano Zampini ierr = PetscMemcpy(dii,hypre_CSRMatrixI(hdiag),(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 44063c07aadSStefano Zampini ierr = PetscMemcpy(djj,hypre_CSRMatrixJ(hdiag),dnnz*sizeof(PetscInt));CHKERRQ(ierr); 44163c07aadSStefano Zampini ierr = PetscMemcpy(da,hypre_CSRMatrixData(hdiag),dnnz*sizeof(PetscScalar));CHKERRQ(ierr); 44263c07aadSStefano Zampini iptr = djj; 44363c07aadSStefano Zampini aptr = da; 44463c07aadSStefano Zampini for (i=0; i<m; i++) { 44563c07aadSStefano Zampini PetscInt nc = dii[i+1]-dii[i]; 44663c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 44763c07aadSStefano Zampini iptr += nc; 44863c07aadSStefano Zampini aptr += nc; 44963c07aadSStefano Zampini } 45063c07aadSStefano Zampini if (size > 1) { 4517d968826Sstefano_zampini HYPRE_Int *offdj,*coffd; 45263c07aadSStefano Zampini 453225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 45463c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&oii);CHKERRQ(ierr); 45563c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&ojj);CHKERRQ(ierr); 45663c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&oa);CHKERRQ(ierr); 457225daaf8SStefano Zampini } else if (reuse == MAT_REUSE_MATRIX) { 45863c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 45963c07aadSStefano Zampini PetscInt nr,hr = hypre_CSRMatrixNumRows(hoffd); 46063c07aadSStefano Zampini PetscBool done; 46163c07aadSStefano Zampini 46263c07aadSStefano Zampini ierr = MatGetRowIJ(b->B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&oii,(const PetscInt**)&ojj,&done);CHKERRQ(ierr); 46363c07aadSStefano 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); 46463c07aadSStefano 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); 46563c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->B,&oa);CHKERRQ(ierr); 466225daaf8SStefano Zampini } else { /* MAT_INPLACE_MATRIX */ 4677d968826Sstefano_zampini oii = (PetscInt*)hypre_CSRMatrixI(hoffd); 4687d968826Sstefano_zampini ojj = (PetscInt*)hypre_CSRMatrixJ(hoffd); 469225daaf8SStefano Zampini oa = hypre_CSRMatrixData(hoffd); 47063c07aadSStefano Zampini } 47163c07aadSStefano Zampini ierr = PetscMemcpy(oii,hypre_CSRMatrixI(hoffd),(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 47263c07aadSStefano Zampini offdj = hypre_CSRMatrixJ(hoffd); 47363c07aadSStefano Zampini coffd = hypre_ParCSRMatrixColMapOffd(parcsr); 47463c07aadSStefano Zampini for (i=0; i<onnz; i++) ojj[i] = coffd[offdj[i]]; 47563c07aadSStefano Zampini ierr = PetscMemcpy(oa,hypre_CSRMatrixData(hoffd),onnz*sizeof(PetscScalar));CHKERRQ(ierr); 47663c07aadSStefano Zampini iptr = ojj; 47763c07aadSStefano Zampini aptr = oa; 47863c07aadSStefano Zampini for (i=0; i<m; i++) { 47963c07aadSStefano Zampini PetscInt nc = oii[i+1]-oii[i]; 48063c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 48163c07aadSStefano Zampini iptr += nc; 48263c07aadSStefano Zampini aptr += nc; 48363c07aadSStefano Zampini } 484225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 48563c07aadSStefano Zampini Mat_MPIAIJ *b; 48663c07aadSStefano Zampini Mat_SeqAIJ *d,*o; 487225daaf8SStefano Zampini 48841073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,B);CHKERRQ(ierr); 48963c07aadSStefano Zampini /* hack MPIAIJ */ 49063c07aadSStefano Zampini b = (Mat_MPIAIJ*)((*B)->data); 49163c07aadSStefano Zampini d = (Mat_SeqAIJ*)b->A->data; 49263c07aadSStefano Zampini o = (Mat_SeqAIJ*)b->B->data; 49363c07aadSStefano Zampini d->free_a = PETSC_TRUE; 49463c07aadSStefano Zampini d->free_ij = PETSC_TRUE; 49563c07aadSStefano Zampini o->free_a = PETSC_TRUE; 49663c07aadSStefano Zampini o->free_ij = PETSC_TRUE; 497225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 498225daaf8SStefano Zampini Mat T; 49941073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,&T);CHKERRQ(ierr); 500225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 501225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 502225daaf8SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 503225daaf8SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 504225daaf8SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 505225daaf8SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 506225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 50763c07aadSStefano Zampini } 508225daaf8SStefano Zampini } else { 509225daaf8SStefano Zampini oii = NULL; 510225daaf8SStefano Zampini ojj = NULL; 511225daaf8SStefano Zampini oa = NULL; 512225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 51363c07aadSStefano Zampini Mat_SeqAIJ* b; 51463c07aadSStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,B);CHKERRQ(ierr); 51563c07aadSStefano Zampini /* hack SeqAIJ */ 51663c07aadSStefano Zampini b = (Mat_SeqAIJ*)((*B)->data); 51763c07aadSStefano Zampini b->free_a = PETSC_TRUE; 51863c07aadSStefano Zampini b->free_ij = PETSC_TRUE; 519225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 520225daaf8SStefano Zampini Mat T; 521225daaf8SStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,&T);CHKERRQ(ierr); 522225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 523225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 524225daaf8SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 525225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 52663c07aadSStefano Zampini } 527225daaf8SStefano Zampini } 528225daaf8SStefano Zampini 529225daaf8SStefano Zampini /* we have to use hypre_Tfree to free the arrays */ 53063c07aadSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 531225daaf8SStefano Zampini void *ptrs[6] = {dii,djj,da,oii,ojj,oa}; 532225daaf8SStefano Zampini const char *names[6] = {"_hypre_csr_dii", 533225daaf8SStefano Zampini "_hypre_csr_djj", 534225daaf8SStefano Zampini "_hypre_csr_da", 535225daaf8SStefano Zampini "_hypre_csr_oii", 536225daaf8SStefano Zampini "_hypre_csr_ojj", 537225daaf8SStefano Zampini "_hypre_csr_oa"}; 538225daaf8SStefano Zampini for (i=0; i<6; i++) { 539225daaf8SStefano Zampini PetscContainer c; 540225daaf8SStefano Zampini 541225daaf8SStefano Zampini ierr = PetscContainerCreate(comm,&c);CHKERRQ(ierr); 542225daaf8SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 543225daaf8SStefano Zampini ierr = PetscContainerSetUserDestroy(c,hypre_array_destroy);CHKERRQ(ierr); 544225daaf8SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*B),names[i],(PetscObject)c);CHKERRQ(ierr); 545225daaf8SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 546225daaf8SStefano Zampini } 54763c07aadSStefano Zampini } 54863c07aadSStefano Zampini PetscFunctionReturn(0); 54963c07aadSStefano Zampini } 55063c07aadSStefano Zampini 551613e5ff0Sstefano_zampini static PetscErrorCode MatAIJGetParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 552c1a070e6SStefano Zampini { 553613e5ff0Sstefano_zampini hypre_ParCSRMatrix *tA; 554c1a070e6SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 555c1a070e6SStefano Zampini Mat_SeqAIJ *diag,*offd; 556c1a070e6SStefano Zampini PetscInt *garray,noffd,dnnz,onnz,*row_starts,*col_starts; 557c1a070e6SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 558613e5ff0Sstefano_zampini PetscBool ismpiaij,isseqaij; 559c1a070e6SStefano Zampini PetscErrorCode ierr; 560c1a070e6SStefano Zampini 561c1a070e6SStefano Zampini PetscFunctionBegin; 562c1a070e6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 5634099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 564c1a070e6SStefano Zampini if (!ismpiaij && !isseqaij) SETERRQ1(comm,PETSC_ERR_SUP,"Unsupported type %s",((PetscObject)A)->type); 565c1a070e6SStefano Zampini if (ismpiaij) { 566c1a070e6SStefano Zampini Mat_MPIAIJ *a = (Mat_MPIAIJ*)(A->data); 567c1a070e6SStefano Zampini 568c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)a->A->data; 569c1a070e6SStefano Zampini offd = (Mat_SeqAIJ*)a->B->data; 570c1a070e6SStefano Zampini garray = a->garray; 571c1a070e6SStefano Zampini noffd = a->B->cmap->N; 572c1a070e6SStefano Zampini dnnz = diag->nz; 573c1a070e6SStefano Zampini onnz = offd->nz; 574c1a070e6SStefano Zampini } else { 575c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)A->data; 576c1a070e6SStefano Zampini offd = NULL; 577c1a070e6SStefano Zampini garray = NULL; 578c1a070e6SStefano Zampini noffd = 0; 579c1a070e6SStefano Zampini dnnz = diag->nz; 580c1a070e6SStefano Zampini onnz = 0; 581c1a070e6SStefano Zampini } 582225daaf8SStefano Zampini 583c1a070e6SStefano Zampini /* create a temporary ParCSR */ 584c1a070e6SStefano Zampini if (HYPRE_AssumedPartitionCheck()) { 585c1a070e6SStefano Zampini PetscMPIInt myid; 586c1a070e6SStefano Zampini 587c1a070e6SStefano Zampini ierr = MPI_Comm_rank(comm,&myid);CHKERRQ(ierr); 588c1a070e6SStefano Zampini row_starts = A->rmap->range + myid; 589c1a070e6SStefano Zampini col_starts = A->cmap->range + myid; 590c1a070e6SStefano Zampini } else { 591c1a070e6SStefano Zampini row_starts = A->rmap->range; 592c1a070e6SStefano Zampini col_starts = A->cmap->range; 593c1a070e6SStefano Zampini } 5947d968826Sstefano_zampini tA = hypre_ParCSRMatrixCreate(comm,A->rmap->N,A->cmap->N,(HYPRE_Int*)row_starts,(HYPRE_Int*)col_starts,noffd,dnnz,onnz); 595c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(tA,0); 596c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(tA,0); 597c1a070e6SStefano Zampini 598225daaf8SStefano Zampini /* set diagonal part */ 599c1a070e6SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(tA); 6007d968826Sstefano_zampini hypre_CSRMatrixI(hdiag) = (HYPRE_Int*)diag->i; 6017d968826Sstefano_zampini hypre_CSRMatrixJ(hdiag) = (HYPRE_Int*)diag->j; 602c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = diag->a; 603c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hdiag) = diag->nz; 604c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hdiag); 605c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hdiag,0); 606c1a070e6SStefano Zampini 607225daaf8SStefano Zampini /* set offdiagonal part */ 608c1a070e6SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(tA); 609c1a070e6SStefano Zampini if (offd) { 6107d968826Sstefano_zampini hypre_CSRMatrixI(hoffd) = (HYPRE_Int*)offd->i; 6117d968826Sstefano_zampini hypre_CSRMatrixJ(hoffd) = (HYPRE_Int*)offd->j; 612c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = offd->a; 613c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hoffd) = offd->nz; 614c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hoffd); 615c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hoffd,0); 616c1a070e6SStefano Zampini hypre_ParCSRMatrixSetNumNonzeros(tA); 6177d968826Sstefano_zampini hypre_ParCSRMatrixColMapOffd(tA) = (HYPRE_Int*)garray; 618c1a070e6SStefano Zampini } 619613e5ff0Sstefano_zampini *hA = tA; 620613e5ff0Sstefano_zampini PetscFunctionReturn(0); 621613e5ff0Sstefano_zampini } 622c1a070e6SStefano Zampini 623613e5ff0Sstefano_zampini static PetscErrorCode MatAIJRestoreParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 624613e5ff0Sstefano_zampini { 625613e5ff0Sstefano_zampini hypre_CSRMatrix *hdiag,*hoffd; 626c1a070e6SStefano Zampini 627613e5ff0Sstefano_zampini PetscFunctionBegin; 628613e5ff0Sstefano_zampini hdiag = hypre_ParCSRMatrixDiag(*hA); 629613e5ff0Sstefano_zampini hoffd = hypre_ParCSRMatrixOffd(*hA); 630c1a070e6SStefano Zampini /* set pointers to NULL before destroying tA */ 631c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 632c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 633c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 634c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 635c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 636c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 637613e5ff0Sstefano_zampini hypre_ParCSRMatrixColMapOffd(*hA) = NULL; 638613e5ff0Sstefano_zampini hypre_ParCSRMatrixDestroy(*hA); 639613e5ff0Sstefano_zampini *hA = NULL; 640613e5ff0Sstefano_zampini PetscFunctionReturn(0); 641613e5ff0Sstefano_zampini } 642613e5ff0Sstefano_zampini 643613e5ff0Sstefano_zampini /* calls RAP from BoomerAMG: 6443dad0653Sstefano_zampini the resulting ParCSR will not own the column and row starts 6453dad0653Sstefano_zampini It looks like we don't need to have the diagonal entries 6463dad0653Sstefano_zampini ordered first in the rows of the diagonal part 6473dad0653Sstefano_zampini for boomerAMGBuildCoarseOperator to work */ 648a055b5aaSBarry Smith static PetscErrorCode MatHYPRE_ParCSR_RAP(hypre_ParCSRMatrix *hR, hypre_ParCSRMatrix *hA,hypre_ParCSRMatrix *hP, hypre_ParCSRMatrix **hRAP) 649613e5ff0Sstefano_zampini { 650613e5ff0Sstefano_zampini HYPRE_Int P_owns_col_starts,R_owns_row_starts; 651613e5ff0Sstefano_zampini 652613e5ff0Sstefano_zampini PetscFunctionBegin; 653613e5ff0Sstefano_zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(hP); 654613e5ff0Sstefano_zampini R_owns_row_starts = hypre_ParCSRMatrixOwnsRowStarts(hR); 655613e5ff0Sstefano_zampini PetscStackCallStandard(hypre_BoomerAMGBuildCoarseOperator,(hR,hA,hP,hRAP)); 656613e5ff0Sstefano_zampini PetscStackCallStandard(hypre_ParCSRMatrixSetNumNonzeros,(*hRAP)); 657613e5ff0Sstefano_zampini /* hypre_BoomerAMGBuildCoarseOperator steals the col_starts from P and the row_starts from R */ 658613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetRowStartsOwner(*hRAP,0); 659613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetColStartsOwner(*hRAP,0); 660613e5ff0Sstefano_zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(hP,1); 661613e5ff0Sstefano_zampini if (R_owns_row_starts) hypre_ParCSRMatrixSetRowStartsOwner(hR,1); 662613e5ff0Sstefano_zampini PetscFunctionReturn(0); 663613e5ff0Sstefano_zampini } 664613e5ff0Sstefano_zampini 6656f231fbdSstefano_zampini static PetscErrorCode MatPtAPNumeric_AIJ_AIJ_wHYPRE(Mat A,Mat P,Mat C) 666613e5ff0Sstefano_zampini { 6676f231fbdSstefano_zampini Mat B; 668613e5ff0Sstefano_zampini hypre_ParCSRMatrix *hA,*hP,*hPtAP; 669613e5ff0Sstefano_zampini PetscErrorCode ierr; 670613e5ff0Sstefano_zampini 671613e5ff0Sstefano_zampini PetscFunctionBegin; 672613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 673613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(P,&hP);CHKERRQ(ierr); 674613e5ff0Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(hP,hA,hP,&hPtAP);CHKERRQ(ierr); 6756f231fbdSstefano_zampini ierr = MatCreateFromParCSR(hPtAP,MATAIJ,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 6766f231fbdSstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 677613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 678613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(P,&hP);CHKERRQ(ierr); 6796f231fbdSstefano_zampini PetscFunctionReturn(0); 6806f231fbdSstefano_zampini } 6816f231fbdSstefano_zampini 6826f231fbdSstefano_zampini PETSC_INTERN PetscErrorCode MatPtAPSymbolic_AIJ_AIJ_wHYPRE(Mat A,Mat P,PetscReal fill,Mat *C) 6836f231fbdSstefano_zampini { 6846f231fbdSstefano_zampini PetscErrorCode ierr; 685ab4d48faSStefano Zampini 6866f231fbdSstefano_zampini PetscFunctionBegin; 6876f231fbdSstefano_zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),C);CHKERRQ(ierr); 6886f231fbdSstefano_zampini ierr = MatSetType(*C,MATAIJ);CHKERRQ(ierr); 6896f231fbdSstefano_zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_AIJ_AIJ_wHYPRE; 690613e5ff0Sstefano_zampini PetscFunctionReturn(0); 691613e5ff0Sstefano_zampini } 692613e5ff0Sstefano_zampini 6934cc28894Sstefano_zampini static PetscErrorCode MatPtAPNumeric_AIJ_HYPRE(Mat A,Mat P,Mat C) 694613e5ff0Sstefano_zampini { 6954cc28894Sstefano_zampini Mat B; 6964cc28894Sstefano_zampini Mat_HYPRE *hP; 697613e5ff0Sstefano_zampini hypre_ParCSRMatrix *hA = NULL,*Pparcsr,*ptapparcsr; 698613e5ff0Sstefano_zampini HYPRE_Int type; 699613e5ff0Sstefano_zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 7004cc28894Sstefano_zampini PetscBool ishypre; 701613e5ff0Sstefano_zampini PetscErrorCode ierr; 702613e5ff0Sstefano_zampini 703613e5ff0Sstefano_zampini PetscFunctionBegin; 7044cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)P,MATHYPRE,&ishypre);CHKERRQ(ierr); 7054cc28894Sstefano_zampini if (!ishypre) SETERRQ1(comm,PETSC_ERR_USER,"P should be of type %s",MATHYPRE); 7064cc28894Sstefano_zampini hP = (Mat_HYPRE*)P->data; 707613e5ff0Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 708613e5ff0Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 709613e5ff0Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 710613e5ff0Sstefano_zampini 711613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 712613e5ff0Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(Pparcsr,hA,Pparcsr,&ptapparcsr);CHKERRQ(ierr); 713613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 714225daaf8SStefano Zampini 7154cc28894Sstefano_zampini /* create temporary matrix and merge to C */ 7164cc28894Sstefano_zampini ierr = MatCreateFromParCSR(ptapparcsr,((PetscObject)C)->type_name,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 7174cc28894Sstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 7184cc28894Sstefano_zampini PetscFunctionReturn(0); 7194cc28894Sstefano_zampini } 7204cc28894Sstefano_zampini 7214cc28894Sstefano_zampini static PetscErrorCode MatPtAP_AIJ_HYPRE(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 7224cc28894Sstefano_zampini { 7234cc28894Sstefano_zampini PetscErrorCode ierr; 7244cc28894Sstefano_zampini 7254cc28894Sstefano_zampini PetscFunctionBegin; 7264cc28894Sstefano_zampini if (scall == MAT_INITIAL_MATRIX) { 7274cc28894Sstefano_zampini const char *deft = MATAIJ; 7284cc28894Sstefano_zampini char type[256]; 7294cc28894Sstefano_zampini PetscBool flg; 7304cc28894Sstefano_zampini 7314cc28894Sstefano_zampini ierr = PetscObjectOptionsBegin((PetscObject)A);CHKERRQ(ierr); 7324cc28894Sstefano_zampini ierr = PetscOptionsFList("-matptap_hypre_outtype","Matrix type",NULL,MatList,deft,type,256,&flg);CHKERRQ(ierr); 7334cc28894Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 7344cc28894Sstefano_zampini ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 7354cc28894Sstefano_zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),C);CHKERRQ(ierr); 7364cc28894Sstefano_zampini if (flg) { 7374cc28894Sstefano_zampini ierr = MatSetType(*C,type);CHKERRQ(ierr); 7384cc28894Sstefano_zampini } else { 7394cc28894Sstefano_zampini ierr = MatSetType(*C,deft);CHKERRQ(ierr); 7404cc28894Sstefano_zampini } 7414cc28894Sstefano_zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_AIJ_HYPRE; 7424cc28894Sstefano_zampini ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 7434cc28894Sstefano_zampini } 7444cc28894Sstefano_zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 7454cc28894Sstefano_zampini ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 746613e5ff0Sstefano_zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 747c1a070e6SStefano Zampini PetscFunctionReturn(0); 748c1a070e6SStefano Zampini } 749c1a070e6SStefano Zampini 7504cc28894Sstefano_zampini static PetscErrorCode MatPtAPNumeric_HYPRE_HYPRE(Mat A,Mat P,Mat C) 7514cc28894Sstefano_zampini { 7524cc28894Sstefano_zampini Mat B; 7534cc28894Sstefano_zampini hypre_ParCSRMatrix *Aparcsr,*Pparcsr,*ptapparcsr; 7544cc28894Sstefano_zampini Mat_HYPRE *hA,*hP; 7554cc28894Sstefano_zampini PetscBool ishypre; 7564cc28894Sstefano_zampini HYPRE_Int type; 7574cc28894Sstefano_zampini PetscErrorCode ierr; 7584cc28894Sstefano_zampini 7594cc28894Sstefano_zampini PetscFunctionBegin; 7604cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)P,MATHYPRE,&ishypre);CHKERRQ(ierr); 7614cc28894Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)P),PETSC_ERR_USER,"P should be of type %s",MATHYPRE); 7624cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr); 7634cc28894Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"A should be of type %s",MATHYPRE); 7644cc28894Sstefano_zampini hA = (Mat_HYPRE*)A->data; 7654cc28894Sstefano_zampini hP = (Mat_HYPRE*)P->data; 7664cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 7674cc28894Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 7684cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 7694cc28894Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)P),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 7704cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&Aparcsr)); 7714cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 7724cc28894Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(Pparcsr,Aparcsr,Pparcsr,&ptapparcsr);CHKERRQ(ierr); 7734cc28894Sstefano_zampini ierr = MatCreateFromParCSR(ptapparcsr,MATHYPRE,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 7744cc28894Sstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 7754cc28894Sstefano_zampini PetscFunctionReturn(0); 7764cc28894Sstefano_zampini } 7774cc28894Sstefano_zampini 778cd8bc7baSStefano Zampini static PetscErrorCode MatPtAP_HYPRE_HYPRE(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 779cd8bc7baSStefano Zampini { 780cd8bc7baSStefano Zampini PetscErrorCode ierr; 781cd8bc7baSStefano Zampini 782cd8bc7baSStefano Zampini PetscFunctionBegin; 7834cc28894Sstefano_zampini if (scall == MAT_INITIAL_MATRIX) { 7844cc28894Sstefano_zampini ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 7854cc28894Sstefano_zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),C);CHKERRQ(ierr); 7864cc28894Sstefano_zampini ierr = MatSetType(*C,MATHYPRE);CHKERRQ(ierr); 7874cc28894Sstefano_zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_HYPRE_HYPRE; 7884cc28894Sstefano_zampini ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 7894cc28894Sstefano_zampini } 790613e5ff0Sstefano_zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 7914cc28894Sstefano_zampini ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 792613e5ff0Sstefano_zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 793cd8bc7baSStefano Zampini PetscFunctionReturn(0); 794cd8bc7baSStefano Zampini } 795cd8bc7baSStefano Zampini 796d501dc42Sstefano_zampini /* calls hypre_ParMatmul 797d501dc42Sstefano_zampini hypre_ParMatMul uses hypre_ParMatrixCreate with the communicator of hA 7983dad0653Sstefano_zampini hypre_ParMatrixCreate does not duplicate the communicator 7993dad0653Sstefano_zampini It looks like we don't need to have the diagonal entries 8003dad0653Sstefano_zampini ordered first in the rows of the diagonal part 8013dad0653Sstefano_zampini for boomerAMGBuildCoarseOperator to work */ 802d501dc42Sstefano_zampini static PetscErrorCode MatHYPRE_ParCSR_MatMatMult(hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hB, hypre_ParCSRMatrix **hAB) 803d501dc42Sstefano_zampini { 804d501dc42Sstefano_zampini PetscFunctionBegin; 805d501dc42Sstefano_zampini PetscStackPush("hypre_ParMatmul"); 806d501dc42Sstefano_zampini *hAB = hypre_ParMatmul(hA,hB); 807d501dc42Sstefano_zampini PetscStackPop; 808d501dc42Sstefano_zampini PetscFunctionReturn(0); 809d501dc42Sstefano_zampini } 810d501dc42Sstefano_zampini 8115e5acdf2Sstefano_zampini static PetscErrorCode MatMatMultNumeric_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C) 8125e5acdf2Sstefano_zampini { 8135e5acdf2Sstefano_zampini Mat D; 814d501dc42Sstefano_zampini hypre_ParCSRMatrix *hA,*hB,*hAB = NULL; 8155e5acdf2Sstefano_zampini PetscErrorCode ierr; 8165e5acdf2Sstefano_zampini 8175e5acdf2Sstefano_zampini PetscFunctionBegin; 8185e5acdf2Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 8195e5acdf2Sstefano_zampini ierr = MatAIJGetParCSR_Private(B,&hB);CHKERRQ(ierr); 820d501dc42Sstefano_zampini ierr = MatHYPRE_ParCSR_MatMatMult(hA,hB,&hAB);CHKERRQ(ierr); 8215e5acdf2Sstefano_zampini ierr = MatCreateFromParCSR(hAB,MATAIJ,PETSC_OWN_POINTER,&D);CHKERRQ(ierr); 8225e5acdf2Sstefano_zampini ierr = MatHeaderMerge(C,&D);CHKERRQ(ierr); 8235e5acdf2Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 8245e5acdf2Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(B,&hB);CHKERRQ(ierr); 8255e5acdf2Sstefano_zampini PetscFunctionReturn(0); 8265e5acdf2Sstefano_zampini } 8275e5acdf2Sstefano_zampini 8285e5acdf2Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMultSymbolic_AIJ_AIJ_wHYPRE(Mat A,Mat B,PetscReal fill,Mat *C) 8295e5acdf2Sstefano_zampini { 8305e5acdf2Sstefano_zampini PetscErrorCode ierr; 83120e1dc0dSstefano_zampini 8325e5acdf2Sstefano_zampini PetscFunctionBegin; 8335e5acdf2Sstefano_zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),C);CHKERRQ(ierr); 8345e5acdf2Sstefano_zampini ierr = MatSetType(*C,MATAIJ);CHKERRQ(ierr); 8355e5acdf2Sstefano_zampini (*C)->ops->matmultnumeric = MatMatMultNumeric_AIJ_AIJ_wHYPRE; 8365e5acdf2Sstefano_zampini PetscFunctionReturn(0); 8375e5acdf2Sstefano_zampini } 8385e5acdf2Sstefano_zampini 839d501dc42Sstefano_zampini static PetscErrorCode MatMatMultNumeric_HYPRE_HYPRE(Mat A,Mat B,Mat C) 840d501dc42Sstefano_zampini { 841d501dc42Sstefano_zampini Mat D; 842d501dc42Sstefano_zampini hypre_ParCSRMatrix *Aparcsr,*Bparcsr,*ABparcsr = NULL; 843d501dc42Sstefano_zampini Mat_HYPRE *hA,*hB; 844d501dc42Sstefano_zampini PetscBool ishypre; 845d501dc42Sstefano_zampini HYPRE_Int type; 846d501dc42Sstefano_zampini PetscErrorCode ierr; 847d501dc42Sstefano_zampini 848d501dc42Sstefano_zampini PetscFunctionBegin; 849d501dc42Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATHYPRE,&ishypre);CHKERRQ(ierr); 850d501dc42Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)B),PETSC_ERR_USER,"B should be of type %s",MATHYPRE); 851d501dc42Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr); 852d501dc42Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"A should be of type %s",MATHYPRE); 853d501dc42Sstefano_zampini hA = (Mat_HYPRE*)A->data; 854d501dc42Sstefano_zampini hB = (Mat_HYPRE*)B->data; 855d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 856d501dc42Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 857d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hB->ij,&type)); 858d501dc42Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 859d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&Aparcsr)); 860d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hB->ij,(void**)&Bparcsr)); 861d501dc42Sstefano_zampini ierr = MatHYPRE_ParCSR_MatMatMult(Aparcsr,Bparcsr,&ABparcsr);CHKERRQ(ierr); 862d501dc42Sstefano_zampini ierr = MatCreateFromParCSR(ABparcsr,MATHYPRE,PETSC_OWN_POINTER,&D);CHKERRQ(ierr); 863d501dc42Sstefano_zampini /* need to use HeaderReplace because HeaderMerge messes up with the communicator */ 864d501dc42Sstefano_zampini ierr = MatHeaderReplace(C,&D);CHKERRQ(ierr); 865d501dc42Sstefano_zampini C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 866d501dc42Sstefano_zampini PetscFunctionReturn(0); 867d501dc42Sstefano_zampini } 868d501dc42Sstefano_zampini 869d501dc42Sstefano_zampini static PetscErrorCode MatMatMult_HYPRE_HYPRE(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 870d501dc42Sstefano_zampini { 871d501dc42Sstefano_zampini PetscErrorCode ierr; 872d501dc42Sstefano_zampini 873d501dc42Sstefano_zampini PetscFunctionBegin; 874d501dc42Sstefano_zampini if (scall == MAT_INITIAL_MATRIX) { 875d501dc42Sstefano_zampini ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 876d501dc42Sstefano_zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),C);CHKERRQ(ierr); 877d501dc42Sstefano_zampini ierr = MatSetType(*C,MATHYPRE);CHKERRQ(ierr); 878d501dc42Sstefano_zampini (*C)->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 879d501dc42Sstefano_zampini ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 880d501dc42Sstefano_zampini } 881d501dc42Sstefano_zampini ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 882d501dc42Sstefano_zampini ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 883d501dc42Sstefano_zampini ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 884d501dc42Sstefano_zampini PetscFunctionReturn(0); 885d501dc42Sstefano_zampini } 886d501dc42Sstefano_zampini 8873dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C,Mat D) 88820e1dc0dSstefano_zampini { 88920e1dc0dSstefano_zampini Mat E; 89020e1dc0dSstefano_zampini hypre_ParCSRMatrix *hA,*hB,*hC,*hABC; 89120e1dc0dSstefano_zampini PetscErrorCode ierr; 89220e1dc0dSstefano_zampini 89320e1dc0dSstefano_zampini PetscFunctionBegin; 89420e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 89520e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(B,&hB);CHKERRQ(ierr); 89620e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(C,&hC);CHKERRQ(ierr); 89720e1dc0dSstefano_zampini ierr = MatHYPRE_ParCSR_RAP(hA,hB,hC,&hABC);CHKERRQ(ierr); 89820e1dc0dSstefano_zampini ierr = MatCreateFromParCSR(hABC,MATAIJ,PETSC_OWN_POINTER,&E);CHKERRQ(ierr); 89920e1dc0dSstefano_zampini ierr = MatHeaderMerge(D,&E);CHKERRQ(ierr); 90020e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 90120e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(B,&hB);CHKERRQ(ierr); 90220e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(C,&hC);CHKERRQ(ierr); 90320e1dc0dSstefano_zampini PetscFunctionReturn(0); 90420e1dc0dSstefano_zampini } 90520e1dc0dSstefano_zampini 9063dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C,PetscReal fill,Mat *D) 90720e1dc0dSstefano_zampini { 90820e1dc0dSstefano_zampini PetscErrorCode ierr; 90920e1dc0dSstefano_zampini 91020e1dc0dSstefano_zampini PetscFunctionBegin; 91120e1dc0dSstefano_zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),D);CHKERRQ(ierr); 91220e1dc0dSstefano_zampini ierr = MatSetType(*D,MATAIJ);CHKERRQ(ierr); 91320e1dc0dSstefano_zampini PetscFunctionReturn(0); 91420e1dc0dSstefano_zampini } 91520e1dc0dSstefano_zampini 916ea9daf28SStefano Zampini static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 91763c07aadSStefano Zampini { 91863c07aadSStefano Zampini PetscErrorCode ierr; 91963c07aadSStefano Zampini 92063c07aadSStefano Zampini PetscFunctionBegin; 921414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,0.0,y,PETSC_TRUE);CHKERRQ(ierr); 92263c07aadSStefano Zampini PetscFunctionReturn(0); 92363c07aadSStefano Zampini } 92463c07aadSStefano Zampini 925ea9daf28SStefano Zampini static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 92663c07aadSStefano Zampini { 92763c07aadSStefano Zampini PetscErrorCode ierr; 92863c07aadSStefano Zampini 92963c07aadSStefano Zampini PetscFunctionBegin; 930414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,0.0,y,PETSC_FALSE);CHKERRQ(ierr); 93163c07aadSStefano Zampini PetscFunctionReturn(0); 93263c07aadSStefano Zampini } 93363c07aadSStefano Zampini 934414bd5c3SStefano Zampini static PetscErrorCode MatMultAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 935414bd5c3SStefano Zampini { 936414bd5c3SStefano Zampini PetscErrorCode ierr; 937414bd5c3SStefano Zampini 938414bd5c3SStefano Zampini PetscFunctionBegin; 939414bd5c3SStefano Zampini if (y != z) { 940414bd5c3SStefano Zampini ierr = VecCopy(y,z);CHKERRQ(ierr); 941414bd5c3SStefano Zampini } 942414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,1.0,z,PETSC_FALSE);CHKERRQ(ierr); 943414bd5c3SStefano Zampini PetscFunctionReturn(0); 944414bd5c3SStefano Zampini } 945414bd5c3SStefano Zampini 946414bd5c3SStefano Zampini static PetscErrorCode MatMultTransposeAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 947414bd5c3SStefano Zampini { 948414bd5c3SStefano Zampini PetscErrorCode ierr; 949414bd5c3SStefano Zampini 950414bd5c3SStefano Zampini PetscFunctionBegin; 951414bd5c3SStefano Zampini if (y != z) { 952414bd5c3SStefano Zampini ierr = VecCopy(y,z);CHKERRQ(ierr); 953414bd5c3SStefano Zampini } 954414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,1.0,z,PETSC_TRUE);CHKERRQ(ierr); 955414bd5c3SStefano Zampini PetscFunctionReturn(0); 956414bd5c3SStefano Zampini } 957414bd5c3SStefano Zampini 958414bd5c3SStefano Zampini /* y = a * A * x + b * y or y = a * A^t * x + b * y depending on trans */ 959414bd5c3SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, PetscScalar a, Vec x, PetscScalar b, Vec y, PetscBool trans) 96063c07aadSStefano Zampini { 96163c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 96263c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 96363c07aadSStefano Zampini hypre_ParVector *hx,*hy; 96463c07aadSStefano Zampini PetscScalar *ax,*ay,*sax,*say; 96563c07aadSStefano Zampini PetscErrorCode ierr; 96663c07aadSStefano Zampini 96763c07aadSStefano Zampini PetscFunctionBegin; 96863c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 96963c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->x,(void**)&hx)); 97063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->b,(void**)&hy)); 97163c07aadSStefano Zampini ierr = VecGetArrayRead(x,(const PetscScalar**)&ax);CHKERRQ(ierr); 97263c07aadSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 97363c07aadSStefano Zampini if (trans) { 97458968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,ay,say); 97558968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,ax,sax); 976414bd5c3SStefano Zampini hypre_ParCSRMatrixMatvecT(a,parcsr,hy,b,hx); 97758968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,say,ay); 97858968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,sax,ax); 97963c07aadSStefano Zampini } else { 98058968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,ax,sax); 98158968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,ay,say); 982414bd5c3SStefano Zampini hypre_ParCSRMatrixMatvec(a,parcsr,hx,b,hy); 98358968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->x,sax,ax); 98458968eb6SStefano Zampini VecHYPRE_ParVectorReplacePointer(hA->b,say,ay); 98563c07aadSStefano Zampini } 98663c07aadSStefano Zampini ierr = VecRestoreArrayRead(x,(const PetscScalar**)&ax);CHKERRQ(ierr); 98763c07aadSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 98863c07aadSStefano Zampini PetscFunctionReturn(0); 98963c07aadSStefano Zampini } 99063c07aadSStefano Zampini 991ea9daf28SStefano Zampini static PetscErrorCode MatDestroy_HYPRE(Mat A) 99263c07aadSStefano Zampini { 99363c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 99463c07aadSStefano Zampini PetscErrorCode ierr; 99563c07aadSStefano Zampini 99663c07aadSStefano Zampini PetscFunctionBegin; 99763c07aadSStefano Zampini if (hA->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(hA->x)); 99863c07aadSStefano Zampini if (hA->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(hA->b)); 999978814f1SStefano Zampini if (hA->ij) { 1000978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 1001978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hA->ij)); 1002978814f1SStefano Zampini } 100363c07aadSStefano Zampini if (hA->comm) { ierr = MPI_Comm_free(&hA->comm);CHKERRQ(ierr); } 1004c69f721fSFande Kong 1005c69f721fSFande Kong ierr = MatStashDestroy_Private(&A->stash);CHKERRQ(ierr); 1006c69f721fSFande Kong 1007c69f721fSFande Kong ierr = PetscFree(hA->array);CHKERRQ(ierr); 1008c69f721fSFande Kong 100963c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_aij_C",NULL);CHKERRQ(ierr); 10102df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_is_C",NULL);CHKERRQ(ierr); 1011c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatPtAP_seqaij_hypre_C",NULL);CHKERRQ(ierr); 1012c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatPtAP_mpiaij_hypre_C",NULL);CHKERRQ(ierr); 1013d975228cSstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatHYPRESetPreallocation_C",NULL);CHKERRQ(ierr); 1014dd9c0a25Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatHYPREGetParCSR_C",NULL);CHKERRQ(ierr); 101575d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatPtAP_is_hypre_C",NULL);CHKERRQ(ierr); 101663c07aadSStefano Zampini ierr = PetscFree(A->data);CHKERRQ(ierr); 101763c07aadSStefano Zampini PetscFunctionReturn(0); 101863c07aadSStefano Zampini } 101963c07aadSStefano Zampini 1020ea9daf28SStefano Zampini static PetscErrorCode MatSetUp_HYPRE(Mat A) 102163c07aadSStefano Zampini { 10224ec6421dSstefano_zampini PetscErrorCode ierr; 10234ec6421dSstefano_zampini 10244ec6421dSstefano_zampini PetscFunctionBegin; 10254ec6421dSstefano_zampini ierr = MatHYPRESetPreallocation(A,PETSC_DEFAULT,NULL,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 10264ec6421dSstefano_zampini PetscFunctionReturn(0); 10274ec6421dSstefano_zampini } 10284ec6421dSstefano_zampini 10294ec6421dSstefano_zampini static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 10304ec6421dSstefano_zampini { 103163c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 103263c07aadSStefano Zampini Vec x,b; 1033c69f721fSFande Kong PetscMPIInt n; 1034c69f721fSFande Kong PetscInt i,j,rstart,ncols,flg; 1035c69f721fSFande Kong PetscInt *row,*col; 1036c69f721fSFande Kong PetscScalar *val; 103763c07aadSStefano Zampini PetscErrorCode ierr; 103863c07aadSStefano Zampini 103963c07aadSStefano Zampini PetscFunctionBegin; 10404ec6421dSstefano_zampini if (mode == MAT_FLUSH_ASSEMBLY) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MAT_FLUSH_ASSEMBLY currently not supported with MATHYPRE"); 1041c69f721fSFande Kong 1042c69f721fSFande Kong if (!A->nooffprocentries) { 1043c69f721fSFande Kong while (1) { 1044c69f721fSFande Kong ierr = MatStashScatterGetMesg_Private(&A->stash,&n,&row,&col,&val,&flg);CHKERRQ(ierr); 1045c69f721fSFande Kong if (!flg) break; 1046c69f721fSFande Kong 1047c69f721fSFande Kong for (i=0; i<n; ) { 1048c69f721fSFande Kong /* Now identify the consecutive vals belonging to the same row */ 1049c69f721fSFande Kong for (j=i,rstart=row[j]; j<n; j++) { 1050c69f721fSFande Kong if (row[j] != rstart) break; 1051c69f721fSFande Kong } 1052c69f721fSFande Kong if (j < n) ncols = j-i; 1053c69f721fSFande Kong else ncols = n-i; 1054c69f721fSFande Kong /* Now assemble all these values with a single function call */ 1055c69f721fSFande Kong ierr = MatSetValues_HYPRE(A,1,row+i,ncols,col+i,val+i,A->insertmode);CHKERRQ(ierr); 1056c69f721fSFande Kong 1057c69f721fSFande Kong i = j; 1058c69f721fSFande Kong } 1059c69f721fSFande Kong } 1060c69f721fSFande Kong ierr = MatStashScatterEnd_Private(&A->stash);CHKERRQ(ierr); 1061c69f721fSFande Kong } 1062c69f721fSFande Kong 10634ec6421dSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixAssemble,(hA->ij)); 1064af1cf968SStefano Zampini /* The assembly routine destroys the aux_matrix, we recreate it here by calling HYPRE_IJMatrixInitalize */ 1065af1cf968SStefano Zampini { 1066af1cf968SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1067af1cf968SStefano Zampini 1068af1cf968SStefano Zampini /* call destroy just to make sure we do not leak anything */ 1069af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1070af1cf968SStefano Zampini PetscStackCallStandard(hypre_AuxParCSRMatrixDestroy,(aux_matrix)); 1071af1cf968SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1072af1cf968SStefano Zampini 1073af1cf968SStefano Zampini /* Initialize with assembled flag -> it only recreates the aux_par_matrix */ 1074af1cf968SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 1075af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1076af1cf968SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; /* see comment in MatHYPRESetPreallocation_HYPRE */ 1077af1cf968SStefano Zampini PetscStackCallStandard(hypre_AuxParCSRMatrixInitialize,(aux_matrix)); 1078af1cf968SStefano Zampini } 107963c07aadSStefano Zampini if (hA->x) PetscFunctionReturn(0); 108063c07aadSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 108163c07aadSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 108263c07aadSStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)A),1,A->cmap->n,A->cmap->N,NULL,&x);CHKERRQ(ierr); 108363c07aadSStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)A),1,A->rmap->n,A->rmap->N,NULL,&b);CHKERRQ(ierr); 108463c07aadSStefano Zampini ierr = VecHYPRE_IJVectorCreate(x,&hA->x);CHKERRQ(ierr); 108563c07aadSStefano Zampini ierr = VecHYPRE_IJVectorCreate(b,&hA->b);CHKERRQ(ierr); 108663c07aadSStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 108763c07aadSStefano Zampini ierr = VecDestroy(&b);CHKERRQ(ierr); 108863c07aadSStefano Zampini PetscFunctionReturn(0); 108963c07aadSStefano Zampini } 109063c07aadSStefano Zampini 1091c69f721fSFande Kong static PetscErrorCode MatGetArray_HYPRE(Mat A, PetscInt size, void **array) 1092c69f721fSFande Kong { 1093c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1094c69f721fSFande Kong PetscErrorCode ierr; 1095c69f721fSFande Kong 1096c69f721fSFande Kong PetscFunctionBegin; 1097c69f721fSFande Kong if (!hA->available) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Temporary space is in use"); 1098c69f721fSFande Kong 1099c69f721fSFande Kong if (hA->size >= size) *array = hA->array; 1100c69f721fSFande Kong else { 1101c69f721fSFande Kong ierr = PetscFree(hA->array);CHKERRQ(ierr); 1102c69f721fSFande Kong hA->size = size; 1103c69f721fSFande Kong ierr = PetscMalloc(hA->size,&hA->array);CHKERRQ(ierr); 1104c69f721fSFande Kong *array = hA->array; 1105c69f721fSFande Kong } 1106c69f721fSFande Kong 1107c69f721fSFande Kong hA->available = PETSC_FALSE; 1108c69f721fSFande Kong PetscFunctionReturn(0); 1109c69f721fSFande Kong } 1110c69f721fSFande Kong 1111708542d2SFande Kong static PetscErrorCode MatRestoreArray_HYPRE(Mat A, void **array) 1112c69f721fSFande Kong { 1113c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1114c69f721fSFande Kong 1115c69f721fSFande Kong PetscFunctionBegin; 1116c69f721fSFande Kong *array = NULL; 1117c69f721fSFande Kong hA->available = PETSC_TRUE; 1118c69f721fSFande Kong PetscFunctionReturn(0); 1119c69f721fSFande Kong } 1120c69f721fSFande Kong 1121d975228cSstefano_zampini PetscErrorCode MatSetValues_HYPRE(Mat A, PetscInt nr, const PetscInt rows[], PetscInt nc, const PetscInt cols[], const PetscScalar v[], InsertMode ins) 1122d975228cSstefano_zampini { 1123d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1124d975228cSstefano_zampini PetscScalar *vals = (PetscScalar *)v; 1125c69f721fSFande Kong PetscScalar *sscr; 1126c69f721fSFande Kong PetscInt *cscr[2]; 1127c69f721fSFande Kong PetscInt i,nzc; 112808defe43SFande Kong void *array = NULL; 1129d975228cSstefano_zampini PetscErrorCode ierr; 1130d975228cSstefano_zampini 1131d975228cSstefano_zampini PetscFunctionBegin; 1132c69f721fSFande Kong ierr = MatGetArray_HYPRE(A,sizeof(PetscInt)*(2*nc)+sizeof(PetscScalar)*nc*nr,&array);CHKERRQ(ierr); 1133c69f721fSFande Kong cscr[0] = (PetscInt*)array; 1134c69f721fSFande Kong cscr[1] = ((PetscInt*)array)+nc; 1135c69f721fSFande Kong sscr = (PetscScalar*)(((PetscInt*)array)+nc*2); 1136d975228cSstefano_zampini for (i=0,nzc=0;i<nc;i++) { 1137d975228cSstefano_zampini if (cols[i] >= 0) { 1138d975228cSstefano_zampini cscr[0][nzc ] = cols[i]; 1139d975228cSstefano_zampini cscr[1][nzc++] = i; 1140d975228cSstefano_zampini } 1141d975228cSstefano_zampini } 1142c69f721fSFande Kong if (!nzc) { 1143708542d2SFande Kong ierr = MatRestoreArray_HYPRE(A,&array);CHKERRQ(ierr); 1144c69f721fSFande Kong PetscFunctionReturn(0); 1145c69f721fSFande Kong } 1146d975228cSstefano_zampini 1147d975228cSstefano_zampini if (ins == ADD_VALUES) { 1148d975228cSstefano_zampini for (i=0;i<nr;i++) { 1149e3977e59Sstefano_zampini if (rows[i] >= 0 && nzc) { 1150d975228cSstefano_zampini PetscInt j; 1151d975228cSstefano_zampini for (j=0;j<nzc;j++) sscr[j] = vals[cscr[1][j]]; 115208defe43SFande Kong PetscStackCallStandard(HYPRE_IJMatrixAddToValues,(hA->ij,1,(HYPRE_Int*)&nzc,(HYPRE_Int*)(rows+i),(HYPRE_Int*)cscr[0],sscr)); 1153d975228cSstefano_zampini } 1154d975228cSstefano_zampini vals += nc; 1155d975228cSstefano_zampini } 1156d975228cSstefano_zampini } else { /* INSERT_VALUES */ 1157d975228cSstefano_zampini PetscInt rst,ren; 1158c69f721fSFande Kong 1159*c6698e78SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr); 1160d975228cSstefano_zampini for (i=0;i<nr;i++) { 1161e3977e59Sstefano_zampini if (rows[i] >= 0 && nzc) { 1162d975228cSstefano_zampini PetscInt j; 1163d975228cSstefano_zampini for (j=0;j<nzc;j++) sscr[j] = vals[cscr[1][j]]; 1164c69f721fSFande Kong /* nonlocal values */ 1165c69f721fSFande Kong if (rows[i] < rst || rows[i] >= ren) { ierr = MatStashValuesRow_Private(&A->stash,rows[i],nzc,cscr[0],sscr,PETSC_FALSE);CHKERRQ(ierr); } 1166c69f721fSFande Kong /* local values */ 116708defe43SFande Kong else PetscStackCallStandard(HYPRE_IJMatrixSetValues,(hA->ij,1,(HYPRE_Int*)&nzc,(HYPRE_Int*)(rows+i),(HYPRE_Int*)cscr[0],sscr)); 1168d975228cSstefano_zampini } 1169d975228cSstefano_zampini vals += nc; 1170d975228cSstefano_zampini } 1171d975228cSstefano_zampini } 1172c69f721fSFande Kong 1173708542d2SFande Kong ierr = MatRestoreArray_HYPRE(A,&array);CHKERRQ(ierr); 1174d975228cSstefano_zampini PetscFunctionReturn(0); 1175d975228cSstefano_zampini } 1176d975228cSstefano_zampini 1177d975228cSstefano_zampini static PetscErrorCode MatHYPRESetPreallocation_HYPRE(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1178d975228cSstefano_zampini { 1179d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 11807d968826Sstefano_zampini HYPRE_Int *hdnnz,*honnz; 118106a29025Sstefano_zampini PetscInt i,rs,re,cs,ce,bs; 1182d975228cSstefano_zampini PetscMPIInt size; 1183d975228cSstefano_zampini PetscErrorCode ierr; 1184d975228cSstefano_zampini 1185d975228cSstefano_zampini PetscFunctionBegin; 118606a29025Sstefano_zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1187d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1188d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1189d975228cSstefano_zampini rs = A->rmap->rstart; 1190d975228cSstefano_zampini re = A->rmap->rend; 1191d975228cSstefano_zampini cs = A->cmap->rstart; 1192d975228cSstefano_zampini ce = A->cmap->rend; 1193d975228cSstefano_zampini if (!hA->ij) { 1194d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rs,re-1,cs,ce-1,&hA->ij)); 1195d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 1196d975228cSstefano_zampini } else { 11977d968826Sstefano_zampini HYPRE_Int hrs,hre,hcs,hce; 1198d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetLocalRange,(hA->ij,&hrs,&hre,&hcs,&hce)); 1199d975228cSstefano_zampini if (hre-hrs+1 != re -rs) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent local rows: IJMatrix [%D,%D), PETSc [%D,%d)",hrs,hre+1,rs,re); 1200d975228cSstefano_zampini if (hce-hcs+1 != ce -cs) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent local cols: IJMatrix [%D,%D), PETSc [%D,%d)",hcs,hce+1,cs,ce); 1201d975228cSstefano_zampini } 120206a29025Sstefano_zampini if (dnz == PETSC_DEFAULT || dnz == PETSC_DECIDE) dnz = 10*bs; 120306a29025Sstefano_zampini if (onz == PETSC_DEFAULT || onz == PETSC_DECIDE) onz = 10*bs; 120406a29025Sstefano_zampini 1205d975228cSstefano_zampini if (!dnnz) { 1206d975228cSstefano_zampini ierr = PetscMalloc1(A->rmap->n,&hdnnz);CHKERRQ(ierr); 1207d975228cSstefano_zampini for (i=0;i<A->rmap->n;i++) hdnnz[i] = dnz; 1208d975228cSstefano_zampini } else { 12097d968826Sstefano_zampini hdnnz = (HYPRE_Int*)dnnz; 1210d975228cSstefano_zampini } 1211d975228cSstefano_zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 1212d975228cSstefano_zampini if (size > 1) { 1213ddbeb582SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1214d975228cSstefano_zampini if (!onnz) { 1215d975228cSstefano_zampini ierr = PetscMalloc1(A->rmap->n,&honnz);CHKERRQ(ierr); 1216d975228cSstefano_zampini for (i=0;i<A->rmap->n;i++) honnz[i] = onz; 1217d975228cSstefano_zampini } else { 12187d968826Sstefano_zampini honnz = (HYPRE_Int*)onnz; 1219d975228cSstefano_zampini } 1220ddbeb582SStefano Zampini /* SetDiagOffdSizes sets hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0, since it seems 1221ddbeb582SStefano Zampini they assume the user will input the entire row values, properly sorted 1222ddbeb582SStefano Zampini In PETSc, we don't make such an assumption, and we instead set this flag to 1 1223ddbeb582SStefano Zampini Also, to avoid possible memory leaks, we destroy and recreate the translator 1224ddbeb582SStefano Zampini This has to be done here, as HYPRE_IJMatrixInitialize will properly initialize 1225ddbeb582SStefano Zampini the IJ matrix for us */ 1226ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1227ddbeb582SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 1228ddbeb582SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1229d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(hA->ij,hdnnz,honnz)); 1230ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1231ddbeb582SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; 1232d975228cSstefano_zampini } else { 1233d975228cSstefano_zampini honnz = NULL; 1234d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetRowSizes,(hA->ij,hdnnz)); 1235d975228cSstefano_zampini } 1236ddbeb582SStefano Zampini 1237af1cf968SStefano Zampini /* reset assembled flag and call the initialize method */ 1238af1cf968SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 0; 1239ddbeb582SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 1240d975228cSstefano_zampini if (!dnnz) { 1241d975228cSstefano_zampini ierr = PetscFree(hdnnz);CHKERRQ(ierr); 1242d975228cSstefano_zampini } 1243d975228cSstefano_zampini if (!onnz && honnz) { 1244d975228cSstefano_zampini ierr = PetscFree(honnz);CHKERRQ(ierr); 1245d975228cSstefano_zampini } 1246af1cf968SStefano Zampini 1247af1cf968SStefano Zampini /* Match AIJ logic */ 124806a29025Sstefano_zampini A->preallocated = PETSC_TRUE; 1249af1cf968SStefano Zampini A->assembled = PETSC_FALSE; 1250d975228cSstefano_zampini PetscFunctionReturn(0); 1251d975228cSstefano_zampini } 1252d975228cSstefano_zampini 1253d975228cSstefano_zampini /*@C 1254d975228cSstefano_zampini MatHYPRESetPreallocation - Preallocates memory for a sparse parallel matrix in HYPRE IJ format 1255d975228cSstefano_zampini 1256d975228cSstefano_zampini Collective on Mat 1257d975228cSstefano_zampini 1258d975228cSstefano_zampini Input Parameters: 1259d975228cSstefano_zampini + A - the matrix 1260d975228cSstefano_zampini . dnz - number of nonzeros per row in DIAGONAL portion of local submatrix 1261d975228cSstefano_zampini (same value is used for all local rows) 1262d975228cSstefano_zampini . dnnz - array containing the number of nonzeros in the various rows of the 1263d975228cSstefano_zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1264d975228cSstefano_zampini or NULL (PETSC_NULL_INTEGER in Fortran), if d_nz is used to specify the nonzero structure. 1265d975228cSstefano_zampini The size of this array is equal to the number of local rows, i.e 'm'. 1266d975228cSstefano_zampini For matrices that will be factored, you must leave room for (and set) 1267d975228cSstefano_zampini the diagonal entry even if it is zero. 1268d975228cSstefano_zampini . onz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1269d975228cSstefano_zampini submatrix (same value is used for all local rows). 1270d975228cSstefano_zampini - onnz - array containing the number of nonzeros in the various rows of the 1271d975228cSstefano_zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1272d975228cSstefano_zampini each row) or NULL (PETSC_NULL_INTEGER in Fortran), if o_nz is used to specify the nonzero 1273d975228cSstefano_zampini structure. The size of this array is equal to the number 1274d975228cSstefano_zampini of local rows, i.e 'm'. 1275d975228cSstefano_zampini 127695452b02SPatrick Sanan Notes: 127795452b02SPatrick Sanan If the *nnz parameter is given then the *nz parameter is ignored; for sequential matrices, onz and onnz are ignored. 1278d975228cSstefano_zampini 1279d975228cSstefano_zampini Level: intermediate 1280d975228cSstefano_zampini 1281d975228cSstefano_zampini .keywords: matrix, aij, compressed row, sparse, parallel 1282d975228cSstefano_zampini 1283af1cf968SStefano Zampini .seealso: MatCreate(), MatMPIAIJSetPreallocation(), MATHYPRE 1284d975228cSstefano_zampini @*/ 1285d975228cSstefano_zampini PetscErrorCode MatHYPRESetPreallocation(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1286d975228cSstefano_zampini { 1287d975228cSstefano_zampini PetscErrorCode ierr; 1288d975228cSstefano_zampini 1289d975228cSstefano_zampini PetscFunctionBegin; 1290d975228cSstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1291d975228cSstefano_zampini PetscValidType(A,1); 1292d975228cSstefano_zampini ierr = PetscTryMethod(A,"MatHYPRESetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(A,dnz,dnnz,onz,onnz));CHKERRQ(ierr); 1293d975228cSstefano_zampini PetscFunctionReturn(0); 1294d975228cSstefano_zampini } 1295d975228cSstefano_zampini 1296225daaf8SStefano Zampini /* 1297225daaf8SStefano Zampini MatCreateFromParCSR - Creates a matrix from a hypre_ParCSRMatrix 1298225daaf8SStefano Zampini 1299225daaf8SStefano Zampini Collective 1300225daaf8SStefano Zampini 1301225daaf8SStefano Zampini Input Parameters: 130245b8d346SStefano Zampini + parcsr - the pointer to the hypre_ParCSRMatrix 1303bb4689ddSStefano Zampini . mtype - matrix type to be created. Currently MATAIJ, MATIS and MATHYPRE are supported. 1304225daaf8SStefano Zampini - copymode - PETSc copying options 1305225daaf8SStefano Zampini 1306225daaf8SStefano Zampini Output Parameter: 1307225daaf8SStefano Zampini . A - the matrix 1308225daaf8SStefano Zampini 1309225daaf8SStefano Zampini Level: intermediate 1310225daaf8SStefano Zampini 1311225daaf8SStefano Zampini .seealso: MatHYPRE, PetscCopyMode 1312225daaf8SStefano Zampini */ 131345b8d346SStefano Zampini PETSC_EXTERN PetscErrorCode MatCreateFromParCSR(hypre_ParCSRMatrix *parcsr, MatType mtype, PetscCopyMode copymode, Mat* A) 1314978814f1SStefano Zampini { 1315225daaf8SStefano Zampini Mat T; 1316978814f1SStefano Zampini Mat_HYPRE *hA; 1317978814f1SStefano Zampini MPI_Comm comm; 1318978814f1SStefano Zampini PetscInt rstart,rend,cstart,cend,M,N; 1319bb4689ddSStefano Zampini PetscBool isseqaij,ismpiaij,isaij,ishyp,isis; 1320978814f1SStefano Zampini PetscErrorCode ierr; 1321978814f1SStefano Zampini 1322978814f1SStefano Zampini PetscFunctionBegin; 1323978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 1324225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1325225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 1326225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATAIJ,&isaij);CHKERRQ(ierr); 1327225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATHYPRE,&ishyp);CHKERRQ(ierr); 13288cfe8d00SStefano Zampini ierr = PetscStrcmp(mtype,MATIS,&isis);CHKERRQ(ierr); 1329225daaf8SStefano Zampini isaij = (PetscBool)(isseqaij || ismpiaij || isaij); 1330bb4689ddSStefano 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); 1331978814f1SStefano Zampini /* access ParCSRMatrix */ 1332978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 1333978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 1334978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 1335978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 1336978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 1337978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 1338978814f1SStefano Zampini 1339fa92c42cSstefano_zampini /* fix for empty local rows/columns */ 1340fa92c42cSstefano_zampini if (rend < rstart) rend = rstart; 1341fa92c42cSstefano_zampini if (cend < cstart) cend = cstart; 1342fa92c42cSstefano_zampini 1343e6471dc9SStefano Zampini /* PETSc convention */ 1344e6471dc9SStefano Zampini rend++; 1345e6471dc9SStefano Zampini cend++; 1346e6471dc9SStefano Zampini rend = PetscMin(rend,M); 1347e6471dc9SStefano Zampini cend = PetscMin(cend,N); 1348e6471dc9SStefano Zampini 1349978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 1350225daaf8SStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1351e6471dc9SStefano Zampini ierr = MatSetSizes(T,rend-rstart,cend-cstart,M,N);CHKERRQ(ierr); 1352225daaf8SStefano Zampini ierr = MatSetType(T,MATHYPRE);CHKERRQ(ierr); 1353225daaf8SStefano Zampini hA = (Mat_HYPRE*)(T->data); 1354978814f1SStefano Zampini 1355978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 1356978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 135745b8d346SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 135845b8d346SStefano Zampini 135945b8d346SStefano Zampini /* create new ParCSR object if needed */ 136045b8d346SStefano Zampini if (ishyp && copymode == PETSC_COPY_VALUES) { 136145b8d346SStefano Zampini hypre_ParCSRMatrix *new_parcsr; 136245b8d346SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd,*ndiag,*noffd; 136345b8d346SStefano Zampini 136445b8d346SStefano Zampini new_parcsr = hypre_ParCSRMatrixCompleteClone(parcsr); 136545b8d346SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 136645b8d346SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 136745b8d346SStefano Zampini ndiag = hypre_ParCSRMatrixDiag(new_parcsr); 136845b8d346SStefano Zampini noffd = hypre_ParCSRMatrixOffd(new_parcsr); 136945b8d346SStefano Zampini ierr = PetscMemcpy(hypre_CSRMatrixData(ndiag),hypre_CSRMatrixData(hdiag),hypre_CSRMatrixNumNonzeros(hdiag)*sizeof(PetscScalar));CHKERRQ(ierr); 137045b8d346SStefano Zampini ierr = PetscMemcpy(hypre_CSRMatrixData(noffd),hypre_CSRMatrixData(hoffd),hypre_CSRMatrixNumNonzeros(hoffd)*sizeof(PetscScalar));CHKERRQ(ierr); 137145b8d346SStefano Zampini parcsr = new_parcsr; 137245b8d346SStefano Zampini copymode = PETSC_OWN_POINTER; 137345b8d346SStefano Zampini } 1374978814f1SStefano Zampini 1375978814f1SStefano Zampini /* set ParCSR object */ 1376978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 13774ec6421dSstefano_zampini T->preallocated = PETSC_TRUE; 1378978814f1SStefano Zampini 1379978814f1SStefano Zampini /* set assembled flag */ 1380978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 1381978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 1382225daaf8SStefano Zampini if (ishyp) { 13836d2a658fSstefano_zampini PetscMPIInt myid = 0; 13846d2a658fSstefano_zampini 13856d2a658fSstefano_zampini /* make sure we always have row_starts and col_starts available */ 13866d2a658fSstefano_zampini if (HYPRE_AssumedPartitionCheck()) { 13876d2a658fSstefano_zampini ierr = MPI_Comm_rank(comm,&myid);CHKERRQ(ierr); 13886d2a658fSstefano_zampini } 13896d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsColStarts(parcsr)) { 13906d2a658fSstefano_zampini PetscLayout map; 13916d2a658fSstefano_zampini 13926d2a658fSstefano_zampini ierr = MatGetLayouts(T,NULL,&map);CHKERRQ(ierr); 13936d2a658fSstefano_zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 13941c92d2d0Sstefano_zampini hypre_ParCSRMatrixColStarts(parcsr) = (HYPRE_Int*)(map->range + myid); 13956d2a658fSstefano_zampini } 13966d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsRowStarts(parcsr)) { 13976d2a658fSstefano_zampini PetscLayout map; 13986d2a658fSstefano_zampini 13996d2a658fSstefano_zampini ierr = MatGetLayouts(T,&map,NULL);CHKERRQ(ierr); 14006d2a658fSstefano_zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 14011c92d2d0Sstefano_zampini hypre_ParCSRMatrixRowStarts(parcsr) = (HYPRE_Int*)(map->range + myid); 14026d2a658fSstefano_zampini } 1403978814f1SStefano Zampini /* prevent from freeing the pointer */ 1404978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 1405225daaf8SStefano Zampini *A = T; 1406978814f1SStefano Zampini ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1407978814f1SStefano Zampini ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1408bb4689ddSStefano Zampini } else if (isaij) { 1409bb4689ddSStefano Zampini if (copymode != PETSC_OWN_POINTER) { 1410225daaf8SStefano Zampini /* prevent from freeing the pointer */ 1411225daaf8SStefano Zampini hA->inner_free = PETSC_FALSE; 1412225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 1413225daaf8SStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1414225daaf8SStefano Zampini } else { /* AIJ return type with PETSC_OWN_POINTER */ 1415225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INPLACE_MATRIX,&T);CHKERRQ(ierr); 1416225daaf8SStefano Zampini *A = T; 1417225daaf8SStefano Zampini } 1418bb4689ddSStefano Zampini } else if (isis) { 14198cfe8d00SStefano Zampini ierr = MatConvert_HYPRE_IS(T,MATIS,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 14208cfe8d00SStefano Zampini if (copymode != PETSC_OWN_POINTER) hA->inner_free = PETSC_FALSE; 1421bb4689ddSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1422bb4689ddSStefano Zampini } 1423978814f1SStefano Zampini PetscFunctionReturn(0); 1424978814f1SStefano Zampini } 1425978814f1SStefano Zampini 142668ec7858SStefano Zampini static PetscErrorCode MatHYPREGetParCSR_HYPRE(Mat A, hypre_ParCSRMatrix **parcsr) 1427dd9c0a25Sstefano_zampini { 1428dd9c0a25Sstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1429dd9c0a25Sstefano_zampini HYPRE_Int type; 1430dd9c0a25Sstefano_zampini 1431dd9c0a25Sstefano_zampini PetscFunctionBegin; 1432dd9c0a25Sstefano_zampini if (!hA->ij) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"HYPRE_IJMatrix not present"); 1433dd9c0a25Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 1434dd9c0a25Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"HYPRE_IJMatrix is not of type HYPRE_PARCSR"); 1435dd9c0a25Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)parcsr)); 1436dd9c0a25Sstefano_zampini PetscFunctionReturn(0); 1437dd9c0a25Sstefano_zampini } 1438dd9c0a25Sstefano_zampini 1439dd9c0a25Sstefano_zampini /* 1440dd9c0a25Sstefano_zampini MatHYPREGetParCSR - Gets the pointer to the ParCSR matrix 1441dd9c0a25Sstefano_zampini 1442dd9c0a25Sstefano_zampini Not collective 1443dd9c0a25Sstefano_zampini 1444dd9c0a25Sstefano_zampini Input Parameters: 1445dd9c0a25Sstefano_zampini + A - the MATHYPRE object 1446dd9c0a25Sstefano_zampini 1447dd9c0a25Sstefano_zampini Output Parameter: 1448dd9c0a25Sstefano_zampini . parcsr - the pointer to the hypre_ParCSRMatrix 1449dd9c0a25Sstefano_zampini 1450dd9c0a25Sstefano_zampini Level: intermediate 1451dd9c0a25Sstefano_zampini 1452dd9c0a25Sstefano_zampini .seealso: MatHYPRE, PetscCopyMode 1453dd9c0a25Sstefano_zampini */ 1454dd9c0a25Sstefano_zampini PetscErrorCode MatHYPREGetParCSR(Mat A, hypre_ParCSRMatrix **parcsr) 1455dd9c0a25Sstefano_zampini { 1456dd9c0a25Sstefano_zampini PetscErrorCode ierr; 1457dd9c0a25Sstefano_zampini 1458dd9c0a25Sstefano_zampini PetscFunctionBegin; 1459dd9c0a25Sstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1460dd9c0a25Sstefano_zampini PetscValidType(A,1); 1461dd9c0a25Sstefano_zampini ierr = PetscUseMethod(A,"MatHYPREGetParCSR_C",(Mat,hypre_ParCSRMatrix**),(A,parcsr));CHKERRQ(ierr); 1462dd9c0a25Sstefano_zampini PetscFunctionReturn(0); 1463dd9c0a25Sstefano_zampini } 1464dd9c0a25Sstefano_zampini 146568ec7858SStefano Zampini static PetscErrorCode MatMissingDiagonal_HYPRE(Mat A, PetscBool *missing, PetscInt *dd) 146668ec7858SStefano Zampini { 146768ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 146868ec7858SStefano Zampini hypre_CSRMatrix *ha; 146968ec7858SStefano Zampini PetscInt rst; 147068ec7858SStefano Zampini PetscErrorCode ierr; 147168ec7858SStefano Zampini 147268ec7858SStefano Zampini PetscFunctionBegin; 147368ec7858SStefano Zampini if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented with non-square diagonal blocks"); 147468ec7858SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,NULL);CHKERRQ(ierr); 147568ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 147668ec7858SStefano Zampini if (missing) *missing = PETSC_FALSE; 147768ec7858SStefano Zampini if (dd) *dd = -1; 147868ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 147968ec7858SStefano Zampini if (ha) { 148068299464SStefano Zampini PetscInt size,i; 148168299464SStefano Zampini HYPRE_Int *ii,*jj; 148268ec7858SStefano Zampini 148368ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 148468ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 148568ec7858SStefano Zampini jj = hypre_CSRMatrixJ(ha); 148668ec7858SStefano Zampini for (i = 0; i < size; i++) { 148768ec7858SStefano Zampini PetscInt j; 148868ec7858SStefano Zampini PetscBool found = PETSC_FALSE; 148968ec7858SStefano Zampini 149068ec7858SStefano Zampini for (j = ii[i]; j < ii[i+1] && !found; j++) 149168ec7858SStefano Zampini found = (jj[j] == i) ? PETSC_TRUE : PETSC_FALSE; 149268ec7858SStefano Zampini 149368ec7858SStefano Zampini if (!found) { 149468ec7858SStefano Zampini PetscInfo1(A,"Matrix is missing local diagonal entry %D\n",i); 149568ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 149668ec7858SStefano Zampini if (dd) *dd = i+rst; 149768ec7858SStefano Zampini PetscFunctionReturn(0); 149868ec7858SStefano Zampini } 149968ec7858SStefano Zampini } 150068ec7858SStefano Zampini if (!size) { 150168ec7858SStefano Zampini PetscInfo(A,"Matrix has no diagonal entries therefore is missing diagonal\n"); 150268ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 150368ec7858SStefano Zampini if (dd) *dd = rst; 150468ec7858SStefano Zampini } 150568ec7858SStefano Zampini } else { 150668ec7858SStefano Zampini PetscInfo(A,"Matrix has no diagonal entries therefore is missing diagonal\n"); 150768ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 150868ec7858SStefano Zampini if (dd) *dd = rst; 150968ec7858SStefano Zampini } 151068ec7858SStefano Zampini PetscFunctionReturn(0); 151168ec7858SStefano Zampini } 151268ec7858SStefano Zampini 151368ec7858SStefano Zampini static PetscErrorCode MatScale_HYPRE(Mat A, PetscScalar s) 151468ec7858SStefano Zampini { 151568ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 151668ec7858SStefano Zampini hypre_CSRMatrix *ha; 151768ec7858SStefano Zampini PetscErrorCode ierr; 151868ec7858SStefano Zampini 151968ec7858SStefano Zampini PetscFunctionBegin; 152068ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 152168ec7858SStefano Zampini /* diagonal part */ 152268ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 152368ec7858SStefano Zampini if (ha) { 152468299464SStefano Zampini PetscInt size,i; 152568299464SStefano Zampini HYPRE_Int *ii; 152668ec7858SStefano Zampini PetscScalar *a; 152768ec7858SStefano Zampini 152868ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 152968ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 153068ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 153168ec7858SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= s; 153268ec7858SStefano Zampini } 153368ec7858SStefano Zampini /* offdiagonal part */ 153468ec7858SStefano Zampini ha = hypre_ParCSRMatrixOffd(parcsr); 153568ec7858SStefano Zampini if (ha) { 153668299464SStefano Zampini PetscInt size,i; 153768299464SStefano Zampini HYPRE_Int *ii; 153868ec7858SStefano Zampini PetscScalar *a; 153968ec7858SStefano Zampini 154068ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 154168ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 154268ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 154368ec7858SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= s; 154468ec7858SStefano Zampini } 154568ec7858SStefano Zampini PetscFunctionReturn(0); 154668ec7858SStefano Zampini } 154768ec7858SStefano Zampini 154868ec7858SStefano Zampini static PetscErrorCode MatZeroRowsColumns_HYPRE(Mat A, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 154968ec7858SStefano Zampini { 155068ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 155168299464SStefano Zampini HYPRE_Int *lrows; 155268299464SStefano Zampini PetscInt rst,ren,i; 155368ec7858SStefano Zampini PetscErrorCode ierr; 155468ec7858SStefano Zampini 155568ec7858SStefano Zampini PetscFunctionBegin; 155668ec7858SStefano Zampini if (x || b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"To be implemented"); 155768ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 155868ec7858SStefano Zampini ierr = PetscMalloc1(numRows,&lrows);CHKERRQ(ierr); 155968ec7858SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr); 156068ec7858SStefano Zampini for (i=0;i<numRows;i++) { 156168ec7858SStefano Zampini if (rows[i] < rst || rows[i] >= ren) 156268ec7858SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-local rows not yet supported"); 156368ec7858SStefano Zampini lrows[i] = rows[i] - rst; 156468ec7858SStefano Zampini } 156568ec7858SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixEliminateRowsCols,(parcsr,numRows,lrows)); 156668ec7858SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 156768ec7858SStefano Zampini PetscFunctionReturn(0); 156868ec7858SStefano Zampini } 156968ec7858SStefano Zampini 1570c69f721fSFande Kong static PetscErrorCode MatZeroEntries_HYPRE_CSRMatrix(hypre_CSRMatrix *ha) 1571c69f721fSFande Kong { 1572c69f721fSFande Kong PetscErrorCode ierr; 1573c69f721fSFande Kong 1574c69f721fSFande Kong PetscFunctionBegin; 1575c69f721fSFande Kong if (ha) { 1576c69f721fSFande Kong HYPRE_Int *ii, size; 1577c69f721fSFande Kong HYPRE_Complex *a; 1578c69f721fSFande Kong 1579c69f721fSFande Kong size = hypre_CSRMatrixNumRows(ha); 1580c69f721fSFande Kong a = hypre_CSRMatrixData(ha); 1581c69f721fSFande Kong ii = hypre_CSRMatrixI(ha); 1582c69f721fSFande Kong 1583c69f721fSFande Kong if (a) { ierr = PetscMemzero(a,(ii[size])*sizeof(HYPRE_Complex));CHKERRQ(ierr); } 1584c69f721fSFande Kong } 1585c69f721fSFande Kong PetscFunctionReturn(0); 1586c69f721fSFande Kong } 1587c69f721fSFande Kong 1588c69f721fSFande Kong PetscErrorCode MatZeroEntries_HYPRE(Mat A) 1589c69f721fSFande Kong { 1590c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1591c69f721fSFande Kong PetscErrorCode ierr; 1592c69f721fSFande Kong 1593c69f721fSFande Kong PetscFunctionBegin; 1594c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1595c69f721fSFande Kong /* diagonal part */ 1596c69f721fSFande Kong ierr = MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr));CHKERRQ(ierr); 1597c69f721fSFande Kong /* off-diagonal part */ 1598c69f721fSFande Kong ierr = MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr));CHKERRQ(ierr); 1599c69f721fSFande Kong PetscFunctionReturn(0); 1600c69f721fSFande Kong } 1601c69f721fSFande Kong 1602c69f721fSFande Kong static PetscErrorCode MatZeroRows_HYPRE_CSRMatrix(hypre_CSRMatrix *hA,PetscInt N,const PetscInt rows[],PetscScalar diag) 1603c69f721fSFande Kong { 1604c69f721fSFande Kong PetscInt ii, jj, ibeg, iend, irow; 1605c69f721fSFande Kong PetscInt *i, *j; 1606c69f721fSFande Kong PetscScalar *a; 1607c69f721fSFande Kong 1608c69f721fSFande Kong PetscFunctionBegin; 1609c69f721fSFande Kong if (!hA) PetscFunctionReturn(0); 1610c69f721fSFande Kong 161108defe43SFande Kong i = (PetscInt*) hypre_CSRMatrixI(hA); 161208defe43SFande Kong j = (PetscInt*) hypre_CSRMatrixJ(hA); 1613c69f721fSFande Kong a = hypre_CSRMatrixData(hA); 1614c69f721fSFande Kong 1615c69f721fSFande Kong for (ii = 0; ii < N; ii++) { 1616c69f721fSFande Kong irow = rows[ii]; 1617c69f721fSFande Kong ibeg = i[irow]; 1618c69f721fSFande Kong iend = i[irow+1]; 1619c69f721fSFande Kong for (jj = ibeg; jj < iend; jj++) 1620c69f721fSFande Kong if (j[jj] == irow) a[jj] = diag; 1621c69f721fSFande Kong else a[jj] = 0.0; 1622c69f721fSFande Kong } 1623c69f721fSFande Kong PetscFunctionReturn(0); 1624c69f721fSFande Kong } 1625c69f721fSFande Kong 1626ddbeb582SStefano Zampini static PetscErrorCode MatZeroRows_HYPRE(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1627c69f721fSFande Kong { 1628c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1629c69f721fSFande Kong PetscInt *lrows,len; 1630c69f721fSFande Kong PetscErrorCode ierr; 1631c69f721fSFande Kong 1632c69f721fSFande Kong PetscFunctionBegin; 1633*c6698e78SStefano Zampini if (x || b) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Does not support to modify the solution and the right hand size"); 1634c69f721fSFande Kong /* retrieve the internal matrix */ 1635c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1636c69f721fSFande Kong /* get locally owned rows */ 1637c69f721fSFande Kong ierr = MatZeroRowsMapLocal_Private(A,N,rows,&len,&lrows);CHKERRQ(ierr); 1638c69f721fSFande Kong /* zero diagonal part */ 1639c69f721fSFande Kong ierr = MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr),len,lrows,diag);CHKERRQ(ierr); 1640c69f721fSFande Kong /* zero off-diagonal part */ 1641c69f721fSFande Kong ierr = MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr),len,lrows,0.0);CHKERRQ(ierr); 1642c69f721fSFande Kong 1643c69f721fSFande Kong ierr = PetscFree(lrows);CHKERRQ(ierr); 1644c69f721fSFande Kong PetscFunctionReturn(0); 1645c69f721fSFande Kong } 1646c69f721fSFande Kong 1647ddbeb582SStefano Zampini static PetscErrorCode MatAssemblyBegin_HYPRE(Mat mat,MatAssemblyType mode) 1648c69f721fSFande Kong { 1649c69f721fSFande Kong PetscErrorCode ierr; 1650c69f721fSFande Kong 1651c69f721fSFande Kong PetscFunctionBegin; 1652c69f721fSFande Kong if (mat->nooffprocentries) PetscFunctionReturn(0); 1653c69f721fSFande Kong 1654c69f721fSFande Kong ierr = MatStashScatterBegin_Private(mat,&mat->stash,mat->rmap->range);CHKERRQ(ierr); 1655c69f721fSFande Kong PetscFunctionReturn(0); 1656c69f721fSFande Kong } 1657c69f721fSFande Kong 1658ddbeb582SStefano Zampini static PetscErrorCode MatGetRow_HYPRE(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1659c69f721fSFande Kong { 1660c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1661c69f721fSFande Kong PetscErrorCode ierr; 1662c69f721fSFande Kong 1663c69f721fSFande Kong PetscFunctionBegin; 1664c69f721fSFande Kong /* retrieve the internal matrix */ 1665c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1666c69f721fSFande Kong /* call HYPRE API */ 166708defe43SFande Kong PetscStackCallStandard(HYPRE_ParCSRMatrixGetRow,(parcsr,row,(HYPRE_Int*)nz,(HYPRE_Int**)idx,v)); 1668c69f721fSFande Kong PetscFunctionReturn(0); 1669c69f721fSFande Kong } 1670c69f721fSFande Kong 1671ddbeb582SStefano Zampini static PetscErrorCode MatRestoreRow_HYPRE(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1672c69f721fSFande Kong { 1673c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1674c69f721fSFande Kong PetscErrorCode ierr; 1675c69f721fSFande Kong 1676c69f721fSFande Kong PetscFunctionBegin; 1677c69f721fSFande Kong /* retrieve the internal matrix */ 1678c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1679c69f721fSFande Kong /* call HYPRE API */ 168008defe43SFande Kong PetscStackCallStandard(HYPRE_ParCSRMatrixRestoreRow,(parcsr,row,(HYPRE_Int*)nz,(HYPRE_Int**)idx,v)); 1681c69f721fSFande Kong PetscFunctionReturn(0); 1682c69f721fSFande Kong } 1683c69f721fSFande Kong 1684ddbeb582SStefano Zampini static PetscErrorCode MatGetValues_HYPRE(Mat A,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1685c69f721fSFande Kong { 168645b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1687c69f721fSFande Kong PetscInt i; 16881d4906efSStefano Zampini 1689c69f721fSFande Kong PetscFunctionBegin; 1690c69f721fSFande Kong if (!m || !n) PetscFunctionReturn(0); 1691c69f721fSFande Kong /* Ignore negative row indices 1692c69f721fSFande Kong * And negative column indices should be automatically ignored in hypre 1693c69f721fSFande Kong * */ 1694c69f721fSFande Kong for (i=0; i<m; i++) 169545b8d346SStefano Zampini if (idxm[i] >= 0) PetscStackCallStandard(HYPRE_IJMatrixGetValues,(hA->ij,1,(HYPRE_Int*)&n,(HYPRE_Int*)&idxm[i],(HYPRE_Int*)idxn,&v[i*n])); 1696c69f721fSFande Kong PetscFunctionReturn(0); 1697c69f721fSFande Kong } 1698c69f721fSFande Kong 1699ddbeb582SStefano Zampini static PetscErrorCode MatSetOption_HYPRE(Mat A,MatOption op,PetscBool flg) 1700ddbeb582SStefano Zampini { 1701ddbeb582SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1702ddbeb582SStefano Zampini 1703ddbeb582SStefano Zampini PetscFunctionBegin; 1704*c6698e78SStefano Zampini switch (op) { 1705ddbeb582SStefano Zampini case MAT_NO_OFF_PROC_ENTRIES: 1706ddbeb582SStefano Zampini if (flg) { 1707ddbeb582SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetMaxOffProcElmts,(hA->ij,0)); 1708ddbeb582SStefano Zampini } 1709ddbeb582SStefano Zampini break; 1710ddbeb582SStefano Zampini default: 1711ddbeb582SStefano Zampini break; 1712ddbeb582SStefano Zampini } 1713ddbeb582SStefano Zampini PetscFunctionReturn(0); 1714ddbeb582SStefano Zampini } 1715c69f721fSFande Kong 171645b8d346SStefano Zampini static PetscErrorCode MatView_HYPRE(Mat A, PetscViewer view) 171745b8d346SStefano Zampini { 171845b8d346SStefano Zampini hypre_ParCSRMatrix *parcsr; 171945b8d346SStefano Zampini PetscErrorCode ierr; 172045b8d346SStefano Zampini Mat B; 172145b8d346SStefano Zampini PetscViewerFormat format; 172245b8d346SStefano Zampini PetscErrorCode (*mview)(Mat,PetscViewer) = NULL; 172345b8d346SStefano Zampini 172445b8d346SStefano Zampini PetscFunctionBegin; 172545b8d346SStefano Zampini ierr = PetscViewerGetFormat(view,&format);CHKERRQ(ierr); 172645b8d346SStefano Zampini if (format != PETSC_VIEWER_NATIVE) { 172745b8d346SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 172845b8d346SStefano Zampini ierr = MatCreateFromParCSR(parcsr,MATAIJ,PETSC_USE_POINTER,&B);CHKERRQ(ierr); 172945b8d346SStefano Zampini ierr = MatGetOperation(B,MATOP_VIEW,(void(**)(void))&mview);CHKERRQ(ierr); 173045b8d346SStefano Zampini if (!mview) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Missing view operation");CHKERRQ(ierr); 173145b8d346SStefano Zampini ierr = (*mview)(B,view);CHKERRQ(ierr); 173245b8d346SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 173345b8d346SStefano Zampini } else { 173445b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 173545b8d346SStefano Zampini PetscMPIInt size; 173645b8d346SStefano Zampini PetscBool isascii; 173745b8d346SStefano Zampini const char *filename; 173845b8d346SStefano Zampini 173945b8d346SStefano Zampini /* HYPRE uses only text files */ 174045b8d346SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 174145b8d346SStefano Zampini if (!isascii) SETERRQ1(PetscObjectComm((PetscObject)view),PETSC_ERR_SUP,"PetscViewerType %s: native HYPRE format needs PETSCVIEWERASCII",((PetscObject)view)->type_name); 174245b8d346SStefano Zampini ierr = PetscViewerFileGetName(view,&filename);CHKERRQ(ierr); 174345b8d346SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixPrint,(hA->ij,filename)); 174445b8d346SStefano Zampini ierr = MPI_Comm_size(hA->comm,&size);CHKERRQ(ierr); 174545b8d346SStefano Zampini if (size > 1) { 174645b8d346SStefano Zampini ierr = PetscViewerASCIIPrintf(view,"Matrix files: %s.%05d ... %s.%05d\n",filename,0,filename,size-1);CHKERRQ(ierr); 174745b8d346SStefano Zampini } else { 174845b8d346SStefano Zampini ierr = PetscViewerASCIIPrintf(view,"Matrix file: %s.%05d\n",filename,0);CHKERRQ(ierr); 174945b8d346SStefano Zampini } 175045b8d346SStefano Zampini } 175145b8d346SStefano Zampini PetscFunctionReturn(0); 175245b8d346SStefano Zampini } 175345b8d346SStefano Zampini 175445b8d346SStefano Zampini static PetscErrorCode MatDuplicate_HYPRE(Mat A,MatDuplicateOption op, Mat *B) 175545b8d346SStefano Zampini { 175645b8d346SStefano Zampini hypre_ParCSRMatrix *parcsr; 175745b8d346SStefano Zampini PetscErrorCode ierr; 175845b8d346SStefano Zampini PetscCopyMode cpmode; 175945b8d346SStefano Zampini 176045b8d346SStefano Zampini PetscFunctionBegin; 176145b8d346SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 176245b8d346SStefano Zampini if (op == MAT_DO_NOT_COPY_VALUES || op == MAT_SHARE_NONZERO_PATTERN) { 176345b8d346SStefano Zampini parcsr = hypre_ParCSRMatrixCompleteClone(parcsr); 176445b8d346SStefano Zampini cpmode = PETSC_OWN_POINTER; 176545b8d346SStefano Zampini } else { 176645b8d346SStefano Zampini cpmode = PETSC_COPY_VALUES; 176745b8d346SStefano Zampini } 176845b8d346SStefano Zampini ierr = MatCreateFromParCSR(parcsr,MATHYPRE,cpmode,B);CHKERRQ(ierr); 176945b8d346SStefano Zampini PetscFunctionReturn(0); 177045b8d346SStefano Zampini } 177145b8d346SStefano Zampini 1772465edc17SStefano Zampini static PetscErrorCode MatCopy_HYPRE(Mat A, Mat B, MatStructure str) 1773465edc17SStefano Zampini { 1774465edc17SStefano Zampini hypre_ParCSRMatrix *acsr,*bcsr; 1775465edc17SStefano Zampini PetscErrorCode ierr; 1776465edc17SStefano Zampini 1777465edc17SStefano Zampini PetscFunctionBegin; 1778465edc17SStefano Zampini if (str == SAME_NONZERO_PATTERN && A->ops->copy == B->ops->copy) { 1779465edc17SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&acsr);CHKERRQ(ierr); 1780465edc17SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(B,&bcsr);CHKERRQ(ierr); 1781465edc17SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixCopy,(acsr,bcsr,1)); 1782465edc17SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1783465edc17SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1784465edc17SStefano Zampini } else { 1785465edc17SStefano Zampini ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1786465edc17SStefano Zampini } 1787465edc17SStefano Zampini PetscFunctionReturn(0); 1788465edc17SStefano Zampini } 1789465edc17SStefano Zampini 17906305df00SStefano Zampini static PetscErrorCode MatGetDiagonal_HYPRE(Mat A, Vec d) 17916305df00SStefano Zampini { 17926305df00SStefano Zampini hypre_ParCSRMatrix *parcsr; 17936305df00SStefano Zampini hypre_CSRMatrix *dmat; 17946305df00SStefano Zampini PetscScalar *a,*data = NULL; 17956305df00SStefano Zampini PetscInt i,*diag = NULL; 17966305df00SStefano Zampini PetscBool cong; 17976305df00SStefano Zampini PetscErrorCode ierr; 17986305df00SStefano Zampini 17996305df00SStefano Zampini PetscFunctionBegin; 18006305df00SStefano Zampini ierr = MatHasCongruentLayouts(A,&cong);CHKERRQ(ierr); 18016305df00SStefano Zampini if (!cong) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only for square matrices with same local distributions of rows and columns"); 18026305df00SStefano Zampini #if defined(PETSC_USE_DEBUG) 18036305df00SStefano Zampini { 18046305df00SStefano Zampini PetscBool miss; 18056305df00SStefano Zampini ierr = MatMissingDiagonal(A,&miss,NULL);CHKERRQ(ierr); 18066305df00SStefano Zampini if (miss && A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented when diagonal entries are missing"); 18076305df00SStefano Zampini } 18086305df00SStefano Zampini #endif 18096305df00SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 18106305df00SStefano Zampini dmat = hypre_ParCSRMatrixDiag(parcsr); 18116305df00SStefano Zampini if (dmat) { 18126305df00SStefano Zampini ierr = VecGetArray(d,&a);CHKERRQ(ierr); 18136305df00SStefano Zampini diag = (PetscInt*)(hypre_CSRMatrixI(dmat)); 18146305df00SStefano Zampini data = (PetscScalar*)(hypre_CSRMatrixData(dmat)); 18156305df00SStefano Zampini for (i=0;i<A->rmap->n;i++) a[i] = data[diag[i]]; 18166305df00SStefano Zampini ierr = VecRestoreArray(d,&a);CHKERRQ(ierr); 18176305df00SStefano Zampini } 18186305df00SStefano Zampini PetscFunctionReturn(0); 18196305df00SStefano Zampini } 18206305df00SStefano Zampini 1821363d496dSStefano Zampini #include <petscblaslapack.h> 1822363d496dSStefano Zampini 1823363d496dSStefano Zampini static PetscErrorCode MatAXPY_HYPRE(Mat Y,PetscScalar a,Mat X,MatStructure str) 1824363d496dSStefano Zampini { 1825363d496dSStefano Zampini PetscErrorCode ierr; 1826363d496dSStefano Zampini 1827363d496dSStefano Zampini PetscFunctionBegin; 1828363d496dSStefano Zampini if (str == SAME_NONZERO_PATTERN) { 1829363d496dSStefano Zampini hypre_ParCSRMatrix *x,*y; 1830363d496dSStefano Zampini hypre_CSRMatrix *xloc,*yloc; 1831363d496dSStefano Zampini PetscInt xnnz,ynnz; 1832363d496dSStefano Zampini PetscScalar *xarr,*yarr; 1833363d496dSStefano Zampini PetscBLASInt one=1,bnz; 1834363d496dSStefano Zampini 1835363d496dSStefano Zampini ierr = MatHYPREGetParCSR(Y,&y);CHKERRQ(ierr); 1836363d496dSStefano Zampini ierr = MatHYPREGetParCSR(X,&x);CHKERRQ(ierr); 1837363d496dSStefano Zampini 1838363d496dSStefano Zampini /* diagonal block */ 1839363d496dSStefano Zampini xloc = hypre_ParCSRMatrixDiag(x); 1840363d496dSStefano Zampini yloc = hypre_ParCSRMatrixDiag(y); 1841363d496dSStefano Zampini xnnz = 0; 1842363d496dSStefano Zampini ynnz = 0; 1843363d496dSStefano Zampini xarr = NULL; 1844363d496dSStefano Zampini yarr = NULL; 1845363d496dSStefano Zampini if (xloc) { 1846363d496dSStefano Zampini xarr = (PetscScalar*)(hypre_CSRMatrixData(xloc)); 1847363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 1848363d496dSStefano Zampini } 1849363d496dSStefano Zampini if (yloc) { 1850363d496dSStefano Zampini yarr = (PetscScalar*)(hypre_CSRMatrixData(yloc)); 1851363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 1852363d496dSStefano Zampini } 1853363d496dSStefano Zampini if (xnnz != ynnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Different number of nonzeros in diagonal block %D != %D",xnnz,ynnz); 1854363d496dSStefano Zampini ierr = PetscBLASIntCast(xnnz,&bnz);CHKERRQ(ierr); 1855363d496dSStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&a,xarr,&one,yarr,&one)); 1856363d496dSStefano Zampini 1857363d496dSStefano Zampini /* off-diagonal block */ 1858363d496dSStefano Zampini xloc = hypre_ParCSRMatrixOffd(x); 1859363d496dSStefano Zampini yloc = hypre_ParCSRMatrixOffd(y); 1860363d496dSStefano Zampini xnnz = 0; 1861363d496dSStefano Zampini ynnz = 0; 1862363d496dSStefano Zampini xarr = NULL; 1863363d496dSStefano Zampini yarr = NULL; 1864363d496dSStefano Zampini if (xloc) { 1865363d496dSStefano Zampini xarr = (PetscScalar*)(hypre_CSRMatrixData(xloc)); 1866363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 1867363d496dSStefano Zampini } 1868363d496dSStefano Zampini if (yloc) { 1869363d496dSStefano Zampini yarr = (PetscScalar*)(hypre_CSRMatrixData(yloc)); 1870363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 1871363d496dSStefano Zampini } 1872363d496dSStefano Zampini if (xnnz != ynnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Different number of nonzeros in off-diagonal block %D != %D",xnnz,ynnz); 1873363d496dSStefano Zampini ierr = PetscBLASIntCast(xnnz,&bnz);CHKERRQ(ierr); 1874363d496dSStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&a,xarr,&one,yarr,&one)); 1875363d496dSStefano Zampini } else if (str == SUBSET_NONZERO_PATTERN) { 1876363d496dSStefano Zampini ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 1877363d496dSStefano Zampini } else { 1878363d496dSStefano Zampini Mat B; 1879363d496dSStefano Zampini 1880363d496dSStefano Zampini ierr = MatAXPY_Basic_Preallocate(Y,X,&B);CHKERRQ(ierr); 1881363d496dSStefano Zampini ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 1882363d496dSStefano Zampini ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 1883363d496dSStefano Zampini } 1884363d496dSStefano Zampini PetscFunctionReturn(0); 1885363d496dSStefano Zampini } 1886363d496dSStefano Zampini 1887a055b5aaSBarry Smith /*MC 1888a055b5aaSBarry Smith MATHYPRE - MATHYPRE = "hypre" - A matrix type to be used for sequential and parallel sparse matrices 1889a055b5aaSBarry Smith based on the hypre IJ interface. 1890a055b5aaSBarry Smith 1891a055b5aaSBarry Smith Level: intermediate 1892a055b5aaSBarry Smith 1893a055b5aaSBarry Smith .seealso: MatCreate() 1894a055b5aaSBarry Smith M*/ 1895a055b5aaSBarry Smith 189663c07aadSStefano Zampini PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 189763c07aadSStefano Zampini { 189863c07aadSStefano Zampini Mat_HYPRE *hB; 189963c07aadSStefano Zampini PetscErrorCode ierr; 190063c07aadSStefano Zampini 190163c07aadSStefano Zampini PetscFunctionBegin; 190263c07aadSStefano Zampini ierr = PetscNewLog(B,&hB);CHKERRQ(ierr); 1903978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 1904c69f721fSFande Kong hB->available = PETSC_TRUE; 1905c69f721fSFande Kong hB->size = 0; 1906c69f721fSFande Kong hB->array = NULL; 1907978814f1SStefano Zampini 190863c07aadSStefano Zampini B->data = (void*)hB; 190963c07aadSStefano Zampini B->rmap->bs = 1; 191063c07aadSStefano Zampini B->assembled = PETSC_FALSE; 191163c07aadSStefano Zampini 1912de393100SStefano Zampini ierr = PetscMemzero(B->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 191363c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 191463c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 1915414bd5c3SStefano Zampini B->ops->multadd = MatMultAdd_HYPRE; 1916414bd5c3SStefano Zampini B->ops->multtransposeadd = MatMultTransposeAdd_HYPRE; 191763c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 191863c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 191963c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 1920c69f721fSFande Kong B->ops->assemblybegin = MatAssemblyBegin_HYPRE; 1921cd8bc7baSStefano Zampini B->ops->ptap = MatPtAP_HYPRE_HYPRE; 1922d501dc42Sstefano_zampini B->ops->matmult = MatMatMult_HYPRE_HYPRE; 1923d975228cSstefano_zampini B->ops->setvalues = MatSetValues_HYPRE; 192468ec7858SStefano Zampini B->ops->missingdiagonal = MatMissingDiagonal_HYPRE; 192568ec7858SStefano Zampini B->ops->scale = MatScale_HYPRE; 192668ec7858SStefano Zampini B->ops->zerorowscolumns = MatZeroRowsColumns_HYPRE; 1927c69f721fSFande Kong B->ops->zeroentries = MatZeroEntries_HYPRE; 1928c69f721fSFande Kong B->ops->zerorows = MatZeroRows_HYPRE; 1929c69f721fSFande Kong B->ops->getrow = MatGetRow_HYPRE; 1930c69f721fSFande Kong B->ops->restorerow = MatRestoreRow_HYPRE; 1931c69f721fSFande Kong B->ops->getvalues = MatGetValues_HYPRE; 1932ddbeb582SStefano Zampini B->ops->setoption = MatSetOption_HYPRE; 193345b8d346SStefano Zampini B->ops->duplicate = MatDuplicate_HYPRE; 1934465edc17SStefano Zampini B->ops->copy = MatCopy_HYPRE; 193545b8d346SStefano Zampini B->ops->view = MatView_HYPRE; 19366305df00SStefano Zampini B->ops->getdiagonal = MatGetDiagonal_HYPRE; 1937363d496dSStefano Zampini B->ops->axpy = MatAXPY_HYPRE; 193845b8d346SStefano Zampini 193945b8d346SStefano Zampini /* build cache for off array entries formed */ 194045b8d346SStefano Zampini ierr = MatStashCreate_Private(PetscObjectComm((PetscObject)B),1,&B->stash);CHKERRQ(ierr); 194163c07aadSStefano Zampini 194263c07aadSStefano Zampini ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)B),&hB->comm);CHKERRQ(ierr); 194363c07aadSStefano Zampini ierr = PetscObjectChangeTypeName((PetscObject)B,MATHYPRE);CHKERRQ(ierr); 194463c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_aij_C",MatConvert_HYPRE_AIJ);CHKERRQ(ierr); 19452df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_is_C",MatConvert_HYPRE_IS);CHKERRQ(ierr); 1946c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_hypre_C",MatPtAP_AIJ_HYPRE);CHKERRQ(ierr); 1947c1a070e6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_mpiaij_hypre_C",MatPtAP_AIJ_HYPRE);CHKERRQ(ierr); 1948d975228cSstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatHYPRESetPreallocation_C",MatHYPRESetPreallocation_HYPRE);CHKERRQ(ierr); 1949dd9c0a25Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatHYPREGetParCSR_C",MatHYPREGetParCSR_HYPRE);CHKERRQ(ierr); 195075d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_hypre_C",MatPtAP_IS_XAIJ);CHKERRQ(ierr); 195163c07aadSStefano Zampini PetscFunctionReturn(0); 195263c07aadSStefano Zampini } 195363c07aadSStefano Zampini 1954225daaf8SStefano Zampini static PetscErrorCode hypre_array_destroy(void *ptr) 1955225daaf8SStefano Zampini { 1956225daaf8SStefano Zampini PetscFunctionBegin; 1957e6de0934SSatish Balay hypre_TFree(ptr,HYPRE_MEMORY_HOST); 1958225daaf8SStefano Zampini PetscFunctionReturn(0); 1959225daaf8SStefano Zampini } 1960