147c6ae99SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 307475bc1SBarry Smith #include <petscmat.h> 447c6ae99SBarry Smith 5e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_1d_MPIAIJ(DM,ISColoringType,ISColoring*); 6e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_2d_MPIAIJ(DM,ISColoringType,ISColoring*); 7e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_2d_5pt_MPIAIJ(DM,ISColoringType,ISColoring*); 8e727c939SJed Brown extern PetscErrorCode DMCreateColoring_DA_3d_MPIAIJ(DM,ISColoringType,ISColoring*); 947c6ae99SBarry Smith 1047c6ae99SBarry Smith /* 1147c6ae99SBarry Smith For ghost i that may be negative or greater than the upper bound this 1247c6ae99SBarry Smith maps it into the 0:m-1 range using periodicity 1347c6ae99SBarry Smith */ 1447c6ae99SBarry Smith #define SetInRange(i,m) ((i < 0) ? m+i : ((i >= m) ? i-m : i)) 1547c6ae99SBarry Smith 16ce308e1dSBarry Smith static PetscErrorCode DMDASetBlockFills_Private(const PetscInt *dfill,PetscInt w,PetscInt **rfill) 1747c6ae99SBarry Smith { 1847c6ae99SBarry Smith PetscErrorCode ierr; 1947c6ae99SBarry Smith PetscInt i,j,nz,*fill; 2047c6ae99SBarry Smith 2147c6ae99SBarry Smith PetscFunctionBegin; 2247c6ae99SBarry Smith if (!dfill) PetscFunctionReturn(0); 2347c6ae99SBarry Smith 2447c6ae99SBarry Smith /* count number nonzeros */ 2547c6ae99SBarry Smith nz = 0; 2647c6ae99SBarry Smith for (i=0; i<w; i++) { 2747c6ae99SBarry Smith for (j=0; j<w; j++) { 2847c6ae99SBarry Smith if (dfill[w*i+j]) nz++; 2947c6ae99SBarry Smith } 3047c6ae99SBarry Smith } 31854ce69bSBarry Smith ierr = PetscMalloc1(nz + w + 1,&fill);CHKERRQ(ierr); 3247c6ae99SBarry Smith /* construct modified CSR storage of nonzero structure */ 33ce308e1dSBarry Smith /* fill[0 -- w] marks starts of each row of column indices (and end of last row) 34ce308e1dSBarry Smith so fill[1] - fill[0] gives number of nonzeros in first row etc */ 3547c6ae99SBarry Smith nz = w + 1; 3647c6ae99SBarry Smith for (i=0; i<w; i++) { 3747c6ae99SBarry Smith fill[i] = nz; 3847c6ae99SBarry Smith for (j=0; j<w; j++) { 3947c6ae99SBarry Smith if (dfill[w*i+j]) { 4047c6ae99SBarry Smith fill[nz] = j; 4147c6ae99SBarry Smith nz++; 4247c6ae99SBarry Smith } 4347c6ae99SBarry Smith } 4447c6ae99SBarry Smith } 4547c6ae99SBarry Smith fill[w] = nz; 4647c6ae99SBarry Smith 4747c6ae99SBarry Smith *rfill = fill; 4847c6ae99SBarry Smith PetscFunctionReturn(0); 4947c6ae99SBarry Smith } 5047c6ae99SBarry Smith 5147c6ae99SBarry Smith /*@ 52aa219208SBarry Smith DMDASetBlockFills - Sets the fill pattern in each block for a multi-component problem 53950540a4SJed Brown of the matrix returned by DMCreateMatrix(). 5447c6ae99SBarry Smith 55aa219208SBarry Smith Logically Collective on DMDA 5647c6ae99SBarry Smith 5747c6ae99SBarry Smith Input Parameter: 5847c6ae99SBarry Smith + da - the distributed array 590298fd71SBarry Smith . dfill - the fill pattern in the diagonal block (may be NULL, means use dense block) 6047c6ae99SBarry Smith - ofill - the fill pattern in the off-diagonal blocks 6147c6ae99SBarry Smith 6247c6ae99SBarry Smith 6347c6ae99SBarry Smith Level: developer 6447c6ae99SBarry Smith 6547c6ae99SBarry Smith Notes: This only makes sense when you are doing multicomponent problems but using the 6647c6ae99SBarry Smith MPIAIJ matrix format 6747c6ae99SBarry Smith 6847c6ae99SBarry Smith The format for dfill and ofill is a 2 dimensional dof by dof matrix with 1 entries 6947c6ae99SBarry Smith representing coupling and 0 entries for missing coupling. For example 7047c6ae99SBarry Smith $ dfill[9] = {1, 0, 0, 7147c6ae99SBarry Smith $ 1, 1, 0, 7247c6ae99SBarry Smith $ 0, 1, 1} 7347c6ae99SBarry Smith means that row 0 is coupled with only itself in the diagonal block, row 1 is coupled with 7447c6ae99SBarry Smith itself and row 0 (in the diagonal block) and row 2 is coupled with itself and row 1 (in the 7547c6ae99SBarry Smith diagonal block). 7647c6ae99SBarry Smith 77aa219208SBarry Smith DMDASetGetMatrix() allows you to provide general code for those more complicated nonzero patterns then 7847c6ae99SBarry Smith can be represented in the dfill, ofill format 7947c6ae99SBarry Smith 8047c6ae99SBarry Smith Contributed by Glenn Hammond 8147c6ae99SBarry Smith 828ddb5d8bSBarry Smith .seealso DMCreateMatrix(), DMDASetGetMatrix(), DMSetMatrixPreallocateOnly() 8347c6ae99SBarry Smith 8447c6ae99SBarry Smith @*/ 85ce308e1dSBarry Smith PetscErrorCode DMDASetBlockFills(DM da,const PetscInt *dfill,const PetscInt *ofill) 8647c6ae99SBarry Smith { 8747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 8847c6ae99SBarry Smith PetscErrorCode ierr; 89ae4f298aSBarry Smith PetscInt i,k,cnt = 1; 9047c6ae99SBarry Smith 9147c6ae99SBarry Smith PetscFunctionBegin; 92aa219208SBarry Smith ierr = DMDASetBlockFills_Private(dfill,dd->w,&dd->dfill);CHKERRQ(ierr); 93aa219208SBarry Smith ierr = DMDASetBlockFills_Private(ofill,dd->w,&dd->ofill);CHKERRQ(ierr); 94ae4f298aSBarry Smith 95ae4f298aSBarry Smith /* ofillcount tracks the columns of ofill that have any nonzero in thems; the value in each location is the number of 96ae4f298aSBarry Smith columns to the left with any nonzeros in them plus 1 */ 971795a4d1SJed Brown ierr = PetscCalloc1(dd->w,&dd->ofillcols);CHKERRQ(ierr); 98ae4f298aSBarry Smith for (i=0; i<dd->w; i++) { 99ae4f298aSBarry Smith for (k=dd->ofill[i]; k<dd->ofill[i+1]; k++) dd->ofillcols[dd->ofill[k]] = 1; 100ae4f298aSBarry Smith } 101ae4f298aSBarry Smith for (i=0; i<dd->w; i++) { 102ae4f298aSBarry Smith if (dd->ofillcols[i]) { 103ae4f298aSBarry Smith dd->ofillcols[i] = cnt++; 104ae4f298aSBarry Smith } 105ae4f298aSBarry Smith } 10647c6ae99SBarry Smith PetscFunctionReturn(0); 10747c6ae99SBarry Smith } 10847c6ae99SBarry Smith 10947c6ae99SBarry Smith 110b412c318SBarry Smith PetscErrorCode DMCreateColoring_DA(DM da,ISColoringType ctype,ISColoring *coloring) 11147c6ae99SBarry Smith { 11247c6ae99SBarry Smith PetscErrorCode ierr; 11347c6ae99SBarry Smith PetscInt dim,m,n,p,nc; 114bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 11547c6ae99SBarry Smith MPI_Comm comm; 11647c6ae99SBarry Smith PetscMPIInt size; 11747c6ae99SBarry Smith PetscBool isBAIJ; 11847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith PetscFunctionBegin; 12147c6ae99SBarry Smith /* 12247c6ae99SBarry Smith m 12347c6ae99SBarry Smith ------------------------------------------------------ 12447c6ae99SBarry Smith | | 12547c6ae99SBarry Smith | | 12647c6ae99SBarry Smith | ---------------------- | 12747c6ae99SBarry Smith | | | | 12847c6ae99SBarry Smith n | yn | | | 12947c6ae99SBarry Smith | | | | 13047c6ae99SBarry Smith | .--------------------- | 13147c6ae99SBarry Smith | (xs,ys) xn | 13247c6ae99SBarry Smith | . | 13347c6ae99SBarry Smith | (gxs,gys) | 13447c6ae99SBarry Smith | | 13547c6ae99SBarry Smith ----------------------------------------------------- 13647c6ae99SBarry Smith */ 13747c6ae99SBarry Smith 13847c6ae99SBarry Smith /* 13947c6ae99SBarry Smith nc - number of components per grid point 14047c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 14147c6ae99SBarry Smith 14247c6ae99SBarry Smith */ 1431321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,0,0,0,&m,&n,&p,&nc,0,&bx,&by,&bz,0);CHKERRQ(ierr); 14447c6ae99SBarry Smith 14547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 14647c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1475bdb020cSBarry Smith if (ctype == IS_COLORING_LOCAL) { 14847c6ae99SBarry Smith if (size == 1) { 14947c6ae99SBarry Smith ctype = IS_COLORING_GLOBAL; 15047c6ae99SBarry Smith } else if (dim > 1) { 151bff4a2f0SMatthew G. Knepley if ((m==1 && bx == DM_BOUNDARY_PERIODIC) || (n==1 && by == DM_BOUNDARY_PERIODIC) || (p==1 && bz == DM_BOUNDARY_PERIODIC)) { 1525bdb020cSBarry Smith SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"IS_COLORING_LOCAL cannot be used for periodic boundary condition having both ends of the domain on the same process"); 15347c6ae99SBarry Smith } 15447c6ae99SBarry Smith } 15547c6ae99SBarry Smith } 15647c6ae99SBarry Smith 157aa219208SBarry Smith /* Tell the DMDA it has 1 degree of freedom per grid point so that the coloring for BAIJ 15847c6ae99SBarry Smith matrices is for the blocks, not the individual matrix elements */ 159b412c318SBarry Smith ierr = PetscStrcmp(da->mattype,MATBAIJ,&isBAIJ);CHKERRQ(ierr); 160b412c318SBarry Smith if (!isBAIJ) {ierr = PetscStrcmp(da->mattype,MATMPIBAIJ,&isBAIJ);CHKERRQ(ierr);} 161b412c318SBarry Smith if (!isBAIJ) {ierr = PetscStrcmp(da->mattype,MATSEQBAIJ,&isBAIJ);CHKERRQ(ierr);} 16247c6ae99SBarry Smith if (isBAIJ) { 16347c6ae99SBarry Smith dd->w = 1; 16447c6ae99SBarry Smith dd->xs = dd->xs/nc; 16547c6ae99SBarry Smith dd->xe = dd->xe/nc; 16647c6ae99SBarry Smith dd->Xs = dd->Xs/nc; 16747c6ae99SBarry Smith dd->Xe = dd->Xe/nc; 16847c6ae99SBarry Smith } 16947c6ae99SBarry Smith 17047c6ae99SBarry Smith /* 171aa219208SBarry Smith We do not provide a getcoloring function in the DMDA operations because 172aa219208SBarry Smith the basic DMDA does not know about matrices. We think of DMDA as being more 17347c6ae99SBarry Smith more low-level then matrices. 17447c6ae99SBarry Smith */ 17547c6ae99SBarry Smith if (dim == 1) { 176e727c939SJed Brown ierr = DMCreateColoring_DA_1d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 17747c6ae99SBarry Smith } else if (dim == 2) { 178e727c939SJed Brown ierr = DMCreateColoring_DA_2d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 17947c6ae99SBarry Smith } else if (dim == 3) { 180e727c939SJed Brown ierr = DMCreateColoring_DA_3d_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 181ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not done for %D dimension, send us mail petsc-maint@mcs.anl.gov for code",dim); 18247c6ae99SBarry Smith if (isBAIJ) { 18347c6ae99SBarry Smith dd->w = nc; 18447c6ae99SBarry Smith dd->xs = dd->xs*nc; 18547c6ae99SBarry Smith dd->xe = dd->xe*nc; 18647c6ae99SBarry Smith dd->Xs = dd->Xs*nc; 18747c6ae99SBarry Smith dd->Xe = dd->Xe*nc; 18847c6ae99SBarry Smith } 18947c6ae99SBarry Smith PetscFunctionReturn(0); 19047c6ae99SBarry Smith } 19147c6ae99SBarry Smith 19247c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 19347c6ae99SBarry Smith 194e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_2d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 19547c6ae99SBarry Smith { 19647c6ae99SBarry Smith PetscErrorCode ierr; 19747c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,ii,gxs,gys,gnx,gny,m,n,M,N,dim,s,k,nc,col; 19847c6ae99SBarry Smith PetscInt ncolors; 19947c6ae99SBarry Smith MPI_Comm comm; 200bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 201aa219208SBarry Smith DMDAStencilType st; 20247c6ae99SBarry Smith ISColoringValue *colors; 20347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 20447c6ae99SBarry Smith 20547c6ae99SBarry Smith PetscFunctionBegin; 20647c6ae99SBarry Smith /* 20747c6ae99SBarry Smith nc - number of components per grid point 20847c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 20947c6ae99SBarry Smith 21047c6ae99SBarry Smith */ 2111321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,&M,&N,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 21247c6ae99SBarry Smith col = 2*s + 1; 213aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 214aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 21547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 21647c6ae99SBarry Smith 21747c6ae99SBarry Smith /* special case as taught to us by Paul Hovland */ 218aa219208SBarry Smith if (st == DMDA_STENCIL_STAR && s == 1) { 219e727c939SJed Brown ierr = DMCreateColoring_DA_2d_5pt_MPIAIJ(da,ctype,coloring);CHKERRQ(ierr); 22047c6ae99SBarry Smith } else { 22147c6ae99SBarry Smith 222bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % col)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in X (%d) is divisible\n\ 22347c6ae99SBarry Smith by 2*stencil_width + 1 (%d)\n", m, col); 224bff4a2f0SMatthew G. Knepley if (by == DM_BOUNDARY_PERIODIC && (n % col)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Y (%d) is divisible\n\ 22547c6ae99SBarry Smith by 2*stencil_width + 1 (%d)\n", n, col); 22647c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 22747c6ae99SBarry Smith if (!dd->localcoloring) { 228785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny,&colors);CHKERRQ(ierr); 22947c6ae99SBarry Smith ii = 0; 23047c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 23147c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 23247c6ae99SBarry Smith for (k=0; k<nc; k++) { 23347c6ae99SBarry Smith colors[ii++] = k + nc*((i % col) + col*(j % col)); 23447c6ae99SBarry Smith } 23547c6ae99SBarry Smith } 23647c6ae99SBarry Smith } 23747c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)); 238aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 23947c6ae99SBarry Smith } 24047c6ae99SBarry Smith *coloring = dd->localcoloring; 2415bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 24247c6ae99SBarry Smith if (!dd->ghostedcoloring) { 243785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny,&colors);CHKERRQ(ierr); 24447c6ae99SBarry Smith ii = 0; 24547c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 24647c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 24747c6ae99SBarry Smith for (k=0; k<nc; k++) { 24847c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 24947c6ae99SBarry Smith colors[ii++] = k + nc*((SetInRange(i,m) % col) + col*(SetInRange(j,n) % col)); 25047c6ae99SBarry Smith } 25147c6ae99SBarry Smith } 25247c6ae99SBarry Smith } 25347c6ae99SBarry Smith ncolors = nc + nc*(col - 1 + col*(col-1)); 254aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 25547c6ae99SBarry Smith /* PetscIntView(ncolors,(PetscInt*)colors,0); */ 25647c6ae99SBarry Smith 2575bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 25847c6ae99SBarry Smith } 25947c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 260ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 26147c6ae99SBarry Smith } 26247c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 26347c6ae99SBarry Smith PetscFunctionReturn(0); 26447c6ae99SBarry Smith } 26547c6ae99SBarry Smith 26647c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 26747c6ae99SBarry Smith 268e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_3d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 26947c6ae99SBarry Smith { 27047c6ae99SBarry Smith PetscErrorCode ierr; 27147c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,gxs,gys,gnx,gny,m,n,p,dim,s,k,nc,col,zs,gzs,ii,l,nz,gnz,M,N,P; 27247c6ae99SBarry Smith PetscInt ncolors; 27347c6ae99SBarry Smith MPI_Comm comm; 274bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 275aa219208SBarry Smith DMDAStencilType st; 27647c6ae99SBarry Smith ISColoringValue *colors; 27747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 27847c6ae99SBarry Smith 27947c6ae99SBarry Smith PetscFunctionBegin; 28047c6ae99SBarry Smith /* 28147c6ae99SBarry Smith nc - number of components per grid point 28247c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 28347c6ae99SBarry Smith 28447c6ae99SBarry Smith */ 2851321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 28647c6ae99SBarry Smith col = 2*s + 1; 287bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in X is divisible\n\ 28847c6ae99SBarry Smith by 2*stencil_width + 1\n"); 289bff4a2f0SMatthew G. Knepley if (by == DM_BOUNDARY_PERIODIC && (n % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Y is divisible\n\ 29047c6ae99SBarry Smith by 2*stencil_width + 1\n"); 291bff4a2f0SMatthew G. Knepley if (bz == DM_BOUNDARY_PERIODIC && (p % col)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Z is divisible\n\ 29247c6ae99SBarry Smith by 2*stencil_width + 1\n"); 29347c6ae99SBarry Smith 294aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 295aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 29647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 29747c6ae99SBarry Smith 29847c6ae99SBarry Smith /* create the coloring */ 29947c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 30047c6ae99SBarry Smith if (!dd->localcoloring) { 301785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny*nz,&colors);CHKERRQ(ierr); 30247c6ae99SBarry Smith ii = 0; 30347c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 30447c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 30547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 30647c6ae99SBarry Smith for (l=0; l<nc; l++) { 30747c6ae99SBarry Smith colors[ii++] = l + nc*((i % col) + col*(j % col) + col*col*(k % col)); 30847c6ae99SBarry Smith } 30947c6ae99SBarry Smith } 31047c6ae99SBarry Smith } 31147c6ae99SBarry Smith } 31247c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)+ col*col*(col-1)); 313aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny*nz,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 31447c6ae99SBarry Smith } 31547c6ae99SBarry Smith *coloring = dd->localcoloring; 3165bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 31747c6ae99SBarry Smith if (!dd->ghostedcoloring) { 318785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny*gnz,&colors);CHKERRQ(ierr); 31947c6ae99SBarry Smith ii = 0; 32047c6ae99SBarry Smith for (k=gzs; k<gzs+gnz; k++) { 32147c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 32247c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 32347c6ae99SBarry Smith for (l=0; l<nc; l++) { 32447c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 32547c6ae99SBarry Smith colors[ii++] = l + nc*((SetInRange(i,m) % col) + col*(SetInRange(j,n) % col) + col*col*(SetInRange(k,p) % col)); 32647c6ae99SBarry Smith } 32747c6ae99SBarry Smith } 32847c6ae99SBarry Smith } 32947c6ae99SBarry Smith } 33047c6ae99SBarry Smith ncolors = nc + nc*(col-1 + col*(col-1)+ col*col*(col-1)); 331aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny*gnz,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 3325bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 33347c6ae99SBarry Smith } 33447c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 335ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 33647c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 33747c6ae99SBarry Smith PetscFunctionReturn(0); 33847c6ae99SBarry Smith } 33947c6ae99SBarry Smith 34047c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 34147c6ae99SBarry Smith 342e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_1d_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 34347c6ae99SBarry Smith { 34447c6ae99SBarry Smith PetscErrorCode ierr; 34547c6ae99SBarry Smith PetscInt xs,nx,i,i1,gxs,gnx,l,m,M,dim,s,nc,col; 34647c6ae99SBarry Smith PetscInt ncolors; 34747c6ae99SBarry Smith MPI_Comm comm; 348bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 34947c6ae99SBarry Smith ISColoringValue *colors; 35047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 35147c6ae99SBarry Smith 35247c6ae99SBarry Smith PetscFunctionBegin; 35347c6ae99SBarry Smith /* 35447c6ae99SBarry Smith nc - number of components per grid point 35547c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 35647c6ae99SBarry Smith 35747c6ae99SBarry Smith */ 3581321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,0,0,&M,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 35947c6ae99SBarry Smith col = 2*s + 1; 36047c6ae99SBarry Smith 361bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % col)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points %d is divisible\n\ 36231e6f798SBarry Smith by 2*stencil_width + 1 %d\n",(int)m,(int)col); 36347c6ae99SBarry Smith 364aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 365aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 36647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 36747c6ae99SBarry Smith 36847c6ae99SBarry Smith /* create the coloring */ 36947c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 37047c6ae99SBarry Smith if (!dd->localcoloring) { 371785e854fSJed Brown ierr = PetscMalloc1(nc*nx,&colors);CHKERRQ(ierr); 372ae4f298aSBarry Smith if (dd->ofillcols) { 373ae4f298aSBarry Smith PetscInt tc = 0; 374ae4f298aSBarry Smith for (i=0; i<nc; i++) tc += (PetscInt) (dd->ofillcols[i] > 0); 375ae4f298aSBarry Smith i1 = 0; 376ae4f298aSBarry Smith for (i=xs; i<xs+nx; i++) { 377ae4f298aSBarry Smith for (l=0; l<nc; l++) { 378ae4f298aSBarry Smith if (dd->ofillcols[l] && (i % col)) { 379ae4f298aSBarry Smith colors[i1++] = nc - 1 + tc*((i % col) - 1) + dd->ofillcols[l]; 380ae4f298aSBarry Smith } else { 381ae4f298aSBarry Smith colors[i1++] = l; 382ae4f298aSBarry Smith } 383ae4f298aSBarry Smith } 384ae4f298aSBarry Smith } 385ae4f298aSBarry Smith ncolors = nc + 2*s*tc; 386ae4f298aSBarry Smith } else { 38747c6ae99SBarry Smith i1 = 0; 38847c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 38947c6ae99SBarry Smith for (l=0; l<nc; l++) { 39047c6ae99SBarry Smith colors[i1++] = l + nc*(i % col); 39147c6ae99SBarry Smith } 39247c6ae99SBarry Smith } 39347c6ae99SBarry Smith ncolors = nc + nc*(col-1); 394ae4f298aSBarry Smith } 395aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 39647c6ae99SBarry Smith } 39747c6ae99SBarry Smith *coloring = dd->localcoloring; 3985bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 39947c6ae99SBarry Smith if (!dd->ghostedcoloring) { 400785e854fSJed Brown ierr = PetscMalloc1(nc*gnx,&colors);CHKERRQ(ierr); 40147c6ae99SBarry Smith i1 = 0; 40247c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 40347c6ae99SBarry Smith for (l=0; l<nc; l++) { 40447c6ae99SBarry Smith /* the complicated stuff is to handle periodic boundaries */ 40547c6ae99SBarry Smith colors[i1++] = l + nc*(SetInRange(i,m) % col); 40647c6ae99SBarry Smith } 40747c6ae99SBarry Smith } 40847c6ae99SBarry Smith ncolors = nc + nc*(col-1); 409aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 4105bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 41147c6ae99SBarry Smith } 41247c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 413ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 41447c6ae99SBarry Smith ierr = ISColoringReference(*coloring);CHKERRQ(ierr); 41547c6ae99SBarry Smith PetscFunctionReturn(0); 41647c6ae99SBarry Smith } 41747c6ae99SBarry Smith 418e727c939SJed Brown PetscErrorCode DMCreateColoring_DA_2d_5pt_MPIAIJ(DM da,ISColoringType ctype,ISColoring *coloring) 41947c6ae99SBarry Smith { 42047c6ae99SBarry Smith PetscErrorCode ierr; 42147c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,ii,gxs,gys,gnx,gny,m,n,dim,s,k,nc; 42247c6ae99SBarry Smith PetscInt ncolors; 42347c6ae99SBarry Smith MPI_Comm comm; 424bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 42547c6ae99SBarry Smith ISColoringValue *colors; 42647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 42747c6ae99SBarry Smith 42847c6ae99SBarry Smith PetscFunctionBegin; 42947c6ae99SBarry Smith /* 43047c6ae99SBarry Smith nc - number of components per grid point 43147c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 43247c6ae99SBarry Smith 43347c6ae99SBarry Smith */ 4341321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,0);CHKERRQ(ierr); 435aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 436aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 43747c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 43847c6ae99SBarry Smith 439bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC && (m % 5)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in X is divisible by 5\n"); 440bff4a2f0SMatthew G. Knepley if (by == DM_BOUNDARY_PERIODIC && (n % 5)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"For coloring efficiency ensure number of grid points in Y is divisible by 5\n"); 44147c6ae99SBarry Smith 44247c6ae99SBarry Smith /* create the coloring */ 44347c6ae99SBarry Smith if (ctype == IS_COLORING_GLOBAL) { 44447c6ae99SBarry Smith if (!dd->localcoloring) { 445785e854fSJed Brown ierr = PetscMalloc1(nc*nx*ny,&colors);CHKERRQ(ierr); 44647c6ae99SBarry Smith ii = 0; 44747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 44847c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 44947c6ae99SBarry Smith for (k=0; k<nc; k++) { 45047c6ae99SBarry Smith colors[ii++] = k + nc*((3*j+i) % 5); 45147c6ae99SBarry Smith } 45247c6ae99SBarry Smith } 45347c6ae99SBarry Smith } 45447c6ae99SBarry Smith ncolors = 5*nc; 455aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*nx*ny,colors,PETSC_OWN_POINTER,&dd->localcoloring);CHKERRQ(ierr); 45647c6ae99SBarry Smith } 45747c6ae99SBarry Smith *coloring = dd->localcoloring; 4585bdb020cSBarry Smith } else if (ctype == IS_COLORING_LOCAL) { 45947c6ae99SBarry Smith if (!dd->ghostedcoloring) { 460785e854fSJed Brown ierr = PetscMalloc1(nc*gnx*gny,&colors);CHKERRQ(ierr); 46147c6ae99SBarry Smith ii = 0; 46247c6ae99SBarry Smith for (j=gys; j<gys+gny; j++) { 46347c6ae99SBarry Smith for (i=gxs; i<gxs+gnx; i++) { 46447c6ae99SBarry Smith for (k=0; k<nc; k++) { 46547c6ae99SBarry Smith colors[ii++] = k + nc*((3*SetInRange(j,n) + SetInRange(i,m)) % 5); 46647c6ae99SBarry Smith } 46747c6ae99SBarry Smith } 46847c6ae99SBarry Smith } 46947c6ae99SBarry Smith ncolors = 5*nc; 470aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(comm,ncolors,nc*gnx*gny,colors,PETSC_OWN_POINTER,&dd->ghostedcoloring);CHKERRQ(ierr); 4715bdb020cSBarry Smith ierr = ISColoringSetType(dd->ghostedcoloring,IS_COLORING_LOCAL);CHKERRQ(ierr); 47247c6ae99SBarry Smith } 47347c6ae99SBarry Smith *coloring = dd->ghostedcoloring; 474ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 47547c6ae99SBarry Smith PetscFunctionReturn(0); 47647c6ae99SBarry Smith } 47747c6ae99SBarry Smith 47847c6ae99SBarry Smith /* =========================================================================== */ 479950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ(DM,Mat); 480ce308e1dSBarry Smith extern PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ_Fill(DM,Mat); 481950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ(DM,Mat); 482950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ_Fill(DM,Mat); 483950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ(DM,Mat); 484950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ_Fill(DM,Mat); 485950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPIBAIJ(DM,Mat); 486950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPIBAIJ(DM,Mat); 487950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_2d_MPISBAIJ(DM,Mat); 488950540a4SJed Brown extern PetscErrorCode DMCreateMatrix_DA_3d_MPISBAIJ(DM,Mat); 489d4002b98SHong Zhang extern PetscErrorCode DMCreateMatrix_DA_2d_MPISELL(DM,Mat); 490d4002b98SHong Zhang extern PetscErrorCode DMCreateMatrix_DA_3d_MPISELL(DM,Mat); 491e584696dSStefano Zampini extern PetscErrorCode DMCreateMatrix_DA_IS(DM,Mat); 49247c6ae99SBarry Smith 4938bbdbebaSMatthew G Knepley /*@C 494c688c046SMatthew G Knepley MatSetupDM - Sets the DMDA that is to be used by the HYPRE_StructMatrix PETSc matrix 49547c6ae99SBarry Smith 49647c6ae99SBarry Smith Logically Collective on Mat 49747c6ae99SBarry Smith 49847c6ae99SBarry Smith Input Parameters: 49947c6ae99SBarry Smith + mat - the matrix 50047c6ae99SBarry Smith - da - the da 50147c6ae99SBarry Smith 50247c6ae99SBarry Smith Level: intermediate 50347c6ae99SBarry Smith 50447c6ae99SBarry Smith @*/ 505c688c046SMatthew G Knepley PetscErrorCode MatSetupDM(Mat mat,DM da) 50647c6ae99SBarry Smith { 50747c6ae99SBarry Smith PetscErrorCode ierr; 50847c6ae99SBarry Smith 50947c6ae99SBarry Smith PetscFunctionBegin; 51047c6ae99SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 51147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 512c688c046SMatthew G Knepley ierr = PetscTryMethod(mat,"MatSetupDM_C",(Mat,DM),(mat,da));CHKERRQ(ierr); 51347c6ae99SBarry Smith PetscFunctionReturn(0); 51447c6ae99SBarry Smith } 51547c6ae99SBarry Smith 5167087cfbeSBarry Smith PetscErrorCode MatView_MPI_DA(Mat A,PetscViewer viewer) 51747c6ae99SBarry Smith { 5189a42bb27SBarry Smith DM da; 51947c6ae99SBarry Smith PetscErrorCode ierr; 52047c6ae99SBarry Smith const char *prefix; 52147c6ae99SBarry Smith Mat Anatural; 52247c6ae99SBarry Smith AO ao; 52347c6ae99SBarry Smith PetscInt rstart,rend,*petsc,i; 52447c6ae99SBarry Smith IS is; 52547c6ae99SBarry Smith MPI_Comm comm; 52674388724SJed Brown PetscViewerFormat format; 52747c6ae99SBarry Smith 52847c6ae99SBarry Smith PetscFunctionBegin; 52974388724SJed Brown /* Check whether we are just printing info, in which case MatView() already viewed everything we wanted to view */ 53074388724SJed Brown ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 53174388724SJed Brown if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 53274388724SJed Brown 53347c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 534c688c046SMatthew G Knepley ierr = MatGetDM(A, &da);CHKERRQ(ierr); 535ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix not generated from a DMDA"); 53647c6ae99SBarry Smith 537aa219208SBarry Smith ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); 53847c6ae99SBarry Smith ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 539854ce69bSBarry Smith ierr = PetscMalloc1(rend-rstart,&petsc);CHKERRQ(ierr); 54047c6ae99SBarry Smith for (i=rstart; i<rend; i++) petsc[i-rstart] = i; 54147c6ae99SBarry Smith ierr = AOApplicationToPetsc(ao,rend-rstart,petsc);CHKERRQ(ierr); 54247c6ae99SBarry Smith ierr = ISCreateGeneral(comm,rend-rstart,petsc,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 54347c6ae99SBarry Smith 54447c6ae99SBarry Smith /* call viewer on natural ordering */ 5457dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,is,is,MAT_INITIAL_MATRIX,&Anatural);CHKERRQ(ierr); 546fcfd50ebSBarry Smith ierr = ISDestroy(&is);CHKERRQ(ierr); 54747c6ae99SBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)A,&prefix);CHKERRQ(ierr); 54847c6ae99SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)Anatural,prefix);CHKERRQ(ierr); 54947c6ae99SBarry Smith ierr = PetscObjectSetName((PetscObject)Anatural,((PetscObject)A)->name);CHKERRQ(ierr); 550539c167fSBarry Smith ierr = MatView(Anatural,viewer);CHKERRQ(ierr); 551fcfd50ebSBarry Smith ierr = MatDestroy(&Anatural);CHKERRQ(ierr); 55247c6ae99SBarry Smith PetscFunctionReturn(0); 55347c6ae99SBarry Smith } 55447c6ae99SBarry Smith 5557087cfbeSBarry Smith PetscErrorCode MatLoad_MPI_DA(Mat A,PetscViewer viewer) 55647c6ae99SBarry Smith { 5579a42bb27SBarry Smith DM da; 55847c6ae99SBarry Smith PetscErrorCode ierr; 55947c6ae99SBarry Smith Mat Anatural,Aapp; 56047c6ae99SBarry Smith AO ao; 561539c167fSBarry Smith PetscInt rstart,rend,*app,i,m,n,M,N; 56247c6ae99SBarry Smith IS is; 56347c6ae99SBarry Smith MPI_Comm comm; 56447c6ae99SBarry Smith 56547c6ae99SBarry Smith PetscFunctionBegin; 56647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 567c688c046SMatthew G Knepley ierr = MatGetDM(A, &da);CHKERRQ(ierr); 568ce94432eSBarry Smith if (!da) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix not generated from a DMDA"); 56947c6ae99SBarry Smith 57047c6ae99SBarry Smith /* Load the matrix in natural ordering */ 571ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Anatural);CHKERRQ(ierr); 57247c6ae99SBarry Smith ierr = MatSetType(Anatural,((PetscObject)A)->type_name);CHKERRQ(ierr); 573539c167fSBarry Smith ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 574539c167fSBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 575539c167fSBarry Smith ierr = MatSetSizes(Anatural,m,n,M,N);CHKERRQ(ierr); 57647c6ae99SBarry Smith ierr = MatLoad(Anatural,viewer);CHKERRQ(ierr); 57747c6ae99SBarry Smith 57847c6ae99SBarry Smith /* Map natural ordering to application ordering and create IS */ 579aa219208SBarry Smith ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); 58047c6ae99SBarry Smith ierr = MatGetOwnershipRange(Anatural,&rstart,&rend);CHKERRQ(ierr); 581854ce69bSBarry Smith ierr = PetscMalloc1(rend-rstart,&app);CHKERRQ(ierr); 58247c6ae99SBarry Smith for (i=rstart; i<rend; i++) app[i-rstart] = i; 58347c6ae99SBarry Smith ierr = AOPetscToApplication(ao,rend-rstart,app);CHKERRQ(ierr); 58447c6ae99SBarry Smith ierr = ISCreateGeneral(comm,rend-rstart,app,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 58547c6ae99SBarry Smith 58647c6ae99SBarry Smith /* Do permutation and replace header */ 5877dae84e0SHong Zhang ierr = MatCreateSubMatrix(Anatural,is,is,MAT_INITIAL_MATRIX,&Aapp);CHKERRQ(ierr); 58828be2f97SBarry Smith ierr = MatHeaderReplace(A,&Aapp);CHKERRQ(ierr); 589fcfd50ebSBarry Smith ierr = ISDestroy(&is);CHKERRQ(ierr); 590fcfd50ebSBarry Smith ierr = MatDestroy(&Anatural);CHKERRQ(ierr); 59147c6ae99SBarry Smith PetscFunctionReturn(0); 59247c6ae99SBarry Smith } 59347c6ae99SBarry Smith 594b412c318SBarry Smith PetscErrorCode DMCreateMatrix_DA(DM da, Mat *J) 59547c6ae99SBarry Smith { 59647c6ae99SBarry Smith PetscErrorCode ierr; 59747c6ae99SBarry Smith PetscInt dim,dof,nx,ny,nz,dims[3],starts[3],M,N,P; 59847c6ae99SBarry Smith Mat A; 59947c6ae99SBarry Smith MPI_Comm comm; 60019fd82e9SBarry Smith MatType Atype; 60137d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 602e584696dSStefano Zampini void (*aij)(void)=NULL,(*baij)(void)=NULL,(*sbaij)(void)=NULL,(*sell)(void)=NULL,(*is)(void)=NULL; 603b412c318SBarry Smith MatType mtype; 60447c6ae99SBarry Smith PetscMPIInt size; 60547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 60647c6ae99SBarry Smith 60747c6ae99SBarry Smith PetscFunctionBegin; 608607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 609b412c318SBarry Smith mtype = da->mattype; 61047c6ae99SBarry Smith 611*e87a4003SBarry Smith ierr = DMGetSection(da, §ion);CHKERRQ(ierr); 61237d0c07bSMatthew G Knepley if (section) { 61337d0c07bSMatthew G Knepley PetscInt bs = -1; 61437d0c07bSMatthew G Knepley PetscInt localSize; 61537d0c07bSMatthew G Knepley PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isSymmetric; 61637d0c07bSMatthew G Knepley 617*e87a4003SBarry Smith ierr = DMGetGlobalSection(da, §ionGlobal);CHKERRQ(ierr); 61837d0c07bSMatthew G Knepley ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 619b5579763SJed Brown ierr = MatCreate(PetscObjectComm((PetscObject)da),&A);CHKERRQ(ierr); 620b5579763SJed Brown ierr = MatSetSizes(A,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 621b5579763SJed Brown ierr = MatSetType(A,mtype);CHKERRQ(ierr); 62237d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSHELL,&isShell);CHKERRQ(ierr); 62337d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATBAIJ,&isBlock);CHKERRQ(ierr); 62437d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSEQBAIJ,&isSeqBlock);CHKERRQ(ierr); 62537d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATMPIBAIJ,&isMPIBlock);CHKERRQ(ierr); 62637d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSBAIJ,&isSymBlock);CHKERRQ(ierr); 62737d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATSEQSBAIJ,&isSymSeqBlock);CHKERRQ(ierr); 62837d0c07bSMatthew G Knepley ierr = PetscStrcmp(mtype,MATMPISBAIJ,&isSymMPIBlock);CHKERRQ(ierr); 62937d0c07bSMatthew G Knepley /* Check for symmetric storage */ 63037d0c07bSMatthew G Knepley isSymmetric = (PetscBool) (isSymBlock || isSymSeqBlock || isSymMPIBlock); 63137d0c07bSMatthew G Knepley if (isSymmetric) { 63237d0c07bSMatthew G Knepley ierr = MatSetOption(*J, MAT_IGNORE_LOWER_TRIANGULAR, PETSC_TRUE);CHKERRQ(ierr); 63337d0c07bSMatthew G Knepley } 63437d0c07bSMatthew G Knepley if (!isShell) { 63537d0c07bSMatthew G Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal; 63637d0c07bSMatthew G Knepley 63737d0c07bSMatthew G Knepley if (bs < 0) { 63837d0c07bSMatthew G Knepley if (isBlock || isSeqBlock || isMPIBlock || isSymBlock || isSymSeqBlock || isSymMPIBlock) { 63937d0c07bSMatthew G Knepley PetscInt pStart, pEnd, p, dof; 64037d0c07bSMatthew G Knepley 64137d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 64237d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 64337d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 64437d0c07bSMatthew G Knepley if (dof) { 64537d0c07bSMatthew G Knepley bs = dof; 64637d0c07bSMatthew G Knepley break; 64737d0c07bSMatthew G Knepley } 64837d0c07bSMatthew G Knepley } 64937d0c07bSMatthew G Knepley } else { 65037d0c07bSMatthew G Knepley bs = 1; 65137d0c07bSMatthew G Knepley } 65237d0c07bSMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 65337d0c07bSMatthew G Knepley bsLocal = bs; 654b2566f29SBarry Smith ierr = MPIU_Allreduce(&bsLocal, &bs, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)da));CHKERRQ(ierr); 65537d0c07bSMatthew G Knepley } 6561795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 657552f7358SJed Brown /* ierr = DMPlexPreallocateOperator(dm, bs, section, sectionGlobal, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); */ 65837d0c07bSMatthew G Knepley ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 65937d0c07bSMatthew G Knepley } 66037d0c07bSMatthew G Knepley } 66147c6ae99SBarry Smith /* 66247c6ae99SBarry Smith m 66347c6ae99SBarry Smith ------------------------------------------------------ 66447c6ae99SBarry Smith | | 66547c6ae99SBarry Smith | | 66647c6ae99SBarry Smith | ---------------------- | 66747c6ae99SBarry Smith | | | | 66847c6ae99SBarry Smith n | ny | | | 66947c6ae99SBarry Smith | | | | 67047c6ae99SBarry Smith | .--------------------- | 67147c6ae99SBarry Smith | (xs,ys) nx | 67247c6ae99SBarry Smith | . | 67347c6ae99SBarry Smith | (gxs,gys) | 67447c6ae99SBarry Smith | | 67547c6ae99SBarry Smith ----------------------------------------------------- 67647c6ae99SBarry Smith */ 67747c6ae99SBarry Smith 67847c6ae99SBarry Smith /* 67947c6ae99SBarry Smith nc - number of components per grid point 68047c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 68147c6ae99SBarry Smith 68247c6ae99SBarry Smith */ 683e30e807fSPeter Brune M = dd->M; 684e30e807fSPeter Brune N = dd->N; 685e30e807fSPeter Brune P = dd->P; 686c73cfb54SMatthew G. Knepley dim = da->dim; 687e30e807fSPeter Brune dof = dd->w; 688e30e807fSPeter Brune /* ierr = DMDAGetInfo(da,&dim,&M,&N,&P,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); */ 689aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&nx,&ny,&nz);CHKERRQ(ierr); 69047c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 69147c6ae99SBarry Smith ierr = MatCreate(comm,&A);CHKERRQ(ierr); 69247c6ae99SBarry Smith ierr = MatSetSizes(A,dof*nx*ny*nz,dof*nx*ny*nz,dof*M*N*P,dof*M*N*P);CHKERRQ(ierr); 693b412c318SBarry Smith ierr = MatSetType(A,mtype);CHKERRQ(ierr); 69495ee5b0eSBarry Smith ierr = MatSetDM(A,da);CHKERRQ(ierr); 695b06ff27eSHong Zhang if (da->structure_only) { 696b06ff27eSHong Zhang ierr = MatSetOption(A,MAT_STRUCTURE_ONLY,PETSC_TRUE);CHKERRQ(ierr); 697b06ff27eSHong Zhang } 69847c6ae99SBarry Smith ierr = MatGetType(A,&Atype);CHKERRQ(ierr); 69947c6ae99SBarry Smith /* 700aa219208SBarry Smith We do not provide a getmatrix function in the DMDA operations because 701aa219208SBarry Smith the basic DMDA does not know about matrices. We think of DMDA as being more 70247c6ae99SBarry Smith more low-level than matrices. This is kind of cheating but, cause sometimes 703aa219208SBarry Smith we think of DMDA has higher level than matrices. 70447c6ae99SBarry Smith 70547c6ae99SBarry Smith We could switch based on Atype (or mtype), but we do not since the 70647c6ae99SBarry Smith specialized setting routines depend only the particular preallocation 70747c6ae99SBarry Smith details of the matrix, not the type itself. 70847c6ae99SBarry Smith */ 70947c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 71047c6ae99SBarry Smith if (!aij) { 71147c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 71247c6ae99SBarry Smith } 71347c6ae99SBarry Smith if (!aij) { 71447c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIBAIJSetPreallocation_C",&baij);CHKERRQ(ierr); 71547c6ae99SBarry Smith if (!baij) { 71647c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqBAIJSetPreallocation_C",&baij);CHKERRQ(ierr); 71747c6ae99SBarry Smith } 71847c6ae99SBarry Smith if (!baij) { 71947c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPISBAIJSetPreallocation_C",&sbaij);CHKERRQ(ierr); 72047c6ae99SBarry Smith if (!sbaij) { 72147c6ae99SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C",&sbaij);CHKERRQ(ierr); 72247c6ae99SBarry Smith } 7235e26d47bSHong Zhang if (!sbaij) { 724d4002b98SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPISELLSetPreallocation_C",&sell);CHKERRQ(ierr); 725d4002b98SHong Zhang if (!sell) { 726d4002b98SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqSELLSetPreallocation_C",&sell);CHKERRQ(ierr); 7275e26d47bSHong Zhang } 7285e26d47bSHong Zhang } 729e584696dSStefano Zampini if (!sell) { 730e584696dSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)A,"MatISSetPreallocation_C",&is);CHKERRQ(ierr); 731e584696dSStefano Zampini } 73247c6ae99SBarry Smith } 73347c6ae99SBarry Smith } 73447c6ae99SBarry Smith if (aij) { 73547c6ae99SBarry Smith if (dim == 1) { 736ce308e1dSBarry Smith if (dd->ofill) { 737ce308e1dSBarry Smith ierr = DMCreateMatrix_DA_1d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 738ce308e1dSBarry Smith } else { 739950540a4SJed Brown ierr = DMCreateMatrix_DA_1d_MPIAIJ(da,A);CHKERRQ(ierr); 740ce308e1dSBarry Smith } 74147c6ae99SBarry Smith } else if (dim == 2) { 74247c6ae99SBarry Smith if (dd->ofill) { 743950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 74447c6ae99SBarry Smith } else { 745950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIAIJ(da,A);CHKERRQ(ierr); 74647c6ae99SBarry Smith } 74747c6ae99SBarry Smith } else if (dim == 3) { 74847c6ae99SBarry Smith if (dd->ofill) { 749950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIAIJ_Fill(da,A);CHKERRQ(ierr); 75047c6ae99SBarry Smith } else { 751950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIAIJ(da,A);CHKERRQ(ierr); 75247c6ae99SBarry Smith } 75347c6ae99SBarry Smith } 75447c6ae99SBarry Smith } else if (baij) { 75547c6ae99SBarry Smith if (dim == 2) { 756950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPIBAIJ(da,A);CHKERRQ(ierr); 75747c6ae99SBarry Smith } else if (dim == 3) { 758950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPIBAIJ(da,A);CHKERRQ(ierr); 759ce94432eSBarry Smith } else SETERRQ3(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not implemented for %D dimension and Matrix Type: %s in %D dimension! Send mail to petsc-maint@mcs.anl.gov for code",dim,Atype,dim); 76047c6ae99SBarry Smith } else if (sbaij) { 76147c6ae99SBarry Smith if (dim == 2) { 762950540a4SJed Brown ierr = DMCreateMatrix_DA_2d_MPISBAIJ(da,A);CHKERRQ(ierr); 76347c6ae99SBarry Smith } else if (dim == 3) { 764950540a4SJed Brown ierr = DMCreateMatrix_DA_3d_MPISBAIJ(da,A);CHKERRQ(ierr); 765ce94432eSBarry Smith } else SETERRQ3(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not implemented for %D dimension and Matrix Type: %s in %D dimension! Send mail to petsc-maint@mcs.anl.gov for code",dim,Atype,dim); 766d4002b98SHong Zhang } else if (sell) { 7675e26d47bSHong Zhang if (dim == 2) { 768d4002b98SHong Zhang ierr = DMCreateMatrix_DA_2d_MPISELL(da,A);CHKERRQ(ierr); 769711261dbSHong Zhang } else if (dim == 3) { 770d4002b98SHong Zhang ierr = DMCreateMatrix_DA_3d_MPISELL(da,A);CHKERRQ(ierr); 7715e26d47bSHong Zhang } else SETERRQ3(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not implemented for %D dimension and Matrix Type: %s in %D dimension! Send mail to petsc-maint@mcs.anl.gov for code",dim,Atype,dim); 772e584696dSStefano Zampini } else if (is) { 773e584696dSStefano Zampini ierr = DMCreateMatrix_DA_IS(da,A);CHKERRQ(ierr); 774869776cdSLisandro Dalcin } else { 77545b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 776e584696dSStefano Zampini 777b026d285SBarry Smith ierr = MatSetBlockSize(A,dof);CHKERRQ(ierr); 7782949035bSJed Brown ierr = MatSetUp(A);CHKERRQ(ierr); 779b026d285SBarry Smith ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 780869776cdSLisandro Dalcin ierr = MatSetLocalToGlobalMapping(A,ltog,ltog);CHKERRQ(ierr); 78147c6ae99SBarry Smith } 782aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&starts[0],&starts[1],&starts[2],&dims[0],&dims[1],&dims[2]);CHKERRQ(ierr); 78347c6ae99SBarry Smith ierr = MatSetStencil(A,dim,dims,starts,dof);CHKERRQ(ierr); 784c688c046SMatthew G Knepley ierr = MatSetDM(A,da);CHKERRQ(ierr); 78547c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 78647c6ae99SBarry Smith if (size > 1) { 78747c6ae99SBarry Smith /* change viewer to display matrix in natural ordering */ 7880c0fd78eSBarry Smith ierr = MatSetOperation(A, MATOP_VIEW, (void (*)(void))MatView_MPI_DA);CHKERRQ(ierr); 7890c0fd78eSBarry Smith ierr = MatSetOperation(A, MATOP_LOAD, (void (*)(void))MatLoad_MPI_DA);CHKERRQ(ierr); 79047c6ae99SBarry Smith } 791b5579763SJed Brown ierr = MatSetFromOptions(A);CHKERRQ(ierr); 79247c6ae99SBarry Smith *J = A; 79347c6ae99SBarry Smith PetscFunctionReturn(0); 79447c6ae99SBarry Smith } 79547c6ae99SBarry Smith 79647c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 797e584696dSStefano Zampini PetscErrorCode DMCreateMatrix_DA_IS(DM dm,Mat J) 798e584696dSStefano Zampini { 799e584696dSStefano Zampini DM_DA *da = (DM_DA*)dm->data; 800e584696dSStefano Zampini Mat lJ; 801e584696dSStefano Zampini ISLocalToGlobalMapping ltog; 802e584696dSStefano Zampini IS is_loc_filt, is_glob; 80305339c03SStefano Zampini const PetscInt *e_loc,*idx; 80405339c03SStefano Zampini PetscInt i,nel,nen,dnz,nv,dof,dim,*gidx,nb; 805e584696dSStefano Zampini PetscErrorCode ierr; 806e584696dSStefano Zampini 807e584696dSStefano Zampini /* The l2g map of DMDA has all ghosted nodes, and e_loc is a subset of all the local nodes (including the ghosted) 808e584696dSStefano Zampini We need to filter the local indices that are represented through the DMDAGetElements decomposition 809e584696dSStefano Zampini This is because the size of the local matrices in MATIS is the local size of the l2g map */ 810e584696dSStefano Zampini PetscFunctionBegin; 811e584696dSStefano Zampini dof = da->w; 812e584696dSStefano Zampini dim = dm->dim; 81305339c03SStefano Zampini 81405339c03SStefano Zampini ierr = MatSetBlockSize(J,dof);CHKERRQ(ierr); 81505339c03SStefano Zampini 81605339c03SStefano Zampini /* get local elements indices in local DMDA numbering */ 817e584696dSStefano Zampini ierr = DMDAGetElements(dm,&nel,&nen,&e_loc);CHKERRQ(ierr); /* this will throw an error if the stencil type is not DMDA_STENCIL_BOX */ 818e584696dSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)dm),dof,nel*nen,e_loc,PETSC_COPY_VALUES,&is_loc_filt);CHKERRQ(ierr); 819e584696dSStefano Zampini ierr = DMDARestoreElements(dm,&nel,&nen,&e_loc);CHKERRQ(ierr); 82005339c03SStefano Zampini 82105339c03SStefano Zampini /* obtain a consistent local ordering for MATIS */ 822e584696dSStefano Zampini ierr = ISSortRemoveDups(is_loc_filt);CHKERRQ(ierr); 82305339c03SStefano Zampini ierr = ISBlockGetLocalSize(is_loc_filt,&nb);CHKERRQ(ierr); 82405339c03SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 82505339c03SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(ltog,&nv);CHKERRQ(ierr); 82605339c03SStefano Zampini ierr = PetscMalloc1(PetscMax(nb,nv/dof),&gidx);CHKERRQ(ierr); 82705339c03SStefano Zampini ierr = ISBlockGetIndices(is_loc_filt,&idx);CHKERRQ(ierr); 82805339c03SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(ltog,nb,idx,gidx);CHKERRQ(ierr); 82905339c03SStefano Zampini ierr = ISBlockRestoreIndices(is_loc_filt,&idx);CHKERRQ(ierr); 83005339c03SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)dm),dof,nb,gidx,PETSC_USE_POINTER,&is_glob);CHKERRQ(ierr); 831e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_glob,<og);CHKERRQ(ierr); 832e584696dSStefano Zampini ierr = ISDestroy(&is_glob);CHKERRQ(ierr); 833e584696dSStefano Zampini ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 834e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 83505339c03SStefano Zampini 836e584696dSStefano Zampini /* We also attach a l2g map to the local matrices to have MatSetValueLocal to work */ 837e584696dSStefano Zampini ierr = MatISGetLocalMat(J,&lJ);CHKERRQ(ierr); 838e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_loc_filt,<og);CHKERRQ(ierr); 839e584696dSStefano Zampini ierr = ISDestroy(&is_loc_filt);CHKERRQ(ierr); 84005339c03SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)lJ),nv/dof,0,1,&is_glob);CHKERRQ(ierr); 84105339c03SStefano Zampini ierr = ISGetIndices(is_glob,&idx);CHKERRQ(ierr); 84205339c03SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(ltog,IS_GTOLM_MASK,nv/dof,idx,&nb,gidx);CHKERRQ(ierr); 84305339c03SStefano Zampini ierr = ISRestoreIndices(is_glob,&idx);CHKERRQ(ierr); 844e584696dSStefano Zampini ierr = ISDestroy(&is_glob);CHKERRQ(ierr); 845e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 846722d6fa8SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,dof,nb,gidx,PETSC_USE_POINTER,&is_loc_filt);CHKERRQ(ierr); 847e584696dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_loc_filt,<og);CHKERRQ(ierr); 848e584696dSStefano Zampini ierr = ISDestroy(&is_loc_filt);CHKERRQ(ierr); 849e584696dSStefano Zampini ierr = MatSetLocalToGlobalMapping(lJ,ltog,ltog);CHKERRQ(ierr); 850e584696dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 85105339c03SStefano Zampini ierr = PetscFree(gidx);CHKERRQ(ierr); 85205339c03SStefano Zampini 853e584696dSStefano Zampini /* Preallocation (not exact) */ 854e584696dSStefano Zampini switch (da->elementtype) { 855e584696dSStefano Zampini case DMDA_ELEMENT_P1: 856e584696dSStefano Zampini case DMDA_ELEMENT_Q1: 857e584696dSStefano Zampini dnz = 1; 858e584696dSStefano Zampini for (i=0; i<dim; i++) dnz *= 3; 859e584696dSStefano Zampini dnz *= dof; 860e584696dSStefano Zampini break; 861e584696dSStefano Zampini default: 862e584696dSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Unhandled element type %d",da->elementtype); 863e584696dSStefano Zampini break; 864e584696dSStefano Zampini } 865e584696dSStefano Zampini ierr = MatSeqAIJSetPreallocation(lJ,dnz,NULL);CHKERRQ(ierr); 866e584696dSStefano Zampini ierr = MatSeqBAIJSetPreallocation(lJ,dof,dnz/dof,NULL);CHKERRQ(ierr); 867e584696dSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(lJ,dof,dnz/dof,NULL);CHKERRQ(ierr); 868e584696dSStefano Zampini ierr = MatISRestoreLocalMat(J,&lJ);CHKERRQ(ierr); 869e584696dSStefano Zampini PetscFunctionReturn(0); 870e584696dSStefano Zampini } 871e584696dSStefano Zampini 872d4002b98SHong Zhang PetscErrorCode DMCreateMatrix_DA_2d_MPISELL(DM da,Mat J) 8735e26d47bSHong Zhang { 8745e26d47bSHong Zhang PetscErrorCode ierr; 8755e26d47bSHong 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; 8765e26d47bSHong Zhang PetscInt lstart,lend,pstart,pend,*dnz,*onz; 8775e26d47bSHong Zhang MPI_Comm comm; 8785e26d47bSHong Zhang PetscScalar *values; 8795e26d47bSHong Zhang DMBoundaryType bx,by; 8805e26d47bSHong Zhang ISLocalToGlobalMapping ltog; 8815e26d47bSHong Zhang DMDAStencilType st; 8825e26d47bSHong Zhang 8835e26d47bSHong Zhang PetscFunctionBegin; 8845e26d47bSHong Zhang /* 8855e26d47bSHong Zhang nc - number of components per grid point 8865e26d47bSHong Zhang col - number of colors needed in one direction for single component problem 8875e26d47bSHong Zhang 8885e26d47bSHong Zhang */ 8895e26d47bSHong Zhang ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 8905e26d47bSHong Zhang col = 2*s + 1; 8915e26d47bSHong Zhang ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 8925e26d47bSHong Zhang ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 8935e26d47bSHong Zhang ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 8945e26d47bSHong Zhang 8955e26d47bSHong Zhang ierr = PetscMalloc2(nc,&rows,col*col*nc*nc,&cols);CHKERRQ(ierr); 8965e26d47bSHong Zhang ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 8975e26d47bSHong Zhang 8985e26d47bSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 8995e26d47bSHong Zhang /* determine the matrix preallocation information */ 9005e26d47bSHong Zhang ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 9015e26d47bSHong Zhang for (i=xs; i<xs+nx; i++) { 9025e26d47bSHong Zhang 9035e26d47bSHong Zhang pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 9045e26d47bSHong Zhang pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 9055e26d47bSHong Zhang 9065e26d47bSHong Zhang for (j=ys; j<ys+ny; j++) { 9075e26d47bSHong Zhang slot = i - gxs + gnx*(j - gys); 9085e26d47bSHong Zhang 9095e26d47bSHong Zhang lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 9105e26d47bSHong Zhang lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 9115e26d47bSHong Zhang 9125e26d47bSHong Zhang cnt = 0; 9135e26d47bSHong Zhang for (k=0; k<nc; k++) { 9145e26d47bSHong Zhang for (l=lstart; l<lend+1; l++) { 9155e26d47bSHong Zhang for (p=pstart; p<pend+1; p++) { 9165e26d47bSHong Zhang if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 9175e26d47bSHong Zhang cols[cnt++] = k + nc*(slot + gnx*l + p); 9185e26d47bSHong Zhang } 9195e26d47bSHong Zhang } 9205e26d47bSHong Zhang } 9215e26d47bSHong Zhang rows[k] = k + nc*(slot); 9225e26d47bSHong Zhang } 9235e26d47bSHong Zhang ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 9245e26d47bSHong Zhang } 9255e26d47bSHong Zhang } 9265e26d47bSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 927d4002b98SHong Zhang ierr = MatSeqSELLSetPreallocation(J,0,dnz);CHKERRQ(ierr); 928d4002b98SHong Zhang ierr = MatMPISELLSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 9295e26d47bSHong Zhang ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 9305e26d47bSHong Zhang 9315e26d47bSHong Zhang ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 9325e26d47bSHong Zhang 9335e26d47bSHong Zhang /* 9345e26d47bSHong Zhang For each node in the grid: we get the neighbors in the local (on processor ordering 9355e26d47bSHong Zhang that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 9365e26d47bSHong Zhang PETSc ordering. 9375e26d47bSHong Zhang */ 9385e26d47bSHong Zhang if (!da->prealloc_only) { 9395e26d47bSHong Zhang ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 9405e26d47bSHong Zhang for (i=xs; i<xs+nx; i++) { 9415e26d47bSHong Zhang 9425e26d47bSHong Zhang pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 9435e26d47bSHong Zhang pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 9445e26d47bSHong Zhang 9455e26d47bSHong Zhang for (j=ys; j<ys+ny; j++) { 9465e26d47bSHong Zhang slot = i - gxs + gnx*(j - gys); 9475e26d47bSHong Zhang 9485e26d47bSHong Zhang lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 9495e26d47bSHong Zhang lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 9505e26d47bSHong Zhang 9515e26d47bSHong Zhang cnt = 0; 9525e26d47bSHong Zhang for (k=0; k<nc; k++) { 9535e26d47bSHong Zhang for (l=lstart; l<lend+1; l++) { 9545e26d47bSHong Zhang for (p=pstart; p<pend+1; p++) { 9555e26d47bSHong Zhang if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 9565e26d47bSHong Zhang cols[cnt++] = k + nc*(slot + gnx*l + p); 9575e26d47bSHong Zhang } 9585e26d47bSHong Zhang } 9595e26d47bSHong Zhang } 9605e26d47bSHong Zhang rows[k] = k + nc*(slot); 9615e26d47bSHong Zhang } 9625e26d47bSHong Zhang ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 9635e26d47bSHong Zhang } 9645e26d47bSHong Zhang } 9655e26d47bSHong Zhang ierr = PetscFree(values);CHKERRQ(ierr); 9665e26d47bSHong Zhang ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9675e26d47bSHong Zhang ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9685e26d47bSHong Zhang ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 9695e26d47bSHong Zhang } 9705e26d47bSHong Zhang ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 9715e26d47bSHong Zhang PetscFunctionReturn(0); 9725e26d47bSHong Zhang } 9735e26d47bSHong Zhang 974d4002b98SHong Zhang PetscErrorCode DMCreateMatrix_DA_3d_MPISELL(DM da,Mat J) 975711261dbSHong Zhang { 976711261dbSHong Zhang PetscErrorCode ierr; 977711261dbSHong Zhang PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 978711261dbSHong Zhang PetscInt m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p,*dnz = NULL,*onz = NULL; 979711261dbSHong Zhang PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 980711261dbSHong Zhang MPI_Comm comm; 981711261dbSHong Zhang PetscScalar *values; 982711261dbSHong Zhang DMBoundaryType bx,by,bz; 983711261dbSHong Zhang ISLocalToGlobalMapping ltog; 984711261dbSHong Zhang DMDAStencilType st; 985711261dbSHong Zhang 986711261dbSHong Zhang PetscFunctionBegin; 987711261dbSHong Zhang /* 988711261dbSHong Zhang nc - number of components per grid point 989711261dbSHong Zhang col - number of colors needed in one direction for single component problem 990711261dbSHong Zhang 991711261dbSHong Zhang */ 992711261dbSHong Zhang ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 993711261dbSHong Zhang col = 2*s + 1; 994711261dbSHong Zhang ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 995711261dbSHong Zhang ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 996711261dbSHong Zhang ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 997711261dbSHong Zhang 998711261dbSHong Zhang ierr = PetscMalloc2(nc,&rows,col*col*col*nc*nc,&cols);CHKERRQ(ierr); 999711261dbSHong Zhang ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1000711261dbSHong Zhang 1001711261dbSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 1002711261dbSHong Zhang /* determine the matrix preallocation information */ 1003711261dbSHong Zhang ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 1004711261dbSHong Zhang for (i=xs; i<xs+nx; i++) { 1005711261dbSHong Zhang istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1006711261dbSHong Zhang iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 1007711261dbSHong Zhang for (j=ys; j<ys+ny; j++) { 1008711261dbSHong Zhang jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1009711261dbSHong Zhang jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 1010711261dbSHong Zhang for (k=zs; k<zs+nz; k++) { 1011711261dbSHong Zhang kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1012711261dbSHong Zhang kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 1013711261dbSHong Zhang 1014711261dbSHong Zhang slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 1015711261dbSHong Zhang 1016711261dbSHong Zhang cnt = 0; 1017711261dbSHong Zhang for (l=0; l<nc; l++) { 1018711261dbSHong Zhang for (ii=istart; ii<iend+1; ii++) { 1019711261dbSHong Zhang for (jj=jstart; jj<jend+1; jj++) { 1020711261dbSHong Zhang for (kk=kstart; kk<kend+1; kk++) { 1021711261dbSHong Zhang if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 1022711261dbSHong Zhang cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 1023711261dbSHong Zhang } 1024711261dbSHong Zhang } 1025711261dbSHong Zhang } 1026711261dbSHong Zhang } 1027711261dbSHong Zhang rows[l] = l + nc*(slot); 1028711261dbSHong Zhang } 1029711261dbSHong Zhang ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1030711261dbSHong Zhang } 1031711261dbSHong Zhang } 1032711261dbSHong Zhang } 1033711261dbSHong Zhang ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 1034d4002b98SHong Zhang ierr = MatSeqSELLSetPreallocation(J,0,dnz);CHKERRQ(ierr); 1035d4002b98SHong Zhang ierr = MatMPISELLSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 1036711261dbSHong Zhang ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1037711261dbSHong Zhang ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 1038711261dbSHong Zhang 1039711261dbSHong Zhang /* 1040711261dbSHong Zhang For each node in the grid: we get the neighbors in the local (on processor ordering 1041711261dbSHong Zhang that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 1042711261dbSHong Zhang PETSc ordering. 1043711261dbSHong Zhang */ 1044711261dbSHong Zhang if (!da->prealloc_only) { 1045711261dbSHong Zhang ierr = PetscCalloc1(col*col*col*nc*nc*nc,&values);CHKERRQ(ierr); 1046711261dbSHong Zhang for (i=xs; i<xs+nx; i++) { 1047711261dbSHong Zhang istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1048711261dbSHong Zhang iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 1049711261dbSHong Zhang for (j=ys; j<ys+ny; j++) { 1050711261dbSHong Zhang jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1051711261dbSHong Zhang jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 1052711261dbSHong Zhang for (k=zs; k<zs+nz; k++) { 1053711261dbSHong Zhang kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1054711261dbSHong Zhang kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 1055711261dbSHong Zhang 1056711261dbSHong Zhang slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 1057711261dbSHong Zhang 1058711261dbSHong Zhang cnt = 0; 1059711261dbSHong Zhang for (l=0; l<nc; l++) { 1060711261dbSHong Zhang for (ii=istart; ii<iend+1; ii++) { 1061711261dbSHong Zhang for (jj=jstart; jj<jend+1; jj++) { 1062711261dbSHong Zhang for (kk=kstart; kk<kend+1; kk++) { 1063711261dbSHong Zhang if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 1064711261dbSHong Zhang cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 1065711261dbSHong Zhang } 1066711261dbSHong Zhang } 1067711261dbSHong Zhang } 1068711261dbSHong Zhang } 1069711261dbSHong Zhang rows[l] = l + nc*(slot); 1070711261dbSHong Zhang } 1071711261dbSHong Zhang ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1072711261dbSHong Zhang } 1073711261dbSHong Zhang } 1074711261dbSHong Zhang } 1075711261dbSHong Zhang ierr = PetscFree(values);CHKERRQ(ierr); 1076711261dbSHong Zhang ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1077711261dbSHong Zhang ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1078711261dbSHong Zhang ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 1079711261dbSHong Zhang } 1080711261dbSHong Zhang ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 1081711261dbSHong Zhang PetscFunctionReturn(0); 1082711261dbSHong Zhang } 1083711261dbSHong Zhang 1084950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ(DM da,Mat J) 108547c6ae99SBarry Smith { 108647c6ae99SBarry Smith PetscErrorCode ierr; 1087c1154cd5SBarry 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; 108847c6ae99SBarry Smith PetscInt lstart,lend,pstart,pend,*dnz,*onz; 108947c6ae99SBarry Smith MPI_Comm comm; 109047c6ae99SBarry Smith PetscScalar *values; 1091bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 109245b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1093aa219208SBarry Smith DMDAStencilType st; 1094c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 109547c6ae99SBarry Smith 109647c6ae99SBarry Smith PetscFunctionBegin; 109747c6ae99SBarry Smith /* 109847c6ae99SBarry Smith nc - number of components per grid point 109947c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 110047c6ae99SBarry Smith 110147c6ae99SBarry Smith */ 1102c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&M,&N,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 110347c6ae99SBarry Smith col = 2*s + 1; 1104c1154cd5SBarry Smith /* 1105c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1106c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1107c1154cd5SBarry Smith */ 1108c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1109c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1110aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1111aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 111247c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 111347c6ae99SBarry Smith 1114dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*col*nc*nc,&cols);CHKERRQ(ierr); 11151411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 111647c6ae99SBarry Smith 111706ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 111847c6ae99SBarry Smith /* determine the matrix preallocation information */ 111947c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 112047c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 112147c6ae99SBarry Smith 1122bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1123bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 112447c6ae99SBarry Smith 112547c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 112647c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 112747c6ae99SBarry Smith 1128bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1129bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 113047c6ae99SBarry Smith 113147c6ae99SBarry Smith cnt = 0; 113247c6ae99SBarry Smith for (k=0; k<nc; k++) { 113347c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 113447c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 1135aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 113647c6ae99SBarry Smith cols[cnt++] = k + nc*(slot + gnx*l + p); 113747c6ae99SBarry Smith } 113847c6ae99SBarry Smith } 113947c6ae99SBarry Smith } 114047c6ae99SBarry Smith rows[k] = k + nc*(slot); 114147c6ae99SBarry Smith } 1142c1154cd5SBarry Smith if (removedups) { 1143c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1144c1154cd5SBarry Smith } else { 1145784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 114647c6ae99SBarry Smith } 114747c6ae99SBarry Smith } 1148c1154cd5SBarry Smith } 1149f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 115047c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 115147c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 115247c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 115347c6ae99SBarry Smith 1154784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 115547c6ae99SBarry Smith 115647c6ae99SBarry Smith /* 115747c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 115847c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 115947c6ae99SBarry Smith PETSc ordering. 116047c6ae99SBarry Smith */ 1161fcfd50ebSBarry Smith if (!da->prealloc_only) { 11621795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 116347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 116447c6ae99SBarry Smith 1165bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1166bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 116747c6ae99SBarry Smith 116847c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 116947c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 117047c6ae99SBarry Smith 1171bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1172bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 117347c6ae99SBarry Smith 117447c6ae99SBarry Smith cnt = 0; 117547c6ae99SBarry Smith for (k=0; k<nc; k++) { 117647c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 117747c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 1178aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star have either l = 0 or p = 0 */ 117947c6ae99SBarry Smith cols[cnt++] = k + nc*(slot + gnx*l + p); 118047c6ae99SBarry Smith } 118147c6ae99SBarry Smith } 118247c6ae99SBarry Smith } 118347c6ae99SBarry Smith rows[k] = k + nc*(slot); 118447c6ae99SBarry Smith } 118547c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 118647c6ae99SBarry Smith } 118747c6ae99SBarry Smith } 118847c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 118947c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 119047c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1191189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 119247c6ae99SBarry Smith } 119347c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 119447c6ae99SBarry Smith PetscFunctionReturn(0); 119547c6ae99SBarry Smith } 119647c6ae99SBarry Smith 1197950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIAIJ_Fill(DM da,Mat J) 119847c6ae99SBarry Smith { 119947c6ae99SBarry Smith PetscErrorCode ierr; 120047c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 1201c1154cd5SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,row,col,cnt,maxcnt = 0,l,p,M,N; 120247c6ae99SBarry Smith PetscInt lstart,lend,pstart,pend,*dnz,*onz; 120347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 120447c6ae99SBarry Smith PetscInt ifill_col,*ofill = dd->ofill, *dfill = dd->dfill; 120547c6ae99SBarry Smith MPI_Comm comm; 120647c6ae99SBarry Smith PetscScalar *values; 1207bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 120845b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1209aa219208SBarry Smith DMDAStencilType st; 1210c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 121147c6ae99SBarry Smith 121247c6ae99SBarry Smith PetscFunctionBegin; 121347c6ae99SBarry Smith /* 121447c6ae99SBarry Smith nc - number of components per grid point 121547c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 121647c6ae99SBarry Smith 121747c6ae99SBarry Smith */ 1218c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&M,&N,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 121947c6ae99SBarry Smith col = 2*s + 1; 1220c1154cd5SBarry Smith /* 1221c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1222c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1223c1154cd5SBarry Smith */ 1224c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1225c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1226aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1227aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 122847c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 122947c6ae99SBarry Smith 12304b26d1cfSBarry Smith ierr = PetscMalloc1(col*col*nc,&cols);CHKERRQ(ierr); 12311411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 123247c6ae99SBarry Smith 123306ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 123447c6ae99SBarry Smith /* determine the matrix preallocation information */ 123547c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny,nc*nx*ny,dnz,onz);CHKERRQ(ierr); 123647c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 123747c6ae99SBarry Smith 1238bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1239bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 124047c6ae99SBarry Smith 124147c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 124247c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 124347c6ae99SBarry Smith 1244bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1245bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 124647c6ae99SBarry Smith 124747c6ae99SBarry Smith for (k=0; k<nc; k++) { 124847c6ae99SBarry Smith cnt = 0; 124947c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 125047c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 125147c6ae99SBarry Smith if (l || p) { 1252aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star */ 12538865f1eaSKarl Rupp for (ifill_col=ofill[k]; ifill_col<ofill[k+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + gnx*l + p); 125447c6ae99SBarry Smith } 125547c6ae99SBarry Smith } else { 125647c6ae99SBarry Smith if (dfill) { 12578865f1eaSKarl Rupp for (ifill_col=dfill[k]; ifill_col<dfill[k+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + gnx*l + p); 125847c6ae99SBarry Smith } else { 12598865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + gnx*l + p); 126047c6ae99SBarry Smith } 126147c6ae99SBarry Smith } 126247c6ae99SBarry Smith } 126347c6ae99SBarry Smith } 126447c6ae99SBarry Smith row = k + nc*(slot); 1265c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,cnt); 1266c1154cd5SBarry Smith if (removedups) { 1267c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1268c1154cd5SBarry Smith } else { 1269784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 127047c6ae99SBarry Smith } 127147c6ae99SBarry Smith } 127247c6ae99SBarry Smith } 1273c1154cd5SBarry Smith } 127447c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 127547c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 127647c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1277784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 127847c6ae99SBarry Smith 127947c6ae99SBarry Smith /* 128047c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 128147c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 128247c6ae99SBarry Smith PETSc ordering. 128347c6ae99SBarry Smith */ 1284fcfd50ebSBarry Smith if (!da->prealloc_only) { 1285c0ab637bSBarry Smith ierr = PetscCalloc1(maxcnt,&values);CHKERRQ(ierr); 128647c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 128747c6ae99SBarry Smith 1288bff4a2f0SMatthew G. Knepley pstart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1289bff4a2f0SMatthew G. Knepley pend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 129047c6ae99SBarry Smith 129147c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 129247c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 129347c6ae99SBarry Smith 1294bff4a2f0SMatthew G. Knepley lstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1295bff4a2f0SMatthew G. Knepley lend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 129647c6ae99SBarry Smith 129747c6ae99SBarry Smith for (k=0; k<nc; k++) { 129847c6ae99SBarry Smith cnt = 0; 129947c6ae99SBarry Smith for (l=lstart; l<lend+1; l++) { 130047c6ae99SBarry Smith for (p=pstart; p<pend+1; p++) { 130147c6ae99SBarry Smith if (l || p) { 1302aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!l || !p)) { /* entries on star */ 13038865f1eaSKarl Rupp for (ifill_col=ofill[k]; ifill_col<ofill[k+1]; ifill_col++) cols[cnt++] = ofill[ifill_col] + nc*(slot + gnx*l + p); 130447c6ae99SBarry Smith } 130547c6ae99SBarry Smith } else { 130647c6ae99SBarry Smith if (dfill) { 13078865f1eaSKarl Rupp for (ifill_col=dfill[k]; ifill_col<dfill[k+1]; ifill_col++) cols[cnt++] = dfill[ifill_col] + nc*(slot + gnx*l + p); 130847c6ae99SBarry Smith } else { 13098865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + gnx*l + p); 131047c6ae99SBarry Smith } 131147c6ae99SBarry Smith } 131247c6ae99SBarry Smith } 131347c6ae99SBarry Smith } 131447c6ae99SBarry Smith row = k + nc*(slot); 131547c6ae99SBarry Smith ierr = MatSetValuesLocal(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 131647c6ae99SBarry Smith } 131747c6ae99SBarry Smith } 131847c6ae99SBarry Smith } 131947c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 132047c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 132147c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1322189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 132347c6ae99SBarry Smith } 132447c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 132547c6ae99SBarry Smith PetscFunctionReturn(0); 132647c6ae99SBarry Smith } 132747c6ae99SBarry Smith 132847c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 132947c6ae99SBarry Smith 1330950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ(DM da,Mat J) 133147c6ae99SBarry Smith { 133247c6ae99SBarry Smith PetscErrorCode ierr; 133347c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 13340298fd71SBarry Smith PetscInt m,n,dim,s,*cols = NULL,k,nc,*rows = NULL,col,cnt,l,p,*dnz = NULL,*onz = NULL; 1335c1154cd5SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 133647c6ae99SBarry Smith MPI_Comm comm; 133747c6ae99SBarry Smith PetscScalar *values; 1338bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 133945b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1340aa219208SBarry Smith DMDAStencilType st; 1341c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 134247c6ae99SBarry Smith 134347c6ae99SBarry Smith PetscFunctionBegin; 134447c6ae99SBarry Smith /* 134547c6ae99SBarry Smith nc - number of components per grid point 134647c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 134747c6ae99SBarry Smith 134847c6ae99SBarry Smith */ 1349c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 135047c6ae99SBarry Smith col = 2*s + 1; 135147c6ae99SBarry Smith 1352c1154cd5SBarry Smith /* 1353c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 1354c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 1355c1154cd5SBarry Smith */ 1356c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 1357c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 1358c1154cd5SBarry Smith if (P == 1 && 2*s >= p) removedups = PETSC_TRUE; 1359c1154cd5SBarry Smith 1360aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1361aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 136247c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 136347c6ae99SBarry Smith 1364dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*col*col*nc*nc,&cols);CHKERRQ(ierr); 13651411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 136647c6ae99SBarry Smith 136706ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 136847c6ae99SBarry Smith /* determine the matrix preallocation information */ 136947c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 137047c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1371bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1372bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 137347c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1374bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1375bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 137647c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1377bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1378bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 137947c6ae99SBarry Smith 138047c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 138147c6ae99SBarry Smith 138247c6ae99SBarry Smith cnt = 0; 138347c6ae99SBarry Smith for (l=0; l<nc; l++) { 138447c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 138547c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 138647c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1387aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 138847c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 138947c6ae99SBarry Smith } 139047c6ae99SBarry Smith } 139147c6ae99SBarry Smith } 139247c6ae99SBarry Smith } 139347c6ae99SBarry Smith rows[l] = l + nc*(slot); 139447c6ae99SBarry Smith } 1395c1154cd5SBarry Smith if (removedups) { 1396c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 1397c1154cd5SBarry Smith } else { 1398784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,nc,rows,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 139947c6ae99SBarry Smith } 140047c6ae99SBarry Smith } 140147c6ae99SBarry Smith } 1402c1154cd5SBarry Smith } 1403f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 140447c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 140547c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 140647c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1407784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 140847c6ae99SBarry Smith 140947c6ae99SBarry Smith /* 141047c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 141147c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 141247c6ae99SBarry Smith PETSc ordering. 141347c6ae99SBarry Smith */ 1414fcfd50ebSBarry Smith if (!da->prealloc_only) { 14151795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc*nc,&values);CHKERRQ(ierr); 141647c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1417bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1418bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 141947c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1420bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1421bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 142247c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1423bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1424bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 142547c6ae99SBarry Smith 142647c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 142747c6ae99SBarry Smith 142847c6ae99SBarry Smith cnt = 0; 142947c6ae99SBarry Smith for (l=0; l<nc; l++) { 143047c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 143147c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 143247c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1433aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 143447c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + ii + gnx*jj + gnx*gny*kk); 143547c6ae99SBarry Smith } 143647c6ae99SBarry Smith } 143747c6ae99SBarry Smith } 143847c6ae99SBarry Smith } 143947c6ae99SBarry Smith rows[l] = l + nc*(slot); 144047c6ae99SBarry Smith } 144147c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 144247c6ae99SBarry Smith } 144347c6ae99SBarry Smith } 144447c6ae99SBarry Smith } 144547c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 144647c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 144747c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1448189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 144947c6ae99SBarry Smith } 145047c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 145147c6ae99SBarry Smith PetscFunctionReturn(0); 145247c6ae99SBarry Smith } 145347c6ae99SBarry Smith 145447c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 145547c6ae99SBarry Smith 1456ce308e1dSBarry Smith PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ_Fill(DM da,Mat J) 1457ce308e1dSBarry Smith { 1458ce308e1dSBarry Smith PetscErrorCode ierr; 1459ce308e1dSBarry Smith DM_DA *dd = (DM_DA*)da->data; 1460ce308e1dSBarry Smith PetscInt xs,nx,i,j,gxs,gnx,row,k,l; 14618d4c968fSBarry Smith PetscInt m,dim,s,*cols = NULL,nc,cnt,maxcnt = 0,*ocols; 14620acb5bebSBarry Smith PetscInt *ofill = dd->ofill,*dfill = dd->dfill; 1463ce308e1dSBarry Smith PetscScalar *values; 1464bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 146545b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 1466ce308e1dSBarry Smith PetscMPIInt rank,size; 1467ce308e1dSBarry Smith 1468ce308e1dSBarry Smith PetscFunctionBegin; 1469bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"With fill provided not implemented with periodic boundary conditions"); 1470ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)da),&rank);CHKERRQ(ierr); 1471ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)da),&size);CHKERRQ(ierr); 1472ce308e1dSBarry Smith 1473ce308e1dSBarry Smith /* 1474ce308e1dSBarry Smith nc - number of components per grid point 1475ce308e1dSBarry Smith 1476ce308e1dSBarry Smith */ 1477ce308e1dSBarry Smith ierr = DMDAGetInfo(da,&dim,&m,0,0,0,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 1478ce308e1dSBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 1479ce308e1dSBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 1480ce308e1dSBarry Smith 1481ce308e1dSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 14821795a4d1SJed Brown ierr = PetscCalloc2(nx*nc,&cols,nx*nc,&ocols);CHKERRQ(ierr); 1483ce308e1dSBarry Smith 1484ce308e1dSBarry Smith /* 1485ce308e1dSBarry Smith note should be smaller for first and last process with no periodic 1486ce308e1dSBarry Smith does not handle dfill 1487ce308e1dSBarry Smith */ 1488ce308e1dSBarry Smith cnt = 0; 1489ce308e1dSBarry Smith /* coupling with process to the left */ 1490ce308e1dSBarry Smith for (i=0; i<s; i++) { 1491ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1492ce308e1dSBarry Smith ocols[cnt] = ((!rank) ? 0 : (s - i)*(ofill[j+1] - ofill[j])); 14930acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + (s + i)*(ofill[j+1] - ofill[j]); 1494c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1495ce308e1dSBarry Smith cnt++; 1496ce308e1dSBarry Smith } 1497ce308e1dSBarry Smith } 1498ce308e1dSBarry Smith for (i=s; i<nx-s; i++) { 1499ce308e1dSBarry Smith for (j=0; j<nc; j++) { 15000acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + 2*s*(ofill[j+1] - ofill[j]); 1501c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1502ce308e1dSBarry Smith cnt++; 1503ce308e1dSBarry Smith } 1504ce308e1dSBarry Smith } 1505ce308e1dSBarry Smith /* coupling with process to the right */ 1506ce308e1dSBarry Smith for (i=nx-s; i<nx; i++) { 1507ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1508ce308e1dSBarry Smith ocols[cnt] = ((rank == (size-1)) ? 0 : (i - nx + s + 1)*(ofill[j+1] - ofill[j])); 15090acb5bebSBarry Smith cols[cnt] = dfill[j+1] - dfill[j] + (s + nx - i - 1)*(ofill[j+1] - ofill[j]); 1510c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,ocols[cnt]+cols[cnt]); 1511ce308e1dSBarry Smith cnt++; 1512ce308e1dSBarry Smith } 1513ce308e1dSBarry Smith } 1514ce308e1dSBarry Smith 1515ce308e1dSBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,cols);CHKERRQ(ierr); 1516ce308e1dSBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,cols,0,ocols);CHKERRQ(ierr); 1517ce308e1dSBarry Smith ierr = PetscFree2(cols,ocols);CHKERRQ(ierr); 1518ce308e1dSBarry Smith 1519ce308e1dSBarry Smith ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1520ce308e1dSBarry Smith ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 1521ce308e1dSBarry Smith 1522ce308e1dSBarry Smith /* 1523ce308e1dSBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 1524ce308e1dSBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 1525ce308e1dSBarry Smith PETSc ordering. 1526ce308e1dSBarry Smith */ 1527ce308e1dSBarry Smith if (!da->prealloc_only) { 1528c0ab637bSBarry Smith ierr = PetscCalloc2(maxcnt,&values,maxcnt,&cols);CHKERRQ(ierr); 1529ce308e1dSBarry Smith 1530ce308e1dSBarry Smith row = xs*nc; 1531ce308e1dSBarry Smith /* coupling with process to the left */ 1532ce308e1dSBarry Smith for (i=xs; i<xs+s; i++) { 1533ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1534ce308e1dSBarry Smith cnt = 0; 1535ce308e1dSBarry Smith if (rank) { 1536ce308e1dSBarry Smith for (l=0; l<s; l++) { 1537ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1538ce308e1dSBarry Smith } 1539ce308e1dSBarry Smith } 15400acb5bebSBarry Smith if (dfill) { 15410acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 15420acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 15430acb5bebSBarry Smith } 15440acb5bebSBarry Smith } else { 1545ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1546ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1547ce308e1dSBarry Smith } 15480acb5bebSBarry Smith } 1549ce308e1dSBarry Smith for (l=0; l<s; l++) { 1550ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1551ce308e1dSBarry Smith } 1552ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1553ce308e1dSBarry Smith row++; 1554ce308e1dSBarry Smith } 1555ce308e1dSBarry Smith } 1556ce308e1dSBarry Smith for (i=xs+s; i<xs+nx-s; i++) { 1557ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1558ce308e1dSBarry Smith cnt = 0; 1559ce308e1dSBarry Smith for (l=0; l<s; l++) { 1560ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1561ce308e1dSBarry Smith } 15620acb5bebSBarry Smith if (dfill) { 15630acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 15640acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 15650acb5bebSBarry Smith } 15660acb5bebSBarry Smith } else { 1567ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1568ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1569ce308e1dSBarry Smith } 15700acb5bebSBarry Smith } 1571ce308e1dSBarry Smith for (l=0; l<s; l++) { 1572ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1573ce308e1dSBarry Smith } 1574ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1575ce308e1dSBarry Smith row++; 1576ce308e1dSBarry Smith } 1577ce308e1dSBarry Smith } 1578ce308e1dSBarry Smith /* coupling with process to the right */ 1579ce308e1dSBarry Smith for (i=xs+nx-s; i<xs+nx; i++) { 1580ce308e1dSBarry Smith for (j=0; j<nc; j++) { 1581ce308e1dSBarry Smith cnt = 0; 1582ce308e1dSBarry Smith for (l=0; l<s; l++) { 1583ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i - s + l)*nc + ofill[k]; 1584ce308e1dSBarry Smith } 15850acb5bebSBarry Smith if (dfill) { 15860acb5bebSBarry Smith for (k=dfill[j]; k<dfill[j+1]; k++) { 15870acb5bebSBarry Smith cols[cnt++] = i*nc + dfill[k]; 15880acb5bebSBarry Smith } 15890acb5bebSBarry Smith } else { 1590ce308e1dSBarry Smith for (k=0; k<nc; k++) { 1591ce308e1dSBarry Smith cols[cnt++] = i*nc + k; 1592ce308e1dSBarry Smith } 15930acb5bebSBarry Smith } 1594ce308e1dSBarry Smith if (rank < size-1) { 1595ce308e1dSBarry Smith for (l=0; l<s; l++) { 1596ce308e1dSBarry Smith for (k=ofill[j]; k<ofill[j+1]; k++) cols[cnt++] = (i + s - l)*nc + ofill[k]; 1597ce308e1dSBarry Smith } 1598ce308e1dSBarry Smith } 1599ce308e1dSBarry Smith ierr = MatSetValues(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 1600ce308e1dSBarry Smith row++; 1601ce308e1dSBarry Smith } 1602ce308e1dSBarry Smith } 1603c0ab637bSBarry Smith ierr = PetscFree2(values,cols);CHKERRQ(ierr); 1604ce308e1dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1605ce308e1dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1606189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 1607ce308e1dSBarry Smith } 1608ce308e1dSBarry Smith PetscFunctionReturn(0); 1609ce308e1dSBarry Smith } 1610ce308e1dSBarry Smith 1611ce308e1dSBarry Smith /* ---------------------------------------------------------------------------------*/ 1612ce308e1dSBarry Smith 1613950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_1d_MPIAIJ(DM da,Mat J) 161447c6ae99SBarry Smith { 161547c6ae99SBarry Smith PetscErrorCode ierr; 161647c6ae99SBarry Smith PetscInt xs,nx,i,i1,slot,gxs,gnx; 16170298fd71SBarry Smith PetscInt m,dim,s,*cols = NULL,nc,*rows = NULL,col,cnt,l; 161847c6ae99SBarry Smith PetscInt istart,iend; 161947c6ae99SBarry Smith PetscScalar *values; 1620bff4a2f0SMatthew G. Knepley DMBoundaryType bx; 162145b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 162247c6ae99SBarry Smith 162347c6ae99SBarry Smith PetscFunctionBegin; 162447c6ae99SBarry Smith /* 162547c6ae99SBarry Smith nc - number of components per grid point 162647c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 162747c6ae99SBarry Smith 162847c6ae99SBarry Smith */ 16291321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,0,0,0,0,0,&nc,&s,&bx,0,0,0);CHKERRQ(ierr); 163047c6ae99SBarry Smith col = 2*s + 1; 163147c6ae99SBarry Smith 1632aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,0,0,&nx,0,0);CHKERRQ(ierr); 1633aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,0,0,&gnx,0,0);CHKERRQ(ierr); 163447c6ae99SBarry Smith 1635f73d5cc4SBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 163647c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,col*nc,0);CHKERRQ(ierr); 163747c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,col*nc,0,col*nc,0);CHKERRQ(ierr); 163847c6ae99SBarry Smith 16391411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 1640784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 164147c6ae99SBarry Smith 164247c6ae99SBarry Smith /* 164347c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 164447c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 164547c6ae99SBarry Smith PETSc ordering. 164647c6ae99SBarry Smith */ 1647fcfd50ebSBarry Smith if (!da->prealloc_only) { 1648dcca6d9dSJed Brown ierr = PetscMalloc2(nc,&rows,col*nc*nc,&cols);CHKERRQ(ierr); 16491795a4d1SJed Brown ierr = PetscCalloc1(col*nc*nc,&values);CHKERRQ(ierr); 165047c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 165147c6ae99SBarry Smith istart = PetscMax(-s,gxs - i); 165247c6ae99SBarry Smith iend = PetscMin(s,gxs + gnx - i - 1); 165347c6ae99SBarry Smith slot = i - gxs; 165447c6ae99SBarry Smith 165547c6ae99SBarry Smith cnt = 0; 165647c6ae99SBarry Smith for (l=0; l<nc; l++) { 165747c6ae99SBarry Smith for (i1=istart; i1<iend+1; i1++) { 165847c6ae99SBarry Smith cols[cnt++] = l + nc*(slot + i1); 165947c6ae99SBarry Smith } 166047c6ae99SBarry Smith rows[l] = l + nc*(slot); 166147c6ae99SBarry Smith } 166247c6ae99SBarry Smith ierr = MatSetValuesLocal(J,nc,rows,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 166347c6ae99SBarry Smith } 166447c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 166547c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 166647c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1667189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 166847c6ae99SBarry Smith ierr = PetscFree2(rows,cols);CHKERRQ(ierr); 1669ce308e1dSBarry Smith } 167047c6ae99SBarry Smith PetscFunctionReturn(0); 167147c6ae99SBarry Smith } 167247c6ae99SBarry Smith 1673950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPIBAIJ(DM da,Mat J) 167447c6ae99SBarry Smith { 167547c6ae99SBarry Smith PetscErrorCode ierr; 167647c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 167747c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,nc,col,cnt,*dnz,*onz; 167847c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,ii,jj; 167947c6ae99SBarry Smith MPI_Comm comm; 168047c6ae99SBarry Smith PetscScalar *values; 1681bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 1682aa219208SBarry Smith DMDAStencilType st; 168345b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 168447c6ae99SBarry Smith 168547c6ae99SBarry Smith PetscFunctionBegin; 168647c6ae99SBarry Smith /* 168747c6ae99SBarry Smith nc - number of components per grid point 168847c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 168947c6ae99SBarry Smith */ 16901321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 169147c6ae99SBarry Smith col = 2*s + 1; 169247c6ae99SBarry Smith 1693aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1694aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 169547c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 169647c6ae99SBarry Smith 1697785e854fSJed Brown ierr = PetscMalloc1(col*col*nc*nc,&cols);CHKERRQ(ierr); 169847c6ae99SBarry Smith 16991411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 170047c6ae99SBarry Smith 170147c6ae99SBarry Smith /* determine the matrix preallocation information */ 170247c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nx*ny,nx*ny,dnz,onz);CHKERRQ(ierr); 170347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1704bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1705bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 170647c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1707bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1708bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 170947c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 171047c6ae99SBarry Smith 171147c6ae99SBarry Smith /* Find block columns in block row */ 171247c6ae99SBarry Smith cnt = 0; 171347c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 171447c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1715aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { /* BOX or on the STAR */ 171647c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 171747c6ae99SBarry Smith } 171847c6ae99SBarry Smith } 171947c6ae99SBarry Smith } 1720d6e23781SBarry Smith ierr = MatPreallocateSetLocalBlock(ltog,1,&slot,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 172147c6ae99SBarry Smith } 172247c6ae99SBarry Smith } 172347c6ae99SBarry Smith ierr = MatSeqBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 172447c6ae99SBarry Smith ierr = MatMPIBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 172547c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 172647c6ae99SBarry Smith 1727784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 172847c6ae99SBarry Smith 172947c6ae99SBarry Smith /* 173047c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 173147c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 173247c6ae99SBarry Smith PETSc ordering. 173347c6ae99SBarry Smith */ 1734fcfd50ebSBarry Smith if (!da->prealloc_only) { 17351795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 173647c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1737bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1738bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 173947c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1740bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1741bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 174247c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 174347c6ae99SBarry Smith cnt = 0; 174447c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 174547c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1746aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { /* BOX or on the STAR */ 174747c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 174847c6ae99SBarry Smith } 174947c6ae99SBarry Smith } 175047c6ae99SBarry Smith } 175147c6ae99SBarry Smith ierr = MatSetValuesBlockedLocal(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 175247c6ae99SBarry Smith } 175347c6ae99SBarry Smith } 175447c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 175547c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 175647c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1757189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 175847c6ae99SBarry Smith } 175947c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 176047c6ae99SBarry Smith PetscFunctionReturn(0); 176147c6ae99SBarry Smith } 176247c6ae99SBarry Smith 1763950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIBAIJ(DM da,Mat J) 176447c6ae99SBarry Smith { 176547c6ae99SBarry Smith PetscErrorCode ierr; 176647c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 176747c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,col,cnt,p,*dnz,*onz; 176847c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk; 176947c6ae99SBarry Smith MPI_Comm comm; 177047c6ae99SBarry Smith PetscScalar *values; 1771bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 1772aa219208SBarry Smith DMDAStencilType st; 177345b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 177447c6ae99SBarry Smith 177547c6ae99SBarry Smith PetscFunctionBegin; 177647c6ae99SBarry Smith /* 177747c6ae99SBarry Smith nc - number of components per grid point 177847c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 177947c6ae99SBarry Smith 178047c6ae99SBarry Smith */ 17811321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,0,0,0,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 178247c6ae99SBarry Smith col = 2*s + 1; 178347c6ae99SBarry Smith 1784aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 1785aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 178647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 178747c6ae99SBarry Smith 1788785e854fSJed Brown ierr = PetscMalloc1(col*col*col,&cols);CHKERRQ(ierr); 178947c6ae99SBarry Smith 17901411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 179147c6ae99SBarry Smith 179247c6ae99SBarry Smith /* determine the matrix preallocation information */ 179347c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nx*ny*nz,nx*ny*nz,dnz,onz);CHKERRQ(ierr); 179447c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1795bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1796bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 179747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1798bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1799bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 180047c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1801bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1802bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 180347c6ae99SBarry Smith 180447c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 180547c6ae99SBarry Smith 180647c6ae99SBarry Smith /* Find block columns in block row */ 180747c6ae99SBarry Smith cnt = 0; 180847c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 180947c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 181047c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1811aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 181247c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 181347c6ae99SBarry Smith } 181447c6ae99SBarry Smith } 181547c6ae99SBarry Smith } 181647c6ae99SBarry Smith } 1817d6e23781SBarry Smith ierr = MatPreallocateSetLocalBlock(ltog,1,&slot,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 181847c6ae99SBarry Smith } 181947c6ae99SBarry Smith } 182047c6ae99SBarry Smith } 182147c6ae99SBarry Smith ierr = MatSeqBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 182247c6ae99SBarry Smith ierr = MatMPIBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 182347c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 182447c6ae99SBarry Smith 1825784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 182647c6ae99SBarry Smith 182747c6ae99SBarry Smith /* 182847c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 182947c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 183047c6ae99SBarry Smith PETSc ordering. 183147c6ae99SBarry Smith */ 1832fcfd50ebSBarry Smith if (!da->prealloc_only) { 18331795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc,&values);CHKERRQ(ierr); 183447c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1835bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1836bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 183747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1838bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1839bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 184047c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 1841bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 1842bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 184347c6ae99SBarry Smith 184447c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 184547c6ae99SBarry Smith 184647c6ae99SBarry Smith cnt = 0; 184747c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 184847c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 184947c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 1850aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 185147c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 185247c6ae99SBarry Smith } 185347c6ae99SBarry Smith } 185447c6ae99SBarry Smith } 185547c6ae99SBarry Smith } 185647c6ae99SBarry Smith ierr = MatSetValuesBlockedLocal(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 185747c6ae99SBarry Smith } 185847c6ae99SBarry Smith } 185947c6ae99SBarry Smith } 186047c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 186147c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 186247c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1863189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 186447c6ae99SBarry Smith } 186547c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 186647c6ae99SBarry Smith PetscFunctionReturn(0); 186747c6ae99SBarry Smith } 186847c6ae99SBarry Smith 186947c6ae99SBarry Smith /* 187047c6ae99SBarry Smith This helper is for of SBAIJ preallocation, to discard the lower-triangular values which are difficult to 187147c6ae99SBarry Smith identify in the local ordering with periodic domain. 187247c6ae99SBarry Smith */ 187347c6ae99SBarry Smith static PetscErrorCode L2GFilterUpperTriangular(ISLocalToGlobalMapping ltog,PetscInt *row,PetscInt *cnt,PetscInt col[]) 187447c6ae99SBarry Smith { 187547c6ae99SBarry Smith PetscErrorCode ierr; 187647c6ae99SBarry Smith PetscInt i,n; 187747c6ae99SBarry Smith 187847c6ae99SBarry Smith PetscFunctionBegin; 1879d6e23781SBarry Smith ierr = ISLocalToGlobalMappingApplyBlock(ltog,1,row,row);CHKERRQ(ierr); 1880d6e23781SBarry Smith ierr = ISLocalToGlobalMappingApplyBlock(ltog,*cnt,col,col);CHKERRQ(ierr); 188147c6ae99SBarry Smith for (i=0,n=0; i<*cnt; i++) { 188247c6ae99SBarry Smith if (col[i] >= *row) col[n++] = col[i]; 188347c6ae99SBarry Smith } 188447c6ae99SBarry Smith *cnt = n; 188547c6ae99SBarry Smith PetscFunctionReturn(0); 188647c6ae99SBarry Smith } 188747c6ae99SBarry Smith 1888950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_2d_MPISBAIJ(DM da,Mat J) 188947c6ae99SBarry Smith { 189047c6ae99SBarry Smith PetscErrorCode ierr; 189147c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 189247c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,nc,col,cnt,*dnz,*onz; 189347c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,ii,jj; 189447c6ae99SBarry Smith MPI_Comm comm; 189547c6ae99SBarry Smith PetscScalar *values; 1896bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by; 1897aa219208SBarry Smith DMDAStencilType st; 189845b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 189947c6ae99SBarry Smith 190047c6ae99SBarry Smith PetscFunctionBegin; 190147c6ae99SBarry Smith /* 190247c6ae99SBarry Smith nc - number of components per grid point 190347c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 190447c6ae99SBarry Smith */ 19051321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,0,0,0,0,&nc,&s,&bx,&by,0,&st);CHKERRQ(ierr); 190647c6ae99SBarry Smith col = 2*s + 1; 190747c6ae99SBarry Smith 1908aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,0,&nx,&ny,0);CHKERRQ(ierr); 1909aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,0,&gnx,&gny,0);CHKERRQ(ierr); 191047c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 191147c6ae99SBarry Smith 1912785e854fSJed Brown ierr = PetscMalloc1(col*col*nc*nc,&cols);CHKERRQ(ierr); 191347c6ae99SBarry Smith 19141411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 191547c6ae99SBarry Smith 191647c6ae99SBarry Smith /* determine the matrix preallocation information */ 1917eabe889fSLisandro Dalcin ierr = MatPreallocateInitialize(comm,nx*ny,nx*ny,dnz,onz);CHKERRQ(ierr); 191847c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1919bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1920bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 192147c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1922bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1923bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 192447c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 192547c6ae99SBarry Smith 192647c6ae99SBarry Smith /* Find block columns in block row */ 192747c6ae99SBarry Smith cnt = 0; 192847c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 192947c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1930aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { 193147c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 193247c6ae99SBarry Smith } 193347c6ae99SBarry Smith } 193447c6ae99SBarry Smith } 193545b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 1936d6e23781SBarry Smith ierr = MatPreallocateSymmetricSetBlock(slot,cnt,cols,dnz,onz);CHKERRQ(ierr); 193747c6ae99SBarry Smith } 193847c6ae99SBarry Smith } 193947c6ae99SBarry Smith ierr = MatSeqSBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 194047c6ae99SBarry Smith ierr = MatMPISBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 194147c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 194247c6ae99SBarry Smith 1943784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 194447c6ae99SBarry Smith 194547c6ae99SBarry Smith /* 194647c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 194747c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 194847c6ae99SBarry Smith PETSc ordering. 194947c6ae99SBarry Smith */ 1950fcfd50ebSBarry Smith if (!da->prealloc_only) { 19511795a4d1SJed Brown ierr = PetscCalloc1(col*col*nc*nc,&values);CHKERRQ(ierr); 195247c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 1953bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 1954bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 195547c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 1956bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 1957bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 195847c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys); 195947c6ae99SBarry Smith 196047c6ae99SBarry Smith /* Find block columns in block row */ 196147c6ae99SBarry Smith cnt = 0; 196247c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 196347c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 1964aa219208SBarry Smith if (st == DMDA_STENCIL_BOX || !ii || !jj) { 196547c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj; 196647c6ae99SBarry Smith } 196747c6ae99SBarry Smith } 196847c6ae99SBarry Smith } 196945b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 197047c6ae99SBarry Smith ierr = MatSetValuesBlocked(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 197147c6ae99SBarry Smith } 197247c6ae99SBarry Smith } 197347c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 197447c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 197547c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1976189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 197747c6ae99SBarry Smith } 197847c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 197947c6ae99SBarry Smith PetscFunctionReturn(0); 198047c6ae99SBarry Smith } 198147c6ae99SBarry Smith 1982950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPISBAIJ(DM da,Mat J) 198347c6ae99SBarry Smith { 198447c6ae99SBarry Smith PetscErrorCode ierr; 198547c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 198647c6ae99SBarry Smith PetscInt m,n,dim,s,*cols,k,nc,col,cnt,p,*dnz,*onz; 198747c6ae99SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk; 198847c6ae99SBarry Smith MPI_Comm comm; 198947c6ae99SBarry Smith PetscScalar *values; 1990bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 1991aa219208SBarry Smith DMDAStencilType st; 199245b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 199347c6ae99SBarry Smith 199447c6ae99SBarry Smith PetscFunctionBegin; 199547c6ae99SBarry Smith /* 199647c6ae99SBarry Smith nc - number of components per grid point 199747c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 199847c6ae99SBarry Smith */ 19991321219cSEthan Coon ierr = DMDAGetInfo(da,&dim,&m,&n,&p,0,0,0,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 200047c6ae99SBarry Smith col = 2*s + 1; 200147c6ae99SBarry Smith 2002aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 2003aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 200447c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 200547c6ae99SBarry Smith 200647c6ae99SBarry Smith /* create the matrix */ 2007785e854fSJed Brown ierr = PetscMalloc1(col*col*col,&cols);CHKERRQ(ierr); 200847c6ae99SBarry Smith 20091411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 201047c6ae99SBarry Smith 201147c6ae99SBarry Smith /* determine the matrix preallocation information */ 2012eabe889fSLisandro Dalcin ierr = MatPreallocateInitialize(comm,nx*ny*nz,nx*ny*nz,dnz,onz);CHKERRQ(ierr); 201347c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2014bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2015bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 201647c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2017bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2018bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 201947c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2020bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2021bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 202247c6ae99SBarry Smith 202347c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 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++) { 202947c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 2030aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!ii && !jj) || (!jj && !kk) || (!ii && !kk)) { 203147c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 203247c6ae99SBarry Smith } 203347c6ae99SBarry Smith } 203447c6ae99SBarry Smith } 203547c6ae99SBarry Smith } 203645b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 2037d6e23781SBarry Smith ierr = MatPreallocateSymmetricSetBlock(slot,cnt,cols,dnz,onz);CHKERRQ(ierr); 203847c6ae99SBarry Smith } 203947c6ae99SBarry Smith } 204047c6ae99SBarry Smith } 204147c6ae99SBarry Smith ierr = MatSeqSBAIJSetPreallocation(J,nc,0,dnz);CHKERRQ(ierr); 204247c6ae99SBarry Smith ierr = MatMPISBAIJSetPreallocation(J,nc,0,dnz,0,onz);CHKERRQ(ierr); 204347c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 204447c6ae99SBarry Smith 2045784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 204647c6ae99SBarry Smith 204747c6ae99SBarry Smith /* 204847c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 204947c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 205047c6ae99SBarry Smith PETSc ordering. 205147c6ae99SBarry Smith */ 2052fcfd50ebSBarry Smith if (!da->prealloc_only) { 20531795a4d1SJed Brown ierr = PetscCalloc1(col*col*col*nc*nc,&values);CHKERRQ(ierr); 205447c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2055bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2056bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 205747c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2058bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2059bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 206047c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2061bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2062bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 206347c6ae99SBarry Smith 206447c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 206547c6ae99SBarry Smith 206647c6ae99SBarry Smith cnt = 0; 206747c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 206847c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 206947c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 2070aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || (!ii && !jj) || (!jj && !kk) || (!ii && !kk)) { 207147c6ae99SBarry Smith cols[cnt++] = slot + ii + gnx*jj + gnx*gny*kk; 207247c6ae99SBarry Smith } 207347c6ae99SBarry Smith } 207447c6ae99SBarry Smith } 207547c6ae99SBarry Smith } 207645b6f7e9SBarry Smith ierr = L2GFilterUpperTriangular(ltog,&slot,&cnt,cols);CHKERRQ(ierr); 207747c6ae99SBarry Smith ierr = MatSetValuesBlocked(J,1,&slot,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 207847c6ae99SBarry Smith } 207947c6ae99SBarry Smith } 208047c6ae99SBarry Smith } 208147c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 208247c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 208347c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2084189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 208547c6ae99SBarry Smith } 208647c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 208747c6ae99SBarry Smith PetscFunctionReturn(0); 208847c6ae99SBarry Smith } 208947c6ae99SBarry Smith 209047c6ae99SBarry Smith /* ---------------------------------------------------------------------------------*/ 209147c6ae99SBarry Smith 2092950540a4SJed Brown PetscErrorCode DMCreateMatrix_DA_3d_MPIAIJ_Fill(DM da,Mat J) 209347c6ae99SBarry Smith { 209447c6ae99SBarry Smith PetscErrorCode ierr; 209547c6ae99SBarry Smith PetscInt xs,ys,nx,ny,i,j,slot,gxs,gys,gnx,gny; 2096c0ab637bSBarry Smith PetscInt m,n,dim,s,*cols,k,nc,row,col,cnt, maxcnt = 0,l,p,*dnz,*onz; 2097c1154cd5SBarry Smith PetscInt istart,iend,jstart,jend,kstart,kend,zs,nz,gzs,gnz,ii,jj,kk,M,N,P; 209847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 209947c6ae99SBarry Smith PetscInt ifill_col,*dfill = dd->dfill,*ofill = dd->ofill; 210047c6ae99SBarry Smith MPI_Comm comm; 210147c6ae99SBarry Smith PetscScalar *values; 2102bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 210345b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 2104aa219208SBarry Smith DMDAStencilType st; 2105c1154cd5SBarry Smith PetscBool removedups = PETSC_FALSE; 210647c6ae99SBarry Smith 210747c6ae99SBarry Smith PetscFunctionBegin; 210847c6ae99SBarry Smith /* 210947c6ae99SBarry Smith nc - number of components per grid point 211047c6ae99SBarry Smith col - number of colors needed in one direction for single component problem 211147c6ae99SBarry Smith 211247c6ae99SBarry Smith */ 2113c1154cd5SBarry Smith ierr = DMDAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&nc,&s,&bx,&by,&bz,&st);CHKERRQ(ierr); 211447c6ae99SBarry Smith col = 2*s + 1; 2115bff4a2f0SMatthew 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\ 211647c6ae99SBarry Smith by 2*stencil_width + 1\n"); 2117bff4a2f0SMatthew 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\ 211847c6ae99SBarry Smith by 2*stencil_width + 1\n"); 2119bff4a2f0SMatthew 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\ 212047c6ae99SBarry Smith by 2*stencil_width + 1\n"); 212147c6ae99SBarry Smith 2122c1154cd5SBarry Smith /* 2123c1154cd5SBarry Smith With one processor in periodic domains in a skinny dimension the code will label nonzero columns multiple times 2124c1154cd5SBarry Smith because of "wrapping" around the end of the domain hitting an entry already counted in the other direction. 2125c1154cd5SBarry Smith */ 2126c1154cd5SBarry Smith if (M == 1 && 2*s >= m) removedups = PETSC_TRUE; 2127c1154cd5SBarry Smith if (N == 1 && 2*s >= n) removedups = PETSC_TRUE; 2128c1154cd5SBarry Smith if (P == 1 && 2*s >= p) removedups = PETSC_TRUE; 2129c1154cd5SBarry Smith 2130aa219208SBarry Smith ierr = DMDAGetCorners(da,&xs,&ys,&zs,&nx,&ny,&nz);CHKERRQ(ierr); 2131aa219208SBarry Smith ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gnx,&gny,&gnz);CHKERRQ(ierr); 213247c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 213347c6ae99SBarry Smith 2134785e854fSJed Brown ierr = PetscMalloc1(col*col*col*nc,&cols);CHKERRQ(ierr); 21351411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(da,<og);CHKERRQ(ierr); 213647c6ae99SBarry Smith 213747c6ae99SBarry Smith /* determine the matrix preallocation information */ 213847c6ae99SBarry Smith ierr = MatPreallocateInitialize(comm,nc*nx*ny*nz,nc*nx*ny*nz,dnz,onz);CHKERRQ(ierr); 213947c6ae99SBarry Smith 214006ca8cadSBarry Smith ierr = MatSetBlockSize(J,nc);CHKERRQ(ierr); 214147c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2142bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2143bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 214447c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2145bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2146bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 214747c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2148bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2149bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 215047c6ae99SBarry Smith 215147c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 215247c6ae99SBarry Smith 215347c6ae99SBarry Smith for (l=0; l<nc; l++) { 215447c6ae99SBarry Smith cnt = 0; 215547c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 215647c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 215747c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 215847c6ae99SBarry Smith if (ii || jj || kk) { 2159aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 21608865f1eaSKarl 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); 216147c6ae99SBarry Smith } 216247c6ae99SBarry Smith } else { 216347c6ae99SBarry Smith if (dfill) { 21648865f1eaSKarl 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); 216547c6ae99SBarry Smith } else { 21668865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + ii + gnx*jj + gnx*gny*kk); 216747c6ae99SBarry Smith } 216847c6ae99SBarry Smith } 216947c6ae99SBarry Smith } 217047c6ae99SBarry Smith } 217147c6ae99SBarry Smith } 217247c6ae99SBarry Smith row = l + nc*(slot); 2173c0ab637bSBarry Smith maxcnt = PetscMax(maxcnt,cnt); 2174c1154cd5SBarry Smith if (removedups) { 2175c1154cd5SBarry Smith ierr = MatPreallocateSetLocalRemoveDups(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 2176c1154cd5SBarry Smith } else { 2177784ac674SJed Brown ierr = MatPreallocateSetLocal(ltog,1,&row,ltog,cnt,cols,dnz,onz);CHKERRQ(ierr); 217847c6ae99SBarry Smith } 217947c6ae99SBarry Smith } 218047c6ae99SBarry Smith } 218147c6ae99SBarry Smith } 2182c1154cd5SBarry Smith } 218347c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(J,0,dnz);CHKERRQ(ierr); 218447c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(J,0,dnz,0,onz);CHKERRQ(ierr); 218547c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2186784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(J,ltog,ltog);CHKERRQ(ierr); 218747c6ae99SBarry Smith 218847c6ae99SBarry Smith /* 218947c6ae99SBarry Smith For each node in the grid: we get the neighbors in the local (on processor ordering 219047c6ae99SBarry Smith that includes the ghost points) then MatSetValuesLocal() maps those indices to the global 219147c6ae99SBarry Smith PETSc ordering. 219247c6ae99SBarry Smith */ 2193fcfd50ebSBarry Smith if (!da->prealloc_only) { 2194c0ab637bSBarry Smith ierr = PetscCalloc1(maxcnt,&values);CHKERRQ(ierr); 219547c6ae99SBarry Smith for (i=xs; i<xs+nx; i++) { 2196bff4a2f0SMatthew G. Knepley istart = (bx == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-i)); 2197bff4a2f0SMatthew G. Knepley iend = (bx == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,m-i-1)); 219847c6ae99SBarry Smith for (j=ys; j<ys+ny; j++) { 2199bff4a2f0SMatthew G. Knepley jstart = (by == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-j)); 2200bff4a2f0SMatthew G. Knepley jend = (by == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,n-j-1)); 220147c6ae99SBarry Smith for (k=zs; k<zs+nz; k++) { 2202bff4a2f0SMatthew G. Knepley kstart = (bz == DM_BOUNDARY_PERIODIC) ? -s : (PetscMax(-s,-k)); 2203bff4a2f0SMatthew G. Knepley kend = (bz == DM_BOUNDARY_PERIODIC) ? s : (PetscMin(s,p-k-1)); 220447c6ae99SBarry Smith 220547c6ae99SBarry Smith slot = i - gxs + gnx*(j - gys) + gnx*gny*(k - gzs); 220647c6ae99SBarry Smith 220747c6ae99SBarry Smith for (l=0; l<nc; l++) { 220847c6ae99SBarry Smith cnt = 0; 220947c6ae99SBarry Smith for (ii=istart; ii<iend+1; ii++) { 221047c6ae99SBarry Smith for (jj=jstart; jj<jend+1; jj++) { 221147c6ae99SBarry Smith for (kk=kstart; kk<kend+1; kk++) { 221247c6ae99SBarry Smith if (ii || jj || kk) { 2213aa219208SBarry Smith if ((st == DMDA_STENCIL_BOX) || ((!ii && !jj) || (!jj && !kk) || (!ii && !kk))) {/* entries on star*/ 22148865f1eaSKarl 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); 221547c6ae99SBarry Smith } 221647c6ae99SBarry Smith } else { 221747c6ae99SBarry Smith if (dfill) { 22188865f1eaSKarl 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); 221947c6ae99SBarry Smith } else { 22208865f1eaSKarl Rupp for (ifill_col=0; ifill_col<nc; ifill_col++) cols[cnt++] = ifill_col + nc*(slot + ii + gnx*jj + gnx*gny*kk); 222147c6ae99SBarry Smith } 222247c6ae99SBarry Smith } 222347c6ae99SBarry Smith } 222447c6ae99SBarry Smith } 222547c6ae99SBarry Smith } 222647c6ae99SBarry Smith row = l + nc*(slot); 222747c6ae99SBarry Smith ierr = MatSetValuesLocal(J,1,&row,cnt,cols,values,INSERT_VALUES);CHKERRQ(ierr); 222847c6ae99SBarry Smith } 222947c6ae99SBarry Smith } 223047c6ae99SBarry Smith } 223147c6ae99SBarry Smith } 223247c6ae99SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 223347c6ae99SBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 223447c6ae99SBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2235189e4007SBarry Smith ierr = MatSetOption(J,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 223647c6ae99SBarry Smith } 223747c6ae99SBarry Smith ierr = PetscFree(cols);CHKERRQ(ierr); 223847c6ae99SBarry Smith PetscFunctionReturn(0); 223947c6ae99SBarry Smith } 2240