1f4bdf6c4SBarry Smith 2f4bdf6c4SBarry Smith /* 3f4bdf6c4SBarry Smith Creates hypre ijmatrix from PETSc matrix 4f4bdf6c4SBarry Smith */ 5c6db04a5SJed Brown #include <petscsys.h> 639accc25SStefano Zampini #include <petsc/private/petschypre.h> 7af0996ceSBarry Smith #include <petsc/private/matimpl.h> 8c6db04a5SJed Brown #include <petscdmda.h> /*I "petscdmda.h" I*/ 9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h> 10f4bdf6c4SBarry Smith 11f4bdf6c4SBarry Smith /* -----------------------------------------------------------------------------------------------------------------*/ 12f4bdf6c4SBarry Smith 13f4bdf6c4SBarry Smith /*MC 14f4bdf6c4SBarry Smith MATHYPRESTRUCT - MATHYPRESTRUCT = "hyprestruct" - A matrix type to be used for parallel sparse matrices 15f4bdf6c4SBarry Smith based on the hypre HYPRE_StructMatrix. 16f4bdf6c4SBarry Smith 17f4bdf6c4SBarry Smith Level: intermediate 18f4bdf6c4SBarry Smith 1995452b02SPatrick Sanan Notes: 2095452b02SPatrick Sanan Unlike the more general support for blocks in hypre this allows only one block per process and requires the block 21f4bdf6c4SBarry Smith be defined by a DMDA. 22f4bdf6c4SBarry Smith 2359cb773eSBarry Smith The matrix needs a DMDA associated with it by either a call to MatSetDM() or if the matrix is obtained from DMCreateMatrix() 24f4bdf6c4SBarry Smith 2559cb773eSBarry Smith .seealso: MatCreate(), PCPFMG, MatSetDM(), DMCreateMatrix() 26f4bdf6c4SBarry Smith M*/ 27f4bdf6c4SBarry Smith 28f4bdf6c4SBarry Smith PetscErrorCode MatSetValuesLocal_HYPREStruct_3d(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 29f4bdf6c4SBarry Smith { 302cf14000SStefano Zampini HYPRE_Int index[3],entries[7]; 312cf14000SStefano Zampini PetscInt i,j,stencil,row; 3239accc25SStefano Zampini HYPRE_Complex *values = (HYPRE_Complex*)y; 33f4bdf6c4SBarry Smith Mat_HYPREStruct *ex = (Mat_HYPREStruct*) mat->data; 34f4bdf6c4SBarry Smith 35f4bdf6c4SBarry Smith PetscFunctionBegin; 369ace16cdSJacob Faibussowitsch PetscAssertFalse(ncol > 7,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"ncol %D > 7 too large",ncol); 37f4bdf6c4SBarry Smith for (i=0; i<nrow; i++) { 38f4bdf6c4SBarry Smith for (j=0; j<ncol; j++) { 39f4bdf6c4SBarry Smith stencil = icol[j] - irow[i]; 40f4bdf6c4SBarry Smith if (!stencil) { 41f4bdf6c4SBarry Smith entries[j] = 3; 42f4bdf6c4SBarry Smith } else if (stencil == -1) { 43f4bdf6c4SBarry Smith entries[j] = 2; 44f4bdf6c4SBarry Smith } else if (stencil == 1) { 45f4bdf6c4SBarry Smith entries[j] = 4; 46f4bdf6c4SBarry Smith } else if (stencil == -ex->gnx) { 47f4bdf6c4SBarry Smith entries[j] = 1; 48f4bdf6c4SBarry Smith } else if (stencil == ex->gnx) { 49f4bdf6c4SBarry Smith entries[j] = 5; 50f4bdf6c4SBarry Smith } else if (stencil == -ex->gnxgny) { 51f4bdf6c4SBarry Smith entries[j] = 0; 52f4bdf6c4SBarry Smith } else if (stencil == ex->gnxgny) { 53f4bdf6c4SBarry Smith entries[j] = 6; 5498921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local row %D local column %D have bad stencil %D",irow[i],icol[j],stencil); 55f4bdf6c4SBarry Smith } 56f4bdf6c4SBarry Smith row = ex->gindices[irow[i]] - ex->rstart; 572cf14000SStefano Zampini index[0] = (HYPRE_Int)(ex->xs + (row % ex->nx)); 582cf14000SStefano Zampini index[1] = (HYPRE_Int)(ex->ys + ((row/ex->nx) % ex->ny)); 592cf14000SStefano Zampini index[2] = (HYPRE_Int)(ex->zs + (row/(ex->nxny))); 60f4bdf6c4SBarry Smith if (addv == ADD_VALUES) { 61*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixAddToValues,ex->hmat,index,ncol,entries,values); 62f4bdf6c4SBarry Smith } else { 63*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixSetValues,ex->hmat,index,ncol,entries,values); 64f4bdf6c4SBarry Smith } 65f4bdf6c4SBarry Smith values += ncol; 66f4bdf6c4SBarry Smith } 67f4bdf6c4SBarry Smith PetscFunctionReturn(0); 68f4bdf6c4SBarry Smith } 69f4bdf6c4SBarry Smith 70f4bdf6c4SBarry Smith PetscErrorCode MatZeroRowsLocal_HYPREStruct_3d(Mat mat,PetscInt nrow,const PetscInt irow[],PetscScalar d,Vec x,Vec b) 71f4bdf6c4SBarry Smith { 72f4bdf6c4SBarry Smith PetscErrorCode ierr; 732cf14000SStefano Zampini HYPRE_Int index[3],entries[7] = {0,1,2,3,4,5,6}; 742cf14000SStefano Zampini PetscInt row,i; 7539accc25SStefano Zampini HYPRE_Complex values[7]; 76f4bdf6c4SBarry Smith Mat_HYPREStruct *ex = (Mat_HYPREStruct*) mat->data; 77f4bdf6c4SBarry Smith 78f4bdf6c4SBarry Smith PetscFunctionBegin; 799ace16cdSJacob Faibussowitsch PetscAssertFalse(x && b,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No support"); 80580bdb30SBarry Smith ierr = PetscArrayzero(values,7);CHKERRQ(ierr); 8139accc25SStefano Zampini ierr = PetscHYPREScalarCast(d,&values[3]);CHKERRQ(ierr); 82f4bdf6c4SBarry Smith for (i=0; i<nrow; i++) { 83f4bdf6c4SBarry Smith row = ex->gindices[irow[i]] - ex->rstart; 842cf14000SStefano Zampini index[0] = (HYPRE_Int)(ex->xs + (row % ex->nx)); 852cf14000SStefano Zampini index[1] = (HYPRE_Int)(ex->ys + ((row/ex->nx) % ex->ny)); 862cf14000SStefano Zampini index[2] = (HYPRE_Int)(ex->zs + (row/(ex->nxny))); 87*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixSetValues,ex->hmat,index,7,entries,values); 88f4bdf6c4SBarry Smith } 89*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixAssemble,ex->hmat); 90f4bdf6c4SBarry Smith PetscFunctionReturn(0); 91f4bdf6c4SBarry Smith } 92f4bdf6c4SBarry Smith 93f4bdf6c4SBarry Smith PetscErrorCode MatZeroEntries_HYPREStruct_3d(Mat mat) 94f4bdf6c4SBarry Smith { 952cf14000SStefano Zampini HYPRE_Int indices[7] = {0,1,2,3,4,5,6}; 96f4bdf6c4SBarry Smith Mat_HYPREStruct *ex = (Mat_HYPREStruct*) mat->data; 97f4bdf6c4SBarry Smith 98f4bdf6c4SBarry Smith PetscFunctionBegin; 99f4bdf6c4SBarry Smith /* hypre has no public interface to do this */ 100*a74df02fSJacob Faibussowitsch PetscStackCallStandard(hypre_StructMatrixClearBoxValues,ex->hmat,&ex->hbox,7,indices,0,1); 101*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixAssemble,ex->hmat); 102f4bdf6c4SBarry Smith PetscFunctionReturn(0); 103f4bdf6c4SBarry Smith } 104f4bdf6c4SBarry Smith 10559cb773eSBarry Smith static PetscErrorCode MatSetUp_HYPREStruct(Mat mat) 106f4bdf6c4SBarry Smith { 107f4bdf6c4SBarry Smith PetscErrorCode ierr; 108f4bdf6c4SBarry Smith Mat_HYPREStruct *ex = (Mat_HYPREStruct*) mat->data; 1092cf14000SStefano Zampini HYPRE_Int sw[6]; 1102cf14000SStefano Zampini HYPRE_Int hlower[3],hupper[3]; 1112cf14000SStefano Zampini PetscInt dim,dof,psw,nx,ny,nz,ilower[3],iupper[3],ssize,i; 112bff4a2f0SMatthew G. Knepley DMBoundaryType px,py,pz; 113f4bdf6c4SBarry Smith DMDAStencilType st; 114565245c5SBarry Smith ISLocalToGlobalMapping ltog; 11559cb773eSBarry Smith DM da; 116f4bdf6c4SBarry Smith 117f4bdf6c4SBarry Smith PetscFunctionBegin; 11859cb773eSBarry Smith ierr = MatGetDM(mat,(DM*)&da);CHKERRQ(ierr); 119f4bdf6c4SBarry Smith ex->da = da; 120f4bdf6c4SBarry Smith ierr = PetscObjectReference((PetscObject)da);CHKERRQ(ierr); 121f4bdf6c4SBarry Smith 1222cf14000SStefano Zampini ierr = DMDAGetInfo(ex->da,&dim,0,0,0,0,0,0,&dof,&psw,&px,&py,&pz,&st);CHKERRQ(ierr); 123f4bdf6c4SBarry Smith ierr = DMDAGetCorners(ex->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1242cf14000SStefano Zampini 1252cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 126f4bdf6c4SBarry Smith iupper[0] += ilower[0] - 1; 127f4bdf6c4SBarry Smith iupper[1] += ilower[1] - 1; 128f4bdf6c4SBarry Smith iupper[2] += ilower[2] - 1; 1292cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 1302cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 1312cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 1322cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 1332cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 1342cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 135f4bdf6c4SBarry Smith 136f4bdf6c4SBarry Smith /* the hypre_Box is used to zero out the matrix entries in MatZeroValues() */ 1372cf14000SStefano Zampini ex->hbox.imin[0] = hlower[0]; 1382cf14000SStefano Zampini ex->hbox.imin[1] = hlower[1]; 1392cf14000SStefano Zampini ex->hbox.imin[2] = hlower[2]; 1402cf14000SStefano Zampini ex->hbox.imax[0] = hupper[0]; 1412cf14000SStefano Zampini ex->hbox.imax[1] = hupper[1]; 1422cf14000SStefano Zampini ex->hbox.imax[2] = hupper[2]; 143f4bdf6c4SBarry Smith 144f4bdf6c4SBarry Smith /* create the hypre grid object and set its information */ 1459ace16cdSJacob Faibussowitsch PetscAssertFalse(dof > 1,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Currently only support for scalar problems"); 1469ace16cdSJacob Faibussowitsch PetscAssertFalse(px || py || pz,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Ask us to add periodic support by calling HYPRE_StructGridSetPeriodic()"); 147*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructGridCreate,ex->hcomm,dim,&ex->hgrid); 148*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructGridSetExtents,ex->hgrid,hlower,hupper); 149*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructGridAssemble,ex->hgrid); 150f4bdf6c4SBarry Smith 1512cf14000SStefano Zampini sw[5] = sw[4] = sw[3] = sw[2] = sw[1] = sw[0] = psw; 152*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructGridSetNumGhost,ex->hgrid,sw); 153f4bdf6c4SBarry Smith 154f4bdf6c4SBarry Smith /* create the hypre stencil object and set its information */ 1559ace16cdSJacob Faibussowitsch PetscAssertFalse(sw[0] > 1,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Ask us to add support for wider stencils"); 1569ace16cdSJacob Faibussowitsch PetscAssertFalse(st == DMDA_STENCIL_BOX,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Ask us to add support for box stencils"); 157f4bdf6c4SBarry Smith if (dim == 1) { 1582cf14000SStefano Zampini HYPRE_Int offsets[3][1] = {{-1},{0},{1}}; 159f4bdf6c4SBarry Smith ssize = 3; 160*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructStencilCreate,dim,ssize,&ex->hstencil); 161f4bdf6c4SBarry Smith for (i=0; i<ssize; i++) { 162*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructStencilSetElement,ex->hstencil,i,offsets[i]); 163f4bdf6c4SBarry Smith } 164f4bdf6c4SBarry Smith } else if (dim == 2) { 1652cf14000SStefano Zampini HYPRE_Int offsets[5][2] = {{0,-1},{-1,0},{0,0},{1,0},{0,1}}; 166f4bdf6c4SBarry Smith ssize = 5; 167*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructStencilCreate,dim,ssize,&ex->hstencil); 168f4bdf6c4SBarry Smith for (i=0; i<ssize; i++) { 169*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructStencilSetElement,ex->hstencil,i,offsets[i]); 170f4bdf6c4SBarry Smith } 171f4bdf6c4SBarry Smith } else if (dim == 3) { 1722cf14000SStefano Zampini HYPRE_Int offsets[7][3] = {{0,0,-1},{0,-1,0},{-1,0,0},{0,0,0},{1,0,0},{0,1,0},{0,0,1}}; 173f4bdf6c4SBarry Smith ssize = 7; 174*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructStencilCreate,dim,ssize,&ex->hstencil); 175f4bdf6c4SBarry Smith for (i=0; i<ssize; i++) { 176*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructStencilSetElement,ex->hstencil,i,offsets[i]); 177f4bdf6c4SBarry Smith } 178f4bdf6c4SBarry Smith } 179f4bdf6c4SBarry Smith 180f4bdf6c4SBarry Smith /* create the HYPRE vector for rhs and solution */ 181*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorCreate,ex->hcomm,ex->hgrid,&ex->hb); 182*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorCreate,ex->hcomm,ex->hgrid,&ex->hx); 183*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorInitialize,ex->hb); 184*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorInitialize,ex->hx); 185*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorAssemble,ex->hb); 186*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorAssemble,ex->hx); 187f4bdf6c4SBarry Smith 188f4bdf6c4SBarry Smith /* create the hypre matrix object and set its information */ 189*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixCreate,ex->hcomm,ex->hgrid,ex->hstencil,&ex->hmat); 190*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructGridDestroy,ex->hgrid); 191*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructStencilDestroy,ex->hstencil); 192f4bdf6c4SBarry Smith if (ex->needsinitialization) { 193*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixInitialize,ex->hmat); 194f4bdf6c4SBarry Smith ex->needsinitialization = PETSC_FALSE; 195f4bdf6c4SBarry Smith } 196f4bdf6c4SBarry Smith 197f4bdf6c4SBarry Smith /* set the global and local sizes of the matrix */ 198f4bdf6c4SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&nx,&ny,&nz);CHKERRQ(ierr); 199f4bdf6c4SBarry Smith ierr = MatSetSizes(mat,dof*nx*ny*nz,dof*nx*ny*nz,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 200f4bdf6c4SBarry Smith ierr = PetscLayoutSetBlockSize(mat->rmap,1);CHKERRQ(ierr); 201f4bdf6c4SBarry Smith ierr = PetscLayoutSetBlockSize(mat->cmap,1);CHKERRQ(ierr); 202f4bdf6c4SBarry Smith ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 203f4bdf6c4SBarry Smith ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 20459cb773eSBarry Smith mat->preallocated = PETSC_TRUE; 205f4bdf6c4SBarry Smith 206f4bdf6c4SBarry Smith if (dim == 3) { 207f4bdf6c4SBarry Smith mat->ops->setvalueslocal = MatSetValuesLocal_HYPREStruct_3d; 208f4bdf6c4SBarry Smith mat->ops->zerorowslocal = MatZeroRowsLocal_HYPREStruct_3d; 209f4bdf6c4SBarry Smith mat->ops->zeroentries = MatZeroEntries_HYPREStruct_3d; 2108865f1eaSKarl Rupp 21159cb773eSBarry Smith /* ierr = MatZeroEntries_HYPREStruct_3d(mat);CHKERRQ(ierr); */ 212ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Only support for 3d DMDA currently"); 213f4bdf6c4SBarry Smith 214f4bdf6c4SBarry Smith /* get values that will be used repeatedly in MatSetValuesLocal() and MatZeroRowsLocal() repeatedly */ 2150298fd71SBarry Smith ierr = MatGetOwnershipRange(mat,&ex->rstart,NULL);CHKERRQ(ierr); 216565245c5SBarry Smith ierr = DMGetLocalToGlobalMapping(ex->da,<og);CHKERRQ(ierr); 217565245c5SBarry Smith ierr = ISLocalToGlobalMappingGetIndices(ltog, (const PetscInt **) &ex->gindices);CHKERRQ(ierr); 218f4bdf6c4SBarry Smith ierr = DMDAGetGhostCorners(ex->da,0,0,0,&ex->gnx,&ex->gnxgny,0);CHKERRQ(ierr); 219f4bdf6c4SBarry Smith ex->gnxgny *= ex->gnx; 220f4bdf6c4SBarry Smith ierr = DMDAGetCorners(ex->da,&ex->xs,&ex->ys,&ex->zs,&ex->nx,&ex->ny,0);CHKERRQ(ierr); 221f4bdf6c4SBarry Smith ex->nxny = ex->nx*ex->ny; 222f4bdf6c4SBarry Smith PetscFunctionReturn(0); 223f4bdf6c4SBarry Smith } 224f4bdf6c4SBarry Smith 225f4bdf6c4SBarry Smith PetscErrorCode MatMult_HYPREStruct(Mat A,Vec x,Vec y) 226f4bdf6c4SBarry Smith { 227f4bdf6c4SBarry Smith PetscErrorCode ierr; 228b026d285SBarry Smith const PetscScalar *xx; 229b026d285SBarry Smith PetscScalar *yy; 2304ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 2312cf14000SStefano Zampini HYPRE_Int hlower[3],hupper[3]; 232f4bdf6c4SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(A->data); 233f4bdf6c4SBarry Smith 234f4bdf6c4SBarry Smith PetscFunctionBegin; 235f4bdf6c4SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 2362cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 237f4bdf6c4SBarry Smith iupper[0] += ilower[0] - 1; 238f4bdf6c4SBarry Smith iupper[1] += ilower[1] - 1; 239f4bdf6c4SBarry Smith iupper[2] += ilower[2] - 1; 2402cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 2412cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 2422cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 2432cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 2442cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 2452cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 246f4bdf6c4SBarry Smith 247f4bdf6c4SBarry Smith /* copy x values over to hypre */ 248*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,mx->hb,0.0); 249b026d285SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 250*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,mx->hb,hlower,hupper,(HYPRE_Complex*)xx); 251b026d285SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 252*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorAssemble,mx->hb); 253*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixMatvec,1.0,mx->hmat,mx->hb,0.0,mx->hx); 254f4bdf6c4SBarry Smith 255f4bdf6c4SBarry Smith /* copy solution values back to PETSc */ 256f4bdf6c4SBarry Smith ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 257*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,mx->hx,hlower,hupper,(HYPRE_Complex*)yy); 258f4bdf6c4SBarry Smith ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 259f4bdf6c4SBarry Smith PetscFunctionReturn(0); 260f4bdf6c4SBarry Smith } 261f4bdf6c4SBarry Smith 262f4bdf6c4SBarry Smith PetscErrorCode MatAssemblyEnd_HYPREStruct(Mat mat,MatAssemblyType mode) 263f4bdf6c4SBarry Smith { 264f4bdf6c4SBarry Smith Mat_HYPREStruct *ex = (Mat_HYPREStruct*) mat->data; 265f4bdf6c4SBarry Smith 266f4bdf6c4SBarry Smith PetscFunctionBegin; 267*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixAssemble,ex->hmat); 268*a74df02fSJacob Faibussowitsch /* PetscStackCallStandard(HYPRE_StructMatrixPrint,"dummy",ex->hmat,0); */ 269f4bdf6c4SBarry Smith PetscFunctionReturn(0); 270f4bdf6c4SBarry Smith } 271f4bdf6c4SBarry Smith 272f4bdf6c4SBarry Smith PetscErrorCode MatZeroEntries_HYPREStruct(Mat mat) 273f4bdf6c4SBarry Smith { 274f4bdf6c4SBarry Smith PetscFunctionBegin; 275f4bdf6c4SBarry Smith /* before the DMDA is set to the matrix the zero doesn't need to do anything */ 276f4bdf6c4SBarry Smith PetscFunctionReturn(0); 277f4bdf6c4SBarry Smith } 278f4bdf6c4SBarry Smith 279f4bdf6c4SBarry Smith PetscErrorCode MatDestroy_HYPREStruct(Mat mat) 280f4bdf6c4SBarry Smith { 281f4bdf6c4SBarry Smith Mat_HYPREStruct *ex = (Mat_HYPREStruct*) mat->data; 282f4bdf6c4SBarry Smith PetscErrorCode ierr; 283f4bdf6c4SBarry Smith 284f4bdf6c4SBarry Smith PetscFunctionBegin; 285*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructMatrixDestroy,ex->hmat); 286*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorDestroy,ex->hx); 287*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_StructVectorDestroy,ex->hb); 28859cb773eSBarry Smith ierr = PetscObjectDereference((PetscObject)ex->da);CHKERRQ(ierr); 289ffc4695bSBarry Smith ierr = MPI_Comm_free(&(ex->hcomm));CHKERRMPI(ierr); 29059cb773eSBarry Smith ierr = PetscFree(ex);CHKERRQ(ierr); 291f4bdf6c4SBarry Smith PetscFunctionReturn(0); 292f4bdf6c4SBarry Smith } 293f4bdf6c4SBarry Smith 2948cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_HYPREStruct(Mat B) 295f4bdf6c4SBarry Smith { 296f4bdf6c4SBarry Smith Mat_HYPREStruct *ex; 297f4bdf6c4SBarry Smith PetscErrorCode ierr; 298f4bdf6c4SBarry Smith 299f4bdf6c4SBarry Smith PetscFunctionBegin; 300b00a9115SJed Brown ierr = PetscNewLog(B,&ex);CHKERRQ(ierr); 301f4bdf6c4SBarry Smith B->data = (void*)ex; 302f4bdf6c4SBarry Smith B->rmap->bs = 1; 303f4bdf6c4SBarry Smith B->assembled = PETSC_FALSE; 304f4bdf6c4SBarry Smith 305f4bdf6c4SBarry Smith B->insertmode = NOT_SET_VALUES; 306f4bdf6c4SBarry Smith 307f4bdf6c4SBarry Smith B->ops->assemblyend = MatAssemblyEnd_HYPREStruct; 308f4bdf6c4SBarry Smith B->ops->mult = MatMult_HYPREStruct; 309f4bdf6c4SBarry Smith B->ops->zeroentries = MatZeroEntries_HYPREStruct; 310f4bdf6c4SBarry Smith B->ops->destroy = MatDestroy_HYPREStruct; 31159cb773eSBarry Smith B->ops->setup = MatSetUp_HYPREStruct; 312f4bdf6c4SBarry Smith 313f4bdf6c4SBarry Smith ex->needsinitialization = PETSC_TRUE; 314f4bdf6c4SBarry Smith 315ffc4695bSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)B),&(ex->hcomm));CHKERRMPI(ierr); 316f4bdf6c4SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATHYPRESTRUCT);CHKERRQ(ierr); 317f4bdf6c4SBarry Smith PetscFunctionReturn(0); 318f4bdf6c4SBarry Smith } 319f4bdf6c4SBarry Smith 320f4bdf6c4SBarry Smith /*MC 321f4bdf6c4SBarry Smith MATHYPRESSTRUCT - MATHYPRESSTRUCT = "hypresstruct" - A matrix type to be used for parallel sparse matrices 322f4bdf6c4SBarry Smith based on the hypre HYPRE_SStructMatrix. 323f4bdf6c4SBarry Smith 324f4bdf6c4SBarry Smith Level: intermediate 325f4bdf6c4SBarry Smith 32695452b02SPatrick Sanan Notes: 32795452b02SPatrick Sanan Unlike hypre's general semi-struct object consisting of a collection of structured-grid objects and unstructured 328b026d285SBarry Smith grid objects, we restrict the semi-struct objects to consist of only structured-grid components. 329f4bdf6c4SBarry Smith 330f4bdf6c4SBarry Smith Unlike the more general support for parts and blocks in hypre this allows only one part, and one block per process and requires the block 331f4bdf6c4SBarry Smith be defined by a DMDA. 332f4bdf6c4SBarry Smith 33359cb773eSBarry Smith The matrix needs a DMDA associated with it by either a call to MatSetDM() or if the matrix is obtained from DMCreateMatrix() 334f4bdf6c4SBarry Smith 335f4bdf6c4SBarry Smith M*/ 336f4bdf6c4SBarry Smith 337f4bdf6c4SBarry Smith PetscErrorCode MatSetValuesLocal_HYPRESStruct_3d(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 338f4bdf6c4SBarry Smith { 339f4bdf6c4SBarry Smith PetscErrorCode ierr; 3402cf14000SStefano Zampini HYPRE_Int index[3],*entries; 3412cf14000SStefano Zampini PetscInt i,j,stencil; 34239accc25SStefano Zampini HYPRE_Complex *values = (HYPRE_Complex*)y; 343f4bdf6c4SBarry Smith Mat_HYPRESStruct *ex = (Mat_HYPRESStruct*) mat->data; 344f4bdf6c4SBarry Smith 3454ddd07fcSJed Brown PetscInt part = 0; /* Petsc sstruct interface only allows 1 part */ 3464ddd07fcSJed Brown PetscInt ordering; 3474ddd07fcSJed Brown PetscInt grid_rank, to_grid_rank; 3484ddd07fcSJed Brown PetscInt var_type, to_var_type; 3494ddd07fcSJed Brown PetscInt to_var_entry = 0; 3504ddd07fcSJed Brown PetscInt nvars= ex->nvars; 3512cf14000SStefano Zampini PetscInt row; 352f4bdf6c4SBarry Smith 353f4bdf6c4SBarry Smith PetscFunctionBegin; 354785e854fSJed Brown ierr = PetscMalloc1(7*nvars,&entries);CHKERRQ(ierr); 355f4bdf6c4SBarry Smith ordering = ex->dofs_order; /* ordering= 0 nodal ordering 356f4bdf6c4SBarry Smith 1 variable ordering */ 35761710fbeSStefano Zampini /* stencil entries are ordered by variables: var0_stencil0, var0_stencil1, ..., var0_stencil6, var1_stencil0, var1_stencil1, ... */ 358f4bdf6c4SBarry Smith if (!ordering) { 359f4bdf6c4SBarry Smith for (i=0; i<nrow; i++) { 360f4bdf6c4SBarry Smith grid_rank= irow[i]/nvars; 361f4bdf6c4SBarry Smith var_type = (irow[i] % nvars); 362f4bdf6c4SBarry Smith 363f4bdf6c4SBarry Smith for (j=0; j<ncol; j++) { 364f4bdf6c4SBarry Smith to_grid_rank= icol[j]/nvars; 365f4bdf6c4SBarry Smith to_var_type = (icol[j] % nvars); 366f4bdf6c4SBarry Smith 367f4bdf6c4SBarry Smith to_var_entry= to_var_entry*7; 368f4bdf6c4SBarry Smith entries[j] = to_var_entry; 369f4bdf6c4SBarry Smith 370f4bdf6c4SBarry Smith stencil = to_grid_rank-grid_rank; 371f4bdf6c4SBarry Smith if (!stencil) { 372f4bdf6c4SBarry Smith entries[j] += 3; 373f4bdf6c4SBarry Smith } else if (stencil == -1) { 374f4bdf6c4SBarry Smith entries[j] += 2; 375f4bdf6c4SBarry Smith } else if (stencil == 1) { 376f4bdf6c4SBarry Smith entries[j] += 4; 377f4bdf6c4SBarry Smith } else if (stencil == -ex->gnx) { 378f4bdf6c4SBarry Smith entries[j] += 1; 379f4bdf6c4SBarry Smith } else if (stencil == ex->gnx) { 380f4bdf6c4SBarry Smith entries[j] += 5; 381f4bdf6c4SBarry Smith } else if (stencil == -ex->gnxgny) { 382f4bdf6c4SBarry Smith entries[j] += 0; 383f4bdf6c4SBarry Smith } else if (stencil == ex->gnxgny) { 384f4bdf6c4SBarry Smith entries[j] += 6; 38598921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local row %D local column %D have bad stencil %D",irow[i],icol[j],stencil); 386f4bdf6c4SBarry Smith } 387f4bdf6c4SBarry Smith 388f4bdf6c4SBarry Smith row = ex->gindices[grid_rank] - ex->rstart; 3892cf14000SStefano Zampini index[0] = (HYPRE_Int)(ex->xs + (row % ex->nx)); 3902cf14000SStefano Zampini index[1] = (HYPRE_Int)(ex->ys + ((row/ex->nx) % ex->ny)); 3912cf14000SStefano Zampini index[2] = (HYPRE_Int)(ex->zs + (row/(ex->nxny))); 392f4bdf6c4SBarry Smith 393f4bdf6c4SBarry Smith if (addv == ADD_VALUES) { 394*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixAddToValues,ex->ss_mat,part,index,var_type,ncol,entries,values); 395f4bdf6c4SBarry Smith } else { 396*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixSetValues,ex->ss_mat,part,index,var_type,ncol,entries,values); 397f4bdf6c4SBarry Smith } 398f4bdf6c4SBarry Smith values += ncol; 399f4bdf6c4SBarry Smith } 400f4bdf6c4SBarry Smith } else { 401f4bdf6c4SBarry Smith for (i=0; i<nrow; i++) { 402f4bdf6c4SBarry Smith var_type = irow[i]/(ex->gnxgnygnz); 403f4bdf6c4SBarry Smith grid_rank= irow[i] - var_type*(ex->gnxgnygnz); 404f4bdf6c4SBarry Smith 405f4bdf6c4SBarry Smith for (j=0; j<ncol; j++) { 406f4bdf6c4SBarry Smith to_var_type = icol[j]/(ex->gnxgnygnz); 407f4bdf6c4SBarry Smith to_grid_rank= icol[j] - to_var_type*(ex->gnxgnygnz); 408f4bdf6c4SBarry Smith 409f4bdf6c4SBarry Smith to_var_entry= to_var_entry*7; 410f4bdf6c4SBarry Smith entries[j] = to_var_entry; 411f4bdf6c4SBarry Smith 412f4bdf6c4SBarry Smith stencil = to_grid_rank-grid_rank; 413f4bdf6c4SBarry Smith if (!stencil) { 414f4bdf6c4SBarry Smith entries[j] += 3; 415f4bdf6c4SBarry Smith } else if (stencil == -1) { 416f4bdf6c4SBarry Smith entries[j] += 2; 417f4bdf6c4SBarry Smith } else if (stencil == 1) { 418f4bdf6c4SBarry Smith entries[j] += 4; 419f4bdf6c4SBarry Smith } else if (stencil == -ex->gnx) { 420f4bdf6c4SBarry Smith entries[j] += 1; 421f4bdf6c4SBarry Smith } else if (stencil == ex->gnx) { 422f4bdf6c4SBarry Smith entries[j] += 5; 423f4bdf6c4SBarry Smith } else if (stencil == -ex->gnxgny) { 424f4bdf6c4SBarry Smith entries[j] += 0; 425f4bdf6c4SBarry Smith } else if (stencil == ex->gnxgny) { 426f4bdf6c4SBarry Smith entries[j] += 6; 42798921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local row %D local column %D have bad stencil %D",irow[i],icol[j],stencil); 428f4bdf6c4SBarry Smith } 429f4bdf6c4SBarry Smith 430f4bdf6c4SBarry Smith row = ex->gindices[grid_rank] - ex->rstart; 4312cf14000SStefano Zampini index[0] = (HYPRE_Int)(ex->xs + (row % ex->nx)); 4322cf14000SStefano Zampini index[1] = (HYPRE_Int)(ex->ys + ((row/ex->nx) % ex->ny)); 4332cf14000SStefano Zampini index[2] = (HYPRE_Int)(ex->zs + (row/(ex->nxny))); 434f4bdf6c4SBarry Smith 435f4bdf6c4SBarry Smith if (addv == ADD_VALUES) { 436*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixAddToValues,ex->ss_mat,part,index,var_type,ncol,entries,values); 437f4bdf6c4SBarry Smith } else { 438*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixSetValues,ex->ss_mat,part,index,var_type,ncol,entries,values); 439f4bdf6c4SBarry Smith } 440f4bdf6c4SBarry Smith values += ncol; 441f4bdf6c4SBarry Smith } 442f4bdf6c4SBarry Smith } 443f4bdf6c4SBarry Smith ierr = PetscFree(entries);CHKERRQ(ierr); 444f4bdf6c4SBarry Smith PetscFunctionReturn(0); 445f4bdf6c4SBarry Smith } 446f4bdf6c4SBarry Smith 447f4bdf6c4SBarry Smith PetscErrorCode MatZeroRowsLocal_HYPRESStruct_3d(Mat mat,PetscInt nrow,const PetscInt irow[],PetscScalar d,Vec x,Vec b) 448f4bdf6c4SBarry Smith { 449f4bdf6c4SBarry Smith PetscErrorCode ierr; 4502cf14000SStefano Zampini HYPRE_Int index[3],*entries; 4512cf14000SStefano Zampini PetscInt i; 45239accc25SStefano Zampini HYPRE_Complex **values; 453f4bdf6c4SBarry Smith Mat_HYPRESStruct *ex = (Mat_HYPRESStruct*) mat->data; 454f4bdf6c4SBarry Smith 4554ddd07fcSJed Brown PetscInt part = 0; /* Petsc sstruct interface only allows 1 part */ 4564ddd07fcSJed Brown PetscInt ordering = ex->dofs_order; 4574ddd07fcSJed Brown PetscInt grid_rank; 4584ddd07fcSJed Brown PetscInt var_type; 4594ddd07fcSJed Brown PetscInt nvars= ex->nvars; 4602cf14000SStefano Zampini PetscInt row; 461f4bdf6c4SBarry Smith 462f4bdf6c4SBarry Smith PetscFunctionBegin; 4639ace16cdSJacob Faibussowitsch PetscAssertFalse(x && b,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No support"); 464785e854fSJed Brown ierr = PetscMalloc1(7*nvars,&entries);CHKERRQ(ierr); 465f4bdf6c4SBarry Smith 466785e854fSJed Brown ierr = PetscMalloc1(nvars,&values);CHKERRQ(ierr); 467785e854fSJed Brown ierr = PetscMalloc1(7*nvars*nvars,&values[0]);CHKERRQ(ierr); 468f4bdf6c4SBarry Smith for (i=1; i<nvars; i++) { 469f4bdf6c4SBarry Smith values[i] = values[i-1] + nvars*7; 470f4bdf6c4SBarry Smith } 471f4bdf6c4SBarry Smith 472f4bdf6c4SBarry Smith for (i=0; i< nvars; i++) { 473580bdb30SBarry Smith ierr = PetscArrayzero(values[i],nvars*7*sizeof(HYPRE_Complex));CHKERRQ(ierr); 47439accc25SStefano Zampini ierr = PetscHYPREScalarCast(d,values[i]+3);CHKERRQ(ierr); 475f4bdf6c4SBarry Smith } 476f4bdf6c4SBarry Smith 4778865f1eaSKarl Rupp for (i=0; i< nvars*7; i++) entries[i] = i; 478f4bdf6c4SBarry Smith 479f4bdf6c4SBarry Smith if (!ordering) { 480f4bdf6c4SBarry Smith for (i=0; i<nrow; i++) { 481f4bdf6c4SBarry Smith grid_rank = irow[i] / nvars; 482f4bdf6c4SBarry Smith var_type = (irow[i] % nvars); 483f4bdf6c4SBarry Smith 484f4bdf6c4SBarry Smith row = ex->gindices[grid_rank] - ex->rstart; 4852cf14000SStefano Zampini index[0] = (HYPRE_Int)(ex->xs + (row % ex->nx)); 4862cf14000SStefano Zampini index[1] = (HYPRE_Int)(ex->ys + ((row/ex->nx) % ex->ny)); 4872cf14000SStefano Zampini index[2] = (HYPRE_Int)(ex->zs + (row/(ex->nxny))); 488*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixSetValues,ex->ss_mat,part,index,var_type,7*nvars,entries,values[var_type]); 489f4bdf6c4SBarry Smith } 490f4bdf6c4SBarry Smith } else { 491f4bdf6c4SBarry Smith for (i=0; i<nrow; i++) { 492f4bdf6c4SBarry Smith var_type = irow[i]/(ex->gnxgnygnz); 493f4bdf6c4SBarry Smith grid_rank= irow[i] - var_type*(ex->gnxgnygnz); 494f4bdf6c4SBarry Smith 495f4bdf6c4SBarry Smith row = ex->gindices[grid_rank] - ex->rstart; 4962cf14000SStefano Zampini index[0] = (HYPRE_Int)(ex->xs + (row % ex->nx)); 4972cf14000SStefano Zampini index[1] = (HYPRE_Int)(ex->ys + ((row/ex->nx) % ex->ny)); 4982cf14000SStefano Zampini index[2] = (HYPRE_Int)(ex->zs + (row/(ex->nxny))); 499*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixSetValues,ex->ss_mat,part,index,var_type,7*nvars,entries,values[var_type]); 500f4bdf6c4SBarry Smith } 501f4bdf6c4SBarry Smith } 502*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixAssemble,ex->ss_mat); 503f4bdf6c4SBarry Smith ierr = PetscFree(values[0]);CHKERRQ(ierr); 504f4bdf6c4SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 505f4bdf6c4SBarry Smith ierr = PetscFree(entries);CHKERRQ(ierr); 506f4bdf6c4SBarry Smith PetscFunctionReturn(0); 507f4bdf6c4SBarry Smith } 508f4bdf6c4SBarry Smith 509f4bdf6c4SBarry Smith PetscErrorCode MatZeroEntries_HYPRESStruct_3d(Mat mat) 510f4bdf6c4SBarry Smith { 511f4bdf6c4SBarry Smith PetscErrorCode ierr; 512f4bdf6c4SBarry Smith Mat_HYPRESStruct *ex = (Mat_HYPRESStruct*) mat->data; 5134ddd07fcSJed Brown PetscInt nvars= ex->nvars; 5144ddd07fcSJed Brown PetscInt size; 5154ddd07fcSJed Brown PetscInt part= 0; /* only one part */ 516f4bdf6c4SBarry Smith 517f4bdf6c4SBarry Smith PetscFunctionBegin; 518f4bdf6c4SBarry Smith size = ((ex->hbox.imax[0])-(ex->hbox.imin[0])+1)*((ex->hbox.imax[1])-(ex->hbox.imin[1])+1)*((ex->hbox.imax[2])-(ex->hbox.imin[2])+1); 519f4bdf6c4SBarry Smith { 5202cf14000SStefano Zampini HYPRE_Int i,*entries,iupper[3],ilower[3]; 52139accc25SStefano Zampini HYPRE_Complex *values; 5224ddd07fcSJed Brown 523f4bdf6c4SBarry Smith for (i= 0; i< 3; i++) { 524f4bdf6c4SBarry Smith ilower[i] = ex->hbox.imin[i]; 525f4bdf6c4SBarry Smith iupper[i] = ex->hbox.imax[i]; 526f4bdf6c4SBarry Smith } 527f4bdf6c4SBarry Smith 528dcca6d9dSJed Brown ierr = PetscMalloc2(nvars*7,&entries,nvars*7*size,&values);CHKERRQ(ierr); 5298865f1eaSKarl Rupp for (i= 0; i< nvars*7; i++) entries[i] = i; 530580bdb30SBarry Smith ierr = PetscArrayzero(values,nvars*7*size);CHKERRQ(ierr); 531f4bdf6c4SBarry Smith 532f4bdf6c4SBarry Smith for (i= 0; i< nvars; i++) { 533*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixSetBoxValues,ex->ss_mat,part,ilower,iupper,i,nvars*7,entries,values); 534f4bdf6c4SBarry Smith } 535f4bdf6c4SBarry Smith ierr = PetscFree2(entries,values);CHKERRQ(ierr); 536f4bdf6c4SBarry Smith } 537*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixAssemble,ex->ss_mat); 538f4bdf6c4SBarry Smith PetscFunctionReturn(0); 539f4bdf6c4SBarry Smith } 540f4bdf6c4SBarry Smith 54159cb773eSBarry Smith static PetscErrorCode MatSetUp_HYPRESStruct(Mat mat) 542f4bdf6c4SBarry Smith { 543f4bdf6c4SBarry Smith PetscErrorCode ierr; 544f4bdf6c4SBarry Smith Mat_HYPRESStruct *ex = (Mat_HYPRESStruct*) mat->data; 545f4bdf6c4SBarry Smith PetscInt dim,dof,sw[3],nx,ny,nz; 5464ddd07fcSJed Brown PetscInt ilower[3],iupper[3],ssize,i; 547bff4a2f0SMatthew G. Knepley DMBoundaryType px,py,pz; 548f4bdf6c4SBarry Smith DMDAStencilType st; 5494ddd07fcSJed Brown PetscInt nparts= 1; /* assuming only one part */ 5504ddd07fcSJed Brown PetscInt part = 0; 551565245c5SBarry Smith ISLocalToGlobalMapping ltog; 55259cb773eSBarry Smith DM da; 553b026d285SBarry Smith 554f4bdf6c4SBarry Smith PetscFunctionBegin; 55559cb773eSBarry Smith ierr = MatGetDM(mat,(DM*)&da);CHKERRQ(ierr); 556f4bdf6c4SBarry Smith ex->da = da; 557f4bdf6c4SBarry Smith ierr = PetscObjectReference((PetscObject)da);CHKERRQ(ierr); 558f4bdf6c4SBarry Smith 5597ab44359SJed Brown ierr = DMDAGetInfo(ex->da,&dim,0,0,0,0,0,0,&dof,&sw[0],&px,&py,&pz,&st);CHKERRQ(ierr); 560f4bdf6c4SBarry Smith ierr = DMDAGetCorners(ex->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 561f4bdf6c4SBarry Smith iupper[0] += ilower[0] - 1; 562f4bdf6c4SBarry Smith iupper[1] += ilower[1] - 1; 563f4bdf6c4SBarry Smith iupper[2] += ilower[2] - 1; 564f4bdf6c4SBarry Smith /* the hypre_Box is used to zero out the matrix entries in MatZeroValues() */ 565f4bdf6c4SBarry Smith ex->hbox.imin[0] = ilower[0]; 566f4bdf6c4SBarry Smith ex->hbox.imin[1] = ilower[1]; 567f4bdf6c4SBarry Smith ex->hbox.imin[2] = ilower[2]; 568f4bdf6c4SBarry Smith ex->hbox.imax[0] = iupper[0]; 569f4bdf6c4SBarry Smith ex->hbox.imax[1] = iupper[1]; 570f4bdf6c4SBarry Smith ex->hbox.imax[2] = iupper[2]; 571f4bdf6c4SBarry Smith 572f4bdf6c4SBarry Smith ex->dofs_order = 0; 573f4bdf6c4SBarry Smith 574f4bdf6c4SBarry Smith /* assuming that the same number of dofs on each gridpoint. Also assume all cell-centred based */ 575f4bdf6c4SBarry Smith ex->nvars= dof; 576f4bdf6c4SBarry Smith 577f4bdf6c4SBarry Smith /* create the hypre grid object and set its information */ 5789ace16cdSJacob Faibussowitsch PetscAssertFalse(px || py || pz,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Ask us to add periodic support by calling HYPRE_SStructGridSetPeriodic()"); 579*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGridCreate,ex->hcomm,dim,nparts,&ex->ss_grid); 580*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGridSetExtents,ex->ss_grid,part,ex->hbox.imin,ex->hbox.imax); 581f4bdf6c4SBarry Smith { 582f4bdf6c4SBarry Smith HYPRE_SStructVariable *vartypes; 583785e854fSJed Brown ierr = PetscMalloc1(ex->nvars,&vartypes);CHKERRQ(ierr); 5848865f1eaSKarl Rupp for (i= 0; i< ex->nvars; i++) vartypes[i]= HYPRE_SSTRUCT_VARIABLE_CELL; 585*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGridSetVariables,ex->ss_grid, part, ex->nvars,vartypes); 586f4bdf6c4SBarry Smith ierr = PetscFree(vartypes);CHKERRQ(ierr); 587f4bdf6c4SBarry Smith } 588*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGridAssemble,ex->ss_grid); 589f4bdf6c4SBarry Smith 590f4bdf6c4SBarry Smith sw[1] = sw[0]; 591f4bdf6c4SBarry Smith sw[2] = sw[1]; 592*a74df02fSJacob Faibussowitsch /* PetscStackCallStandard(HYPRE_SStructGridSetNumGhost,ex->ss_grid,sw); */ 593f4bdf6c4SBarry Smith 594f4bdf6c4SBarry Smith /* create the hypre stencil object and set its information */ 5959ace16cdSJacob Faibussowitsch PetscAssertFalse(sw[0] > 1,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Ask us to add support for wider stencils"); 5969ace16cdSJacob Faibussowitsch PetscAssertFalse(st == DMDA_STENCIL_BOX,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Ask us to add support for box stencils"); 597f4bdf6c4SBarry Smith 598f4bdf6c4SBarry Smith if (dim == 1) { 5992cf14000SStefano Zampini HYPRE_Int offsets[3][1] = {{-1},{0},{1}}; 6004ddd07fcSJed Brown PetscInt j, cnt; 601f4bdf6c4SBarry Smith 602f4bdf6c4SBarry Smith ssize = 3*(ex->nvars); 603*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructStencilCreate,dim,ssize,&ex->ss_stencil); 604f4bdf6c4SBarry Smith cnt= 0; 605f4bdf6c4SBarry Smith for (i = 0; i < (ex->nvars); i++) { 606f4bdf6c4SBarry Smith for (j = 0; j < 3; j++) { 607*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructStencilSetEntry,ex->ss_stencil, cnt, offsets[j], i); 608f4bdf6c4SBarry Smith cnt++; 609f4bdf6c4SBarry Smith } 610f4bdf6c4SBarry Smith } 611f4bdf6c4SBarry Smith } else if (dim == 2) { 6122cf14000SStefano Zampini HYPRE_Int offsets[5][2] = {{0,-1},{-1,0},{0,0},{1,0},{0,1}}; 6134ddd07fcSJed Brown PetscInt j, cnt; 614f4bdf6c4SBarry Smith 615f4bdf6c4SBarry Smith ssize = 5*(ex->nvars); 616*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructStencilCreate,dim,ssize,&ex->ss_stencil); 617f4bdf6c4SBarry Smith cnt= 0; 618f4bdf6c4SBarry Smith for (i= 0; i< (ex->nvars); i++) { 619f4bdf6c4SBarry Smith for (j= 0; j< 5; j++) { 620*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructStencilSetEntry,ex->ss_stencil, cnt, offsets[j], i); 621f4bdf6c4SBarry Smith cnt++; 622f4bdf6c4SBarry Smith } 623f4bdf6c4SBarry Smith } 624f4bdf6c4SBarry Smith } else if (dim == 3) { 6252cf14000SStefano Zampini HYPRE_Int offsets[7][3] = {{0,0,-1},{0,-1,0},{-1,0,0},{0,0,0},{1,0,0},{0,1,0},{0,0,1}}; 6264ddd07fcSJed Brown PetscInt j, cnt; 627f4bdf6c4SBarry Smith 628f4bdf6c4SBarry Smith ssize = 7*(ex->nvars); 629*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructStencilCreate,dim,ssize,&ex->ss_stencil); 630f4bdf6c4SBarry Smith cnt= 0; 631f4bdf6c4SBarry Smith for (i= 0; i< (ex->nvars); i++) { 632f4bdf6c4SBarry Smith for (j= 0; j< 7; j++) { 633*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructStencilSetEntry,ex->ss_stencil, cnt, offsets[j], i); 634f4bdf6c4SBarry Smith cnt++; 635f4bdf6c4SBarry Smith } 636f4bdf6c4SBarry Smith } 637f4bdf6c4SBarry Smith } 638f4bdf6c4SBarry Smith 639f4bdf6c4SBarry Smith /* create the HYPRE graph */ 640*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGraphCreate,ex->hcomm, ex->ss_grid, &(ex->ss_graph)); 641f4bdf6c4SBarry Smith 642f4bdf6c4SBarry Smith /* set the stencil graph. Note that each variable has the same graph. This means that each 643f4bdf6c4SBarry Smith variable couples to all the other variable and with the same stencil pattern. */ 644f4bdf6c4SBarry Smith for (i= 0; i< (ex->nvars); i++) { 645*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGraphSetStencil,ex->ss_graph,part,i,ex->ss_stencil); 646f4bdf6c4SBarry Smith } 647*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGraphAssemble,ex->ss_graph); 648f4bdf6c4SBarry Smith 649f4bdf6c4SBarry Smith /* create the HYPRE sstruct vectors for rhs and solution */ 650*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorCreate,ex->hcomm,ex->ss_grid,&ex->ss_b); 651*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorCreate,ex->hcomm,ex->ss_grid,&ex->ss_x); 652*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorInitialize,ex->ss_b); 653*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorInitialize,ex->ss_x); 654*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorAssemble,ex->ss_b); 655*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorAssemble,ex->ss_x); 656f4bdf6c4SBarry Smith 657f4bdf6c4SBarry Smith /* create the hypre matrix object and set its information */ 658*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixCreate,ex->hcomm,ex->ss_graph,&ex->ss_mat); 659*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGridDestroy,ex->ss_grid); 660*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructStencilDestroy,ex->ss_stencil); 661f4bdf6c4SBarry Smith if (ex->needsinitialization) { 662*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixInitialize,ex->ss_mat); 663f4bdf6c4SBarry Smith ex->needsinitialization = PETSC_FALSE; 664f4bdf6c4SBarry Smith } 665f4bdf6c4SBarry Smith 666f4bdf6c4SBarry Smith /* set the global and local sizes of the matrix */ 667f4bdf6c4SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&nx,&ny,&nz);CHKERRQ(ierr); 668f4bdf6c4SBarry Smith ierr = MatSetSizes(mat,dof*nx*ny*nz,dof*nx*ny*nz,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 66961710fbeSStefano Zampini ierr = PetscLayoutSetBlockSize(mat->rmap,dof);CHKERRQ(ierr); 67061710fbeSStefano Zampini ierr = PetscLayoutSetBlockSize(mat->cmap,dof);CHKERRQ(ierr); 671f4bdf6c4SBarry Smith ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 672f4bdf6c4SBarry Smith ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 67361710fbeSStefano Zampini mat->preallocated = PETSC_TRUE; 674f4bdf6c4SBarry Smith 675f4bdf6c4SBarry Smith if (dim == 3) { 676f4bdf6c4SBarry Smith mat->ops->setvalueslocal = MatSetValuesLocal_HYPRESStruct_3d; 677f4bdf6c4SBarry Smith mat->ops->zerorowslocal = MatZeroRowsLocal_HYPRESStruct_3d; 678f4bdf6c4SBarry Smith mat->ops->zeroentries = MatZeroEntries_HYPRESStruct_3d; 6798865f1eaSKarl Rupp 68061710fbeSStefano Zampini /* ierr = MatZeroEntries_HYPRESStruct_3d(mat);CHKERRQ(ierr); */ 681ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Only support for 3d DMDA currently"); 682f4bdf6c4SBarry Smith 683f4bdf6c4SBarry Smith /* get values that will be used repeatedly in MatSetValuesLocal() and MatZeroRowsLocal() repeatedly */ 6840298fd71SBarry Smith ierr = MatGetOwnershipRange(mat,&ex->rstart,NULL);CHKERRQ(ierr); 685565245c5SBarry Smith ierr = DMGetLocalToGlobalMapping(ex->da,<og);CHKERRQ(ierr); 686565245c5SBarry Smith ierr = ISLocalToGlobalMappingGetIndices(ltog, (const PetscInt **) &ex->gindices);CHKERRQ(ierr); 687f4bdf6c4SBarry Smith ierr = DMDAGetGhostCorners(ex->da,0,0,0,&ex->gnx,&ex->gnxgny,&ex->gnxgnygnz);CHKERRQ(ierr); 6888865f1eaSKarl Rupp 689f4bdf6c4SBarry Smith ex->gnxgny *= ex->gnx; 690f4bdf6c4SBarry Smith ex->gnxgnygnz *= ex->gnxgny; 6918865f1eaSKarl Rupp 692f4bdf6c4SBarry Smith ierr = DMDAGetCorners(ex->da,&ex->xs,&ex->ys,&ex->zs,&ex->nx,&ex->ny,&ex->nz);CHKERRQ(ierr); 6938865f1eaSKarl Rupp 694f4bdf6c4SBarry Smith ex->nxny = ex->nx*ex->ny; 695f4bdf6c4SBarry Smith ex->nxnynz = ex->nz*ex->nxny; 696f4bdf6c4SBarry Smith PetscFunctionReturn(0); 697f4bdf6c4SBarry Smith } 698f4bdf6c4SBarry Smith 699f4bdf6c4SBarry Smith PetscErrorCode MatMult_HYPRESStruct(Mat A,Vec x,Vec y) 700f4bdf6c4SBarry Smith { 701f4bdf6c4SBarry Smith PetscErrorCode ierr; 702b026d285SBarry Smith const PetscScalar *xx; 703b026d285SBarry Smith PetscScalar *yy; 7042cf14000SStefano Zampini HYPRE_Int hlower[3],hupper[3]; 7054ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 706f4bdf6c4SBarry Smith Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(A->data); 7074ddd07fcSJed Brown PetscInt ordering= mx->dofs_order; 7084ddd07fcSJed Brown PetscInt nvars = mx->nvars; 7094ddd07fcSJed Brown PetscInt part = 0; 7104ddd07fcSJed Brown PetscInt size; 7114ddd07fcSJed Brown PetscInt i; 712f4bdf6c4SBarry Smith 713f4bdf6c4SBarry Smith PetscFunctionBegin; 714f4bdf6c4SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 7152cf14000SStefano Zampini 7162cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 717f4bdf6c4SBarry Smith iupper[0] += ilower[0] - 1; 718f4bdf6c4SBarry Smith iupper[1] += ilower[1] - 1; 719f4bdf6c4SBarry Smith iupper[2] += ilower[2] - 1; 7202cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 7212cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 7222cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 7232cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 7242cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 7252cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 726f4bdf6c4SBarry Smith 727f4bdf6c4SBarry Smith size= 1; 7288865f1eaSKarl Rupp for (i = 0; i < 3; i++) size *= (iupper[i]-ilower[i]+1); 729f4bdf6c4SBarry Smith 730f4bdf6c4SBarry Smith /* copy x values over to hypre for variable ordering */ 731f4bdf6c4SBarry Smith if (ordering) { 732*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0); 733b026d285SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 734f4bdf6c4SBarry Smith for (i= 0; i< nvars; i++) { 735*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))); 736f4bdf6c4SBarry Smith } 737b026d285SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 738*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorAssemble,mx->ss_b); 739*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixMatvec,1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x); 740f4bdf6c4SBarry Smith 741f4bdf6c4SBarry Smith /* copy solution values back to PETSc */ 742f4bdf6c4SBarry Smith ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 743f4bdf6c4SBarry Smith for (i= 0; i< nvars; i++) { 744*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))); 745f4bdf6c4SBarry Smith } 746f4bdf6c4SBarry Smith ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 747f4bdf6c4SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 748f4bdf6c4SBarry Smith PetscScalar *z; 7494ddd07fcSJed Brown PetscInt j, k; 750f4bdf6c4SBarry Smith 751785e854fSJed Brown ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr); 752*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0); 753b026d285SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 754f4bdf6c4SBarry Smith 755f4bdf6c4SBarry Smith /* transform nodal to hypre's variable ordering for sys_pfmg */ 756f4bdf6c4SBarry Smith for (i= 0; i< size; i++) { 757f4bdf6c4SBarry Smith k= i*nvars; 7588865f1eaSKarl Rupp for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j]; 759f4bdf6c4SBarry Smith } 760f4bdf6c4SBarry Smith for (i= 0; i< nvars; i++) { 761*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))); 762f4bdf6c4SBarry Smith } 763b026d285SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 764*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorAssemble,mx->ss_b); 765*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixMatvec,1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x); 766f4bdf6c4SBarry Smith 767f4bdf6c4SBarry Smith /* copy solution values back to PETSc */ 768f4bdf6c4SBarry Smith ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 769f4bdf6c4SBarry Smith for (i= 0; i< nvars; i++) { 770*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))); 771f4bdf6c4SBarry Smith } 772f4bdf6c4SBarry Smith /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 773f4bdf6c4SBarry Smith for (i= 0; i< size; i++) { 774f4bdf6c4SBarry Smith k= i*nvars; 7758865f1eaSKarl Rupp for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i]; 776f4bdf6c4SBarry Smith } 777f4bdf6c4SBarry Smith ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 778f4bdf6c4SBarry Smith ierr = PetscFree(z);CHKERRQ(ierr); 779f4bdf6c4SBarry Smith } 780f4bdf6c4SBarry Smith PetscFunctionReturn(0); 781f4bdf6c4SBarry Smith } 782f4bdf6c4SBarry Smith 783f4bdf6c4SBarry Smith PetscErrorCode MatAssemblyEnd_HYPRESStruct(Mat mat,MatAssemblyType mode) 784f4bdf6c4SBarry Smith { 785f4bdf6c4SBarry Smith Mat_HYPRESStruct *ex = (Mat_HYPRESStruct*) mat->data; 786f4bdf6c4SBarry Smith 787f4bdf6c4SBarry Smith PetscFunctionBegin; 788*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixAssemble,ex->ss_mat); 789f4bdf6c4SBarry Smith PetscFunctionReturn(0); 790f4bdf6c4SBarry Smith } 791f4bdf6c4SBarry Smith 792f4bdf6c4SBarry Smith PetscErrorCode MatZeroEntries_HYPRESStruct(Mat mat) 793f4bdf6c4SBarry Smith { 794f4bdf6c4SBarry Smith PetscFunctionBegin; 795f4bdf6c4SBarry Smith /* before the DMDA is set to the matrix the zero doesn't need to do anything */ 796f4bdf6c4SBarry Smith PetscFunctionReturn(0); 797f4bdf6c4SBarry Smith } 798f4bdf6c4SBarry Smith 799f4bdf6c4SBarry Smith PetscErrorCode MatDestroy_HYPRESStruct(Mat mat) 800f4bdf6c4SBarry Smith { 801f4bdf6c4SBarry Smith Mat_HYPRESStruct *ex = (Mat_HYPRESStruct*) mat->data; 802f4bdf6c4SBarry Smith PetscErrorCode ierr; 803d94fc0b6SBarry Smith ISLocalToGlobalMapping ltog; 804f4bdf6c4SBarry Smith 805f4bdf6c4SBarry Smith PetscFunctionBegin; 806d94fc0b6SBarry Smith ierr = DMGetLocalToGlobalMapping(ex->da,<og);CHKERRQ(ierr); 807d94fc0b6SBarry Smith ierr = ISLocalToGlobalMappingRestoreIndices(ltog, (const PetscInt **) &ex->gindices);CHKERRQ(ierr); 808*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructGraphDestroy,ex->ss_graph); 809*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructMatrixDestroy,ex->ss_mat); 810*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorDestroy,ex->ss_x); 811*a74df02fSJacob Faibussowitsch PetscStackCallStandard(HYPRE_SStructVectorDestroy,ex->ss_b); 81259cb773eSBarry Smith ierr = PetscObjectDereference((PetscObject)ex->da);CHKERRQ(ierr); 813ffc4695bSBarry Smith ierr = MPI_Comm_free(&(ex->hcomm));CHKERRMPI(ierr); 81459cb773eSBarry Smith ierr = PetscFree(ex);CHKERRQ(ierr); 815f4bdf6c4SBarry Smith PetscFunctionReturn(0); 816f4bdf6c4SBarry Smith } 817f4bdf6c4SBarry Smith 8188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_HYPRESStruct(Mat B) 819f4bdf6c4SBarry Smith { 820f4bdf6c4SBarry Smith Mat_HYPRESStruct *ex; 821f4bdf6c4SBarry Smith PetscErrorCode ierr; 822f4bdf6c4SBarry Smith 823f4bdf6c4SBarry Smith PetscFunctionBegin; 824b00a9115SJed Brown ierr = PetscNewLog(B,&ex);CHKERRQ(ierr); 825f4bdf6c4SBarry Smith B->data = (void*)ex; 826f4bdf6c4SBarry Smith B->rmap->bs = 1; 827f4bdf6c4SBarry Smith B->assembled = PETSC_FALSE; 828f4bdf6c4SBarry Smith 829f4bdf6c4SBarry Smith B->insertmode = NOT_SET_VALUES; 830f4bdf6c4SBarry Smith 831f4bdf6c4SBarry Smith B->ops->assemblyend = MatAssemblyEnd_HYPRESStruct; 832f4bdf6c4SBarry Smith B->ops->mult = MatMult_HYPRESStruct; 833f4bdf6c4SBarry Smith B->ops->zeroentries = MatZeroEntries_HYPRESStruct; 834f4bdf6c4SBarry Smith B->ops->destroy = MatDestroy_HYPRESStruct; 83559cb773eSBarry Smith B->ops->setup = MatSetUp_HYPRESStruct; 836f4bdf6c4SBarry Smith 837f4bdf6c4SBarry Smith ex->needsinitialization = PETSC_TRUE; 838f4bdf6c4SBarry Smith 839ffc4695bSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)B),&(ex->hcomm));CHKERRMPI(ierr); 840f4bdf6c4SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATHYPRESSTRUCT);CHKERRQ(ierr); 841f4bdf6c4SBarry Smith PetscFunctionReturn(0); 842f4bdf6c4SBarry Smith } 843f4bdf6c4SBarry Smith 844