163c07aadSStefano Zampini 263c07aadSStefano Zampini /* 363c07aadSStefano Zampini Creates hypre ijmatrix from PETSc matrix 463c07aadSStefano Zampini */ 563c07aadSStefano Zampini #include <petscsys.h> 663c07aadSStefano Zampini #include <petsc/private/matimpl.h> 763c07aadSStefano Zampini #include <../src/mat/impls/hypre/mhypre.h> 863c07aadSStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 963c07aadSStefano Zampini #include <HYPRE_struct_mv.h> 1063c07aadSStefano Zampini #include <HYPRE_struct_ls.h> 1163c07aadSStefano Zampini #include <_hypre_struct_mv.h> 1263c07aadSStefano Zampini 1363c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat,Mat_HYPRE*); 1463c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat,Mat,HYPRE_IJMatrix); 1563c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat,HYPRE_IJMatrix); 1663c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat,HYPRE_IJMatrix); 1763c07aadSStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat,Vec,Vec,PetscBool); 1863c07aadSStefano Zampini 1963c07aadSStefano Zampini #undef __FUNCT__ 2063c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixPreallocate" 2163c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat A_d, Mat A_o, HYPRE_IJMatrix ij) 2263c07aadSStefano Zampini { 2363c07aadSStefano Zampini PetscErrorCode ierr; 2463c07aadSStefano Zampini PetscInt i,n_d,n_o; 2563c07aadSStefano Zampini const PetscInt *ia_d,*ia_o; 2663c07aadSStefano Zampini PetscBool done_d=PETSC_FALSE,done_o=PETSC_FALSE; 2763c07aadSStefano Zampini PetscInt *nnz_d=NULL,*nnz_o=NULL; 2863c07aadSStefano Zampini 2963c07aadSStefano Zampini PetscFunctionBegin; 3063c07aadSStefano Zampini if (A_d) { /* determine number of nonzero entries in local diagonal part */ 3163c07aadSStefano Zampini ierr = MatGetRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,&n_d,&ia_d,NULL,&done_d);CHKERRQ(ierr); 3263c07aadSStefano Zampini if (done_d) { 3363c07aadSStefano Zampini ierr = PetscMalloc1(n_d,&nnz_d);CHKERRQ(ierr); 3463c07aadSStefano Zampini for (i=0; i<n_d; i++) { 3563c07aadSStefano Zampini nnz_d[i] = ia_d[i+1] - ia_d[i]; 3663c07aadSStefano Zampini } 3763c07aadSStefano Zampini } 3863c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,NULL,&ia_d,NULL,&done_d);CHKERRQ(ierr); 3963c07aadSStefano Zampini } 4063c07aadSStefano Zampini if (A_o) { /* determine number of nonzero entries in local off-diagonal part */ 4163c07aadSStefano Zampini ierr = MatGetRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 4263c07aadSStefano Zampini if (done_o) { 4363c07aadSStefano Zampini ierr = PetscMalloc1(n_o,&nnz_o);CHKERRQ(ierr); 4463c07aadSStefano Zampini for (i=0; i<n_o; i++) { 4563c07aadSStefano Zampini nnz_o[i] = ia_o[i+1] - ia_o[i]; 4663c07aadSStefano Zampini } 4763c07aadSStefano Zampini } 4863c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 4963c07aadSStefano Zampini } 5063c07aadSStefano Zampini if (done_d) { /* set number of nonzeros in HYPRE IJ matrix */ 5163c07aadSStefano Zampini if (!done_o) { /* only diagonal part */ 5263c07aadSStefano Zampini ierr = PetscMalloc1(n_d,&nnz_o);CHKERRQ(ierr); 5363c07aadSStefano Zampini for (i=0; i<n_d; i++) { 5463c07aadSStefano Zampini nnz_o[i] = 0; 5563c07aadSStefano Zampini } 5663c07aadSStefano Zampini } 5763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(ij,(HYPRE_Int *)nnz_d,(HYPRE_Int *)nnz_o)); 5863c07aadSStefano Zampini ierr = PetscFree(nnz_d);CHKERRQ(ierr); 5963c07aadSStefano Zampini ierr = PetscFree(nnz_o);CHKERRQ(ierr); 6063c07aadSStefano Zampini } 6163c07aadSStefano Zampini PetscFunctionReturn(0); 6263c07aadSStefano Zampini } 6363c07aadSStefano Zampini 6463c07aadSStefano Zampini #undef __FUNCT__ 6563c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_CreateFromMat" 6663c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat A, Mat_HYPRE *hA) 6763c07aadSStefano Zampini { 6863c07aadSStefano Zampini PetscErrorCode ierr; 6963c07aadSStefano Zampini PetscInt rstart,rend,cstart,cend; 7063c07aadSStefano Zampini 7163c07aadSStefano Zampini PetscFunctionBegin; 7263c07aadSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 7363c07aadSStefano Zampini rstart = A->rmap->rstart; 7463c07aadSStefano Zampini rend = A->rmap->rend; 7563c07aadSStefano Zampini cstart = A->cmap->rstart; 7663c07aadSStefano Zampini cend = A->cmap->rend; 7763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 7863c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 7963c07aadSStefano Zampini { 8063c07aadSStefano Zampini PetscBool same; 8163c07aadSStefano Zampini Mat A_d,A_o; 8263c07aadSStefano Zampini const PetscInt *colmap; 8363c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&same);CHKERRQ(ierr); 8463c07aadSStefano Zampini if (same) { 8563c07aadSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 8663c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 8763c07aadSStefano Zampini PetscFunctionReturn(0); 8863c07aadSStefano Zampini } 8963c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&same);CHKERRQ(ierr); 9063c07aadSStefano Zampini if (same) { 9163c07aadSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 9263c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 9363c07aadSStefano Zampini PetscFunctionReturn(0); 9463c07aadSStefano Zampini } 9563c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&same);CHKERRQ(ierr); 9663c07aadSStefano Zampini if (same) { 9763c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A,NULL,hA->ij);CHKERRQ(ierr); 9863c07aadSStefano Zampini PetscFunctionReturn(0); 9963c07aadSStefano Zampini } 10063c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&same);CHKERRQ(ierr); 10163c07aadSStefano Zampini if (same) { 10263c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A,NULL,hA->ij);CHKERRQ(ierr); 10363c07aadSStefano Zampini PetscFunctionReturn(0); 10463c07aadSStefano Zampini } 10563c07aadSStefano Zampini } 10663c07aadSStefano Zampini PetscFunctionReturn(0); 10763c07aadSStefano Zampini } 10863c07aadSStefano Zampini 10963c07aadSStefano Zampini #undef __FUNCT__ 11063c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixCopy" 11163c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopy(Mat A, HYPRE_IJMatrix ij) 11263c07aadSStefano Zampini { 11363c07aadSStefano Zampini PetscErrorCode ierr; 11463c07aadSStefano Zampini PetscInt i,rstart,rend,ncols,nr,nc; 11563c07aadSStefano Zampini const PetscScalar *values; 11663c07aadSStefano Zampini const PetscInt *cols; 11763c07aadSStefano Zampini PetscBool flg; 11863c07aadSStefano Zampini 11963c07aadSStefano Zampini PetscFunctionBegin; 12063c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr); 12163c07aadSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 12263c07aadSStefano Zampini if (flg && nr == nc) { 12363c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_MPIAIJ(A,ij);CHKERRQ(ierr); 12463c07aadSStefano Zampini PetscFunctionReturn(0); 12563c07aadSStefano Zampini } 12663c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr); 12763c07aadSStefano Zampini if (flg) { 12863c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_SeqAIJ(A,ij);CHKERRQ(ierr); 12963c07aadSStefano Zampini PetscFunctionReturn(0); 13063c07aadSStefano Zampini } 13163c07aadSStefano Zampini 13263c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 13363c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 13463c07aadSStefano Zampini for (i=rstart; i<rend; i++) { 13563c07aadSStefano Zampini ierr = MatGetRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 13663c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetValues,(ij,1,(HYPRE_Int *)&ncols,(HYPRE_Int *)&i,(HYPRE_Int *)cols,values)); 13763c07aadSStefano Zampini ierr = MatRestoreRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 13863c07aadSStefano Zampini } 13963c07aadSStefano Zampini PetscFunctionReturn(0); 14063c07aadSStefano Zampini } 14163c07aadSStefano Zampini 14263c07aadSStefano Zampini #undef __FUNCT__ 14363c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixFastCopy_SeqAIJ" 14463c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat A, HYPRE_IJMatrix ij) 14563c07aadSStefano Zampini { 14663c07aadSStefano Zampini PetscErrorCode ierr; 14763c07aadSStefano Zampini Mat_SeqAIJ *pdiag = (Mat_SeqAIJ*)A->data; 148ea9daf28SStefano Zampini int type; 14963c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 15063c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 15163c07aadSStefano Zampini hypre_CSRMatrix *hdiag; 15263c07aadSStefano Zampini 15363c07aadSStefano Zampini PetscFunctionBegin; 15463c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 155ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 156ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 157ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 15863c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 15963c07aadSStefano Zampini /* 16063c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 16163c07aadSStefano Zampini */ 16263c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->i,pdiag->i,(A->rmap->n + 1)*sizeof(PetscInt)); 16363c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->j,pdiag->j,pdiag->nz*sizeof(PetscInt)); 16463c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar)); 165ea9daf28SStefano Zampini 166ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 16763c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 16863c07aadSStefano Zampini PetscFunctionReturn(0); 16963c07aadSStefano Zampini } 17063c07aadSStefano Zampini 17163c07aadSStefano Zampini #undef __FUNCT__ 17263c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixFastCopy_MPIAIJ" 17363c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat A, HYPRE_IJMatrix ij) 17463c07aadSStefano Zampini { 17563c07aadSStefano Zampini PetscErrorCode ierr; 17663c07aadSStefano Zampini Mat_MPIAIJ *pA = (Mat_MPIAIJ*)A->data; 17763c07aadSStefano Zampini Mat_SeqAIJ *pdiag,*poffd; 17863c07aadSStefano Zampini PetscInt i,*garray = pA->garray,*jj,cstart,*pjj; 179ea9daf28SStefano Zampini int type; 18063c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 18163c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 18263c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 18363c07aadSStefano Zampini 18463c07aadSStefano Zampini PetscFunctionBegin; 18563c07aadSStefano Zampini pdiag = (Mat_SeqAIJ*) pA->A->data; 18663c07aadSStefano Zampini poffd = (Mat_SeqAIJ*) pA->B->data; 18763c07aadSStefano Zampini /* cstart is only valid for square MPIAIJ layed out in the usual way */ 18863c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&cstart,NULL);CHKERRQ(ierr); 18963c07aadSStefano Zampini 19063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 191ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 192ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 193ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 19463c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 19563c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(par_matrix); 19663c07aadSStefano Zampini 19763c07aadSStefano Zampini /* 19863c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 19963c07aadSStefano Zampini */ 20063c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->i,pdiag->i,(pA->A->rmap->n + 1)*sizeof(PetscInt)); 20163c07aadSStefano Zampini /* need to shift the diag column indices (hdiag->j) back to global numbering since hypre is expecting this */ 20263c07aadSStefano Zampini jj = (PetscInt*)hdiag->j; 20363c07aadSStefano Zampini pjj = (PetscInt*)pdiag->j; 20463c07aadSStefano Zampini for (i=0; i<pdiag->nz; i++) jj[i] = cstart + pjj[i]; 20563c07aadSStefano Zampini ierr = PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar)); 20663c07aadSStefano Zampini ierr = PetscMemcpy(hoffd->i,poffd->i,(pA->A->rmap->n + 1)*sizeof(PetscInt)); 20763c07aadSStefano Zampini /* need to move the offd column indices (hoffd->j) back to global numbering since hypre is expecting this 20863c07aadSStefano Zampini If we hacked a hypre a bit more we might be able to avoid this step */ 20963c07aadSStefano Zampini jj = (PetscInt*) hoffd->j; 21063c07aadSStefano Zampini pjj = (PetscInt*) poffd->j; 21163c07aadSStefano Zampini for (i=0; i<poffd->nz; i++) jj[i] = garray[pjj[i]]; 21263c07aadSStefano Zampini ierr = PetscMemcpy(hoffd->data,poffd->a,poffd->nz*sizeof(PetscScalar)); 21363c07aadSStefano Zampini 214ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 21563c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 21663c07aadSStefano Zampini PetscFunctionReturn(0); 21763c07aadSStefano Zampini } 21863c07aadSStefano Zampini 21963c07aadSStefano Zampini #undef __FUNCT__ 2202df22349SStefano Zampini #define __FUNCT__ "MatConvert_HYPRE_IS" 2212df22349SStefano Zampini static PetscErrorCode MatConvert_HYPRE_IS(Mat A, MatType mtype, MatReuse reuse, Mat* B) 2222df22349SStefano Zampini { 2232df22349SStefano Zampini Mat_HYPRE* mhA = (Mat_HYPRE*)(A->data); 2242df22349SStefano Zampini Mat lA; 2252df22349SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2262df22349SStefano Zampini IS is; 2272df22349SStefano Zampini hypre_ParCSRMatrix *hA; 2282df22349SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 2292df22349SStefano Zampini MPI_Comm comm; 2302df22349SStefano Zampini PetscScalar *hdd,*hod,*aa,*data; 2312df22349SStefano Zampini PetscInt *col_map_offd,*hdi,*hdj,*hoi,*hoj; 2322df22349SStefano Zampini PetscInt *ii,*jj,*iptr,*jptr; 2332df22349SStefano Zampini PetscInt cum,dr,dc,oc,str,stc,nnz,i,jd,jo,M,N; 2342df22349SStefano Zampini int type; 2352df22349SStefano Zampini PetscErrorCode ierr; 2362df22349SStefano Zampini 2372df22349SStefano Zampini PetscFunctionBegin; 238a1787963SStefano Zampini comm = PetscObjectComm((PetscObject)A); 2392df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(mhA->ij,&type)); 2402df22349SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 2412df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(mhA->ij,(void**)&hA)); 2422df22349SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(hA); 2432df22349SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(hA); 2442df22349SStefano Zampini str = hypre_ParCSRMatrixFirstRowIndex(hA); 2452df22349SStefano Zampini stc = hypre_ParCSRMatrixFirstColDiag(hA); 2462df22349SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(hA); 2472df22349SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(hA); 2482df22349SStefano Zampini dr = hypre_CSRMatrixNumRows(hdiag); 2492df22349SStefano Zampini dc = hypre_CSRMatrixNumCols(hdiag); 2502df22349SStefano Zampini nnz = hypre_CSRMatrixNumNonzeros(hdiag); 2512df22349SStefano Zampini hdi = hypre_CSRMatrixI(hdiag); 2522df22349SStefano Zampini hdj = hypre_CSRMatrixJ(hdiag); 2532df22349SStefano Zampini hdd = hypre_CSRMatrixData(hdiag); 2542df22349SStefano Zampini oc = hypre_CSRMatrixNumCols(hoffd); 2552df22349SStefano Zampini nnz += hypre_CSRMatrixNumNonzeros(hoffd); 2562df22349SStefano Zampini hoi = hypre_CSRMatrixI(hoffd); 2572df22349SStefano Zampini hoj = hypre_CSRMatrixJ(hoffd); 2582df22349SStefano Zampini hod = hypre_CSRMatrixData(hoffd); 2592df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2602df22349SStefano Zampini PetscInt *aux; 2612df22349SStefano Zampini 2622df22349SStefano Zampini /* generate l2g maps for rows and cols */ 2632df22349SStefano Zampini ierr = ISCreateStride(comm,dr,str,1,&is);CHKERRQ(ierr); 2642df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2652df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2662df22349SStefano Zampini col_map_offd = hypre_ParCSRMatrixColMapOffd(hA); 2672df22349SStefano Zampini ierr = PetscMalloc1(dc+oc,&aux);CHKERRQ(ierr); 2682df22349SStefano Zampini for (i=0; i<dc; i++) aux[i] = i+stc; 2692df22349SStefano Zampini for (i=0; i<oc; i++) aux[i+dc] = col_map_offd[i]; 2702df22349SStefano Zampini ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2712df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2722df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2732df22349SStefano Zampini /* create MATIS object */ 2742df22349SStefano Zampini ierr = MatCreate(comm,B);CHKERRQ(ierr); 2752df22349SStefano Zampini ierr = MatSetSizes(*B,dr,dc,M,N);CHKERRQ(ierr); 2762df22349SStefano Zampini ierr = MatSetType(*B,MATIS);CHKERRQ(ierr); 2772df22349SStefano Zampini ierr = MatSetLocalToGlobalMapping(*B,rl2g,cl2g);CHKERRQ(ierr); 2782df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2792df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2802df22349SStefano Zampini 2812df22349SStefano Zampini /* allocate CSR for local matrix */ 2822df22349SStefano Zampini ierr = PetscMalloc1(dr+1,&iptr);CHKERRQ(ierr); 2832df22349SStefano Zampini ierr = PetscMalloc1(nnz,&jptr);CHKERRQ(ierr); 2842df22349SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 2852df22349SStefano Zampini } else { 2862df22349SStefano Zampini PetscInt nr; 2872df22349SStefano Zampini PetscBool done; 2882df22349SStefano Zampini ierr = MatISGetLocalMat(*B,&lA);CHKERRQ(ierr); 2892df22349SStefano Zampini ierr = MatGetRowIJ(lA,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&iptr,(const PetscInt**)&jptr,&done);CHKERRQ(ierr); 2902df22349SStefano 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); 2912df22349SStefano 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); 2922df22349SStefano Zampini ierr = MatSeqAIJGetArray(lA,&data);CHKERRQ(ierr); 2932df22349SStefano Zampini } 2942df22349SStefano Zampini /* merge local matrices */ 2952df22349SStefano Zampini ii = iptr; 2962df22349SStefano Zampini jj = jptr; 2972df22349SStefano Zampini aa = data; 2982df22349SStefano Zampini *ii = *(hdi++) + *(hoi++); 2992df22349SStefano Zampini for (jd=0,jo=0,cum=0; *ii<nnz; cum++) { 3002df22349SStefano Zampini PetscScalar *aold = aa; 3012df22349SStefano Zampini PetscInt *jold = jj,nc = jd+jo; 3022df22349SStefano Zampini for (; jd<*hdi; jd++) { *jj++ = *hdj++; *aa++ = *hdd++; } 3032df22349SStefano Zampini for (; jo<*hoi; jo++) { *jj++ = *hoj++ + dc; *aa++ = *hod++; } 3042df22349SStefano Zampini *(++ii) = *(hdi++) + *(hoi++); 3052df22349SStefano Zampini ierr = PetscSortIntWithScalarArray(jd+jo-nc,jold,aold);CHKERRQ(ierr); 3062df22349SStefano Zampini } 3072df22349SStefano Zampini for (; cum<dr; cum++) *(++ii) = nnz; 3082df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 309*a033916dSStefano Zampini Mat_SeqAIJ* a; 310*a033916dSStefano Zampini 3112df22349SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,dc+oc,iptr,jptr,data,&lA);CHKERRQ(ierr); 3122df22349SStefano Zampini ierr = MatISSetLocalMat(*B,lA);CHKERRQ(ierr); 313*a033916dSStefano Zampini /* hack SeqAIJ */ 314*a033916dSStefano Zampini a = (Mat_SeqAIJ*)(lA->data); 315*a033916dSStefano Zampini a->free_a = PETSC_TRUE; 316*a033916dSStefano Zampini a->free_ij = PETSC_TRUE; 3172df22349SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 3182df22349SStefano Zampini } 3192df22349SStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3202df22349SStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3212df22349SStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 3222df22349SStefano Zampini ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); 3232df22349SStefano Zampini } 3242df22349SStefano Zampini PetscFunctionReturn(0); 3252df22349SStefano Zampini } 3262df22349SStefano Zampini 3272df22349SStefano Zampini #undef __FUNCT__ 32863c07aadSStefano Zampini #define __FUNCT__ "MatConvert_AIJ_HYPRE" 32963c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A, MatType type, MatReuse reuse, Mat *B) 33063c07aadSStefano Zampini { 33163c07aadSStefano Zampini Mat_HYPRE *hB; 33263c07aadSStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 33363c07aadSStefano Zampini PetscErrorCode ierr; 33463c07aadSStefano Zampini 33563c07aadSStefano Zampini PetscFunctionBegin; 33663c07aadSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) SETERRQ(comm,PETSC_ERR_SUP,"Unsupported MAT_INPLACE_MATRIX"); 33763c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 33863c07aadSStefano Zampini /* always destroy the old matrix and create a new memory; 33963c07aadSStefano Zampini hope this does not churn the memory too much. The problem 34063c07aadSStefano Zampini is I do not know if it is possible to put the matrix back to 34163c07aadSStefano Zampini its initial state so that we can directly copy the values 34263c07aadSStefano Zampini the second time through. */ 34363c07aadSStefano Zampini hB = (Mat_HYPRE*)((*B)->data); 34463c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hB->ij)); 34563c07aadSStefano Zampini } else { 34663c07aadSStefano Zampini ierr = MatCreate(comm,B);CHKERRQ(ierr); 34763c07aadSStefano Zampini ierr = MatSetType(*B,MATHYPRE);CHKERRQ(ierr); 34863c07aadSStefano Zampini ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 34963c07aadSStefano Zampini ierr = MatSetUp(*B);CHKERRQ(ierr); 35063c07aadSStefano Zampini hB = (Mat_HYPRE*)((*B)->data); 35163c07aadSStefano Zampini } 35263c07aadSStefano Zampini ierr = MatHYPRE_CreateFromMat(A,hB);CHKERRQ(ierr); 35363c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,hB->ij);CHKERRQ(ierr); 35463c07aadSStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 35563c07aadSStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 35663c07aadSStefano Zampini PetscFunctionReturn(0); 35763c07aadSStefano Zampini } 35863c07aadSStefano Zampini 35963c07aadSStefano Zampini #undef __FUNCT__ 36063c07aadSStefano Zampini #define __FUNCT__ "MatConvert_HYPRE_AIJ" 361ea9daf28SStefano Zampini static PetscErrorCode MatConvert_HYPRE_AIJ(Mat A, MatType mtype, MatReuse reuse, Mat *B) 36263c07aadSStefano Zampini { 36363c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 36463c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 36563c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 36663c07aadSStefano Zampini MPI_Comm comm; 36763c07aadSStefano Zampini PetscScalar *da,*oa,*aptr; 36863c07aadSStefano Zampini PetscInt *dii,*djj,*oii,*ojj,*iptr; 36963c07aadSStefano Zampini PetscInt i,dnnz,onnz,m,n; 37063c07aadSStefano Zampini int type; 37163c07aadSStefano Zampini PetscMPIInt size; 37263c07aadSStefano Zampini PetscErrorCode ierr; 37363c07aadSStefano Zampini 37463c07aadSStefano Zampini PetscFunctionBegin; 37563c07aadSStefano Zampini comm = PetscObjectComm((PetscObject)A); 37663c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 37763c07aadSStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 37863c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 37963c07aadSStefano Zampini PetscBool ismpiaij,isseqaij; 38063c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 38163c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 38263c07aadSStefano Zampini if (!ismpiaij && !isseqaij) SETERRQ(comm,PETSC_ERR_SUP,"Only MATMPIAIJ or MATSEQAIJ are supported"); 38363c07aadSStefano Zampini } 38463c07aadSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 38563c07aadSStefano Zampini 38663c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 38763c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 38863c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 38963c07aadSStefano Zampini m = hypre_CSRMatrixNumRows(hdiag); 39063c07aadSStefano Zampini n = hypre_CSRMatrixNumCols(hdiag); 39163c07aadSStefano Zampini dnnz = hypre_CSRMatrixNumNonzeros(hdiag); 39263c07aadSStefano Zampini onnz = hypre_CSRMatrixNumNonzeros(hoffd); 39363c07aadSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 39463c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&dii);CHKERRQ(ierr); 39563c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&djj);CHKERRQ(ierr); 39663c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&da);CHKERRQ(ierr); 39763c07aadSStefano Zampini } else { 39863c07aadSStefano Zampini PetscInt nr; 39963c07aadSStefano Zampini PetscBool done; 40063c07aadSStefano Zampini if (size > 1) { 40163c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 40263c07aadSStefano Zampini 40363c07aadSStefano Zampini ierr = MatGetRowIJ(b->A,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 40463c07aadSStefano 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); 40563c07aadSStefano 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); 40663c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->A,&da);CHKERRQ(ierr); 40763c07aadSStefano Zampini } else { 40863c07aadSStefano Zampini ierr = MatGetRowIJ(*B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 40963c07aadSStefano Zampini if (nr != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows! %D != %D",nr,m); 41063c07aadSStefano 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); 41163c07aadSStefano Zampini ierr = MatSeqAIJGetArray(*B,&da);CHKERRQ(ierr); 41263c07aadSStefano Zampini } 41363c07aadSStefano Zampini } 41463c07aadSStefano Zampini ierr = PetscMemcpy(dii,hypre_CSRMatrixI(hdiag),(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 41563c07aadSStefano Zampini ierr = PetscMemcpy(djj,hypre_CSRMatrixJ(hdiag),dnnz*sizeof(PetscInt));CHKERRQ(ierr); 41663c07aadSStefano Zampini ierr = PetscMemcpy(da,hypre_CSRMatrixData(hdiag),dnnz*sizeof(PetscScalar));CHKERRQ(ierr); 41763c07aadSStefano Zampini iptr = djj; 41863c07aadSStefano Zampini aptr = da; 41963c07aadSStefano Zampini for (i=0; i<m; i++) { 42063c07aadSStefano Zampini PetscInt nc = dii[i+1]-dii[i]; 42163c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 42263c07aadSStefano Zampini iptr += nc; 42363c07aadSStefano Zampini aptr += nc; 42463c07aadSStefano Zampini } 42563c07aadSStefano Zampini if (size > 1) { 42663c07aadSStefano Zampini PetscInt *offdj,*coffd; 42763c07aadSStefano Zampini 42863c07aadSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 42963c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&oii);CHKERRQ(ierr); 43063c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&ojj);CHKERRQ(ierr); 43163c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&oa);CHKERRQ(ierr); 43263c07aadSStefano Zampini } else { 43363c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 43463c07aadSStefano Zampini PetscInt nr,hr = hypre_CSRMatrixNumRows(hoffd); 43563c07aadSStefano Zampini PetscBool done; 43663c07aadSStefano Zampini 43763c07aadSStefano Zampini ierr = MatGetRowIJ(b->B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&oii,(const PetscInt**)&ojj,&done);CHKERRQ(ierr); 43863c07aadSStefano 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); 43963c07aadSStefano 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); 44063c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->B,&oa);CHKERRQ(ierr); 44163c07aadSStefano Zampini } 44263c07aadSStefano Zampini ierr = PetscMemcpy(oii,hypre_CSRMatrixI(hoffd),(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 44363c07aadSStefano Zampini offdj = hypre_CSRMatrixJ(hoffd); 44463c07aadSStefano Zampini coffd = hypre_ParCSRMatrixColMapOffd(parcsr); 44563c07aadSStefano Zampini for (i=0; i<onnz; i++) ojj[i] = coffd[offdj[i]]; 44663c07aadSStefano Zampini ierr = PetscMemcpy(oa,hypre_CSRMatrixData(hoffd),onnz*sizeof(PetscScalar));CHKERRQ(ierr); 44763c07aadSStefano Zampini iptr = ojj; 44863c07aadSStefano Zampini aptr = oa; 44963c07aadSStefano Zampini for (i=0; i<m; i++) { 45063c07aadSStefano Zampini PetscInt nc = oii[i+1]-oii[i]; 45163c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 45263c07aadSStefano Zampini iptr += nc; 45363c07aadSStefano Zampini aptr += nc; 45463c07aadSStefano Zampini } 45563c07aadSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 45663c07aadSStefano Zampini Mat_MPIAIJ *b; 45763c07aadSStefano Zampini Mat_SeqAIJ *d,*o; 45863c07aadSStefano Zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii, 45963c07aadSStefano Zampini djj,da,oii,ojj,oa,B);CHKERRQ(ierr); 46063c07aadSStefano Zampini /* hack MPIAIJ */ 46163c07aadSStefano Zampini b = (Mat_MPIAIJ*)((*B)->data); 46263c07aadSStefano Zampini d = (Mat_SeqAIJ*)b->A->data; 46363c07aadSStefano Zampini o = (Mat_SeqAIJ*)b->B->data; 46463c07aadSStefano Zampini d->free_a = PETSC_TRUE; 46563c07aadSStefano Zampini d->free_ij = PETSC_TRUE; 46663c07aadSStefano Zampini o->free_a = PETSC_TRUE; 46763c07aadSStefano Zampini o->free_ij = PETSC_TRUE; 46863c07aadSStefano Zampini } 46963c07aadSStefano Zampini } else if (reuse != MAT_REUSE_MATRIX) { 47063c07aadSStefano Zampini Mat_SeqAIJ* b; 47163c07aadSStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,B);CHKERRQ(ierr); 47263c07aadSStefano Zampini /* hack SeqAIJ */ 47363c07aadSStefano Zampini b = (Mat_SeqAIJ*)((*B)->data); 47463c07aadSStefano Zampini b->free_a = PETSC_TRUE; 47563c07aadSStefano Zampini b->free_ij = PETSC_TRUE; 47663c07aadSStefano Zampini } 47763c07aadSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 47863c07aadSStefano Zampini ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); 47963c07aadSStefano Zampini } 48063c07aadSStefano Zampini PetscFunctionReturn(0); 48163c07aadSStefano Zampini } 48263c07aadSStefano Zampini 48363c07aadSStefano Zampini #undef __FUNCT__ 48463c07aadSStefano Zampini #define __FUNCT__ "MatMultTranspose_HYPRE" 485ea9daf28SStefano Zampini static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 48663c07aadSStefano Zampini { 48763c07aadSStefano Zampini PetscErrorCode ierr; 48863c07aadSStefano Zampini 48963c07aadSStefano Zampini PetscFunctionBegin; 49063c07aadSStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 49163c07aadSStefano Zampini PetscFunctionReturn(0); 49263c07aadSStefano Zampini } 49363c07aadSStefano Zampini 49463c07aadSStefano Zampini #undef __FUNCT__ 49563c07aadSStefano Zampini #define __FUNCT__ "MatMult_HYPRE" 496ea9daf28SStefano Zampini static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 49763c07aadSStefano Zampini { 49863c07aadSStefano Zampini PetscErrorCode ierr; 49963c07aadSStefano Zampini 50063c07aadSStefano Zampini PetscFunctionBegin; 50163c07aadSStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 50263c07aadSStefano Zampini PetscFunctionReturn(0); 50363c07aadSStefano Zampini } 50463c07aadSStefano Zampini 50563c07aadSStefano Zampini #undef __FUNCT__ 50663c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_MultKernel_Private" 507ea9daf28SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, Vec x, Vec y, PetscBool trans) 50863c07aadSStefano Zampini { 50963c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 51063c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 51163c07aadSStefano Zampini hypre_ParVector *hx,*hy; 51263c07aadSStefano Zampini PetscScalar *ax,*ay,*sax,*say; 51363c07aadSStefano Zampini PetscErrorCode ierr; 51463c07aadSStefano Zampini 51563c07aadSStefano Zampini PetscFunctionBegin; 51663c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 51763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->x,(void**)&hx)); 51863c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->b,(void**)&hy)); 51963c07aadSStefano Zampini ierr = VecGetArrayRead(x,(const PetscScalar**)&ax);CHKERRQ(ierr); 52063c07aadSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 52163c07aadSStefano Zampini if (trans) { 52263c07aadSStefano Zampini HYPREReplacePointer(hA->x,ay,say); 52363c07aadSStefano Zampini HYPREReplacePointer(hA->b,ax,sax); 52463c07aadSStefano Zampini hypre_ParCSRMatrixMatvecT(1.,parcsr,hy,0.,hx); 52563c07aadSStefano Zampini HYPREReplacePointer(hA->x,say,ay); 52663c07aadSStefano Zampini HYPREReplacePointer(hA->b,sax,ax); 52763c07aadSStefano Zampini } else { 52863c07aadSStefano Zampini HYPREReplacePointer(hA->x,ax,sax); 52963c07aadSStefano Zampini HYPREReplacePointer(hA->b,ay,say); 53063c07aadSStefano Zampini hypre_ParCSRMatrixMatvec(1.,parcsr,hx,0.,hy); 53163c07aadSStefano Zampini HYPREReplacePointer(hA->x,sax,ax); 53263c07aadSStefano Zampini HYPREReplacePointer(hA->b,say,ay); 53363c07aadSStefano Zampini } 53463c07aadSStefano Zampini ierr = VecRestoreArrayRead(x,(const PetscScalar**)&ax);CHKERRQ(ierr); 53563c07aadSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 53663c07aadSStefano Zampini PetscFunctionReturn(0); 53763c07aadSStefano Zampini } 53863c07aadSStefano Zampini 53963c07aadSStefano Zampini #undef __FUNCT__ 54063c07aadSStefano Zampini #define __FUNCT__ "MatDestroy_HYPRE" 541ea9daf28SStefano Zampini static PetscErrorCode MatDestroy_HYPRE(Mat A) 54263c07aadSStefano Zampini { 54363c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 54463c07aadSStefano Zampini PetscErrorCode ierr; 54563c07aadSStefano Zampini 54663c07aadSStefano Zampini PetscFunctionBegin; 54763c07aadSStefano Zampini if (hA->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(hA->x)); 54863c07aadSStefano Zampini if (hA->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(hA->b)); 549978814f1SStefano Zampini if (hA->ij) { 550978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 551978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hA->ij)); 552978814f1SStefano Zampini } 55363c07aadSStefano Zampini if (hA->comm) { ierr = MPI_Comm_free(&hA->comm);CHKERRQ(ierr); } 55463c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_aij_C",NULL);CHKERRQ(ierr); 5552df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_is_C",NULL);CHKERRQ(ierr); 55663c07aadSStefano Zampini ierr = PetscFree(A->data);CHKERRQ(ierr); 55763c07aadSStefano Zampini PetscFunctionReturn(0); 55863c07aadSStefano Zampini } 55963c07aadSStefano Zampini 56063c07aadSStefano Zampini #undef __FUNCT__ 56163c07aadSStefano Zampini #define __FUNCT__ "MatSetUp_HYPRE" 562ea9daf28SStefano Zampini static PetscErrorCode MatSetUp_HYPRE(Mat A) 56363c07aadSStefano Zampini { 56463c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 56563c07aadSStefano Zampini Vec x,b; 56663c07aadSStefano Zampini PetscErrorCode ierr; 56763c07aadSStefano Zampini 56863c07aadSStefano Zampini PetscFunctionBegin; 56963c07aadSStefano Zampini if (hA->x) PetscFunctionReturn(0); 57063c07aadSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 57163c07aadSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 57263c07aadSStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)A),1,A->cmap->n,A->cmap->N,NULL,&x);CHKERRQ(ierr); 57363c07aadSStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)A),1,A->rmap->n,A->rmap->N,NULL,&b);CHKERRQ(ierr); 57463c07aadSStefano Zampini ierr = VecHYPRE_IJVectorCreate(x,&hA->x);CHKERRQ(ierr); 57563c07aadSStefano Zampini ierr = VecHYPRE_IJVectorCreate(b,&hA->b);CHKERRQ(ierr); 57663c07aadSStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 57763c07aadSStefano Zampini ierr = VecDestroy(&b);CHKERRQ(ierr); 57863c07aadSStefano Zampini PetscFunctionReturn(0); 57963c07aadSStefano Zampini } 58063c07aadSStefano Zampini 58163c07aadSStefano Zampini #undef __FUNCT__ 58263c07aadSStefano Zampini #define __FUNCT__ "MatAssemblyEnd_HYPRE" 583ea9daf28SStefano Zampini static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 58463c07aadSStefano Zampini { 58563c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 58663c07aadSStefano Zampini PetscErrorCode ierr; 58763c07aadSStefano Zampini 58863c07aadSStefano Zampini PetscFunctionBegin; 58963c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixAssemble,(hA->ij)); 59063c07aadSStefano Zampini PetscFunctionReturn(0); 59163c07aadSStefano Zampini } 59263c07aadSStefano Zampini 593978814f1SStefano Zampini #undef __FUNCT__ 594978814f1SStefano Zampini #define __FUNCT__ "MatHYPRECreateFromParCSR" 595978814f1SStefano Zampini PETSC_EXTERN PetscErrorCode MatHYPRECreateFromParCSR(void *vparcsr, PetscCopyMode copymode, Mat* A) 596978814f1SStefano Zampini { 597978814f1SStefano Zampini Mat_HYPRE *hA; 59863c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 599978814f1SStefano Zampini MPI_Comm comm; 600978814f1SStefano Zampini PetscInt rstart,rend,cstart,cend,M,N; 601978814f1SStefano Zampini PetscErrorCode ierr; 602978814f1SStefano Zampini 603978814f1SStefano Zampini PetscFunctionBegin; 604978814f1SStefano Zampini parcsr = (hypre_ParCSRMatrix *)vparcsr; 605978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 606978814f1SStefano Zampini if (copymode == PETSC_COPY_VALUES) SETERRQ(comm,PETSC_ERR_SUP,"Unsupported copymode PETSC_COPY_VALUES"); 607978814f1SStefano Zampini 608978814f1SStefano Zampini /* access ParCSRMatrix */ 609978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 610978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 611978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 612978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 613978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 614978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 615978814f1SStefano Zampini 616978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 617978814f1SStefano Zampini ierr = MatCreate(comm,A);CHKERRQ(ierr); 618978814f1SStefano Zampini ierr = MatSetSizes(*A,rend-rstart+1,cend-cstart+1,M,N);CHKERRQ(ierr); 619978814f1SStefano Zampini ierr = MatSetType(*A,MATHYPRE);CHKERRQ(ierr); 620978814f1SStefano Zampini ierr = MatSetUp(*A);CHKERRQ(ierr); 621978814f1SStefano Zampini hA = (Mat_HYPRE*)((*A)->data); 622978814f1SStefano Zampini 623978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 624978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 625978814f1SStefano Zampini 626978814f1SStefano Zampini /* set ParCSR object */ 627978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 628978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 629978814f1SStefano Zampini 630978814f1SStefano Zampini /* set assembled flag */ 631978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 632978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 633978814f1SStefano Zampini 634978814f1SStefano Zampini /* prevent from freeing the pointer */ 635978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 636978814f1SStefano Zampini 637978814f1SStefano Zampini ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 638978814f1SStefano Zampini ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 639978814f1SStefano Zampini PetscFunctionReturn(0); 640978814f1SStefano Zampini } 641978814f1SStefano Zampini 64263c07aadSStefano Zampini #undef __FUNCT__ 64363c07aadSStefano Zampini #define __FUNCT__ "MatCreate_HYPRE" 64463c07aadSStefano Zampini PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 64563c07aadSStefano Zampini { 64663c07aadSStefano Zampini Mat_HYPRE *hB; 64763c07aadSStefano Zampini PetscErrorCode ierr; 64863c07aadSStefano Zampini 64963c07aadSStefano Zampini PetscFunctionBegin; 65063c07aadSStefano Zampini ierr = PetscNewLog(B,&hB);CHKERRQ(ierr); 651978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 652978814f1SStefano Zampini 65363c07aadSStefano Zampini B->data = (void*)hB; 65463c07aadSStefano Zampini B->rmap->bs = 1; 65563c07aadSStefano Zampini B->assembled = PETSC_FALSE; 65663c07aadSStefano Zampini 65763c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 65863c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 65963c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 66063c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 66163c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 66263c07aadSStefano Zampini 66363c07aadSStefano Zampini ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)B),&hB->comm);CHKERRQ(ierr); 66463c07aadSStefano Zampini ierr = PetscObjectChangeTypeName((PetscObject)B,MATHYPRE);CHKERRQ(ierr); 66563c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_aij_C",MatConvert_HYPRE_AIJ);CHKERRQ(ierr); 6662df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_is_C",MatConvert_HYPRE_IS);CHKERRQ(ierr); 66763c07aadSStefano Zampini PetscFunctionReturn(0); 66863c07aadSStefano Zampini } 66963c07aadSStefano Zampini 67063c07aadSStefano Zampini #if 0 67163c07aadSStefano Zampini /* 67263c07aadSStefano Zampini Does NOT copy the data over, instead uses DIRECTLY the pointers from the PETSc MPIAIJ format 67363c07aadSStefano Zampini 67463c07aadSStefano Zampini This is UNFINISHED and does NOT work! The problem is that hypre puts the diagonal entry first 67563c07aadSStefano Zampini which will corrupt the PETSc data structure if we did this. Need a work around to this problem. 67663c07aadSStefano Zampini */ 67763c07aadSStefano Zampini #include <_hypre_IJ_mv.h> 67863c07aadSStefano Zampini #include <HYPRE_IJ_mv.h> 67963c07aadSStefano Zampini 68063c07aadSStefano Zampini #undef __FUNCT__ 68163c07aadSStefano Zampini #define __FUNCT__ "MatHYPRE_IJMatrixLink" 68263c07aadSStefano Zampini PetscErrorCode MatHYPRE_IJMatrixLink(Mat A, HYPRE_IJMatrix *ij) 68363c07aadSStefano Zampini { 68463c07aadSStefano Zampini PetscErrorCode ierr; 68563c07aadSStefano Zampini PetscInt rstart,rend,cstart,cend; 68663c07aadSStefano Zampini PetscBool flg; 68763c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 68863c07aadSStefano Zampini 68963c07aadSStefano Zampini PetscFunctionBegin; 69063c07aadSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 69163c07aadSStefano Zampini PetscValidType(A,1); 69263c07aadSStefano Zampini PetscValidPointer(ij,2); 69363c07aadSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr); 69463c07aadSStefano Zampini if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Can only use with PETSc MPIAIJ matrices"); 69563c07aadSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 69663c07aadSStefano Zampini 69763c07aadSStefano Zampini ierr = PetscLogEventBegin(MAT_Convert,A,0,0,0);CHKERRQ(ierr); 69863c07aadSStefano Zampini rstart = A->rmap->rstart; 69963c07aadSStefano Zampini rend = A->rmap->rend; 70063c07aadSStefano Zampini cstart = A->cmap->rstart; 70163c07aadSStefano Zampini cend = A->cmap->rend; 70263c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(PetscObjectComm((PetscObject)A),rstart,rend-1,cstart,cend-1,ij)); 70363c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(*ij,HYPRE_PARCSR)); 70463c07aadSStefano Zampini 70563c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(*ij)); 70663c07aadSStefano Zampini PetscStackCall("hypre_IJMatrixTranslator",aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(*ij)); 70763c07aadSStefano Zampini 70863c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 70963c07aadSStefano Zampini 71063c07aadSStefano Zampini /* this is the Hack part where we monkey directly with the hypre datastructures */ 71163c07aadSStefano Zampini 71263c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixAssemble,(*ij)); 71363c07aadSStefano Zampini ierr = PetscLogEventEnd(MAT_Convert,A,0,0,0);CHKERRQ(ierr); 71463c07aadSStefano Zampini PetscFunctionReturn(0); 71563c07aadSStefano Zampini } 71663c07aadSStefano Zampini #endif 717