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 51*09e28618SBarry Smith 52*09e28618SBarry Smith static PetscErrorCode DMDASetBlockFillsSparse_Private(const PetscInt *dfillsparse,PetscInt w,PetscInt **rfill) 53*09e28618SBarry Smith { 54*09e28618SBarry Smith PetscErrorCode ierr; 55*09e28618SBarry Smith PetscInt i,nz,*fill; 56*09e28618SBarry Smith 57*09e28618SBarry Smith PetscFunctionBegin; 58*09e28618SBarry Smith if (!dfillsparse) PetscFunctionReturn(0); 59*09e28618SBarry Smith 60*09e28618SBarry Smith /* Determine number of non-zeros */ 61*09e28618SBarry Smith nz = (dfillsparse[w] - w - 1); 62*09e28618SBarry Smith 63*09e28618SBarry Smith /* Allocate space for our copy of the given sparse matrix representation. */ 64*09e28618SBarry Smith ierr = PetscMalloc1(nz + w + 1,&fill);CHKERRQ(ierr); 65*09e28618SBarry Smith 66*09e28618SBarry Smith /* Copy the given sparse matrix representation. */ 67*09e28618SBarry Smith for(i = 0; i < (nz + w + 1); ++i) 68*09e28618SBarry Smith { 69*09e28618SBarry Smith fill[i] = dfillsparse[i]; 70*09e28618SBarry Smith } 71*09e28618SBarry Smith 72*09e28618SBarry Smith *rfill = fill; 73*09e28618SBarry Smith PetscFunctionReturn(0); 74*09e28618SBarry Smith } 75*09e28618SBarry Smith 76*09e28618SBarry Smith 77*09e28618SBarry Smith static PetscErrorCode DMDASetBlockFills_Private2(DM_DA *dd) 78*09e28618SBarry Smith { 79*09e28618SBarry Smith PetscErrorCode ierr; 80*09e28618SBarry Smith PetscInt i,k,cnt = 1; 81*09e28618SBarry Smith 82*09e28618SBarry Smith PetscFunctionBegin; 83*09e28618SBarry Smith 84*09e28618SBarry Smith /* ofillcount tracks the columns of ofill that have any nonzero in thems; the value in each location is the number of 85*09e28618SBarry Smith columns to the left with any nonzeros in them plus 1 */ 86*09e28618SBarry Smith ierr = PetscCalloc1(dd->w,&dd->ofillcols);CHKERRQ(ierr); 87*09e28618SBarry Smith for (i=0; i<dd->w; i++) { 88*09e28618SBarry Smith for (k=dd->ofill[i]; k<dd->ofill[i+1]; k++) dd->ofillcols[dd->ofill[k]] = 1; 89*09e28618SBarry Smith } 90*09e28618SBarry Smith for (i=0; i<dd->w; i++) { 91*09e28618SBarry Smith if (dd->ofillcols[i]) { 92*09e28618SBarry Smith dd->ofillcols[i] = cnt++; 93*09e28618SBarry Smith } 94*09e28618SBarry Smith } 95*09e28618SBarry Smith PetscFunctionReturn(0); 96*09e28618SBarry Smith } 97*09e28618SBarry Smith 98*09e28618SBarry Smith 99*09e28618SBarry Smith 10047c6ae99SBarry Smith /*@ 101aa219208SBarry Smith DMDASetBlockFills - Sets the fill pattern in each block for a multi-component problem 102950540a4SJed Brown of the matrix returned by DMCreateMatrix(). 10347c6ae99SBarry Smith 104aa219208SBarry Smith Logically Collective on DMDA 10547c6ae99SBarry Smith 10647c6ae99SBarry Smith Input Parameter: 10747c6ae99SBarry Smith + da - the distributed array 1080298fd71SBarry Smith . dfill - the fill pattern in the diagonal block (may be NULL, means use dense block) 10947c6ae99SBarry Smith - ofill - the fill pattern in the off-diagonal blocks 11047c6ae99SBarry Smith 11147c6ae99SBarry Smith 11247c6ae99SBarry Smith Level: developer 11347c6ae99SBarry Smith 11495452b02SPatrick Sanan Notes: 11595452b02SPatrick Sanan This only makes sense when you are doing multicomponent problems but using the 11647c6ae99SBarry Smith MPIAIJ matrix format 11747c6ae99SBarry Smith 11847c6ae99SBarry Smith The format for dfill and ofill is a 2 dimensional dof by dof matrix with 1 entries 11947c6ae99SBarry Smith representing coupling and 0 entries for missing coupling. For example 12047c6ae99SBarry Smith $ dfill[9] = {1, 0, 0, 12147c6ae99SBarry Smith $ 1, 1, 0, 12247c6ae99SBarry Smith $ 0, 1, 1} 12347c6ae99SBarry Smith means that row 0 is coupled with only itself in the diagonal block, row 1 is coupled with 12447c6ae99SBarry Smith itself and row 0 (in the diagonal block) and row 2 is coupled with itself and row 1 (in the 12547c6ae99SBarry Smith diagonal block). 12647c6ae99SBarry Smith 127aa219208SBarry Smith DMDASetGetMatrix() allows you to provide general code for those more complicated nonzero patterns then 12847c6ae99SBarry Smith can be represented in the dfill, ofill format 12947c6ae99SBarry Smith 13047c6ae99SBarry Smith Contributed by Glenn Hammond 13147c6ae99SBarry Smith 1328ddb5d8bSBarry Smith .seealso DMCreateMatrix(), DMDASetGetMatrix(), DMSetMatrixPreallocateOnly() 13347c6ae99SBarry Smith 13447c6ae99SBarry Smith @*/ 135ce308e1dSBarry Smith PetscErrorCode DMDASetBlockFills(DM da,const PetscInt *dfill,const PetscInt *ofill) 13647c6ae99SBarry Smith { 13747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 13847c6ae99SBarry Smith PetscErrorCode ierr; 13947c6ae99SBarry Smith 14047c6ae99SBarry Smith PetscFunctionBegin; 141*09e28618SBarry Smith /* save the given dfill and ofill information */ 142aa219208SBarry Smith ierr = DMDASetBlockFills_Private(dfill,dd->w,&dd->dfill);CHKERRQ(ierr); 143aa219208SBarry Smith ierr = DMDASetBlockFills_Private(ofill,dd->w,&dd->ofill);CHKERRQ(ierr); 144ae4f298aSBarry Smith 145*09e28618SBarry Smith /* count nonzeros in ofill columns */ 146*09e28618SBarry Smith ierr = DMDASetBlockFills_Private2(dd);CHKERRQ(ierr); 147*09e28618SBarry Smith 148*09e28618SBarry Smith PetscFunctionReturn(0); 149ae4f298aSBarry Smith } 150*09e28618SBarry Smith 151*09e28618SBarry Smith 152*09e28618SBarry Smith /*@ 153*09e28618SBarry Smith DMDASetBlockFillsSparse - Sets the fill pattern in each block for a multi-component problem 154*09e28618SBarry Smith of the matrix returned by DMCreateMatrix(), using sparse representations 155*09e28618SBarry Smith of fill patterns. 156*09e28618SBarry Smith 157*09e28618SBarry Smith Logically Collective on DMDA 158*09e28618SBarry Smith 159*09e28618SBarry Smith Input Parameter: 160*09e28618SBarry Smith + da - the distributed array 161*09e28618SBarry Smith . dfill - the sparse fill pattern in the diagonal block (may be NULL, means use dense block) 162*09e28618SBarry Smith - ofill - the sparse fill pattern in the off-diagonal blocks 163*09e28618SBarry Smith 164*09e28618SBarry Smith 165*09e28618SBarry Smith Level: developer 166*09e28618SBarry Smith 167*09e28618SBarry Smith Notes: This only makes sense when you are doing multicomponent problems but using the 168*09e28618SBarry Smith MPIAIJ matrix format 169*09e28618SBarry Smith 170*09e28618SBarry Smith The format for dfill and ofill is a sparse representation of a 171*09e28618SBarry Smith dof-by-dof matrix with 1 entries representing coupling and 0 entries 172*09e28618SBarry Smith for missing coupling. The sparse representation is a 1 dimensional 173*09e28618SBarry Smith array of length nz + dof + 1, where nz is the number of non-zeros in 174*09e28618SBarry Smith the matrix. The first dof entries in the array give the 175*09e28618SBarry Smith starting array indices of each row's items in the rest of the array, 176*09e28618SBarry Smith the dof+1st item indicates the total number of nonzeros, 177*09e28618SBarry Smith and the remaining nz items give the column indices of each of 178*09e28618SBarry Smith the 1s within the logical 2D matrix. Each row's items within 179*09e28618SBarry Smith the array are the column indices of the 1s within that row 180*09e28618SBarry Smith of the 2D matrix. PETSc developers may recognize that this is the 181*09e28618SBarry Smith same format as that computed by the DMDASetBlockFills_Private() 182*09e28618SBarry Smith function from a dense 2D matrix representation. 183*09e28618SBarry Smith 184*09e28618SBarry Smith DMDASetGetMatrix() allows you to provide general code for those more complicated nonzero patterns then 185*09e28618SBarry Smith can be represented in the dfill, ofill format 186*09e28618SBarry Smith 187*09e28618SBarry Smith Contributed by Philip C. Roth 188*09e28618SBarry Smith 189*09e28618SBarry Smith .seealso DMDASetBlockFills(), DMCreateMatrix(), DMDASetGetMatrix(), DMSetMatrixPreallocateOnly() 190*09e28618SBarry Smith 191*09e28618SBarry Smith @*/ 192*09e28618SBarry Smith PetscErrorCode DMDASetBlockFillsSparse(DM da,const PetscInt *dfillsparse,const PetscInt *ofillsparse) 193*09e28618SBarry Smith { 194*09e28618SBarry Smith DM_DA *dd = (DM_DA*)da->data; 195*09e28618SBarry Smith PetscErrorCode ierr; 196*09e28618SBarry Smith 197*09e28618SBarry Smith PetscFunctionBegin; 198*09e28618SBarry Smith /* save the given dfill and ofill information */ 199*09e28618SBarry Smith ierr = DMDASetBlockFillsSparse_Private(dfillsparse,dd->w,&dd->dfill);CHKERRQ(ierr); 200*09e28618SBarry Smith ierr = DMDASetBlockFillsSparse_Private(ofillsparse,dd->w,&dd->ofill);CHKERRQ(ierr); 201*09e28618SBarry Smith 202*09e28618SBarry Smith /* count nonzeros in ofill columns */ 203*09e28618SBarry Smith ierr = DMDASetBlockFills_Private2(dd);CHKERRQ(ierr); 204*09e28618SBarry Smith 20547c6ae99SBarry Smith PetscFunctionReturn(0); 20647c6ae99SBarry Smith } 20747c6ae99SBarry Smith 20847c6ae99SBarry Smith 209b412c318SBarry Smith PetscErrorCode DMCreateColoring_DA(DM da,ISColoringType ctype,ISColoring *coloring) 21047c6ae99SBarry Smith { 21147c6ae99SBarry Smith PetscErrorCode ierr; 21247c6ae99SBarry Smith PetscInt dim,m,n,p,nc; 213bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 21447c6ae99SBarry Smith MPI_Comm comm; 21547c6ae99SBarry Smith PetscMPIInt size; 21647c6ae99SBarry Smith PetscBool isBAIJ; 21747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 21847c6ae99SBarry Smith 21947c6ae99SBarry Smith PetscFunctionBegin; 22047c6ae99SBarry Smith /* 22147c6ae99SBarry Smith m 22247c6ae99SBarry Smith ------------------------------------------------------ 22347c6ae99SBarry Smith | | 22447c6ae99SBarry Smith | | 22547c6ae99SBarry Smith | ---------------------- | 22647c6ae99SBarry Smith | | | | 22747c6ae99SBarry Smith n | yn | | | 22847c6ae99SBarry Smith | | | | 22947c6ae99SBarry Smith | .--------------------- | 23047c6ae99SBarry Smith | (xs,ys) xn | 23147c6ae99SBarry Smith | . | 23247c6ae99SBarry Smith | (gxs,gys) | 23347c6ae99SBarry Smith | | 23447c6ae99SBarry Smith ----------------------------------------------------- 23547c6ae99SBarry Smith */ 23647c6ae99SBarry Smith 23747c6ae99SBarry Smith /* 23847c6ae99SBarry Smith nc - number of components per grid point 23947c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 24047c6ae99SBarry Smith 24147c6ae99SBarry Smith */ 2421321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,0,0,0,&m,&n,&p,&nc,0,&bx,&by,&bz,0);CHKERRQ(ierr); 24347c6ae99SBarry Smith 24447c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 24547c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2465bdb020cSBarry Smith if (ctype == IS_COLORING_LOCAL) { 24747c6ae99SBarry Smith if (size == 1) { 24847c6ae99SBarry Smith ctype = IS_COLORING_GLOBAL; 24947c6ae99SBarry Smith } else if (dim > 1) { 250bff4a2f0SMatthew G. Knepley if ((m==1 && bx == DM_BOUNDARY_PERIODIC) || (n==1 && by == DM_BOUNDARY_PERIODIC) || (p==1 && bz == DM_BOUNDARY_PERIODIC)) { 2515bdb020cSBarry 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"); 25247c6ae99SBarry Smith } 25347c6ae99SBarry Smith } 25447c6ae99SBarry Smith } 25547c6ae99SBarry Smith 256aa219208SBarry Smith /* Tell the DMDA it has 1 degree of freedom per grid point so that the coloring for BAIJ 25747c6ae99SBarry Smith matrices is for the blocks, not the individual matrix elements */ 258b412c318SBarry Smith ierr = PetscStrcmp(da->mattype,MATBAIJ,&isBAIJ);CHKERRQ(ierr); 259b412c318SBarry Smith if (!isBAIJ) {ierr = PetscStrcmp(da->mattype,MATMPIBAIJ,&isBAIJ);CHKERRQ(ierr);} 260b412c318SBarry Smith if (!isBAIJ) {ierr = PetscStrcmp(da->mattype,MATSEQBAIJ,&isBAIJ);CHKERRQ(ierr);} 26147c6ae99SBarry Smith if (isBAIJ) { 26247c6ae99SBarry Smith dd->w = 1; 26347c6ae99SBarry Smith dd->xs = dd->xs/nc; 26447c6ae99SBarry Smith dd->xe = dd->xe/nc; 26547c6ae99SBarry Smith dd->Xs = dd->Xs/nc; 26647c6ae99SBarry Smith dd->Xe = dd->Xe/nc; 26747c6ae99SBarry Smith } 26847c6ae99SBarry Smith 26947c6ae99SBarry Smith /* 270aa219208SBarry Smith We do not provide a getcoloring function in the DMDA operations because 271aa219208SBarry Smith the basic DMDA does not know about matrices. We think of DMDA as being more 27247c6ae99SBarry Smith more low-level then matrices. 27347c6ae99SBarry Smith */ 27447c6ae99SBarry Smith if (dim == 1) { 275e727c939SJed Brown ierr = DMCreateColoring_DA_1d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 27647c6ae99SBarry Smith } else if (dim == 2) { 277e727c939SJed Brown ierr = DMCreateColoring_DA_2d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 27847c6ae99SBarry Smith } else if (dim == 3) { 279e727c939SJed Brown ierr = DMCreateColoring_DA_3d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 280ce94432eSBarry 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); 28147c6ae99SBarry Smith if (isBAIJ) { 28247c6ae99SBarry Smith dd->w = nc; 28347c6ae99SBarry Smith dd->xs = dd->xs*nc; 28447c6ae99SBarry Smith dd->xe = dd->xe*nc; 28547c6ae99SBarry Smith dd->Xs = dd->Xs*nc; 28647c6ae99SBarry Smith dd->Xe = dd->Xe*nc; 28747c6ae99SBarry Smith } 28847c6ae99SBarry Smith PetscFunctionReturn(0); 28947c6ae99SBarry Smith } 29047c6ae99SBarry Smith 29147c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 29247c6ae99SBarry Smith 293e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_2d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 29447c6ae99SBarry Smith { 29547c6ae99SBarry Smith PetscErrorCode ierr; 29647c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,ii,gxs,gys,gnx,gny,m,n,M,N,dim,s,k,nc,col; 29747c6ae99SBarry Smith PetscInt ncolors; 29847c6ae99SBarry Smith MPI_Comm comm; 299bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 300aa219208SBarry Smith DMDAStencilType st; 30147c6ae99SBarry Smith ISColoringValue *colors; 30247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 30347c6ae99SBarry Smith 30447c6ae99SBarry Smith PetscFunctionBegin; 30547c6ae99SBarry Smith /* 30647c6ae99SBarry Smith nc - number of components per grid point 30747c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 30847c6ae99SBarry Smith 30947c6ae99SBarry Smith */ 3101321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,&M,&N,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 31147c6ae99SBarry Smith col = 2*s + 1; 312aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 313aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 31447c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 31547c6ae99SBarry Smith 31647c6ae99SBarry Smith /* special case as taught to us by Paul Hovland */ 317aa219208SBarry Smith if (st == DMDA_STENCIL_STAR && s == 1) { 318e727c939SJed Brown ierr = DMCreateColoring_DA_2d_5pt_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 31947c6ae99SBarry Smith } else { 32047c6ae99SBarry Smith 321bff4a2f0SMatthew 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\ 32247c6ae99SBarry Smith by 2*stencil_width + 1 (%d)\n", m, col); 323bff4a2f0SMatthew 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\ 32447c6ae99SBarry Smith by 2*stencil_width + 1 (%d)\n", n, col); 32547c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 32647c6ae99SBarry Smith if (!dd->localcoloring) { 327785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny,&colors);CHKERRQ(ierr); 32847c6ae99SBarry Smith ii = 0; 32947c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 33047c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 33147c6ae99SBarry Smith for (k=0; k<nc; k++) { 33247c6ae99SBarry Smith colors[ii++] = k + nc*((i % col) + col*(j % col)); 33347c6ae99SBarry Smith } 33447c6ae99SBarry Smith } 33547c6ae99SBarry Smith } 33647c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)); 337aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 33847c6ae99SBarry Smith } 33947c6ae99SBarry Smith *coloring = dd->localcoloring; 3405bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 34147c6ae99SBarry Smith if (!dd->ghostedcoloring) { 342785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny,&colors);CHKERRQ(ierr); 34347c6ae99SBarry Smith ii = 0; 34447c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 34547c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 34647c6ae99SBarry Smith for (k=0; k<nc; k++) { 34747c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 34847c6ae99SBarry Smith colors[ii++] = k + nc*((SetInRange(i,m) % col) + col*(SetInRange(j,n) % col)); 34947c6ae99SBarry Smith } 35047c6ae99SBarry Smith } 35147c6ae99SBarry Smith } 35247c6ae99SBarry Smith ncolors = nc + nc*(col - 1 + col*(col-1)); 353aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 35447c6ae99SBarry Smith /* PetscIntView(ncolors,(PetscInt*)colors,0); */ 35547c6ae99SBarry Smith 3565bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 35747c6ae99SBarry Smith } 35847c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 359ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 36047c6ae99SBarry Smith } 36147c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 36247c6ae99SBarry Smith PetscFunctionReturn(0); 36347c6ae99SBarry Smith } 36447c6ae99SBarry Smith 36547c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 36647c6ae99SBarry Smith 367e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_3d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 36847c6ae99SBarry Smith { 36947c6ae99SBarry Smith PetscErrorCode ierr; 37047c6ae99SBarry 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; 37147c6ae99SBarry Smith PetscInt ncolors; 37247c6ae99SBarry Smith MPI_Comm comm; 373bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 374aa219208SBarry Smith DMDAStencilType st; 37547c6ae99SBarry Smith ISColoringValue *colors; 37647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 37747c6ae99SBarry Smith 37847c6ae99SBarry Smith PetscFunctionBegin; 37947c6ae99SBarry Smith /* 38047c6ae99SBarry Smith nc - number of components per grid point 38147c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 38247c6ae99SBarry Smith 38347c6ae99SBarry Smith */ 3841321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 38547c6ae99SBarry Smith col = 2*s + 1; 386bff4a2f0SMatthew 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\ 38747c6ae99SBarry Smith by 2*stencil_width + 1\n"); 388bff4a2f0SMatthew 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\ 38947c6ae99SBarry Smith by 2*stencil_width + 1\n"); 390bff4a2f0SMatthew 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\ 39147c6ae99SBarry Smith by 2*stencil_width + 1\n"); 39247c6ae99SBarry Smith 393aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 394aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 39547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 39647c6ae99SBarry Smith 39747c6ae99SBarry Smith /* create the coloring */ 39847c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 39947c6ae99SBarry Smith if (!dd->localcoloring) { 400785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny*nz,&colors);CHKERRQ(ierr); 40147c6ae99SBarry Smith ii = 0; 40247c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 40347c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 40447c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 40547c6ae99SBarry Smith for (l=0; l<nc; l++) { 40647c6ae99SBarry Smith colors[ii++] = l + nc*((i % col) + col*(j % col) + col*col*(k % col)); 40747c6ae99SBarry Smith } 40847c6ae99SBarry Smith } 40947c6ae99SBarry Smith } 41047c6ae99SBarry Smith } 41147c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)+ col*col*(col-1)); 412aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny*nz,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 41347c6ae99SBarry Smith } 41447c6ae99SBarry Smith *coloring = dd->localcoloring; 4155bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 41647c6ae99SBarry Smith if (!dd->ghostedcoloring) { 417785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny*gnz,&colors);CHKERRQ(ierr); 41847c6ae99SBarry Smith ii = 0; 41947c6ae99SBarry Smith for (k=gzs; k<gzs+gnz; k++) { 42047c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 42147c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 42247c6ae99SBarry Smith for (l=0; l<nc; l++) { 42347c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 42447c6ae99SBarry Smith colors[ii++] = l + nc*((SetInRange(i,m) % col) + col*(SetInRange(j,n) % col) + col*col*(SetInRange(k,p) % col)); 42547c6ae99SBarry Smith } 42647c6ae99SBarry Smith } 42747c6ae99SBarry Smith } 42847c6ae99SBarry Smith } 42947c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)+ col*col*(col-1)); 430aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny*gnz,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 4315bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 43247c6ae99SBarry Smith } 43347c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 434ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 43547c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 43647c6ae99SBarry Smith PetscFunctionReturn(0); 43747c6ae99SBarry Smith } 43847c6ae99SBarry Smith 43947c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 44047c6ae99SBarry Smith 441e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_1d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 44247c6ae99SBarry Smith { 44347c6ae99SBarry Smith PetscErrorCode ierr; 44447c6ae99SBarry Smith PetscInt xs,nx,i,i1,gxs,gnx,l,m,M,dim,s,nc,col; 44547c6ae99SBarry Smith PetscInt ncolors; 44647c6ae99SBarry Smith MPI_Comm comm; 447bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 44847c6ae99SBarry Smith ISColoringValue *colors; 44947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 45047c6ae99SBarry Smith 45147c6ae99SBarry Smith PetscFunctionBegin; 45247c6ae99SBarry Smith /* 45347c6ae99SBarry Smith nc - number of components per grid point 45447c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 45547c6ae99SBarry Smith 45647c6ae99SBarry Smith */ 4571321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,0,0,&M,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 45847c6ae99SBarry Smith col = 2*s + 1; 45947c6ae99SBarry Smith 460bff4a2f0SMatthew 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\ 46131e6f798SBarry Smith by 2*stencil_width + 1 %d\n",(int)m,(int)col); 46247c6ae99SBarry Smith 463aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 464aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 46547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 46647c6ae99SBarry Smith 46747c6ae99SBarry Smith /* create the coloring */ 46847c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 46947c6ae99SBarry Smith if (!dd->localcoloring) { 470785e854fSJed Brown ierr = PetscMalloc1(nc*nx,&colors);CHKERRQ(ierr); 471ae4f298aSBarry Smith if (dd->ofillcols) { 472ae4f298aSBarry Smith PetscInt tc = 0; 473ae4f298aSBarry Smith for (i=0; i<nc; i++) tc += (PetscInt) (dd->ofillcols[i] > 0); 474ae4f298aSBarry Smith i1 = 0; 475ae4f298aSBarry Smith for (i=xs; i<xs+nx; i++) { 476ae4f298aSBarry Smith for (l=0; l<nc; l++) { 477ae4f298aSBarry Smith if (dd->ofillcols[l] && (i % col)) { 478ae4f298aSBarry Smith colors[i1++] = nc - 1 + tc*((i % col) - 1) + dd->ofillcols[l]; 479ae4f298aSBarry Smith } else { 480ae4f298aSBarry Smith colors[i1++] = l; 481ae4f298aSBarry Smith } 482ae4f298aSBarry Smith } 483ae4f298aSBarry Smith } 484ae4f298aSBarry Smith ncolors = nc + 2*s*tc; 485ae4f298aSBarry Smith } else { 48647c6ae99SBarry Smith i1 = 0; 48747c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 48847c6ae99SBarry Smith for (l=0; l<nc; l++) { 48947c6ae99SBarry Smith colors[i1++] = l + nc*(i % col); 49047c6ae99SBarry Smith } 49147c6ae99SBarry Smith } 49247c6ae99SBarry Smith ncolors = nc + nc*(col-1); 493ae4f298aSBarry Smith } 494aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 49547c6ae99SBarry Smith } 49647c6ae99SBarry Smith *coloring = dd->localcoloring; 4975bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 49847c6ae99SBarry Smith if (!dd->ghostedcoloring) { 499785e854fSJed Brown ierr = PetscMalloc1(nc*gnx,&colors);CHKERRQ(ierr); 50047c6ae99SBarry Smith i1 = 0; 50147c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 50247c6ae99SBarry Smith for (l=0; l<nc; l++) { 50347c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 50447c6ae99SBarry Smith colors[i1++] = l + nc*(SetInRange(i,m) % col); 50547c6ae99SBarry Smith } 50647c6ae99SBarry Smith } 50747c6ae99SBarry Smith ncolors = nc + nc*(col-1); 508aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 5095bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 51047c6ae99SBarry Smith } 51147c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 512ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 51347c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 51447c6ae99SBarry Smith PetscFunctionReturn(0); 51547c6ae99SBarry Smith } 51647c6ae99SBarry Smith 517e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_2d_5pt_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 51847c6ae99SBarry Smith { 51947c6ae99SBarry Smith PetscErrorCode ierr; 52047c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,ii,gxs,gys,gnx,gny,m,n,dim,s,k,nc; 52147c6ae99SBarry Smith PetscInt ncolors; 52247c6ae99SBarry Smith MPI_Comm comm; 523bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 52447c6ae99SBarry Smith ISColoringValue *colors; 52547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 52647c6ae99SBarry Smith 52747c6ae99SBarry Smith PetscFunctionBegin; 52847c6ae99SBarry Smith /* 52947c6ae99SBarry Smith nc - number of components per grid point 53047c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 53147c6ae99SBarry Smith 53247c6ae99SBarry Smith */ 5331321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,0);CHKERRQ(ierr); 534aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 535aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 53647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 53747c6ae99SBarry Smith 538bff4a2f0SMatthew 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"); 539bff4a2f0SMatthew 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"); 54047c6ae99SBarry Smith 54147c6ae99SBarry Smith /* create the coloring */ 54247c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 54347c6ae99SBarry Smith if (!dd->localcoloring) { 544785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny,&colors);CHKERRQ(ierr); 54547c6ae99SBarry Smith ii = 0; 54647c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 54747c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 54847c6ae99SBarry Smith for (k=0; k<nc; k++) { 54947c6ae99SBarry Smith colors[ii++] = k + nc*((3*j+i) % 5); 55047c6ae99SBarry Smith } 55147c6ae99SBarry Smith } 55247c6ae99SBarry Smith } 55347c6ae99SBarry Smith ncolors = 5*nc; 554aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 55547c6ae99SBarry Smith } 55647c6ae99SBarry Smith *coloring = dd->localcoloring; 5575bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 55847c6ae99SBarry Smith if (!dd->ghostedcoloring) { 559785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny,&colors);CHKERRQ(ierr); 56047c6ae99SBarry Smith ii = 0; 56147c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 56247c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 56347c6ae99SBarry Smith for (k=0; k<nc; k++) { 56447c6ae99SBarry Smith colors[ii++] = k + nc*((3*SetInRange(j,n) + SetInRange(i,m)) % 5); 56547c6ae99SBarry Smith } 56647c6ae99SBarry Smith } 56747c6ae99SBarry Smith } 56847c6ae99SBarry Smith ncolors = 5*nc; 569aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 5705bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 57147c6ae99SBarry Smith } 57247c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 573ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 57447c6ae99SBarry Smith PetscFunctionReturn(0); 57547c6ae99SBarry Smith } 57647c6ae99SBarry Smith 57747c6ae99SBarry Smith /* =========================================================================== */ 578950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ(DM,Mat); 579ce308e1dSBarry Smith extern PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ_Fill(DM,Mat); 580950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ(DM,Mat); 581950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ_Fill(DM,Mat); 582950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ(DM,Mat); 583950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ_Fill(DM,Mat); 584950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIBAIJ(DM,Mat); 585950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIBAIJ(DM,Mat); 586950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPISBAIJ(DM,Mat); 587950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPISBAIJ(DM,Mat); 588d4002b98SHong Zhang extern PetscErrorCode DMCreateMatrix_DA_2d_MPISELL(DM,Mat); 589d4002b98SHong Zhang extern PetscErrorCode DMCreateMatrix_DA_3d_MPISELL(DM,Mat); 590e584696dSStefano Zampini extern PetscErrorCode DMCreateMatrix_DA_IS(DM,Mat); 59147c6ae99SBarry Smith 5928bbdbebaSMatthew G Knepley /*@C 593c688c046SMatthew G Knepley MatSetupDM - Sets the DMDA that is to be used by the HYPRE_StructMatrix PETSc matrix 59447c6ae99SBarry Smith 59547c6ae99SBarry Smith Logically Collective on Mat 59647c6ae99SBarry Smith 59747c6ae99SBarry Smith Input Parameters: 59847c6ae99SBarry Smith + mat - the matrix 59947c6ae99SBarry Smith - da - the da 60047c6ae99SBarry Smith 60147c6ae99SBarry Smith Level: intermediate 60247c6ae99SBarry Smith 60347c6ae99SBarry Smith @*/ 604c688c046SMatthew G Knepley PetscErrorCode MatSetupDM(Mat mat,DM da) 60547c6ae99SBarry Smith { 60647c6ae99SBarry Smith PetscErrorCode ierr; 60747c6ae99SBarry Smith 60847c6ae99SBarry Smith PetscFunctionBegin; 60947c6ae99SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 610a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 611c688c046SMatthew G Knepley ierr = PetscTryMethod(mat,"MatSetupDM_C",(Mat,DM),(mat,da));CHKERRQ(ierr); 61247c6ae99SBarry Smith PetscFunctionReturn(0); 61347c6ae99SBarry Smith } 61447c6ae99SBarry Smith 6157087cfbeSBarry Smith PetscErrorCode MatView_MPI_DA(Mat A,PetscViewer viewer) 61647c6ae99SBarry Smith { 6179a42bb27SBarry Smith DM da; 61847c6ae99SBarry Smith PetscErrorCode ierr; 61947c6ae99SBarry Smith const char *prefix; 62047c6ae99SBarry Smith Mat Anatural; 62147c6ae99SBarry Smith AO ao; 62247c6ae99SBarry Smith PetscInt rstart,rend,*petsc,i; 62347c6ae99SBarry Smith IS is; 62447c6ae99SBarry Smith MPI_Comm comm; 62574388724SJed Brown PetscViewerFormat format; 62647c6ae99SBarry Smith 62747c6ae99SBarry Smith PetscFunctionBegin; 62874388724SJed Brown /* Check whether we are just printing info, in which case MatView() already viewed everything we wanted to view */ 62974388724SJed Brown ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 63074388724SJed Brown if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 63174388724SJed Brown 63247c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 633c688c046SMatthew G Knepley ierr = MatGetDM(A, &da);CHKERRQ(ierr); 634ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix not generated from a DMDA"); 63547c6ae99SBarry Smith 636aa219208SBarry Smith ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); 63747c6ae99SBarry Smith ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 638854ce69bSBarry Smith ierr = PetscMalloc1(rend-rstart,&petsc);CHKERRQ(ierr); 63947c6ae99SBarry Smith for (i=rstart; i<rend; i++) petsc[i-rstart] = i; 64047c6ae99SBarry Smith ierr = AOApplicationToPetsc(ao,rend-rstart,petsc);CHKERRQ(ierr); 64147c6ae99SBarry Smith ierr = ISCreateGeneral(comm,rend-rstart,petsc,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 64247c6ae99SBarry Smith 64347c6ae99SBarry Smith /* call viewer on natural ordering */ 6447dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,is,is,MAT_INITIAL_MATRIX,&Anatural);CHKERRQ(ierr); 645fcfd50ebSBarry Smith ierr = ISDestroy(&is);CHKERRQ(ierr); 64647c6ae99SBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)A,&prefix);CHKERRQ(ierr); 64747c6ae99SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)Anatural,prefix);CHKERRQ(ierr); 64847c6ae99SBarry Smith ierr = PetscObjectSetName((PetscObject)Anatural,((PetscObject)A)->name);CHKERRQ(ierr); 649539c167fSBarry Smith ierr = MatView(Anatural,viewer);CHKERRQ(ierr); 650fcfd50ebSBarry Smith ierr = MatDestroy(&Anatural);CHKERRQ(ierr); 65147c6ae99SBarry Smith PetscFunctionReturn(0); 65247c6ae99SBarry Smith } 65347c6ae99SBarry Smith 6547087cfbeSBarry Smith PetscErrorCode MatLoad_MPI_DA(Mat A,PetscViewer viewer) 65547c6ae99SBarry Smith { 6569a42bb27SBarry Smith DM da; 65747c6ae99SBarry Smith PetscErrorCode ierr; 65847c6ae99SBarry Smith Mat Anatural,Aapp; 65947c6ae99SBarry Smith AO ao; 660539c167fSBarry Smith PetscInt rstart,rend,*app,i,m,n,M,N; 66147c6ae99SBarry Smith IS is; 66247c6ae99SBarry Smith MPI_Comm comm; 66347c6ae99SBarry Smith 66447c6ae99SBarry Smith PetscFunctionBegin; 66547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 666c688c046SMatthew G Knepley ierr = MatGetDM(A, &da);CHKERRQ(ierr); 667ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix not generated from a DMDA"); 66847c6ae99SBarry Smith 66947c6ae99SBarry Smith /* Load the matrix in natural ordering */ 670ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Anatural);CHKERRQ(ierr); 67147c6ae99SBarry Smith ierr = MatSetType(Anatural,((PetscObject)A)->type_name);CHKERRQ(ierr); 672539c167fSBarry Smith ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 673539c167fSBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 674539c167fSBarry Smith ierr = MatSetSizes(Anatural,m,n,M,N);CHKERRQ(ierr); 67547c6ae99SBarry Smith ierr = MatLoad(Anatural,viewer);CHKERRQ(ierr); 67647c6ae99SBarry Smith 67747c6ae99SBarry Smith /* Map natural ordering to application ordering and create IS */ 678aa219208SBarry Smith ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); 67947c6ae99SBarry Smith ierr = MatGetOwnershipRange(Anatural,&rstart,&rend);CHKERRQ(ierr); 680854ce69bSBarry Smith ierr = PetscMalloc1(rend-rstart,&app);CHKERRQ(ierr); 68147c6ae99SBarry Smith for (i=rstart; i<rend; i++) app[i-rstart] = i; 68247c6ae99SBarry Smith ierr = AOPetscToApplication(ao,rend-rstart,app);CHKERRQ(ierr); 68347c6ae99SBarry Smith ierr = ISCreateGeneral(comm,rend-rstart,app,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 68447c6ae99SBarry Smith 68547c6ae99SBarry Smith /* Do permutation and replace header */ 6867dae84e0SHong Zhang ierr = MatCreateSubMatrix(Anatural,is,is,MAT_INITIAL_MATRIX,&Aapp);CHKERRQ(ierr); 68728be2f97SBarry Smith ierr = MatHeaderReplace(A,&Aapp);CHKERRQ(ierr); 688fcfd50ebSBarry Smith ierr = ISDestroy(&is);CHKERRQ(ierr); 689fcfd50ebSBarry Smith ierr = MatDestroy(&Anatural);CHKERRQ(ierr); 69047c6ae99SBarry Smith PetscFunctionReturn(0); 69147c6ae99SBarry Smith } 69247c6ae99SBarry Smith 693b412c318SBarry Smith PetscErrorCode DMCreateMatrix_DA(DM da, Mat *J) 69447c6ae99SBarry Smith { 69547c6ae99SBarry Smith PetscErrorCode ierr; 69647c6ae99SBarry Smith PetscInt dim,dof,nx,ny,nz,dims[3],starts[3],M,N,P; 69747c6ae99SBarry Smith Mat A; 69847c6ae99SBarry Smith MPI_Comm comm; 69919fd82e9SBarry Smith MatType Atype; 70037d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 701e584696dSStefano Zampini void (*aij)(void)=NULL,(*baij)(void)=NULL,(*sbaij)(void)=NULL,(*sell)(void)=NULL,(*is)(void)=NULL; 702b412c318SBarry Smith MatType mtype; 70347c6ae99SBarry Smith PetscMPIInt size; 70447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 70547c6ae99SBarry Smith 70647c6ae99SBarry Smith PetscFunctionBegin; 707607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 708b412c318SBarry Smith mtype = da->mattype; 70947c6ae99SBarry Smith 71037d0c07bSMatthew G Knepley ierr = DMGetDefaultSection(da, §ion);CHKERRQ(ierr); 71137d0c07bSMatthew G Knepley if (section) { 71237d0c07bSMatthew G Knepley PetscInt bs = -1; 71337d0c07bSMatthew G Knepley PetscInt localSize; 71437d0c07bSMatthew G Knepley PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isSymmetric; 71537d0c07bSMatthew G Knepley 71637d0c07bSMatthew G Knepley ierr = DMGetDefaultGlobalSection(da, §ionGlobal);CHKERRQ(ierr); 71737d0c07bSMatthew G Knepley ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 718b5579763SJed Brown ierr = MatCreate(PetscObjectComm((PetscObject)da),&A);CHKERRQ(ierr); 719b5579763SJed Brown ierr = MatSetSizes(A,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 720b5579763SJed Brown ierr = MatSetType(A,mtype);CHKERRQ(ierr); 72137d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSHELL,&isShell);CHKERRQ(ierr); 72237d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATBAIJ,&isBlock);CHKERRQ(ierr); 72337d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSEQBAIJ,&isSeqBlock);CHKERRQ(ierr); 72437d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATMPIBAIJ,&isMPIBlock);CHKERRQ(ierr); 72537d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSBAIJ,&isSymBlock);CHKERRQ(ierr); 72637d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSEQSBAIJ,&isSymSeqBlock);CHKERRQ(ierr); 72737d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATMPISBAIJ,&isSymMPIBlock);CHKERRQ(ierr); 72837d0c07bSMatthew G Knepley /* Check for symmetric storage */ 72937d0c07bSMatthew G Knepley isSymmetric = (PetscBool) (isSymBlock || isSymSeqBlock || isSymMPIBlock); 73037d0c07bSMatthew G Knepley if (isSymmetric) { 73137d0c07bSMatthew G Knepley ierr = MatSetOption(*J, MAT_IGNORE_LOWER_TRIANGULAR, PETSC_TRUE);CHKERRQ(ierr); 73237d0c07bSMatthew G Knepley } 73337d0c07bSMatthew G Knepley if (!isShell) { 73437d0c07bSMatthew G Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal; 73537d0c07bSMatthew G Knepley 73637d0c07bSMatthew G Knepley if (bs < 0) { 73737d0c07bSMatthew G Knepley if (isBlock || isSeqBlock || isMPIBlock || isSymBlock || isSymSeqBlock || isSymMPIBlock) { 73837d0c07bSMatthew G Knepley PetscInt pStart, pEnd, p, dof; 73937d0c07bSMatthew G Knepley 74037d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 74137d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 74237d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 74337d0c07bSMatthew G Knepley if (dof) { 74437d0c07bSMatthew G Knepley bs = dof; 74537d0c07bSMatthew G Knepley break; 74637d0c07bSMatthew G Knepley } 74737d0c07bSMatthew G Knepley } 74837d0c07bSMatthew G Knepley } else { 74937d0c07bSMatthew G Knepley bs = 1; 75037d0c07bSMatthew G Knepley } 75137d0c07bSMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 75237d0c07bSMatthew G Knepley bsLocal = bs; 753b2566f29SBarry Smith ierr = MPIU_Allreduce(&bsLocal, &bs, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)da));CHKERRQ(ierr); 75437d0c07bSMatthew G Knepley } 7551795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 756552f7358SJed Brown /* ierr = DMPlexPreallocateOperator(dm, bs, section, sectionGlobal, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); */ 75737d0c07bSMatthew G Knepley ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 75837d0c07bSMatthew G Knepley } 75937d0c07bSMatthew G Knepley } 76047c6ae99SBarry Smith /* 76147c6ae99SBarry Smith m 76247c6ae99SBarry Smith ------------------------------------------------------ 76347c6ae99SBarry Smith | | 76447c6ae99SBarry Smith | | 76547c6ae99SBarry Smith | ---------------------- | 76647c6ae99SBarry Smith | | | | 76747c6ae99SBarry Smith n | ny | | | 76847c6ae99SBarry Smith | | | | 76947c6ae99SBarry Smith | .--------------------- | 77047c6ae99SBarry Smith | (xs,ys) nx | 77147c6ae99SBarry Smith | . | 77247c6ae99SBarry Smith | (gxs,gys) | 77347c6ae99SBarry Smith | | 77447c6ae99SBarry Smith ----------------------------------------------------- 77547c6ae99SBarry Smith */ 77647c6ae99SBarry Smith 77747c6ae99SBarry Smith /* 77847c6ae99SBarry Smith nc - number of components per grid point 77947c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 78047c6ae99SBarry Smith 78147c6ae99SBarry Smith */ 782e30e807fSPeter Brune M = dd->M; 783e30e807fSPeter Brune N = dd->N; 784e30e807fSPeter Brune P = dd->P; 785c73cfb54SMatthew G. Knepley dim = da->dim; 786e30e807fSPeter Brune dof = dd->w; 787e30e807fSPeter Brune /* ierr = DMDAGetInfo(da,&dim,&M,&N,&P,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); */ 788aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&nx,&ny,&nz);CHKERRQ(ierr); 78947c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 79047c6ae99SBarry Smith ierr = MatCreate(comm,&A);CHKERRQ(ierr); 79147c6ae99SBarry Smith ierr = MatSetSizes(A,dof*nx*ny*nz,dof*nx*ny*nz,dof*M*N*P,dof*M*N*P);CHKERRQ(ierr); 792b412c318SBarry Smith ierr = MatSetType(A,mtype);CHKERRQ(ierr); 79395ee5b0eSBarry Smith ierr = MatSetDM(A,da);CHKERRQ(ierr); 794b06ff27eSHong Zhang if (da->structure_only) { 795b06ff27eSHong Zhang ierr = MatSetOption(A,MAT_STRUCTURE_ONLY,PETSC_TRUE);CHKERRQ(ierr); 796b06ff27eSHong Zhang } 79747c6ae99SBarry Smith ierr = MatGetType(A,&Atype);CHKERRQ(ierr); 79847c6ae99SBarry Smith /* 799aa219208SBarry Smith We do not provide a getmatrix function in the DMDA operations because 800aa219208SBarry Smith the basic DMDA does not know about matrices. We think of DMDA as being more 80147c6ae99SBarry Smith more low-level than matrices. This is kind of cheating but, cause sometimes 802aa219208SBarry Smith we think of DMDA has higher level than matrices. 80347c6ae99SBarry Smith 80447c6ae99SBarry Smith We could switch based on Atype (or mtype), but we do not since the 80547c6ae99SBarry Smith specialized setting routines depend only the particular preallocation 80647c6ae99SBarry Smith details of the matrix, not the type itself. 80747c6ae99SBarry Smith */ 80847c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 80947c6ae99SBarry Smith if (!aij) { 81047c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 81147c6ae99SBarry Smith } 81247c6ae99SBarry Smith if (!aij) { 81347c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIBAIJSetPreallocation_C",&baij);CHKERRQ(ierr); 81447c6ae99SBarry Smith if (!baij) { 81547c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqBAIJSetPreallocation_C",&baij);CHKERRQ(ierr); 81647c6ae99SBarry Smith } 81747c6ae99SBarry Smith if (!baij) { 81847c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPISBAIJSetPreallocation_C",&sbaij);CHKERRQ(ierr); 81947c6ae99SBarry Smith if (!sbaij) { 82047c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C",&sbaij);CHKERRQ(ierr); 82147c6ae99SBarry Smith } 8225e26d47bSHong Zhang if (!sbaij) { 823d4002b98SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPISELLSetPreallocation_C",&sell);CHKERRQ(ierr); 824d4002b98SHong Zhang if (!sell) { 825d4002b98SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqSELLSetPreallocation_C",&sell);CHKERRQ(ierr); 8265e26d47bSHong Zhang } 8275e26d47bSHong Zhang } 828e584696dSStefano Zampini if (!sell) { 829e584696dSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)A,"MatISSetPreallocation_C",&is);CHKERRQ(ierr); 830e584696dSStefano Zampini } 83147c6ae99SBarry Smith } 83247c6ae99SBarry Smith } 83347c6ae99SBarry Smith if (aij) { 83447c6ae99SBarry Smith if (dim == 1) { 835ce308e1dSBarry Smith if (dd->ofill) { 836ce308e1dSBarry Smith ierr = DMCreateMatrix_DA_1d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 837ce308e1dSBarry Smith } else { 838950540a4SJed Brown ierr = DMCreateMatrix_DA_1d_MPIAIJ(da,A);CHKERRQ(ierr); 839ce308e1dSBarry Smith } 84047c6ae99SBarry Smith } else if (dim == 2) { 84147c6ae99SBarry Smith if (dd->ofill) { 842950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 84347c6ae99SBarry Smith } else { 844950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIAIJ(da,A);CHKERRQ(ierr); 84547c6ae99SBarry Smith } 84647c6ae99SBarry Smith } else if (dim == 3) { 84747c6ae99SBarry Smith if (dd->ofill) { 848950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 84947c6ae99SBarry Smith } else { 850950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIAIJ(da,A);CHKERRQ(ierr); 85147c6ae99SBarry Smith } 85247c6ae99SBarry Smith } 85347c6ae99SBarry Smith } else if (baij) { 85447c6ae99SBarry Smith if (dim == 2) { 855950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIBAIJ(da,A);CHKERRQ(ierr); 85647c6ae99SBarry Smith } else if (dim == 3) { 857950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIBAIJ(da,A);CHKERRQ(ierr); 858ce94432eSBarry 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); 85947c6ae99SBarry Smith } else if (sbaij) { 86047c6ae99SBarry Smith if (dim == 2) { 861950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPISBAIJ(da,A);CHKERRQ(ierr); 86247c6ae99SBarry Smith } else if (dim == 3) { 863950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPISBAIJ(da,A);CHKERRQ(ierr); 864ce94432eSBarry 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); 865d4002b98SHong Zhang } else if (sell) { 8665e26d47bSHong Zhang if (dim == 2) { 867d4002b98SHong Zhang ierr = DMCreateMatrix_DA_2d_MPISELL(da,A);CHKERRQ(ierr); 868711261dbSHong Zhang } else if (dim == 3) { 869d4002b98SHong Zhang ierr = DMCreateMatrix_DA_3d_MPISELL(da,A);CHKERRQ(ierr); 8705e26d47bSHong 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); 871e584696dSStefano Zampini } else if (is) { 872e584696dSStefano Zampini ierr = DMCreateMatrix_DA_IS(da,A);CHKERRQ(ierr); 873869776cdSLisandro Dalcin } else { 87445b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 875e584696dSStefano Zampini 876b026d285SBarry Smith ierr = MatSetBlockSize(A,dof);CHKERRQ(ierr); 8772949035bSJed Brown ierr = MatSetUp(A);CHKERRQ(ierr); 878b026d285SBarry Smith ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 879869776cdSLisandro Dalcin ierr = MatSetLocalToGlobalMapping(A,ltog,ltog);CHKERRQ(ierr); 88047c6ae99SBarry Smith } 881aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&starts[0],&starts[1],&starts[2],&dims[0],&dims[1],&dims[2]);CHKERRQ(ierr); 88247c6ae99SBarry Smith ierr = MatSetStencil(A,dim,dims,starts,dof);CHKERRQ(ierr); 883c688c046SMatthew G Knepley ierr = MatSetDM(A,da);CHKERRQ(ierr); 88447c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 88547c6ae99SBarry Smith if (size > 1) { 88647c6ae99SBarry Smith /* change viewer to display matrix in natural ordering */ 8870c0fd78eSBarry Smith ierr = MatSetOperation(A, MATOP_VIEW, (void (*)(void))MatView_MPI_DA);CHKERRQ(ierr); 8880c0fd78eSBarry Smith ierr = MatSetOperation(A, MATOP_LOAD, (void (*)(void))MatLoad_MPI_DA);CHKERRQ(ierr); 88947c6ae99SBarry Smith } 890b5579763SJed Brown ierr = MatSetFromOptions(A);CHKERRQ(ierr); 89147c6ae99SBarry Smith *J = A; 89247c6ae99SBarry Smith PetscFunctionReturn(0); 89347c6ae99SBarry Smith } 89447c6ae99SBarry Smith 89547c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 896e584696dSStefano Zampini PetscErrorCode DMCreateMatrix_DA_IS(DM dm,Mat J) 897e584696dSStefano Zampini { 898e584696dSStefano Zampini DM_DA *da = (DM_DA*)dm->data; 899e584696dSStefano Zampini Mat lJ; 900e584696dSStefano Zampini ISLocalToGlobalMapping ltog; 901e584696dSStefano Zampini IS is_loc_filt, is_glob; 90205339c03SStefano Zampini const PetscInt *e_loc,*idx; 90305339c03SStefano Zampini PetscInt i,nel,nen,dnz,nv,dof,dim,*gidx,nb; 904e584696dSStefano Zampini PetscErrorCode ierr; 905e584696dSStefano Zampini 906e584696dSStefano Zampini /* The l2g map of DMDA has all ghosted nodes, and e_loc is a subset of all the local nodes (including the ghosted) 907e584696dSStefano Zampini We need to filter the local indices that are represented through the DMDAGetElements decomposition 908e584696dSStefano Zampini This is because the size of the local matrices in MATIS is the local size of the l2g map */ 909e584696dSStefano Zampini PetscFunctionBegin; 910e584696dSStefano Zampini dof = da->w; 911e584696dSStefano Zampini dim = dm->dim; 91205339c03SStefano Zampini 91305339c03SStefano Zampini ierr = MatSetBlockSize(J,dof);CHKERRQ(ierr); 91405339c03SStefano Zampini 91505339c03SStefano Zampini /* get local elements indices in local DMDA numbering */ 916e584696dSStefano Zampini ierr = DMDAGetElements(dm,&nel,&nen,&e_loc);CHKERRQ(ierr); /* this will throw an error if the stencil type is not DMDA_STENCIL_BOX */ 917e584696dSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)dm),dof,nel*nen,e_loc,PETSC_COPY_VALUES,&is_loc_filt);CHKERRQ(ierr); 918e584696dSStefano Zampini ierr = DMDARestoreElements(dm,&nel,&nen,&e_loc);CHKERRQ(ierr); 91905339c03SStefano Zampini 92005339c03SStefano Zampini /* obtain a consistent local ordering for MATIS */ 921e584696dSStefano Zampini ierr = ISSortRemoveDups(is_loc_filt);CHKERRQ(ierr); 92205339c03SStefano Zampini ierr = ISBlockGetLocalSize(is_loc_filt,&nb);CHKERRQ(ierr); 92305339c03SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 92405339c03SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(ltog,&nv);CHKERRQ(ierr); 92505339c03SStefano Zampini ierr = PetscMalloc1(PetscMax(nb,nv/dof),&gidx);CHKERRQ(ierr); 92605339c03SStefano Zampini ierr = ISBlockGetIndices(is_loc_filt,&idx);CHKERRQ(ierr); 92705339c03SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(ltog,nb,idx,gidx);CHKERRQ(ierr); 92805339c03SStefano Zampini ierr = ISBlockRestoreIndices(is_loc_filt,&idx);CHKERRQ(ierr); 92905339c03SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)dm),dof,nb,gidx,PETSC_USE_POINTER,&is_glob);CHKERRQ(ierr); 930e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_glob,<og);CHKERRQ(ierr); 931e584696dSStefano Zampini ierr = ISDestroy(&is_glob);CHKERRQ(ierr); 932e584696dSStefano Zampini ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 933e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 93405339c03SStefano Zampini 935e584696dSStefano Zampini /* We also attach a l2g map to the local matrices to have MatSetValueLocal to work */ 936e584696dSStefano Zampini ierr = MatISGetLocalMat(J,&lJ);CHKERRQ(ierr); 937e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_loc_filt,<og);CHKERRQ(ierr); 938e584696dSStefano Zampini ierr = ISDestroy(&is_loc_filt);CHKERRQ(ierr); 93905339c03SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)lJ),nv/dof,0,1,&is_glob);CHKERRQ(ierr); 94005339c03SStefano Zampini ierr = ISGetIndices(is_glob,&idx);CHKERRQ(ierr); 94105339c03SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(ltog,IS_GTOLM_MASK,nv/dof,idx,&nb,gidx);CHKERRQ(ierr); 94205339c03SStefano Zampini ierr = ISRestoreIndices(is_glob,&idx);CHKERRQ(ierr); 943e584696dSStefano Zampini ierr = ISDestroy(&is_glob);CHKERRQ(ierr); 944e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 945722d6fa8SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,dof,nb,gidx,PETSC_USE_POINTER,&is_loc_filt);CHKERRQ(ierr); 946e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_loc_filt,<og);CHKERRQ(ierr); 947e584696dSStefano Zampini ierr = ISDestroy(&is_loc_filt);CHKERRQ(ierr); 948e584696dSStefano Zampini ierr = MatSetLocalToGlobalMapping(lJ,ltog,ltog);CHKERRQ(ierr); 949e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 95005339c03SStefano Zampini ierr = PetscFree(gidx);CHKERRQ(ierr); 95105339c03SStefano Zampini 952e584696dSStefano Zampini /* Preallocation (not exact) */ 953e584696dSStefano Zampini switch (da->elementtype) { 954e584696dSStefano Zampini case DMDA_ELEMENT_P1: 955e584696dSStefano Zampini case DMDA_ELEMENT_Q1: 956e584696dSStefano Zampini dnz = 1; 957e584696dSStefano Zampini for (i=0; i<dim; i++) dnz *= 3; 958e584696dSStefano Zampini dnz *= dof; 959e584696dSStefano Zampini break; 960e584696dSStefano Zampini default: 961e584696dSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Unhandled element type %d",da->elementtype); 962e584696dSStefano Zampini break; 963e584696dSStefano Zampini } 964e584696dSStefano Zampini ierr = MatSeqAIJSetPreallocation(lJ,dnz,NULL);CHKERRQ(ierr); 965e584696dSStefano Zampini ierr = MatSeqBAIJSetPreallocation(lJ,dof,dnz/dof,NULL);CHKERRQ(ierr); 966e584696dSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(lJ,dof,dnz/dof,NULL);CHKERRQ(ierr); 967e584696dSStefano Zampini ierr = MatISRestoreLocalMat(J,&lJ);CHKERRQ(ierr); 968e584696dSStefano Zampini PetscFunctionReturn(0); 969e584696dSStefano Zampini } 970e584696dSStefano Zampini 971d4002b98SHong Zhang PetscErrorCode DMCreateMatrix_DA_2d_MPISELL(DM da,Mat J) 9725e26d47bSHong Zhang { 9735e26d47bSHong Zhang PetscErrorCode ierr; 9745e26d47bSHong 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; 9755e26d47bSHong Zhang PetscInt lstart,lend,pstart,pend,*dnz,*onz; 9765e26d47bSHong Zhang MPI_Comm comm; 9775e26d47bSHong Zhang PetscScalar *values; 9785e26d47bSHong Zhang DMBoundaryType bx,by; 9795e26d47bSHong Zhang ISLocalToGlobalMapping ltog; 9805e26d47bSHong Zhang DMDAStencilType st; 9815e26d47bSHong Zhang 9825e26d47bSHong Zhang PetscFunctionBegin; 9835e26d47bSHong Zhang /* 9845e26d47bSHong Zhang nc - number of components per grid point 9855e26d47bSHong Zhang col - number of colors needed in one direction for single component problem 9865e26d47bSHong Zhang 9875e26d47bSHong Zhang */ 9885e26d47bSHong Zhang ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 9895e26d47bSHong Zhang col = 2*s + 1; 9905e26d47bSHong Zhang ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 9915e26d47bSHong Zhang ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 9925e26d47bSHong Zhang ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 9935e26d47bSHong Zhang 9945e26d47bSHong Zhang ierr = PetscMalloc2(nc,&rows,col*col*nc*nc,&cols);CHKERRQ(ierr); 9955e26d47bSHong Zhang ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 9965e26d47bSHong Zhang 9975e26d47bSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 9985e26d47bSHong Zhang /* determine the matrix preallocation information */ 9995e26d47bSHong Zhang ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 10005e26d47bSHong Zhang for (i=xs; i<xs+nx; i++) { 10015e26d47bSHong Zhang 10025e26d47bSHong Zhang pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 10035e26d47bSHong Zhang pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 10045e26d47bSHong Zhang 10055e26d47bSHong Zhang for (j=ys; j<ys+ny; j++) { 10065e26d47bSHong Zhang slot = i - gxs + gnx*(j - gys); 10075e26d47bSHong Zhang 10085e26d47bSHong Zhang lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 10095e26d47bSHong Zhang lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 10105e26d47bSHong Zhang 10115e26d47bSHong Zhang cnt = 0; 10125e26d47bSHong Zhang for (k=0; k<nc; k++) { 10135e26d47bSHong Zhang for (l=lstart; l<lend+1; l++) { 10145e26d47bSHong Zhang for (p=pstart; p<pend+1; p++) { 10155e26d47bSHong Zhang if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 10165e26d47bSHong Zhang cols[cnt++] = k + nc*(slot + gnx*l + p); 10175e26d47bSHong Zhang } 10185e26d47bSHong Zhang } 10195e26d47bSHong Zhang } 10205e26d47bSHong Zhang rows[k] = k + nc*(slot); 10215e26d47bSHong Zhang } 10225e26d47bSHong Zhang ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 10235e26d47bSHong Zhang } 10245e26d47bSHong Zhang } 10255e26d47bSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 1026d4002b98SHong Zhang ierr = MatSeqSELLSetPreallocation(J,0,dnz);CHKERRQ(ierr); 1027d4002b98SHong Zhang ierr = MatMPISELLSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 10285e26d47bSHong Zhang ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 10295e26d47bSHong Zhang 10305e26d47bSHong Zhang ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 10315e26d47bSHong Zhang 10325e26d47bSHong Zhang /* 10335e26d47bSHong Zhang For each node in the grid: we get the neighbors in the local (on processor ordering 10345e26d47bSHong Zhang that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 10355e26d47bSHong Zhang PETSc ordering. 10365e26d47bSHong Zhang */ 10375e26d47bSHong Zhang if (!da->prealloc_only) { 10385e26d47bSHong Zhang ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 10395e26d47bSHong Zhang for (i=xs; i<xs+nx; i++) { 10405e26d47bSHong Zhang 10415e26d47bSHong Zhang pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 10425e26d47bSHong Zhang pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 10435e26d47bSHong Zhang 10445e26d47bSHong Zhang for (j=ys; j<ys+ny; j++) { 10455e26d47bSHong Zhang slot = i - gxs + gnx*(j - gys); 10465e26d47bSHong Zhang 10475e26d47bSHong Zhang lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 10485e26d47bSHong Zhang lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 10495e26d47bSHong Zhang 10505e26d47bSHong Zhang cnt = 0; 10515e26d47bSHong Zhang for (k=0; k<nc; k++) { 10525e26d47bSHong Zhang for (l=lstart; l<lend+1; l++) { 10535e26d47bSHong Zhang for (p=pstart; p<pend+1; p++) { 10545e26d47bSHong Zhang if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 10555e26d47bSHong Zhang cols[cnt++] = k + nc*(slot + gnx*l + p); 10565e26d47bSHong Zhang } 10575e26d47bSHong Zhang } 10585e26d47bSHong Zhang } 10595e26d47bSHong Zhang rows[k] = k + nc*(slot); 10605e26d47bSHong Zhang } 10615e26d47bSHong Zhang ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 10625e26d47bSHong Zhang } 10635e26d47bSHong Zhang } 10645e26d47bSHong Zhang ierr = PetscFree(values);CHKERRQ(ierr); 10655e26d47bSHong Zhang ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10665e26d47bSHong Zhang ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10675e26d47bSHong Zhang ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 10685e26d47bSHong Zhang } 10695e26d47bSHong Zhang ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 10705e26d47bSHong Zhang PetscFunctionReturn(0); 10715e26d47bSHong Zhang } 10725e26d47bSHong Zhang 1073d4002b98SHong Zhang PetscErrorCode DMCreateMatrix_DA_3d_MPISELL(DM da,Mat J) 1074711261dbSHong Zhang { 1075711261dbSHong Zhang PetscErrorCode ierr; 1076711261dbSHong Zhang PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 1077711261dbSHong Zhang PetscInt m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p,*dnz = NULL,*onz = NULL; 1078711261dbSHong Zhang PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 1079711261dbSHong Zhang MPI_Comm comm; 1080711261dbSHong Zhang PetscScalar *values; 1081711261dbSHong Zhang DMBoundaryType bx,by,bz; 1082711261dbSHong Zhang ISLocalToGlobalMapping ltog; 1083711261dbSHong Zhang DMDAStencilType st; 1084711261dbSHong Zhang 1085711261dbSHong Zhang PetscFunctionBegin; 1086711261dbSHong Zhang /* 1087711261dbSHong Zhang nc - number of components per grid point 1088711261dbSHong Zhang col - number of colors needed in one direction for single component problem 1089711261dbSHong Zhang 1090711261dbSHong Zhang */ 1091711261dbSHong Zhang ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 1092711261dbSHong Zhang col = 2*s + 1; 1093711261dbSHong Zhang ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1094711261dbSHong Zhang ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 1095711261dbSHong Zhang ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 1096711261dbSHong Zhang 1097711261dbSHong Zhang ierr = PetscMalloc2(nc,&rows,col*col*col*nc*nc,&cols);CHKERRQ(ierr); 1098711261dbSHong Zhang ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1099711261dbSHong Zhang 1100711261dbSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 1101711261dbSHong Zhang /* determine the matrix preallocation information */ 1102711261dbSHong Zhang ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 1103711261dbSHong Zhang for (i=xs; i<xs+nx; i++) { 1104711261dbSHong Zhang istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1105711261dbSHong Zhang iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 1106711261dbSHong Zhang for (j=ys; j<ys+ny; j++) { 1107711261dbSHong Zhang jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1108711261dbSHong Zhang jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 1109711261dbSHong Zhang for (k=zs; k<zs+nz; k++) { 1110711261dbSHong Zhang kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1111711261dbSHong Zhang kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 1112711261dbSHong Zhang 1113711261dbSHong Zhang slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 1114711261dbSHong Zhang 1115711261dbSHong Zhang cnt = 0; 1116711261dbSHong Zhang for (l=0; l<nc; l++) { 1117711261dbSHong Zhang for (ii=istart; ii<iend+1; ii++) { 1118711261dbSHong Zhang for (jj=jstart; jj<jend+1; jj++) { 1119711261dbSHong Zhang for (kk=kstart; kk<kend+1; kk++) { 1120711261dbSHong Zhang if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 1121711261dbSHong Zhang cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 1122711261dbSHong Zhang } 1123711261dbSHong Zhang } 1124711261dbSHong Zhang } 1125711261dbSHong Zhang } 1126711261dbSHong Zhang rows[l] = l + nc*(slot); 1127711261dbSHong Zhang } 1128711261dbSHong Zhang ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1129711261dbSHong Zhang } 1130711261dbSHong Zhang } 1131711261dbSHong Zhang } 1132711261dbSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 1133d4002b98SHong Zhang ierr = MatSeqSELLSetPreallocation(J,0,dnz);CHKERRQ(ierr); 1134d4002b98SHong Zhang ierr = MatMPISELLSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 1135711261dbSHong Zhang ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1136711261dbSHong Zhang ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 1137711261dbSHong Zhang 1138711261dbSHong Zhang /* 1139711261dbSHong Zhang For each node in the grid: we get the neighbors in the local (on processor ordering 1140711261dbSHong Zhang that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 1141711261dbSHong Zhang PETSc ordering. 1142711261dbSHong Zhang */ 1143711261dbSHong Zhang if (!da->prealloc_only) { 1144711261dbSHong Zhang ierr = PetscCalloc1(col*col*col*nc*nc*nc,&values);CHKERRQ(ierr); 1145711261dbSHong Zhang for (i=xs; i<xs+nx; i++) { 1146711261dbSHong Zhang istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1147711261dbSHong Zhang iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 1148711261dbSHong Zhang for (j=ys; j<ys+ny; j++) { 1149711261dbSHong Zhang jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1150711261dbSHong Zhang jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 1151711261dbSHong Zhang for (k=zs; k<zs+nz; k++) { 1152711261dbSHong Zhang kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1153711261dbSHong Zhang kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 1154711261dbSHong Zhang 1155711261dbSHong Zhang slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 1156711261dbSHong Zhang 1157711261dbSHong Zhang cnt = 0; 1158711261dbSHong Zhang for (l=0; l<nc; l++) { 1159711261dbSHong Zhang for (ii=istart; ii<iend+1; ii++) { 1160711261dbSHong Zhang for (jj=jstart; jj<jend+1; jj++) { 1161711261dbSHong Zhang for (kk=kstart; kk<kend+1; kk++) { 1162711261dbSHong Zhang if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 1163711261dbSHong Zhang cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 1164711261dbSHong Zhang } 1165711261dbSHong Zhang } 1166711261dbSHong Zhang } 1167711261dbSHong Zhang } 1168711261dbSHong Zhang rows[l] = l + nc*(slot); 1169711261dbSHong Zhang } 1170711261dbSHong Zhang ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1171711261dbSHong Zhang } 1172711261dbSHong Zhang } 1173711261dbSHong Zhang } 1174711261dbSHong Zhang ierr = PetscFree(values);CHKERRQ(ierr); 1175711261dbSHong Zhang ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1176711261dbSHong Zhang ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1177711261dbSHong Zhang ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 1178711261dbSHong Zhang } 1179711261dbSHong Zhang ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 1180711261dbSHong Zhang PetscFunctionReturn(0); 1181711261dbSHong Zhang } 1182711261dbSHong Zhang 1183950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ(DM da,Mat J) 118447c6ae99SBarry Smith { 118547c6ae99SBarry Smith PetscErrorCode ierr; 1186c1154cd5SBarry 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; 118747c6ae99SBarry Smith PetscInt lstart,lend,pstart,pend,*dnz,*onz; 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 1213dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*col*nc*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 cnt = 0; 123147c6ae99SBarry Smith for (k=0; k<nc; k++) { 123247c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 123347c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 1234aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 123547c6ae99SBarry Smith cols[cnt++] = k + nc*(slot + gnx*l + p); 123647c6ae99SBarry Smith } 123747c6ae99SBarry Smith } 123847c6ae99SBarry Smith } 123947c6ae99SBarry Smith rows[k] = k + nc*(slot); 124047c6ae99SBarry Smith } 1241c1154cd5SBarry Smith if (removedups) { 1242c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1243c1154cd5SBarry Smith } else { 1244784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 124547c6ae99SBarry Smith } 124647c6ae99SBarry Smith } 1247c1154cd5SBarry Smith } 1248f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 124947c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 125047c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 125147c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 125247c6ae99SBarry Smith 1253784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 125447c6ae99SBarry Smith 125547c6ae99SBarry Smith /* 125647c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 125747c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 125847c6ae99SBarry Smith PETSc ordering. 125947c6ae99SBarry Smith */ 1260fcfd50ebSBarry Smith if (!da->prealloc_only) { 12611795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 126247c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 126347c6ae99SBarry Smith 1264bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1265bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 126647c6ae99SBarry Smith 126747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 126847c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 126947c6ae99SBarry Smith 1270bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1271bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 127247c6ae99SBarry Smith 127347c6ae99SBarry Smith cnt = 0; 127447c6ae99SBarry Smith for (k=0; k<nc; k++) { 127547c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 127647c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 1277aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 127847c6ae99SBarry Smith cols[cnt++] = k + nc*(slot + gnx*l + p); 127947c6ae99SBarry Smith } 128047c6ae99SBarry Smith } 128147c6ae99SBarry Smith } 128247c6ae99SBarry Smith rows[k] = k + nc*(slot); 128347c6ae99SBarry Smith } 128447c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 128547c6ae99SBarry Smith } 128647c6ae99SBarry Smith } 128747c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 128847c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 128947c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1290189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 129147c6ae99SBarry Smith } 129247c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 129347c6ae99SBarry Smith PetscFunctionReturn(0); 129447c6ae99SBarry Smith } 129547c6ae99SBarry Smith 1296950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ_Fill(DM da,Mat J) 129747c6ae99SBarry Smith { 129847c6ae99SBarry Smith PetscErrorCode ierr; 129947c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 1300c1154cd5SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,row,col,cnt,maxcnt = 0,l,p,M,N; 130147c6ae99SBarry Smith PetscInt lstart,lend,pstart,pend,*dnz,*onz; 130247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 130347c6ae99SBarry Smith PetscInt ifill_col,*ofill = dd->ofill, *dfill = dd->dfill; 130447c6ae99SBarry Smith MPI_Comm comm; 130547c6ae99SBarry Smith PetscScalar *values; 1306bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 130745b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1308aa219208SBarry Smith DMDAStencilType st; 1309c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 131047c6ae99SBarry Smith 131147c6ae99SBarry Smith PetscFunctionBegin; 131247c6ae99SBarry Smith /* 131347c6ae99SBarry Smith nc - number of components per grid point 131447c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 131547c6ae99SBarry Smith 131647c6ae99SBarry Smith */ 1317c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&M,&N,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 131847c6ae99SBarry Smith col = 2*s + 1; 1319c1154cd5SBarry Smith /* 1320c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1321c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1322c1154cd5SBarry Smith */ 1323c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1324c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1325aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1326aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 132747c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 132847c6ae99SBarry Smith 13294b26d1cfSBarry Smith ierr = PetscMalloc1(col*col*nc,&cols);CHKERRQ(ierr); 13301411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 133147c6ae99SBarry Smith 133206ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 133347c6ae99SBarry Smith /* determine the matrix preallocation information */ 133447c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 133547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 133647c6ae99SBarry Smith 1337bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1338bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 133947c6ae99SBarry Smith 134047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 134147c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 134247c6ae99SBarry Smith 1343bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1344bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 134547c6ae99SBarry Smith 134647c6ae99SBarry Smith for (k=0; k<nc; k++) { 134747c6ae99SBarry Smith cnt = 0; 134847c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 134947c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 135047c6ae99SBarry Smith if (l || p) { 1351aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star */ 13528865f1eaSKarl Rupp for (ifill_col=ofill[k]; ifill_col<ofill[k+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + gnx*l + p); 135347c6ae99SBarry Smith } 135447c6ae99SBarry Smith } else { 135547c6ae99SBarry Smith if (dfill) { 13568865f1eaSKarl Rupp for (ifill_col=dfill[k]; ifill_col<dfill[k+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + gnx*l + p); 135747c6ae99SBarry Smith } else { 13588865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + gnx*l + p); 135947c6ae99SBarry Smith } 136047c6ae99SBarry Smith } 136147c6ae99SBarry Smith } 136247c6ae99SBarry Smith } 136347c6ae99SBarry Smith row = k + nc*(slot); 1364c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,cnt); 1365c1154cd5SBarry Smith if (removedups) { 1366c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1367c1154cd5SBarry Smith } else { 1368784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 136947c6ae99SBarry Smith } 137047c6ae99SBarry Smith } 137147c6ae99SBarry Smith } 1372c1154cd5SBarry Smith } 137347c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 137447c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 137547c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1376784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 137747c6ae99SBarry Smith 137847c6ae99SBarry Smith /* 137947c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 138047c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 138147c6ae99SBarry Smith PETSc ordering. 138247c6ae99SBarry Smith */ 1383fcfd50ebSBarry Smith if (!da->prealloc_only) { 1384c0ab637bSBarry Smith ierr = PetscCalloc1(maxcnt,&values);CHKERRQ(ierr); 138547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 138647c6ae99SBarry Smith 1387bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1388bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 138947c6ae99SBarry Smith 139047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 139147c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 139247c6ae99SBarry Smith 1393bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1394bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 139547c6ae99SBarry Smith 139647c6ae99SBarry Smith for (k=0; k<nc; k++) { 139747c6ae99SBarry Smith cnt = 0; 139847c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 139947c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 140047c6ae99SBarry Smith if (l || p) { 1401aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star */ 14028865f1eaSKarl Rupp for (ifill_col=ofill[k]; ifill_col<ofill[k+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + gnx*l + p); 140347c6ae99SBarry Smith } 140447c6ae99SBarry Smith } else { 140547c6ae99SBarry Smith if (dfill) { 14068865f1eaSKarl Rupp for (ifill_col=dfill[k]; ifill_col<dfill[k+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + gnx*l + p); 140747c6ae99SBarry Smith } else { 14088865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + gnx*l + p); 140947c6ae99SBarry Smith } 141047c6ae99SBarry Smith } 141147c6ae99SBarry Smith } 141247c6ae99SBarry Smith } 141347c6ae99SBarry Smith row = k + nc*(slot); 141447c6ae99SBarry Smith ierr = MatSetValuesLocal(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 141547c6ae99SBarry Smith } 141647c6ae99SBarry Smith } 141747c6ae99SBarry Smith } 141847c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 141947c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 142047c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1421189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 142247c6ae99SBarry Smith } 142347c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 142447c6ae99SBarry Smith PetscFunctionReturn(0); 142547c6ae99SBarry Smith } 142647c6ae99SBarry Smith 142747c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 142847c6ae99SBarry Smith 1429950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ(DM da,Mat J) 143047c6ae99SBarry Smith { 143147c6ae99SBarry Smith PetscErrorCode ierr; 143247c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 14330298fd71SBarry Smith PetscInt m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p,*dnz = NULL,*onz = NULL; 1434c1154cd5SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 143547c6ae99SBarry Smith MPI_Comm comm; 143647c6ae99SBarry Smith PetscScalar *values; 1437bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 143845b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1439aa219208SBarry Smith DMDAStencilType st; 1440c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 144147c6ae99SBarry Smith 144247c6ae99SBarry Smith PetscFunctionBegin; 144347c6ae99SBarry Smith /* 144447c6ae99SBarry Smith nc - number of components per grid point 144547c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 144647c6ae99SBarry Smith 144747c6ae99SBarry Smith */ 1448c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 144947c6ae99SBarry Smith col = 2*s + 1; 145047c6ae99SBarry Smith 1451c1154cd5SBarry Smith /* 1452c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1453c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1454c1154cd5SBarry Smith */ 1455c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1456c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1457c1154cd5SBarry Smith if (P == 1 && 2*s >= p) removedups = PETSC_TRUE; 1458c1154cd5SBarry Smith 1459aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1460aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 146147c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 146247c6ae99SBarry Smith 1463dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*col*col*nc*nc,&cols);CHKERRQ(ierr); 14641411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 146547c6ae99SBarry Smith 146606ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 146747c6ae99SBarry Smith /* determine the matrix preallocation information */ 146847c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 146947c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1470bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1471bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 147247c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1473bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1474bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 147547c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1476bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1477bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 147847c6ae99SBarry Smith 147947c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 148047c6ae99SBarry Smith 148147c6ae99SBarry Smith cnt = 0; 148247c6ae99SBarry Smith for (l=0; l<nc; l++) { 148347c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 148447c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 148547c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1486aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 148747c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 148847c6ae99SBarry Smith } 148947c6ae99SBarry Smith } 149047c6ae99SBarry Smith } 149147c6ae99SBarry Smith } 149247c6ae99SBarry Smith rows[l] = l + nc*(slot); 149347c6ae99SBarry Smith } 1494c1154cd5SBarry Smith if (removedups) { 1495c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1496c1154cd5SBarry Smith } else { 1497784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 149847c6ae99SBarry Smith } 149947c6ae99SBarry Smith } 150047c6ae99SBarry Smith } 1501c1154cd5SBarry Smith } 1502f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 150347c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 150447c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 150547c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1506784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 150747c6ae99SBarry Smith 150847c6ae99SBarry Smith /* 150947c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 151047c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 151147c6ae99SBarry Smith PETSc ordering. 151247c6ae99SBarry Smith */ 1513fcfd50ebSBarry Smith if (!da->prealloc_only) { 15141795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc*nc,&values);CHKERRQ(ierr); 151547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1516bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1517bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 151847c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1519bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1520bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 152147c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1522bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1523bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 152447c6ae99SBarry Smith 152547c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 152647c6ae99SBarry Smith 152747c6ae99SBarry Smith cnt = 0; 152847c6ae99SBarry Smith for (l=0; l<nc; l++) { 152947c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 153047c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 153147c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1532aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 153347c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 153447c6ae99SBarry Smith } 153547c6ae99SBarry Smith } 153647c6ae99SBarry Smith } 153747c6ae99SBarry Smith } 153847c6ae99SBarry Smith rows[l] = l + nc*(slot); 153947c6ae99SBarry Smith } 154047c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 154147c6ae99SBarry Smith } 154247c6ae99SBarry Smith } 154347c6ae99SBarry Smith } 154447c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 154547c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 154647c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1547189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 154847c6ae99SBarry Smith } 154947c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 155047c6ae99SBarry Smith PetscFunctionReturn(0); 155147c6ae99SBarry Smith } 155247c6ae99SBarry Smith 155347c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 155447c6ae99SBarry Smith 1555ce308e1dSBarry Smith PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ_Fill(DM da,Mat J) 1556ce308e1dSBarry Smith { 1557ce308e1dSBarry Smith PetscErrorCode ierr; 1558ce308e1dSBarry Smith DM_DA *dd = (DM_DA*)da->data; 1559ce308e1dSBarry Smith PetscInt xs,nx,i,j,gxs,gnx,row,k,l; 15608d4c968fSBarry Smith PetscInt m,dim,s,*cols = NULL,nc,cnt,maxcnt = 0,*ocols; 15610acb5bebSBarry Smith PetscInt *ofill = dd->ofill,*dfill = dd->dfill; 1562ce308e1dSBarry Smith PetscScalar *values; 1563bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 156445b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1565ce308e1dSBarry Smith PetscMPIInt rank,size; 1566ce308e1dSBarry Smith 1567ce308e1dSBarry Smith PetscFunctionBegin; 1568bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"With fill provided not implemented with periodic boundary conditions"); 1569ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)da),&rank);CHKERRQ(ierr); 1570ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)da),&size);CHKERRQ(ierr); 1571ce308e1dSBarry Smith 1572ce308e1dSBarry Smith /* 1573ce308e1dSBarry Smith nc - number of components per grid point 1574ce308e1dSBarry Smith 1575ce308e1dSBarry Smith */ 1576ce308e1dSBarry Smith ierr = DMDAGetInfo(da,&dim,&m,0,0,0,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 1577ce308e1dSBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 1578ce308e1dSBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 1579ce308e1dSBarry Smith 1580ce308e1dSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 15811795a4d1SJed Brown ierr = PetscCalloc2(nx*nc,&cols,nx*nc,&ocols);CHKERRQ(ierr); 1582ce308e1dSBarry Smith 1583ce308e1dSBarry Smith /* 1584ce308e1dSBarry Smith note should be smaller for first and last process with no periodic 1585ce308e1dSBarry Smith does not handle dfill 1586ce308e1dSBarry Smith */ 1587ce308e1dSBarry Smith cnt = 0; 1588ce308e1dSBarry Smith /* coupling with process to the left */ 1589ce308e1dSBarry Smith for (i=0; i<s; i++) { 1590ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1591ce308e1dSBarry Smith ocols[cnt] = ((!rank) ? 0 : (s - i)*(ofill[j+1] - ofill[j])); 15920acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + (s + i)*(ofill[j+1] - ofill[j]); 1593c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1594ce308e1dSBarry Smith cnt++; 1595ce308e1dSBarry Smith } 1596ce308e1dSBarry Smith } 1597ce308e1dSBarry Smith for (i=s; i<nx-s; i++) { 1598ce308e1dSBarry Smith for (j=0; j<nc; j++) { 15990acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + 2*s*(ofill[j+1] - ofill[j]); 1600c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1601ce308e1dSBarry Smith cnt++; 1602ce308e1dSBarry Smith } 1603ce308e1dSBarry Smith } 1604ce308e1dSBarry Smith /* coupling with process to the right */ 1605ce308e1dSBarry Smith for (i=nx-s; i<nx; i++) { 1606ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1607ce308e1dSBarry Smith ocols[cnt] = ((rank == (size-1)) ? 0 : (i - nx + s + 1)*(ofill[j+1] - ofill[j])); 16080acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + (s + nx - i - 1)*(ofill[j+1] - ofill[j]); 1609c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1610ce308e1dSBarry Smith cnt++; 1611ce308e1dSBarry Smith } 1612ce308e1dSBarry Smith } 1613ce308e1dSBarry Smith 1614ce308e1dSBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,cols);CHKERRQ(ierr); 1615ce308e1dSBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,cols,0,ocols);CHKERRQ(ierr); 1616ce308e1dSBarry Smith ierr = PetscFree2(cols,ocols);CHKERRQ(ierr); 1617ce308e1dSBarry Smith 1618ce308e1dSBarry Smith ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1619ce308e1dSBarry Smith ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 1620ce308e1dSBarry Smith 1621ce308e1dSBarry Smith /* 1622ce308e1dSBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 1623ce308e1dSBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 1624ce308e1dSBarry Smith PETSc ordering. 1625ce308e1dSBarry Smith */ 1626ce308e1dSBarry Smith if (!da->prealloc_only) { 1627c0ab637bSBarry Smith ierr = PetscCalloc2(maxcnt,&values,maxcnt,&cols);CHKERRQ(ierr); 1628ce308e1dSBarry Smith 1629ce308e1dSBarry Smith row = xs*nc; 1630ce308e1dSBarry Smith /* coupling with process to the left */ 1631ce308e1dSBarry Smith for (i=xs; i<xs+s; i++) { 1632ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1633ce308e1dSBarry Smith cnt = 0; 1634ce308e1dSBarry Smith if (rank) { 1635ce308e1dSBarry Smith for (l=0; l<s; l++) { 1636ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1637ce308e1dSBarry Smith } 1638ce308e1dSBarry Smith } 16390acb5bebSBarry Smith if (dfill) { 16400acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 16410acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 16420acb5bebSBarry Smith } 16430acb5bebSBarry Smith } else { 1644ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1645ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1646ce308e1dSBarry Smith } 16470acb5bebSBarry Smith } 1648ce308e1dSBarry Smith for (l=0; l<s; l++) { 1649ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1650ce308e1dSBarry Smith } 1651ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1652ce308e1dSBarry Smith row++; 1653ce308e1dSBarry Smith } 1654ce308e1dSBarry Smith } 1655ce308e1dSBarry Smith for (i=xs+s; i<xs+nx-s; i++) { 1656ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1657ce308e1dSBarry Smith cnt = 0; 1658ce308e1dSBarry Smith for (l=0; l<s; l++) { 1659ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1660ce308e1dSBarry Smith } 16610acb5bebSBarry Smith if (dfill) { 16620acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 16630acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 16640acb5bebSBarry Smith } 16650acb5bebSBarry Smith } else { 1666ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1667ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1668ce308e1dSBarry Smith } 16690acb5bebSBarry Smith } 1670ce308e1dSBarry Smith for (l=0; l<s; l++) { 1671ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1672ce308e1dSBarry Smith } 1673ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1674ce308e1dSBarry Smith row++; 1675ce308e1dSBarry Smith } 1676ce308e1dSBarry Smith } 1677ce308e1dSBarry Smith /* coupling with process to the right */ 1678ce308e1dSBarry Smith for (i=xs+nx-s; i<xs+nx; i++) { 1679ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1680ce308e1dSBarry Smith cnt = 0; 1681ce308e1dSBarry Smith for (l=0; l<s; l++) { 1682ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1683ce308e1dSBarry Smith } 16840acb5bebSBarry Smith if (dfill) { 16850acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 16860acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 16870acb5bebSBarry Smith } 16880acb5bebSBarry Smith } else { 1689ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1690ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1691ce308e1dSBarry Smith } 16920acb5bebSBarry Smith } 1693ce308e1dSBarry Smith if (rank < size-1) { 1694ce308e1dSBarry Smith for (l=0; l<s; l++) { 1695ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1696ce308e1dSBarry Smith } 1697ce308e1dSBarry Smith } 1698ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1699ce308e1dSBarry Smith row++; 1700ce308e1dSBarry Smith } 1701ce308e1dSBarry Smith } 1702c0ab637bSBarry Smith ierr = PetscFree2(values,cols);CHKERRQ(ierr); 1703ce308e1dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1704ce308e1dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1705189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 1706ce308e1dSBarry Smith } 1707ce308e1dSBarry Smith PetscFunctionReturn(0); 1708ce308e1dSBarry Smith } 1709ce308e1dSBarry Smith 1710ce308e1dSBarry Smith /* ---------------------------------------------------------------------------------*/ 1711ce308e1dSBarry Smith 1712950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ(DM da,Mat J) 171347c6ae99SBarry Smith { 171447c6ae99SBarry Smith PetscErrorCode ierr; 171547c6ae99SBarry Smith PetscInt xs,nx,i,i1,slot,gxs,gnx; 17160298fd71SBarry Smith PetscInt m,dim,s,*cols = NULL,nc,*rows = NULL,col,cnt,l; 171747c6ae99SBarry Smith PetscInt istart,iend; 171847c6ae99SBarry Smith PetscScalar *values; 1719bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 172045b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 172147c6ae99SBarry Smith 172247c6ae99SBarry Smith PetscFunctionBegin; 172347c6ae99SBarry Smith /* 172447c6ae99SBarry Smith nc - number of components per grid point 172547c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 172647c6ae99SBarry Smith 172747c6ae99SBarry Smith */ 17281321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,0,0,0,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 172947c6ae99SBarry Smith col = 2*s + 1; 173047c6ae99SBarry Smith 1731aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 1732aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 173347c6ae99SBarry Smith 1734f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 173547c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,col*nc,0);CHKERRQ(ierr); 173647c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,col*nc,0,col*nc,0);CHKERRQ(ierr); 173747c6ae99SBarry Smith 17381411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1739784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 174047c6ae99SBarry Smith 174147c6ae99SBarry Smith /* 174247c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 174347c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 174447c6ae99SBarry Smith PETSc ordering. 174547c6ae99SBarry Smith */ 1746fcfd50ebSBarry Smith if (!da->prealloc_only) { 1747dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*nc*nc,&cols);CHKERRQ(ierr); 17481795a4d1SJed Brown ierr = PetscCalloc1(col*nc*nc,&values);CHKERRQ(ierr); 174947c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 175047c6ae99SBarry Smith istart = PetscMax(-s,gxs - i); 175147c6ae99SBarry Smith iend = PetscMin(s,gxs + gnx - i - 1); 175247c6ae99SBarry Smith slot = i - gxs; 175347c6ae99SBarry Smith 175447c6ae99SBarry Smith cnt = 0; 175547c6ae99SBarry Smith for (l=0; l<nc; l++) { 175647c6ae99SBarry Smith for (i1=istart; i1<iend+1; i1++) { 175747c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + i1); 175847c6ae99SBarry Smith } 175947c6ae99SBarry Smith rows[l] = l + nc*(slot); 176047c6ae99SBarry Smith } 176147c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 176247c6ae99SBarry Smith } 176347c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 176447c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 176547c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1766189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 176747c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 1768ce308e1dSBarry Smith } 176947c6ae99SBarry Smith PetscFunctionReturn(0); 177047c6ae99SBarry Smith } 177147c6ae99SBarry Smith 1772950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIBAIJ(DM da,Mat J) 177347c6ae99SBarry Smith { 177447c6ae99SBarry Smith PetscErrorCode ierr; 177547c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 177647c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,nc,col,cnt,*dnz,*onz; 177747c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,ii,jj; 177847c6ae99SBarry Smith MPI_Comm comm; 177947c6ae99SBarry Smith PetscScalar *values; 1780bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 1781aa219208SBarry Smith DMDAStencilType st; 178245b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 178347c6ae99SBarry Smith 178447c6ae99SBarry Smith PetscFunctionBegin; 178547c6ae99SBarry Smith /* 178647c6ae99SBarry Smith nc - number of components per grid point 178747c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 178847c6ae99SBarry Smith */ 17891321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 179047c6ae99SBarry Smith col = 2*s + 1; 179147c6ae99SBarry Smith 1792aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1793aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 179447c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 179547c6ae99SBarry Smith 1796785e854fSJed Brown ierr = PetscMalloc1(col*col*nc*nc,&cols);CHKERRQ(ierr); 179747c6ae99SBarry Smith 17981411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 179947c6ae99SBarry Smith 180047c6ae99SBarry Smith /* determine the matrix preallocation information */ 180147c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nx*ny,nx*ny,dnz,onz);CHKERRQ(ierr); 180247c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1803bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1804bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 180547c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1806bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1807bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 180847c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 180947c6ae99SBarry Smith 181047c6ae99SBarry Smith /* Find block columns in block row */ 181147c6ae99SBarry Smith cnt = 0; 181247c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 181347c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1814aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { /* BOX or on the STAR */ 181547c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 181647c6ae99SBarry Smith } 181747c6ae99SBarry Smith } 181847c6ae99SBarry Smith } 1819d6e23781SBarry Smith ierr = MatPreallocateSetLocalBlock(ltog,1,&slot,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 182047c6ae99SBarry Smith } 182147c6ae99SBarry Smith } 182247c6ae99SBarry Smith ierr = MatSeqBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 182347c6ae99SBarry Smith ierr = MatMPIBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 182447c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 182547c6ae99SBarry Smith 1826784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 182747c6ae99SBarry Smith 182847c6ae99SBarry Smith /* 182947c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 183047c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 183147c6ae99SBarry Smith PETSc ordering. 183247c6ae99SBarry Smith */ 1833fcfd50ebSBarry Smith if (!da->prealloc_only) { 18341795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 183547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1836bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1837bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 183847c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1839bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1840bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 184147c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 184247c6ae99SBarry Smith cnt = 0; 184347c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 184447c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1845aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { /* BOX or on the STAR */ 184647c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 184747c6ae99SBarry Smith } 184847c6ae99SBarry Smith } 184947c6ae99SBarry Smith } 185047c6ae99SBarry Smith ierr = MatSetValuesBlockedLocal(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 185147c6ae99SBarry Smith } 185247c6ae99SBarry Smith } 185347c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 185447c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 185547c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1856189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 185747c6ae99SBarry Smith } 185847c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 185947c6ae99SBarry Smith PetscFunctionReturn(0); 186047c6ae99SBarry Smith } 186147c6ae99SBarry Smith 1862950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIBAIJ(DM da,Mat J) 186347c6ae99SBarry Smith { 186447c6ae99SBarry Smith PetscErrorCode ierr; 186547c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 186647c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,col,cnt,p,*dnz,*onz; 186747c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk; 186847c6ae99SBarry Smith MPI_Comm comm; 186947c6ae99SBarry Smith PetscScalar *values; 1870bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 1871aa219208SBarry Smith DMDAStencilType st; 187245b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 187347c6ae99SBarry Smith 187447c6ae99SBarry Smith PetscFunctionBegin; 187547c6ae99SBarry Smith /* 187647c6ae99SBarry Smith nc - number of components per grid point 187747c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 187847c6ae99SBarry Smith 187947c6ae99SBarry Smith */ 18801321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,0,0,0,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 188147c6ae99SBarry Smith col = 2*s + 1; 188247c6ae99SBarry Smith 1883aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1884aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 188547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 188647c6ae99SBarry Smith 1887785e854fSJed Brown ierr = PetscMalloc1(col*col*col,&cols);CHKERRQ(ierr); 188847c6ae99SBarry Smith 18891411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 189047c6ae99SBarry Smith 189147c6ae99SBarry Smith /* determine the matrix preallocation information */ 189247c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nx*ny*nz,nx*ny*nz,dnz,onz);CHKERRQ(ierr); 189347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1894bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1895bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 189647c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1897bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1898bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 189947c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1900bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1901bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 190247c6ae99SBarry Smith 190347c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 190447c6ae99SBarry Smith 190547c6ae99SBarry Smith /* Find block columns in block row */ 190647c6ae99SBarry Smith cnt = 0; 190747c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 190847c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 190947c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1910aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 191147c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 191247c6ae99SBarry Smith } 191347c6ae99SBarry Smith } 191447c6ae99SBarry Smith } 191547c6ae99SBarry Smith } 1916d6e23781SBarry Smith ierr = MatPreallocateSetLocalBlock(ltog,1,&slot,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 191747c6ae99SBarry Smith } 191847c6ae99SBarry Smith } 191947c6ae99SBarry Smith } 192047c6ae99SBarry Smith ierr = MatSeqBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 192147c6ae99SBarry Smith ierr = MatMPIBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 192247c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 192347c6ae99SBarry Smith 1924784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 192547c6ae99SBarry Smith 192647c6ae99SBarry Smith /* 192747c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 192847c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 192947c6ae99SBarry Smith PETSc ordering. 193047c6ae99SBarry Smith */ 1931fcfd50ebSBarry Smith if (!da->prealloc_only) { 19321795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc,&values);CHKERRQ(ierr); 193347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1934bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1935bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 193647c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1937bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1938bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 193947c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1940bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1941bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 194247c6ae99SBarry Smith 194347c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 194447c6ae99SBarry Smith 194547c6ae99SBarry Smith cnt = 0; 194647c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 194747c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 194847c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1949aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 195047c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 195147c6ae99SBarry Smith } 195247c6ae99SBarry Smith } 195347c6ae99SBarry Smith } 195447c6ae99SBarry Smith } 195547c6ae99SBarry Smith ierr = MatSetValuesBlockedLocal(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 195647c6ae99SBarry Smith } 195747c6ae99SBarry Smith } 195847c6ae99SBarry Smith } 195947c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 196047c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 196147c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1962189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 196347c6ae99SBarry Smith } 196447c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 196547c6ae99SBarry Smith PetscFunctionReturn(0); 196647c6ae99SBarry Smith } 196747c6ae99SBarry Smith 196847c6ae99SBarry Smith /* 196947c6ae99SBarry Smith This helper is for of SBAIJ preallocation, to discard the lower-triangular values which are difficult to 197047c6ae99SBarry Smith identify in the local ordering with periodic domain. 197147c6ae99SBarry Smith */ 197247c6ae99SBarry Smith static PetscErrorCode L2GFilterUpperTriangular(ISLocalToGlobalMapping ltog,PetscInt *row,PetscInt *cnt,PetscInt col[]) 197347c6ae99SBarry Smith { 197447c6ae99SBarry Smith PetscErrorCode ierr; 197547c6ae99SBarry Smith PetscInt i,n; 197647c6ae99SBarry Smith 197747c6ae99SBarry Smith PetscFunctionBegin; 1978d6e23781SBarry Smith ierr = ISLocalToGlobalMappingApplyBlock(ltog,1,row,row);CHKERRQ(ierr); 1979d6e23781SBarry Smith ierr = ISLocalToGlobalMappingApplyBlock(ltog,*cnt,col,col);CHKERRQ(ierr); 198047c6ae99SBarry Smith for (i=0,n=0; i<*cnt; i++) { 198147c6ae99SBarry Smith if (col[i] >= *row) col[n++] = col[i]; 198247c6ae99SBarry Smith } 198347c6ae99SBarry Smith *cnt = n; 198447c6ae99SBarry Smith PetscFunctionReturn(0); 198547c6ae99SBarry Smith } 198647c6ae99SBarry Smith 1987950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPISBAIJ(DM da,Mat J) 198847c6ae99SBarry Smith { 198947c6ae99SBarry Smith PetscErrorCode ierr; 199047c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 199147c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,nc,col,cnt,*dnz,*onz; 199247c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,ii,jj; 199347c6ae99SBarry Smith MPI_Comm comm; 199447c6ae99SBarry Smith PetscScalar *values; 1995bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 1996aa219208SBarry Smith DMDAStencilType st; 199745b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 199847c6ae99SBarry Smith 199947c6ae99SBarry Smith PetscFunctionBegin; 200047c6ae99SBarry Smith /* 200147c6ae99SBarry Smith nc - number of components per grid point 200247c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 200347c6ae99SBarry Smith */ 20041321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 200547c6ae99SBarry Smith col = 2*s + 1; 200647c6ae99SBarry Smith 2007aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 2008aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 200947c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 201047c6ae99SBarry Smith 2011785e854fSJed Brown ierr = PetscMalloc1(col*col*nc*nc,&cols);CHKERRQ(ierr); 201247c6ae99SBarry Smith 20131411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 201447c6ae99SBarry Smith 201547c6ae99SBarry Smith /* determine the matrix preallocation information */ 2016eabe889fSLisandro Dalcin ierr = MatPreallocateInitialize(comm,nx*ny,nx*ny,dnz,onz);CHKERRQ(ierr); 201747c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2018bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2019bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 202047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2021bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2022bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 202347c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 202447c6ae99SBarry Smith 202547c6ae99SBarry Smith /* Find block columns in block row */ 202647c6ae99SBarry Smith cnt = 0; 202747c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 202847c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 2029aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { 203047c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 203147c6ae99SBarry Smith } 203247c6ae99SBarry Smith } 203347c6ae99SBarry Smith } 203445b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 2035d6e23781SBarry Smith ierr = MatPreallocateSymmetricSetBlock(slot,cnt,cols,dnz,onz);CHKERRQ(ierr); 203647c6ae99SBarry Smith } 203747c6ae99SBarry Smith } 203847c6ae99SBarry Smith ierr = MatSeqSBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 203947c6ae99SBarry Smith ierr = MatMPISBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 204047c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 204147c6ae99SBarry Smith 2042784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 204347c6ae99SBarry Smith 204447c6ae99SBarry Smith /* 204547c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 204647c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 204747c6ae99SBarry Smith PETSc ordering. 204847c6ae99SBarry Smith */ 2049fcfd50ebSBarry Smith if (!da->prealloc_only) { 20501795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 205147c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2052bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2053bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 205447c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2055bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2056bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 205747c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 205847c6ae99SBarry Smith 205947c6ae99SBarry Smith /* Find block columns in block row */ 206047c6ae99SBarry Smith cnt = 0; 206147c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 206247c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 2063aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { 206447c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 206547c6ae99SBarry Smith } 206647c6ae99SBarry Smith } 206747c6ae99SBarry Smith } 206845b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 206947c6ae99SBarry Smith ierr = MatSetValuesBlocked(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 207047c6ae99SBarry Smith } 207147c6ae99SBarry Smith } 207247c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 207347c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 207447c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2075189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 207647c6ae99SBarry Smith } 207747c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 207847c6ae99SBarry Smith PetscFunctionReturn(0); 207947c6ae99SBarry Smith } 208047c6ae99SBarry Smith 2081950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPISBAIJ(DM da,Mat J) 208247c6ae99SBarry Smith { 208347c6ae99SBarry Smith PetscErrorCode ierr; 208447c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 208547c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,col,cnt,p,*dnz,*onz; 208647c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk; 208747c6ae99SBarry Smith MPI_Comm comm; 208847c6ae99SBarry Smith PetscScalar *values; 2089bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 2090aa219208SBarry Smith DMDAStencilType st; 209145b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 209247c6ae99SBarry Smith 209347c6ae99SBarry Smith PetscFunctionBegin; 209447c6ae99SBarry Smith /* 209547c6ae99SBarry Smith nc - number of components per grid point 209647c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 209747c6ae99SBarry Smith */ 20981321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,0,0,0,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 209947c6ae99SBarry Smith col = 2*s + 1; 210047c6ae99SBarry Smith 2101aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 2102aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 210347c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 210447c6ae99SBarry Smith 210547c6ae99SBarry Smith /* create the matrix */ 2106785e854fSJed Brown ierr = PetscMalloc1(col*col*col,&cols);CHKERRQ(ierr); 210747c6ae99SBarry Smith 21081411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 210947c6ae99SBarry Smith 211047c6ae99SBarry Smith /* determine the matrix preallocation information */ 2111eabe889fSLisandro Dalcin ierr = MatPreallocateInitialize(comm,nx*ny*nz,nx*ny*nz,dnz,onz);CHKERRQ(ierr); 211247c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2113bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2114bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 211547c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2116bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2117bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 211847c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2119bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2120bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 212147c6ae99SBarry Smith 212247c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 212347c6ae99SBarry Smith 212447c6ae99SBarry Smith /* Find block columns in block row */ 212547c6ae99SBarry Smith cnt = 0; 212647c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 212747c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 212847c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 2129aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!ii && !jj) || (!jj && !kk) || (!ii && !kk)) { 213047c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 213147c6ae99SBarry Smith } 213247c6ae99SBarry Smith } 213347c6ae99SBarry Smith } 213447c6ae99SBarry Smith } 213545b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 2136d6e23781SBarry Smith ierr = MatPreallocateSymmetricSetBlock(slot,cnt,cols,dnz,onz);CHKERRQ(ierr); 213747c6ae99SBarry Smith } 213847c6ae99SBarry Smith } 213947c6ae99SBarry Smith } 214047c6ae99SBarry Smith ierr = MatSeqSBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 214147c6ae99SBarry Smith ierr = MatMPISBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 214247c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 214347c6ae99SBarry Smith 2144784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 214547c6ae99SBarry Smith 214647c6ae99SBarry Smith /* 214747c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 214847c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 214947c6ae99SBarry Smith PETSc ordering. 215047c6ae99SBarry Smith */ 2151fcfd50ebSBarry Smith if (!da->prealloc_only) { 21521795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc,&values);CHKERRQ(ierr); 215347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2154bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2155bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 215647c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2157bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2158bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 215947c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2160bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2161bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 216247c6ae99SBarry Smith 216347c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 216447c6ae99SBarry Smith 216547c6ae99SBarry Smith cnt = 0; 216647c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 216747c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 216847c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 2169aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!ii && !jj) || (!jj && !kk) || (!ii && !kk)) { 217047c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 217147c6ae99SBarry Smith } 217247c6ae99SBarry Smith } 217347c6ae99SBarry Smith } 217447c6ae99SBarry Smith } 217545b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 217647c6ae99SBarry Smith ierr = MatSetValuesBlocked(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 217747c6ae99SBarry Smith } 217847c6ae99SBarry Smith } 217947c6ae99SBarry Smith } 218047c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 218147c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 218247c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2183189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 218447c6ae99SBarry Smith } 218547c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 218647c6ae99SBarry Smith PetscFunctionReturn(0); 218747c6ae99SBarry Smith } 218847c6ae99SBarry Smith 218947c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 219047c6ae99SBarry Smith 2191950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ_Fill(DM da,Mat J) 219247c6ae99SBarry Smith { 219347c6ae99SBarry Smith PetscErrorCode ierr; 219447c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 2195c0ab637bSBarry Smith PetscInt m,n,dim,s,*cols,k,nc,row,col,cnt, maxcnt = 0,l,p,*dnz,*onz; 2196c1154cd5SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 219747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 219847c6ae99SBarry Smith PetscInt ifill_col,*dfill = dd->dfill,*ofill = dd->ofill; 219947c6ae99SBarry Smith MPI_Comm comm; 220047c6ae99SBarry Smith PetscScalar *values; 2201bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 220245b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 2203aa219208SBarry Smith DMDAStencilType st; 2204c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 220547c6ae99SBarry Smith 220647c6ae99SBarry Smith PetscFunctionBegin; 220747c6ae99SBarry Smith /* 220847c6ae99SBarry Smith nc - number of components per grid point 220947c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 221047c6ae99SBarry Smith 221147c6ae99SBarry Smith */ 2212c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 221347c6ae99SBarry Smith col = 2*s + 1; 2214bff4a2f0SMatthew 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\ 221547c6ae99SBarry Smith by 2*stencil_width + 1\n"); 2216bff4a2f0SMatthew 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\ 221747c6ae99SBarry Smith by 2*stencil_width + 1\n"); 2218bff4a2f0SMatthew 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\ 221947c6ae99SBarry Smith by 2*stencil_width + 1\n"); 222047c6ae99SBarry Smith 2221c1154cd5SBarry Smith /* 2222c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 2223c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 2224c1154cd5SBarry Smith */ 2225c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 2226c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 2227c1154cd5SBarry Smith if (P == 1 && 2*s >= p) removedups = PETSC_TRUE; 2228c1154cd5SBarry Smith 2229aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 2230aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 223147c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 223247c6ae99SBarry Smith 2233785e854fSJed Brown ierr = PetscMalloc1(col*col*col*nc,&cols);CHKERRQ(ierr); 22341411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 223547c6ae99SBarry Smith 223647c6ae99SBarry Smith /* determine the matrix preallocation information */ 223747c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 223847c6ae99SBarry Smith 223906ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 224047c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2241bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2242bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 224347c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2244bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2245bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 224647c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2247bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2248bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 224947c6ae99SBarry Smith 225047c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 225147c6ae99SBarry Smith 225247c6ae99SBarry Smith for (l=0; l<nc; l++) { 225347c6ae99SBarry Smith cnt = 0; 225447c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 225547c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 225647c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 225747c6ae99SBarry Smith if (ii || jj || kk) { 2258aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 22598865f1eaSKarl 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); 226047c6ae99SBarry Smith } 226147c6ae99SBarry Smith } else { 226247c6ae99SBarry Smith if (dfill) { 22638865f1eaSKarl 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); 226447c6ae99SBarry Smith } else { 22658865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + ii + gnx*jj + gnx*gny*kk); 226647c6ae99SBarry Smith } 226747c6ae99SBarry Smith } 226847c6ae99SBarry Smith } 226947c6ae99SBarry Smith } 227047c6ae99SBarry Smith } 227147c6ae99SBarry Smith row = l + nc*(slot); 2272c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,cnt); 2273c1154cd5SBarry Smith if (removedups) { 2274c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 2275c1154cd5SBarry Smith } else { 2276784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 227747c6ae99SBarry Smith } 227847c6ae99SBarry Smith } 227947c6ae99SBarry Smith } 228047c6ae99SBarry Smith } 2281c1154cd5SBarry Smith } 228247c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 228347c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 228447c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2285784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 228647c6ae99SBarry Smith 228747c6ae99SBarry Smith /* 228847c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 228947c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 229047c6ae99SBarry Smith PETSc ordering. 229147c6ae99SBarry Smith */ 2292fcfd50ebSBarry Smith if (!da->prealloc_only) { 2293c0ab637bSBarry Smith ierr = PetscCalloc1(maxcnt,&values);CHKERRQ(ierr); 229447c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2295bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2296bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 229747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2298bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2299bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 230047c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2301bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2302bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 230347c6ae99SBarry Smith 230447c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 230547c6ae99SBarry Smith 230647c6ae99SBarry Smith for (l=0; l<nc; l++) { 230747c6ae99SBarry Smith cnt = 0; 230847c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 230947c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 231047c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 231147c6ae99SBarry Smith if (ii || jj || kk) { 2312aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 23138865f1eaSKarl 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); 231447c6ae99SBarry Smith } 231547c6ae99SBarry Smith } else { 231647c6ae99SBarry Smith if (dfill) { 23178865f1eaSKarl 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); 231847c6ae99SBarry Smith } else { 23198865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + ii + gnx*jj + gnx*gny*kk); 232047c6ae99SBarry Smith } 232147c6ae99SBarry Smith } 232247c6ae99SBarry Smith } 232347c6ae99SBarry Smith } 232447c6ae99SBarry Smith } 232547c6ae99SBarry Smith row = l + nc*(slot); 232647c6ae99SBarry Smith ierr = MatSetValuesLocal(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 232747c6ae99SBarry Smith } 232847c6ae99SBarry Smith } 232947c6ae99SBarry Smith } 233047c6ae99SBarry Smith } 233147c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 233247c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 233347c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2334189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 233547c6ae99SBarry Smith } 233647c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 233747c6ae99SBarry Smith PetscFunctionReturn(0); 233847c6ae99SBarry Smith } 2339