xref: /petsc/src/dm/impls/da/da3.c (revision 47c6ae997ffd1b2afd66b6474dff5950ae8613d1)
1*47c6ae99SBarry Smith #define PETSCDM_DLL
2*47c6ae99SBarry Smith /*
3*47c6ae99SBarry Smith    Code for manipulating distributed regular 3d arrays in parallel.
4*47c6ae99SBarry Smith    File created by Peter Mell  7/14/95
5*47c6ae99SBarry Smith  */
6*47c6ae99SBarry Smith 
7*47c6ae99SBarry Smith #include "private/daimpl.h"     /*I   "petscda.h"    I*/
8*47c6ae99SBarry Smith 
9*47c6ae99SBarry Smith #undef __FUNCT__
10*47c6ae99SBarry Smith #define __FUNCT__ "DAView_3d"
11*47c6ae99SBarry Smith PetscErrorCode DAView_3d(DA da,PetscViewer viewer)
12*47c6ae99SBarry Smith {
13*47c6ae99SBarry Smith   PetscErrorCode ierr;
14*47c6ae99SBarry Smith   PetscMPIInt    rank;
15*47c6ae99SBarry Smith   PetscBool      iascii,isdraw;
16*47c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
17*47c6ae99SBarry Smith 
18*47c6ae99SBarry Smith   PetscFunctionBegin;
19*47c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)da)->comm,&rank);CHKERRQ(ierr);
20*47c6ae99SBarry Smith 
21*47c6ae99SBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
22*47c6ae99SBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
23*47c6ae99SBarry Smith   if (iascii) {
24*47c6ae99SBarry Smith     PetscViewerFormat format;
25*47c6ae99SBarry Smith 
26*47c6ae99SBarry Smith     ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
27*47c6ae99SBarry Smith     if (format != PETSC_VIEWER_ASCII_VTK && format != PETSC_VIEWER_ASCII_VTK_CELL) {
28*47c6ae99SBarry Smith       DALocalInfo info;
29*47c6ae99SBarry Smith       ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr);
30*47c6ae99SBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Processor [%d] M %D N %D P %D m %D n %D p %D w %D s %D\n",rank,dd->M,dd->N,dd->P,dd->m,dd->n,dd->p,dd->w,dd->s);CHKERRQ(ierr);
31*47c6ae99SBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"X range of indices: %D %D, Y range of indices: %D %D, Z range of indices: %D %D\n",
32*47c6ae99SBarry Smith                                                 info.xs,info.xs+info.xm,info.ys,info.ys+info.ym,info.zs,info.zs+info.zm);CHKERRQ(ierr);
33*47c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
34*47c6ae99SBarry Smith       if (dd->coordinates) {
35*47c6ae99SBarry Smith         PetscInt        last;
36*47c6ae99SBarry Smith         const PetscReal *coors;
37*47c6ae99SBarry Smith         ierr = VecGetArrayRead(dd->coordinates,&coors);CHKERRQ(ierr);
38*47c6ae99SBarry Smith         ierr = VecGetLocalSize(dd->coordinates,&last);CHKERRQ(ierr);
39*47c6ae99SBarry Smith         last = last - 3;
40*47c6ae99SBarry Smith         ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Lower left corner %G %G %G : Upper right %G %G %G\n",coors[0],coors[1],coors[2],coors[last],coors[last+1],coors[last+2]);CHKERRQ(ierr);
41*47c6ae99SBarry Smith         ierr = VecRestoreArrayRead(dd->coordinates,&coors);CHKERRQ(ierr);
42*47c6ae99SBarry Smith       }
43*47c6ae99SBarry Smith #endif
44*47c6ae99SBarry Smith       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
45*47c6ae99SBarry Smith     }
46*47c6ae99SBarry Smith   } else if (isdraw) {
47*47c6ae99SBarry Smith     PetscDraw       draw;
48*47c6ae99SBarry Smith     PetscReal     ymin = -1.0,ymax = (PetscReal)dd->N;
49*47c6ae99SBarry Smith     PetscReal     xmin = -1.0,xmax = (PetscReal)((dd->M+2)*dd->P),x,y,ycoord,xcoord;
50*47c6ae99SBarry Smith     PetscInt        k,plane,base,*idx;
51*47c6ae99SBarry Smith     char       node[10];
52*47c6ae99SBarry Smith     PetscBool  isnull;
53*47c6ae99SBarry Smith 
54*47c6ae99SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
55*47c6ae99SBarry Smith     ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
56*47c6ae99SBarry Smith     ierr = PetscDrawSetCoordinates(draw,xmin,ymin,xmax,ymax);CHKERRQ(ierr);
57*47c6ae99SBarry Smith     ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr);
58*47c6ae99SBarry Smith 
59*47c6ae99SBarry Smith     /* first processor draw all node lines */
60*47c6ae99SBarry Smith     if (!rank) {
61*47c6ae99SBarry Smith       for (k=0; k<dd->P; k++) {
62*47c6ae99SBarry Smith         ymin = 0.0; ymax = (PetscReal)(dd->N - 1);
63*47c6ae99SBarry Smith         for (xmin=(PetscReal)(k*(dd->M+1)); xmin<(PetscReal)(dd->M+(k*(dd->M+1))); xmin++) {
64*47c6ae99SBarry Smith           ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_BLACK);CHKERRQ(ierr);
65*47c6ae99SBarry Smith         }
66*47c6ae99SBarry Smith 
67*47c6ae99SBarry Smith         xmin = (PetscReal)(k*(dd->M+1)); xmax = xmin + (PetscReal)(dd->M - 1);
68*47c6ae99SBarry Smith         for (ymin=0; ymin<(PetscReal)dd->N; ymin++) {
69*47c6ae99SBarry Smith           ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_BLACK);CHKERRQ(ierr);
70*47c6ae99SBarry Smith         }
71*47c6ae99SBarry Smith       }
72*47c6ae99SBarry Smith     }
73*47c6ae99SBarry Smith     ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
74*47c6ae99SBarry Smith     ierr = PetscDrawPause(draw);CHKERRQ(ierr);
75*47c6ae99SBarry Smith 
76*47c6ae99SBarry Smith     for (k=0; k<dd->P; k++) {  /*Go through and draw for each plane*/
77*47c6ae99SBarry Smith       if ((k >= dd->zs) && (k < dd->ze)) {
78*47c6ae99SBarry Smith         /* draw my box */
79*47c6ae99SBarry Smith         ymin = dd->ys;
80*47c6ae99SBarry Smith         ymax = dd->ye - 1;
81*47c6ae99SBarry Smith         xmin = dd->xs/dd->w    + (dd->M+1)*k;
82*47c6ae99SBarry Smith         xmax =(dd->xe-1)/dd->w + (dd->M+1)*k;
83*47c6ae99SBarry Smith 
84*47c6ae99SBarry Smith         ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_RED);CHKERRQ(ierr);
85*47c6ae99SBarry Smith         ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_RED);CHKERRQ(ierr);
86*47c6ae99SBarry Smith         ierr = PetscDrawLine(draw,xmin,ymax,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr);
87*47c6ae99SBarry Smith         ierr = PetscDrawLine(draw,xmax,ymin,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr);
88*47c6ae99SBarry Smith 
89*47c6ae99SBarry Smith         xmin = dd->xs/dd->w;
90*47c6ae99SBarry Smith         xmax =(dd->xe-1)/dd->w;
91*47c6ae99SBarry Smith 
92*47c6ae99SBarry Smith         /* put in numbers*/
93*47c6ae99SBarry Smith         base = (dd->base+(dd->xe-dd->xs)*(dd->ye-dd->ys)*(k-dd->zs))/dd->w;
94*47c6ae99SBarry Smith 
95*47c6ae99SBarry Smith         /* Identify which processor owns the box */
96*47c6ae99SBarry Smith         sprintf(node,"%d",rank);
97*47c6ae99SBarry Smith         ierr = PetscDrawString(draw,xmin+(dd->M+1)*k+.2,ymin+.3,PETSC_DRAW_RED,node);CHKERRQ(ierr);
98*47c6ae99SBarry Smith 
99*47c6ae99SBarry Smith         for (y=ymin; y<=ymax; y++) {
100*47c6ae99SBarry Smith           for (x=xmin+(dd->M+1)*k; x<=xmax+(dd->M+1)*k; x++) {
101*47c6ae99SBarry Smith             sprintf(node,"%d",(int)base++);
102*47c6ae99SBarry Smith             ierr = PetscDrawString(draw,x,y,PETSC_DRAW_BLACK,node);CHKERRQ(ierr);
103*47c6ae99SBarry Smith           }
104*47c6ae99SBarry Smith         }
105*47c6ae99SBarry Smith 
106*47c6ae99SBarry Smith       }
107*47c6ae99SBarry Smith     }
108*47c6ae99SBarry Smith     ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
109*47c6ae99SBarry Smith     ierr = PetscDrawPause(draw);CHKERRQ(ierr);
110*47c6ae99SBarry Smith 
111*47c6ae99SBarry Smith     for (k=0-dd->s; k<dd->P+dd->s; k++) {
112*47c6ae99SBarry Smith       /* Go through and draw for each plane */
113*47c6ae99SBarry Smith       if ((k >= dd->Zs) && (k < dd->Ze)) {
114*47c6ae99SBarry Smith 
115*47c6ae99SBarry Smith         /* overlay ghost numbers, useful for error checking */
116*47c6ae99SBarry Smith         base = (dd->Xe-dd->Xs)*(dd->Ye-dd->Ys)*(k-dd->Zs); idx = dd->idx;
117*47c6ae99SBarry Smith         plane=k;
118*47c6ae99SBarry Smith         /* Keep z wrap around points on the dradrawg */
119*47c6ae99SBarry Smith         if (k<0)    { plane=dd->P+k; }
120*47c6ae99SBarry Smith         if (k>=dd->P) { plane=k-dd->P; }
121*47c6ae99SBarry Smith         ymin = dd->Ys; ymax = dd->Ye;
122*47c6ae99SBarry Smith         xmin = (dd->M+1)*plane*dd->w;
123*47c6ae99SBarry Smith         xmax = (dd->M+1)*plane*dd->w+dd->M*dd->w;
124*47c6ae99SBarry Smith         for (y=ymin; y<ymax; y++) {
125*47c6ae99SBarry Smith           for (x=xmin+dd->Xs; x<xmin+dd->Xe; x+=dd->w) {
126*47c6ae99SBarry Smith             sprintf(node,"%d",(int)(idx[base]/dd->w));
127*47c6ae99SBarry Smith             ycoord = y;
128*47c6ae99SBarry Smith             /*Keep y wrap around points on drawing */
129*47c6ae99SBarry Smith             if (y<0)      { ycoord = dd->N+y; }
130*47c6ae99SBarry Smith 
131*47c6ae99SBarry Smith             if (y>=dd->N) { ycoord = y-dd->N; }
132*47c6ae99SBarry Smith             xcoord = x;   /* Keep x wrap points on drawing */
133*47c6ae99SBarry Smith 
134*47c6ae99SBarry Smith             if (x<xmin)  { xcoord = xmax - (xmin-x); }
135*47c6ae99SBarry Smith             if (x>=xmax) { xcoord = xmin + (x-xmax); }
136*47c6ae99SBarry Smith             ierr = PetscDrawString(draw,xcoord/dd->w,ycoord,PETSC_DRAW_BLUE,node);CHKERRQ(ierr);
137*47c6ae99SBarry Smith             base+=dd->w;
138*47c6ae99SBarry Smith           }
139*47c6ae99SBarry Smith         }
140*47c6ae99SBarry Smith       }
141*47c6ae99SBarry Smith     }
142*47c6ae99SBarry Smith     ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
143*47c6ae99SBarry Smith     ierr = PetscDrawPause(draw);CHKERRQ(ierr);
144*47c6ae99SBarry Smith   } else {
145*47c6ae99SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for DA 3d",((PetscObject)viewer)->type_name);
146*47c6ae99SBarry Smith   }
147*47c6ae99SBarry Smith   PetscFunctionReturn(0);
148*47c6ae99SBarry Smith }
149*47c6ae99SBarry Smith 
150*47c6ae99SBarry Smith EXTERN_C_BEGIN
151*47c6ae99SBarry Smith #undef __FUNCT__
152*47c6ae99SBarry Smith #define __FUNCT__ "DACreate_3D"
153*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DACreate_3D(DA da)
154*47c6ae99SBarry Smith {
155*47c6ae99SBarry Smith   DM_DA               *dd           = (DM_DA*)da->data;
156*47c6ae99SBarry Smith   const PetscInt       dim          = dd->dim;
157*47c6ae99SBarry Smith   const PetscInt       M            = dd->M;
158*47c6ae99SBarry Smith   const PetscInt       N            = dd->N;
159*47c6ae99SBarry Smith   const PetscInt       P            = dd->P;
160*47c6ae99SBarry Smith   PetscInt             m            = dd->m;
161*47c6ae99SBarry Smith   PetscInt             n            = dd->n;
162*47c6ae99SBarry Smith   PetscInt             p            = dd->p;
163*47c6ae99SBarry Smith   const PetscInt       dof          = dd->w;
164*47c6ae99SBarry Smith   const PetscInt       s            = dd->s;
165*47c6ae99SBarry Smith   const DAPeriodicType wrap         = dd->wrap;
166*47c6ae99SBarry Smith   const DAStencilType  stencil_type = dd->stencil_type;
167*47c6ae99SBarry Smith   PetscInt            *lx           = dd->lx;
168*47c6ae99SBarry Smith   PetscInt            *ly           = dd->ly;
169*47c6ae99SBarry Smith   PetscInt            *lz           = dd->lz;
170*47c6ae99SBarry Smith   MPI_Comm             comm;
171*47c6ae99SBarry Smith   PetscMPIInt    rank,size;
172*47c6ae99SBarry Smith   PetscInt       xs = 0,xe,ys = 0,ye,zs = 0,ze,x = 0,y = 0,z = 0,Xs,Xe,Ys,Ye,Zs,Ze,start,end,pm;
173*47c6ae99SBarry Smith   PetscInt       left,up,down,bottom,top,i,j,k,*idx,nn;
174*47c6ae99SBarry Smith   PetscInt       n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n14;
175*47c6ae99SBarry Smith   PetscInt       n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26;
176*47c6ae99SBarry Smith   PetscInt       *bases,*ldims,x_t,y_t,z_t,s_t,base,count,s_x,s_y,s_z;
177*47c6ae99SBarry Smith   PetscInt       sn0 = 0,sn1 = 0,sn2 = 0,sn3 = 0,sn5 = 0,sn6 = 0,sn7 = 0;
178*47c6ae99SBarry Smith   PetscInt       sn8 = 0,sn9 = 0,sn11 = 0,sn15 = 0,sn24 = 0,sn25 = 0,sn26 = 0;
179*47c6ae99SBarry Smith   PetscInt       sn17 = 0,sn18 = 0,sn19 = 0,sn20 = 0,sn21 = 0,sn23 = 0;
180*47c6ae99SBarry Smith   Vec            local,global;
181*47c6ae99SBarry Smith   VecScatter     ltog,gtol;
182*47c6ae99SBarry Smith   IS             to,from;
183*47c6ae99SBarry Smith   PetscErrorCode ierr;
184*47c6ae99SBarry Smith 
185*47c6ae99SBarry Smith   PetscFunctionBegin;
186*47c6ae99SBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
187*47c6ae99SBarry Smith   ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr);
188*47c6ae99SBarry Smith #endif
189*47c6ae99SBarry Smith 
190*47c6ae99SBarry Smith   if (dim != PETSC_DECIDE && dim != 3) SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Dimension should be 3: %D",dim);
191*47c6ae99SBarry Smith   if (dof < 1) SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have 1 or more degrees of freedom per node: %D",dof);
192*47c6ae99SBarry Smith   if (s < 0) SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Stencil width cannot be negative: %D",s);
193*47c6ae99SBarry Smith 
194*47c6ae99SBarry Smith   ierr = PetscObjectGetComm((PetscObject) da, &comm);CHKERRQ(ierr);
195*47c6ae99SBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
196*47c6ae99SBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
197*47c6ae99SBarry Smith 
198*47c6ae99SBarry Smith   dd->dim = 3;
199*47c6ae99SBarry Smith   ierr = PetscMalloc(dof*sizeof(char*),&dd->fieldname);CHKERRQ(ierr);
200*47c6ae99SBarry Smith   ierr = PetscMemzero(dd->fieldname,dof*sizeof(char*));CHKERRQ(ierr);
201*47c6ae99SBarry Smith 
202*47c6ae99SBarry Smith   if (m != PETSC_DECIDE) {
203*47c6ae99SBarry Smith     if (m < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in X direction: %D",m);
204*47c6ae99SBarry Smith     else if (m > size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in X direction: %D %d",m,size);
205*47c6ae99SBarry Smith   }
206*47c6ae99SBarry Smith   if (n != PETSC_DECIDE) {
207*47c6ae99SBarry Smith     if (n < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in Y direction: %D",n);
208*47c6ae99SBarry Smith     else if (n > size)  SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in Y direction: %D %d",n,size);
209*47c6ae99SBarry Smith   }
210*47c6ae99SBarry Smith   if (p != PETSC_DECIDE) {
211*47c6ae99SBarry Smith     if (p < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in Z direction: %D",p);
212*47c6ae99SBarry Smith     else if (p > size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in Z direction: %D %d",p,size);
213*47c6ae99SBarry Smith   }
214*47c6ae99SBarry Smith 
215*47c6ae99SBarry Smith   /* Partition the array among the processors */
216*47c6ae99SBarry Smith   if (m == PETSC_DECIDE && n != PETSC_DECIDE && p != PETSC_DECIDE) {
217*47c6ae99SBarry Smith     m = size/(n*p);
218*47c6ae99SBarry Smith   } else if (m != PETSC_DECIDE && n == PETSC_DECIDE && p != PETSC_DECIDE) {
219*47c6ae99SBarry Smith     n = size/(m*p);
220*47c6ae99SBarry Smith   } else if (m != PETSC_DECIDE && n != PETSC_DECIDE && p == PETSC_DECIDE) {
221*47c6ae99SBarry Smith     p = size/(m*n);
222*47c6ae99SBarry Smith   } else if (m == PETSC_DECIDE && n == PETSC_DECIDE && p != PETSC_DECIDE) {
223*47c6ae99SBarry Smith     /* try for squarish distribution */
224*47c6ae99SBarry Smith     m = (int)(0.5 + sqrt(((PetscReal)M)*((PetscReal)size)/((PetscReal)N*p)));
225*47c6ae99SBarry Smith     if (!m) m = 1;
226*47c6ae99SBarry Smith     while (m > 0) {
227*47c6ae99SBarry Smith       n = size/(m*p);
228*47c6ae99SBarry Smith       if (m*n*p == size) break;
229*47c6ae99SBarry Smith       m--;
230*47c6ae99SBarry Smith     }
231*47c6ae99SBarry Smith     if (!m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"bad p value: p = %D",p);
232*47c6ae99SBarry Smith     if (M > N && m < n) {PetscInt _m = m; m = n; n = _m;}
233*47c6ae99SBarry Smith   } else if (m == PETSC_DECIDE && n != PETSC_DECIDE && p == PETSC_DECIDE) {
234*47c6ae99SBarry Smith     /* try for squarish distribution */
235*47c6ae99SBarry Smith     m = (int)(0.5 + sqrt(((PetscReal)M)*((PetscReal)size)/((PetscReal)P*n)));
236*47c6ae99SBarry Smith     if (!m) m = 1;
237*47c6ae99SBarry Smith     while (m > 0) {
238*47c6ae99SBarry Smith       p = size/(m*n);
239*47c6ae99SBarry Smith       if (m*n*p == size) break;
240*47c6ae99SBarry Smith       m--;
241*47c6ae99SBarry Smith     }
242*47c6ae99SBarry Smith     if (!m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"bad n value: n = %D",n);
243*47c6ae99SBarry Smith     if (M > P && m < p) {PetscInt _m = m; m = p; p = _m;}
244*47c6ae99SBarry Smith   } else if (m != PETSC_DECIDE && n == PETSC_DECIDE && p == PETSC_DECIDE) {
245*47c6ae99SBarry Smith     /* try for squarish distribution */
246*47c6ae99SBarry Smith     n = (int)(0.5 + sqrt(((PetscReal)N)*((PetscReal)size)/((PetscReal)P*m)));
247*47c6ae99SBarry Smith     if (!n) n = 1;
248*47c6ae99SBarry Smith     while (n > 0) {
249*47c6ae99SBarry Smith       p = size/(m*n);
250*47c6ae99SBarry Smith       if (m*n*p == size) break;
251*47c6ae99SBarry Smith       n--;
252*47c6ae99SBarry Smith     }
253*47c6ae99SBarry Smith     if (!n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"bad m value: m = %D",n);
254*47c6ae99SBarry Smith     if (N > P && n < p) {PetscInt _n = n; n = p; p = _n;}
255*47c6ae99SBarry Smith   } else if (m == PETSC_DECIDE && n == PETSC_DECIDE && p == PETSC_DECIDE) {
256*47c6ae99SBarry Smith     /* try for squarish distribution */
257*47c6ae99SBarry Smith     n = (PetscInt)(0.5 + pow(((PetscReal)N*N)*((PetscReal)size)/((PetscReal)P*M),(PetscReal)(1./3.)));
258*47c6ae99SBarry Smith     if (!n) n = 1;
259*47c6ae99SBarry Smith     while (n > 0) {
260*47c6ae99SBarry Smith       pm = size/n;
261*47c6ae99SBarry Smith       if (n*pm == size) break;
262*47c6ae99SBarry Smith       n--;
263*47c6ae99SBarry Smith     }
264*47c6ae99SBarry Smith     if (!n) n = 1;
265*47c6ae99SBarry Smith     m = (PetscInt)(0.5 + sqrt(((PetscReal)M)*((PetscReal)size)/((PetscReal)P*n)));
266*47c6ae99SBarry Smith     if (!m) m = 1;
267*47c6ae99SBarry Smith     while (m > 0) {
268*47c6ae99SBarry Smith       p = size/(m*n);
269*47c6ae99SBarry Smith       if (m*n*p == size) break;
270*47c6ae99SBarry Smith       m--;
271*47c6ae99SBarry Smith     }
272*47c6ae99SBarry Smith     if (M > P && m < p) {PetscInt _m = m; m = p; p = _m;}
273*47c6ae99SBarry Smith   } else if (m*n*p != size) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Given Bad partition");
274*47c6ae99SBarry Smith 
275*47c6ae99SBarry Smith   if (m*n*p != size) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_PLIB,"Could not find good partition");
276*47c6ae99SBarry Smith   if (M < m) SETERRQ2(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in x direction is too fine! %D %D",M,m);
277*47c6ae99SBarry Smith   if (N < n) SETERRQ2(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in y direction is too fine! %D %D",N,n);
278*47c6ae99SBarry Smith   if (P < p) SETERRQ2(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in z direction is too fine! %D %D",P,p);
279*47c6ae99SBarry Smith 
280*47c6ae99SBarry Smith   /*
281*47c6ae99SBarry Smith      Determine locally owned region
282*47c6ae99SBarry Smith      [x, y, or z]s is the first local node number, [x, y, z] is the number of local nodes
283*47c6ae99SBarry Smith   */
284*47c6ae99SBarry Smith 
285*47c6ae99SBarry Smith   if (!lx) {
286*47c6ae99SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt), &dd->lx);CHKERRQ(ierr);
287*47c6ae99SBarry Smith     lx = dd->lx;
288*47c6ae99SBarry Smith     for (i=0; i<m; i++) {
289*47c6ae99SBarry Smith       lx[i] = M/m + ((M % m) > (i % m));
290*47c6ae99SBarry Smith     }
291*47c6ae99SBarry Smith   }
292*47c6ae99SBarry Smith   x  = lx[rank % m];
293*47c6ae99SBarry Smith   xs = 0;
294*47c6ae99SBarry Smith   for (i=0; i<(rank%m); i++) { xs += lx[i];}
295*47c6ae99SBarry Smith   if (m > 1 && x < s) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column width is too thin for stencil! %D %D",x,s);
296*47c6ae99SBarry Smith 
297*47c6ae99SBarry Smith   if (!ly) {
298*47c6ae99SBarry Smith     ierr = PetscMalloc(n*sizeof(PetscInt), &dd->ly);CHKERRQ(ierr);
299*47c6ae99SBarry Smith     ly = dd->ly;
300*47c6ae99SBarry Smith     for (i=0; i<n; i++) {
301*47c6ae99SBarry Smith       ly[i] = N/n + ((N % n) > (i % n));
302*47c6ae99SBarry Smith     }
303*47c6ae99SBarry Smith   }
304*47c6ae99SBarry Smith   y  = ly[(rank % (m*n))/m];
305*47c6ae99SBarry Smith   if (n > 1 && y < s) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row width is too thin for stencil! %D %D",y,s);
306*47c6ae99SBarry Smith   ys = 0;
307*47c6ae99SBarry Smith   for (i=0; i<(rank % (m*n))/m; i++) { ys += ly[i];}
308*47c6ae99SBarry Smith 
309*47c6ae99SBarry Smith   if (!lz) {
310*47c6ae99SBarry Smith     ierr = PetscMalloc(p*sizeof(PetscInt), &dd->lz);CHKERRQ(ierr);
311*47c6ae99SBarry Smith     lz = dd->lz;
312*47c6ae99SBarry Smith     for (i=0; i<p; i++) {
313*47c6ae99SBarry Smith       lz[i] = P/p + ((P % p) > (i % p));
314*47c6ae99SBarry Smith     }
315*47c6ae99SBarry Smith   }
316*47c6ae99SBarry Smith   z  = lz[rank/(m*n)];
317*47c6ae99SBarry Smith   if (p > 1 && z < s) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Plane width is too thin for stencil! %D %D",z,s);
318*47c6ae99SBarry Smith   zs = 0;
319*47c6ae99SBarry Smith   for (i=0; i<(rank/(m*n)); i++) { zs += lz[i];}
320*47c6ae99SBarry Smith   ye = ys + y;
321*47c6ae99SBarry Smith   xe = xs + x;
322*47c6ae99SBarry Smith   ze = zs + z;
323*47c6ae99SBarry Smith 
324*47c6ae99SBarry Smith   /* determine ghost region */
325*47c6ae99SBarry Smith   /* Assume No Periodicity */
326*47c6ae99SBarry Smith   if (xs-s > 0) Xs = xs - s; else Xs = 0;
327*47c6ae99SBarry Smith   if (ys-s > 0) Ys = ys - s; else Ys = 0;
328*47c6ae99SBarry Smith   if (zs-s > 0) Zs = zs - s; else Zs = 0;
329*47c6ae99SBarry Smith   if (xe+s <= M) Xe = xe + s; else Xe = M;
330*47c6ae99SBarry Smith   if (ye+s <= N) Ye = ye + s; else Ye = N;
331*47c6ae99SBarry Smith   if (ze+s <= P) Ze = ze + s; else Ze = P;
332*47c6ae99SBarry Smith 
333*47c6ae99SBarry Smith   /* X Periodic */
334*47c6ae99SBarry Smith   if (DAXPeriodic(wrap)){
335*47c6ae99SBarry Smith     Xs = xs - s;
336*47c6ae99SBarry Smith     Xe = xe + s;
337*47c6ae99SBarry Smith   }
338*47c6ae99SBarry Smith 
339*47c6ae99SBarry Smith   /* Y Periodic */
340*47c6ae99SBarry Smith   if (DAYPeriodic(wrap)){
341*47c6ae99SBarry Smith     Ys = ys - s;
342*47c6ae99SBarry Smith     Ye = ye + s;
343*47c6ae99SBarry Smith   }
344*47c6ae99SBarry Smith 
345*47c6ae99SBarry Smith   /* Z Periodic */
346*47c6ae99SBarry Smith   if (DAZPeriodic(wrap)){
347*47c6ae99SBarry Smith     Zs = zs - s;
348*47c6ae99SBarry Smith     Ze = ze + s;
349*47c6ae99SBarry Smith   }
350*47c6ae99SBarry Smith 
351*47c6ae99SBarry Smith   /* Resize all X parameters to reflect w */
352*47c6ae99SBarry Smith   x   *= dof;
353*47c6ae99SBarry Smith   xs  *= dof;
354*47c6ae99SBarry Smith   xe  *= dof;
355*47c6ae99SBarry Smith   Xs  *= dof;
356*47c6ae99SBarry Smith   Xe  *= dof;
357*47c6ae99SBarry Smith   s_x  = s*dof;
358*47c6ae99SBarry Smith   s_y  = s;
359*47c6ae99SBarry Smith   s_z  = s;
360*47c6ae99SBarry Smith 
361*47c6ae99SBarry Smith   /* determine starting point of each processor */
362*47c6ae99SBarry Smith   nn       = x*y*z;
363*47c6ae99SBarry Smith   ierr     = PetscMalloc2(size+1,PetscInt,&bases,size,PetscInt,&ldims);CHKERRQ(ierr);
364*47c6ae99SBarry Smith   ierr     = MPI_Allgather(&nn,1,MPIU_INT,ldims,1,MPIU_INT,comm);CHKERRQ(ierr);
365*47c6ae99SBarry Smith   bases[0] = 0;
366*47c6ae99SBarry Smith   for (i=1; i<=size; i++) {
367*47c6ae99SBarry Smith     bases[i] = ldims[i-1];
368*47c6ae99SBarry Smith   }
369*47c6ae99SBarry Smith   for (i=1; i<=size; i++) {
370*47c6ae99SBarry Smith     bases[i] += bases[i-1];
371*47c6ae99SBarry Smith   }
372*47c6ae99SBarry Smith 
373*47c6ae99SBarry Smith   /* allocate the base parallel and sequential vectors */
374*47c6ae99SBarry Smith   dd->Nlocal = x*y*z;
375*47c6ae99SBarry Smith   ierr = VecCreateMPIWithArray(comm,dd->Nlocal,PETSC_DECIDE,0,&global);CHKERRQ(ierr);
376*47c6ae99SBarry Smith   ierr = VecSetBlockSize(global,dof);CHKERRQ(ierr);
377*47c6ae99SBarry Smith   dd->nlocal = (Xe-Xs)*(Ye-Ys)*(Ze-Zs);
378*47c6ae99SBarry Smith   ierr = VecCreateSeqWithArray(MPI_COMM_SELF,dd->nlocal,0,&local);CHKERRQ(ierr);
379*47c6ae99SBarry Smith   ierr = VecSetBlockSize(local,dof);CHKERRQ(ierr);
380*47c6ae99SBarry Smith 
381*47c6ae99SBarry Smith   /* generate appropriate vector scatters */
382*47c6ae99SBarry Smith   /* local to global inserts non-ghost point region into global */
383*47c6ae99SBarry Smith   ierr = VecGetOwnershipRange(global,&start,&end);CHKERRQ(ierr);
384*47c6ae99SBarry Smith   ierr = ISCreateStride(comm,x*y*z,start,1,&to);CHKERRQ(ierr);
385*47c6ae99SBarry Smith 
386*47c6ae99SBarry Smith   left   = xs - Xs;
387*47c6ae99SBarry Smith   bottom = ys - Ys; top = bottom + y;
388*47c6ae99SBarry Smith   down   = zs - Zs; up  = down + z;
389*47c6ae99SBarry Smith   count  = x*(top-bottom)*(up-down);
390*47c6ae99SBarry Smith   ierr = PetscMalloc(count*sizeof(PetscInt)/dof,&idx);CHKERRQ(ierr);
391*47c6ae99SBarry Smith   count  = 0;
392*47c6ae99SBarry Smith   for (i=down; i<up; i++) {
393*47c6ae99SBarry Smith     for (j=bottom; j<top; j++) {
394*47c6ae99SBarry Smith       for (k=0; k<x; k += dof) {
395*47c6ae99SBarry Smith         idx[count++] = ((left+j*(Xe-Xs))+i*(Xe-Xs)*(Ye-Ys) + k)/dof;
396*47c6ae99SBarry Smith       }
397*47c6ae99SBarry Smith     }
398*47c6ae99SBarry Smith   }
399*47c6ae99SBarry Smith 
400*47c6ae99SBarry Smith   ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&from);CHKERRQ(ierr);
401*47c6ae99SBarry Smith 
402*47c6ae99SBarry Smith   ierr = VecScatterCreate(local,from,global,to,&ltog);CHKERRQ(ierr);
403*47c6ae99SBarry Smith   ierr = PetscLogObjectParent(da,ltog);CHKERRQ(ierr);
404*47c6ae99SBarry Smith   ierr = ISDestroy(from);CHKERRQ(ierr);
405*47c6ae99SBarry Smith   ierr = ISDestroy(to);CHKERRQ(ierr);
406*47c6ae99SBarry Smith 
407*47c6ae99SBarry Smith   /* global to local must include ghost points */
408*47c6ae99SBarry Smith   if (stencil_type == DA_STENCIL_BOX) {
409*47c6ae99SBarry Smith     ierr = ISCreateStride(comm,(Xe-Xs)*(Ye-Ys)*(Ze-Zs),0,1,&to);CHKERRQ(ierr);
410*47c6ae99SBarry Smith   } else {
411*47c6ae99SBarry Smith     /* This is way ugly! We need to list the funny cross type region */
412*47c6ae99SBarry Smith     /* the bottom chunck */
413*47c6ae99SBarry Smith     left   = xs - Xs;
414*47c6ae99SBarry Smith     bottom = ys - Ys; top = bottom + y;
415*47c6ae99SBarry Smith     down   = zs - Zs;   up  = down + z;
416*47c6ae99SBarry Smith     count  = down*(top-bottom)*x + (up-down)*(bottom*x  + (top-bottom)*(Xe-Xs) + (Ye-Ys-top)*x) + (Ze-Zs-up)*(top-bottom)*x;
417*47c6ae99SBarry Smith     ierr   = PetscMalloc(count*sizeof(PetscInt)/dof,&idx);CHKERRQ(ierr);
418*47c6ae99SBarry Smith     count  = 0;
419*47c6ae99SBarry Smith     for (i=0; i<down; i++) {
420*47c6ae99SBarry Smith       for (j=bottom; j<top; j++) {
421*47c6ae99SBarry Smith         for (k=0; k<x; k += dof) idx[count++] = left+j*(Xe-Xs)+i*(Xe-Xs)*(Ye-Ys)+k;
422*47c6ae99SBarry Smith       }
423*47c6ae99SBarry Smith     }
424*47c6ae99SBarry Smith     /* the middle piece */
425*47c6ae99SBarry Smith     for (i=down; i<up; i++) {
426*47c6ae99SBarry Smith       /* front */
427*47c6ae99SBarry Smith       for (j=0; j<bottom; j++) {
428*47c6ae99SBarry Smith         for (k=0; k<x; k += dof) idx[count++] = left+j*(Xe-Xs)+i*(Xe-Xs)*(Ye-Ys)+k;
429*47c6ae99SBarry Smith       }
430*47c6ae99SBarry Smith       /* middle */
431*47c6ae99SBarry Smith       for (j=bottom; j<top; j++) {
432*47c6ae99SBarry Smith         for (k=0; k<Xe-Xs; k += dof) idx[count++] = j*(Xe-Xs)+i*(Xe-Xs)*(Ye-Ys)+k;
433*47c6ae99SBarry Smith       }
434*47c6ae99SBarry Smith       /* back */
435*47c6ae99SBarry Smith       for (j=top; j<Ye-Ys; j++) {
436*47c6ae99SBarry Smith         for (k=0; k<x; k += dof) idx[count++] = left+j*(Xe-Xs)+i*(Xe-Xs)*(Ye-Ys)+k;
437*47c6ae99SBarry Smith       }
438*47c6ae99SBarry Smith     }
439*47c6ae99SBarry Smith     /* the top piece */
440*47c6ae99SBarry Smith     for (i=up; i<Ze-Zs; i++) {
441*47c6ae99SBarry Smith       for (j=bottom; j<top; j++) {
442*47c6ae99SBarry Smith         for (k=0; k<x; k += dof) idx[count++] = left+j*(Xe-Xs)+i*(Xe-Xs)*(Ye-Ys)+k;
443*47c6ae99SBarry Smith       }
444*47c6ae99SBarry Smith     }
445*47c6ae99SBarry Smith     for (i=0; i<count; i++) idx[i] = idx[i]/dof;
446*47c6ae99SBarry Smith     ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&to);CHKERRQ(ierr);
447*47c6ae99SBarry Smith   }
448*47c6ae99SBarry Smith 
449*47c6ae99SBarry Smith   /* determine who lies on each side of use stored in    n24 n25 n26
450*47c6ae99SBarry Smith                                                          n21 n22 n23
451*47c6ae99SBarry Smith                                                          n18 n19 n20
452*47c6ae99SBarry Smith 
453*47c6ae99SBarry Smith                                                          n15 n16 n17
454*47c6ae99SBarry Smith                                                          n12     n14
455*47c6ae99SBarry Smith                                                          n9  n10 n11
456*47c6ae99SBarry Smith 
457*47c6ae99SBarry Smith                                                          n6  n7  n8
458*47c6ae99SBarry Smith                                                          n3  n4  n5
459*47c6ae99SBarry Smith                                                          n0  n1  n2
460*47c6ae99SBarry Smith   */
461*47c6ae99SBarry Smith 
462*47c6ae99SBarry Smith   /* Solve for X,Y, and Z Periodic Case First, Then Modify Solution */
463*47c6ae99SBarry Smith 
464*47c6ae99SBarry Smith   /* Assume Nodes are Internal to the Cube */
465*47c6ae99SBarry Smith 
466*47c6ae99SBarry Smith   n0  = rank - m*n - m - 1;
467*47c6ae99SBarry Smith   n1  = rank - m*n - m;
468*47c6ae99SBarry Smith   n2  = rank - m*n - m + 1;
469*47c6ae99SBarry Smith   n3  = rank - m*n -1;
470*47c6ae99SBarry Smith   n4  = rank - m*n;
471*47c6ae99SBarry Smith   n5  = rank - m*n + 1;
472*47c6ae99SBarry Smith   n6  = rank - m*n + m - 1;
473*47c6ae99SBarry Smith   n7  = rank - m*n + m;
474*47c6ae99SBarry Smith   n8  = rank - m*n + m + 1;
475*47c6ae99SBarry Smith 
476*47c6ae99SBarry Smith   n9  = rank - m - 1;
477*47c6ae99SBarry Smith   n10 = rank - m;
478*47c6ae99SBarry Smith   n11 = rank - m + 1;
479*47c6ae99SBarry Smith   n12 = rank - 1;
480*47c6ae99SBarry Smith   n14 = rank + 1;
481*47c6ae99SBarry Smith   n15 = rank + m - 1;
482*47c6ae99SBarry Smith   n16 = rank + m;
483*47c6ae99SBarry Smith   n17 = rank + m + 1;
484*47c6ae99SBarry Smith 
485*47c6ae99SBarry Smith   n18 = rank + m*n - m - 1;
486*47c6ae99SBarry Smith   n19 = rank + m*n - m;
487*47c6ae99SBarry Smith   n20 = rank + m*n - m + 1;
488*47c6ae99SBarry Smith   n21 = rank + m*n - 1;
489*47c6ae99SBarry Smith   n22 = rank + m*n;
490*47c6ae99SBarry Smith   n23 = rank + m*n + 1;
491*47c6ae99SBarry Smith   n24 = rank + m*n + m - 1;
492*47c6ae99SBarry Smith   n25 = rank + m*n + m;
493*47c6ae99SBarry Smith   n26 = rank + m*n + m + 1;
494*47c6ae99SBarry Smith 
495*47c6ae99SBarry Smith   /* Assume Pieces are on Faces of Cube */
496*47c6ae99SBarry Smith 
497*47c6ae99SBarry Smith   if (xs == 0) { /* First assume not corner or edge */
498*47c6ae99SBarry Smith     n0  = rank       -1 - (m*n);
499*47c6ae99SBarry Smith     n3  = rank + m   -1 - (m*n);
500*47c6ae99SBarry Smith     n6  = rank + 2*m -1 - (m*n);
501*47c6ae99SBarry Smith     n9  = rank       -1;
502*47c6ae99SBarry Smith     n12 = rank + m   -1;
503*47c6ae99SBarry Smith     n15 = rank + 2*m -1;
504*47c6ae99SBarry Smith     n18 = rank       -1 + (m*n);
505*47c6ae99SBarry Smith     n21 = rank + m   -1 + (m*n);
506*47c6ae99SBarry Smith     n24 = rank + 2*m -1 + (m*n);
507*47c6ae99SBarry Smith    }
508*47c6ae99SBarry Smith 
509*47c6ae99SBarry Smith   if (xe == M*dof) { /* First assume not corner or edge */
510*47c6ae99SBarry Smith     n2  = rank -2*m +1 - (m*n);
511*47c6ae99SBarry Smith     n5  = rank - m  +1 - (m*n);
512*47c6ae99SBarry Smith     n8  = rank      +1 - (m*n);
513*47c6ae99SBarry Smith     n11 = rank -2*m +1;
514*47c6ae99SBarry Smith     n14 = rank - m  +1;
515*47c6ae99SBarry Smith     n17 = rank      +1;
516*47c6ae99SBarry Smith     n20 = rank -2*m +1 + (m*n);
517*47c6ae99SBarry Smith     n23 = rank - m  +1 + (m*n);
518*47c6ae99SBarry Smith     n26 = rank      +1 + (m*n);
519*47c6ae99SBarry Smith   }
520*47c6ae99SBarry Smith 
521*47c6ae99SBarry Smith   if (ys==0) { /* First assume not corner or edge */
522*47c6ae99SBarry Smith     n0  = rank + m * (n-1) -1 - (m*n);
523*47c6ae99SBarry Smith     n1  = rank + m * (n-1)    - (m*n);
524*47c6ae99SBarry Smith     n2  = rank + m * (n-1) +1 - (m*n);
525*47c6ae99SBarry Smith     n9  = rank + m * (n-1) -1;
526*47c6ae99SBarry Smith     n10 = rank + m * (n-1);
527*47c6ae99SBarry Smith     n11 = rank + m * (n-1) +1;
528*47c6ae99SBarry Smith     n18 = rank + m * (n-1) -1 + (m*n);
529*47c6ae99SBarry Smith     n19 = rank + m * (n-1)    + (m*n);
530*47c6ae99SBarry Smith     n20 = rank + m * (n-1) +1 + (m*n);
531*47c6ae99SBarry Smith   }
532*47c6ae99SBarry Smith 
533*47c6ae99SBarry Smith   if (ye == N) { /* First assume not corner or edge */
534*47c6ae99SBarry Smith     n6  = rank - m * (n-1) -1 - (m*n);
535*47c6ae99SBarry Smith     n7  = rank - m * (n-1)    - (m*n);
536*47c6ae99SBarry Smith     n8  = rank - m * (n-1) +1 - (m*n);
537*47c6ae99SBarry Smith     n15 = rank - m * (n-1) -1;
538*47c6ae99SBarry Smith     n16 = rank - m * (n-1);
539*47c6ae99SBarry Smith     n17 = rank - m * (n-1) +1;
540*47c6ae99SBarry Smith     n24 = rank - m * (n-1) -1 + (m*n);
541*47c6ae99SBarry Smith     n25 = rank - m * (n-1)    + (m*n);
542*47c6ae99SBarry Smith     n26 = rank - m * (n-1) +1 + (m*n);
543*47c6ae99SBarry Smith   }
544*47c6ae99SBarry Smith 
545*47c6ae99SBarry Smith   if (zs == 0) { /* First assume not corner or edge */
546*47c6ae99SBarry Smith     n0 = size - (m*n) + rank - m - 1;
547*47c6ae99SBarry Smith     n1 = size - (m*n) + rank - m;
548*47c6ae99SBarry Smith     n2 = size - (m*n) + rank - m + 1;
549*47c6ae99SBarry Smith     n3 = size - (m*n) + rank - 1;
550*47c6ae99SBarry Smith     n4 = size - (m*n) + rank;
551*47c6ae99SBarry Smith     n5 = size - (m*n) + rank + 1;
552*47c6ae99SBarry Smith     n6 = size - (m*n) + rank + m - 1;
553*47c6ae99SBarry Smith     n7 = size - (m*n) + rank + m ;
554*47c6ae99SBarry Smith     n8 = size - (m*n) + rank + m + 1;
555*47c6ae99SBarry Smith   }
556*47c6ae99SBarry Smith 
557*47c6ae99SBarry Smith   if (ze == P) { /* First assume not corner or edge */
558*47c6ae99SBarry Smith     n18 = (m*n) - (size-rank) - m - 1;
559*47c6ae99SBarry Smith     n19 = (m*n) - (size-rank) - m;
560*47c6ae99SBarry Smith     n20 = (m*n) - (size-rank) - m + 1;
561*47c6ae99SBarry Smith     n21 = (m*n) - (size-rank) - 1;
562*47c6ae99SBarry Smith     n22 = (m*n) - (size-rank);
563*47c6ae99SBarry Smith     n23 = (m*n) - (size-rank) + 1;
564*47c6ae99SBarry Smith     n24 = (m*n) - (size-rank) + m - 1;
565*47c6ae99SBarry Smith     n25 = (m*n) - (size-rank) + m;
566*47c6ae99SBarry Smith     n26 = (m*n) - (size-rank) + m + 1;
567*47c6ae99SBarry Smith   }
568*47c6ae99SBarry Smith 
569*47c6ae99SBarry Smith   if ((xs==0) && (zs==0)) { /* Assume an edge, not corner */
570*47c6ae99SBarry Smith     n0 = size - m*n + rank + m-1 - m;
571*47c6ae99SBarry Smith     n3 = size - m*n + rank + m-1;
572*47c6ae99SBarry Smith     n6 = size - m*n + rank + m-1 + m;
573*47c6ae99SBarry Smith   }
574*47c6ae99SBarry Smith 
575*47c6ae99SBarry Smith   if ((xs==0) && (ze==P)) { /* Assume an edge, not corner */
576*47c6ae99SBarry Smith     n18 = m*n - (size - rank) + m-1 - m;
577*47c6ae99SBarry Smith     n21 = m*n - (size - rank) + m-1;
578*47c6ae99SBarry Smith     n24 = m*n - (size - rank) + m-1 + m;
579*47c6ae99SBarry Smith   }
580*47c6ae99SBarry Smith 
581*47c6ae99SBarry Smith   if ((xs==0) && (ys==0)) { /* Assume an edge, not corner */
582*47c6ae99SBarry Smith     n0  = rank + m*n -1 - m*n;
583*47c6ae99SBarry Smith     n9  = rank + m*n -1;
584*47c6ae99SBarry Smith     n18 = rank + m*n -1 + m*n;
585*47c6ae99SBarry Smith   }
586*47c6ae99SBarry Smith 
587*47c6ae99SBarry Smith   if ((xs==0) && (ye==N)) { /* Assume an edge, not corner */
588*47c6ae99SBarry Smith     n6  = rank - m*(n-1) + m-1 - m*n;
589*47c6ae99SBarry Smith     n15 = rank - m*(n-1) + m-1;
590*47c6ae99SBarry Smith     n24 = rank - m*(n-1) + m-1 + m*n;
591*47c6ae99SBarry Smith   }
592*47c6ae99SBarry Smith 
593*47c6ae99SBarry Smith   if ((xe==M*dof) && (zs==0)) { /* Assume an edge, not corner */
594*47c6ae99SBarry Smith     n2 = size - (m*n-rank) - (m-1) - m;
595*47c6ae99SBarry Smith     n5 = size - (m*n-rank) - (m-1);
596*47c6ae99SBarry Smith     n8 = size - (m*n-rank) - (m-1) + m;
597*47c6ae99SBarry Smith   }
598*47c6ae99SBarry Smith 
599*47c6ae99SBarry Smith   if ((xe==M*dof) && (ze==P)) { /* Assume an edge, not corner */
600*47c6ae99SBarry Smith     n20 = m*n - (size - rank) - (m-1) - m;
601*47c6ae99SBarry Smith     n23 = m*n - (size - rank) - (m-1);
602*47c6ae99SBarry Smith     n26 = m*n - (size - rank) - (m-1) + m;
603*47c6ae99SBarry Smith   }
604*47c6ae99SBarry Smith 
605*47c6ae99SBarry Smith   if ((xe==M*dof) && (ys==0)) { /* Assume an edge, not corner */
606*47c6ae99SBarry Smith     n2  = rank + m*(n-1) - (m-1) - m*n;
607*47c6ae99SBarry Smith     n11 = rank + m*(n-1) - (m-1);
608*47c6ae99SBarry Smith     n20 = rank + m*(n-1) - (m-1) + m*n;
609*47c6ae99SBarry Smith   }
610*47c6ae99SBarry Smith 
611*47c6ae99SBarry Smith   if ((xe==M*dof) && (ye==N)) { /* Assume an edge, not corner */
612*47c6ae99SBarry Smith     n8  = rank - m*n +1 - m*n;
613*47c6ae99SBarry Smith     n17 = rank - m*n +1;
614*47c6ae99SBarry Smith     n26 = rank - m*n +1 + m*n;
615*47c6ae99SBarry Smith   }
616*47c6ae99SBarry Smith 
617*47c6ae99SBarry Smith   if ((ys==0) && (zs==0)) { /* Assume an edge, not corner */
618*47c6ae99SBarry Smith     n0 = size - m + rank -1;
619*47c6ae99SBarry Smith     n1 = size - m + rank;
620*47c6ae99SBarry Smith     n2 = size - m + rank +1;
621*47c6ae99SBarry Smith   }
622*47c6ae99SBarry Smith 
623*47c6ae99SBarry Smith   if ((ys==0) && (ze==P)) { /* Assume an edge, not corner */
624*47c6ae99SBarry Smith     n18 = m*n - (size - rank) + m*(n-1) -1;
625*47c6ae99SBarry Smith     n19 = m*n - (size - rank) + m*(n-1);
626*47c6ae99SBarry Smith     n20 = m*n - (size - rank) + m*(n-1) +1;
627*47c6ae99SBarry Smith   }
628*47c6ae99SBarry Smith 
629*47c6ae99SBarry Smith   if ((ye==N) && (zs==0)) { /* Assume an edge, not corner */
630*47c6ae99SBarry Smith     n6 = size - (m*n-rank) - m * (n-1) -1;
631*47c6ae99SBarry Smith     n7 = size - (m*n-rank) - m * (n-1);
632*47c6ae99SBarry Smith     n8 = size - (m*n-rank) - m * (n-1) +1;
633*47c6ae99SBarry Smith   }
634*47c6ae99SBarry Smith 
635*47c6ae99SBarry Smith   if ((ye==N) && (ze==P)) { /* Assume an edge, not corner */
636*47c6ae99SBarry Smith     n24 = rank - (size-m) -1;
637*47c6ae99SBarry Smith     n25 = rank - (size-m);
638*47c6ae99SBarry Smith     n26 = rank - (size-m) +1;
639*47c6ae99SBarry Smith   }
640*47c6ae99SBarry Smith 
641*47c6ae99SBarry Smith   /* Check for Corners */
642*47c6ae99SBarry Smith   if ((xs==0)   && (ys==0) && (zs==0)) { n0  = size -1;}
643*47c6ae99SBarry Smith   if ((xs==0)   && (ys==0) && (ze==P)) { n18 = m*n-1;}
644*47c6ae99SBarry Smith   if ((xs==0)   && (ye==N) && (zs==0)) { n6  = (size-1)-m*(n-1);}
645*47c6ae99SBarry Smith   if ((xs==0)   && (ye==N) && (ze==P)) { n24 = m-1;}
646*47c6ae99SBarry Smith   if ((xe==M*dof) && (ys==0) && (zs==0)) { n2  = size-m;}
647*47c6ae99SBarry Smith   if ((xe==M*dof) && (ys==0) && (ze==P)) { n20 = m*n-m;}
648*47c6ae99SBarry Smith   if ((xe==M*dof) && (ye==N) && (zs==0)) { n8  = size-m*n;}
649*47c6ae99SBarry Smith   if ((xe==M*dof) && (ye==N) && (ze==P)) { n26 = 0;}
650*47c6ae99SBarry Smith 
651*47c6ae99SBarry Smith   /* Check for when not X,Y, and Z Periodic */
652*47c6ae99SBarry Smith 
653*47c6ae99SBarry Smith   /* If not X periodic */
654*47c6ae99SBarry Smith   if ((wrap != DA_XPERIODIC)  && (wrap != DA_XYPERIODIC) &&
655*47c6ae99SBarry Smith      (wrap != DA_XZPERIODIC) && (wrap != DA_XYZPERIODIC)) {
656*47c6ae99SBarry Smith     if (xs==0)   {n0  = n3  = n6  = n9  = n12 = n15 = n18 = n21 = n24 = -2;}
657*47c6ae99SBarry Smith     if (xe==M*dof) {n2  = n5  = n8  = n11 = n14 = n17 = n20 = n23 = n26 = -2;}
658*47c6ae99SBarry Smith   }
659*47c6ae99SBarry Smith 
660*47c6ae99SBarry Smith   /* If not Y periodic */
661*47c6ae99SBarry Smith   if ((wrap != DA_YPERIODIC)  && (wrap != DA_XYPERIODIC) &&
662*47c6ae99SBarry Smith       (wrap != DA_YZPERIODIC) && (wrap != DA_XYZPERIODIC)) {
663*47c6ae99SBarry Smith     if (ys==0)   {n0  = n1  = n2  = n9  = n10 = n11 = n18 = n19 = n20 = -2;}
664*47c6ae99SBarry Smith     if (ye==N)   {n6  = n7  = n8  = n15 = n16 = n17 = n24 = n25 = n26 = -2;}
665*47c6ae99SBarry Smith   }
666*47c6ae99SBarry Smith 
667*47c6ae99SBarry Smith   /* If not Z periodic */
668*47c6ae99SBarry Smith   if ((wrap != DA_ZPERIODIC)  && (wrap != DA_XZPERIODIC) &&
669*47c6ae99SBarry Smith       (wrap != DA_YZPERIODIC) && (wrap != DA_XYZPERIODIC)) {
670*47c6ae99SBarry Smith     if (zs==0)   {n0  = n1  = n2  = n3  = n4  = n5  = n6  = n7  = n8  = -2;}
671*47c6ae99SBarry Smith     if (ze==P)   {n18 = n19 = n20 = n21 = n22 = n23 = n24 = n25 = n26 = -2;}
672*47c6ae99SBarry Smith   }
673*47c6ae99SBarry Smith 
674*47c6ae99SBarry Smith   ierr = PetscMalloc(27*sizeof(PetscInt),&dd->neighbors);CHKERRQ(ierr);
675*47c6ae99SBarry Smith   dd->neighbors[0] = n0;
676*47c6ae99SBarry Smith   dd->neighbors[1] = n1;
677*47c6ae99SBarry Smith   dd->neighbors[2] = n2;
678*47c6ae99SBarry Smith   dd->neighbors[3] = n3;
679*47c6ae99SBarry Smith   dd->neighbors[4] = n4;
680*47c6ae99SBarry Smith   dd->neighbors[5] = n5;
681*47c6ae99SBarry Smith   dd->neighbors[6] = n6;
682*47c6ae99SBarry Smith   dd->neighbors[7] = n7;
683*47c6ae99SBarry Smith   dd->neighbors[8] = n8;
684*47c6ae99SBarry Smith   dd->neighbors[9] = n9;
685*47c6ae99SBarry Smith   dd->neighbors[10] = n10;
686*47c6ae99SBarry Smith   dd->neighbors[11] = n11;
687*47c6ae99SBarry Smith   dd->neighbors[12] = n12;
688*47c6ae99SBarry Smith   dd->neighbors[13] = rank;
689*47c6ae99SBarry Smith   dd->neighbors[14] = n14;
690*47c6ae99SBarry Smith   dd->neighbors[15] = n15;
691*47c6ae99SBarry Smith   dd->neighbors[16] = n16;
692*47c6ae99SBarry Smith   dd->neighbors[17] = n17;
693*47c6ae99SBarry Smith   dd->neighbors[18] = n18;
694*47c6ae99SBarry Smith   dd->neighbors[19] = n19;
695*47c6ae99SBarry Smith   dd->neighbors[20] = n20;
696*47c6ae99SBarry Smith   dd->neighbors[21] = n21;
697*47c6ae99SBarry Smith   dd->neighbors[22] = n22;
698*47c6ae99SBarry Smith   dd->neighbors[23] = n23;
699*47c6ae99SBarry Smith   dd->neighbors[24] = n24;
700*47c6ae99SBarry Smith   dd->neighbors[25] = n25;
701*47c6ae99SBarry Smith   dd->neighbors[26] = n26;
702*47c6ae99SBarry Smith 
703*47c6ae99SBarry Smith   /* If star stencil then delete the corner neighbors */
704*47c6ae99SBarry Smith   if (stencil_type == DA_STENCIL_STAR) {
705*47c6ae99SBarry Smith      /* save information about corner neighbors */
706*47c6ae99SBarry Smith      sn0 = n0; sn1 = n1; sn2 = n2; sn3 = n3; sn5 = n5; sn6 = n6; sn7 = n7;
707*47c6ae99SBarry Smith      sn8 = n8; sn9 = n9; sn11 = n11; sn15 = n15; sn17 = n17; sn18 = n18;
708*47c6ae99SBarry Smith      sn19 = n19; sn20 = n20; sn21 = n21; sn23 = n23; sn24 = n24; sn25 = n25;
709*47c6ae99SBarry Smith      sn26 = n26;
710*47c6ae99SBarry Smith      n0  = n1  = n2  = n3  = n5  = n6  = n7  = n8  = n9  = n11 =
711*47c6ae99SBarry Smith      n15 = n17 = n18 = n19 = n20 = n21 = n23 = n24 = n25 = n26 = -1;
712*47c6ae99SBarry Smith   }
713*47c6ae99SBarry Smith 
714*47c6ae99SBarry Smith 
715*47c6ae99SBarry Smith   ierr = PetscMalloc((Xe-Xs)*(Ye-Ys)*(Ze-Zs)*sizeof(PetscInt),&idx);CHKERRQ(ierr);
716*47c6ae99SBarry Smith   ierr = PetscLogObjectMemory(da,(Xe-Xs)*(Ye-Ys)*(Ze-Zs)*sizeof(PetscInt));CHKERRQ(ierr);
717*47c6ae99SBarry Smith 
718*47c6ae99SBarry Smith   nn = 0;
719*47c6ae99SBarry Smith 
720*47c6ae99SBarry Smith   /* Bottom Level */
721*47c6ae99SBarry Smith   for (k=0; k<s_z; k++) {
722*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
723*47c6ae99SBarry Smith       if (n0 >= 0) { /* left below */
724*47c6ae99SBarry Smith         x_t = lx[n0 % m]*dof;
725*47c6ae99SBarry Smith         y_t = ly[(n0 % (m*n))/m];
726*47c6ae99SBarry Smith         z_t = lz[n0 / (m*n)];
727*47c6ae99SBarry Smith         s_t = bases[n0] + x_t*y_t*z_t - (s_y-i)*x_t - s_x - (s_z-k-1)*x_t*y_t;
728*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
729*47c6ae99SBarry Smith       }
730*47c6ae99SBarry Smith       if (n1 >= 0) { /* directly below */
731*47c6ae99SBarry Smith         x_t = x;
732*47c6ae99SBarry Smith         y_t = ly[(n1 % (m*n))/m];
733*47c6ae99SBarry Smith         z_t = lz[n1 / (m*n)];
734*47c6ae99SBarry Smith         s_t = bases[n1] + x_t*y_t*z_t - (s_y+1-i)*x_t - (s_z-k-1)*x_t*y_t;
735*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
736*47c6ae99SBarry Smith       }
737*47c6ae99SBarry Smith       if (n2 >= 0) { /* right below */
738*47c6ae99SBarry Smith         x_t = lx[n2 % m]*dof;
739*47c6ae99SBarry Smith         y_t = ly[(n2 % (m*n))/m];
740*47c6ae99SBarry Smith         z_t = lz[n2 / (m*n)];
741*47c6ae99SBarry Smith         s_t = bases[n2] + x_t*y_t*z_t - (s_y+1-i)*x_t - (s_z-k-1)*x_t*y_t;
742*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
743*47c6ae99SBarry Smith       }
744*47c6ae99SBarry Smith     }
745*47c6ae99SBarry Smith 
746*47c6ae99SBarry Smith     for (i=0; i<y; i++) {
747*47c6ae99SBarry Smith       if (n3 >= 0) { /* directly left */
748*47c6ae99SBarry Smith         x_t = lx[n3 % m]*dof;
749*47c6ae99SBarry Smith         y_t = y;
750*47c6ae99SBarry Smith         z_t = lz[n3 / (m*n)];
751*47c6ae99SBarry Smith         s_t = bases[n3] + (i+1)*x_t - s_x + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
752*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
753*47c6ae99SBarry Smith       }
754*47c6ae99SBarry Smith 
755*47c6ae99SBarry Smith       if (n4 >= 0) { /* middle */
756*47c6ae99SBarry Smith         x_t = x;
757*47c6ae99SBarry Smith         y_t = y;
758*47c6ae99SBarry Smith         z_t = lz[n4 / (m*n)];
759*47c6ae99SBarry Smith         s_t = bases[n4] + i*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
760*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
761*47c6ae99SBarry Smith       }
762*47c6ae99SBarry Smith 
763*47c6ae99SBarry Smith       if (n5 >= 0) { /* directly right */
764*47c6ae99SBarry Smith         x_t = lx[n5 % m]*dof;
765*47c6ae99SBarry Smith         y_t = y;
766*47c6ae99SBarry Smith         z_t = lz[n5 / (m*n)];
767*47c6ae99SBarry Smith         s_t = bases[n5] + i*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
768*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
769*47c6ae99SBarry Smith       }
770*47c6ae99SBarry Smith     }
771*47c6ae99SBarry Smith 
772*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
773*47c6ae99SBarry Smith       if (n6 >= 0) { /* left above */
774*47c6ae99SBarry Smith         x_t = lx[n6 % m]*dof;
775*47c6ae99SBarry Smith         y_t = ly[(n6 % (m*n))/m];
776*47c6ae99SBarry Smith         z_t = lz[n6 / (m*n)];
777*47c6ae99SBarry Smith         s_t = bases[n6] + i*x_t - s_x + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
778*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
779*47c6ae99SBarry Smith       }
780*47c6ae99SBarry Smith       if (n7 >= 0) { /* directly above */
781*47c6ae99SBarry Smith         x_t = x;
782*47c6ae99SBarry Smith         y_t = ly[(n7 % (m*n))/m];
783*47c6ae99SBarry Smith         z_t = lz[n7 / (m*n)];
784*47c6ae99SBarry Smith         s_t = bases[n7] + (i-1)*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
785*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
786*47c6ae99SBarry Smith       }
787*47c6ae99SBarry Smith       if (n8 >= 0) { /* right above */
788*47c6ae99SBarry Smith         x_t = lx[n8 % m]*dof;
789*47c6ae99SBarry Smith         y_t = ly[(n8 % (m*n))/m];
790*47c6ae99SBarry Smith         z_t = lz[n8 / (m*n)];
791*47c6ae99SBarry Smith         s_t = bases[n8] + (i-1)*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
792*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
793*47c6ae99SBarry Smith       }
794*47c6ae99SBarry Smith     }
795*47c6ae99SBarry Smith   }
796*47c6ae99SBarry Smith 
797*47c6ae99SBarry Smith   /* Middle Level */
798*47c6ae99SBarry Smith   for (k=0; k<z; k++) {
799*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
800*47c6ae99SBarry Smith       if (n9 >= 0) { /* left below */
801*47c6ae99SBarry Smith         x_t = lx[n9 % m]*dof;
802*47c6ae99SBarry Smith         y_t = ly[(n9 % (m*n))/m];
803*47c6ae99SBarry Smith         /* z_t = z; */
804*47c6ae99SBarry Smith         s_t = bases[n9] - (s_y-i)*x_t -s_x + (k+1)*x_t*y_t;
805*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
806*47c6ae99SBarry Smith       }
807*47c6ae99SBarry Smith       if (n10 >= 0) { /* directly below */
808*47c6ae99SBarry Smith         x_t = x;
809*47c6ae99SBarry Smith         y_t = ly[(n10 % (m*n))/m];
810*47c6ae99SBarry Smith         /* z_t = z; */
811*47c6ae99SBarry Smith         s_t = bases[n10] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
812*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
813*47c6ae99SBarry Smith       }
814*47c6ae99SBarry Smith       if (n11 >= 0) { /* right below */
815*47c6ae99SBarry Smith         x_t = lx[n11 % m]*dof;
816*47c6ae99SBarry Smith         y_t = ly[(n11 % (m*n))/m];
817*47c6ae99SBarry Smith         /* z_t = z; */
818*47c6ae99SBarry Smith         s_t = bases[n11] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
819*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
820*47c6ae99SBarry Smith       }
821*47c6ae99SBarry Smith     }
822*47c6ae99SBarry Smith 
823*47c6ae99SBarry Smith     for (i=0; i<y; i++) {
824*47c6ae99SBarry Smith       if (n12 >= 0) { /* directly left */
825*47c6ae99SBarry Smith         x_t = lx[n12 % m]*dof;
826*47c6ae99SBarry Smith         y_t = y;
827*47c6ae99SBarry Smith         /* z_t = z; */
828*47c6ae99SBarry Smith         s_t = bases[n12] + (i+1)*x_t - s_x + k*x_t*y_t;
829*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
830*47c6ae99SBarry Smith       }
831*47c6ae99SBarry Smith 
832*47c6ae99SBarry Smith       /* Interior */
833*47c6ae99SBarry Smith       s_t = bases[rank] + i*x + k*x*y;
834*47c6ae99SBarry Smith       for (j=0; j<x; j++) { idx[nn++] = s_t++;}
835*47c6ae99SBarry Smith 
836*47c6ae99SBarry Smith       if (n14 >= 0) { /* directly right */
837*47c6ae99SBarry Smith         x_t = lx[n14 % m]*dof;
838*47c6ae99SBarry Smith         y_t = y;
839*47c6ae99SBarry Smith         /* z_t = z; */
840*47c6ae99SBarry Smith         s_t = bases[n14] + i*x_t + k*x_t*y_t;
841*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
842*47c6ae99SBarry Smith       }
843*47c6ae99SBarry Smith     }
844*47c6ae99SBarry Smith 
845*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
846*47c6ae99SBarry Smith       if (n15 >= 0) { /* left above */
847*47c6ae99SBarry Smith         x_t = lx[n15 % m]*dof;
848*47c6ae99SBarry Smith         y_t = ly[(n15 % (m*n))/m];
849*47c6ae99SBarry Smith         /* z_t = z; */
850*47c6ae99SBarry Smith         s_t = bases[n15] + i*x_t - s_x + k*x_t*y_t;
851*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
852*47c6ae99SBarry Smith       }
853*47c6ae99SBarry Smith       if (n16 >= 0) { /* directly above */
854*47c6ae99SBarry Smith         x_t = x;
855*47c6ae99SBarry Smith         y_t = ly[(n16 % (m*n))/m];
856*47c6ae99SBarry Smith         /* z_t = z; */
857*47c6ae99SBarry Smith         s_t = bases[n16] + (i-1)*x_t + k*x_t*y_t;
858*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
859*47c6ae99SBarry Smith       }
860*47c6ae99SBarry Smith       if (n17 >= 0) { /* right above */
861*47c6ae99SBarry Smith         x_t = lx[n17 % m]*dof;
862*47c6ae99SBarry Smith         y_t = ly[(n17 % (m*n))/m];
863*47c6ae99SBarry Smith         /* z_t = z; */
864*47c6ae99SBarry Smith         s_t = bases[n17] + (i-1)*x_t + k*x_t*y_t;
865*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
866*47c6ae99SBarry Smith       }
867*47c6ae99SBarry Smith     }
868*47c6ae99SBarry Smith   }
869*47c6ae99SBarry Smith 
870*47c6ae99SBarry Smith   /* Upper Level */
871*47c6ae99SBarry Smith   for (k=0; k<s_z; k++) {
872*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
873*47c6ae99SBarry Smith       if (n18 >= 0) { /* left below */
874*47c6ae99SBarry Smith         x_t = lx[n18 % m]*dof;
875*47c6ae99SBarry Smith         y_t = ly[(n18 % (m*n))/m];
876*47c6ae99SBarry Smith         /* z_t = lz[n18 / (m*n)]; */
877*47c6ae99SBarry Smith         s_t = bases[n18] - (s_y-i)*x_t -s_x + (k+1)*x_t*y_t;
878*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
879*47c6ae99SBarry Smith       }
880*47c6ae99SBarry Smith       if (n19 >= 0) { /* directly below */
881*47c6ae99SBarry Smith         x_t = x;
882*47c6ae99SBarry Smith         y_t = ly[(n19 % (m*n))/m];
883*47c6ae99SBarry Smith         /* z_t = lz[n19 / (m*n)]; */
884*47c6ae99SBarry Smith         s_t = bases[n19] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
885*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
886*47c6ae99SBarry Smith       }
887*47c6ae99SBarry Smith       if (n20 >= 0) { /* right below */
888*47c6ae99SBarry Smith         x_t = lx[n20 % m]*dof;
889*47c6ae99SBarry Smith         y_t = ly[(n20 % (m*n))/m];
890*47c6ae99SBarry Smith         /* z_t = lz[n20 / (m*n)]; */
891*47c6ae99SBarry Smith         s_t = bases[n20] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
892*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
893*47c6ae99SBarry Smith       }
894*47c6ae99SBarry Smith     }
895*47c6ae99SBarry Smith 
896*47c6ae99SBarry Smith     for (i=0; i<y; i++) {
897*47c6ae99SBarry Smith       if (n21 >= 0) { /* directly left */
898*47c6ae99SBarry Smith         x_t = lx[n21 % m]*dof;
899*47c6ae99SBarry Smith         y_t = y;
900*47c6ae99SBarry Smith         /* z_t = lz[n21 / (m*n)]; */
901*47c6ae99SBarry Smith         s_t = bases[n21] + (i+1)*x_t - s_x + k*x_t*y_t;
902*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
903*47c6ae99SBarry Smith       }
904*47c6ae99SBarry Smith 
905*47c6ae99SBarry Smith       if (n22 >= 0) { /* middle */
906*47c6ae99SBarry Smith         x_t = x;
907*47c6ae99SBarry Smith         y_t = y;
908*47c6ae99SBarry Smith         /* z_t = lz[n22 / (m*n)]; */
909*47c6ae99SBarry Smith         s_t = bases[n22] + i*x_t + k*x_t*y_t;
910*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
911*47c6ae99SBarry Smith       }
912*47c6ae99SBarry Smith 
913*47c6ae99SBarry Smith       if (n23 >= 0) { /* directly right */
914*47c6ae99SBarry Smith         x_t = lx[n23 % m]*dof;
915*47c6ae99SBarry Smith         y_t = y;
916*47c6ae99SBarry Smith         /* z_t = lz[n23 / (m*n)]; */
917*47c6ae99SBarry Smith         s_t = bases[n23] + i*x_t + k*x_t*y_t;
918*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
919*47c6ae99SBarry Smith       }
920*47c6ae99SBarry Smith     }
921*47c6ae99SBarry Smith 
922*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
923*47c6ae99SBarry Smith       if (n24 >= 0) { /* left above */
924*47c6ae99SBarry Smith         x_t = lx[n24 % m]*dof;
925*47c6ae99SBarry Smith         y_t = ly[(n24 % (m*n))/m];
926*47c6ae99SBarry Smith         /* z_t = lz[n24 / (m*n)]; */
927*47c6ae99SBarry Smith         s_t = bases[n24] + i*x_t - s_x + k*x_t*y_t;
928*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
929*47c6ae99SBarry Smith       }
930*47c6ae99SBarry Smith       if (n25 >= 0) { /* directly above */
931*47c6ae99SBarry Smith         x_t = x;
932*47c6ae99SBarry Smith         y_t = ly[(n25 % (m*n))/m];
933*47c6ae99SBarry Smith         /* z_t = lz[n25 / (m*n)]; */
934*47c6ae99SBarry Smith         s_t = bases[n25] + (i-1)*x_t + k*x_t*y_t;
935*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
936*47c6ae99SBarry Smith       }
937*47c6ae99SBarry Smith       if (n26 >= 0) { /* right above */
938*47c6ae99SBarry Smith         x_t = lx[n26 % m]*dof;
939*47c6ae99SBarry Smith         y_t = ly[(n26 % (m*n))/m];
940*47c6ae99SBarry Smith         /* z_t = lz[n26 / (m*n)]; */
941*47c6ae99SBarry Smith         s_t = bases[n26] + (i-1)*x_t + k*x_t*y_t;
942*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
943*47c6ae99SBarry Smith       }
944*47c6ae99SBarry Smith     }
945*47c6ae99SBarry Smith   }
946*47c6ae99SBarry Smith   base = bases[rank];
947*47c6ae99SBarry Smith   {
948*47c6ae99SBarry Smith     PetscInt nnn = nn/dof,*iidx;
949*47c6ae99SBarry Smith     ierr = PetscMalloc(nnn*sizeof(PetscInt),&iidx);CHKERRQ(ierr);
950*47c6ae99SBarry Smith     for (i=0; i<nnn; i++) {
951*47c6ae99SBarry Smith       iidx[i] = idx[dof*i]/dof;
952*47c6ae99SBarry Smith     }
953*47c6ae99SBarry Smith     ierr = ISCreateBlock(comm,dof,nnn,iidx,PETSC_OWN_POINTER,&from);CHKERRQ(ierr);
954*47c6ae99SBarry Smith   }
955*47c6ae99SBarry Smith   ierr = VecScatterCreate(global,from,local,to,&gtol);CHKERRQ(ierr);
956*47c6ae99SBarry Smith   ierr = PetscLogObjectParent(da,gtol);CHKERRQ(ierr);
957*47c6ae99SBarry Smith   ierr = ISDestroy(from);CHKERRQ(ierr);
958*47c6ae99SBarry Smith   ierr = ISDestroy(to);CHKERRQ(ierr);
959*47c6ae99SBarry Smith 
960*47c6ae99SBarry Smith   dd->m  = m;  dd->n  = n;  dd->p  = p;
961*47c6ae99SBarry Smith   dd->xs = xs; dd->xe = xe; dd->ys = ys; dd->ye = ye; dd->zs = zs; dd->ze = ze;
962*47c6ae99SBarry Smith   dd->Xs = Xs; dd->Xe = Xe; dd->Ys = Ys; dd->Ye = Ye; dd->Zs = Zs; dd->Ze = Ze;
963*47c6ae99SBarry Smith 
964*47c6ae99SBarry Smith   ierr = VecDestroy(local);CHKERRQ(ierr);
965*47c6ae99SBarry Smith   ierr = VecDestroy(global);CHKERRQ(ierr);
966*47c6ae99SBarry Smith 
967*47c6ae99SBarry Smith   if (stencil_type == DA_STENCIL_STAR) {
968*47c6ae99SBarry Smith     /*
969*47c6ae99SBarry Smith         Recompute the local to global mappings, this time keeping the
970*47c6ae99SBarry Smith       information about the cross corner processor numbers.
971*47c6ae99SBarry Smith     */
972*47c6ae99SBarry Smith     n0  = sn0;  n1  = sn1;  n2  = sn2;  n3  = sn3;  n5  = sn5;  n6  = sn6; n7 = sn7;
973*47c6ae99SBarry Smith     n8  = sn8;  n9  = sn9;  n11 = sn11; n15 = sn15; n17 = sn17; n18 = sn18;
974*47c6ae99SBarry Smith     n19 = sn19; n20 = sn20; n21 = sn21; n23 = sn23; n24 = sn24; n25 = sn25;
975*47c6ae99SBarry Smith     n26 = sn26;
976*47c6ae99SBarry Smith 
977*47c6ae99SBarry Smith     nn = 0;
978*47c6ae99SBarry Smith 
979*47c6ae99SBarry Smith     /* Bottom Level */
980*47c6ae99SBarry Smith     for (k=0; k<s_z; k++) {
981*47c6ae99SBarry Smith       for (i=1; i<=s_y; i++) {
982*47c6ae99SBarry Smith         if (n0 >= 0) { /* left below */
983*47c6ae99SBarry Smith           x_t = lx[n0 % m]*dof;
984*47c6ae99SBarry Smith           y_t = ly[(n0 % (m*n))/m];
985*47c6ae99SBarry Smith           z_t = lz[n0 / (m*n)];
986*47c6ae99SBarry Smith           s_t = bases[n0] + x_t*y_t*z_t - (s_y-i)*x_t - s_x - (s_z-k-1)*x_t*y_t;
987*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
988*47c6ae99SBarry Smith         }
989*47c6ae99SBarry Smith         if (n1 >= 0) { /* directly below */
990*47c6ae99SBarry Smith           x_t = x;
991*47c6ae99SBarry Smith           y_t = ly[(n1 % (m*n))/m];
992*47c6ae99SBarry Smith           z_t = lz[n1 / (m*n)];
993*47c6ae99SBarry Smith           s_t = bases[n1] + x_t*y_t*z_t - (s_y+1-i)*x_t - (s_z-k-1)*x_t*y_t;
994*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
995*47c6ae99SBarry Smith         }
996*47c6ae99SBarry Smith         if (n2 >= 0) { /* right below */
997*47c6ae99SBarry Smith           x_t = lx[n2 % m]*dof;
998*47c6ae99SBarry Smith           y_t = ly[(n2 % (m*n))/m];
999*47c6ae99SBarry Smith           z_t = lz[n2 / (m*n)];
1000*47c6ae99SBarry Smith           s_t = bases[n2] + x_t*y_t*z_t - (s_y+1-i)*x_t - (s_z-k-1)*x_t*y_t;
1001*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1002*47c6ae99SBarry Smith         }
1003*47c6ae99SBarry Smith       }
1004*47c6ae99SBarry Smith 
1005*47c6ae99SBarry Smith       for (i=0; i<y; i++) {
1006*47c6ae99SBarry Smith         if (n3 >= 0) { /* directly left */
1007*47c6ae99SBarry Smith           x_t = lx[n3 % m]*dof;
1008*47c6ae99SBarry Smith           y_t = y;
1009*47c6ae99SBarry Smith           z_t = lz[n3 / (m*n)];
1010*47c6ae99SBarry Smith           s_t = bases[n3] + (i+1)*x_t - s_x + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1011*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1012*47c6ae99SBarry Smith         }
1013*47c6ae99SBarry Smith 
1014*47c6ae99SBarry Smith         if (n4 >= 0) { /* middle */
1015*47c6ae99SBarry Smith           x_t = x;
1016*47c6ae99SBarry Smith           y_t = y;
1017*47c6ae99SBarry Smith           z_t = lz[n4 / (m*n)];
1018*47c6ae99SBarry Smith           s_t = bases[n4] + i*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1019*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1020*47c6ae99SBarry Smith         }
1021*47c6ae99SBarry Smith 
1022*47c6ae99SBarry Smith         if (n5 >= 0) { /* directly right */
1023*47c6ae99SBarry Smith           x_t = lx[n5 % m]*dof;
1024*47c6ae99SBarry Smith           y_t = y;
1025*47c6ae99SBarry Smith           z_t = lz[n5 / (m*n)];
1026*47c6ae99SBarry Smith           s_t = bases[n5] + i*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1027*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1028*47c6ae99SBarry Smith         }
1029*47c6ae99SBarry Smith       }
1030*47c6ae99SBarry Smith 
1031*47c6ae99SBarry Smith       for (i=1; i<=s_y; i++) {
1032*47c6ae99SBarry Smith         if (n6 >= 0) { /* left above */
1033*47c6ae99SBarry Smith           x_t = lx[n6 % m]*dof;
1034*47c6ae99SBarry Smith           y_t = ly[(n6 % (m*n))/m];
1035*47c6ae99SBarry Smith           z_t = lz[n6 / (m*n)];
1036*47c6ae99SBarry Smith           s_t = bases[n6] + i*x_t - s_x + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1037*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1038*47c6ae99SBarry Smith         }
1039*47c6ae99SBarry Smith         if (n7 >= 0) { /* directly above */
1040*47c6ae99SBarry Smith           x_t = x;
1041*47c6ae99SBarry Smith           y_t = ly[(n7 % (m*n))/m];
1042*47c6ae99SBarry Smith           z_t = lz[n7 / (m*n)];
1043*47c6ae99SBarry Smith           s_t = bases[n7] + (i-1)*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1044*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1045*47c6ae99SBarry Smith         }
1046*47c6ae99SBarry Smith         if (n8 >= 0) { /* right above */
1047*47c6ae99SBarry Smith           x_t = lx[n8 % m]*dof;
1048*47c6ae99SBarry Smith           y_t = ly[(n8 % (m*n))/m];
1049*47c6ae99SBarry Smith           z_t = lz[n8 / (m*n)];
1050*47c6ae99SBarry Smith           s_t = bases[n8] + (i-1)*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1051*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1052*47c6ae99SBarry Smith         }
1053*47c6ae99SBarry Smith       }
1054*47c6ae99SBarry Smith     }
1055*47c6ae99SBarry Smith 
1056*47c6ae99SBarry Smith     /* Middle Level */
1057*47c6ae99SBarry Smith     for (k=0; k<z; k++) {
1058*47c6ae99SBarry Smith       for (i=1; i<=s_y; i++) {
1059*47c6ae99SBarry Smith         if (n9 >= 0) { /* left below */
1060*47c6ae99SBarry Smith           x_t = lx[n9 % m]*dof;
1061*47c6ae99SBarry Smith           y_t = ly[(n9 % (m*n))/m];
1062*47c6ae99SBarry Smith           /* z_t = z; */
1063*47c6ae99SBarry Smith           s_t = bases[n9] - (s_y-i)*x_t -s_x + (k+1)*x_t*y_t;
1064*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1065*47c6ae99SBarry Smith         }
1066*47c6ae99SBarry Smith         if (n10 >= 0) { /* directly below */
1067*47c6ae99SBarry Smith           x_t = x;
1068*47c6ae99SBarry Smith           y_t = ly[(n10 % (m*n))/m];
1069*47c6ae99SBarry Smith           /* z_t = z; */
1070*47c6ae99SBarry Smith           s_t = bases[n10] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1071*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1072*47c6ae99SBarry Smith         }
1073*47c6ae99SBarry Smith         if (n11 >= 0) { /* right below */
1074*47c6ae99SBarry Smith           x_t = lx[n11 % m]*dof;
1075*47c6ae99SBarry Smith           y_t = ly[(n11 % (m*n))/m];
1076*47c6ae99SBarry Smith           /* z_t = z; */
1077*47c6ae99SBarry Smith           s_t = bases[n11] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1078*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1079*47c6ae99SBarry Smith         }
1080*47c6ae99SBarry Smith       }
1081*47c6ae99SBarry Smith 
1082*47c6ae99SBarry Smith       for (i=0; i<y; i++) {
1083*47c6ae99SBarry Smith         if (n12 >= 0) { /* directly left */
1084*47c6ae99SBarry Smith           x_t = lx[n12 % m]*dof;
1085*47c6ae99SBarry Smith           y_t = y;
1086*47c6ae99SBarry Smith           /* z_t = z; */
1087*47c6ae99SBarry Smith           s_t = bases[n12] + (i+1)*x_t - s_x + k*x_t*y_t;
1088*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1089*47c6ae99SBarry Smith         }
1090*47c6ae99SBarry Smith 
1091*47c6ae99SBarry Smith         /* Interior */
1092*47c6ae99SBarry Smith         s_t = bases[rank] + i*x + k*x*y;
1093*47c6ae99SBarry Smith         for (j=0; j<x; j++) { idx[nn++] = s_t++;}
1094*47c6ae99SBarry Smith 
1095*47c6ae99SBarry Smith         if (n14 >= 0) { /* directly right */
1096*47c6ae99SBarry Smith           x_t = lx[n14 % m]*dof;
1097*47c6ae99SBarry Smith           y_t = y;
1098*47c6ae99SBarry Smith           /* z_t = z; */
1099*47c6ae99SBarry Smith           s_t = bases[n14] + i*x_t + k*x_t*y_t;
1100*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1101*47c6ae99SBarry Smith         }
1102*47c6ae99SBarry Smith       }
1103*47c6ae99SBarry Smith 
1104*47c6ae99SBarry Smith       for (i=1; i<=s_y; i++) {
1105*47c6ae99SBarry Smith         if (n15 >= 0) { /* left above */
1106*47c6ae99SBarry Smith           x_t = lx[n15 % m]*dof;
1107*47c6ae99SBarry Smith           y_t = ly[(n15 % (m*n))/m];
1108*47c6ae99SBarry Smith           /* z_t = z; */
1109*47c6ae99SBarry Smith           s_t = bases[n15] + i*x_t - s_x + k*x_t*y_t;
1110*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1111*47c6ae99SBarry Smith         }
1112*47c6ae99SBarry Smith         if (n16 >= 0) { /* directly above */
1113*47c6ae99SBarry Smith           x_t = x;
1114*47c6ae99SBarry Smith           y_t = ly[(n16 % (m*n))/m];
1115*47c6ae99SBarry Smith           /* z_t = z; */
1116*47c6ae99SBarry Smith           s_t = bases[n16] + (i-1)*x_t + k*x_t*y_t;
1117*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1118*47c6ae99SBarry Smith         }
1119*47c6ae99SBarry Smith         if (n17 >= 0) { /* right above */
1120*47c6ae99SBarry Smith           x_t = lx[n17 % m]*dof;
1121*47c6ae99SBarry Smith           y_t = ly[(n17 % (m*n))/m];
1122*47c6ae99SBarry Smith           /* z_t = z; */
1123*47c6ae99SBarry Smith           s_t = bases[n17] + (i-1)*x_t + k*x_t*y_t;
1124*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1125*47c6ae99SBarry Smith         }
1126*47c6ae99SBarry Smith       }
1127*47c6ae99SBarry Smith     }
1128*47c6ae99SBarry Smith 
1129*47c6ae99SBarry Smith     /* Upper Level */
1130*47c6ae99SBarry Smith     for (k=0; k<s_z; k++) {
1131*47c6ae99SBarry Smith       for (i=1; i<=s_y; i++) {
1132*47c6ae99SBarry Smith         if (n18 >= 0) { /* left below */
1133*47c6ae99SBarry Smith           x_t = lx[n18 % m]*dof;
1134*47c6ae99SBarry Smith           y_t = ly[(n18 % (m*n))/m];
1135*47c6ae99SBarry Smith           /* z_t = lz[n18 / (m*n)]; */
1136*47c6ae99SBarry Smith           s_t = bases[n18] - (s_y-i)*x_t -s_x + (k+1)*x_t*y_t;
1137*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1138*47c6ae99SBarry Smith         }
1139*47c6ae99SBarry Smith         if (n19 >= 0) { /* directly below */
1140*47c6ae99SBarry Smith           x_t = x;
1141*47c6ae99SBarry Smith           y_t = ly[(n19 % (m*n))/m];
1142*47c6ae99SBarry Smith           /* z_t = lz[n19 / (m*n)]; */
1143*47c6ae99SBarry Smith           s_t = bases[n19] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1144*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1145*47c6ae99SBarry Smith         }
1146*47c6ae99SBarry Smith         if (n20 >= 0) { /* right below */
1147*47c6ae99SBarry Smith           x_t = lx[n20 % m]*dof;
1148*47c6ae99SBarry Smith           y_t = ly[(n20 % (m*n))/m];
1149*47c6ae99SBarry Smith           /* z_t = lz[n20 / (m*n)]; */
1150*47c6ae99SBarry Smith           s_t = bases[n20] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1151*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1152*47c6ae99SBarry Smith         }
1153*47c6ae99SBarry Smith       }
1154*47c6ae99SBarry Smith 
1155*47c6ae99SBarry Smith       for (i=0; i<y; i++) {
1156*47c6ae99SBarry Smith         if (n21 >= 0) { /* directly left */
1157*47c6ae99SBarry Smith           x_t = lx[n21 % m]*dof;
1158*47c6ae99SBarry Smith           y_t = y;
1159*47c6ae99SBarry Smith           /* z_t = lz[n21 / (m*n)]; */
1160*47c6ae99SBarry Smith           s_t = bases[n21] + (i+1)*x_t - s_x + k*x_t*y_t;
1161*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1162*47c6ae99SBarry Smith         }
1163*47c6ae99SBarry Smith 
1164*47c6ae99SBarry Smith         if (n22 >= 0) { /* middle */
1165*47c6ae99SBarry Smith           x_t = x;
1166*47c6ae99SBarry Smith           y_t = y;
1167*47c6ae99SBarry Smith           /* z_t = lz[n22 / (m*n)]; */
1168*47c6ae99SBarry Smith           s_t = bases[n22] + i*x_t + k*x_t*y_t;
1169*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1170*47c6ae99SBarry Smith         }
1171*47c6ae99SBarry Smith 
1172*47c6ae99SBarry Smith         if (n23 >= 0) { /* directly right */
1173*47c6ae99SBarry Smith           x_t = lx[n23 % m]*dof;
1174*47c6ae99SBarry Smith           y_t = y;
1175*47c6ae99SBarry Smith           /* z_t = lz[n23 / (m*n)]; */
1176*47c6ae99SBarry Smith           s_t = bases[n23] + i*x_t + k*x_t*y_t;
1177*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1178*47c6ae99SBarry Smith         }
1179*47c6ae99SBarry Smith       }
1180*47c6ae99SBarry Smith 
1181*47c6ae99SBarry Smith       for (i=1; i<=s_y; i++) {
1182*47c6ae99SBarry Smith         if (n24 >= 0) { /* left above */
1183*47c6ae99SBarry Smith           x_t = lx[n24 % m]*dof;
1184*47c6ae99SBarry Smith           y_t = ly[(n24 % (m*n))/m];
1185*47c6ae99SBarry Smith           /* z_t = lz[n24 / (m*n)]; */
1186*47c6ae99SBarry Smith           s_t = bases[n24] + i*x_t - s_x + k*x_t*y_t;
1187*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1188*47c6ae99SBarry Smith         }
1189*47c6ae99SBarry Smith         if (n25 >= 0) { /* directly above */
1190*47c6ae99SBarry Smith           x_t = x;
1191*47c6ae99SBarry Smith           y_t = ly[(n25 % (m*n))/m];
1192*47c6ae99SBarry Smith           /* z_t = lz[n25 / (m*n)]; */
1193*47c6ae99SBarry Smith           s_t = bases[n25] + (i-1)*x_t + k*x_t*y_t;
1194*47c6ae99SBarry Smith           for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1195*47c6ae99SBarry Smith         }
1196*47c6ae99SBarry Smith         if (n26 >= 0) { /* right above */
1197*47c6ae99SBarry Smith           x_t = lx[n26 % m]*dof;
1198*47c6ae99SBarry Smith           y_t = ly[(n26 % (m*n))/m];
1199*47c6ae99SBarry Smith           /* z_t = lz[n26 / (m*n)]; */
1200*47c6ae99SBarry Smith           s_t = bases[n26] + (i-1)*x_t + k*x_t*y_t;
1201*47c6ae99SBarry Smith           for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1202*47c6ae99SBarry Smith         }
1203*47c6ae99SBarry Smith       }
1204*47c6ae99SBarry Smith     }
1205*47c6ae99SBarry Smith   }
1206*47c6ae99SBarry Smith   /* redo idx to include "missing" ghost points */
1207*47c6ae99SBarry Smith   /* Solve for X,Y, and Z Periodic Case First, Then Modify Solution */
1208*47c6ae99SBarry Smith 
1209*47c6ae99SBarry Smith   /* Assume Nodes are Internal to the Cube */
1210*47c6ae99SBarry Smith 
1211*47c6ae99SBarry Smith   n0  = rank - m*n - m - 1;
1212*47c6ae99SBarry Smith   n1  = rank - m*n - m;
1213*47c6ae99SBarry Smith   n2  = rank - m*n - m + 1;
1214*47c6ae99SBarry Smith   n3  = rank - m*n -1;
1215*47c6ae99SBarry Smith   n4  = rank - m*n;
1216*47c6ae99SBarry Smith   n5  = rank - m*n + 1;
1217*47c6ae99SBarry Smith   n6  = rank - m*n + m - 1;
1218*47c6ae99SBarry Smith   n7  = rank - m*n + m;
1219*47c6ae99SBarry Smith   n8  = rank - m*n + m + 1;
1220*47c6ae99SBarry Smith 
1221*47c6ae99SBarry Smith   n9  = rank - m - 1;
1222*47c6ae99SBarry Smith   n10 = rank - m;
1223*47c6ae99SBarry Smith   n11 = rank - m + 1;
1224*47c6ae99SBarry Smith   n12 = rank - 1;
1225*47c6ae99SBarry Smith   n14 = rank + 1;
1226*47c6ae99SBarry Smith   n15 = rank + m - 1;
1227*47c6ae99SBarry Smith   n16 = rank + m;
1228*47c6ae99SBarry Smith   n17 = rank + m + 1;
1229*47c6ae99SBarry Smith 
1230*47c6ae99SBarry Smith   n18 = rank + m*n - m - 1;
1231*47c6ae99SBarry Smith   n19 = rank + m*n - m;
1232*47c6ae99SBarry Smith   n20 = rank + m*n - m + 1;
1233*47c6ae99SBarry Smith   n21 = rank + m*n - 1;
1234*47c6ae99SBarry Smith   n22 = rank + m*n;
1235*47c6ae99SBarry Smith   n23 = rank + m*n + 1;
1236*47c6ae99SBarry Smith   n24 = rank + m*n + m - 1;
1237*47c6ae99SBarry Smith   n25 = rank + m*n + m;
1238*47c6ae99SBarry Smith   n26 = rank + m*n + m + 1;
1239*47c6ae99SBarry Smith 
1240*47c6ae99SBarry Smith   /* Assume Pieces are on Faces of Cube */
1241*47c6ae99SBarry Smith 
1242*47c6ae99SBarry Smith   if (xs == 0) { /* First assume not corner or edge */
1243*47c6ae99SBarry Smith     n0  = rank       -1 - (m*n);
1244*47c6ae99SBarry Smith     n3  = rank + m   -1 - (m*n);
1245*47c6ae99SBarry Smith     n6  = rank + 2*m -1 - (m*n);
1246*47c6ae99SBarry Smith     n9  = rank       -1;
1247*47c6ae99SBarry Smith     n12 = rank + m   -1;
1248*47c6ae99SBarry Smith     n15 = rank + 2*m -1;
1249*47c6ae99SBarry Smith     n18 = rank       -1 + (m*n);
1250*47c6ae99SBarry Smith     n21 = rank + m   -1 + (m*n);
1251*47c6ae99SBarry Smith     n24 = rank + 2*m -1 + (m*n);
1252*47c6ae99SBarry Smith    }
1253*47c6ae99SBarry Smith 
1254*47c6ae99SBarry Smith   if (xe == M*dof) { /* First assume not corner or edge */
1255*47c6ae99SBarry Smith     n2  = rank -2*m +1 - (m*n);
1256*47c6ae99SBarry Smith     n5  = rank - m  +1 - (m*n);
1257*47c6ae99SBarry Smith     n8  = rank      +1 - (m*n);
1258*47c6ae99SBarry Smith     n11 = rank -2*m +1;
1259*47c6ae99SBarry Smith     n14 = rank - m  +1;
1260*47c6ae99SBarry Smith     n17 = rank      +1;
1261*47c6ae99SBarry Smith     n20 = rank -2*m +1 + (m*n);
1262*47c6ae99SBarry Smith     n23 = rank - m  +1 + (m*n);
1263*47c6ae99SBarry Smith     n26 = rank      +1 + (m*n);
1264*47c6ae99SBarry Smith   }
1265*47c6ae99SBarry Smith 
1266*47c6ae99SBarry Smith   if (ys==0) { /* First assume not corner or edge */
1267*47c6ae99SBarry Smith     n0  = rank + m * (n-1) -1 - (m*n);
1268*47c6ae99SBarry Smith     n1  = rank + m * (n-1)    - (m*n);
1269*47c6ae99SBarry Smith     n2  = rank + m * (n-1) +1 - (m*n);
1270*47c6ae99SBarry Smith     n9  = rank + m * (n-1) -1;
1271*47c6ae99SBarry Smith     n10 = rank + m * (n-1);
1272*47c6ae99SBarry Smith     n11 = rank + m * (n-1) +1;
1273*47c6ae99SBarry Smith     n18 = rank + m * (n-1) -1 + (m*n);
1274*47c6ae99SBarry Smith     n19 = rank + m * (n-1)    + (m*n);
1275*47c6ae99SBarry Smith     n20 = rank + m * (n-1) +1 + (m*n);
1276*47c6ae99SBarry Smith   }
1277*47c6ae99SBarry Smith 
1278*47c6ae99SBarry Smith   if (ye == N) { /* First assume not corner or edge */
1279*47c6ae99SBarry Smith     n6  = rank - m * (n-1) -1 - (m*n);
1280*47c6ae99SBarry Smith     n7  = rank - m * (n-1)    - (m*n);
1281*47c6ae99SBarry Smith     n8  = rank - m * (n-1) +1 - (m*n);
1282*47c6ae99SBarry Smith     n15 = rank - m * (n-1) -1;
1283*47c6ae99SBarry Smith     n16 = rank - m * (n-1);
1284*47c6ae99SBarry Smith     n17 = rank - m * (n-1) +1;
1285*47c6ae99SBarry Smith     n24 = rank - m * (n-1) -1 + (m*n);
1286*47c6ae99SBarry Smith     n25 = rank - m * (n-1)    + (m*n);
1287*47c6ae99SBarry Smith     n26 = rank - m * (n-1) +1 + (m*n);
1288*47c6ae99SBarry Smith   }
1289*47c6ae99SBarry Smith 
1290*47c6ae99SBarry Smith   if (zs == 0) { /* First assume not corner or edge */
1291*47c6ae99SBarry Smith     n0 = size - (m*n) + rank - m - 1;
1292*47c6ae99SBarry Smith     n1 = size - (m*n) + rank - m;
1293*47c6ae99SBarry Smith     n2 = size - (m*n) + rank - m + 1;
1294*47c6ae99SBarry Smith     n3 = size - (m*n) + rank - 1;
1295*47c6ae99SBarry Smith     n4 = size - (m*n) + rank;
1296*47c6ae99SBarry Smith     n5 = size - (m*n) + rank + 1;
1297*47c6ae99SBarry Smith     n6 = size - (m*n) + rank + m - 1;
1298*47c6ae99SBarry Smith     n7 = size - (m*n) + rank + m ;
1299*47c6ae99SBarry Smith     n8 = size - (m*n) + rank + m + 1;
1300*47c6ae99SBarry Smith   }
1301*47c6ae99SBarry Smith 
1302*47c6ae99SBarry Smith   if (ze == P) { /* First assume not corner or edge */
1303*47c6ae99SBarry Smith     n18 = (m*n) - (size-rank) - m - 1;
1304*47c6ae99SBarry Smith     n19 = (m*n) - (size-rank) - m;
1305*47c6ae99SBarry Smith     n20 = (m*n) - (size-rank) - m + 1;
1306*47c6ae99SBarry Smith     n21 = (m*n) - (size-rank) - 1;
1307*47c6ae99SBarry Smith     n22 = (m*n) - (size-rank);
1308*47c6ae99SBarry Smith     n23 = (m*n) - (size-rank) + 1;
1309*47c6ae99SBarry Smith     n24 = (m*n) - (size-rank) + m - 1;
1310*47c6ae99SBarry Smith     n25 = (m*n) - (size-rank) + m;
1311*47c6ae99SBarry Smith     n26 = (m*n) - (size-rank) + m + 1;
1312*47c6ae99SBarry Smith   }
1313*47c6ae99SBarry Smith 
1314*47c6ae99SBarry Smith   if ((xs==0) && (zs==0)) { /* Assume an edge, not corner */
1315*47c6ae99SBarry Smith     n0 = size - m*n + rank + m-1 - m;
1316*47c6ae99SBarry Smith     n3 = size - m*n + rank + m-1;
1317*47c6ae99SBarry Smith     n6 = size - m*n + rank + m-1 + m;
1318*47c6ae99SBarry Smith   }
1319*47c6ae99SBarry Smith 
1320*47c6ae99SBarry Smith   if ((xs==0) && (ze==P)) { /* Assume an edge, not corner */
1321*47c6ae99SBarry Smith     n18 = m*n - (size - rank) + m-1 - m;
1322*47c6ae99SBarry Smith     n21 = m*n - (size - rank) + m-1;
1323*47c6ae99SBarry Smith     n24 = m*n - (size - rank) + m-1 + m;
1324*47c6ae99SBarry Smith   }
1325*47c6ae99SBarry Smith 
1326*47c6ae99SBarry Smith   if ((xs==0) && (ys==0)) { /* Assume an edge, not corner */
1327*47c6ae99SBarry Smith     n0  = rank + m*n -1 - m*n;
1328*47c6ae99SBarry Smith     n9  = rank + m*n -1;
1329*47c6ae99SBarry Smith     n18 = rank + m*n -1 + m*n;
1330*47c6ae99SBarry Smith   }
1331*47c6ae99SBarry Smith 
1332*47c6ae99SBarry Smith   if ((xs==0) && (ye==N)) { /* Assume an edge, not corner */
1333*47c6ae99SBarry Smith     n6  = rank - m*(n-1) + m-1 - m*n;
1334*47c6ae99SBarry Smith     n15 = rank - m*(n-1) + m-1;
1335*47c6ae99SBarry Smith     n24 = rank - m*(n-1) + m-1 + m*n;
1336*47c6ae99SBarry Smith   }
1337*47c6ae99SBarry Smith 
1338*47c6ae99SBarry Smith   if ((xe==M*dof) && (zs==0)) { /* Assume an edge, not corner */
1339*47c6ae99SBarry Smith     n2 = size - (m*n-rank) - (m-1) - m;
1340*47c6ae99SBarry Smith     n5 = size - (m*n-rank) - (m-1);
1341*47c6ae99SBarry Smith     n8 = size - (m*n-rank) - (m-1) + m;
1342*47c6ae99SBarry Smith   }
1343*47c6ae99SBarry Smith 
1344*47c6ae99SBarry Smith   if ((xe==M*dof) && (ze==P)) { /* Assume an edge, not corner */
1345*47c6ae99SBarry Smith     n20 = m*n - (size - rank) - (m-1) - m;
1346*47c6ae99SBarry Smith     n23 = m*n - (size - rank) - (m-1);
1347*47c6ae99SBarry Smith     n26 = m*n - (size - rank) - (m-1) + m;
1348*47c6ae99SBarry Smith   }
1349*47c6ae99SBarry Smith 
1350*47c6ae99SBarry Smith   if ((xe==M*dof) && (ys==0)) { /* Assume an edge, not corner */
1351*47c6ae99SBarry Smith     n2  = rank + m*(n-1) - (m-1) - m*n;
1352*47c6ae99SBarry Smith     n11 = rank + m*(n-1) - (m-1);
1353*47c6ae99SBarry Smith     n20 = rank + m*(n-1) - (m-1) + m*n;
1354*47c6ae99SBarry Smith   }
1355*47c6ae99SBarry Smith 
1356*47c6ae99SBarry Smith   if ((xe==M*dof) && (ye==N)) { /* Assume an edge, not corner */
1357*47c6ae99SBarry Smith     n8  = rank - m*n +1 - m*n;
1358*47c6ae99SBarry Smith     n17 = rank - m*n +1;
1359*47c6ae99SBarry Smith     n26 = rank - m*n +1 + m*n;
1360*47c6ae99SBarry Smith   }
1361*47c6ae99SBarry Smith 
1362*47c6ae99SBarry Smith   if ((ys==0) && (zs==0)) { /* Assume an edge, not corner */
1363*47c6ae99SBarry Smith     n0 = size - m + rank -1;
1364*47c6ae99SBarry Smith     n1 = size - m + rank;
1365*47c6ae99SBarry Smith     n2 = size - m + rank +1;
1366*47c6ae99SBarry Smith   }
1367*47c6ae99SBarry Smith 
1368*47c6ae99SBarry Smith   if ((ys==0) && (ze==P)) { /* Assume an edge, not corner */
1369*47c6ae99SBarry Smith     n18 = m*n - (size - rank) + m*(n-1) -1;
1370*47c6ae99SBarry Smith     n19 = m*n - (size - rank) + m*(n-1);
1371*47c6ae99SBarry Smith     n20 = m*n - (size - rank) + m*(n-1) +1;
1372*47c6ae99SBarry Smith   }
1373*47c6ae99SBarry Smith 
1374*47c6ae99SBarry Smith   if ((ye==N) && (zs==0)) { /* Assume an edge, not corner */
1375*47c6ae99SBarry Smith     n6 = size - (m*n-rank) - m * (n-1) -1;
1376*47c6ae99SBarry Smith     n7 = size - (m*n-rank) - m * (n-1);
1377*47c6ae99SBarry Smith     n8 = size - (m*n-rank) - m * (n-1) +1;
1378*47c6ae99SBarry Smith   }
1379*47c6ae99SBarry Smith 
1380*47c6ae99SBarry Smith   if ((ye==N) && (ze==P)) { /* Assume an edge, not corner */
1381*47c6ae99SBarry Smith     n24 = rank - (size-m) -1;
1382*47c6ae99SBarry Smith     n25 = rank - (size-m);
1383*47c6ae99SBarry Smith     n26 = rank - (size-m) +1;
1384*47c6ae99SBarry Smith   }
1385*47c6ae99SBarry Smith 
1386*47c6ae99SBarry Smith   /* Check for Corners */
1387*47c6ae99SBarry Smith   if ((xs==0)   && (ys==0) && (zs==0)) { n0  = size -1;}
1388*47c6ae99SBarry Smith   if ((xs==0)   && (ys==0) && (ze==P)) { n18 = m*n-1;}
1389*47c6ae99SBarry Smith   if ((xs==0)   && (ye==N) && (zs==0)) { n6  = (size-1)-m*(n-1);}
1390*47c6ae99SBarry Smith   if ((xs==0)   && (ye==N) && (ze==P)) { n24 = m-1;}
1391*47c6ae99SBarry Smith   if ((xe==M*dof) && (ys==0) && (zs==0)) { n2  = size-m;}
1392*47c6ae99SBarry Smith   if ((xe==M*dof) && (ys==0) && (ze==P)) { n20 = m*n-m;}
1393*47c6ae99SBarry Smith   if ((xe==M*dof) && (ye==N) && (zs==0)) { n8  = size-m*n;}
1394*47c6ae99SBarry Smith   if ((xe==M*dof) && (ye==N) && (ze==P)) { n26 = 0;}
1395*47c6ae99SBarry Smith 
1396*47c6ae99SBarry Smith   /* Check for when not X,Y, and Z Periodic */
1397*47c6ae99SBarry Smith 
1398*47c6ae99SBarry Smith   /* If not X periodic */
1399*47c6ae99SBarry Smith   if (!DAXPeriodic(wrap)){
1400*47c6ae99SBarry Smith     if (xs==0)   {n0  = n3  = n6  = n9  = n12 = n15 = n18 = n21 = n24 = -2;}
1401*47c6ae99SBarry Smith     if (xe==M*dof) {n2  = n5  = n8  = n11 = n14 = n17 = n20 = n23 = n26 = -2;}
1402*47c6ae99SBarry Smith   }
1403*47c6ae99SBarry Smith 
1404*47c6ae99SBarry Smith   /* If not Y periodic */
1405*47c6ae99SBarry Smith   if (!DAYPeriodic(wrap)){
1406*47c6ae99SBarry Smith     if (ys==0)   {n0  = n1  = n2  = n9  = n10 = n11 = n18 = n19 = n20 = -2;}
1407*47c6ae99SBarry Smith     if (ye==N)   {n6  = n7  = n8  = n15 = n16 = n17 = n24 = n25 = n26 = -2;}
1408*47c6ae99SBarry Smith   }
1409*47c6ae99SBarry Smith 
1410*47c6ae99SBarry Smith   /* If not Z periodic */
1411*47c6ae99SBarry Smith   if (!DAZPeriodic(wrap)){
1412*47c6ae99SBarry Smith     if (zs==0)   {n0  = n1  = n2  = n3  = n4  = n5  = n6  = n7  = n8  = -2;}
1413*47c6ae99SBarry Smith     if (ze==P)   {n18 = n19 = n20 = n21 = n22 = n23 = n24 = n25 = n26 = -2;}
1414*47c6ae99SBarry Smith   }
1415*47c6ae99SBarry Smith 
1416*47c6ae99SBarry Smith   nn = 0;
1417*47c6ae99SBarry Smith 
1418*47c6ae99SBarry Smith   /* Bottom Level */
1419*47c6ae99SBarry Smith   for (k=0; k<s_z; k++) {
1420*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
1421*47c6ae99SBarry Smith       if (n0 >= 0) { /* left below */
1422*47c6ae99SBarry Smith         x_t = lx[n0 % m]*dof;
1423*47c6ae99SBarry Smith         y_t = ly[(n0 % (m*n))/m];
1424*47c6ae99SBarry Smith         z_t = lz[n0 / (m*n)];
1425*47c6ae99SBarry Smith         s_t = bases[n0] + x_t*y_t*z_t - (s_y-i)*x_t -s_x - (s_z-k-1)*x_t*y_t;
1426*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1427*47c6ae99SBarry Smith       }
1428*47c6ae99SBarry Smith       if (n1 >= 0) { /* directly below */
1429*47c6ae99SBarry Smith         x_t = x;
1430*47c6ae99SBarry Smith         y_t = ly[(n1 % (m*n))/m];
1431*47c6ae99SBarry Smith         z_t = lz[n1 / (m*n)];
1432*47c6ae99SBarry Smith         s_t = bases[n1] + x_t*y_t*z_t - (s_y+1-i)*x_t - (s_z-k-1)*x_t*y_t;
1433*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1434*47c6ae99SBarry Smith       }
1435*47c6ae99SBarry Smith       if (n2 >= 0) { /* right below */
1436*47c6ae99SBarry Smith         x_t = lx[n2 % m]*dof;
1437*47c6ae99SBarry Smith         y_t = ly[(n2 % (m*n))/m];
1438*47c6ae99SBarry Smith         z_t = lz[n2 / (m*n)];
1439*47c6ae99SBarry Smith         s_t = bases[n2] + x_t*y_t*z_t - (s_y+1-i)*x_t - (s_z-k-1)*x_t*y_t;
1440*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1441*47c6ae99SBarry Smith       }
1442*47c6ae99SBarry Smith     }
1443*47c6ae99SBarry Smith 
1444*47c6ae99SBarry Smith     for (i=0; i<y; i++) {
1445*47c6ae99SBarry Smith       if (n3 >= 0) { /* directly left */
1446*47c6ae99SBarry Smith         x_t = lx[n3 % m]*dof;
1447*47c6ae99SBarry Smith         y_t = y;
1448*47c6ae99SBarry Smith         z_t = lz[n3 / (m*n)];
1449*47c6ae99SBarry Smith         s_t = bases[n3] + (i+1)*x_t - s_x + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1450*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1451*47c6ae99SBarry Smith       }
1452*47c6ae99SBarry Smith 
1453*47c6ae99SBarry Smith       if (n4 >= 0) { /* middle */
1454*47c6ae99SBarry Smith         x_t = x;
1455*47c6ae99SBarry Smith         y_t = y;
1456*47c6ae99SBarry Smith         z_t = lz[n4 / (m*n)];
1457*47c6ae99SBarry Smith         s_t = bases[n4] + i*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1458*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1459*47c6ae99SBarry Smith       }
1460*47c6ae99SBarry Smith 
1461*47c6ae99SBarry Smith       if (n5 >= 0) { /* directly right */
1462*47c6ae99SBarry Smith         x_t = lx[n5 % m]*dof;
1463*47c6ae99SBarry Smith         y_t = y;
1464*47c6ae99SBarry Smith         z_t = lz[n5 / (m*n)];
1465*47c6ae99SBarry Smith         s_t = bases[n5] + i*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1466*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1467*47c6ae99SBarry Smith       }
1468*47c6ae99SBarry Smith     }
1469*47c6ae99SBarry Smith 
1470*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
1471*47c6ae99SBarry Smith       if (n6 >= 0) { /* left above */
1472*47c6ae99SBarry Smith         x_t = lx[n6 % m]*dof;
1473*47c6ae99SBarry Smith         y_t = ly[(n6 % (m*n))/m];
1474*47c6ae99SBarry Smith         z_t = lz[n6 / (m*n)];
1475*47c6ae99SBarry Smith         s_t = bases[n6] + i*x_t - s_x + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1476*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1477*47c6ae99SBarry Smith       }
1478*47c6ae99SBarry Smith       if (n7 >= 0) { /* directly above */
1479*47c6ae99SBarry Smith         x_t = x;
1480*47c6ae99SBarry Smith         y_t = ly[(n7 % (m*n))/m];
1481*47c6ae99SBarry Smith         z_t = lz[n7 / (m*n)];
1482*47c6ae99SBarry Smith         s_t = bases[n7] + (i-1)*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1483*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1484*47c6ae99SBarry Smith       }
1485*47c6ae99SBarry Smith       if (n8 >= 0) { /* right above */
1486*47c6ae99SBarry Smith         x_t = lx[n8 % m]*dof;
1487*47c6ae99SBarry Smith         y_t = ly[(n8 % (m*n))/m];
1488*47c6ae99SBarry Smith         z_t = lz[n8 / (m*n)];
1489*47c6ae99SBarry Smith         s_t = bases[n8] + (i-1)*x_t + x_t*y_t*z_t - (s_z-k)*x_t*y_t;
1490*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1491*47c6ae99SBarry Smith       }
1492*47c6ae99SBarry Smith     }
1493*47c6ae99SBarry Smith   }
1494*47c6ae99SBarry Smith 
1495*47c6ae99SBarry Smith   /* Middle Level */
1496*47c6ae99SBarry Smith   for (k=0; k<z; k++) {
1497*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
1498*47c6ae99SBarry Smith       if (n9 >= 0) { /* left below */
1499*47c6ae99SBarry Smith         x_t = lx[n9 % m]*dof;
1500*47c6ae99SBarry Smith         y_t = ly[(n9 % (m*n))/m];
1501*47c6ae99SBarry Smith         /* z_t = z; */
1502*47c6ae99SBarry Smith         s_t = bases[n9] - (s_y-i)*x_t -s_x + (k+1)*x_t*y_t;
1503*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1504*47c6ae99SBarry Smith       }
1505*47c6ae99SBarry Smith       if (n10 >= 0) { /* directly below */
1506*47c6ae99SBarry Smith         x_t = x;
1507*47c6ae99SBarry Smith         y_t = ly[(n10 % (m*n))/m];
1508*47c6ae99SBarry Smith         /* z_t = z; */
1509*47c6ae99SBarry Smith         s_t = bases[n10] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1510*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1511*47c6ae99SBarry Smith       }
1512*47c6ae99SBarry Smith       if (n11 >= 0) { /* right below */
1513*47c6ae99SBarry Smith         x_t = lx[n11 % m]*dof;
1514*47c6ae99SBarry Smith         y_t = ly[(n11 % (m*n))/m];
1515*47c6ae99SBarry Smith         /* z_t = z; */
1516*47c6ae99SBarry Smith         s_t = bases[n11] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1517*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1518*47c6ae99SBarry Smith       }
1519*47c6ae99SBarry Smith     }
1520*47c6ae99SBarry Smith 
1521*47c6ae99SBarry Smith     for (i=0; i<y; i++) {
1522*47c6ae99SBarry Smith       if (n12 >= 0) { /* directly left */
1523*47c6ae99SBarry Smith         x_t = lx[n12 % m]*dof;
1524*47c6ae99SBarry Smith         y_t = y;
1525*47c6ae99SBarry Smith         /* z_t = z; */
1526*47c6ae99SBarry Smith         s_t = bases[n12] + (i+1)*x_t - s_x + k*x_t*y_t;
1527*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1528*47c6ae99SBarry Smith       }
1529*47c6ae99SBarry Smith 
1530*47c6ae99SBarry Smith       /* Interior */
1531*47c6ae99SBarry Smith       s_t = bases[rank] + i*x + k*x*y;
1532*47c6ae99SBarry Smith       for (j=0; j<x; j++) { idx[nn++] = s_t++;}
1533*47c6ae99SBarry Smith 
1534*47c6ae99SBarry Smith       if (n14 >= 0) { /* directly right */
1535*47c6ae99SBarry Smith         x_t = lx[n14 % m]*dof;
1536*47c6ae99SBarry Smith         y_t = y;
1537*47c6ae99SBarry Smith         /* z_t = z; */
1538*47c6ae99SBarry Smith         s_t = bases[n14] + i*x_t + k*x_t*y_t;
1539*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1540*47c6ae99SBarry Smith       }
1541*47c6ae99SBarry Smith     }
1542*47c6ae99SBarry Smith 
1543*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
1544*47c6ae99SBarry Smith       if (n15 >= 0) { /* left above */
1545*47c6ae99SBarry Smith         x_t = lx[n15 % m]*dof;
1546*47c6ae99SBarry Smith         y_t = ly[(n15 % (m*n))/m];
1547*47c6ae99SBarry Smith         /* z_t = z; */
1548*47c6ae99SBarry Smith         s_t = bases[n15] + i*x_t - s_x + k*x_t*y_t;
1549*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1550*47c6ae99SBarry Smith       }
1551*47c6ae99SBarry Smith       if (n16 >= 0) { /* directly above */
1552*47c6ae99SBarry Smith         x_t = x;
1553*47c6ae99SBarry Smith         y_t = ly[(n16 % (m*n))/m];
1554*47c6ae99SBarry Smith         /* z_t = z; */
1555*47c6ae99SBarry Smith         s_t = bases[n16] + (i-1)*x_t + k*x_t*y_t;
1556*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1557*47c6ae99SBarry Smith       }
1558*47c6ae99SBarry Smith       if (n17 >= 0) { /* right above */
1559*47c6ae99SBarry Smith         x_t = lx[n17 % m]*dof;
1560*47c6ae99SBarry Smith         y_t = ly[(n17 % (m*n))/m];
1561*47c6ae99SBarry Smith         /* z_t = z; */
1562*47c6ae99SBarry Smith         s_t = bases[n17] + (i-1)*x_t + k*x_t*y_t;
1563*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1564*47c6ae99SBarry Smith       }
1565*47c6ae99SBarry Smith     }
1566*47c6ae99SBarry Smith   }
1567*47c6ae99SBarry Smith 
1568*47c6ae99SBarry Smith   /* Upper Level */
1569*47c6ae99SBarry Smith   for (k=0; k<s_z; k++) {
1570*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
1571*47c6ae99SBarry Smith       if (n18 >= 0) { /* left below */
1572*47c6ae99SBarry Smith         x_t = lx[n18 % m]*dof;
1573*47c6ae99SBarry Smith         y_t = ly[(n18 % (m*n))/m];
1574*47c6ae99SBarry Smith         /* z_t = lz[n18 / (m*n)]; */
1575*47c6ae99SBarry Smith         s_t = bases[n18] - (s_y-i)*x_t -s_x + (k+1)*x_t*y_t;
1576*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1577*47c6ae99SBarry Smith       }
1578*47c6ae99SBarry Smith       if (n19 >= 0) { /* directly below */
1579*47c6ae99SBarry Smith         x_t = x;
1580*47c6ae99SBarry Smith         y_t = ly[(n19 % (m*n))/m];
1581*47c6ae99SBarry Smith         /* z_t = lz[n19 / (m*n)]; */
1582*47c6ae99SBarry Smith         s_t = bases[n19] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1583*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1584*47c6ae99SBarry Smith       }
1585*47c6ae99SBarry Smith       if (n20 >= 0) { /* right belodof */
1586*47c6ae99SBarry Smith         x_t = lx[n20 % m]*dof;
1587*47c6ae99SBarry Smith         y_t = ly[(n20 % (m*n))/m];
1588*47c6ae99SBarry Smith         /* z_t = lz[n20 / (m*n)]; */
1589*47c6ae99SBarry Smith         s_t = bases[n20] - (s_y+1-i)*x_t + (k+1)*x_t*y_t;
1590*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1591*47c6ae99SBarry Smith       }
1592*47c6ae99SBarry Smith     }
1593*47c6ae99SBarry Smith 
1594*47c6ae99SBarry Smith     for (i=0; i<y; i++) {
1595*47c6ae99SBarry Smith       if (n21 >= 0) { /* directly left */
1596*47c6ae99SBarry Smith         x_t = lx[n21 % m]*dof;
1597*47c6ae99SBarry Smith         y_t = y;
1598*47c6ae99SBarry Smith         /* z_t = lz[n21 / (m*n)]; */
1599*47c6ae99SBarry Smith         s_t = bases[n21] + (i+1)*x_t - s_x + k*x_t*y_t;
1600*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1601*47c6ae99SBarry Smith       }
1602*47c6ae99SBarry Smith 
1603*47c6ae99SBarry Smith       if (n22 >= 0) { /* middle */
1604*47c6ae99SBarry Smith         x_t = x;
1605*47c6ae99SBarry Smith         y_t = y;
1606*47c6ae99SBarry Smith         /* z_t = lz[n22 / (m*n)]; */
1607*47c6ae99SBarry Smith         s_t = bases[n22] + i*x_t + k*x_t*y_t;
1608*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1609*47c6ae99SBarry Smith       }
1610*47c6ae99SBarry Smith 
1611*47c6ae99SBarry Smith       if (n23 >= 0) { /* directly right */
1612*47c6ae99SBarry Smith         x_t = lx[n23 % m]*dof;
1613*47c6ae99SBarry Smith         y_t = y;
1614*47c6ae99SBarry Smith         /* z_t = lz[n23 / (m*n)]; */
1615*47c6ae99SBarry Smith         s_t = bases[n23] + i*x_t + k*x_t*y_t;
1616*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1617*47c6ae99SBarry Smith       }
1618*47c6ae99SBarry Smith     }
1619*47c6ae99SBarry Smith 
1620*47c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
1621*47c6ae99SBarry Smith       if (n24 >= 0) { /* left above */
1622*47c6ae99SBarry Smith         x_t = lx[n24 % m]*dof;
1623*47c6ae99SBarry Smith         y_t = ly[(n24 % (m*n))/m];
1624*47c6ae99SBarry Smith         /* z_t = lz[n24 / (m*n)]; */
1625*47c6ae99SBarry Smith         s_t = bases[n24] + i*x_t - s_x + k*x_t*y_t;
1626*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1627*47c6ae99SBarry Smith       }
1628*47c6ae99SBarry Smith       if (n25 >= 0) { /* directly above */
1629*47c6ae99SBarry Smith         x_t = x;
1630*47c6ae99SBarry Smith         y_t = ly[(n25 % (m*n))/m];
1631*47c6ae99SBarry Smith         /* z_t = lz[n25 / (m*n)]; */
1632*47c6ae99SBarry Smith         s_t = bases[n25] + (i-1)*x_t + k*x_t*y_t;
1633*47c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1634*47c6ae99SBarry Smith       }
1635*47c6ae99SBarry Smith       if (n26 >= 0) { /* right above */
1636*47c6ae99SBarry Smith         x_t = lx[n26 % m]*dof;
1637*47c6ae99SBarry Smith         y_t = ly[(n26 % (m*n))/m];
1638*47c6ae99SBarry Smith         /* z_t = lz[n26 / (m*n)]; */
1639*47c6ae99SBarry Smith         s_t = bases[n26] + (i-1)*x_t + k*x_t*y_t;
1640*47c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1641*47c6ae99SBarry Smith       }
1642*47c6ae99SBarry Smith     }
1643*47c6ae99SBarry Smith   }
1644*47c6ae99SBarry Smith   ierr = PetscFree2(bases,ldims);CHKERRQ(ierr);
1645*47c6ae99SBarry Smith   dd->gtol      = gtol;
1646*47c6ae99SBarry Smith   dd->ltog      = ltog;
1647*47c6ae99SBarry Smith   dd->idx       = idx;
1648*47c6ae99SBarry Smith   dd->Nl        = nn;
1649*47c6ae99SBarry Smith   dd->base      = base;
1650*47c6ae99SBarry Smith   da->ops->view = DAView_3d;
1651*47c6ae99SBarry Smith 
1652*47c6ae99SBarry Smith   /*
1653*47c6ae99SBarry Smith      Set the local to global ordering in the global vector, this allows use
1654*47c6ae99SBarry Smith      of VecSetValuesLocal().
1655*47c6ae99SBarry Smith   */
1656*47c6ae99SBarry Smith   ierr = ISLocalToGlobalMappingCreate(comm,nn,idx,PETSC_OWN_POINTER,&dd->ltogmap);CHKERRQ(ierr);
1657*47c6ae99SBarry Smith   ierr = ISLocalToGlobalMappingBlock(dd->ltogmap,dd->w,&dd->ltogmapb);CHKERRQ(ierr);
1658*47c6ae99SBarry Smith   ierr = PetscLogObjectParent(da,dd->ltogmap);CHKERRQ(ierr);
1659*47c6ae99SBarry Smith 
1660*47c6ae99SBarry Smith   dd->ltol = PETSC_NULL;
1661*47c6ae99SBarry Smith   dd->ao   = PETSC_NULL;
1662*47c6ae99SBarry Smith   PetscFunctionReturn(0);
1663*47c6ae99SBarry Smith }
1664*47c6ae99SBarry Smith EXTERN_C_END
1665*47c6ae99SBarry Smith 
1666*47c6ae99SBarry Smith #undef __FUNCT__
1667*47c6ae99SBarry Smith #define __FUNCT__ "DACreate3d"
1668*47c6ae99SBarry Smith /*@C
1669*47c6ae99SBarry Smith    DACreate3d - Creates an object that will manage the communication of three-dimensional
1670*47c6ae99SBarry Smith    regular array data that is distributed across some processors.
1671*47c6ae99SBarry Smith 
1672*47c6ae99SBarry Smith    Collective on MPI_Comm
1673*47c6ae99SBarry Smith 
1674*47c6ae99SBarry Smith    Input Parameters:
1675*47c6ae99SBarry Smith +  comm - MPI communicator
1676*47c6ae99SBarry Smith .  wrap - type of periodicity the array should have, if any.  Use one
1677*47c6ae99SBarry Smith           of DA_NONPERIODIC, DA_XPERIODIC, DA_YPERIODIC, DA_ZPERIODIC, DA_XYPERIODIC, DA_XZPERIODIC, DA_YZPERIODIC, DA_XYZPERIODIC, or DA_XYZGHOSTED.
1678*47c6ae99SBarry Smith .  stencil_type - Type of stencil (DA_STENCIL_STAR or DA_STENCIL_BOX)
1679*47c6ae99SBarry Smith .  M,N,P - global dimension in each direction of the array (use -M, -N, and or -P to indicate that it may be set to a different value
1680*47c6ae99SBarry Smith             from the command line with -da_grid_x <M> -da_grid_y <N> -da_grid_z <P>)
1681*47c6ae99SBarry Smith .  m,n,p - corresponding number of processors in each dimension
1682*47c6ae99SBarry Smith            (or PETSC_DECIDE to have calculated)
1683*47c6ae99SBarry Smith .  dof - number of degrees of freedom per node
1684*47c6ae99SBarry Smith .  lx, ly, lz - arrays containing the number of nodes in each cell along
1685*47c6ae99SBarry Smith           the x, y, and z coordinates, or PETSC_NULL. If non-null, these
1686*47c6ae99SBarry Smith           must be of length as m,n,p and the corresponding
1687*47c6ae99SBarry Smith           m,n, or p cannot be PETSC_DECIDE. Sum of the lx[] entries must be M, sum of
1688*47c6ae99SBarry Smith           the ly[] must N, sum of the lz[] must be P
1689*47c6ae99SBarry Smith -  s - stencil width
1690*47c6ae99SBarry Smith 
1691*47c6ae99SBarry Smith    Output Parameter:
1692*47c6ae99SBarry Smith .  da - the resulting distributed array object
1693*47c6ae99SBarry Smith 
1694*47c6ae99SBarry Smith    Options Database Key:
1695*47c6ae99SBarry Smith +  -da_view - Calls DAView() at the conclusion of DACreate3d()
1696*47c6ae99SBarry Smith .  -da_grid_x <nx> - number of grid points in x direction, if M < 0
1697*47c6ae99SBarry Smith .  -da_grid_y <ny> - number of grid points in y direction, if N < 0
1698*47c6ae99SBarry Smith .  -da_grid_z <nz> - number of grid points in z direction, if P < 0
1699*47c6ae99SBarry Smith .  -da_processors_x <MX> - number of processors in x direction
1700*47c6ae99SBarry Smith .  -da_processors_y <MY> - number of processors in y direction
1701*47c6ae99SBarry Smith .  -da_processors_z <MZ> - number of processors in z direction
1702*47c6ae99SBarry Smith .  -da_refine_x - refinement ratio in x direction
1703*47c6ae99SBarry Smith .  -da_refine_y - refinement ratio in y direction
1704*47c6ae99SBarry Smith -  -da_refine_y - refinement ratio in z direction
1705*47c6ae99SBarry Smith 
1706*47c6ae99SBarry Smith    Level: beginner
1707*47c6ae99SBarry Smith 
1708*47c6ae99SBarry Smith    Notes:
1709*47c6ae99SBarry Smith    The stencil type DA_STENCIL_STAR with width 1 corresponds to the
1710*47c6ae99SBarry Smith    standard 7-pt stencil, while DA_STENCIL_BOX with width 1 denotes
1711*47c6ae99SBarry Smith    the standard 27-pt stencil.
1712*47c6ae99SBarry Smith 
1713*47c6ae99SBarry Smith    The array data itself is NOT stored in the DA, it is stored in Vec objects;
1714*47c6ae99SBarry Smith    The appropriate vector objects can be obtained with calls to DACreateGlobalVector()
1715*47c6ae99SBarry Smith    and DACreateLocalVector() and calls to VecDuplicate() if more are needed.
1716*47c6ae99SBarry Smith 
1717*47c6ae99SBarry Smith .keywords: distributed array, create, three-dimensional
1718*47c6ae99SBarry Smith 
1719*47c6ae99SBarry Smith .seealso: DADestroy(), DAView(), DACreate1d(), DACreate2d(), DAGlobalToLocalBegin(), DAGetRefinementFactor(),
1720*47c6ae99SBarry Smith           DAGlobalToLocalEnd(), DALocalToGlobal(), DALocalToLocalBegin(), DALocalToLocalEnd(), DASetRefinementFactor(),
1721*47c6ae99SBarry Smith           DAGetInfo(), DACreateGlobalVector(), DACreateLocalVector(), DACreateNaturalVector(), DALoad(), DAView(), DAGetOwnershipRanges()
1722*47c6ae99SBarry Smith 
1723*47c6ae99SBarry Smith @*/
1724*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DACreate3d(MPI_Comm comm,DAPeriodicType wrap,DAStencilType stencil_type,PetscInt M,
1725*47c6ae99SBarry Smith                PetscInt N,PetscInt P,PetscInt m,PetscInt n,PetscInt p,PetscInt dof,PetscInt s,const PetscInt lx[],const PetscInt ly[],const PetscInt lz[],DA *da)
1726*47c6ae99SBarry Smith {
1727*47c6ae99SBarry Smith   PetscErrorCode ierr;
1728*47c6ae99SBarry Smith 
1729*47c6ae99SBarry Smith   PetscFunctionBegin;
1730*47c6ae99SBarry Smith   ierr = DACreate(comm, da);CHKERRQ(ierr);
1731*47c6ae99SBarry Smith   ierr = DASetDim(*da, 3);CHKERRQ(ierr);
1732*47c6ae99SBarry Smith   ierr = DASetSizes(*da, M, N, P);CHKERRQ(ierr);
1733*47c6ae99SBarry Smith   ierr = DASetNumProcs(*da, m, n, p);CHKERRQ(ierr);
1734*47c6ae99SBarry Smith   ierr = DASetPeriodicity(*da, wrap);CHKERRQ(ierr);
1735*47c6ae99SBarry Smith   ierr = DASetDof(*da, dof);CHKERRQ(ierr);
1736*47c6ae99SBarry Smith   ierr = DASetStencilType(*da, stencil_type);CHKERRQ(ierr);
1737*47c6ae99SBarry Smith   ierr = DASetStencilWidth(*da, s);CHKERRQ(ierr);
1738*47c6ae99SBarry Smith   ierr = DASetOwnershipRanges(*da, lx, ly, lz);CHKERRQ(ierr);
1739*47c6ae99SBarry Smith   /* This violates the behavior for other classes, but right now users expect negative dimensions to be handled this way */
1740*47c6ae99SBarry Smith   ierr = DASetFromOptions(*da);CHKERRQ(ierr);
1741*47c6ae99SBarry Smith   ierr = DASetType(*da, DA3D);CHKERRQ(ierr);
1742*47c6ae99SBarry Smith   PetscFunctionReturn(0);
1743*47c6ae99SBarry Smith }
1744