xref: /petsc/src/dm/impls/da/dalocal.c (revision b2fff234e343d3f6da3dc5791c5b064a6c231e37)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
64035e84dSBarry Smith #include <petsc-private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/
7*b2fff234SMatthew G. Knepley #include <petscbt.h>
80c312b8eSJed Brown #include <petscsf.h>
947c6ae99SBarry Smith 
1047c6ae99SBarry Smith /*
11e3c5b3baSBarry Smith    This allows the DMDA vectors to properly tell MATLAB their dimensions
1247c6ae99SBarry Smith */
1347c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
14c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
15c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
1647c6ae99SBarry Smith #undef __FUNCT__
1747c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d"
181e6b0712SBarry Smith static PetscErrorCode  VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine)
1947c6ae99SBarry Smith {
2047c6ae99SBarry Smith   PetscErrorCode ierr;
2147c6ae99SBarry Smith   PetscInt       n,m;
2247c6ae99SBarry Smith   Vec            vec = (Vec)obj;
2347c6ae99SBarry Smith   PetscScalar    *array;
2447c6ae99SBarry Smith   mxArray        *mat;
259a42bb27SBarry Smith   DM             da;
2647c6ae99SBarry Smith 
2747c6ae99SBarry Smith   PetscFunctionBegin;
28c688c046SMatthew G Knepley   ierr = VecGetDM(vec, &da);CHKERRQ(ierr);
29ce94432eSBarry Smith   if (!da) SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA");
30aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr);
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith   ierr = VecGetArray(vec,&array);CHKERRQ(ierr);
3347c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
3447c6ae99SBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxREAL);
3547c6ae99SBarry Smith #else
3647c6ae99SBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3747c6ae99SBarry Smith #endif
3847c6ae99SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr);
3947c6ae99SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
4047c6ae99SBarry Smith   engPutVariable((Engine*)mengine,obj->name,mat);
4147c6ae99SBarry Smith 
4247c6ae99SBarry Smith   ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr);
4347c6ae99SBarry Smith   PetscFunctionReturn(0);
4447c6ae99SBarry Smith }
4547c6ae99SBarry Smith #endif
4647c6ae99SBarry Smith 
4747c6ae99SBarry Smith 
4847c6ae99SBarry Smith #undef __FUNCT__
49564755cdSBarry Smith #define __FUNCT__ "DMCreateLocalVector_DA"
507087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_DA(DM da,Vec *g)
5147c6ae99SBarry Smith {
5247c6ae99SBarry Smith   PetscErrorCode ierr;
5347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
5447c6ae99SBarry Smith 
5547c6ae99SBarry Smith   PetscFunctionBegin;
5647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
5747c6ae99SBarry Smith   PetscValidPointer(g,2);
5811689aebSJed Brown   if (da->defaultSection) {
5911689aebSJed Brown     ierr = DMCreateLocalVector_Section_Private(da,g);CHKERRQ(ierr);
6011689aebSJed Brown   } else {
6147c6ae99SBarry Smith     ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr);
6247c6ae99SBarry Smith     ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
6347c6ae99SBarry Smith     ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
64401ddaa8SBarry Smith     ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
65c688c046SMatthew G Knepley     ierr = VecSetDM(*g, da);CHKERRQ(ierr);
6647c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
6747c6ae99SBarry Smith     if (dd->w == 1  && dd->dim == 2) {
68bdf89e91SBarry Smith       ierr = PetscObjectComposeFunction((PetscObject)*g,"PetscMatlabEnginePut_C",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
6947c6ae99SBarry Smith     }
7047c6ae99SBarry Smith #endif
7111689aebSJed Brown   }
7247c6ae99SBarry Smith   PetscFunctionReturn(0);
7347c6ae99SBarry Smith }
7447c6ae99SBarry Smith 
75a66d4d66SMatthew G Knepley #undef __FUNCT__
7657459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumCells"
7757459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCells)
7857459e9aSMatthew G Knepley {
7957459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
8057459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
8157459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
8257459e9aSMatthew G Knepley   const PetscInt nC  = (mx)*(dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1);
8357459e9aSMatthew G Knepley 
8457459e9aSMatthew G Knepley   PetscFunctionBegin;
8557459e9aSMatthew G Knepley   if (numCells) {
8657459e9aSMatthew G Knepley     PetscValidIntPointer(numCells,2);
8757459e9aSMatthew G Knepley     *numCells = nC;
8857459e9aSMatthew G Knepley   }
8957459e9aSMatthew G Knepley   PetscFunctionReturn(0);
9057459e9aSMatthew G Knepley }
9157459e9aSMatthew G Knepley 
9257459e9aSMatthew G Knepley #undef __FUNCT__
9357459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumVertices"
9457459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices)
9557459e9aSMatthew G Knepley {
9657459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
9757459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
9857459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
9957459e9aSMatthew G Knepley   const PetscInt nVx = mx+1;
10057459e9aSMatthew G Knepley   const PetscInt nVy = dim > 1 ? (my+1) : 1;
10157459e9aSMatthew G Knepley   const PetscInt nVz = dim > 2 ? (mz+1) : 1;
10257459e9aSMatthew G Knepley   const PetscInt nV  = nVx*nVy*nVz;
10357459e9aSMatthew G Knepley 
10457459e9aSMatthew G Knepley   PetscFunctionBegin;
10557459e9aSMatthew G Knepley   if (numVerticesX) {
10657459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesX,2);
10757459e9aSMatthew G Knepley     *numVerticesX = nVx;
10857459e9aSMatthew G Knepley   }
10957459e9aSMatthew G Knepley   if (numVerticesY) {
11057459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesY,3);
11157459e9aSMatthew G Knepley     *numVerticesY = nVy;
11257459e9aSMatthew G Knepley   }
11357459e9aSMatthew G Knepley   if (numVerticesZ) {
11457459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesZ,4);
11557459e9aSMatthew G Knepley     *numVerticesZ = nVz;
11657459e9aSMatthew G Knepley   }
11757459e9aSMatthew G Knepley   if (numVertices) {
11857459e9aSMatthew G Knepley     PetscValidIntPointer(numVertices,5);
11957459e9aSMatthew G Knepley     *numVertices = nV;
12057459e9aSMatthew G Knepley   }
12157459e9aSMatthew G Knepley   PetscFunctionReturn(0);
12257459e9aSMatthew G Knepley }
12357459e9aSMatthew G Knepley 
12457459e9aSMatthew G Knepley #undef __FUNCT__
12557459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumFaces"
12657459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces)
12757459e9aSMatthew G Knepley {
12857459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
12957459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
13057459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
13157459e9aSMatthew G Knepley   const PetscInt nxF = (dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1);
13257459e9aSMatthew G Knepley   const PetscInt nXF = (mx+1)*nxF;
13357459e9aSMatthew G Knepley   const PetscInt nyF = mx*(dim > 2 ? mz : 1);
13457459e9aSMatthew G Knepley   const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0;
13557459e9aSMatthew G Knepley   const PetscInt nzF = mx*(dim > 1 ? my : 0);
13657459e9aSMatthew G Knepley   const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0;
13757459e9aSMatthew G Knepley 
13857459e9aSMatthew G Knepley   PetscFunctionBegin;
13957459e9aSMatthew G Knepley   if (numXFacesX) {
14057459e9aSMatthew G Knepley     PetscValidIntPointer(numXFacesX,2);
14157459e9aSMatthew G Knepley     *numXFacesX = nxF;
14257459e9aSMatthew G Knepley   }
14357459e9aSMatthew G Knepley   if (numXFaces) {
14457459e9aSMatthew G Knepley     PetscValidIntPointer(numXFaces,3);
14557459e9aSMatthew G Knepley     *numXFaces = nXF;
14657459e9aSMatthew G Knepley   }
14757459e9aSMatthew G Knepley   if (numYFacesY) {
14857459e9aSMatthew G Knepley     PetscValidIntPointer(numYFacesY,4);
14957459e9aSMatthew G Knepley     *numYFacesY = nyF;
15057459e9aSMatthew G Knepley   }
15157459e9aSMatthew G Knepley   if (numYFaces) {
15257459e9aSMatthew G Knepley     PetscValidIntPointer(numYFaces,5);
15357459e9aSMatthew G Knepley     *numYFaces = nYF;
15457459e9aSMatthew G Knepley   }
15557459e9aSMatthew G Knepley   if (numZFacesZ) {
15657459e9aSMatthew G Knepley     PetscValidIntPointer(numZFacesZ,6);
15757459e9aSMatthew G Knepley     *numZFacesZ = nzF;
15857459e9aSMatthew G Knepley   }
15957459e9aSMatthew G Knepley   if (numZFaces) {
16057459e9aSMatthew G Knepley     PetscValidIntPointer(numZFaces,7);
16157459e9aSMatthew G Knepley     *numZFaces = nZF;
16257459e9aSMatthew G Knepley   }
16357459e9aSMatthew G Knepley   PetscFunctionReturn(0);
16457459e9aSMatthew G Knepley }
16557459e9aSMatthew G Knepley 
16657459e9aSMatthew G Knepley #undef __FUNCT__
16757459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetHeightStratum"
16857459e9aSMatthew G Knepley PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd)
16957459e9aSMatthew G Knepley {
17057459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
17157459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
17257459e9aSMatthew G Knepley   PetscInt       nC, nV, nXF, nYF, nZF;
17357459e9aSMatthew G Knepley   PetscErrorCode ierr;
17457459e9aSMatthew G Knepley 
17557459e9aSMatthew G Knepley   PetscFunctionBegin;
1768865f1eaSKarl Rupp   if (pStart) PetscValidIntPointer(pStart,3);
1778865f1eaSKarl Rupp   if (pEnd)   PetscValidIntPointer(pEnd,4);
17857459e9aSMatthew G Knepley   ierr = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr);
1790298fd71SBarry Smith   ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr);
1800298fd71SBarry Smith   ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr);
18157459e9aSMatthew G Knepley   if (height == 0) {
18257459e9aSMatthew G Knepley     /* Cells */
1838865f1eaSKarl Rupp     if (pStart) *pStart = 0;
1848865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC;
18557459e9aSMatthew G Knepley   } else if (height == 1) {
18657459e9aSMatthew G Knepley     /* Faces */
1878865f1eaSKarl Rupp     if (pStart) *pStart = nC+nV;
1888865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
18957459e9aSMatthew G Knepley   } else if (height == dim) {
19057459e9aSMatthew G Knepley     /* Vertices */
1918865f1eaSKarl Rupp     if (pStart) *pStart = nC;
1928865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV;
19357459e9aSMatthew G Knepley   } else if (height < 0) {
19457459e9aSMatthew G Knepley     /* All points */
1958865f1eaSKarl Rupp     if (pStart) *pStart = 0;
1968865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
19782f516ccSBarry Smith   } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height);
19857459e9aSMatthew G Knepley   PetscFunctionReturn(0);
19957459e9aSMatthew G Knepley }
20057459e9aSMatthew G Knepley 
20157459e9aSMatthew G Knepley #undef __FUNCT__
202a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection"
203a66d4d66SMatthew G Knepley /*@C
204a66d4d66SMatthew G Knepley   DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with
205a66d4d66SMatthew G Knepley   different numbers of dofs on vertices, cells, and faces in each direction.
206a66d4d66SMatthew G Knepley 
207a66d4d66SMatthew G Knepley   Input Parameters:
208a66d4d66SMatthew G Knepley + dm- The DMDA
209a66d4d66SMatthew G Knepley . numFields - The number of fields
2100298fd71SBarry Smith . numComp - The number of components in each field, or NULL for 1
2110298fd71SBarry Smith . numVertexDof - The number of dofs per vertex for each field, or NULL
2120298fd71SBarry Smith . numFaceDof - The number of dofs per face for each field and direction, or NULL
2130298fd71SBarry Smith - numCellDof - The number of dofs per cell for each field, or NULL
214a66d4d66SMatthew G Knepley 
215a66d4d66SMatthew G Knepley   Level: developer
216a66d4d66SMatthew G Knepley 
217a66d4d66SMatthew G Knepley   Note:
218a66d4d66SMatthew G Knepley   The default DMDA numbering is as follows:
219a66d4d66SMatthew G Knepley 
220a66d4d66SMatthew G Knepley     - Cells:    [0,             nC)
221a66d4d66SMatthew G Knepley     - Vertices: [nC,            nC+nV)
22288ed4aceSMatthew G Knepley     - X-Faces:  [nC+nV,         nC+nV+nXF)         normal is +- x-dir
22388ed4aceSMatthew G Knepley     - Y-Faces:  [nC+nV+nXF,     nC+nV+nXF+nYF)     normal is +- y-dir
22488ed4aceSMatthew G Knepley     - Z-Faces:  [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir
225a66d4d66SMatthew G Knepley 
226a66d4d66SMatthew G Knepley   We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment.
227a66d4d66SMatthew G Knepley @*/
22880800b1aSMatthew G Knepley PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[])
229a66d4d66SMatthew G Knepley {
230a66d4d66SMatthew G Knepley   DM_DA            *da  = (DM_DA*) dm->data;
23188ed4aceSMatthew G Knepley   const PetscInt    dim = da->dim;
23280800b1aSMatthew G Knepley   PetscInt          numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0};
233*b2fff234SMatthew G. Knepley   PetscBT           isLeaf;
23488ed4aceSMatthew G Knepley   PetscSF           sf;
235feafbc5cSMatthew G Knepley   PetscMPIInt       rank;
23688ed4aceSMatthew G Knepley   const PetscMPIInt *neighbors;
23788ed4aceSMatthew G Knepley   PetscInt          *localPoints;
23888ed4aceSMatthew G Knepley   PetscSFNode       *remotePoints;
239f5eeb527SMatthew G Knepley   PetscInt          nleaves = 0,  nleavesCheck = 0, nL = 0;
24057459e9aSMatthew G Knepley   PetscInt          nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF;
24157459e9aSMatthew G Knepley   PetscInt          pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd;
24288ed4aceSMatthew G Knepley   PetscInt          f, v, c, xf, yf, zf, xn, yn, zn;
243a66d4d66SMatthew G Knepley   PetscErrorCode    ierr;
244a66d4d66SMatthew G Knepley 
245a66d4d66SMatthew G Knepley   PetscFunctionBegin;
246a66d4d66SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
24782f516ccSBarry Smith   ierr    = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr);
24857459e9aSMatthew G Knepley   ierr    = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr);
24957459e9aSMatthew G Knepley   ierr    = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr);
25057459e9aSMatthew G Knepley   ierr    = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
25157459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, -1,  &pStart, &pEnd);CHKERRQ(ierr);
25257459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, 0,   &cStart, &cEnd);CHKERRQ(ierr);
25357459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, 1,   &fStart, &fEnd);CHKERRQ(ierr);
25457459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr);
25557459e9aSMatthew G Knepley   xfStart = vEnd;  xfEnd = xfStart+nXF;
25657459e9aSMatthew G Knepley   yfStart = xfEnd; yfEnd = yfStart+nYF;
25757459e9aSMatthew G Knepley   zfStart = yfEnd; zfEnd = zfStart+nZF;
25882f516ccSBarry Smith   if (zfEnd != fEnd) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd);
25988ed4aceSMatthew G Knepley   /* Create local section */
26080800b1aSMatthew G Knepley   ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr);
261a66d4d66SMatthew G Knepley   for (f = 0; f < numFields; ++f) {
2628865f1eaSKarl Rupp     if (numVertexDof) numVertexTotDof  += numVertexDof[f];
2638865f1eaSKarl Rupp     if (numCellDof)   numCellTotDof    += numCellDof[f];
2648865f1eaSKarl Rupp     if (numFaceDof) {
2658865f1eaSKarl Rupp       numFaceTotDof[0] += numFaceDof[f*dim+0];
26688ed4aceSMatthew G Knepley       numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0;
2670ad7597dSKarl Rupp       numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0;
2680ad7597dSKarl Rupp     }
269a66d4d66SMatthew G Knepley   }
27082f516ccSBarry Smith   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &dm->defaultSection);CHKERRQ(ierr);
271a66d4d66SMatthew G Knepley   if (numFields > 1) {
27288ed4aceSMatthew G Knepley     ierr = PetscSectionSetNumFields(dm->defaultSection, numFields);CHKERRQ(ierr);
273a66d4d66SMatthew G Knepley     for (f = 0; f < numFields; ++f) {
27480800b1aSMatthew G Knepley       const char *name;
27580800b1aSMatthew G Knepley 
27680800b1aSMatthew G Knepley       ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr);
27788ed4aceSMatthew G Knepley       ierr = PetscSectionSetFieldName(dm->defaultSection, f, name);CHKERRQ(ierr);
27880800b1aSMatthew G Knepley       if (numComp) {
27988ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldComponents(dm->defaultSection, f, numComp[f]);CHKERRQ(ierr);
280a66d4d66SMatthew G Knepley       }
281a66d4d66SMatthew G Knepley     }
282a66d4d66SMatthew G Knepley   } else {
283a66d4d66SMatthew G Knepley     numFields = 0;
284a66d4d66SMatthew G Knepley   }
28588ed4aceSMatthew G Knepley   ierr = PetscSectionSetChart(dm->defaultSection, pStart, pEnd);CHKERRQ(ierr);
286a66d4d66SMatthew G Knepley   if (numVertexDof) {
287a66d4d66SMatthew G Knepley     for (v = vStart; v < vEnd; ++v) {
288a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
28988ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, v, f, numVertexDof[f]);CHKERRQ(ierr);
290a66d4d66SMatthew G Knepley       }
29188ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, v, numVertexTotDof);CHKERRQ(ierr);
292a66d4d66SMatthew G Knepley     }
293a66d4d66SMatthew G Knepley   }
294a66d4d66SMatthew G Knepley   if (numFaceDof) {
295a66d4d66SMatthew G Knepley     for (xf = xfStart; xf < xfEnd; ++xf) {
296a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
29788ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, xf, f, numFaceDof[f*dim+0]);CHKERRQ(ierr);
298a66d4d66SMatthew G Knepley       }
29988ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, xf, numFaceTotDof[0]);CHKERRQ(ierr);
300a66d4d66SMatthew G Knepley     }
301a66d4d66SMatthew G Knepley     for (yf = yfStart; yf < yfEnd; ++yf) {
302a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
30388ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, yf, f, numFaceDof[f*dim+1]);CHKERRQ(ierr);
304a66d4d66SMatthew G Knepley       }
30588ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, yf, numFaceTotDof[1]);CHKERRQ(ierr);
306a66d4d66SMatthew G Knepley     }
307a66d4d66SMatthew G Knepley     for (zf = zfStart; zf < zfEnd; ++zf) {
308a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
30988ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, zf, f, numFaceDof[f*dim+2]);CHKERRQ(ierr);
310a66d4d66SMatthew G Knepley       }
31188ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, zf, numFaceTotDof[2]);CHKERRQ(ierr);
312a66d4d66SMatthew G Knepley     }
313a66d4d66SMatthew G Knepley   }
314a66d4d66SMatthew G Knepley   if (numCellDof) {
315a66d4d66SMatthew G Knepley     for (c = cStart; c < cEnd; ++c) {
316a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
31788ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, c, f, numCellDof[f]);CHKERRQ(ierr);
318a66d4d66SMatthew G Knepley       }
31988ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, c, numCellTotDof);CHKERRQ(ierr);
320a66d4d66SMatthew G Knepley     }
321a66d4d66SMatthew G Knepley   }
32288ed4aceSMatthew G Knepley   ierr = PetscSectionSetUp(dm->defaultSection);CHKERRQ(ierr);
32388ed4aceSMatthew G Knepley   /* Create mesh point SF */
324*b2fff234SMatthew G. Knepley   ierr = PetscBTCreate(pEnd-pStart, &isLeaf);CHKERRQ(ierr);
32588ed4aceSMatthew G Knepley   ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr);
32688ed4aceSMatthew G Knepley   for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
32788ed4aceSMatthew G Knepley     for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
32888ed4aceSMatthew G Knepley       for (xn = 0; xn < 3; ++xn) {
3297128ae9fSMatthew G Knepley         const PetscInt xp       = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
33088ed4aceSMatthew G Knepley         const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
331*b2fff234SMatthew G. Knepley         PetscInt       xv, yv, zv;
33288ed4aceSMatthew G Knepley 
3333814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
334*b2fff234SMatthew G. Knepley           if (xp < 0) { /* left */
335*b2fff234SMatthew G. Knepley             if (yp < 0) { /* bottom */
336*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
337*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx +     0 + nC; /* left bottom back vertex */
338*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
339*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
340*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* left bottom front vertex */
341*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
342*b2fff234SMatthew G. Knepley               } else {
343*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
344*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx +     0 + nC; /* left bottom vertices */
345*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
346*b2fff234SMatthew G. Knepley                 }
347*b2fff234SMatthew G. Knepley               }
348*b2fff234SMatthew G. Knepley             } else if (yp > 0) { /* top */
349*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
350*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx +     0 + nC; /* left top back vertex */
351*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
352*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
353*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* left top front vertex */
354*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
355*b2fff234SMatthew G. Knepley               } else {
356*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
357*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx +     0 + nC; /* left top vertices */
358*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
359*b2fff234SMatthew G. Knepley                 }
360*b2fff234SMatthew G. Knepley               }
361*b2fff234SMatthew G. Knepley             } else {
362*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
363*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
364*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx +     0 + nC; /* left back vertices */
365*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
366*b2fff234SMatthew G. Knepley                 }
367*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
368*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
369*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* left front vertices */
370*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
371*b2fff234SMatthew G. Knepley                 }
372*b2fff234SMatthew G. Knepley               } else {
373*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
374*b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
375*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx +     0 + nC; /* left vertices */
376*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
377*b2fff234SMatthew G. Knepley                   }
378*b2fff234SMatthew G. Knepley                 }
379*b2fff234SMatthew G. Knepley #if 0
380*b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
381*b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
382*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* left faces */
383*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
384*b2fff234SMatthew G. Knepley                 }
385*b2fff234SMatthew G. Knepley #endif
386*b2fff234SMatthew G. Knepley               }
387*b2fff234SMatthew G. Knepley             }
388*b2fff234SMatthew G. Knepley           } else if (xp > 0) { /* right */
389*b2fff234SMatthew G. Knepley             if (yp < 0) { /* bottom */
390*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
391*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx + nVx-1 + nC; /* right bottom back vertex */
392*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
393*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
394*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* right bottom front vertex */
395*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
396*b2fff234SMatthew G. Knepley               } else {
397*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
398*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx + nVx-1 + nC; /* right bottom vertices */
399*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
400*b2fff234SMatthew G. Knepley                 }
401*b2fff234SMatthew G. Knepley               }
402*b2fff234SMatthew G. Knepley             } else if (yp > 0) { /* top */
403*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
404*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */
405*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
406*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
407*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */
408*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
409*b2fff234SMatthew G. Knepley               } else {
410*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
411*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */
412*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
413*b2fff234SMatthew G. Knepley                 }
414*b2fff234SMatthew G. Knepley               }
415*b2fff234SMatthew G. Knepley             } else {
416*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
417*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
418*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */
419*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
420*b2fff234SMatthew G. Knepley                 }
421*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
422*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
423*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */
424*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
425*b2fff234SMatthew G. Knepley                 }
426*b2fff234SMatthew G. Knepley               } else {
427*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
428*b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
429*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */
430*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
431*b2fff234SMatthew G. Knepley                   }
432*b2fff234SMatthew G. Knepley                 }
433*b2fff234SMatthew G. Knepley #if 0
434*b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
435*b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
436*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* right faces */
437*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
438*b2fff234SMatthew G. Knepley                 }
439*b2fff234SMatthew G. Knepley #endif
440*b2fff234SMatthew G. Knepley               }
441*b2fff234SMatthew G. Knepley             }
442*b2fff234SMatthew G. Knepley           } else {
443*b2fff234SMatthew G. Knepley             if (yp < 0) { /* bottom */
444*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
445*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
446*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy +     0)*nVx + xv + nC; /* bottom back vertices */
447*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
448*b2fff234SMatthew G. Knepley                 }
449*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
450*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
451*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* bottom front vertices */
452*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
453*b2fff234SMatthew G. Knepley                 }
454*b2fff234SMatthew G. Knepley               } else {
455*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
456*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
457*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy +     0)*nVx + xv + nC; /* bottom vertices */
458*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
459*b2fff234SMatthew G. Knepley                   }
460*b2fff234SMatthew G. Knepley                 }
461*b2fff234SMatthew G. Knepley #if 0
462*b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
463*b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
464*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* bottom faces */
465*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves;
466*b2fff234SMatthew G. Knepley                 }
467*b2fff234SMatthew G. Knepley #endif
468*b2fff234SMatthew G. Knepley               }
469*b2fff234SMatthew G. Knepley             } else if (yp > 0) { /* top */
470*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
471*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
472*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */
473*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
474*b2fff234SMatthew G. Knepley                 }
475*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
476*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
477*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */
478*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
479*b2fff234SMatthew G. Knepley                 }
480*b2fff234SMatthew G. Knepley               } else {
481*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
482*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
483*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */
484*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
485*b2fff234SMatthew G. Knepley                   }
486*b2fff234SMatthew G. Knepley                 }
487*b2fff234SMatthew G. Knepley #if 0
488*b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
489*b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
490*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* top faces */
491*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves;
492*b2fff234SMatthew G. Knepley                 }
493*b2fff234SMatthew G. Knepley #endif
494*b2fff234SMatthew G. Knepley               }
495*b2fff234SMatthew G. Knepley             } else {
496*b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
497*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
498*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
499*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (      0*nVy + yv)*nVx + xv + nC; /* back vertices */
500*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
501*b2fff234SMatthew G. Knepley                   }
502*b2fff234SMatthew G. Knepley                 }
503*b2fff234SMatthew G. Knepley #if 0
504*b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
505*b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
506*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* back faces */
507*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
508*b2fff234SMatthew G. Knepley                 }
509*b2fff234SMatthew G. Knepley #endif
510*b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
511*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
512*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
513*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */
514*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
515*b2fff234SMatthew G. Knepley                   }
516*b2fff234SMatthew G. Knepley                 }
517*b2fff234SMatthew G. Knepley #if 0
518*b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
519*b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
520*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* front faces */
521*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
522*b2fff234SMatthew G. Knepley                 }
523*b2fff234SMatthew G. Knepley #endif
524*b2fff234SMatthew G. Knepley               } else {
525*b2fff234SMatthew G. Knepley                 /* Nothing is shared from the interior */
52688ed4aceSMatthew G Knepley               }
52788ed4aceSMatthew G Knepley             }
52888ed4aceSMatthew G Knepley           }
52988ed4aceSMatthew G Knepley         }
53088ed4aceSMatthew G Knepley       }
531*b2fff234SMatthew G. Knepley     }
532*b2fff234SMatthew G. Knepley   }
533*b2fff234SMatthew G. Knepley   ierr = PetscBTMemzero(pEnd-pStart, isLeaf);CHKERRQ(ierr);
53488ed4aceSMatthew G Knepley   ierr = PetscMalloc2(nleaves,PetscInt,&localPoints,nleaves,PetscSFNode,&remotePoints);CHKERRQ(ierr);
53588ed4aceSMatthew G Knepley   for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
53688ed4aceSMatthew G Knepley     for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
53788ed4aceSMatthew G Knepley       for (xn = 0; xn < 3; ++xn) {
5387128ae9fSMatthew G Knepley         const PetscInt xp       = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
53988ed4aceSMatthew G Knepley         const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
540f5eeb527SMatthew G Knepley         PetscInt       xv, yv, zv;
54188ed4aceSMatthew G Knepley 
5423814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
54388ed4aceSMatthew G Knepley           if (xp < 0) { /* left */
54488ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
54588ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
546*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx +     0 + nC; /* left bottom back vertex */
547f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
548f5eeb527SMatthew G Knepley 
549*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
550f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
551f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
552f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
553f5eeb527SMatthew G Knepley                   ++nL;
554*b2fff234SMatthew G. Knepley                 }
55588ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
556*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* left bottom front vertex */
557f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
558f5eeb527SMatthew G Knepley 
559*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
560f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
561f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
562f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
563f5eeb527SMatthew G Knepley                   ++nL;
564*b2fff234SMatthew G. Knepley                 }
56588ed4aceSMatthew G Knepley               } else {
566*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
567*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx +     0 + nC; /* left bottom vertices */
568f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
569f5eeb527SMatthew G Knepley 
570*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
571f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
572f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
573f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
574*b2fff234SMatthew G. Knepley                     ++nL;
575*b2fff234SMatthew G. Knepley                   }
576f5eeb527SMatthew G Knepley                 }
57788ed4aceSMatthew G Knepley               }
57888ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
57988ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
580*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx +     0 + nC; /* left top back vertex */
581f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
582f5eeb527SMatthew G Knepley 
583*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
584f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
585f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
586f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
587f5eeb527SMatthew G Knepley                   ++nL;
588*b2fff234SMatthew G. Knepley                 }
58988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
590*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* left top front vertex */
591f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
592f5eeb527SMatthew G Knepley 
593*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
594f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
595f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
596f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
597f5eeb527SMatthew G Knepley                   ++nL;
598*b2fff234SMatthew G. Knepley                 }
59988ed4aceSMatthew G Knepley               } else {
600*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
601*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx +     0 + nC; /* left top vertices */
602f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
603f5eeb527SMatthew G Knepley 
604*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
605f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
606f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
607f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
608*b2fff234SMatthew G. Knepley                     ++nL;
609*b2fff234SMatthew G. Knepley                   }
610f5eeb527SMatthew G Knepley                 }
61188ed4aceSMatthew G Knepley               }
61288ed4aceSMatthew G Knepley             } else {
61388ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
614*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
615*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx +     0 + nC; /* left back vertices */
616f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
617f5eeb527SMatthew G Knepley 
618*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
619f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
620f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
621f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
622*b2fff234SMatthew G. Knepley                     ++nL;
623*b2fff234SMatthew G. Knepley                   }
624f5eeb527SMatthew G Knepley                 }
62588ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
626*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
627*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* left front vertices */
628f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
629f5eeb527SMatthew G Knepley 
630*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
631f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
632f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
633f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
634*b2fff234SMatthew G. Knepley                     ++nL;
635*b2fff234SMatthew G. Knepley                   }
636f5eeb527SMatthew G Knepley                 }
63788ed4aceSMatthew G Knepley               } else {
638f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
639*b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
640*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx +     0 + nC; /* left vertices */
641f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
642f5eeb527SMatthew G Knepley 
643*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
644f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
645f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
646f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
647*b2fff234SMatthew G. Knepley                       ++nL;
648f5eeb527SMatthew G Knepley                     }
649f5eeb527SMatthew G Knepley                   }
650*b2fff234SMatthew G. Knepley                 }
651*b2fff234SMatthew G. Knepley #if 0
652*b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
653f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
654*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* left faces */
655f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
656f5eeb527SMatthew G Knepley 
657*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
658f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
659f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
660f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
661f5eeb527SMatthew G Knepley                   }
66288ed4aceSMatthew G Knepley                 }
663*b2fff234SMatthew G. Knepley #endif
664*b2fff234SMatthew G. Knepley               }
66588ed4aceSMatthew G Knepley             }
66688ed4aceSMatthew G Knepley           } else if (xp > 0) { /* right */
66788ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
66888ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
669*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx + nVx-1 + nC; /* right bottom back vertex */
670f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
671f5eeb527SMatthew G Knepley 
672*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
673f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
674f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
675f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
676f5eeb527SMatthew G Knepley                   ++nL;
677*b2fff234SMatthew G. Knepley                 }
67888ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
679*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* right bottom front vertex */
680f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
681f5eeb527SMatthew G Knepley 
682*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
683f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
684f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
685f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
686f5eeb527SMatthew G Knepley                   ++nL;
687*b2fff234SMatthew G. Knepley                 }
68888ed4aceSMatthew G Knepley               } else {
689*b2fff234SMatthew G. Knepley                 nleavesCheck += nVz;
690*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
691*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx + nVx-1 + nC; /* right bottom vertices */
692f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
693f5eeb527SMatthew G Knepley 
694*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
695f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
696f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
697f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
698*b2fff234SMatthew G. Knepley                     ++nL;
699*b2fff234SMatthew G. Knepley                   }
700f5eeb527SMatthew G Knepley                 }
70188ed4aceSMatthew G Knepley               }
70288ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
70388ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
704*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */
705f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
706f5eeb527SMatthew G Knepley 
707*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
708f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
709f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
710f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
711f5eeb527SMatthew G Knepley                   ++nL;
712*b2fff234SMatthew G. Knepley                 }
71388ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
714*b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */
715f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
716f5eeb527SMatthew G Knepley 
717*b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
718f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
719f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
720f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
721f5eeb527SMatthew G Knepley                   ++nL;
722*b2fff234SMatthew G. Knepley                 }
72388ed4aceSMatthew G Knepley               } else {
724*b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
725*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */
726f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
727f5eeb527SMatthew G Knepley 
728*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
729f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
730f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
731f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
732*b2fff234SMatthew G. Knepley                     ++nL;
733*b2fff234SMatthew G. Knepley                   }
734f5eeb527SMatthew G Knepley                 }
73588ed4aceSMatthew G Knepley               }
73688ed4aceSMatthew G Knepley             } else {
73788ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
738*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
739*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */
740f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
741f5eeb527SMatthew G Knepley 
742*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
743f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
744f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
745f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
746*b2fff234SMatthew G. Knepley                     ++nL;
747*b2fff234SMatthew G. Knepley                   }
748f5eeb527SMatthew G Knepley                 }
74988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
750*b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
751*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */
752f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
753f5eeb527SMatthew G Knepley 
754*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
755f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
756f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
757f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
758*b2fff234SMatthew G. Knepley                     ++nL;
759*b2fff234SMatthew G. Knepley                   }
760f5eeb527SMatthew G Knepley                 }
76188ed4aceSMatthew G Knepley               } else {
762f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
763*b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
764*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */
765f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0     + nC; /* TODO: Correct this for neighbor sizes */
766f5eeb527SMatthew G Knepley 
767*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
768f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
769f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
770f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
771*b2fff234SMatthew G. Knepley                       ++nL;
772f5eeb527SMatthew G Knepley                     }
773f5eeb527SMatthew G Knepley                   }
774*b2fff234SMatthew G. Knepley                 }
775*b2fff234SMatthew G. Knepley #if 0
776*b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
777f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
778*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* right faces */
779f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
780f5eeb527SMatthew G Knepley 
781*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
782f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
783f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
784f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
785*b2fff234SMatthew G. Knepley                     ++nL;
786f5eeb527SMatthew G Knepley                   }
78788ed4aceSMatthew G Knepley                 }
788*b2fff234SMatthew G. Knepley #endif
789*b2fff234SMatthew G. Knepley               }
79088ed4aceSMatthew G Knepley             }
79188ed4aceSMatthew G Knepley           } else {
79288ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
79388ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
794*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
795*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy +     0)*nVx + xv + nC; /* bottom back vertices */
796f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
797f5eeb527SMatthew G Knepley 
798*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
799f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
800f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
801f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
802*b2fff234SMatthew G. Knepley                     ++nL;
803*b2fff234SMatthew G. Knepley                   }
804f5eeb527SMatthew G Knepley                 }
80588ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
806*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
807*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* bottom front vertices */
808f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
809f5eeb527SMatthew G Knepley 
810*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
811f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
812f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
813f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
814*b2fff234SMatthew G. Knepley                     ++nL;
815*b2fff234SMatthew G. Knepley                   }
816f5eeb527SMatthew G Knepley                 }
81788ed4aceSMatthew G Knepley               } else {
818f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
819*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
820*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy +     0)*nVx + xv + nC; /* bottom vertices */
821f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
822f5eeb527SMatthew G Knepley 
823*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
824f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
825f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
826f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
827*b2fff234SMatthew G. Knepley                       ++nL;
828f5eeb527SMatthew G Knepley                     }
829f5eeb527SMatthew G Knepley                   }
830*b2fff234SMatthew G. Knepley                 }
831*b2fff234SMatthew G. Knepley #if 0
832*b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
833f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
834*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* bottom faces */
835f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
836f5eeb527SMatthew G Knepley 
837*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
838f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
839f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
840f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
841*b2fff234SMatthew G. Knepley                     ++nL;
842f5eeb527SMatthew G Knepley                   }
84388ed4aceSMatthew G Knepley                 }
844*b2fff234SMatthew G. Knepley #endif
845*b2fff234SMatthew G. Knepley               }
84688ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
84788ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
848*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
849*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */
850f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
851f5eeb527SMatthew G Knepley 
852*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
853f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
854f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
855f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
856*b2fff234SMatthew G. Knepley                     ++nL;
857*b2fff234SMatthew G. Knepley                   }
858f5eeb527SMatthew G Knepley                 }
85988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
860*b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
861*b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */
862f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
863f5eeb527SMatthew G Knepley 
864*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
865f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
866f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
867f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
868*b2fff234SMatthew G. Knepley                     ++nL;
869*b2fff234SMatthew G. Knepley                   }
870f5eeb527SMatthew G Knepley                 }
87188ed4aceSMatthew G Knepley               } else {
872f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
873*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
874*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */
875f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
876f5eeb527SMatthew G Knepley 
877*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
878f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
879f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
880f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
881*b2fff234SMatthew G. Knepley                       ++nL;
882f5eeb527SMatthew G Knepley                     }
883f5eeb527SMatthew G Knepley                   }
884*b2fff234SMatthew G. Knepley                 }
885*b2fff234SMatthew G. Knepley #if 0
886*b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
887f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
888*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* top faces */
889f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
890f5eeb527SMatthew G Knepley 
891*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
892f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
893f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
894f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
895*b2fff234SMatthew G. Knepley                     ++nL;
896f5eeb527SMatthew G Knepley                   }
89788ed4aceSMatthew G Knepley                 }
898*b2fff234SMatthew G. Knepley #endif
899*b2fff234SMatthew G. Knepley               }
90088ed4aceSMatthew G Knepley             } else {
90188ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
902f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv) {
903*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
904*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (      0*nVy + yv)*nVx + xv + nC; /* back vertices */
905f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
906f5eeb527SMatthew G Knepley 
907*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
908f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
909f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
910f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
911*b2fff234SMatthew G. Knepley                       ++nL;
912f5eeb527SMatthew G Knepley                     }
913f5eeb527SMatthew G Knepley                   }
914*b2fff234SMatthew G. Knepley                 }
915*b2fff234SMatthew G. Knepley #if 0
916*b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
917f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
918*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* back faces */
919f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
920f5eeb527SMatthew G Knepley 
921*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
922f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
923f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
924f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
925*b2fff234SMatthew G. Knepley                     ++nL;
926f5eeb527SMatthew G Knepley                   }
927*b2fff234SMatthew G. Knepley                 }
928*b2fff234SMatthew G. Knepley #endif
92988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
930f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv) {
931*b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
932*b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */
933f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (      0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
934f5eeb527SMatthew G Knepley 
935*b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
936f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
937f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
938f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
939*b2fff234SMatthew G. Knepley                       ++nL;
940f5eeb527SMatthew G Knepley                     }
941f5eeb527SMatthew G Knepley                   }
942*b2fff234SMatthew G. Knepley                 }
943*b2fff234SMatthew G. Knepley #if 0
944*b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
945f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
946*b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* front faces */
947f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
948f5eeb527SMatthew G Knepley 
949*b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
950f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
951f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
952f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
953*b2fff234SMatthew G. Knepley                     ++nL;
954f5eeb527SMatthew G Knepley                   }
955*b2fff234SMatthew G. Knepley                 }
956*b2fff234SMatthew G. Knepley #endif
95788ed4aceSMatthew G Knepley               } else {
95888ed4aceSMatthew G Knepley                 /* Nothing is shared from the interior */
95988ed4aceSMatthew G Knepley               }
96088ed4aceSMatthew G Knepley             }
96188ed4aceSMatthew G Knepley           }
96288ed4aceSMatthew G Knepley         }
96388ed4aceSMatthew G Knepley       }
96488ed4aceSMatthew G Knepley     }
96588ed4aceSMatthew G Knepley   }
966*b2fff234SMatthew G. Knepley   ierr = PetscBTDestroy(&isLeaf);CHKERRQ(ierr);
967*b2fff234SMatthew G. Knepley   /* Remove duplication in leaf determination */
968*b2fff234SMatthew G. Knepley   if (nleaves != nL) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "The number of leaves %d did not match the number of remote leaves %d", nleaves, nleavesCheck);
96982f516ccSBarry Smith   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), &sf);CHKERRQ(ierr);
97088ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr);
97188ed4aceSMatthew G Knepley   /* Create global section */
972eaf8d80aSMatthew G Knepley   ierr = PetscSectionCreateGlobalSection(dm->defaultSection, sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
97388ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&sf);CHKERRQ(ierr);
97488ed4aceSMatthew G Knepley   /* Create default SF */
97588ed4aceSMatthew G Knepley   ierr = DMCreateDefaultSF(dm, dm->defaultSection, dm->defaultGlobalSection);CHKERRQ(ierr);
976a66d4d66SMatthew G Knepley   PetscFunctionReturn(0);
977a66d4d66SMatthew G Knepley }
978a66d4d66SMatthew G Knepley 
97947c6ae99SBarry Smith /* ------------------------------------------------------------------- */
98047c6ae99SBarry Smith 
98147c6ae99SBarry Smith #undef __FUNCT__
982aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
98347c6ae99SBarry Smith /*@C
984aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
98547c6ae99SBarry Smith 
98647c6ae99SBarry Smith     Input Parameter:
98747c6ae99SBarry Smith +    da - information about my local patch
98847c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
98947c6ae99SBarry Smith 
99047c6ae99SBarry Smith     Output Parameters:
99147c6ae99SBarry Smith .    vptr - array data structured
99247c6ae99SBarry Smith 
99347c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
99447c6ae99SBarry Smith            to zero them.
99547c6ae99SBarry Smith 
99647c6ae99SBarry Smith   Level: advanced
99747c6ae99SBarry Smith 
998bcaeba4dSBarry Smith .seealso: DMDARestoreArray()
99947c6ae99SBarry Smith 
100047c6ae99SBarry Smith @*/
10017087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool ghosted,void *vptr)
100247c6ae99SBarry Smith {
100347c6ae99SBarry Smith   PetscErrorCode ierr;
100447c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
100547c6ae99SBarry Smith   char           *iarray_start;
100647c6ae99SBarry Smith   void           **iptr = (void**)vptr;
100747c6ae99SBarry Smith   DM_DA          *dd    = (DM_DA*)da->data;
100847c6ae99SBarry Smith 
100947c6ae99SBarry Smith   PetscFunctionBegin;
101047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
101147c6ae99SBarry Smith   if (ghosted) {
1012aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
101347c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
101447c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
101547c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
10160298fd71SBarry Smith         dd->arrayghostedin[i] = NULL;
10170298fd71SBarry Smith         dd->startghostedin[i] = NULL;
101847c6ae99SBarry Smith 
101947c6ae99SBarry Smith         goto done;
102047c6ae99SBarry Smith       }
102147c6ae99SBarry Smith     }
102247c6ae99SBarry Smith     xs = dd->Xs;
102347c6ae99SBarry Smith     ys = dd->Ys;
102447c6ae99SBarry Smith     zs = dd->Zs;
102547c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
102647c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
102747c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
102847c6ae99SBarry Smith   } else {
1029aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
103047c6ae99SBarry Smith       if (dd->arrayin[i]) {
103147c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
103247c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
10330298fd71SBarry Smith         dd->arrayin[i] = NULL;
10340298fd71SBarry Smith         dd->startin[i] = NULL;
103547c6ae99SBarry Smith 
103647c6ae99SBarry Smith         goto done;
103747c6ae99SBarry Smith       }
103847c6ae99SBarry Smith     }
103947c6ae99SBarry Smith     xs = dd->xs;
104047c6ae99SBarry Smith     ys = dd->ys;
104147c6ae99SBarry Smith     zs = dd->zs;
104247c6ae99SBarry Smith     xm = dd->xe-dd->xs;
104347c6ae99SBarry Smith     ym = dd->ye-dd->ys;
104447c6ae99SBarry Smith     zm = dd->ze-dd->zs;
104547c6ae99SBarry Smith   }
104647c6ae99SBarry Smith 
104747c6ae99SBarry Smith   switch (dd->dim) {
104847c6ae99SBarry Smith   case 1: {
104947c6ae99SBarry Smith     void *ptr;
105047c6ae99SBarry Smith 
105147c6ae99SBarry Smith     ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
105247c6ae99SBarry Smith 
105347c6ae99SBarry Smith     ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
105447c6ae99SBarry Smith     *iptr = (void*)ptr;
10558865f1eaSKarl Rupp     break;
10568865f1eaSKarl Rupp   }
105747c6ae99SBarry Smith   case 2: {
105847c6ae99SBarry Smith     void **ptr;
105947c6ae99SBarry Smith 
106047c6ae99SBarry Smith     ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
106147c6ae99SBarry Smith 
106247c6ae99SBarry Smith     ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
10638865f1eaSKarl Rupp     for (j=ys; j<ys+ym; j++) ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
106447c6ae99SBarry Smith     *iptr = (void*)ptr;
10658865f1eaSKarl Rupp     break;
10668865f1eaSKarl Rupp   }
106747c6ae99SBarry Smith   case 3: {
106847c6ae99SBarry Smith     void ***ptr,**bptr;
106947c6ae99SBarry Smith 
107047c6ae99SBarry Smith     ierr = PetscMalloc((zm+1)*sizeof(void**)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
107147c6ae99SBarry Smith 
107247c6ae99SBarry Smith     ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
107347c6ae99SBarry Smith     bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
10748865f1eaSKarl Rupp     for (i=zs; i<zs+zm; i++) ptr[i] = bptr + ((i-zs)*ym - ys);
107547c6ae99SBarry Smith     for (i=zs; i<zs+zm; i++) {
107647c6ae99SBarry Smith       for (j=ys; j<ys+ym; j++) {
107747c6ae99SBarry Smith         ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
107847c6ae99SBarry Smith       }
107947c6ae99SBarry Smith     }
108047c6ae99SBarry Smith     *iptr = (void*)ptr;
10818865f1eaSKarl Rupp     break;
10828865f1eaSKarl Rupp   }
108347c6ae99SBarry Smith   default:
1084ce94432eSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
108547c6ae99SBarry Smith   }
108647c6ae99SBarry Smith 
108747c6ae99SBarry Smith done:
108847c6ae99SBarry Smith   /* add arrays to the checked out list */
108947c6ae99SBarry Smith   if (ghosted) {
1090aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
109147c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
109247c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr;
109347c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
109447c6ae99SBarry Smith         break;
109547c6ae99SBarry Smith       }
109647c6ae99SBarry Smith     }
109747c6ae99SBarry Smith   } else {
1098aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
109947c6ae99SBarry Smith       if (!dd->arrayout[i]) {
110047c6ae99SBarry Smith         dd->arrayout[i] = *iptr;
110147c6ae99SBarry Smith         dd->startout[i] = iarray_start;
110247c6ae99SBarry Smith         break;
110347c6ae99SBarry Smith       }
110447c6ae99SBarry Smith     }
110547c6ae99SBarry Smith   }
110647c6ae99SBarry Smith   PetscFunctionReturn(0);
110747c6ae99SBarry Smith }
110847c6ae99SBarry Smith 
110947c6ae99SBarry Smith #undef __FUNCT__
1110aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
111147c6ae99SBarry Smith /*@C
1112aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
111347c6ae99SBarry Smith 
111447c6ae99SBarry Smith     Input Parameter:
111547c6ae99SBarry Smith +    da - information about my local patch
111647c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
111747c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
111847c6ae99SBarry Smith 
111947c6ae99SBarry Smith      Level: advanced
112047c6ae99SBarry Smith 
1121bcaeba4dSBarry Smith .seealso: DMDAGetArray()
112247c6ae99SBarry Smith 
112347c6ae99SBarry Smith @*/
11247087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool ghosted,void *vptr)
112547c6ae99SBarry Smith {
112647c6ae99SBarry Smith   PetscInt i;
112747c6ae99SBarry Smith   void     **iptr = (void**)vptr,*iarray_start = 0;
112847c6ae99SBarry Smith   DM_DA    *dd    = (DM_DA*)da->data;
112947c6ae99SBarry Smith 
113047c6ae99SBarry Smith   PetscFunctionBegin;
113147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
113247c6ae99SBarry Smith   if (ghosted) {
1133aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
113447c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
113547c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
11360298fd71SBarry Smith         dd->arrayghostedout[i] = NULL;
11370298fd71SBarry Smith         dd->startghostedout[i] = NULL;
113847c6ae99SBarry Smith         break;
113947c6ae99SBarry Smith       }
114047c6ae99SBarry Smith     }
1141aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
114247c6ae99SBarry Smith       if (!dd->arrayghostedin[i]) {
114347c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
114447c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
114547c6ae99SBarry Smith         break;
114647c6ae99SBarry Smith       }
114747c6ae99SBarry Smith     }
114847c6ae99SBarry Smith   } else {
1149aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
115047c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
115147c6ae99SBarry Smith         iarray_start    = dd->startout[i];
11520298fd71SBarry Smith         dd->arrayout[i] = NULL;
11530298fd71SBarry Smith         dd->startout[i] = NULL;
115447c6ae99SBarry Smith         break;
115547c6ae99SBarry Smith       }
115647c6ae99SBarry Smith     }
1157aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
115847c6ae99SBarry Smith       if (!dd->arrayin[i]) {
115947c6ae99SBarry Smith         dd->arrayin[i] = *iptr;
116047c6ae99SBarry Smith         dd->startin[i] = iarray_start;
116147c6ae99SBarry Smith         break;
116247c6ae99SBarry Smith       }
116347c6ae99SBarry Smith     }
116447c6ae99SBarry Smith   }
116547c6ae99SBarry Smith   PetscFunctionReturn(0);
116647c6ae99SBarry Smith }
116747c6ae99SBarry Smith 
1168