147c6ae99SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 307475bc1SBarry Smith #include <petscmat.h> 447c6ae99SBarry Smith 5e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_1d_MPIAIJ(DM,ISColoringType,ISColoring*); 6e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_2d_MPIAIJ(DM,ISColoringType,ISColoring*); 7e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_2d_5pt_MPIAIJ(DM,ISColoringType,ISColoring*); 8e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_3d_MPIAIJ(DM,ISColoringType,ISColoring*); 947c6ae99SBarry Smith 1047c6ae99SBarry Smith /* 1147c6ae99SBarry Smith For ghost i that may be negative or greater than the upper bound this 1247c6ae99SBarry Smith maps it into the 0:m-1 range using periodicity 1347c6ae99SBarry Smith */ 1447c6ae99SBarry Smith #define SetInRange(i,m) ((i < 0) ? m+i : ((i >= m) ? i-m : i)) 1547c6ae99SBarry Smith 16ce308e1dSBarry Smith static PetscErrorCode DMDASetBlockFills_Private(const PetscInt *dfill,PetscInt w,PetscInt **rfill) 1747c6ae99SBarry Smith { 1847c6ae99SBarry Smith PetscErrorCode ierr; 1947c6ae99SBarry Smith PetscInt i,j,nz,*fill; 2047c6ae99SBarry Smith 2147c6ae99SBarry Smith PetscFunctionBegin; 2247c6ae99SBarry Smith if (!dfill) PetscFunctionReturn(0); 2347c6ae99SBarry Smith 2447c6ae99SBarry Smith /* count number nonzeros */ 2547c6ae99SBarry Smith nz = 0; 2647c6ae99SBarry Smith for (i=0; i<w; i++) { 2747c6ae99SBarry Smith for (j=0; j<w; j++) { 2847c6ae99SBarry Smith if (dfill[w*i+j]) nz++; 2947c6ae99SBarry Smith } 3047c6ae99SBarry Smith } 31854ce69bSBarry Smith ierr = PetscMalloc1(nz + w + 1,&fill);CHKERRQ(ierr); 3247c6ae99SBarry Smith /* construct modified CSR storage of nonzero structure */ 33ce308e1dSBarry Smith /* fill[0 -- w] marks starts of each row of column indices (and end of last row) 34ce308e1dSBarry Smith so fill[1] - fill[0] gives number of nonzeros in first row etc */ 3547c6ae99SBarry Smith nz = w + 1; 3647c6ae99SBarry Smith for (i=0; i<w; i++) { 3747c6ae99SBarry Smith fill[i] = nz; 3847c6ae99SBarry Smith for (j=0; j<w; j++) { 3947c6ae99SBarry Smith if (dfill[w*i+j]) { 4047c6ae99SBarry Smith fill[nz] = j; 4147c6ae99SBarry Smith nz++; 4247c6ae99SBarry Smith } 4347c6ae99SBarry Smith } 4447c6ae99SBarry Smith } 4547c6ae99SBarry Smith fill[w] = nz; 4647c6ae99SBarry Smith 4747c6ae99SBarry Smith *rfill = fill; 4847c6ae99SBarry Smith PetscFunctionReturn(0); 4947c6ae99SBarry Smith } 5047c6ae99SBarry Smith 5147c6ae99SBarry Smith /*@ 52aa219208SBarry Smith DMDASetBlockFills - Sets the fill pattern in each block for a multi-component problem 53950540a4SJed Brown of the matrix returned by DMCreateMatrix(). 5447c6ae99SBarry Smith 55aa219208SBarry Smith Logically Collective on DMDA 5647c6ae99SBarry Smith 5747c6ae99SBarry Smith Input Parameter: 5847c6ae99SBarry Smith + da - the distributed array 590298fd71SBarry Smith . dfill - the fill pattern in the diagonal block (may be NULL, means use dense block) 6047c6ae99SBarry Smith - ofill - the fill pattern in the off-diagonal blocks 6147c6ae99SBarry Smith 6247c6ae99SBarry Smith 6347c6ae99SBarry Smith Level: developer 6447c6ae99SBarry Smith 6547c6ae99SBarry Smith Notes: This only makes sense when you are doing multicomponent problems but using the 6647c6ae99SBarry Smith MPIAIJ matrix format 6747c6ae99SBarry Smith 6847c6ae99SBarry Smith The format for dfill and ofill is a 2 dimensional dof by dof matrix with 1 entries 6947c6ae99SBarry Smith representing coupling and 0 entries for missing coupling. For example 7047c6ae99SBarry Smith $ dfill[9] = {1, 0, 0, 7147c6ae99SBarry Smith $ 1, 1, 0, 7247c6ae99SBarry Smith $ 0, 1, 1} 7347c6ae99SBarry Smith means that row 0 is coupled with only itself in the diagonal block, row 1 is coupled with 7447c6ae99SBarry Smith itself and row 0 (in the diagonal block) and row 2 is coupled with itself and row 1 (in the 7547c6ae99SBarry Smith diagonal block). 7647c6ae99SBarry Smith 77aa219208SBarry Smith DMDASetGetMatrix() allows you to provide general code for those more complicated nonzero patterns then 7847c6ae99SBarry Smith can be represented in the dfill, ofill format 7947c6ae99SBarry Smith 8047c6ae99SBarry Smith Contributed by Glenn Hammond 8147c6ae99SBarry Smith 828ddb5d8bSBarry Smith .seealso DMCreateMatrix(), DMDASetGetMatrix(), DMSetMatrixPreallocateOnly() 8347c6ae99SBarry Smith 8447c6ae99SBarry Smith @*/ 85ce308e1dSBarry Smith PetscErrorCode DMDASetBlockFills(DM da,const PetscInt *dfill,const PetscInt *ofill) 8647c6ae99SBarry Smith { 8747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 8847c6ae99SBarry Smith PetscErrorCode ierr; 89ae4f298aSBarry Smith PetscInt i,k,cnt = 1; 9047c6ae99SBarry Smith 9147c6ae99SBarry Smith PetscFunctionBegin; 92aa219208SBarry Smith ierr = DMDASetBlockFills_Private(dfill,dd->w,&dd->dfill);CHKERRQ(ierr); 93aa219208SBarry Smith ierr = DMDASetBlockFills_Private(ofill,dd->w,&dd->ofill);CHKERRQ(ierr); 94ae4f298aSBarry Smith 95ae4f298aSBarry Smith /* ofillcount tracks the columns of ofill that have any nonzero in thems; the value in each location is the number of 96ae4f298aSBarry Smith columns to the left with any nonzeros in them plus 1 */ 971795a4d1SJed Brown ierr = PetscCalloc1(dd->w,&dd->ofillcols);CHKERRQ(ierr); 98ae4f298aSBarry Smith for (i=0; i<dd->w; i++) { 99ae4f298aSBarry Smith for (k=dd->ofill[i]; k<dd->ofill[i+1]; k++) dd->ofillcols[dd->ofill[k]] = 1; 100ae4f298aSBarry Smith } 101ae4f298aSBarry Smith for (i=0; i<dd->w; i++) { 102ae4f298aSBarry Smith if (dd->ofillcols[i]) { 103ae4f298aSBarry Smith dd->ofillcols[i] = cnt++; 104ae4f298aSBarry Smith } 105ae4f298aSBarry Smith } 10647c6ae99SBarry Smith PetscFunctionReturn(0); 10747c6ae99SBarry Smith } 10847c6ae99SBarry Smith 10947c6ae99SBarry Smith 110b412c318SBarry Smith PetscErrorCode DMCreateColoring_DA(DM da,ISColoringType ctype,ISColoring *coloring) 11147c6ae99SBarry Smith { 11247c6ae99SBarry Smith PetscErrorCode ierr; 11347c6ae99SBarry Smith PetscInt dim,m,n,p,nc; 114bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 11547c6ae99SBarry Smith MPI_Comm comm; 11647c6ae99SBarry Smith PetscMPIInt size; 11747c6ae99SBarry Smith PetscBool isBAIJ; 11847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith PetscFunctionBegin; 12147c6ae99SBarry Smith /* 12247c6ae99SBarry Smith m 12347c6ae99SBarry Smith ------------------------------------------------------ 12447c6ae99SBarry Smith | | 12547c6ae99SBarry Smith | | 12647c6ae99SBarry Smith | ---------------------- | 12747c6ae99SBarry Smith | | | | 12847c6ae99SBarry Smith n | yn | | | 12947c6ae99SBarry Smith | | | | 13047c6ae99SBarry Smith | .--------------------- | 13147c6ae99SBarry Smith | (xs,ys) xn | 13247c6ae99SBarry Smith | . | 13347c6ae99SBarry Smith | (gxs,gys) | 13447c6ae99SBarry Smith | | 13547c6ae99SBarry Smith ----------------------------------------------------- 13647c6ae99SBarry Smith */ 13747c6ae99SBarry Smith 13847c6ae99SBarry Smith /* 13947c6ae99SBarry Smith nc - number of components per grid point 14047c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 14147c6ae99SBarry Smith 14247c6ae99SBarry Smith */ 1431321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,0,0,0,&m,&n,&p,&nc,0,&bx,&by,&bz,0);CHKERRQ(ierr); 14447c6ae99SBarry Smith 14547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 14647c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1475bdb020cSBarry Smith if (ctype == IS_COLORING_LOCAL) { 14847c6ae99SBarry Smith if (size == 1) { 14947c6ae99SBarry Smith ctype = IS_COLORING_GLOBAL; 15047c6ae99SBarry Smith } else if (dim > 1) { 151bff4a2f0SMatthew G. Knepley if ((m==1 && bx == DM_BOUNDARY_PERIODIC) || (n==1 && by == DM_BOUNDARY_PERIODIC) || (p==1 && bz == DM_BOUNDARY_PERIODIC)) { 1525bdb020cSBarry Smith SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"IS_COLORING_LOCAL cannot be used for periodic boundary condition having both ends of the domain on the same process"); 15347c6ae99SBarry Smith } 15447c6ae99SBarry Smith } 15547c6ae99SBarry Smith } 15647c6ae99SBarry Smith 157aa219208SBarry Smith /* Tell the DMDA it has 1 degree of freedom per grid point so that the coloring for BAIJ 15847c6ae99SBarry Smith matrices is for the blocks, not the individual matrix elements */ 159b412c318SBarry Smith ierr = PetscStrcmp(da->mattype,MATBAIJ,&isBAIJ);CHKERRQ(ierr); 160b412c318SBarry Smith if (!isBAIJ) {ierr = PetscStrcmp(da->mattype,MATMPIBAIJ,&isBAIJ);CHKERRQ(ierr);} 161b412c318SBarry Smith if (!isBAIJ) {ierr = PetscStrcmp(da->mattype,MATSEQBAIJ,&isBAIJ);CHKERRQ(ierr);} 16247c6ae99SBarry Smith if (isBAIJ) { 16347c6ae99SBarry Smith dd->w = 1; 16447c6ae99SBarry Smith dd->xs = dd->xs/nc; 16547c6ae99SBarry Smith dd->xe = dd->xe/nc; 16647c6ae99SBarry Smith dd->Xs = dd->Xs/nc; 16747c6ae99SBarry Smith dd->Xe = dd->Xe/nc; 16847c6ae99SBarry Smith } 16947c6ae99SBarry Smith 17047c6ae99SBarry Smith /* 171aa219208SBarry Smith We do not provide a getcoloring function in the DMDA operations because 172aa219208SBarry Smith the basic DMDA does not know about matrices. We think of DMDA as being more 17347c6ae99SBarry Smith more low-level then matrices. 17447c6ae99SBarry Smith */ 17547c6ae99SBarry Smith if (dim == 1) { 176e727c939SJed Brown ierr = DMCreateColoring_DA_1d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 17747c6ae99SBarry Smith } else if (dim == 2) { 178e727c939SJed Brown ierr = DMCreateColoring_DA_2d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 17947c6ae99SBarry Smith } else if (dim == 3) { 180e727c939SJed Brown ierr = DMCreateColoring_DA_3d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 181ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not done for %D dimension, send us mail petsc-maint@mcs.anl.gov for code",dim); 18247c6ae99SBarry Smith if (isBAIJ) { 18347c6ae99SBarry Smith dd->w = nc; 18447c6ae99SBarry Smith dd->xs = dd->xs*nc; 18547c6ae99SBarry Smith dd->xe = dd->xe*nc; 18647c6ae99SBarry Smith dd->Xs = dd->Xs*nc; 18747c6ae99SBarry Smith dd->Xe = dd->Xe*nc; 18847c6ae99SBarry Smith } 18947c6ae99SBarry Smith PetscFunctionReturn(0); 19047c6ae99SBarry Smith } 19147c6ae99SBarry Smith 19247c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 19347c6ae99SBarry Smith 194e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_2d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 19547c6ae99SBarry Smith { 19647c6ae99SBarry Smith PetscErrorCode ierr; 19747c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,ii,gxs,gys,gnx,gny,m,n,M,N,dim,s,k,nc,col; 19847c6ae99SBarry Smith PetscInt ncolors; 19947c6ae99SBarry Smith MPI_Comm comm; 200bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 201aa219208SBarry Smith DMDAStencilType st; 20247c6ae99SBarry Smith ISColoringValue *colors; 20347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 20447c6ae99SBarry Smith 20547c6ae99SBarry Smith PetscFunctionBegin; 20647c6ae99SBarry Smith /* 20747c6ae99SBarry Smith nc - number of components per grid point 20847c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 20947c6ae99SBarry Smith 21047c6ae99SBarry Smith */ 2111321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,&M,&N,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 21247c6ae99SBarry Smith col = 2*s + 1; 213aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 214aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 21547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 21647c6ae99SBarry Smith 21747c6ae99SBarry Smith /* special case as taught to us by Paul Hovland */ 218aa219208SBarry Smith if (st == DMDA_STENCIL_STAR && s == 1) { 219e727c939SJed Brown ierr = DMCreateColoring_DA_2d_5pt_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 22047c6ae99SBarry Smith } else { 22147c6ae99SBarry Smith 222bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % col)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in X (%d) is divisible\n\ 22347c6ae99SBarry Smith by 2*stencil_width + 1 (%d)\n", m, col); 224bff4a2f0SMatthew G. Knepley if (by == DM_BOUNDARY_PERIODIC && (n % col)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Y (%d) is divisible\n\ 22547c6ae99SBarry Smith by 2*stencil_width + 1 (%d)\n", n, col); 22647c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 22747c6ae99SBarry Smith if (!dd->localcoloring) { 228785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny,&colors);CHKERRQ(ierr); 22947c6ae99SBarry Smith ii = 0; 23047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 23147c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 23247c6ae99SBarry Smith for (k=0; k<nc; k++) { 23347c6ae99SBarry Smith colors[ii++] = k + nc*((i % col) + col*(j % col)); 23447c6ae99SBarry Smith } 23547c6ae99SBarry Smith } 23647c6ae99SBarry Smith } 23747c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)); 238aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 23947c6ae99SBarry Smith } 24047c6ae99SBarry Smith *coloring = dd->localcoloring; 2415bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 24247c6ae99SBarry Smith if (!dd->ghostedcoloring) { 243785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny,&colors);CHKERRQ(ierr); 24447c6ae99SBarry Smith ii = 0; 24547c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 24647c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 24747c6ae99SBarry Smith for (k=0; k<nc; k++) { 24847c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 24947c6ae99SBarry Smith colors[ii++] = k + nc*((SetInRange(i,m) % col) + col*(SetInRange(j,n) % col)); 25047c6ae99SBarry Smith } 25147c6ae99SBarry Smith } 25247c6ae99SBarry Smith } 25347c6ae99SBarry Smith ncolors = nc + nc*(col - 1 + col*(col-1)); 254aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 25547c6ae99SBarry Smith /* PetscIntView(ncolors,(PetscInt*)colors,0); */ 25647c6ae99SBarry Smith 2575bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 25847c6ae99SBarry Smith } 25947c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 260ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 26147c6ae99SBarry Smith } 26247c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 26347c6ae99SBarry Smith PetscFunctionReturn(0); 26447c6ae99SBarry Smith } 26547c6ae99SBarry Smith 26647c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 26747c6ae99SBarry Smith 268e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_3d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 26947c6ae99SBarry Smith { 27047c6ae99SBarry Smith PetscErrorCode ierr; 27147c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,gxs,gys,gnx,gny,m,n,p,dim,s,k,nc,col,zs,gzs,ii,l,nz,gnz,M,N,P; 27247c6ae99SBarry Smith PetscInt ncolors; 27347c6ae99SBarry Smith MPI_Comm comm; 274bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 275aa219208SBarry Smith DMDAStencilType st; 27647c6ae99SBarry Smith ISColoringValue *colors; 27747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 27847c6ae99SBarry Smith 27947c6ae99SBarry Smith PetscFunctionBegin; 28047c6ae99SBarry Smith /* 28147c6ae99SBarry Smith nc - number of components per grid point 28247c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 28347c6ae99SBarry Smith 28447c6ae99SBarry Smith */ 2851321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 28647c6ae99SBarry Smith col = 2*s + 1; 287bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in X is divisible\n\ 28847c6ae99SBarry Smith by 2*stencil_width + 1\n"); 289bff4a2f0SMatthew G. Knepley if (by == DM_BOUNDARY_PERIODIC && (n % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Y is divisible\n\ 29047c6ae99SBarry Smith by 2*stencil_width + 1\n"); 291bff4a2f0SMatthew G. Knepley if (bz == DM_BOUNDARY_PERIODIC && (p % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Z is divisible\n\ 29247c6ae99SBarry Smith by 2*stencil_width + 1\n"); 29347c6ae99SBarry Smith 294aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 295aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 29647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 29747c6ae99SBarry Smith 29847c6ae99SBarry Smith /* create the coloring */ 29947c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 30047c6ae99SBarry Smith if (!dd->localcoloring) { 301785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny*nz,&colors);CHKERRQ(ierr); 30247c6ae99SBarry Smith ii = 0; 30347c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 30447c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 30547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 30647c6ae99SBarry Smith for (l=0; l<nc; l++) { 30747c6ae99SBarry Smith colors[ii++] = l + nc*((i % col) + col*(j % col) + col*col*(k % col)); 30847c6ae99SBarry Smith } 30947c6ae99SBarry Smith } 31047c6ae99SBarry Smith } 31147c6ae99SBarry Smith } 31247c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)+ col*col*(col-1)); 313aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny*nz,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 31447c6ae99SBarry Smith } 31547c6ae99SBarry Smith *coloring = dd->localcoloring; 3165bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 31747c6ae99SBarry Smith if (!dd->ghostedcoloring) { 318785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny*gnz,&colors);CHKERRQ(ierr); 31947c6ae99SBarry Smith ii = 0; 32047c6ae99SBarry Smith for (k=gzs; k<gzs+gnz; k++) { 32147c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 32247c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 32347c6ae99SBarry Smith for (l=0; l<nc; l++) { 32447c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 32547c6ae99SBarry Smith colors[ii++] = l + nc*((SetInRange(i,m) % col) + col*(SetInRange(j,n) % col) + col*col*(SetInRange(k,p) % col)); 32647c6ae99SBarry Smith } 32747c6ae99SBarry Smith } 32847c6ae99SBarry Smith } 32947c6ae99SBarry Smith } 33047c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)+ col*col*(col-1)); 331aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny*gnz,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 3325bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 33347c6ae99SBarry Smith } 33447c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 335ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 33647c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 33747c6ae99SBarry Smith PetscFunctionReturn(0); 33847c6ae99SBarry Smith } 33947c6ae99SBarry Smith 34047c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 34147c6ae99SBarry Smith 342e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_1d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 34347c6ae99SBarry Smith { 34447c6ae99SBarry Smith PetscErrorCode ierr; 34547c6ae99SBarry Smith PetscInt xs,nx,i,i1,gxs,gnx,l,m,M,dim,s,nc,col; 34647c6ae99SBarry Smith PetscInt ncolors; 34747c6ae99SBarry Smith MPI_Comm comm; 348bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 34947c6ae99SBarry Smith ISColoringValue *colors; 35047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 35147c6ae99SBarry Smith 35247c6ae99SBarry Smith PetscFunctionBegin; 35347c6ae99SBarry Smith /* 35447c6ae99SBarry Smith nc - number of components per grid point 35547c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 35647c6ae99SBarry Smith 35747c6ae99SBarry Smith */ 3581321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,0,0,&M,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 35947c6ae99SBarry Smith col = 2*s + 1; 36047c6ae99SBarry Smith 361bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % col)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points %d is divisible\n\ 36231e6f798SBarry Smith by 2*stencil_width + 1 %d\n",(int)m,(int)col); 36347c6ae99SBarry Smith 364aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 365aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 36647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 36747c6ae99SBarry Smith 36847c6ae99SBarry Smith /* create the coloring */ 36947c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 37047c6ae99SBarry Smith if (!dd->localcoloring) { 371785e854fSJed Brown ierr = PetscMalloc1(nc*nx,&colors);CHKERRQ(ierr); 372ae4f298aSBarry Smith if (dd->ofillcols) { 373ae4f298aSBarry Smith PetscInt tc = 0; 374ae4f298aSBarry Smith for (i=0; i<nc; i++) tc += (PetscInt) (dd->ofillcols[i] > 0); 375ae4f298aSBarry Smith i1 = 0; 376ae4f298aSBarry Smith for (i=xs; i<xs+nx; i++) { 377ae4f298aSBarry Smith for (l=0; l<nc; l++) { 378ae4f298aSBarry Smith if (dd->ofillcols[l] && (i % col)) { 379ae4f298aSBarry Smith colors[i1++] = nc - 1 + tc*((i % col) - 1) + dd->ofillcols[l]; 380ae4f298aSBarry Smith } else { 381ae4f298aSBarry Smith colors[i1++] = l; 382ae4f298aSBarry Smith } 383ae4f298aSBarry Smith } 384ae4f298aSBarry Smith } 385ae4f298aSBarry Smith ncolors = nc + 2*s*tc; 386ae4f298aSBarry Smith } else { 38747c6ae99SBarry Smith i1 = 0; 38847c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 38947c6ae99SBarry Smith for (l=0; l<nc; l++) { 39047c6ae99SBarry Smith colors[i1++] = l + nc*(i % col); 39147c6ae99SBarry Smith } 39247c6ae99SBarry Smith } 39347c6ae99SBarry Smith ncolors = nc + nc*(col-1); 394ae4f298aSBarry Smith } 395aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 39647c6ae99SBarry Smith } 39747c6ae99SBarry Smith *coloring = dd->localcoloring; 3985bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 39947c6ae99SBarry Smith if (!dd->ghostedcoloring) { 400785e854fSJed Brown ierr = PetscMalloc1(nc*gnx,&colors);CHKERRQ(ierr); 40147c6ae99SBarry Smith i1 = 0; 40247c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 40347c6ae99SBarry Smith for (l=0; l<nc; l++) { 40447c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 40547c6ae99SBarry Smith colors[i1++] = l + nc*(SetInRange(i,m) % col); 40647c6ae99SBarry Smith } 40747c6ae99SBarry Smith } 40847c6ae99SBarry Smith ncolors = nc + nc*(col-1); 409aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 4105bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 41147c6ae99SBarry Smith } 41247c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 413ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 41447c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 41547c6ae99SBarry Smith PetscFunctionReturn(0); 41647c6ae99SBarry Smith } 41747c6ae99SBarry Smith 418e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_2d_5pt_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 41947c6ae99SBarry Smith { 42047c6ae99SBarry Smith PetscErrorCode ierr; 42147c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,ii,gxs,gys,gnx,gny,m,n,dim,s,k,nc; 42247c6ae99SBarry Smith PetscInt ncolors; 42347c6ae99SBarry Smith MPI_Comm comm; 424bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 42547c6ae99SBarry Smith ISColoringValue *colors; 42647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 42747c6ae99SBarry Smith 42847c6ae99SBarry Smith PetscFunctionBegin; 42947c6ae99SBarry Smith /* 43047c6ae99SBarry Smith nc - number of components per grid point 43147c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 43247c6ae99SBarry Smith 43347c6ae99SBarry Smith */ 4341321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,0);CHKERRQ(ierr); 435aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 436aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 43747c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 43847c6ae99SBarry Smith 439bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % 5)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in X is divisible by 5\n"); 440bff4a2f0SMatthew G. Knepley if (by == DM_BOUNDARY_PERIODIC && (n % 5)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Y is divisible by 5\n"); 44147c6ae99SBarry Smith 44247c6ae99SBarry Smith /* create the coloring */ 44347c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 44447c6ae99SBarry Smith if (!dd->localcoloring) { 445785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny,&colors);CHKERRQ(ierr); 44647c6ae99SBarry Smith ii = 0; 44747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 44847c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 44947c6ae99SBarry Smith for (k=0; k<nc; k++) { 45047c6ae99SBarry Smith colors[ii++] = k + nc*((3*j+i) % 5); 45147c6ae99SBarry Smith } 45247c6ae99SBarry Smith } 45347c6ae99SBarry Smith } 45447c6ae99SBarry Smith ncolors = 5*nc; 455aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 45647c6ae99SBarry Smith } 45747c6ae99SBarry Smith *coloring = dd->localcoloring; 4585bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 45947c6ae99SBarry Smith if (!dd->ghostedcoloring) { 460785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny,&colors);CHKERRQ(ierr); 46147c6ae99SBarry Smith ii = 0; 46247c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 46347c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 46447c6ae99SBarry Smith for (k=0; k<nc; k++) { 46547c6ae99SBarry Smith colors[ii++] = k + nc*((3*SetInRange(j,n) + SetInRange(i,m)) % 5); 46647c6ae99SBarry Smith } 46747c6ae99SBarry Smith } 46847c6ae99SBarry Smith } 46947c6ae99SBarry Smith ncolors = 5*nc; 470aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 4715bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 47247c6ae99SBarry Smith } 47347c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 474ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 47547c6ae99SBarry Smith PetscFunctionReturn(0); 47647c6ae99SBarry Smith } 47747c6ae99SBarry Smith 47847c6ae99SBarry Smith /* =========================================================================== */ 479950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ(DM,Mat); 480ce308e1dSBarry Smith extern PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ_Fill(DM,Mat); 481950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ(DM,Mat); 482950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ_Fill(DM,Mat); 483950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ(DM,Mat); 484950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ_Fill(DM,Mat); 485950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIBAIJ(DM,Mat); 486950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIBAIJ(DM,Mat); 487950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPISBAIJ(DM,Mat); 488950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPISBAIJ(DM,Mat); 489d4002b98SHong Zhang extern PetscErrorCode DMCreateMatrix_DA_2d_MPISELL(DM,Mat); 490d4002b98SHong Zhang extern PetscErrorCode DMCreateMatrix_DA_3d_MPISELL(DM,Mat); 491*e584696dSStefano Zampini extern PetscErrorCode DMCreateMatrix_DA_IS(DM,Mat); 49247c6ae99SBarry Smith 4938bbdbebaSMatthew G Knepley /*@C 494c688c046SMatthew G Knepley MatSetupDM - Sets the DMDA that is to be used by the HYPRE_StructMatrix PETSc matrix 49547c6ae99SBarry Smith 49647c6ae99SBarry Smith Logically Collective on Mat 49747c6ae99SBarry Smith 49847c6ae99SBarry Smith Input Parameters: 49947c6ae99SBarry Smith + mat - the matrix 50047c6ae99SBarry Smith - da - the da 50147c6ae99SBarry Smith 50247c6ae99SBarry Smith Level: intermediate 50347c6ae99SBarry Smith 50447c6ae99SBarry Smith @*/ 505c688c046SMatthew G Knepley PetscErrorCode MatSetupDM(Mat mat,DM da) 50647c6ae99SBarry Smith { 50747c6ae99SBarry Smith PetscErrorCode ierr; 50847c6ae99SBarry Smith 50947c6ae99SBarry Smith PetscFunctionBegin; 51047c6ae99SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 51147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 512c688c046SMatthew G Knepley ierr = PetscTryMethod(mat,"MatSetupDM_C",(Mat,DM),(mat,da));CHKERRQ(ierr); 51347c6ae99SBarry Smith PetscFunctionReturn(0); 51447c6ae99SBarry Smith } 51547c6ae99SBarry Smith 5167087cfbeSBarry Smith PetscErrorCode MatView_MPI_DA(Mat A,PetscViewer viewer) 51747c6ae99SBarry Smith { 5189a42bb27SBarry Smith DM da; 51947c6ae99SBarry Smith PetscErrorCode ierr; 52047c6ae99SBarry Smith const char *prefix; 52147c6ae99SBarry Smith Mat Anatural; 52247c6ae99SBarry Smith AO ao; 52347c6ae99SBarry Smith PetscInt rstart,rend,*petsc,i; 52447c6ae99SBarry Smith IS is; 52547c6ae99SBarry Smith MPI_Comm comm; 52674388724SJed Brown PetscViewerFormat format; 52747c6ae99SBarry Smith 52847c6ae99SBarry Smith PetscFunctionBegin; 52974388724SJed Brown /* Check whether we are just printing info, in which case MatView() already viewed everything we wanted to view */ 53074388724SJed Brown ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 53174388724SJed Brown if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 53274388724SJed Brown 53347c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 534c688c046SMatthew G Knepley ierr = MatGetDM(A, &da);CHKERRQ(ierr); 535ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix not generated from a DMDA"); 53647c6ae99SBarry Smith 537aa219208SBarry Smith ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); 53847c6ae99SBarry Smith ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 539854ce69bSBarry Smith ierr = PetscMalloc1(rend-rstart,&petsc);CHKERRQ(ierr); 54047c6ae99SBarry Smith for (i=rstart; i<rend; i++) petsc[i-rstart] = i; 54147c6ae99SBarry Smith ierr = AOApplicationToPetsc(ao,rend-rstart,petsc);CHKERRQ(ierr); 54247c6ae99SBarry Smith ierr = ISCreateGeneral(comm,rend-rstart,petsc,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 54347c6ae99SBarry Smith 54447c6ae99SBarry Smith /* call viewer on natural ordering */ 5457dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,is,is,MAT_INITIAL_MATRIX,&Anatural);CHKERRQ(ierr); 546fcfd50ebSBarry Smith ierr = ISDestroy(&is);CHKERRQ(ierr); 54747c6ae99SBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)A,&prefix);CHKERRQ(ierr); 54847c6ae99SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)Anatural,prefix);CHKERRQ(ierr); 54947c6ae99SBarry Smith ierr = PetscObjectSetName((PetscObject)Anatural,((PetscObject)A)->name);CHKERRQ(ierr); 550539c167fSBarry Smith ierr = MatView(Anatural,viewer);CHKERRQ(ierr); 551fcfd50ebSBarry Smith ierr = MatDestroy(&Anatural);CHKERRQ(ierr); 55247c6ae99SBarry Smith PetscFunctionReturn(0); 55347c6ae99SBarry Smith } 55447c6ae99SBarry Smith 5557087cfbeSBarry Smith PetscErrorCode MatLoad_MPI_DA(Mat A,PetscViewer viewer) 55647c6ae99SBarry Smith { 5579a42bb27SBarry Smith DM da; 55847c6ae99SBarry Smith PetscErrorCode ierr; 55947c6ae99SBarry Smith Mat Anatural,Aapp; 56047c6ae99SBarry Smith AO ao; 561539c167fSBarry Smith PetscInt rstart,rend,*app,i,m,n,M,N; 56247c6ae99SBarry Smith IS is; 56347c6ae99SBarry Smith MPI_Comm comm; 56447c6ae99SBarry Smith 56547c6ae99SBarry Smith PetscFunctionBegin; 56647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 567c688c046SMatthew G Knepley ierr = MatGetDM(A, &da);CHKERRQ(ierr); 568ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix not generated from a DMDA"); 56947c6ae99SBarry Smith 57047c6ae99SBarry Smith /* Load the matrix in natural ordering */ 571ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Anatural);CHKERRQ(ierr); 57247c6ae99SBarry Smith ierr = MatSetType(Anatural,((PetscObject)A)->type_name);CHKERRQ(ierr); 573539c167fSBarry Smith ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 574539c167fSBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 575539c167fSBarry Smith ierr = MatSetSizes(Anatural,m,n,M,N);CHKERRQ(ierr); 57647c6ae99SBarry Smith ierr = MatLoad(Anatural,viewer);CHKERRQ(ierr); 57747c6ae99SBarry Smith 57847c6ae99SBarry Smith /* Map natural ordering to application ordering and create IS */ 579aa219208SBarry Smith ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); 58047c6ae99SBarry Smith ierr = MatGetOwnershipRange(Anatural,&rstart,&rend);CHKERRQ(ierr); 581854ce69bSBarry Smith ierr = PetscMalloc1(rend-rstart,&app);CHKERRQ(ierr); 58247c6ae99SBarry Smith for (i=rstart; i<rend; i++) app[i-rstart] = i; 58347c6ae99SBarry Smith ierr = AOPetscToApplication(ao,rend-rstart,app);CHKERRQ(ierr); 58447c6ae99SBarry Smith ierr = ISCreateGeneral(comm,rend-rstart,app,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 58547c6ae99SBarry Smith 58647c6ae99SBarry Smith /* Do permutation and replace header */ 5877dae84e0SHong Zhang ierr = MatCreateSubMatrix(Anatural,is,is,MAT_INITIAL_MATRIX,&Aapp);CHKERRQ(ierr); 58828be2f97SBarry Smith ierr = MatHeaderReplace(A,&Aapp);CHKERRQ(ierr); 589fcfd50ebSBarry Smith ierr = ISDestroy(&is);CHKERRQ(ierr); 590fcfd50ebSBarry Smith ierr = MatDestroy(&Anatural);CHKERRQ(ierr); 59147c6ae99SBarry Smith PetscFunctionReturn(0); 59247c6ae99SBarry Smith } 59347c6ae99SBarry Smith 594b412c318SBarry Smith PetscErrorCode DMCreateMatrix_DA(DM da, Mat *J) 59547c6ae99SBarry Smith { 59647c6ae99SBarry Smith PetscErrorCode ierr; 59747c6ae99SBarry Smith PetscInt dim,dof,nx,ny,nz,dims[3],starts[3],M,N,P; 59847c6ae99SBarry Smith Mat A; 59947c6ae99SBarry Smith MPI_Comm comm; 60019fd82e9SBarry Smith MatType Atype; 60137d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 602*e584696dSStefano Zampini void (*aij)(void)=NULL,(*baij)(void)=NULL,(*sbaij)(void)=NULL,(*sell)(void)=NULL,(*is)(void)=NULL; 603b412c318SBarry Smith MatType mtype; 60447c6ae99SBarry Smith PetscMPIInt size; 60547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 60647c6ae99SBarry Smith 60747c6ae99SBarry Smith PetscFunctionBegin; 608607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 609b412c318SBarry Smith mtype = da->mattype; 61047c6ae99SBarry Smith 61137d0c07bSMatthew G Knepley ierr = DMGetDefaultSection(da, §ion);CHKERRQ(ierr); 61237d0c07bSMatthew G Knepley if (section) { 61337d0c07bSMatthew G Knepley PetscInt bs = -1; 61437d0c07bSMatthew G Knepley PetscInt localSize; 61537d0c07bSMatthew G Knepley PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isSymmetric; 61637d0c07bSMatthew G Knepley 61737d0c07bSMatthew G Knepley ierr = DMGetDefaultGlobalSection(da, §ionGlobal);CHKERRQ(ierr); 61837d0c07bSMatthew G Knepley ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 619b5579763SJed Brown ierr = MatCreate(PetscObjectComm((PetscObject)da),&A);CHKERRQ(ierr); 620b5579763SJed Brown ierr = MatSetSizes(A,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 621b5579763SJed Brown ierr = MatSetType(A,mtype);CHKERRQ(ierr); 62237d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSHELL,&isShell);CHKERRQ(ierr); 62337d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATBAIJ,&isBlock);CHKERRQ(ierr); 62437d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSEQBAIJ,&isSeqBlock);CHKERRQ(ierr); 62537d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATMPIBAIJ,&isMPIBlock);CHKERRQ(ierr); 62637d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSBAIJ,&isSymBlock);CHKERRQ(ierr); 62737d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSEQSBAIJ,&isSymSeqBlock);CHKERRQ(ierr); 62837d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATMPISBAIJ,&isSymMPIBlock);CHKERRQ(ierr); 62937d0c07bSMatthew G Knepley /* Check for symmetric storage */ 63037d0c07bSMatthew G Knepley isSymmetric = (PetscBool) (isSymBlock || isSymSeqBlock || isSymMPIBlock); 63137d0c07bSMatthew G Knepley if (isSymmetric) { 63237d0c07bSMatthew G Knepley ierr = MatSetOption(*J, MAT_IGNORE_LOWER_TRIANGULAR, PETSC_TRUE);CHKERRQ(ierr); 63337d0c07bSMatthew G Knepley } 63437d0c07bSMatthew G Knepley if (!isShell) { 63537d0c07bSMatthew G Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal; 63637d0c07bSMatthew G Knepley 63737d0c07bSMatthew G Knepley if (bs < 0) { 63837d0c07bSMatthew G Knepley if (isBlock || isSeqBlock || isMPIBlock || isSymBlock || isSymSeqBlock || isSymMPIBlock) { 63937d0c07bSMatthew G Knepley PetscInt pStart, pEnd, p, dof; 64037d0c07bSMatthew G Knepley 64137d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 64237d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 64337d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 64437d0c07bSMatthew G Knepley if (dof) { 64537d0c07bSMatthew G Knepley bs = dof; 64637d0c07bSMatthew G Knepley break; 64737d0c07bSMatthew G Knepley } 64837d0c07bSMatthew G Knepley } 64937d0c07bSMatthew G Knepley } else { 65037d0c07bSMatthew G Knepley bs = 1; 65137d0c07bSMatthew G Knepley } 65237d0c07bSMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 65337d0c07bSMatthew G Knepley bsLocal = bs; 654b2566f29SBarry Smith ierr = MPIU_Allreduce(&bsLocal, &bs, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)da));CHKERRQ(ierr); 65537d0c07bSMatthew G Knepley } 6561795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 657552f7358SJed Brown /* ierr = DMPlexPreallocateOperator(dm, bs, section, sectionGlobal, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); */ 65837d0c07bSMatthew G Knepley ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 65937d0c07bSMatthew G Knepley } 66037d0c07bSMatthew G Knepley } 66147c6ae99SBarry Smith /* 66247c6ae99SBarry Smith m 66347c6ae99SBarry Smith ------------------------------------------------------ 66447c6ae99SBarry Smith | | 66547c6ae99SBarry Smith | | 66647c6ae99SBarry Smith | ---------------------- | 66747c6ae99SBarry Smith | | | | 66847c6ae99SBarry Smith n | ny | | | 66947c6ae99SBarry Smith | | | | 67047c6ae99SBarry Smith | .--------------------- | 67147c6ae99SBarry Smith | (xs,ys) nx | 67247c6ae99SBarry Smith | . | 67347c6ae99SBarry Smith | (gxs,gys) | 67447c6ae99SBarry Smith | | 67547c6ae99SBarry Smith ----------------------------------------------------- 67647c6ae99SBarry Smith */ 67747c6ae99SBarry Smith 67847c6ae99SBarry Smith /* 67947c6ae99SBarry Smith nc - number of components per grid point 68047c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 68147c6ae99SBarry Smith 68247c6ae99SBarry Smith */ 683e30e807fSPeter Brune M = dd->M; 684e30e807fSPeter Brune N = dd->N; 685e30e807fSPeter Brune P = dd->P; 686c73cfb54SMatthew G. Knepley dim = da->dim; 687e30e807fSPeter Brune dof = dd->w; 688e30e807fSPeter Brune /* ierr = DMDAGetInfo(da,&dim,&M,&N,&P,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); */ 689aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&nx,&ny,&nz);CHKERRQ(ierr); 69047c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 69147c6ae99SBarry Smith ierr = MatCreate(comm,&A);CHKERRQ(ierr); 69247c6ae99SBarry Smith ierr = MatSetSizes(A,dof*nx*ny*nz,dof*nx*ny*nz,dof*M*N*P,dof*M*N*P);CHKERRQ(ierr); 693b412c318SBarry Smith ierr = MatSetType(A,mtype);CHKERRQ(ierr); 69495ee5b0eSBarry Smith ierr = MatSetDM(A,da);CHKERRQ(ierr); 695b06ff27eSHong Zhang if (da->structure_only) { 696b06ff27eSHong Zhang ierr = MatSetOption(A,MAT_STRUCTURE_ONLY,PETSC_TRUE);CHKERRQ(ierr); 697b06ff27eSHong Zhang } 69847c6ae99SBarry Smith ierr = MatGetType(A,&Atype);CHKERRQ(ierr); 69947c6ae99SBarry Smith /* 700aa219208SBarry Smith We do not provide a getmatrix function in the DMDA operations because 701aa219208SBarry Smith the basic DMDA does not know about matrices. We think of DMDA as being more 70247c6ae99SBarry Smith more low-level than matrices. This is kind of cheating but, cause sometimes 703aa219208SBarry Smith we think of DMDA has higher level than matrices. 70447c6ae99SBarry Smith 70547c6ae99SBarry Smith We could switch based on Atype (or mtype), but we do not since the 70647c6ae99SBarry Smith specialized setting routines depend only the particular preallocation 70747c6ae99SBarry Smith details of the matrix, not the type itself. 70847c6ae99SBarry Smith */ 70947c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 71047c6ae99SBarry Smith if (!aij) { 71147c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 71247c6ae99SBarry Smith } 71347c6ae99SBarry Smith if (!aij) { 71447c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIBAIJSetPreallocation_C",&baij);CHKERRQ(ierr); 71547c6ae99SBarry Smith if (!baij) { 71647c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqBAIJSetPreallocation_C",&baij);CHKERRQ(ierr); 71747c6ae99SBarry Smith } 71847c6ae99SBarry Smith if (!baij) { 71947c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPISBAIJSetPreallocation_C",&sbaij);CHKERRQ(ierr); 72047c6ae99SBarry Smith if (!sbaij) { 72147c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C",&sbaij);CHKERRQ(ierr); 72247c6ae99SBarry Smith } 7235e26d47bSHong Zhang if (!sbaij) { 724d4002b98SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPISELLSetPreallocation_C",&sell);CHKERRQ(ierr); 725d4002b98SHong Zhang if (!sell) { 726d4002b98SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqSELLSetPreallocation_C",&sell);CHKERRQ(ierr); 7275e26d47bSHong Zhang } 7285e26d47bSHong Zhang } 729*e584696dSStefano Zampini if (!sell) { 730*e584696dSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)A,"MatISSetPreallocation_C",&is);CHKERRQ(ierr); 731*e584696dSStefano Zampini } 73247c6ae99SBarry Smith } 73347c6ae99SBarry Smith } 73447c6ae99SBarry Smith if (aij) { 73547c6ae99SBarry Smith if (dim == 1) { 736ce308e1dSBarry Smith if (dd->ofill) { 737ce308e1dSBarry Smith ierr = DMCreateMatrix_DA_1d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 738ce308e1dSBarry Smith } else { 739950540a4SJed Brown ierr = DMCreateMatrix_DA_1d_MPIAIJ(da,A);CHKERRQ(ierr); 740ce308e1dSBarry Smith } 74147c6ae99SBarry Smith } else if (dim == 2) { 74247c6ae99SBarry Smith if (dd->ofill) { 743950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 74447c6ae99SBarry Smith } else { 745950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIAIJ(da,A);CHKERRQ(ierr); 74647c6ae99SBarry Smith } 74747c6ae99SBarry Smith } else if (dim == 3) { 74847c6ae99SBarry Smith if (dd->ofill) { 749950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 75047c6ae99SBarry Smith } else { 751950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIAIJ(da,A);CHKERRQ(ierr); 75247c6ae99SBarry Smith } 75347c6ae99SBarry Smith } 75447c6ae99SBarry Smith } else if (baij) { 75547c6ae99SBarry Smith if (dim == 2) { 756950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIBAIJ(da,A);CHKERRQ(ierr); 75747c6ae99SBarry Smith } else if (dim == 3) { 758950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIBAIJ(da,A);CHKERRQ(ierr); 759ce94432eSBarry Smith } else SETERRQ3(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not implemented for %D dimension and Matrix Type: %s in %D dimension! Send mail to petsc-maint@mcs.anl.gov for code",dim,Atype,dim); 76047c6ae99SBarry Smith } else if (sbaij) { 76147c6ae99SBarry Smith if (dim == 2) { 762950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPISBAIJ(da,A);CHKERRQ(ierr); 76347c6ae99SBarry Smith } else if (dim == 3) { 764950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPISBAIJ(da,A);CHKERRQ(ierr); 765ce94432eSBarry Smith } else SETERRQ3(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not implemented for %D dimension and Matrix Type: %s in %D dimension! Send mail to petsc-maint@mcs.anl.gov for code",dim,Atype,dim); 766d4002b98SHong Zhang } else if (sell) { 7675e26d47bSHong Zhang if (dim == 2) { 768d4002b98SHong Zhang ierr = DMCreateMatrix_DA_2d_MPISELL(da,A);CHKERRQ(ierr); 769711261dbSHong Zhang } else if (dim == 3) { 770d4002b98SHong Zhang ierr = DMCreateMatrix_DA_3d_MPISELL(da,A);CHKERRQ(ierr); 7715e26d47bSHong Zhang } else SETERRQ3(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not implemented for %D dimension and Matrix Type: %s in %D dimension! Send mail to petsc-maint@mcs.anl.gov for code",dim,Atype,dim); 772*e584696dSStefano Zampini } else if (is) { 773*e584696dSStefano Zampini ierr = DMCreateMatrix_DA_IS(da,A);CHKERRQ(ierr); 774869776cdSLisandro Dalcin } else { 77545b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 776*e584696dSStefano Zampini 777b026d285SBarry Smith ierr = MatSetBlockSize(A,dof);CHKERRQ(ierr); 7782949035bSJed Brown ierr = MatSetUp(A);CHKERRQ(ierr); 779b026d285SBarry Smith ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 780869776cdSLisandro Dalcin ierr = MatSetLocalToGlobalMapping(A,ltog,ltog);CHKERRQ(ierr); 78147c6ae99SBarry Smith } 782aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&starts[0],&starts[1],&starts[2],&dims[0],&dims[1],&dims[2]);CHKERRQ(ierr); 78347c6ae99SBarry Smith ierr = MatSetStencil(A,dim,dims,starts,dof);CHKERRQ(ierr); 784c688c046SMatthew G Knepley ierr = MatSetDM(A,da);CHKERRQ(ierr); 78547c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 78647c6ae99SBarry Smith if (size > 1) { 78747c6ae99SBarry Smith /* change viewer to display matrix in natural ordering */ 78847c6ae99SBarry Smith ierr = MatShellSetOperation(A, MATOP_VIEW, (void (*)(void))MatView_MPI_DA);CHKERRQ(ierr); 78947c6ae99SBarry Smith ierr = MatShellSetOperation(A, MATOP_LOAD, (void (*)(void))MatLoad_MPI_DA);CHKERRQ(ierr); 79047c6ae99SBarry Smith } 791b5579763SJed Brown ierr = MatSetFromOptions(A);CHKERRQ(ierr); 79247c6ae99SBarry Smith *J = A; 79347c6ae99SBarry Smith PetscFunctionReturn(0); 79447c6ae99SBarry Smith } 79547c6ae99SBarry Smith 79647c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 797*e584696dSStefano Zampini PetscErrorCode DMCreateMatrix_DA_IS(DM dm,Mat J) 798*e584696dSStefano Zampini { 799*e584696dSStefano Zampini DM_DA *da = (DM_DA*)dm->data; 800*e584696dSStefano Zampini Mat lJ; 801*e584696dSStefano Zampini ISLocalToGlobalMapping ltog; 802*e584696dSStefano Zampini IS is_loc_filt, is_glob; 803*e584696dSStefano Zampini const PetscInt *e_loc; 804*e584696dSStefano Zampini PetscInt i,nel,nen,dnz,nv,dof,dim; 805*e584696dSStefano Zampini PetscErrorCode ierr; 806*e584696dSStefano Zampini 807*e584696dSStefano Zampini /* The l2g map of DMDA has all ghosted nodes, and e_loc is a subset of all the local nodes (including the ghosted) 808*e584696dSStefano Zampini We need to filter the local indices that are represented through the DMDAGetElements decomposition 809*e584696dSStefano Zampini This is because the size of the local matrices in MATIS is the local size of the l2g map */ 810*e584696dSStefano Zampini PetscFunctionBegin; 811*e584696dSStefano Zampini dof = da->w; 812*e584696dSStefano Zampini dim = dm->dim; 813*e584696dSStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 814*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(ltog,&nv);CHKERRQ(ierr); 815*e584696dSStefano Zampini ierr = DMDAGetElements(dm,&nel,&nen,&e_loc);CHKERRQ(ierr); /* this will throw an error if the stencil type is not DMDA_STENCIL_BOX */ 816*e584696dSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)dm),dof,nel*nen,e_loc,PETSC_COPY_VALUES,&is_loc_filt);CHKERRQ(ierr); 817*e584696dSStefano Zampini ierr = DMDARestoreElements(dm,&nel,&nen,&e_loc);CHKERRQ(ierr); 818*e584696dSStefano Zampini ierr = ISSortRemoveDups(is_loc_filt);CHKERRQ(ierr); 819*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(ltog,is_loc_filt,&is_glob);CHKERRQ(ierr); 820*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_glob,<og);CHKERRQ(ierr); 821*e584696dSStefano Zampini ierr = ISDestroy(&is_glob);CHKERRQ(ierr); 822*e584696dSStefano Zampini ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 823*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 824*e584696dSStefano Zampini /* We also attach a l2g map to the local matrices to have MatSetValueLocal to work */ 825*e584696dSStefano Zampini ierr = MatISGetLocalMat(J,&lJ);CHKERRQ(ierr); 826*e584696dSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)lJ),nv,0,1,&is_glob);CHKERRQ(ierr); 827*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_loc_filt,<og);CHKERRQ(ierr); 828*e584696dSStefano Zampini ierr = ISDestroy(&is_loc_filt);CHKERRQ(ierr); 829*e584696dSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(ltog,IS_GTOLM_MASK,is_glob,&is_loc_filt);CHKERRQ(ierr); 830*e584696dSStefano Zampini ierr = ISDestroy(&is_glob);CHKERRQ(ierr); 831*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 832*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_loc_filt,<og);CHKERRQ(ierr); 833*e584696dSStefano Zampini ierr = ISDestroy(&is_loc_filt);CHKERRQ(ierr); 834*e584696dSStefano Zampini ierr = MatSetLocalToGlobalMapping(lJ,ltog,ltog);CHKERRQ(ierr); 835*e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 836*e584696dSStefano Zampini /* Preallocation (not exact) */ 837*e584696dSStefano Zampini switch (da->elementtype) { 838*e584696dSStefano Zampini case DMDA_ELEMENT_P1: 839*e584696dSStefano Zampini case DMDA_ELEMENT_Q1: 840*e584696dSStefano Zampini dnz = 1; 841*e584696dSStefano Zampini for (i=0; i<dim; i++) dnz *= 3; 842*e584696dSStefano Zampini dnz *= dof; 843*e584696dSStefano Zampini break; 844*e584696dSStefano Zampini default: 845*e584696dSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Unhandled element type %d",da->elementtype); 846*e584696dSStefano Zampini break; 847*e584696dSStefano Zampini } 848*e584696dSStefano Zampini ierr = MatSeqAIJSetPreallocation(lJ,dnz,NULL);CHKERRQ(ierr); 849*e584696dSStefano Zampini ierr = MatSeqBAIJSetPreallocation(lJ,dof,dnz/dof,NULL);CHKERRQ(ierr); 850*e584696dSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(lJ,dof,dnz/dof,NULL);CHKERRQ(ierr); 851*e584696dSStefano Zampini ierr = MatISRestoreLocalMat(J,&lJ);CHKERRQ(ierr); 852*e584696dSStefano Zampini PetscFunctionReturn(0); 853*e584696dSStefano Zampini } 854*e584696dSStefano Zampini 855d4002b98SHong Zhang PetscErrorCode DMCreateMatrix_DA_2d_MPISELL(DM da,Mat J) 8565e26d47bSHong Zhang { 8575e26d47bSHong Zhang PetscErrorCode ierr; 8585e26d47bSHong Zhang PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny,m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p; 8595e26d47bSHong Zhang PetscInt lstart,lend,pstart,pend,*dnz,*onz; 8605e26d47bSHong Zhang MPI_Comm comm; 8615e26d47bSHong Zhang PetscScalar *values; 8625e26d47bSHong Zhang DMBoundaryType bx,by; 8635e26d47bSHong Zhang ISLocalToGlobalMapping ltog; 8645e26d47bSHong Zhang DMDAStencilType st; 8655e26d47bSHong Zhang 8665e26d47bSHong Zhang PetscFunctionBegin; 8675e26d47bSHong Zhang /* 8685e26d47bSHong Zhang nc - number of components per grid point 8695e26d47bSHong Zhang col - number of colors needed in one direction for single component problem 8705e26d47bSHong Zhang 8715e26d47bSHong Zhang */ 8725e26d47bSHong Zhang ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 8735e26d47bSHong Zhang col = 2*s + 1; 8745e26d47bSHong Zhang ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 8755e26d47bSHong Zhang ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 8765e26d47bSHong Zhang ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 8775e26d47bSHong Zhang 8785e26d47bSHong Zhang ierr = PetscMalloc2(nc,&rows,col*col*nc*nc,&cols);CHKERRQ(ierr); 8795e26d47bSHong Zhang ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 8805e26d47bSHong Zhang 8815e26d47bSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 8825e26d47bSHong Zhang /* determine the matrix preallocation information */ 8835e26d47bSHong Zhang ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 8845e26d47bSHong Zhang for (i=xs; i<xs+nx; i++) { 8855e26d47bSHong Zhang 8865e26d47bSHong Zhang pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 8875e26d47bSHong Zhang pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 8885e26d47bSHong Zhang 8895e26d47bSHong Zhang for (j=ys; j<ys+ny; j++) { 8905e26d47bSHong Zhang slot = i - gxs + gnx*(j - gys); 8915e26d47bSHong Zhang 8925e26d47bSHong Zhang lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 8935e26d47bSHong Zhang lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 8945e26d47bSHong Zhang 8955e26d47bSHong Zhang cnt = 0; 8965e26d47bSHong Zhang for (k=0; k<nc; k++) { 8975e26d47bSHong Zhang for (l=lstart; l<lend+1; l++) { 8985e26d47bSHong Zhang for (p=pstart; p<pend+1; p++) { 8995e26d47bSHong Zhang if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 9005e26d47bSHong Zhang cols[cnt++] = k + nc*(slot + gnx*l + p); 9015e26d47bSHong Zhang } 9025e26d47bSHong Zhang } 9035e26d47bSHong Zhang } 9045e26d47bSHong Zhang rows[k] = k + nc*(slot); 9055e26d47bSHong Zhang } 9065e26d47bSHong Zhang ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 9075e26d47bSHong Zhang } 9085e26d47bSHong Zhang } 9095e26d47bSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 910d4002b98SHong Zhang ierr = MatSeqSELLSetPreallocation(J,0,dnz);CHKERRQ(ierr); 911d4002b98SHong Zhang ierr = MatMPISELLSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 9125e26d47bSHong Zhang ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 9135e26d47bSHong Zhang 9145e26d47bSHong Zhang ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 9155e26d47bSHong Zhang 9165e26d47bSHong Zhang /* 9175e26d47bSHong Zhang For each node in the grid: we get the neighbors in the local (on processor ordering 9185e26d47bSHong Zhang that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 9195e26d47bSHong Zhang PETSc ordering. 9205e26d47bSHong Zhang */ 9215e26d47bSHong Zhang if (!da->prealloc_only) { 9225e26d47bSHong Zhang ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 9235e26d47bSHong Zhang for (i=xs; i<xs+nx; i++) { 9245e26d47bSHong Zhang 9255e26d47bSHong Zhang pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 9265e26d47bSHong Zhang pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 9275e26d47bSHong Zhang 9285e26d47bSHong Zhang for (j=ys; j<ys+ny; j++) { 9295e26d47bSHong Zhang slot = i - gxs + gnx*(j - gys); 9305e26d47bSHong Zhang 9315e26d47bSHong Zhang lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 9325e26d47bSHong Zhang lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 9335e26d47bSHong Zhang 9345e26d47bSHong Zhang cnt = 0; 9355e26d47bSHong Zhang for (k=0; k<nc; k++) { 9365e26d47bSHong Zhang for (l=lstart; l<lend+1; l++) { 9375e26d47bSHong Zhang for (p=pstart; p<pend+1; p++) { 9385e26d47bSHong Zhang if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 9395e26d47bSHong Zhang cols[cnt++] = k + nc*(slot + gnx*l + p); 9405e26d47bSHong Zhang } 9415e26d47bSHong Zhang } 9425e26d47bSHong Zhang } 9435e26d47bSHong Zhang rows[k] = k + nc*(slot); 9445e26d47bSHong Zhang } 9455e26d47bSHong Zhang ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 9465e26d47bSHong Zhang } 9475e26d47bSHong Zhang } 9485e26d47bSHong Zhang ierr = PetscFree(values);CHKERRQ(ierr); 9495e26d47bSHong Zhang ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9505e26d47bSHong Zhang ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9515e26d47bSHong Zhang ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 9525e26d47bSHong Zhang } 9535e26d47bSHong Zhang ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 9545e26d47bSHong Zhang PetscFunctionReturn(0); 9555e26d47bSHong Zhang } 9565e26d47bSHong Zhang 957d4002b98SHong Zhang PetscErrorCode DMCreateMatrix_DA_3d_MPISELL(DM da,Mat J) 958711261dbSHong Zhang { 959711261dbSHong Zhang PetscErrorCode ierr; 960711261dbSHong Zhang PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 961711261dbSHong Zhang PetscInt m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p,*dnz = NULL,*onz = NULL; 962711261dbSHong Zhang PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 963711261dbSHong Zhang MPI_Comm comm; 964711261dbSHong Zhang PetscScalar *values; 965711261dbSHong Zhang DMBoundaryType bx,by,bz; 966711261dbSHong Zhang ISLocalToGlobalMapping ltog; 967711261dbSHong Zhang DMDAStencilType st; 968711261dbSHong Zhang 969711261dbSHong Zhang PetscFunctionBegin; 970711261dbSHong Zhang /* 971711261dbSHong Zhang nc - number of components per grid point 972711261dbSHong Zhang col - number of colors needed in one direction for single component problem 973711261dbSHong Zhang 974711261dbSHong Zhang */ 975711261dbSHong Zhang ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 976711261dbSHong Zhang col = 2*s + 1; 977711261dbSHong Zhang ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 978711261dbSHong Zhang ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 979711261dbSHong Zhang ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 980711261dbSHong Zhang 981711261dbSHong Zhang ierr = PetscMalloc2(nc,&rows,col*col*col*nc*nc,&cols);CHKERRQ(ierr); 982711261dbSHong Zhang ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 983711261dbSHong Zhang 984711261dbSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 985711261dbSHong Zhang /* determine the matrix preallocation information */ 986711261dbSHong Zhang ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 987711261dbSHong Zhang for (i=xs; i<xs+nx; i++) { 988711261dbSHong Zhang istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 989711261dbSHong Zhang iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 990711261dbSHong Zhang for (j=ys; j<ys+ny; j++) { 991711261dbSHong Zhang jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 992711261dbSHong Zhang jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 993711261dbSHong Zhang for (k=zs; k<zs+nz; k++) { 994711261dbSHong Zhang kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 995711261dbSHong Zhang kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 996711261dbSHong Zhang 997711261dbSHong Zhang slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 998711261dbSHong Zhang 999711261dbSHong Zhang cnt = 0; 1000711261dbSHong Zhang for (l=0; l<nc; l++) { 1001711261dbSHong Zhang for (ii=istart; ii<iend+1; ii++) { 1002711261dbSHong Zhang for (jj=jstart; jj<jend+1; jj++) { 1003711261dbSHong Zhang for (kk=kstart; kk<kend+1; kk++) { 1004711261dbSHong Zhang if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 1005711261dbSHong Zhang cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 1006711261dbSHong Zhang } 1007711261dbSHong Zhang } 1008711261dbSHong Zhang } 1009711261dbSHong Zhang } 1010711261dbSHong Zhang rows[l] = l + nc*(slot); 1011711261dbSHong Zhang } 1012711261dbSHong Zhang ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1013711261dbSHong Zhang } 1014711261dbSHong Zhang } 1015711261dbSHong Zhang } 1016711261dbSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 1017d4002b98SHong Zhang ierr = MatSeqSELLSetPreallocation(J,0,dnz);CHKERRQ(ierr); 1018d4002b98SHong Zhang ierr = MatMPISELLSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 1019711261dbSHong Zhang ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1020711261dbSHong Zhang ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 1021711261dbSHong Zhang 1022711261dbSHong Zhang /* 1023711261dbSHong Zhang For each node in the grid: we get the neighbors in the local (on processor ordering 1024711261dbSHong Zhang that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 1025711261dbSHong Zhang PETSc ordering. 1026711261dbSHong Zhang */ 1027711261dbSHong Zhang if (!da->prealloc_only) { 1028711261dbSHong Zhang ierr = PetscCalloc1(col*col*col*nc*nc*nc,&values);CHKERRQ(ierr); 1029711261dbSHong Zhang for (i=xs; i<xs+nx; i++) { 1030711261dbSHong Zhang istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1031711261dbSHong Zhang iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 1032711261dbSHong Zhang for (j=ys; j<ys+ny; j++) { 1033711261dbSHong Zhang jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1034711261dbSHong Zhang jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 1035711261dbSHong Zhang for (k=zs; k<zs+nz; k++) { 1036711261dbSHong Zhang kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1037711261dbSHong Zhang kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 1038711261dbSHong Zhang 1039711261dbSHong Zhang slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 1040711261dbSHong Zhang 1041711261dbSHong Zhang cnt = 0; 1042711261dbSHong Zhang for (l=0; l<nc; l++) { 1043711261dbSHong Zhang for (ii=istart; ii<iend+1; ii++) { 1044711261dbSHong Zhang for (jj=jstart; jj<jend+1; jj++) { 1045711261dbSHong Zhang for (kk=kstart; kk<kend+1; kk++) { 1046711261dbSHong Zhang if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 1047711261dbSHong Zhang cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 1048711261dbSHong Zhang } 1049711261dbSHong Zhang } 1050711261dbSHong Zhang } 1051711261dbSHong Zhang } 1052711261dbSHong Zhang rows[l] = l + nc*(slot); 1053711261dbSHong Zhang } 1054711261dbSHong Zhang ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1055711261dbSHong Zhang } 1056711261dbSHong Zhang } 1057711261dbSHong Zhang } 1058711261dbSHong Zhang ierr = PetscFree(values);CHKERRQ(ierr); 1059711261dbSHong Zhang ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1060711261dbSHong Zhang ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1061711261dbSHong Zhang ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 1062711261dbSHong Zhang } 1063711261dbSHong Zhang ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 1064711261dbSHong Zhang PetscFunctionReturn(0); 1065711261dbSHong Zhang } 1066711261dbSHong Zhang 1067950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ(DM da,Mat J) 106847c6ae99SBarry Smith { 106947c6ae99SBarry Smith PetscErrorCode ierr; 1070c1154cd5SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny,m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p,M,N; 107147c6ae99SBarry Smith PetscInt lstart,lend,pstart,pend,*dnz,*onz; 107247c6ae99SBarry Smith MPI_Comm comm; 107347c6ae99SBarry Smith PetscScalar *values; 1074bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 107545b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1076aa219208SBarry Smith DMDAStencilType st; 1077c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 107847c6ae99SBarry Smith 107947c6ae99SBarry Smith PetscFunctionBegin; 108047c6ae99SBarry Smith /* 108147c6ae99SBarry Smith nc - number of components per grid point 108247c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 108347c6ae99SBarry Smith 108447c6ae99SBarry Smith */ 1085c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&M,&N,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 108647c6ae99SBarry Smith col = 2*s + 1; 1087c1154cd5SBarry Smith /* 1088c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1089c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1090c1154cd5SBarry Smith */ 1091c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1092c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1093aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1094aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 109547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 109647c6ae99SBarry Smith 1097dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*col*nc*nc,&cols);CHKERRQ(ierr); 10981411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 109947c6ae99SBarry Smith 110006ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 110147c6ae99SBarry Smith /* determine the matrix preallocation information */ 110247c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 110347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 110447c6ae99SBarry Smith 1105bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1106bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 110747c6ae99SBarry Smith 110847c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 110947c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 111047c6ae99SBarry Smith 1111bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1112bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 111347c6ae99SBarry Smith 111447c6ae99SBarry Smith cnt = 0; 111547c6ae99SBarry Smith for (k=0; k<nc; k++) { 111647c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 111747c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 1118aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 111947c6ae99SBarry Smith cols[cnt++] = k + nc*(slot + gnx*l + p); 112047c6ae99SBarry Smith } 112147c6ae99SBarry Smith } 112247c6ae99SBarry Smith } 112347c6ae99SBarry Smith rows[k] = k + nc*(slot); 112447c6ae99SBarry Smith } 1125c1154cd5SBarry Smith if (removedups) { 1126c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1127c1154cd5SBarry Smith } else { 1128784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 112947c6ae99SBarry Smith } 113047c6ae99SBarry Smith } 1131c1154cd5SBarry Smith } 1132f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 113347c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 113447c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 113547c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 113647c6ae99SBarry Smith 1137784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 113847c6ae99SBarry Smith 113947c6ae99SBarry Smith /* 114047c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 114147c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 114247c6ae99SBarry Smith PETSc ordering. 114347c6ae99SBarry Smith */ 1144fcfd50ebSBarry Smith if (!da->prealloc_only) { 11451795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 114647c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 114747c6ae99SBarry Smith 1148bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1149bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 115047c6ae99SBarry Smith 115147c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 115247c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 115347c6ae99SBarry Smith 1154bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1155bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 115647c6ae99SBarry Smith 115747c6ae99SBarry Smith cnt = 0; 115847c6ae99SBarry Smith for (k=0; k<nc; k++) { 115947c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 116047c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 1161aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 116247c6ae99SBarry Smith cols[cnt++] = k + nc*(slot + gnx*l + p); 116347c6ae99SBarry Smith } 116447c6ae99SBarry Smith } 116547c6ae99SBarry Smith } 116647c6ae99SBarry Smith rows[k] = k + nc*(slot); 116747c6ae99SBarry Smith } 116847c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 116947c6ae99SBarry Smith } 117047c6ae99SBarry Smith } 117147c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 117247c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 117347c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1174189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 117547c6ae99SBarry Smith } 117647c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 117747c6ae99SBarry Smith PetscFunctionReturn(0); 117847c6ae99SBarry Smith } 117947c6ae99SBarry Smith 1180950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ_Fill(DM da,Mat J) 118147c6ae99SBarry Smith { 118247c6ae99SBarry Smith PetscErrorCode ierr; 118347c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 1184c1154cd5SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,row,col,cnt,maxcnt = 0,l,p,M,N; 118547c6ae99SBarry Smith PetscInt lstart,lend,pstart,pend,*dnz,*onz; 118647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 118747c6ae99SBarry Smith PetscInt ifill_col,*ofill = dd->ofill, *dfill = dd->dfill; 118847c6ae99SBarry Smith MPI_Comm comm; 118947c6ae99SBarry Smith PetscScalar *values; 1190bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 119145b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1192aa219208SBarry Smith DMDAStencilType st; 1193c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 119447c6ae99SBarry Smith 119547c6ae99SBarry Smith PetscFunctionBegin; 119647c6ae99SBarry Smith /* 119747c6ae99SBarry Smith nc - number of components per grid point 119847c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 119947c6ae99SBarry Smith 120047c6ae99SBarry Smith */ 1201c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&M,&N,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 120247c6ae99SBarry Smith col = 2*s + 1; 1203c1154cd5SBarry Smith /* 1204c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1205c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1206c1154cd5SBarry Smith */ 1207c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1208c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1209aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1210aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 121147c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 121247c6ae99SBarry Smith 12134b26d1cfSBarry Smith ierr = PetscMalloc1(col*col*nc,&cols);CHKERRQ(ierr); 12141411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 121547c6ae99SBarry Smith 121606ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 121747c6ae99SBarry Smith /* determine the matrix preallocation information */ 121847c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 121947c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 122047c6ae99SBarry Smith 1221bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1222bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 122347c6ae99SBarry Smith 122447c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 122547c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 122647c6ae99SBarry Smith 1227bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1228bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 122947c6ae99SBarry Smith 123047c6ae99SBarry Smith for (k=0; k<nc; k++) { 123147c6ae99SBarry Smith cnt = 0; 123247c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 123347c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 123447c6ae99SBarry Smith if (l || p) { 1235aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star */ 12368865f1eaSKarl Rupp for (ifill_col=ofill[k]; ifill_col<ofill[k+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + gnx*l + p); 123747c6ae99SBarry Smith } 123847c6ae99SBarry Smith } else { 123947c6ae99SBarry Smith if (dfill) { 12408865f1eaSKarl Rupp for (ifill_col=dfill[k]; ifill_col<dfill[k+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + gnx*l + p); 124147c6ae99SBarry Smith } else { 12428865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + gnx*l + p); 124347c6ae99SBarry Smith } 124447c6ae99SBarry Smith } 124547c6ae99SBarry Smith } 124647c6ae99SBarry Smith } 124747c6ae99SBarry Smith row = k + nc*(slot); 1248c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,cnt); 1249c1154cd5SBarry Smith if (removedups) { 1250c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1251c1154cd5SBarry Smith } else { 1252784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 125347c6ae99SBarry Smith } 125447c6ae99SBarry Smith } 125547c6ae99SBarry Smith } 1256c1154cd5SBarry Smith } 125747c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 125847c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 125947c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1260784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 126147c6ae99SBarry Smith 126247c6ae99SBarry Smith /* 126347c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 126447c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 126547c6ae99SBarry Smith PETSc ordering. 126647c6ae99SBarry Smith */ 1267fcfd50ebSBarry Smith if (!da->prealloc_only) { 1268c0ab637bSBarry Smith ierr = PetscCalloc1(maxcnt,&values);CHKERRQ(ierr); 126947c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 127047c6ae99SBarry Smith 1271bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1272bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 127347c6ae99SBarry Smith 127447c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 127547c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 127647c6ae99SBarry Smith 1277bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1278bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 127947c6ae99SBarry Smith 128047c6ae99SBarry Smith for (k=0; k<nc; k++) { 128147c6ae99SBarry Smith cnt = 0; 128247c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 128347c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 128447c6ae99SBarry Smith if (l || p) { 1285aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star */ 12868865f1eaSKarl Rupp for (ifill_col=ofill[k]; ifill_col<ofill[k+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + gnx*l + p); 128747c6ae99SBarry Smith } 128847c6ae99SBarry Smith } else { 128947c6ae99SBarry Smith if (dfill) { 12908865f1eaSKarl Rupp for (ifill_col=dfill[k]; ifill_col<dfill[k+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + gnx*l + p); 129147c6ae99SBarry Smith } else { 12928865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + gnx*l + p); 129347c6ae99SBarry Smith } 129447c6ae99SBarry Smith } 129547c6ae99SBarry Smith } 129647c6ae99SBarry Smith } 129747c6ae99SBarry Smith row = k + nc*(slot); 129847c6ae99SBarry Smith ierr = MatSetValuesLocal(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 129947c6ae99SBarry Smith } 130047c6ae99SBarry Smith } 130147c6ae99SBarry Smith } 130247c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 130347c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 130447c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1305189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 130647c6ae99SBarry Smith } 130747c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 130847c6ae99SBarry Smith PetscFunctionReturn(0); 130947c6ae99SBarry Smith } 131047c6ae99SBarry Smith 131147c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 131247c6ae99SBarry Smith 1313950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ(DM da,Mat J) 131447c6ae99SBarry Smith { 131547c6ae99SBarry Smith PetscErrorCode ierr; 131647c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 13170298fd71SBarry Smith PetscInt m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p,*dnz = NULL,*onz = NULL; 1318c1154cd5SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 131947c6ae99SBarry Smith MPI_Comm comm; 132047c6ae99SBarry Smith PetscScalar *values; 1321bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 132245b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1323aa219208SBarry Smith DMDAStencilType st; 1324c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 132547c6ae99SBarry Smith 132647c6ae99SBarry Smith PetscFunctionBegin; 132747c6ae99SBarry Smith /* 132847c6ae99SBarry Smith nc - number of components per grid point 132947c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 133047c6ae99SBarry Smith 133147c6ae99SBarry Smith */ 1332c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 133347c6ae99SBarry Smith col = 2*s + 1; 133447c6ae99SBarry Smith 1335c1154cd5SBarry Smith /* 1336c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1337c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1338c1154cd5SBarry Smith */ 1339c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1340c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1341c1154cd5SBarry Smith if (P == 1 && 2*s >= p) removedups = PETSC_TRUE; 1342c1154cd5SBarry Smith 1343aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1344aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 134547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 134647c6ae99SBarry Smith 1347dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*col*col*nc*nc,&cols);CHKERRQ(ierr); 13481411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 134947c6ae99SBarry Smith 135006ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 135147c6ae99SBarry Smith /* determine the matrix preallocation information */ 135247c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 135347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1354bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1355bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 135647c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1357bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1358bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 135947c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1360bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1361bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 136247c6ae99SBarry Smith 136347c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 136447c6ae99SBarry Smith 136547c6ae99SBarry Smith cnt = 0; 136647c6ae99SBarry Smith for (l=0; l<nc; l++) { 136747c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 136847c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 136947c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1370aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 137147c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 137247c6ae99SBarry Smith } 137347c6ae99SBarry Smith } 137447c6ae99SBarry Smith } 137547c6ae99SBarry Smith } 137647c6ae99SBarry Smith rows[l] = l + nc*(slot); 137747c6ae99SBarry Smith } 1378c1154cd5SBarry Smith if (removedups) { 1379c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1380c1154cd5SBarry Smith } else { 1381784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 138247c6ae99SBarry Smith } 138347c6ae99SBarry Smith } 138447c6ae99SBarry Smith } 1385c1154cd5SBarry Smith } 1386f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 138747c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 138847c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 138947c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1390784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 139147c6ae99SBarry Smith 139247c6ae99SBarry Smith /* 139347c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 139447c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 139547c6ae99SBarry Smith PETSc ordering. 139647c6ae99SBarry Smith */ 1397fcfd50ebSBarry Smith if (!da->prealloc_only) { 13981795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc*nc,&values);CHKERRQ(ierr); 139947c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1400bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1401bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 140247c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1403bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1404bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 140547c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1406bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1407bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 140847c6ae99SBarry Smith 140947c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 141047c6ae99SBarry Smith 141147c6ae99SBarry Smith cnt = 0; 141247c6ae99SBarry Smith for (l=0; l<nc; l++) { 141347c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 141447c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 141547c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1416aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 141747c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 141847c6ae99SBarry Smith } 141947c6ae99SBarry Smith } 142047c6ae99SBarry Smith } 142147c6ae99SBarry Smith } 142247c6ae99SBarry Smith rows[l] = l + nc*(slot); 142347c6ae99SBarry Smith } 142447c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 142547c6ae99SBarry Smith } 142647c6ae99SBarry Smith } 142747c6ae99SBarry Smith } 142847c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 142947c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 143047c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1431189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 143247c6ae99SBarry Smith } 143347c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 143447c6ae99SBarry Smith PetscFunctionReturn(0); 143547c6ae99SBarry Smith } 143647c6ae99SBarry Smith 143747c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 143847c6ae99SBarry Smith 1439ce308e1dSBarry Smith PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ_Fill(DM da,Mat J) 1440ce308e1dSBarry Smith { 1441ce308e1dSBarry Smith PetscErrorCode ierr; 1442ce308e1dSBarry Smith DM_DA *dd = (DM_DA*)da->data; 1443ce308e1dSBarry Smith PetscInt xs,nx,i,j,gxs,gnx,row,k,l; 14448d4c968fSBarry Smith PetscInt m,dim,s,*cols = NULL,nc,cnt,maxcnt = 0,*ocols; 14450acb5bebSBarry Smith PetscInt *ofill = dd->ofill,*dfill = dd->dfill; 1446ce308e1dSBarry Smith PetscScalar *values; 1447bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 144845b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1449ce308e1dSBarry Smith PetscMPIInt rank,size; 1450ce308e1dSBarry Smith 1451ce308e1dSBarry Smith PetscFunctionBegin; 1452bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"With fill provided not implemented with periodic boundary conditions"); 1453ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)da),&rank);CHKERRQ(ierr); 1454ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)da),&size);CHKERRQ(ierr); 1455ce308e1dSBarry Smith 1456ce308e1dSBarry Smith /* 1457ce308e1dSBarry Smith nc - number of components per grid point 1458ce308e1dSBarry Smith 1459ce308e1dSBarry Smith */ 1460ce308e1dSBarry Smith ierr = DMDAGetInfo(da,&dim,&m,0,0,0,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 1461ce308e1dSBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 1462ce308e1dSBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 1463ce308e1dSBarry Smith 1464ce308e1dSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 14651795a4d1SJed Brown ierr = PetscCalloc2(nx*nc,&cols,nx*nc,&ocols);CHKERRQ(ierr); 1466ce308e1dSBarry Smith 1467ce308e1dSBarry Smith /* 1468ce308e1dSBarry Smith note should be smaller for first and last process with no periodic 1469ce308e1dSBarry Smith does not handle dfill 1470ce308e1dSBarry Smith */ 1471ce308e1dSBarry Smith cnt = 0; 1472ce308e1dSBarry Smith /* coupling with process to the left */ 1473ce308e1dSBarry Smith for (i=0; i<s; i++) { 1474ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1475ce308e1dSBarry Smith ocols[cnt] = ((!rank) ? 0 : (s - i)*(ofill[j+1] - ofill[j])); 14760acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + (s + i)*(ofill[j+1] - ofill[j]); 1477c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1478ce308e1dSBarry Smith cnt++; 1479ce308e1dSBarry Smith } 1480ce308e1dSBarry Smith } 1481ce308e1dSBarry Smith for (i=s; i<nx-s; i++) { 1482ce308e1dSBarry Smith for (j=0; j<nc; j++) { 14830acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + 2*s*(ofill[j+1] - ofill[j]); 1484c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1485ce308e1dSBarry Smith cnt++; 1486ce308e1dSBarry Smith } 1487ce308e1dSBarry Smith } 1488ce308e1dSBarry Smith /* coupling with process to the right */ 1489ce308e1dSBarry Smith for (i=nx-s; i<nx; i++) { 1490ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1491ce308e1dSBarry Smith ocols[cnt] = ((rank == (size-1)) ? 0 : (i - nx + s + 1)*(ofill[j+1] - ofill[j])); 14920acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + (s + nx - i - 1)*(ofill[j+1] - ofill[j]); 1493c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1494ce308e1dSBarry Smith cnt++; 1495ce308e1dSBarry Smith } 1496ce308e1dSBarry Smith } 1497ce308e1dSBarry Smith 1498ce308e1dSBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,cols);CHKERRQ(ierr); 1499ce308e1dSBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,cols,0,ocols);CHKERRQ(ierr); 1500ce308e1dSBarry Smith ierr = PetscFree2(cols,ocols);CHKERRQ(ierr); 1501ce308e1dSBarry Smith 1502ce308e1dSBarry Smith ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1503ce308e1dSBarry Smith ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 1504ce308e1dSBarry Smith 1505ce308e1dSBarry Smith /* 1506ce308e1dSBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 1507ce308e1dSBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 1508ce308e1dSBarry Smith PETSc ordering. 1509ce308e1dSBarry Smith */ 1510ce308e1dSBarry Smith if (!da->prealloc_only) { 1511c0ab637bSBarry Smith ierr = PetscCalloc2(maxcnt,&values,maxcnt,&cols);CHKERRQ(ierr); 1512ce308e1dSBarry Smith 1513ce308e1dSBarry Smith row = xs*nc; 1514ce308e1dSBarry Smith /* coupling with process to the left */ 1515ce308e1dSBarry Smith for (i=xs; i<xs+s; i++) { 1516ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1517ce308e1dSBarry Smith cnt = 0; 1518ce308e1dSBarry Smith if (rank) { 1519ce308e1dSBarry Smith for (l=0; l<s; l++) { 1520ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1521ce308e1dSBarry Smith } 1522ce308e1dSBarry Smith } 15230acb5bebSBarry Smith if (dfill) { 15240acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 15250acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 15260acb5bebSBarry Smith } 15270acb5bebSBarry Smith } else { 1528ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1529ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1530ce308e1dSBarry Smith } 15310acb5bebSBarry Smith } 1532ce308e1dSBarry Smith for (l=0; l<s; l++) { 1533ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1534ce308e1dSBarry Smith } 1535ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1536ce308e1dSBarry Smith row++; 1537ce308e1dSBarry Smith } 1538ce308e1dSBarry Smith } 1539ce308e1dSBarry Smith for (i=xs+s; i<xs+nx-s; i++) { 1540ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1541ce308e1dSBarry Smith cnt = 0; 1542ce308e1dSBarry Smith for (l=0; l<s; l++) { 1543ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1544ce308e1dSBarry Smith } 15450acb5bebSBarry Smith if (dfill) { 15460acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 15470acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 15480acb5bebSBarry Smith } 15490acb5bebSBarry Smith } else { 1550ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1551ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1552ce308e1dSBarry Smith } 15530acb5bebSBarry Smith } 1554ce308e1dSBarry Smith for (l=0; l<s; l++) { 1555ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1556ce308e1dSBarry Smith } 1557ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1558ce308e1dSBarry Smith row++; 1559ce308e1dSBarry Smith } 1560ce308e1dSBarry Smith } 1561ce308e1dSBarry Smith /* coupling with process to the right */ 1562ce308e1dSBarry Smith for (i=xs+nx-s; i<xs+nx; i++) { 1563ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1564ce308e1dSBarry Smith cnt = 0; 1565ce308e1dSBarry Smith for (l=0; l<s; l++) { 1566ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1567ce308e1dSBarry Smith } 15680acb5bebSBarry Smith if (dfill) { 15690acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 15700acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 15710acb5bebSBarry Smith } 15720acb5bebSBarry Smith } else { 1573ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1574ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1575ce308e1dSBarry Smith } 15760acb5bebSBarry Smith } 1577ce308e1dSBarry Smith if (rank < size-1) { 1578ce308e1dSBarry Smith for (l=0; l<s; l++) { 1579ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1580ce308e1dSBarry Smith } 1581ce308e1dSBarry Smith } 1582ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1583ce308e1dSBarry Smith row++; 1584ce308e1dSBarry Smith } 1585ce308e1dSBarry Smith } 1586c0ab637bSBarry Smith ierr = PetscFree2(values,cols);CHKERRQ(ierr); 1587ce308e1dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1588ce308e1dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1589189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 1590ce308e1dSBarry Smith } 1591ce308e1dSBarry Smith PetscFunctionReturn(0); 1592ce308e1dSBarry Smith } 1593ce308e1dSBarry Smith 1594ce308e1dSBarry Smith /* ---------------------------------------------------------------------------------*/ 1595ce308e1dSBarry Smith 1596950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ(DM da,Mat J) 159747c6ae99SBarry Smith { 159847c6ae99SBarry Smith PetscErrorCode ierr; 159947c6ae99SBarry Smith PetscInt xs,nx,i,i1,slot,gxs,gnx; 16000298fd71SBarry Smith PetscInt m,dim,s,*cols = NULL,nc,*rows = NULL,col,cnt,l; 160147c6ae99SBarry Smith PetscInt istart,iend; 160247c6ae99SBarry Smith PetscScalar *values; 1603bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 160445b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 160547c6ae99SBarry Smith 160647c6ae99SBarry Smith PetscFunctionBegin; 160747c6ae99SBarry Smith /* 160847c6ae99SBarry Smith nc - number of components per grid point 160947c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 161047c6ae99SBarry Smith 161147c6ae99SBarry Smith */ 16121321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,0,0,0,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 161347c6ae99SBarry Smith col = 2*s + 1; 161447c6ae99SBarry Smith 1615aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 1616aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 161747c6ae99SBarry Smith 1618f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 161947c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,col*nc,0);CHKERRQ(ierr); 162047c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,col*nc,0,col*nc,0);CHKERRQ(ierr); 162147c6ae99SBarry Smith 16221411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1623784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 162447c6ae99SBarry Smith 162547c6ae99SBarry Smith /* 162647c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 162747c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 162847c6ae99SBarry Smith PETSc ordering. 162947c6ae99SBarry Smith */ 1630fcfd50ebSBarry Smith if (!da->prealloc_only) { 1631dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*nc*nc,&cols);CHKERRQ(ierr); 16321795a4d1SJed Brown ierr = PetscCalloc1(col*nc*nc,&values);CHKERRQ(ierr); 163347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 163447c6ae99SBarry Smith istart = PetscMax(-s,gxs - i); 163547c6ae99SBarry Smith iend = PetscMin(s,gxs + gnx - i - 1); 163647c6ae99SBarry Smith slot = i - gxs; 163747c6ae99SBarry Smith 163847c6ae99SBarry Smith cnt = 0; 163947c6ae99SBarry Smith for (l=0; l<nc; l++) { 164047c6ae99SBarry Smith for (i1=istart; i1<iend+1; i1++) { 164147c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + i1); 164247c6ae99SBarry Smith } 164347c6ae99SBarry Smith rows[l] = l + nc*(slot); 164447c6ae99SBarry Smith } 164547c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 164647c6ae99SBarry Smith } 164747c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 164847c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 164947c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1650189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 165147c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 1652ce308e1dSBarry Smith } 165347c6ae99SBarry Smith PetscFunctionReturn(0); 165447c6ae99SBarry Smith } 165547c6ae99SBarry Smith 1656950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIBAIJ(DM da,Mat J) 165747c6ae99SBarry Smith { 165847c6ae99SBarry Smith PetscErrorCode ierr; 165947c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 166047c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,nc,col,cnt,*dnz,*onz; 166147c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,ii,jj; 166247c6ae99SBarry Smith MPI_Comm comm; 166347c6ae99SBarry Smith PetscScalar *values; 1664bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 1665aa219208SBarry Smith DMDAStencilType st; 166645b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 166747c6ae99SBarry Smith 166847c6ae99SBarry Smith PetscFunctionBegin; 166947c6ae99SBarry Smith /* 167047c6ae99SBarry Smith nc - number of components per grid point 167147c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 167247c6ae99SBarry Smith */ 16731321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 167447c6ae99SBarry Smith col = 2*s + 1; 167547c6ae99SBarry Smith 1676aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1677aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 167847c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 167947c6ae99SBarry Smith 1680785e854fSJed Brown ierr = PetscMalloc1(col*col*nc*nc,&cols);CHKERRQ(ierr); 168147c6ae99SBarry Smith 16821411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 168347c6ae99SBarry Smith 168447c6ae99SBarry Smith /* determine the matrix preallocation information */ 168547c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nx*ny,nx*ny,dnz,onz);CHKERRQ(ierr); 168647c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1687bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1688bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 168947c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1690bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1691bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 169247c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 169347c6ae99SBarry Smith 169447c6ae99SBarry Smith /* Find block columns in block row */ 169547c6ae99SBarry Smith cnt = 0; 169647c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 169747c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1698aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { /* BOX or on the STAR */ 169947c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 170047c6ae99SBarry Smith } 170147c6ae99SBarry Smith } 170247c6ae99SBarry Smith } 1703d6e23781SBarry Smith ierr = MatPreallocateSetLocalBlock(ltog,1,&slot,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 170447c6ae99SBarry Smith } 170547c6ae99SBarry Smith } 170647c6ae99SBarry Smith ierr = MatSeqBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 170747c6ae99SBarry Smith ierr = MatMPIBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 170847c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 170947c6ae99SBarry Smith 1710784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 171147c6ae99SBarry Smith 171247c6ae99SBarry Smith /* 171347c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 171447c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 171547c6ae99SBarry Smith PETSc ordering. 171647c6ae99SBarry Smith */ 1717fcfd50ebSBarry Smith if (!da->prealloc_only) { 17181795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 171947c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1720bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1721bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 172247c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1723bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1724bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 172547c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 172647c6ae99SBarry Smith cnt = 0; 172747c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 172847c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1729aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { /* BOX or on the STAR */ 173047c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 173147c6ae99SBarry Smith } 173247c6ae99SBarry Smith } 173347c6ae99SBarry Smith } 173447c6ae99SBarry Smith ierr = MatSetValuesBlockedLocal(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 173547c6ae99SBarry Smith } 173647c6ae99SBarry Smith } 173747c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 173847c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 173947c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1740189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 174147c6ae99SBarry Smith } 174247c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 174347c6ae99SBarry Smith PetscFunctionReturn(0); 174447c6ae99SBarry Smith } 174547c6ae99SBarry Smith 1746950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIBAIJ(DM da,Mat J) 174747c6ae99SBarry Smith { 174847c6ae99SBarry Smith PetscErrorCode ierr; 174947c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 175047c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,col,cnt,p,*dnz,*onz; 175147c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk; 175247c6ae99SBarry Smith MPI_Comm comm; 175347c6ae99SBarry Smith PetscScalar *values; 1754bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 1755aa219208SBarry Smith DMDAStencilType st; 175645b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 175747c6ae99SBarry Smith 175847c6ae99SBarry Smith PetscFunctionBegin; 175947c6ae99SBarry Smith /* 176047c6ae99SBarry Smith nc - number of components per grid point 176147c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 176247c6ae99SBarry Smith 176347c6ae99SBarry Smith */ 17641321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,0,0,0,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 176547c6ae99SBarry Smith col = 2*s + 1; 176647c6ae99SBarry Smith 1767aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1768aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 176947c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 177047c6ae99SBarry Smith 1771785e854fSJed Brown ierr = PetscMalloc1(col*col*col,&cols);CHKERRQ(ierr); 177247c6ae99SBarry Smith 17731411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 177447c6ae99SBarry Smith 177547c6ae99SBarry Smith /* determine the matrix preallocation information */ 177647c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nx*ny*nz,nx*ny*nz,dnz,onz);CHKERRQ(ierr); 177747c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1778bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1779bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 178047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1781bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1782bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 178347c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1784bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1785bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 178647c6ae99SBarry Smith 178747c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 178847c6ae99SBarry Smith 178947c6ae99SBarry Smith /* Find block columns in block row */ 179047c6ae99SBarry Smith cnt = 0; 179147c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 179247c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 179347c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1794aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 179547c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 179647c6ae99SBarry Smith } 179747c6ae99SBarry Smith } 179847c6ae99SBarry Smith } 179947c6ae99SBarry Smith } 1800d6e23781SBarry Smith ierr = MatPreallocateSetLocalBlock(ltog,1,&slot,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 180147c6ae99SBarry Smith } 180247c6ae99SBarry Smith } 180347c6ae99SBarry Smith } 180447c6ae99SBarry Smith ierr = MatSeqBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 180547c6ae99SBarry Smith ierr = MatMPIBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 180647c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 180747c6ae99SBarry Smith 1808784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 180947c6ae99SBarry Smith 181047c6ae99SBarry Smith /* 181147c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 181247c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 181347c6ae99SBarry Smith PETSc ordering. 181447c6ae99SBarry Smith */ 1815fcfd50ebSBarry Smith if (!da->prealloc_only) { 18161795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc,&values);CHKERRQ(ierr); 181747c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1818bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1819bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 182047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1821bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1822bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 182347c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1824bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1825bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 182647c6ae99SBarry Smith 182747c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 182847c6ae99SBarry Smith 182947c6ae99SBarry Smith cnt = 0; 183047c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 183147c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 183247c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1833aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 183447c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 183547c6ae99SBarry Smith } 183647c6ae99SBarry Smith } 183747c6ae99SBarry Smith } 183847c6ae99SBarry Smith } 183947c6ae99SBarry Smith ierr = MatSetValuesBlockedLocal(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 184047c6ae99SBarry Smith } 184147c6ae99SBarry Smith } 184247c6ae99SBarry Smith } 184347c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 184447c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 184547c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1846189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 184747c6ae99SBarry Smith } 184847c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 184947c6ae99SBarry Smith PetscFunctionReturn(0); 185047c6ae99SBarry Smith } 185147c6ae99SBarry Smith 185247c6ae99SBarry Smith /* 185347c6ae99SBarry Smith This helper is for of SBAIJ preallocation, to discard the lower-triangular values which are difficult to 185447c6ae99SBarry Smith identify in the local ordering with periodic domain. 185547c6ae99SBarry Smith */ 185647c6ae99SBarry Smith static PetscErrorCode L2GFilterUpperTriangular(ISLocalToGlobalMapping ltog,PetscInt *row,PetscInt *cnt,PetscInt col[]) 185747c6ae99SBarry Smith { 185847c6ae99SBarry Smith PetscErrorCode ierr; 185947c6ae99SBarry Smith PetscInt i,n; 186047c6ae99SBarry Smith 186147c6ae99SBarry Smith PetscFunctionBegin; 1862d6e23781SBarry Smith ierr = ISLocalToGlobalMappingApplyBlock(ltog,1,row,row);CHKERRQ(ierr); 1863d6e23781SBarry Smith ierr = ISLocalToGlobalMappingApplyBlock(ltog,*cnt,col,col);CHKERRQ(ierr); 186447c6ae99SBarry Smith for (i=0,n=0; i<*cnt; i++) { 186547c6ae99SBarry Smith if (col[i] >= *row) col[n++] = col[i]; 186647c6ae99SBarry Smith } 186747c6ae99SBarry Smith *cnt = n; 186847c6ae99SBarry Smith PetscFunctionReturn(0); 186947c6ae99SBarry Smith } 187047c6ae99SBarry Smith 1871950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPISBAIJ(DM da,Mat J) 187247c6ae99SBarry Smith { 187347c6ae99SBarry Smith PetscErrorCode ierr; 187447c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 187547c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,nc,col,cnt,*dnz,*onz; 187647c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,ii,jj; 187747c6ae99SBarry Smith MPI_Comm comm; 187847c6ae99SBarry Smith PetscScalar *values; 1879bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 1880aa219208SBarry Smith DMDAStencilType st; 188145b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 188247c6ae99SBarry Smith 188347c6ae99SBarry Smith PetscFunctionBegin; 188447c6ae99SBarry Smith /* 188547c6ae99SBarry Smith nc - number of components per grid point 188647c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 188747c6ae99SBarry Smith */ 18881321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 188947c6ae99SBarry Smith col = 2*s + 1; 189047c6ae99SBarry Smith 1891aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1892aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 189347c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 189447c6ae99SBarry Smith 1895785e854fSJed Brown ierr = PetscMalloc1(col*col*nc*nc,&cols);CHKERRQ(ierr); 189647c6ae99SBarry Smith 18971411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 189847c6ae99SBarry Smith 189947c6ae99SBarry Smith /* determine the matrix preallocation information */ 1900eabe889fSLisandro Dalcin ierr = MatPreallocateInitialize(comm,nx*ny,nx*ny,dnz,onz);CHKERRQ(ierr); 190147c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1902bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1903bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 190447c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1905bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1906bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 190747c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 190847c6ae99SBarry Smith 190947c6ae99SBarry Smith /* Find block columns in block row */ 191047c6ae99SBarry Smith cnt = 0; 191147c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 191247c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1913aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { 191447c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 191547c6ae99SBarry Smith } 191647c6ae99SBarry Smith } 191747c6ae99SBarry Smith } 191845b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 1919d6e23781SBarry Smith ierr = MatPreallocateSymmetricSetBlock(slot,cnt,cols,dnz,onz);CHKERRQ(ierr); 192047c6ae99SBarry Smith } 192147c6ae99SBarry Smith } 192247c6ae99SBarry Smith ierr = MatSeqSBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 192347c6ae99SBarry Smith ierr = MatMPISBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 192447c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 192547c6ae99SBarry Smith 1926784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 192747c6ae99SBarry Smith 192847c6ae99SBarry Smith /* 192947c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 193047c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 193147c6ae99SBarry Smith PETSc ordering. 193247c6ae99SBarry Smith */ 1933fcfd50ebSBarry Smith if (!da->prealloc_only) { 19341795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 193547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1936bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1937bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 193847c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1939bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1940bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 194147c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 194247c6ae99SBarry Smith 194347c6ae99SBarry Smith /* Find block columns in block row */ 194447c6ae99SBarry Smith cnt = 0; 194547c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 194647c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1947aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { 194847c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 194947c6ae99SBarry Smith } 195047c6ae99SBarry Smith } 195147c6ae99SBarry Smith } 195245b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 195347c6ae99SBarry Smith ierr = MatSetValuesBlocked(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 195447c6ae99SBarry Smith } 195547c6ae99SBarry Smith } 195647c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 195747c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 195847c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1959189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 196047c6ae99SBarry Smith } 196147c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 196247c6ae99SBarry Smith PetscFunctionReturn(0); 196347c6ae99SBarry Smith } 196447c6ae99SBarry Smith 1965950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPISBAIJ(DM da,Mat J) 196647c6ae99SBarry Smith { 196747c6ae99SBarry Smith PetscErrorCode ierr; 196847c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 196947c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,col,cnt,p,*dnz,*onz; 197047c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk; 197147c6ae99SBarry Smith MPI_Comm comm; 197247c6ae99SBarry Smith PetscScalar *values; 1973bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 1974aa219208SBarry Smith DMDAStencilType st; 197545b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 197647c6ae99SBarry Smith 197747c6ae99SBarry Smith PetscFunctionBegin; 197847c6ae99SBarry Smith /* 197947c6ae99SBarry Smith nc - number of components per grid point 198047c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 198147c6ae99SBarry Smith */ 19821321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,0,0,0,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 198347c6ae99SBarry Smith col = 2*s + 1; 198447c6ae99SBarry Smith 1985aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1986aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 198747c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 198847c6ae99SBarry Smith 198947c6ae99SBarry Smith /* create the matrix */ 1990785e854fSJed Brown ierr = PetscMalloc1(col*col*col,&cols);CHKERRQ(ierr); 199147c6ae99SBarry Smith 19921411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 199347c6ae99SBarry Smith 199447c6ae99SBarry Smith /* determine the matrix preallocation information */ 1995eabe889fSLisandro Dalcin ierr = MatPreallocateInitialize(comm,nx*ny*nz,nx*ny*nz,dnz,onz);CHKERRQ(ierr); 199647c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1997bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1998bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 199947c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2000bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2001bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 200247c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2003bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2004bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 200547c6ae99SBarry Smith 200647c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 200747c6ae99SBarry Smith 200847c6ae99SBarry Smith /* Find block columns in block row */ 200947c6ae99SBarry Smith cnt = 0; 201047c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 201147c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 201247c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 2013aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!ii && !jj) || (!jj && !kk) || (!ii && !kk)) { 201447c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 201547c6ae99SBarry Smith } 201647c6ae99SBarry Smith } 201747c6ae99SBarry Smith } 201847c6ae99SBarry Smith } 201945b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 2020d6e23781SBarry Smith ierr = MatPreallocateSymmetricSetBlock(slot,cnt,cols,dnz,onz);CHKERRQ(ierr); 202147c6ae99SBarry Smith } 202247c6ae99SBarry Smith } 202347c6ae99SBarry Smith } 202447c6ae99SBarry Smith ierr = MatSeqSBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 202547c6ae99SBarry Smith ierr = MatMPISBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 202647c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 202747c6ae99SBarry Smith 2028784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 202947c6ae99SBarry Smith 203047c6ae99SBarry Smith /* 203147c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 203247c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 203347c6ae99SBarry Smith PETSc ordering. 203447c6ae99SBarry Smith */ 2035fcfd50ebSBarry Smith if (!da->prealloc_only) { 20361795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc,&values);CHKERRQ(ierr); 203747c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2038bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2039bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 204047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2041bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2042bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 204347c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2044bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2045bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 204647c6ae99SBarry Smith 204747c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 204847c6ae99SBarry Smith 204947c6ae99SBarry Smith cnt = 0; 205047c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 205147c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 205247c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 2053aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!ii && !jj) || (!jj && !kk) || (!ii && !kk)) { 205447c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 205547c6ae99SBarry Smith } 205647c6ae99SBarry Smith } 205747c6ae99SBarry Smith } 205847c6ae99SBarry Smith } 205945b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 206047c6ae99SBarry Smith ierr = MatSetValuesBlocked(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 206147c6ae99SBarry Smith } 206247c6ae99SBarry Smith } 206347c6ae99SBarry Smith } 206447c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 206547c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 206647c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2067189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 206847c6ae99SBarry Smith } 206947c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 207047c6ae99SBarry Smith PetscFunctionReturn(0); 207147c6ae99SBarry Smith } 207247c6ae99SBarry Smith 207347c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 207447c6ae99SBarry Smith 2075950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ_Fill(DM da,Mat J) 207647c6ae99SBarry Smith { 207747c6ae99SBarry Smith PetscErrorCode ierr; 207847c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 2079c0ab637bSBarry Smith PetscInt m,n,dim,s,*cols,k,nc,row,col,cnt, maxcnt = 0,l,p,*dnz,*onz; 2080c1154cd5SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 208147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 208247c6ae99SBarry Smith PetscInt ifill_col,*dfill = dd->dfill,*ofill = dd->ofill; 208347c6ae99SBarry Smith MPI_Comm comm; 208447c6ae99SBarry Smith PetscScalar *values; 2085bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 208645b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 2087aa219208SBarry Smith DMDAStencilType st; 2088c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 208947c6ae99SBarry Smith 209047c6ae99SBarry Smith PetscFunctionBegin; 209147c6ae99SBarry Smith /* 209247c6ae99SBarry Smith nc - number of components per grid point 209347c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 209447c6ae99SBarry Smith 209547c6ae99SBarry Smith */ 2096c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 209747c6ae99SBarry Smith col = 2*s + 1; 2098bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in X is divisible\n\ 209947c6ae99SBarry Smith by 2*stencil_width + 1\n"); 2100bff4a2f0SMatthew G. Knepley if (by == DM_BOUNDARY_PERIODIC && (n % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Y is divisible\n\ 210147c6ae99SBarry Smith by 2*stencil_width + 1\n"); 2102bff4a2f0SMatthew G. Knepley if (bz == DM_BOUNDARY_PERIODIC && (p % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Z is divisible\n\ 210347c6ae99SBarry Smith by 2*stencil_width + 1\n"); 210447c6ae99SBarry Smith 2105c1154cd5SBarry Smith /* 2106c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 2107c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 2108c1154cd5SBarry Smith */ 2109c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 2110c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 2111c1154cd5SBarry Smith if (P == 1 && 2*s >= p) removedups = PETSC_TRUE; 2112c1154cd5SBarry Smith 2113aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 2114aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 211547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 211647c6ae99SBarry Smith 2117785e854fSJed Brown ierr = PetscMalloc1(col*col*col*nc,&cols);CHKERRQ(ierr); 21181411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 211947c6ae99SBarry Smith 212047c6ae99SBarry Smith /* determine the matrix preallocation information */ 212147c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 212247c6ae99SBarry Smith 212306ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 212447c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2125bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2126bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 212747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2128bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2129bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 213047c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2131bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2132bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 213347c6ae99SBarry Smith 213447c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 213547c6ae99SBarry Smith 213647c6ae99SBarry Smith for (l=0; l<nc; l++) { 213747c6ae99SBarry Smith cnt = 0; 213847c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 213947c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 214047c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 214147c6ae99SBarry Smith if (ii || jj || kk) { 2142aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 21438865f1eaSKarl Rupp for (ifill_col=ofill[l]; ifill_col<ofill[l+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + ii + gnx*jj + gnx*gny*kk); 214447c6ae99SBarry Smith } 214547c6ae99SBarry Smith } else { 214647c6ae99SBarry Smith if (dfill) { 21478865f1eaSKarl Rupp for (ifill_col=dfill[l]; ifill_col<dfill[l+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + ii + gnx*jj + gnx*gny*kk); 214847c6ae99SBarry Smith } else { 21498865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + ii + gnx*jj + gnx*gny*kk); 215047c6ae99SBarry Smith } 215147c6ae99SBarry Smith } 215247c6ae99SBarry Smith } 215347c6ae99SBarry Smith } 215447c6ae99SBarry Smith } 215547c6ae99SBarry Smith row = l + nc*(slot); 2156c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,cnt); 2157c1154cd5SBarry Smith if (removedups) { 2158c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 2159c1154cd5SBarry Smith } else { 2160784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 216147c6ae99SBarry Smith } 216247c6ae99SBarry Smith } 216347c6ae99SBarry Smith } 216447c6ae99SBarry Smith } 2165c1154cd5SBarry Smith } 216647c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 216747c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 216847c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2169784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 217047c6ae99SBarry Smith 217147c6ae99SBarry Smith /* 217247c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 217347c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 217447c6ae99SBarry Smith PETSc ordering. 217547c6ae99SBarry Smith */ 2176fcfd50ebSBarry Smith if (!da->prealloc_only) { 2177c0ab637bSBarry Smith ierr = PetscCalloc1(maxcnt,&values);CHKERRQ(ierr); 217847c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2179bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2180bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 218147c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2182bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2183bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 218447c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2185bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2186bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 218747c6ae99SBarry Smith 218847c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 218947c6ae99SBarry Smith 219047c6ae99SBarry Smith for (l=0; l<nc; l++) { 219147c6ae99SBarry Smith cnt = 0; 219247c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 219347c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 219447c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 219547c6ae99SBarry Smith if (ii || jj || kk) { 2196aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 21978865f1eaSKarl Rupp for (ifill_col=ofill[l]; ifill_col<ofill[l+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + ii + gnx*jj + gnx*gny*kk); 219847c6ae99SBarry Smith } 219947c6ae99SBarry Smith } else { 220047c6ae99SBarry Smith if (dfill) { 22018865f1eaSKarl Rupp for (ifill_col=dfill[l]; ifill_col<dfill[l+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + ii + gnx*jj + gnx*gny*kk); 220247c6ae99SBarry Smith } else { 22038865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + ii + gnx*jj + gnx*gny*kk); 220447c6ae99SBarry Smith } 220547c6ae99SBarry Smith } 220647c6ae99SBarry Smith } 220747c6ae99SBarry Smith } 220847c6ae99SBarry Smith } 220947c6ae99SBarry Smith row = l + nc*(slot); 221047c6ae99SBarry Smith ierr = MatSetValuesLocal(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 221147c6ae99SBarry Smith } 221247c6ae99SBarry Smith } 221347c6ae99SBarry Smith } 221447c6ae99SBarry Smith } 221547c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 221647c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 221747c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2218189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 221947c6ae99SBarry Smith } 222047c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 222147c6ae99SBarry Smith PetscFunctionReturn(0); 222247c6ae99SBarry Smith } 2223