xref: /petsc/src/dm/impls/da/dalocal.c (revision e42e3c5890f67a7deb9e6c9bc150511d5d6944eb)
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*/
7b2fff234SMatthew 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"
77*e42e3c58SMatthew G. Knepley PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCellsX, PetscInt *numCellsY, PetscInt *numCellsZ, 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;
85*e42e3c58SMatthew G. Knepley   if (numCellsX) {
86*e42e3c58SMatthew G. Knepley     PetscValidIntPointer(numCellsX,2);
87*e42e3c58SMatthew G. Knepley     *numCellsX = mx;
88*e42e3c58SMatthew G. Knepley   }
89*e42e3c58SMatthew G. Knepley   if (numCellsY) {
90*e42e3c58SMatthew G. Knepley     PetscValidIntPointer(numCellsX,3);
91*e42e3c58SMatthew G. Knepley     *numCellsY = my;
92*e42e3c58SMatthew G. Knepley   }
93*e42e3c58SMatthew G. Knepley   if (numCellsZ) {
94*e42e3c58SMatthew G. Knepley     PetscValidIntPointer(numCellsX,4);
95*e42e3c58SMatthew G. Knepley     *numCellsZ = mz;
96*e42e3c58SMatthew G. Knepley   }
9757459e9aSMatthew G Knepley   if (numCells) {
98*e42e3c58SMatthew G. Knepley     PetscValidIntPointer(numCells,5);
9957459e9aSMatthew G Knepley     *numCells = nC;
10057459e9aSMatthew G Knepley   }
10157459e9aSMatthew G Knepley   PetscFunctionReturn(0);
10257459e9aSMatthew G Knepley }
10357459e9aSMatthew G Knepley 
10457459e9aSMatthew G Knepley #undef __FUNCT__
10557459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumVertices"
10657459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices)
10757459e9aSMatthew G Knepley {
10857459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
10957459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
11057459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
11157459e9aSMatthew G Knepley   const PetscInt nVx = mx+1;
11257459e9aSMatthew G Knepley   const PetscInt nVy = dim > 1 ? (my+1) : 1;
11357459e9aSMatthew G Knepley   const PetscInt nVz = dim > 2 ? (mz+1) : 1;
11457459e9aSMatthew G Knepley   const PetscInt nV  = nVx*nVy*nVz;
11557459e9aSMatthew G Knepley 
11657459e9aSMatthew G Knepley   PetscFunctionBegin;
11757459e9aSMatthew G Knepley   if (numVerticesX) {
11857459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesX,2);
11957459e9aSMatthew G Knepley     *numVerticesX = nVx;
12057459e9aSMatthew G Knepley   }
12157459e9aSMatthew G Knepley   if (numVerticesY) {
12257459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesY,3);
12357459e9aSMatthew G Knepley     *numVerticesY = nVy;
12457459e9aSMatthew G Knepley   }
12557459e9aSMatthew G Knepley   if (numVerticesZ) {
12657459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesZ,4);
12757459e9aSMatthew G Knepley     *numVerticesZ = nVz;
12857459e9aSMatthew G Knepley   }
12957459e9aSMatthew G Knepley   if (numVertices) {
13057459e9aSMatthew G Knepley     PetscValidIntPointer(numVertices,5);
13157459e9aSMatthew G Knepley     *numVertices = nV;
13257459e9aSMatthew G Knepley   }
13357459e9aSMatthew G Knepley   PetscFunctionReturn(0);
13457459e9aSMatthew G Knepley }
13557459e9aSMatthew G Knepley 
13657459e9aSMatthew G Knepley #undef __FUNCT__
13757459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumFaces"
13857459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces)
13957459e9aSMatthew G Knepley {
14057459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
14157459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
14257459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
14357459e9aSMatthew G Knepley   const PetscInt nxF = (dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1);
14457459e9aSMatthew G Knepley   const PetscInt nXF = (mx+1)*nxF;
14557459e9aSMatthew G Knepley   const PetscInt nyF = mx*(dim > 2 ? mz : 1);
14657459e9aSMatthew G Knepley   const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0;
14757459e9aSMatthew G Knepley   const PetscInt nzF = mx*(dim > 1 ? my : 0);
14857459e9aSMatthew G Knepley   const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0;
14957459e9aSMatthew G Knepley 
15057459e9aSMatthew G Knepley   PetscFunctionBegin;
15157459e9aSMatthew G Knepley   if (numXFacesX) {
15257459e9aSMatthew G Knepley     PetscValidIntPointer(numXFacesX,2);
15357459e9aSMatthew G Knepley     *numXFacesX = nxF;
15457459e9aSMatthew G Knepley   }
15557459e9aSMatthew G Knepley   if (numXFaces) {
15657459e9aSMatthew G Knepley     PetscValidIntPointer(numXFaces,3);
15757459e9aSMatthew G Knepley     *numXFaces = nXF;
15857459e9aSMatthew G Knepley   }
15957459e9aSMatthew G Knepley   if (numYFacesY) {
16057459e9aSMatthew G Knepley     PetscValidIntPointer(numYFacesY,4);
16157459e9aSMatthew G Knepley     *numYFacesY = nyF;
16257459e9aSMatthew G Knepley   }
16357459e9aSMatthew G Knepley   if (numYFaces) {
16457459e9aSMatthew G Knepley     PetscValidIntPointer(numYFaces,5);
16557459e9aSMatthew G Knepley     *numYFaces = nYF;
16657459e9aSMatthew G Knepley   }
16757459e9aSMatthew G Knepley   if (numZFacesZ) {
16857459e9aSMatthew G Knepley     PetscValidIntPointer(numZFacesZ,6);
16957459e9aSMatthew G Knepley     *numZFacesZ = nzF;
17057459e9aSMatthew G Knepley   }
17157459e9aSMatthew G Knepley   if (numZFaces) {
17257459e9aSMatthew G Knepley     PetscValidIntPointer(numZFaces,7);
17357459e9aSMatthew G Knepley     *numZFaces = nZF;
17457459e9aSMatthew G Knepley   }
17557459e9aSMatthew G Knepley   PetscFunctionReturn(0);
17657459e9aSMatthew G Knepley }
17757459e9aSMatthew G Knepley 
17857459e9aSMatthew G Knepley #undef __FUNCT__
17957459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetHeightStratum"
18057459e9aSMatthew G Knepley PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd)
18157459e9aSMatthew G Knepley {
18257459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
18357459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
18457459e9aSMatthew G Knepley   PetscInt       nC, nV, nXF, nYF, nZF;
18557459e9aSMatthew G Knepley   PetscErrorCode ierr;
18657459e9aSMatthew G Knepley 
18757459e9aSMatthew G Knepley   PetscFunctionBegin;
1888865f1eaSKarl Rupp   if (pStart) PetscValidIntPointer(pStart,3);
1898865f1eaSKarl Rupp   if (pEnd)   PetscValidIntPointer(pEnd,4);
190*e42e3c58SMatthew G. Knepley   ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr);
1910298fd71SBarry Smith   ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr);
1920298fd71SBarry Smith   ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr);
19357459e9aSMatthew G Knepley   if (height == 0) {
19457459e9aSMatthew G Knepley     /* Cells */
1958865f1eaSKarl Rupp     if (pStart) *pStart = 0;
1968865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC;
19757459e9aSMatthew G Knepley   } else if (height == 1) {
19857459e9aSMatthew G Knepley     /* Faces */
1998865f1eaSKarl Rupp     if (pStart) *pStart = nC+nV;
2008865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
20157459e9aSMatthew G Knepley   } else if (height == dim) {
20257459e9aSMatthew G Knepley     /* Vertices */
2038865f1eaSKarl Rupp     if (pStart) *pStart = nC;
2048865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV;
20557459e9aSMatthew G Knepley   } else if (height < 0) {
20657459e9aSMatthew G Knepley     /* All points */
2078865f1eaSKarl Rupp     if (pStart) *pStart = 0;
2088865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
20982f516ccSBarry Smith   } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height);
21057459e9aSMatthew G Knepley   PetscFunctionReturn(0);
21157459e9aSMatthew G Knepley }
21257459e9aSMatthew G Knepley 
21357459e9aSMatthew G Knepley #undef __FUNCT__
214a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection"
215a66d4d66SMatthew G Knepley /*@C
216a66d4d66SMatthew G Knepley   DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with
217a66d4d66SMatthew G Knepley   different numbers of dofs on vertices, cells, and faces in each direction.
218a66d4d66SMatthew G Knepley 
219a66d4d66SMatthew G Knepley   Input Parameters:
220a66d4d66SMatthew G Knepley + dm- The DMDA
221a66d4d66SMatthew G Knepley . numFields - The number of fields
2220298fd71SBarry Smith . numComp - The number of components in each field, or NULL for 1
2230298fd71SBarry Smith . numVertexDof - The number of dofs per vertex for each field, or NULL
2240298fd71SBarry Smith . numFaceDof - The number of dofs per face for each field and direction, or NULL
2250298fd71SBarry Smith - numCellDof - The number of dofs per cell for each field, or NULL
226a66d4d66SMatthew G Knepley 
227a66d4d66SMatthew G Knepley   Level: developer
228a66d4d66SMatthew G Knepley 
229a66d4d66SMatthew G Knepley   Note:
230a66d4d66SMatthew G Knepley   The default DMDA numbering is as follows:
231a66d4d66SMatthew G Knepley 
232a66d4d66SMatthew G Knepley     - Cells:    [0,             nC)
233a66d4d66SMatthew G Knepley     - Vertices: [nC,            nC+nV)
23488ed4aceSMatthew G Knepley     - X-Faces:  [nC+nV,         nC+nV+nXF)         normal is +- x-dir
23588ed4aceSMatthew G Knepley     - Y-Faces:  [nC+nV+nXF,     nC+nV+nXF+nYF)     normal is +- y-dir
23688ed4aceSMatthew G Knepley     - Z-Faces:  [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir
237a66d4d66SMatthew G Knepley 
238a66d4d66SMatthew G Knepley   We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment.
239a66d4d66SMatthew G Knepley @*/
24080800b1aSMatthew G Knepley PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[])
241a66d4d66SMatthew G Knepley {
242a66d4d66SMatthew G Knepley   DM_DA            *da  = (DM_DA*) dm->data;
243a4b60ecfSMatthew G. Knepley   PetscSection      section;
24488ed4aceSMatthew G Knepley   const PetscInt    dim = da->dim;
24580800b1aSMatthew G Knepley   PetscInt          numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0};
246b2fff234SMatthew G. Knepley   PetscBT           isLeaf;
24788ed4aceSMatthew G Knepley   PetscSF           sf;
248feafbc5cSMatthew G Knepley   PetscMPIInt       rank;
24988ed4aceSMatthew G Knepley   const PetscMPIInt *neighbors;
25088ed4aceSMatthew G Knepley   PetscInt          *localPoints;
25188ed4aceSMatthew G Knepley   PetscSFNode       *remotePoints;
252f5eeb527SMatthew G Knepley   PetscInt          nleaves = 0,  nleavesCheck = 0, nL = 0;
25357459e9aSMatthew G Knepley   PetscInt          nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF;
25457459e9aSMatthew G Knepley   PetscInt          pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd;
25588ed4aceSMatthew G Knepley   PetscInt          f, v, c, xf, yf, zf, xn, yn, zn;
256a66d4d66SMatthew G Knepley   PetscErrorCode    ierr;
257a66d4d66SMatthew G Knepley 
258a66d4d66SMatthew G Knepley   PetscFunctionBegin;
259a66d4d66SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
260*e42e3c58SMatthew G. Knepley   PetscValidPointer(s, 4);
26182f516ccSBarry Smith   ierr    = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr);
262*e42e3c58SMatthew G. Knepley   ierr    = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr);
26357459e9aSMatthew G Knepley   ierr    = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr);
26457459e9aSMatthew G Knepley   ierr    = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
26557459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, -1,  &pStart, &pEnd);CHKERRQ(ierr);
26657459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, 0,   &cStart, &cEnd);CHKERRQ(ierr);
26757459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, 1,   &fStart, &fEnd);CHKERRQ(ierr);
26857459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr);
26957459e9aSMatthew G Knepley   xfStart = vEnd;  xfEnd = xfStart+nXF;
27057459e9aSMatthew G Knepley   yfStart = xfEnd; yfEnd = yfStart+nYF;
27157459e9aSMatthew G Knepley   zfStart = yfEnd; zfEnd = zfStart+nZF;
27282f516ccSBarry Smith   if (zfEnd != fEnd) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd);
27388ed4aceSMatthew G Knepley   /* Create local section */
27480800b1aSMatthew G Knepley   ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr);
275a66d4d66SMatthew G Knepley   for (f = 0; f < numFields; ++f) {
2768865f1eaSKarl Rupp     if (numVertexDof) numVertexTotDof  += numVertexDof[f];
2778865f1eaSKarl Rupp     if (numCellDof)   numCellTotDof    += numCellDof[f];
2788865f1eaSKarl Rupp     if (numFaceDof) {
2798865f1eaSKarl Rupp       numFaceTotDof[0] += numFaceDof[f*dim+0];
28088ed4aceSMatthew G Knepley       numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0;
2810ad7597dSKarl Rupp       numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0;
2820ad7597dSKarl Rupp     }
283a66d4d66SMatthew G Knepley   }
284a4b60ecfSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &section);CHKERRQ(ierr);
285a66d4d66SMatthew G Knepley   if (numFields > 1) {
286a4b60ecfSMatthew G. Knepley     ierr = PetscSectionSetNumFields(section, numFields);CHKERRQ(ierr);
287a66d4d66SMatthew G Knepley     for (f = 0; f < numFields; ++f) {
28880800b1aSMatthew G Knepley       const char *name;
28980800b1aSMatthew G Knepley 
29080800b1aSMatthew G Knepley       ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr);
291a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetFieldName(section, f, name);CHKERRQ(ierr);
29280800b1aSMatthew G Knepley       if (numComp) {
293a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldComponents(section, f, numComp[f]);CHKERRQ(ierr);
294a66d4d66SMatthew G Knepley       }
295a66d4d66SMatthew G Knepley     }
296a66d4d66SMatthew G Knepley   } else {
297a66d4d66SMatthew G Knepley     numFields = 0;
298a66d4d66SMatthew G Knepley   }
299a4b60ecfSMatthew G. Knepley   ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr);
300a66d4d66SMatthew G Knepley   if (numVertexDof) {
301a66d4d66SMatthew G Knepley     for (v = vStart; v < vEnd; ++v) {
302a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
303a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, v, f, numVertexDof[f]);CHKERRQ(ierr);
304a66d4d66SMatthew G Knepley       }
305a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, v, numVertexTotDof);CHKERRQ(ierr);
306a66d4d66SMatthew G Knepley     }
307a66d4d66SMatthew G Knepley   }
308a66d4d66SMatthew G Knepley   if (numFaceDof) {
309a66d4d66SMatthew G Knepley     for (xf = xfStart; xf < xfEnd; ++xf) {
310a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
311a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, xf, f, numFaceDof[f*dim+0]);CHKERRQ(ierr);
312a66d4d66SMatthew G Knepley       }
313a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, xf, numFaceTotDof[0]);CHKERRQ(ierr);
314a66d4d66SMatthew G Knepley     }
315a66d4d66SMatthew G Knepley     for (yf = yfStart; yf < yfEnd; ++yf) {
316a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
317a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, yf, f, numFaceDof[f*dim+1]);CHKERRQ(ierr);
318a66d4d66SMatthew G Knepley       }
319a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, yf, numFaceTotDof[1]);CHKERRQ(ierr);
320a66d4d66SMatthew G Knepley     }
321a66d4d66SMatthew G Knepley     for (zf = zfStart; zf < zfEnd; ++zf) {
322a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
323a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, zf, f, numFaceDof[f*dim+2]);CHKERRQ(ierr);
324a66d4d66SMatthew G Knepley       }
325a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, zf, numFaceTotDof[2]);CHKERRQ(ierr);
326a66d4d66SMatthew G Knepley     }
327a66d4d66SMatthew G Knepley   }
328a66d4d66SMatthew G Knepley   if (numCellDof) {
329a66d4d66SMatthew G Knepley     for (c = cStart; c < cEnd; ++c) {
330a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
331a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, c, f, numCellDof[f]);CHKERRQ(ierr);
332a66d4d66SMatthew G Knepley       }
333a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, c, numCellTotDof);CHKERRQ(ierr);
334a66d4d66SMatthew G Knepley     }
335a66d4d66SMatthew G Knepley   }
336a4b60ecfSMatthew G. Knepley   ierr = PetscSectionSetUp(section);CHKERRQ(ierr);
33788ed4aceSMatthew G Knepley   /* Create mesh point SF */
338b2fff234SMatthew G. Knepley   ierr = PetscBTCreate(pEnd-pStart, &isLeaf);CHKERRQ(ierr);
33988ed4aceSMatthew G Knepley   ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr);
34088ed4aceSMatthew G Knepley   for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
34188ed4aceSMatthew G Knepley     for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
34288ed4aceSMatthew G Knepley       for (xn = 0; xn < 3; ++xn) {
3437128ae9fSMatthew G Knepley         const PetscInt xp       = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
34488ed4aceSMatthew G Knepley         const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
345b2fff234SMatthew G. Knepley         PetscInt       xv, yv, zv;
34688ed4aceSMatthew G Knepley 
3473814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
348b2fff234SMatthew G. Knepley           if (xp < 0) { /* left */
349b2fff234SMatthew G. Knepley             if (yp < 0) { /* bottom */
350b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
351b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx +     0 + nC; /* left bottom back vertex */
352b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
353b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
354b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* left bottom front vertex */
355b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
356b2fff234SMatthew G. Knepley               } else {
357b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
358b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx +     0 + nC; /* left bottom vertices */
359b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
360b2fff234SMatthew G. Knepley                 }
361b2fff234SMatthew G. Knepley               }
362b2fff234SMatthew G. Knepley             } else if (yp > 0) { /* top */
363b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
364b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx +     0 + nC; /* left top back vertex */
365b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
366b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
367b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* left top front vertex */
368b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
369b2fff234SMatthew G. Knepley               } else {
370b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
371b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx +     0 + nC; /* left top vertices */
372b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
373b2fff234SMatthew G. Knepley                 }
374b2fff234SMatthew G. Knepley               }
375b2fff234SMatthew G. Knepley             } else {
376b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
377b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
378b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx +     0 + nC; /* left back vertices */
379b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
380b2fff234SMatthew G. Knepley                 }
381b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
382b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
383b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* left front vertices */
384b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
385b2fff234SMatthew G. Knepley                 }
386b2fff234SMatthew G. Knepley               } else {
387b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
388b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
389b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx +     0 + nC; /* left vertices */
390b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
391b2fff234SMatthew G. Knepley                   }
392b2fff234SMatthew G. Knepley                 }
393b2fff234SMatthew G. Knepley #if 0
394b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
395b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
396b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* left faces */
397b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
398b2fff234SMatthew G. Knepley                 }
399b2fff234SMatthew G. Knepley #endif
400b2fff234SMatthew G. Knepley               }
401b2fff234SMatthew G. Knepley             }
402b2fff234SMatthew G. Knepley           } else if (xp > 0) { /* right */
403b2fff234SMatthew G. Knepley             if (yp < 0) { /* bottom */
404b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
405b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx + nVx-1 + nC; /* right bottom back vertex */
406b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
407b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
408b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* right bottom front vertex */
409b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
410b2fff234SMatthew G. Knepley               } else {
411b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
412b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx + nVx-1 + nC; /* right bottom vertices */
413b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
414b2fff234SMatthew G. Knepley                 }
415b2fff234SMatthew G. Knepley               }
416b2fff234SMatthew G. Knepley             } else if (yp > 0) { /* top */
417b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
418b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */
419b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
420b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
421b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */
422b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
423b2fff234SMatthew G. Knepley               } else {
424b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
425b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */
426b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
427b2fff234SMatthew G. Knepley                 }
428b2fff234SMatthew G. Knepley               }
429b2fff234SMatthew G. Knepley             } else {
430b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
431b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
432b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */
433b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
434b2fff234SMatthew G. Knepley                 }
435b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
436b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
437b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */
438b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
439b2fff234SMatthew G. Knepley                 }
440b2fff234SMatthew G. Knepley               } else {
441b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
442b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
443b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */
444b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
445b2fff234SMatthew G. Knepley                   }
446b2fff234SMatthew G. Knepley                 }
447b2fff234SMatthew G. Knepley #if 0
448b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
449b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
450b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* right faces */
451b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
452b2fff234SMatthew G. Knepley                 }
453b2fff234SMatthew G. Knepley #endif
454b2fff234SMatthew G. Knepley               }
455b2fff234SMatthew G. Knepley             }
456b2fff234SMatthew G. Knepley           } else {
457b2fff234SMatthew G. Knepley             if (yp < 0) { /* bottom */
458b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
459b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
460b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy +     0)*nVx + xv + nC; /* bottom back vertices */
461b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
462b2fff234SMatthew G. Knepley                 }
463b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
464b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
465b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* bottom front vertices */
466b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
467b2fff234SMatthew G. Knepley                 }
468b2fff234SMatthew G. Knepley               } else {
469b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
470b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
471b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy +     0)*nVx + xv + nC; /* bottom vertices */
472b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
473b2fff234SMatthew G. Knepley                   }
474b2fff234SMatthew G. Knepley                 }
475b2fff234SMatthew G. Knepley #if 0
476b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
477b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
478b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* bottom faces */
479b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves;
480b2fff234SMatthew G. Knepley                 }
481b2fff234SMatthew G. Knepley #endif
482b2fff234SMatthew G. Knepley               }
483b2fff234SMatthew G. Knepley             } else if (yp > 0) { /* top */
484b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
485b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
486b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */
487b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
488b2fff234SMatthew G. Knepley                 }
489b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
490b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
491b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */
492b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
493b2fff234SMatthew G. Knepley                 }
494b2fff234SMatthew G. Knepley               } else {
495b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
496b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
497b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */
498b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
499b2fff234SMatthew G. Knepley                   }
500b2fff234SMatthew G. Knepley                 }
501b2fff234SMatthew G. Knepley #if 0
502b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
503b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
504b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* top faces */
505b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVFace)) ++nleaves;
506b2fff234SMatthew G. Knepley                 }
507b2fff234SMatthew G. Knepley #endif
508b2fff234SMatthew G. Knepley               }
509b2fff234SMatthew G. Knepley             } else {
510b2fff234SMatthew G. Knepley               if (zp < 0) { /* back */
511b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
512b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
513b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (      0*nVy + yv)*nVx + xv + nC; /* back vertices */
514b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
515b2fff234SMatthew G. Knepley                   }
516b2fff234SMatthew G. Knepley                 }
517b2fff234SMatthew G. Knepley #if 0
518b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
519b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
520b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* back faces */
521b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
522b2fff234SMatthew G. Knepley                 }
523b2fff234SMatthew G. Knepley #endif
524b2fff234SMatthew G. Knepley               } else if (zp > 0) { /* front */
525b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
526b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
527b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */
528b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) ++nleaves;
529b2fff234SMatthew G. Knepley                   }
530b2fff234SMatthew G. Knepley                 }
531b2fff234SMatthew G. Knepley #if 0
532b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
533b2fff234SMatthew G. Knepley                   /* THIS IS WRONG */
534b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* front faces */
535b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) ++nleaves;
536b2fff234SMatthew G. Knepley                 }
537b2fff234SMatthew G. Knepley #endif
538b2fff234SMatthew G. Knepley               } else {
539b2fff234SMatthew G. Knepley                 /* Nothing is shared from the interior */
54088ed4aceSMatthew G Knepley               }
54188ed4aceSMatthew G Knepley             }
54288ed4aceSMatthew G Knepley           }
54388ed4aceSMatthew G Knepley         }
54488ed4aceSMatthew G Knepley       }
545b2fff234SMatthew G. Knepley     }
546b2fff234SMatthew G. Knepley   }
547b2fff234SMatthew G. Knepley   ierr = PetscBTMemzero(pEnd-pStart, isLeaf);CHKERRQ(ierr);
54888ed4aceSMatthew G Knepley   ierr = PetscMalloc2(nleaves,PetscInt,&localPoints,nleaves,PetscSFNode,&remotePoints);CHKERRQ(ierr);
54988ed4aceSMatthew G Knepley   for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
55088ed4aceSMatthew G Knepley     for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
55188ed4aceSMatthew G Knepley       for (xn = 0; xn < 3; ++xn) {
5527128ae9fSMatthew G Knepley         const PetscInt xp       = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
55388ed4aceSMatthew G Knepley         const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
554f5eeb527SMatthew G Knepley         PetscInt       xv, yv, zv;
55588ed4aceSMatthew G Knepley 
5563814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
55788ed4aceSMatthew G Knepley           if (xp < 0) { /* left */
55888ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
55988ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
560b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx +     0 + nC; /* left bottom back vertex */
561f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
562f5eeb527SMatthew G Knepley 
563b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
564f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
565f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
566f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
567f5eeb527SMatthew G Knepley                   ++nL;
568b2fff234SMatthew G. Knepley                 }
56988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
570b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* left bottom front vertex */
571f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
572f5eeb527SMatthew G Knepley 
573b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
574f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
575f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
576f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
577f5eeb527SMatthew G Knepley                   ++nL;
578b2fff234SMatthew G. Knepley                 }
57988ed4aceSMatthew G Knepley               } else {
580b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
581b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx +     0 + nC; /* left bottom vertices */
582f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
583f5eeb527SMatthew G Knepley 
584b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
585f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
586f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
587f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
588b2fff234SMatthew G. Knepley                     ++nL;
589b2fff234SMatthew G. Knepley                   }
590f5eeb527SMatthew G Knepley                 }
59188ed4aceSMatthew G Knepley               }
59288ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
59388ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
594b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx +     0 + nC; /* left top back vertex */
595f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
596f5eeb527SMatthew G Knepley 
597b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
598f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
599f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
600f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
601f5eeb527SMatthew G Knepley                   ++nL;
602b2fff234SMatthew G. Knepley                 }
60388ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
604b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* left top front vertex */
605f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
606f5eeb527SMatthew G Knepley 
607b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
608f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
609f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
610f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
611f5eeb527SMatthew G Knepley                   ++nL;
612b2fff234SMatthew G. Knepley                 }
61388ed4aceSMatthew G Knepley               } else {
614b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
615b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx +     0 + nC; /* left top vertices */
616f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
617f5eeb527SMatthew G Knepley 
618b2fff234SMatthew 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;
622b2fff234SMatthew G. Knepley                     ++nL;
623b2fff234SMatthew G. Knepley                   }
624f5eeb527SMatthew G Knepley                 }
62588ed4aceSMatthew G Knepley               }
62688ed4aceSMatthew G Knepley             } else {
62788ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
628b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
629b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx +     0 + nC; /* left back vertices */
630f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
631f5eeb527SMatthew G Knepley 
632b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
633f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
634f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
635f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
636b2fff234SMatthew G. Knepley                     ++nL;
637b2fff234SMatthew G. Knepley                   }
638f5eeb527SMatthew G Knepley                 }
63988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
640b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
641b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* left front vertices */
642f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
643f5eeb527SMatthew G Knepley 
644b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
645f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
646f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
647f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
648b2fff234SMatthew G. Knepley                     ++nL;
649b2fff234SMatthew G. Knepley                   }
650f5eeb527SMatthew G Knepley                 }
65188ed4aceSMatthew G Knepley               } else {
652f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
653b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
654b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx +     0 + nC; /* left vertices */
655f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
656f5eeb527SMatthew G Knepley 
657b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
658f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
659f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
660f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
661b2fff234SMatthew G. Knepley                       ++nL;
662f5eeb527SMatthew G Knepley                     }
663f5eeb527SMatthew G Knepley                   }
664b2fff234SMatthew G. Knepley                 }
665b2fff234SMatthew G. Knepley #if 0
666b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
667f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
668b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* left faces */
669f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
670f5eeb527SMatthew G Knepley 
671b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
672f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
673f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
674f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
675f5eeb527SMatthew G Knepley                   }
67688ed4aceSMatthew G Knepley                 }
677b2fff234SMatthew G. Knepley #endif
678b2fff234SMatthew G. Knepley               }
67988ed4aceSMatthew G Knepley             }
68088ed4aceSMatthew G Knepley           } else if (xp > 0) { /* right */
68188ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
68288ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
683b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx + nVx-1 + nC; /* right bottom back vertex */
684f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
685f5eeb527SMatthew G Knepley 
686b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
687f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
688f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
689f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
690f5eeb527SMatthew G Knepley                   ++nL;
691b2fff234SMatthew G. Knepley                 }
69288ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
693b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* right bottom front vertex */
694f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
695f5eeb527SMatthew G Knepley 
696b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
697f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
698f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
699f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
700f5eeb527SMatthew G Knepley                   ++nL;
701b2fff234SMatthew G. Knepley                 }
70288ed4aceSMatthew G Knepley               } else {
703b2fff234SMatthew G. Knepley                 nleavesCheck += nVz;
704b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
705b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx + nVx-1 + nC; /* right bottom vertices */
706f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
707f5eeb527SMatthew G Knepley 
708b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
709f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
710f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
711f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
712b2fff234SMatthew G. Knepley                     ++nL;
713b2fff234SMatthew G. Knepley                   }
714f5eeb527SMatthew G Knepley                 }
71588ed4aceSMatthew G Knepley               }
71688ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
71788ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
718b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top back vertex */
719f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
720f5eeb527SMatthew G Knepley 
721b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
722f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
723f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
724f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
725f5eeb527SMatthew G Knepley                   ++nL;
726b2fff234SMatthew G. Knepley                 }
72788ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
728b2fff234SMatthew G. Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top front vertex */
729f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
730f5eeb527SMatthew G Knepley 
731b2fff234SMatthew G. Knepley                 if (!PetscBTLookupSet(isLeaf, localVertex)) {
732f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
733f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
734f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
735f5eeb527SMatthew G Knepley                   ++nL;
736b2fff234SMatthew G. Knepley                 }
73788ed4aceSMatthew G Knepley               } else {
738b2fff234SMatthew G. Knepley                 for (zv = 0; zv < nVz; ++zv) {
739b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* right top vertices */
740f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
741f5eeb527SMatthew G Knepley 
742b2fff234SMatthew 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;
746b2fff234SMatthew G. Knepley                     ++nL;
747b2fff234SMatthew G. Knepley                   }
748f5eeb527SMatthew G Knepley                 }
74988ed4aceSMatthew G Knepley               }
75088ed4aceSMatthew G Knepley             } else {
75188ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
752b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
753b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx + nVx-1 + nC; /* right back vertices */
754f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
755f5eeb527SMatthew G Knepley 
756b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
757f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
758f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
759f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
760b2fff234SMatthew G. Knepley                     ++nL;
761b2fff234SMatthew G. Knepley                   }
762f5eeb527SMatthew G Knepley                 }
76388ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
764b2fff234SMatthew G. Knepley                 for (yv = 0; yv < nVy; ++yv) {
765b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* right front vertices */
766f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
767f5eeb527SMatthew G Knepley 
768b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
769f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
770f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
771f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
772b2fff234SMatthew G. Knepley                     ++nL;
773b2fff234SMatthew G. Knepley                   }
774f5eeb527SMatthew G Knepley                 }
77588ed4aceSMatthew G Knepley               } else {
776f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
777b2fff234SMatthew G. Knepley                   for (yv = 0; yv < nVy; ++yv) {
778b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx + nVx-1 + nC; /* right vertices */
779f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0     + nC; /* TODO: Correct this for neighbor sizes */
780f5eeb527SMatthew G Knepley 
781b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
782f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
783f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
784f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
785b2fff234SMatthew G. Knepley                       ++nL;
786f5eeb527SMatthew G Knepley                     }
787f5eeb527SMatthew G Knepley                   }
788b2fff234SMatthew G. Knepley                 }
789b2fff234SMatthew G. Knepley #if 0
790b2fff234SMatthew G. Knepley                 for (xf = 0; xf < nxF; ++xf) {
791f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
792b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* right faces */
793f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
794f5eeb527SMatthew G Knepley 
795b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
796f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
797f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
798f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
799b2fff234SMatthew G. Knepley                     ++nL;
800f5eeb527SMatthew G Knepley                   }
80188ed4aceSMatthew G Knepley                 }
802b2fff234SMatthew G. Knepley #endif
803b2fff234SMatthew G. Knepley               }
80488ed4aceSMatthew G Knepley             }
80588ed4aceSMatthew G Knepley           } else {
80688ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
80788ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
808b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
809b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy +     0)*nVx + xv + nC; /* bottom back vertices */
810f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
811f5eeb527SMatthew G Knepley 
812b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
813f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
814f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
815f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
816b2fff234SMatthew G. Knepley                     ++nL;
817b2fff234SMatthew G. Knepley                   }
818f5eeb527SMatthew G Knepley                 }
81988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
820b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
821b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* bottom front vertices */
822f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
823f5eeb527SMatthew G Knepley 
824b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
825f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
826f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
827f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
828b2fff234SMatthew G. Knepley                     ++nL;
829b2fff234SMatthew G. Knepley                   }
830f5eeb527SMatthew G Knepley                 }
83188ed4aceSMatthew G Knepley               } else {
832f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
833b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
834b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy +     0)*nVx + xv + nC; /* bottom vertices */
835f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
836f5eeb527SMatthew G Knepley 
837b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
838f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
839f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
840f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
841b2fff234SMatthew G. Knepley                       ++nL;
842f5eeb527SMatthew G Knepley                     }
843f5eeb527SMatthew G Knepley                   }
844b2fff234SMatthew G. Knepley                 }
845b2fff234SMatthew G. Knepley #if 0
846b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
847f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
848b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* bottom faces */
849f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
850f5eeb527SMatthew G Knepley 
851b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
852f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
853f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
854f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
855b2fff234SMatthew G. Knepley                     ++nL;
856f5eeb527SMatthew G Knepley                   }
85788ed4aceSMatthew G Knepley                 }
858b2fff234SMatthew G. Knepley #endif
859b2fff234SMatthew G. Knepley               }
86088ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
86188ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
862b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
863b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + xv + nC; /* top back vertices */
864f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
865f5eeb527SMatthew G Knepley 
866b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
867f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
868f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
869f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
870b2fff234SMatthew G. Knepley                     ++nL;
871b2fff234SMatthew G. Knepley                   }
872f5eeb527SMatthew G Knepley                 }
87388ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
874b2fff234SMatthew G. Knepley                 for (xv = 0; xv < nVx; ++xv) {
875b2fff234SMatthew G. Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* top front vertices */
876f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
877f5eeb527SMatthew G Knepley 
878b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localVertex)) {
879f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
880f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
881f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
882b2fff234SMatthew G. Knepley                     ++nL;
883b2fff234SMatthew G. Knepley                   }
884f5eeb527SMatthew G Knepley                 }
88588ed4aceSMatthew G Knepley               } else {
886f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
887b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
888b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + xv + nC; /* top vertices */
889f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
890f5eeb527SMatthew G Knepley 
891b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
892f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
893f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
894f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
895b2fff234SMatthew G. Knepley                       ++nL;
896f5eeb527SMatthew G Knepley                     }
897f5eeb527SMatthew G Knepley                   }
898b2fff234SMatthew G. Knepley                 }
899b2fff234SMatthew G. Knepley #if 0
900b2fff234SMatthew G. Knepley                 for (yf = 0; yf < nyF; ++yf) {
901f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
902b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* top faces */
903f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
904f5eeb527SMatthew G Knepley 
905b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
906f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
907f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
908f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
909b2fff234SMatthew G. Knepley                     ++nL;
910f5eeb527SMatthew G Knepley                   }
91188ed4aceSMatthew G Knepley                 }
912b2fff234SMatthew G. Knepley #endif
913b2fff234SMatthew G. Knepley               }
91488ed4aceSMatthew G Knepley             } else {
91588ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
916f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv) {
917b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
918b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = (      0*nVy + yv)*nVx + xv + nC; /* back vertices */
919f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
920f5eeb527SMatthew G Knepley 
921b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
922f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
923f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
924f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
925b2fff234SMatthew G. Knepley                       ++nL;
926f5eeb527SMatthew G Knepley                     }
927f5eeb527SMatthew G Knepley                   }
928b2fff234SMatthew G. Knepley                 }
929b2fff234SMatthew G. Knepley #if 0
930b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
931f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
932b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* back faces */
933f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
934f5eeb527SMatthew G Knepley 
935b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
936f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
937f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
938f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
939b2fff234SMatthew G. Knepley                     ++nL;
940f5eeb527SMatthew G Knepley                   }
941b2fff234SMatthew G. Knepley                 }
942b2fff234SMatthew G. Knepley #endif
94388ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
944f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv) {
945b2fff234SMatthew G. Knepley                   for (xv = 0; xv < nVx; ++xv) {
946b2fff234SMatthew G. Knepley                     const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* front vertices */
947f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (      0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
948f5eeb527SMatthew G Knepley 
949b2fff234SMatthew G. Knepley                     if (!PetscBTLookupSet(isLeaf, localVertex)) {
950f5eeb527SMatthew G Knepley                       localPoints[nL]        = localVertex;
951f5eeb527SMatthew G Knepley                       remotePoints[nL].rank  = neighbor;
952f5eeb527SMatthew G Knepley                       remotePoints[nL].index = remoteVertex;
953b2fff234SMatthew G. Knepley                       ++nL;
954f5eeb527SMatthew G Knepley                     }
955f5eeb527SMatthew G Knepley                   }
956b2fff234SMatthew G. Knepley                 }
957b2fff234SMatthew G. Knepley #if 0
958b2fff234SMatthew G. Knepley                 for (zf = 0; zf < nzF; ++zf) {
959f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
960b2fff234SMatthew G. Knepley                   const PetscInt localFace  = 0 + nC+nV; /* front faces */
961f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
962f5eeb527SMatthew G Knepley 
963b2fff234SMatthew G. Knepley                   if (!PetscBTLookupSet(isLeaf, localFace)) {
964f5eeb527SMatthew G Knepley                     localPoints[nL]        = localFace;
965f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
966f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteFace;
967b2fff234SMatthew G. Knepley                     ++nL;
968f5eeb527SMatthew G Knepley                   }
969b2fff234SMatthew G. Knepley                 }
970b2fff234SMatthew G. Knepley #endif
97188ed4aceSMatthew G Knepley               } else {
97288ed4aceSMatthew G Knepley                 /* Nothing is shared from the interior */
97388ed4aceSMatthew G Knepley               }
97488ed4aceSMatthew G Knepley             }
97588ed4aceSMatthew G Knepley           }
97688ed4aceSMatthew G Knepley         }
97788ed4aceSMatthew G Knepley       }
97888ed4aceSMatthew G Knepley     }
97988ed4aceSMatthew G Knepley   }
980b2fff234SMatthew G. Knepley   ierr = PetscBTDestroy(&isLeaf);CHKERRQ(ierr);
981b2fff234SMatthew G. Knepley   /* Remove duplication in leaf determination */
982b2fff234SMatthew 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);
98382f516ccSBarry Smith   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), &sf);CHKERRQ(ierr);
98488ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr);
985a4b60ecfSMatthew G. Knepley   ierr = DMSetPointSF(dm, sf);CHKERRQ(ierr);
98688ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&sf);CHKERRQ(ierr);
987a4b60ecfSMatthew G. Knepley   ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr);
988a4b60ecfSMatthew G. Knepley   ierr = PetscSectionDestroy(&section);CHKERRQ(ierr);
989a66d4d66SMatthew G Knepley   PetscFunctionReturn(0);
990a66d4d66SMatthew G Knepley }
991a66d4d66SMatthew G Knepley 
99247c6ae99SBarry Smith /* ------------------------------------------------------------------- */
99347c6ae99SBarry Smith 
99447c6ae99SBarry Smith #undef __FUNCT__
995aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
99647c6ae99SBarry Smith /*@C
997aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
99847c6ae99SBarry Smith 
99947c6ae99SBarry Smith     Input Parameter:
100047c6ae99SBarry Smith +    da - information about my local patch
100147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
100247c6ae99SBarry Smith 
100347c6ae99SBarry Smith     Output Parameters:
100447c6ae99SBarry Smith .    vptr - array data structured
100547c6ae99SBarry Smith 
100647c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
100747c6ae99SBarry Smith            to zero them.
100847c6ae99SBarry Smith 
100947c6ae99SBarry Smith   Level: advanced
101047c6ae99SBarry Smith 
1011bcaeba4dSBarry Smith .seealso: DMDARestoreArray()
101247c6ae99SBarry Smith 
101347c6ae99SBarry Smith @*/
10147087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool ghosted,void *vptr)
101547c6ae99SBarry Smith {
101647c6ae99SBarry Smith   PetscErrorCode ierr;
101747c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
101847c6ae99SBarry Smith   char           *iarray_start;
101947c6ae99SBarry Smith   void           **iptr = (void**)vptr;
102047c6ae99SBarry Smith   DM_DA          *dd    = (DM_DA*)da->data;
102147c6ae99SBarry Smith 
102247c6ae99SBarry Smith   PetscFunctionBegin;
102347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
102447c6ae99SBarry Smith   if (ghosted) {
1025aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
102647c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
102747c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
102847c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
10290298fd71SBarry Smith         dd->arrayghostedin[i] = NULL;
10300298fd71SBarry Smith         dd->startghostedin[i] = NULL;
103147c6ae99SBarry Smith 
103247c6ae99SBarry Smith         goto done;
103347c6ae99SBarry Smith       }
103447c6ae99SBarry Smith     }
103547c6ae99SBarry Smith     xs = dd->Xs;
103647c6ae99SBarry Smith     ys = dd->Ys;
103747c6ae99SBarry Smith     zs = dd->Zs;
103847c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
103947c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
104047c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
104147c6ae99SBarry Smith   } else {
1042aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
104347c6ae99SBarry Smith       if (dd->arrayin[i]) {
104447c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
104547c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
10460298fd71SBarry Smith         dd->arrayin[i] = NULL;
10470298fd71SBarry Smith         dd->startin[i] = NULL;
104847c6ae99SBarry Smith 
104947c6ae99SBarry Smith         goto done;
105047c6ae99SBarry Smith       }
105147c6ae99SBarry Smith     }
105247c6ae99SBarry Smith     xs = dd->xs;
105347c6ae99SBarry Smith     ys = dd->ys;
105447c6ae99SBarry Smith     zs = dd->zs;
105547c6ae99SBarry Smith     xm = dd->xe-dd->xs;
105647c6ae99SBarry Smith     ym = dd->ye-dd->ys;
105747c6ae99SBarry Smith     zm = dd->ze-dd->zs;
105847c6ae99SBarry Smith   }
105947c6ae99SBarry Smith 
106047c6ae99SBarry Smith   switch (dd->dim) {
106147c6ae99SBarry Smith   case 1: {
106247c6ae99SBarry Smith     void *ptr;
106347c6ae99SBarry Smith 
106447c6ae99SBarry Smith     ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
106547c6ae99SBarry Smith 
106647c6ae99SBarry Smith     ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
106747c6ae99SBarry Smith     *iptr = (void*)ptr;
10688865f1eaSKarl Rupp     break;
10698865f1eaSKarl Rupp   }
107047c6ae99SBarry Smith   case 2: {
107147c6ae99SBarry Smith     void **ptr;
107247c6ae99SBarry Smith 
107347c6ae99SBarry Smith     ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
107447c6ae99SBarry Smith 
107547c6ae99SBarry Smith     ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
10768865f1eaSKarl Rupp     for (j=ys; j<ys+ym; j++) ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
107747c6ae99SBarry Smith     *iptr = (void*)ptr;
10788865f1eaSKarl Rupp     break;
10798865f1eaSKarl Rupp   }
108047c6ae99SBarry Smith   case 3: {
108147c6ae99SBarry Smith     void ***ptr,**bptr;
108247c6ae99SBarry Smith 
108347c6ae99SBarry Smith     ierr = PetscMalloc((zm+1)*sizeof(void**)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
108447c6ae99SBarry Smith 
108547c6ae99SBarry Smith     ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
108647c6ae99SBarry Smith     bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
10878865f1eaSKarl Rupp     for (i=zs; i<zs+zm; i++) ptr[i] = bptr + ((i-zs)*ym - ys);
108847c6ae99SBarry Smith     for (i=zs; i<zs+zm; i++) {
108947c6ae99SBarry Smith       for (j=ys; j<ys+ym; j++) {
109047c6ae99SBarry Smith         ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
109147c6ae99SBarry Smith       }
109247c6ae99SBarry Smith     }
109347c6ae99SBarry Smith     *iptr = (void*)ptr;
10948865f1eaSKarl Rupp     break;
10958865f1eaSKarl Rupp   }
109647c6ae99SBarry Smith   default:
1097ce94432eSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
109847c6ae99SBarry Smith   }
109947c6ae99SBarry Smith 
110047c6ae99SBarry Smith done:
110147c6ae99SBarry Smith   /* add arrays to the checked out list */
110247c6ae99SBarry Smith   if (ghosted) {
1103aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
110447c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
110547c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr;
110647c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
110747c6ae99SBarry Smith         break;
110847c6ae99SBarry Smith       }
110947c6ae99SBarry Smith     }
111047c6ae99SBarry Smith   } else {
1111aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
111247c6ae99SBarry Smith       if (!dd->arrayout[i]) {
111347c6ae99SBarry Smith         dd->arrayout[i] = *iptr;
111447c6ae99SBarry Smith         dd->startout[i] = iarray_start;
111547c6ae99SBarry Smith         break;
111647c6ae99SBarry Smith       }
111747c6ae99SBarry Smith     }
111847c6ae99SBarry Smith   }
111947c6ae99SBarry Smith   PetscFunctionReturn(0);
112047c6ae99SBarry Smith }
112147c6ae99SBarry Smith 
112247c6ae99SBarry Smith #undef __FUNCT__
1123aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
112447c6ae99SBarry Smith /*@C
1125aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
112647c6ae99SBarry Smith 
112747c6ae99SBarry Smith     Input Parameter:
112847c6ae99SBarry Smith +    da - information about my local patch
112947c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
113047c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
113147c6ae99SBarry Smith 
113247c6ae99SBarry Smith      Level: advanced
113347c6ae99SBarry Smith 
1134bcaeba4dSBarry Smith .seealso: DMDAGetArray()
113547c6ae99SBarry Smith 
113647c6ae99SBarry Smith @*/
11377087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool ghosted,void *vptr)
113847c6ae99SBarry Smith {
113947c6ae99SBarry Smith   PetscInt i;
114047c6ae99SBarry Smith   void     **iptr = (void**)vptr,*iarray_start = 0;
114147c6ae99SBarry Smith   DM_DA    *dd    = (DM_DA*)da->data;
114247c6ae99SBarry Smith 
114347c6ae99SBarry Smith   PetscFunctionBegin;
114447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
114547c6ae99SBarry Smith   if (ghosted) {
1146aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
114747c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
114847c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
11490298fd71SBarry Smith         dd->arrayghostedout[i] = NULL;
11500298fd71SBarry Smith         dd->startghostedout[i] = NULL;
115147c6ae99SBarry Smith         break;
115247c6ae99SBarry Smith       }
115347c6ae99SBarry Smith     }
1154aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
115547c6ae99SBarry Smith       if (!dd->arrayghostedin[i]) {
115647c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
115747c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
115847c6ae99SBarry Smith         break;
115947c6ae99SBarry Smith       }
116047c6ae99SBarry Smith     }
116147c6ae99SBarry Smith   } else {
1162aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
116347c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
116447c6ae99SBarry Smith         iarray_start    = dd->startout[i];
11650298fd71SBarry Smith         dd->arrayout[i] = NULL;
11660298fd71SBarry Smith         dd->startout[i] = NULL;
116747c6ae99SBarry Smith         break;
116847c6ae99SBarry Smith       }
116947c6ae99SBarry Smith     }
1170aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
117147c6ae99SBarry Smith       if (!dd->arrayin[i]) {
117247c6ae99SBarry Smith         dd->arrayin[i] = *iptr;
117347c6ae99SBarry Smith         dd->startin[i] = iarray_start;
117447c6ae99SBarry Smith         break;
117547c6ae99SBarry Smith       }
117647c6ae99SBarry Smith     }
117747c6ae99SBarry Smith   }
117847c6ae99SBarry Smith   PetscFunctionReturn(0);
117947c6ae99SBarry Smith }
118047c6ae99SBarry Smith 
1181