xref: /petsc/src/dm/impls/da/dalocal.c (revision 3385ff7e2d1212a0f59ed2e0b7938fe2031de2c1)
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*/
70c312b8eSJed Brown #include <petscsf.h>
847c6ae99SBarry Smith 
947c6ae99SBarry Smith /*
10e3c5b3baSBarry Smith    This allows the DMDA vectors to properly tell MATLAB their dimensions
1147c6ae99SBarry Smith */
1247c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
13c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
14c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
1547c6ae99SBarry Smith #undef __FUNCT__
1647c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d"
171e6b0712SBarry Smith static PetscErrorCode  VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine)
1847c6ae99SBarry Smith {
1947c6ae99SBarry Smith   PetscErrorCode ierr;
2047c6ae99SBarry Smith   PetscInt       n,m;
2147c6ae99SBarry Smith   Vec            vec = (Vec)obj;
2247c6ae99SBarry Smith   PetscScalar    *array;
2347c6ae99SBarry Smith   mxArray        *mat;
249a42bb27SBarry Smith   DM             da;
2547c6ae99SBarry Smith 
2647c6ae99SBarry Smith   PetscFunctionBegin;
27c688c046SMatthew G Knepley   ierr = VecGetDM(vec, &da);CHKERRQ(ierr);
28ce94432eSBarry Smith   if (!da) SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA");
29aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr);
3047c6ae99SBarry Smith 
3147c6ae99SBarry Smith   ierr = VecGetArray(vec,&array);CHKERRQ(ierr);
3247c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
3347c6ae99SBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxREAL);
3447c6ae99SBarry Smith #else
3547c6ae99SBarry Smith   mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3647c6ae99SBarry Smith #endif
3747c6ae99SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr);
3847c6ae99SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
3947c6ae99SBarry Smith   engPutVariable((Engine*)mengine,obj->name,mat);
4047c6ae99SBarry Smith 
4147c6ae99SBarry Smith   ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr);
4247c6ae99SBarry Smith   PetscFunctionReturn(0);
4347c6ae99SBarry Smith }
4447c6ae99SBarry Smith #endif
4547c6ae99SBarry Smith 
4647c6ae99SBarry Smith 
4747c6ae99SBarry Smith #undef __FUNCT__
48564755cdSBarry Smith #define __FUNCT__ "DMCreateLocalVector_DA"
497087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_DA(DM da,Vec *g)
5047c6ae99SBarry Smith {
5147c6ae99SBarry Smith   PetscErrorCode ierr;
5247c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
5347c6ae99SBarry Smith 
5447c6ae99SBarry Smith   PetscFunctionBegin;
5547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
5647c6ae99SBarry Smith   PetscValidPointer(g,2);
5711689aebSJed Brown   if (da->defaultSection) {
5811689aebSJed Brown     ierr = DMCreateLocalVector_Section_Private(da,g);CHKERRQ(ierr);
5911689aebSJed Brown   } else {
6047c6ae99SBarry Smith     ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr);
6147c6ae99SBarry Smith     ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
6247c6ae99SBarry Smith     ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
63401ddaa8SBarry Smith     ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
64c688c046SMatthew G Knepley     ierr = VecSetDM(*g, da);CHKERRQ(ierr);
6547c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
6647c6ae99SBarry Smith     if (dd->w == 1  && dd->dim == 2) {
67bdf89e91SBarry Smith       ierr = PetscObjectComposeFunction((PetscObject)*g,"PetscMatlabEnginePut_C",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
6847c6ae99SBarry Smith     }
6947c6ae99SBarry Smith #endif
7011689aebSJed Brown   }
7147c6ae99SBarry Smith   PetscFunctionReturn(0);
7247c6ae99SBarry Smith }
7347c6ae99SBarry Smith 
74a66d4d66SMatthew G Knepley #undef __FUNCT__
7557459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumCells"
763582350cSMatthew G. Knepley PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCellsX, PetscInt *numCellsY, PetscInt *numCellsZ, PetscInt *numCells)
7757459e9aSMatthew G Knepley {
7857459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
7957459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
8057459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
8157459e9aSMatthew G Knepley   const PetscInt nC  = (mx)*(dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1);
8257459e9aSMatthew G Knepley 
8357459e9aSMatthew G Knepley   PetscFunctionBegin;
843582350cSMatthew G. Knepley   if (numCellsX) {
853582350cSMatthew G. Knepley     PetscValidIntPointer(numCellsX,2);
863582350cSMatthew G. Knepley     *numCellsX = mx;
873582350cSMatthew G. Knepley   }
883582350cSMatthew G. Knepley   if (numCellsY) {
893582350cSMatthew G. Knepley     PetscValidIntPointer(numCellsX,3);
903582350cSMatthew G. Knepley     *numCellsY = my;
913582350cSMatthew G. Knepley   }
923582350cSMatthew G. Knepley   if (numCellsZ) {
933582350cSMatthew G. Knepley     PetscValidIntPointer(numCellsX,4);
943582350cSMatthew G. Knepley     *numCellsZ = mz;
953582350cSMatthew G. Knepley   }
9657459e9aSMatthew G Knepley   if (numCells) {
973582350cSMatthew G. Knepley     PetscValidIntPointer(numCells,5);
9857459e9aSMatthew G Knepley     *numCells = nC;
9957459e9aSMatthew G Knepley   }
10057459e9aSMatthew G Knepley   PetscFunctionReturn(0);
10157459e9aSMatthew G Knepley }
10257459e9aSMatthew G Knepley 
10357459e9aSMatthew G Knepley #undef __FUNCT__
10457459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumVertices"
10557459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices)
10657459e9aSMatthew G Knepley {
10757459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
10857459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
10957459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
11057459e9aSMatthew G Knepley   const PetscInt nVx = mx+1;
11157459e9aSMatthew G Knepley   const PetscInt nVy = dim > 1 ? (my+1) : 1;
11257459e9aSMatthew G Knepley   const PetscInt nVz = dim > 2 ? (mz+1) : 1;
11357459e9aSMatthew G Knepley   const PetscInt nV  = nVx*nVy*nVz;
11457459e9aSMatthew G Knepley 
11557459e9aSMatthew G Knepley   PetscFunctionBegin;
11657459e9aSMatthew G Knepley   if (numVerticesX) {
11757459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesX,2);
11857459e9aSMatthew G Knepley     *numVerticesX = nVx;
11957459e9aSMatthew G Knepley   }
12057459e9aSMatthew G Knepley   if (numVerticesY) {
12157459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesY,3);
12257459e9aSMatthew G Knepley     *numVerticesY = nVy;
12357459e9aSMatthew G Knepley   }
12457459e9aSMatthew G Knepley   if (numVerticesZ) {
12557459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesZ,4);
12657459e9aSMatthew G Knepley     *numVerticesZ = nVz;
12757459e9aSMatthew G Knepley   }
12857459e9aSMatthew G Knepley   if (numVertices) {
12957459e9aSMatthew G Knepley     PetscValidIntPointer(numVertices,5);
13057459e9aSMatthew G Knepley     *numVertices = nV;
13157459e9aSMatthew G Knepley   }
13257459e9aSMatthew G Knepley   PetscFunctionReturn(0);
13357459e9aSMatthew G Knepley }
13457459e9aSMatthew G Knepley 
13557459e9aSMatthew G Knepley #undef __FUNCT__
13657459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumFaces"
13757459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces)
13857459e9aSMatthew G Knepley {
13957459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
14057459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
14157459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
14257459e9aSMatthew G Knepley   const PetscInt nxF = (dim > 1 ? (my)*(dim > 2 ? (mz) : 1) : 1);
14357459e9aSMatthew G Knepley   const PetscInt nXF = (mx+1)*nxF;
14457459e9aSMatthew G Knepley   const PetscInt nyF = mx*(dim > 2 ? mz : 1);
14557459e9aSMatthew G Knepley   const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0;
14657459e9aSMatthew G Knepley   const PetscInt nzF = mx*(dim > 1 ? my : 0);
14757459e9aSMatthew G Knepley   const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0;
14857459e9aSMatthew G Knepley 
14957459e9aSMatthew G Knepley   PetscFunctionBegin;
15057459e9aSMatthew G Knepley   if (numXFacesX) {
15157459e9aSMatthew G Knepley     PetscValidIntPointer(numXFacesX,2);
15257459e9aSMatthew G Knepley     *numXFacesX = nxF;
15357459e9aSMatthew G Knepley   }
15457459e9aSMatthew G Knepley   if (numXFaces) {
15557459e9aSMatthew G Knepley     PetscValidIntPointer(numXFaces,3);
15657459e9aSMatthew G Knepley     *numXFaces = nXF;
15757459e9aSMatthew G Knepley   }
15857459e9aSMatthew G Knepley   if (numYFacesY) {
15957459e9aSMatthew G Knepley     PetscValidIntPointer(numYFacesY,4);
16057459e9aSMatthew G Knepley     *numYFacesY = nyF;
16157459e9aSMatthew G Knepley   }
16257459e9aSMatthew G Knepley   if (numYFaces) {
16357459e9aSMatthew G Knepley     PetscValidIntPointer(numYFaces,5);
16457459e9aSMatthew G Knepley     *numYFaces = nYF;
16557459e9aSMatthew G Knepley   }
16657459e9aSMatthew G Knepley   if (numZFacesZ) {
16757459e9aSMatthew G Knepley     PetscValidIntPointer(numZFacesZ,6);
16857459e9aSMatthew G Knepley     *numZFacesZ = nzF;
16957459e9aSMatthew G Knepley   }
17057459e9aSMatthew G Knepley   if (numZFaces) {
17157459e9aSMatthew G Knepley     PetscValidIntPointer(numZFaces,7);
17257459e9aSMatthew G Knepley     *numZFaces = nZF;
17357459e9aSMatthew G Knepley   }
17457459e9aSMatthew G Knepley   PetscFunctionReturn(0);
17557459e9aSMatthew G Knepley }
17657459e9aSMatthew G Knepley 
17757459e9aSMatthew G Knepley #undef __FUNCT__
17857459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetHeightStratum"
17957459e9aSMatthew G Knepley PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd)
18057459e9aSMatthew G Knepley {
18157459e9aSMatthew G Knepley   DM_DA          *da = (DM_DA*) dm->data;
18257459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
18357459e9aSMatthew G Knepley   PetscInt       nC, nV, nXF, nYF, nZF;
18457459e9aSMatthew G Knepley   PetscErrorCode ierr;
18557459e9aSMatthew G Knepley 
18657459e9aSMatthew G Knepley   PetscFunctionBegin;
1878865f1eaSKarl Rupp   if (pStart) PetscValidIntPointer(pStart,3);
1888865f1eaSKarl Rupp   if (pEnd)   PetscValidIntPointer(pEnd,4);
1893582350cSMatthew G. Knepley   ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr);
1900298fd71SBarry Smith   ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr);
1910298fd71SBarry Smith   ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr);
19257459e9aSMatthew G Knepley   if (height == 0) {
19357459e9aSMatthew G Knepley     /* Cells */
1948865f1eaSKarl Rupp     if (pStart) *pStart = 0;
1958865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC;
19657459e9aSMatthew G Knepley   } else if (height == 1) {
19757459e9aSMatthew G Knepley     /* Faces */
1988865f1eaSKarl Rupp     if (pStart) *pStart = nC+nV;
1998865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
20057459e9aSMatthew G Knepley   } else if (height == dim) {
20157459e9aSMatthew G Knepley     /* Vertices */
2028865f1eaSKarl Rupp     if (pStart) *pStart = nC;
2038865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV;
20457459e9aSMatthew G Knepley   } else if (height < 0) {
20557459e9aSMatthew G Knepley     /* All points */
2068865f1eaSKarl Rupp     if (pStart) *pStart = 0;
2078865f1eaSKarl Rupp     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
20882f516ccSBarry Smith   } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height);
20957459e9aSMatthew G Knepley   PetscFunctionReturn(0);
21057459e9aSMatthew G Knepley }
21157459e9aSMatthew G Knepley 
21257459e9aSMatthew G Knepley #undef __FUNCT__
213*3385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDAGetDepthStratum"
214*3385ff7eSMatthew G. Knepley PetscErrorCode DMDAGetDepthStratum(DM dm, PetscInt depth, PetscInt *pStart, PetscInt *pEnd)
215*3385ff7eSMatthew G. Knepley {
216*3385ff7eSMatthew G. Knepley   DM_DA         *da  = (DM_DA*) dm->data;
217*3385ff7eSMatthew G. Knepley   const PetscInt dim = da->dim;
218*3385ff7eSMatthew G. Knepley   PetscInt       nC, nV, nXF, nYF, nZF;
219*3385ff7eSMatthew G. Knepley   PetscErrorCode ierr;
220*3385ff7eSMatthew G. Knepley 
221*3385ff7eSMatthew G. Knepley   PetscFunctionBegin;
222*3385ff7eSMatthew G. Knepley   if (pStart) PetscValidIntPointer(pStart,3);
223*3385ff7eSMatthew G. Knepley   if (pEnd)   PetscValidIntPointer(pEnd,4);
224*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr);
225*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr);
226*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr);
227*3385ff7eSMatthew G. Knepley   if (depth == dim) {
228*3385ff7eSMatthew G. Knepley     /* Cells */
229*3385ff7eSMatthew G. Knepley     if (pStart) *pStart = 0;
230*3385ff7eSMatthew G. Knepley     if (pEnd)   *pEnd   = nC;
231*3385ff7eSMatthew G. Knepley   } else if (depth == dim-1) {
232*3385ff7eSMatthew G. Knepley     /* Faces */
233*3385ff7eSMatthew G. Knepley     if (pStart) *pStart = nC+nV;
234*3385ff7eSMatthew G. Knepley     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
235*3385ff7eSMatthew G. Knepley   } else if (depth == 0) {
236*3385ff7eSMatthew G. Knepley     /* Vertices */
237*3385ff7eSMatthew G. Knepley     if (pStart) *pStart = nC;
238*3385ff7eSMatthew G. Knepley     if (pEnd)   *pEnd   = nC+nV;
239*3385ff7eSMatthew G. Knepley   } else if (depth < 0) {
240*3385ff7eSMatthew G. Knepley     /* All points */
241*3385ff7eSMatthew G. Knepley     if (pStart) *pStart = 0;
242*3385ff7eSMatthew G. Knepley     if (pEnd)   *pEnd   = nC+nV+nXF+nYF+nZF;
243*3385ff7eSMatthew G. Knepley   } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No points of depth %d in the DA", depth);
244*3385ff7eSMatthew G. Knepley   PetscFunctionReturn(0);
245*3385ff7eSMatthew G. Knepley }
246*3385ff7eSMatthew G. Knepley 
247*3385ff7eSMatthew G. Knepley #undef __FUNCT__
248*3385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDAGetConeSize"
249*3385ff7eSMatthew G. Knepley PetscErrorCode DMDAGetConeSize(DM dm, PetscInt p, PetscInt *coneSize)
250*3385ff7eSMatthew G. Knepley {
251*3385ff7eSMatthew G. Knepley   DM_DA         *da  = (DM_DA*) dm->data;
252*3385ff7eSMatthew G. Knepley   const PetscInt dim = da->dim;
253*3385ff7eSMatthew G. Knepley   PetscInt       nC, nV, nXF, nYF, nZF;
254*3385ff7eSMatthew G. Knepley   PetscErrorCode ierr;
255*3385ff7eSMatthew G. Knepley 
256*3385ff7eSMatthew G. Knepley   PetscFunctionBegin;
257*3385ff7eSMatthew G. Knepley   *coneSize = 0;
258*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr);
259*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumVertices(dm, NULL, NULL, NULL, &nV);CHKERRQ(ierr);
260*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumFaces(dm, NULL, &nXF, NULL, &nYF, NULL, &nZF);CHKERRQ(ierr);
261*3385ff7eSMatthew G. Knepley   switch (dim) {
262*3385ff7eSMatthew G. Knepley   case 2:
263*3385ff7eSMatthew G. Knepley     if (p >= 0) {
264*3385ff7eSMatthew G. Knepley       if (p < nC) {
265*3385ff7eSMatthew G. Knepley         *coneSize = 4;
266*3385ff7eSMatthew G. Knepley       } else if (p < nC+nV) {
267*3385ff7eSMatthew G. Knepley         *coneSize = 0;
268*3385ff7eSMatthew G. Knepley       } else if (p < nC+nV+nXF+nYF+nZF) {
269*3385ff7eSMatthew G. Knepley         *coneSize = 2;
270*3385ff7eSMatthew G. Knepley       } else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d should be in [0, %d)", p, nC+nV+nXF+nYF+nZF);
271*3385ff7eSMatthew G. Knepley     } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative point %d is invalid", p);
272*3385ff7eSMatthew G. Knepley     break;
273*3385ff7eSMatthew G. Knepley   case 3:
274*3385ff7eSMatthew G. Knepley     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do 3D");
275*3385ff7eSMatthew G. Knepley     break;
276*3385ff7eSMatthew G. Knepley   }
277*3385ff7eSMatthew G. Knepley   PetscFunctionReturn(0);
278*3385ff7eSMatthew G. Knepley }
279*3385ff7eSMatthew G. Knepley 
280*3385ff7eSMatthew G. Knepley #undef __FUNCT__
281*3385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDAGetCone"
282*3385ff7eSMatthew G. Knepley PetscErrorCode DMDAGetCone(DM dm, PetscInt p, PetscInt *cone[])
283*3385ff7eSMatthew G. Knepley {
284*3385ff7eSMatthew G. Knepley   DM_DA         *da  = (DM_DA*) dm->data;
285*3385ff7eSMatthew G. Knepley   const PetscInt dim = da->dim;
286*3385ff7eSMatthew G. Knepley   PetscInt       nCx, nCy, nCz, nC, nVx, nVy, nVz, nV, nxF, nyF, nzF, nXF, nYF, nZF;
287*3385ff7eSMatthew G. Knepley   PetscErrorCode ierr;
288*3385ff7eSMatthew G. Knepley 
289*3385ff7eSMatthew G. Knepley   PetscFunctionBegin;
290*3385ff7eSMatthew G. Knepley   if (!cone) {ierr = DMGetWorkArray(dm, 6, PETSC_INT, cone);CHKERRQ(ierr);}
291*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumCells(dm, &nCx, &nCy, &nCz, &nC);CHKERRQ(ierr);
292*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr);
293*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
294*3385ff7eSMatthew G. Knepley   switch (dim) {
295*3385ff7eSMatthew G. Knepley   case 2:
296*3385ff7eSMatthew G. Knepley     if (p >= 0) {
297*3385ff7eSMatthew G. Knepley       if (p < nC) {
298*3385ff7eSMatthew G. Knepley         const PetscInt cy = p / nCx;
299*3385ff7eSMatthew G. Knepley         const PetscInt cx = p % nCx;
300*3385ff7eSMatthew G. Knepley 
301*3385ff7eSMatthew G. Knepley         (*cone)[0] = cy*nxF + cx + nC+nV;
302*3385ff7eSMatthew G. Knepley         (*cone)[1] = cx*nyF + cy + nyF + nC+nV+nXF;
303*3385ff7eSMatthew G. Knepley         (*cone)[2] = cy*nxF + cx + nxF + nC+nV;
304*3385ff7eSMatthew G. Knepley         (*cone)[3] = cx*nyF + cy + nC+nV+nXF;
305*3385ff7eSMatthew G. Knepley         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do cell cones");
306*3385ff7eSMatthew G. Knepley       } else if (p < nC+nV) {
307*3385ff7eSMatthew G. Knepley       } else if (p < nC+nV+nXF) {
308*3385ff7eSMatthew G. Knepley         const PetscInt fy = (p - nC+nV) / nxF;
309*3385ff7eSMatthew G. Knepley         const PetscInt fx = (p - nC+nV) % nxF;
310*3385ff7eSMatthew G. Knepley 
311*3385ff7eSMatthew G. Knepley         (*cone)[0] = fy*nVx + fx + nC;
312*3385ff7eSMatthew G. Knepley         (*cone)[1] = fy*nVx + fx + 1 + nC;
313*3385ff7eSMatthew G. Knepley       } else if (p < nC+nV+nXF+nYF) {
314*3385ff7eSMatthew G. Knepley         const PetscInt fx = (p - nC+nV+nXF) / nyF;
315*3385ff7eSMatthew G. Knepley         const PetscInt fy = (p - nC+nV+nXF) % nyF;
316*3385ff7eSMatthew G. Knepley 
317*3385ff7eSMatthew G. Knepley         (*cone)[0] = fy*nVx + fx + nC;
318*3385ff7eSMatthew G. Knepley         (*cone)[1] = fy*nVx + fx + nVx + nC;
319*3385ff7eSMatthew G. Knepley       } else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d should be in [0, %d)", p, nC+nV+nXF+nYF+nZF);
320*3385ff7eSMatthew G. Knepley     } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative point %d is invalid", p);
321*3385ff7eSMatthew G. Knepley     break;
322*3385ff7eSMatthew G. Knepley   case 3:
323*3385ff7eSMatthew G. Knepley     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to do 3D");
324*3385ff7eSMatthew G. Knepley     break;
325*3385ff7eSMatthew G. Knepley   }
326*3385ff7eSMatthew G. Knepley   PetscFunctionReturn(0);
327*3385ff7eSMatthew G. Knepley }
328*3385ff7eSMatthew G. Knepley 
329*3385ff7eSMatthew G. Knepley #undef __FUNCT__
330*3385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDARestoreCone"
331*3385ff7eSMatthew G. Knepley PetscErrorCode DMDARestoreCone(DM dm, PetscInt p, PetscInt *cone[])
332*3385ff7eSMatthew G. Knepley {
333*3385ff7eSMatthew G. Knepley   PetscErrorCode ierr;
334*3385ff7eSMatthew G. Knepley 
335*3385ff7eSMatthew G. Knepley   PetscFunctionBegin;
336*3385ff7eSMatthew G. Knepley   ierr = DMGetWorkArray(dm, 6, PETSC_INT, cone);CHKERRQ(ierr);
337*3385ff7eSMatthew G. Knepley   PetscFunctionReturn(0);
338*3385ff7eSMatthew G. Knepley }
339*3385ff7eSMatthew G. Knepley 
340*3385ff7eSMatthew G. Knepley #undef __FUNCT__
341a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection"
342a66d4d66SMatthew G Knepley /*@C
343a66d4d66SMatthew G Knepley   DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with
344a66d4d66SMatthew G Knepley   different numbers of dofs on vertices, cells, and faces in each direction.
345a66d4d66SMatthew G Knepley 
346a66d4d66SMatthew G Knepley   Input Parameters:
347a66d4d66SMatthew G Knepley + dm- The DMDA
348a66d4d66SMatthew G Knepley . numFields - The number of fields
3490298fd71SBarry Smith . numComp - The number of components in each field, or NULL for 1
3500298fd71SBarry Smith . numVertexDof - The number of dofs per vertex for each field, or NULL
3510298fd71SBarry Smith . numFaceDof - The number of dofs per face for each field and direction, or NULL
3520298fd71SBarry Smith - numCellDof - The number of dofs per cell for each field, or NULL
353a66d4d66SMatthew G Knepley 
354a66d4d66SMatthew G Knepley   Level: developer
355a66d4d66SMatthew G Knepley 
356a66d4d66SMatthew G Knepley   Note:
357a66d4d66SMatthew G Knepley   The default DMDA numbering is as follows:
358a66d4d66SMatthew G Knepley 
359a66d4d66SMatthew G Knepley     - Cells:    [0,             nC)
360a66d4d66SMatthew G Knepley     - Vertices: [nC,            nC+nV)
36188ed4aceSMatthew G Knepley     - X-Faces:  [nC+nV,         nC+nV+nXF)         normal is +- x-dir
36288ed4aceSMatthew G Knepley     - Y-Faces:  [nC+nV+nXF,     nC+nV+nXF+nYF)     normal is +- y-dir
36388ed4aceSMatthew G Knepley     - Z-Faces:  [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir
364a66d4d66SMatthew G Knepley 
365a66d4d66SMatthew G Knepley   We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment.
366a66d4d66SMatthew G Knepley @*/
36780800b1aSMatthew G Knepley PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[])
368a66d4d66SMatthew G Knepley {
369a66d4d66SMatthew G Knepley   DM_DA            *da  = (DM_DA*) dm->data;
370a4b60ecfSMatthew G. Knepley   PetscSection      section;
37188ed4aceSMatthew G Knepley   const PetscInt    dim = da->dim;
37280800b1aSMatthew G Knepley   PetscInt          numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0};
37388ed4aceSMatthew G Knepley   PetscSF           sf;
374feafbc5cSMatthew G Knepley   PetscMPIInt       rank;
37588ed4aceSMatthew G Knepley   const PetscMPIInt *neighbors;
37688ed4aceSMatthew G Knepley   PetscInt          *localPoints;
37788ed4aceSMatthew G Knepley   PetscSFNode       *remotePoints;
378f5eeb527SMatthew G Knepley   PetscInt          nleaves = 0,  nleavesCheck = 0, nL = 0;
37957459e9aSMatthew G Knepley   PetscInt          nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF;
38057459e9aSMatthew G Knepley   PetscInt          pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd;
38188ed4aceSMatthew G Knepley   PetscInt          f, v, c, xf, yf, zf, xn, yn, zn;
382a66d4d66SMatthew G Knepley   PetscErrorCode    ierr;
383a66d4d66SMatthew G Knepley 
384a66d4d66SMatthew G Knepley   PetscFunctionBegin;
385a66d4d66SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3863582350cSMatthew G. Knepley   PetscValidPointer(s, 4);
38782f516ccSBarry Smith   ierr    = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr);
3883582350cSMatthew G. Knepley   ierr    = DMDAGetNumCells(dm, NULL, NULL, NULL, &nC);CHKERRQ(ierr);
38957459e9aSMatthew G Knepley   ierr    = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr);
39057459e9aSMatthew G Knepley   ierr    = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
39157459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, -1,  &pStart, &pEnd);CHKERRQ(ierr);
39257459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, 0,   &cStart, &cEnd);CHKERRQ(ierr);
39357459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, 1,   &fStart, &fEnd);CHKERRQ(ierr);
39457459e9aSMatthew G Knepley   ierr    = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr);
39557459e9aSMatthew G Knepley   xfStart = vEnd;  xfEnd = xfStart+nXF;
39657459e9aSMatthew G Knepley   yfStart = xfEnd; yfEnd = yfStart+nYF;
39757459e9aSMatthew G Knepley   zfStart = yfEnd; zfEnd = zfStart+nZF;
39882f516ccSBarry Smith   if (zfEnd != fEnd) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd);
39988ed4aceSMatthew G Knepley   /* Create local section */
40080800b1aSMatthew G Knepley   ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr);
401a66d4d66SMatthew G Knepley   for (f = 0; f < numFields; ++f) {
4028865f1eaSKarl Rupp     if (numVertexDof) numVertexTotDof  += numVertexDof[f];
4038865f1eaSKarl Rupp     if (numCellDof)   numCellTotDof    += numCellDof[f];
4048865f1eaSKarl Rupp     if (numFaceDof) {
4058865f1eaSKarl Rupp       numFaceTotDof[0] += numFaceDof[f*dim+0];
40688ed4aceSMatthew G Knepley       numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0;
4070ad7597dSKarl Rupp       numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0;
4080ad7597dSKarl Rupp     }
409a66d4d66SMatthew G Knepley   }
410a4b60ecfSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &section);CHKERRQ(ierr);
411a66d4d66SMatthew G Knepley   if (numFields > 1) {
412a4b60ecfSMatthew G. Knepley     ierr = PetscSectionSetNumFields(section, numFields);CHKERRQ(ierr);
413a66d4d66SMatthew G Knepley     for (f = 0; f < numFields; ++f) {
41480800b1aSMatthew G Knepley       const char *name;
41580800b1aSMatthew G Knepley 
41680800b1aSMatthew G Knepley       ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr);
417a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetFieldName(section, f, name);CHKERRQ(ierr);
41880800b1aSMatthew G Knepley       if (numComp) {
419a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldComponents(section, f, numComp[f]);CHKERRQ(ierr);
420a66d4d66SMatthew G Knepley       }
421a66d4d66SMatthew G Knepley     }
422a66d4d66SMatthew G Knepley   } else {
423a66d4d66SMatthew G Knepley     numFields = 0;
424a66d4d66SMatthew G Knepley   }
425a4b60ecfSMatthew G. Knepley   ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr);
426a66d4d66SMatthew G Knepley   if (numVertexDof) {
427a66d4d66SMatthew G Knepley     for (v = vStart; v < vEnd; ++v) {
428a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
429a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, v, f, numVertexDof[f]);CHKERRQ(ierr);
430a66d4d66SMatthew G Knepley       }
431a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, v, numVertexTotDof);CHKERRQ(ierr);
432a66d4d66SMatthew G Knepley     }
433a66d4d66SMatthew G Knepley   }
434a66d4d66SMatthew G Knepley   if (numFaceDof) {
435a66d4d66SMatthew G Knepley     for (xf = xfStart; xf < xfEnd; ++xf) {
436a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
437a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, xf, f, numFaceDof[f*dim+0]);CHKERRQ(ierr);
438a66d4d66SMatthew G Knepley       }
439a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, xf, numFaceTotDof[0]);CHKERRQ(ierr);
440a66d4d66SMatthew G Knepley     }
441a66d4d66SMatthew G Knepley     for (yf = yfStart; yf < yfEnd; ++yf) {
442a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
443a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, yf, f, numFaceDof[f*dim+1]);CHKERRQ(ierr);
444a66d4d66SMatthew G Knepley       }
445a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, yf, numFaceTotDof[1]);CHKERRQ(ierr);
446a66d4d66SMatthew G Knepley     }
447a66d4d66SMatthew G Knepley     for (zf = zfStart; zf < zfEnd; ++zf) {
448a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
449a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, zf, f, numFaceDof[f*dim+2]);CHKERRQ(ierr);
450a66d4d66SMatthew G Knepley       }
451a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, zf, numFaceTotDof[2]);CHKERRQ(ierr);
452a66d4d66SMatthew G Knepley     }
453a66d4d66SMatthew G Knepley   }
454a66d4d66SMatthew G Knepley   if (numCellDof) {
455a66d4d66SMatthew G Knepley     for (c = cStart; c < cEnd; ++c) {
456a66d4d66SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
457a4b60ecfSMatthew G. Knepley         ierr = PetscSectionSetFieldDof(section, c, f, numCellDof[f]);CHKERRQ(ierr);
458a66d4d66SMatthew G Knepley       }
459a4b60ecfSMatthew G. Knepley       ierr = PetscSectionSetDof(section, c, numCellTotDof);CHKERRQ(ierr);
460a66d4d66SMatthew G Knepley     }
461a66d4d66SMatthew G Knepley   }
462a4b60ecfSMatthew G. Knepley   ierr = PetscSectionSetUp(section);CHKERRQ(ierr);
46388ed4aceSMatthew G Knepley   /* Create mesh point SF */
46488ed4aceSMatthew G Knepley   ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr);
46588ed4aceSMatthew G Knepley   for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
46688ed4aceSMatthew G Knepley     for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
46788ed4aceSMatthew G Knepley       for (xn = 0; xn < 3; ++xn) {
4687128ae9fSMatthew G Knepley         const PetscInt xp       = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
46988ed4aceSMatthew G Knepley         const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
47088ed4aceSMatthew G Knepley 
4713814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
472feafbc5cSMatthew G Knepley           nleaves += (!xp ? nVx : 1) * (!yp ? nVy : 1) * (!zp ? nVz : 1); /* vertices */
47388ed4aceSMatthew G Knepley           if (xp && !yp && !zp) {
47488ed4aceSMatthew G Knepley             nleaves += nxF; /* x faces */
47588ed4aceSMatthew G Knepley           } else if (yp && !zp && !xp) {
47688ed4aceSMatthew G Knepley             nleaves += nyF; /* y faces */
47788ed4aceSMatthew G Knepley           } else if (zp && !xp && !yp) {
47888ed4aceSMatthew G Knepley             nleaves += nzF; /* z faces */
47988ed4aceSMatthew G Knepley           }
48088ed4aceSMatthew G Knepley         }
48188ed4aceSMatthew G Knepley       }
48288ed4aceSMatthew G Knepley     }
48388ed4aceSMatthew G Knepley   }
484dcca6d9dSJed Brown   ierr = PetscMalloc2(nleaves,&localPoints,nleaves,&remotePoints);CHKERRQ(ierr);
48588ed4aceSMatthew G Knepley   for (zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
48688ed4aceSMatthew G Knepley     for (yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
48788ed4aceSMatthew G Knepley       for (xn = 0; xn < 3; ++xn) {
4887128ae9fSMatthew G Knepley         const PetscInt xp       = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
48988ed4aceSMatthew G Knepley         const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
490f5eeb527SMatthew G Knepley         PetscInt       xv, yv, zv;
49188ed4aceSMatthew G Knepley 
4923814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
49388ed4aceSMatthew G Knepley           if (xp < 0) { /* left */
49488ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
49588ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
496f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx +     0 + nC;
497f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
498628e3b0dSSatish Balay                 nleavesCheck += 1; /* left bottom back vertex */
499f5eeb527SMatthew G Knepley 
500f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
501f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
502f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
503f5eeb527SMatthew G Knepley                 ++nL;
50488ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
505f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx +     0 + nC;
506f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
507628e3b0dSSatish Balay                 nleavesCheck += 1; /* left bottom front vertex */
508f5eeb527SMatthew G Knepley 
509f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
510f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
511f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
512f5eeb527SMatthew G Knepley                 ++nL;
51388ed4aceSMatthew G Knepley               } else {
51488ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* left bottom vertices */
515f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv, ++nL) {
516f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx +     0 + nC;
517f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
518f5eeb527SMatthew G Knepley 
519f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
520f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
521f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
522f5eeb527SMatthew G Knepley                 }
52388ed4aceSMatthew G Knepley               }
52488ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
52588ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
526f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx +     0 + nC;
527f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
528628e3b0dSSatish Balay                 nleavesCheck += 1; /* left top back vertex */
529f5eeb527SMatthew G Knepley 
530f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
531f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
532f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
533f5eeb527SMatthew G Knepley                 ++nL;
53488ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
535f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC;
536f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
537628e3b0dSSatish Balay                 nleavesCheck += 1; /* left top front vertex */
538f5eeb527SMatthew G Knepley 
539f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
540f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
541f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
542f5eeb527SMatthew G Knepley                 ++nL;
54388ed4aceSMatthew G Knepley               } else {
54488ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* left top vertices */
545f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv, ++nL) {
546f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx +     0 + nC;
547f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
548f5eeb527SMatthew G Knepley 
549f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
550f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
551f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
552f5eeb527SMatthew G Knepley                 }
55388ed4aceSMatthew G Knepley               }
55488ed4aceSMatthew G Knepley             } else {
55588ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
55688ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* left back vertices */
557f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv, ++nL) {
558f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx +     0 + nC;
559f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
560f5eeb527SMatthew G Knepley 
561f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
562f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
563f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
564f5eeb527SMatthew G Knepley                 }
56588ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
56688ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* left front vertices */
567f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv, ++nL) {
568f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx +     0 + nC;
569f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
570f5eeb527SMatthew G Knepley 
571f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
572f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
573f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
574f5eeb527SMatthew G Knepley                 }
57588ed4aceSMatthew G Knepley               } else {
57688ed4aceSMatthew G Knepley                 nleavesCheck += nVy*nVz; /* left vertices */
577f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
578f5eeb527SMatthew G Knepley                   for (yv = 0; yv < nVy; ++yv, ++nL) {
579f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx +     0 + nC;
580f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
581f5eeb527SMatthew G Knepley 
582f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
583f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
584f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
585f5eeb527SMatthew G Knepley                   }
586f5eeb527SMatthew G Knepley                 }
58788ed4aceSMatthew G Knepley                 nleavesCheck += nxF;     /* left faces */
588f5eeb527SMatthew G Knepley                 for (xf = 0; xf < nxF; ++xf, ++nL) {
589f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
590f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
591f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
592f5eeb527SMatthew G Knepley 
593f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
594f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
595f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
596f5eeb527SMatthew G Knepley                 }
59788ed4aceSMatthew G Knepley               }
59888ed4aceSMatthew G Knepley             }
59988ed4aceSMatthew G Knepley           } else if (xp > 0) { /* right */
60088ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
60188ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
602f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx + nVx-1 + nC;
603f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
604628e3b0dSSatish Balay                 nleavesCheck += 1; /* right bottom back vertex */
605f5eeb527SMatthew G Knepley 
606f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
607f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
608f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
609f5eeb527SMatthew G Knepley                 ++nL;
61088ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
611f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC;
612f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
613628e3b0dSSatish Balay                 nleavesCheck += 1; /* right bottom front vertex */
614f5eeb527SMatthew G Knepley 
615f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
616f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
617f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
618f5eeb527SMatthew G Knepley                 ++nL;
61988ed4aceSMatthew G Knepley               } else {
62088ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* right bottom vertices */
621f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv, ++nL) {
622f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx + nVx-1 + nC;
623f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
624f5eeb527SMatthew G Knepley 
625f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
626f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
627f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
628f5eeb527SMatthew G Knepley                 }
62988ed4aceSMatthew G Knepley               }
63088ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
63188ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
632f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + nVx-1 + nC;
633f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
634628e3b0dSSatish Balay                 nleavesCheck += 1; /* right top back vertex */
635f5eeb527SMatthew G Knepley 
636f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
637f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
638f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
639f5eeb527SMatthew G Knepley                 ++nL;
64088ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
641f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC;
642f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
643628e3b0dSSatish Balay                 nleavesCheck += 1; /* right top front vertex */
644f5eeb527SMatthew G Knepley 
645f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
646f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
647f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
648f5eeb527SMatthew G Knepley                 ++nL;
64988ed4aceSMatthew G Knepley               } else {
65088ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* right top vertices */
651f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv, ++nL) {
652f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + nVx-1 + nC;
653f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
654f5eeb527SMatthew G Knepley 
655f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
656f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
657f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
658f5eeb527SMatthew G Knepley                 }
65988ed4aceSMatthew G Knepley               }
66088ed4aceSMatthew G Knepley             } else {
66188ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
66288ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* right back vertices */
663f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv, ++nL) {
664f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx + nVx-1 + nC;
665f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
666f5eeb527SMatthew G Knepley 
667f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
668f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
669f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
670f5eeb527SMatthew G Knepley                 }
67188ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
67288ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* right front vertices */
673f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv, ++nL) {
674f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC;
675f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
676f5eeb527SMatthew G Knepley 
677f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
678f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
679f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
680f5eeb527SMatthew G Knepley                 }
68188ed4aceSMatthew G Knepley               } else {
68288ed4aceSMatthew G Knepley                 nleavesCheck += nVy*nVz; /* right vertices */
683f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
684f5eeb527SMatthew G Knepley                   for (yv = 0; yv < nVy; ++yv, ++nL) {
685f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx + nVx-1 + nC;
686f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0     + nC; /* TODO: Correct this for neighbor sizes */
687f5eeb527SMatthew G Knepley 
688f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
689f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
690f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
691f5eeb527SMatthew G Knepley                   }
692f5eeb527SMatthew G Knepley                 }
69388ed4aceSMatthew G Knepley                 nleavesCheck += nxF;     /* right faces */
694f5eeb527SMatthew G Knepley                 for (xf = 0; xf < nxF; ++xf, ++nL) {
695f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
696f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
697f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
698f5eeb527SMatthew G Knepley 
699f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
700f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
701f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
702f5eeb527SMatthew G Knepley                 }
70388ed4aceSMatthew G Knepley               }
70488ed4aceSMatthew G Knepley             }
70588ed4aceSMatthew G Knepley           } else {
70688ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
70788ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
70888ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* bottom back vertices */
709f5eeb527SMatthew G Knepley                 for (xv = 0; xv < nVx; ++xv, ++nL) {
710f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy +     0)*nVx + xv + nC;
711f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
712f5eeb527SMatthew G Knepley 
713f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
714f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
715f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
716f5eeb527SMatthew G Knepley                 }
71788ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
71888ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* bottom front vertices */
719f5eeb527SMatthew G Knepley                 for (xv = 0; xv < nVx; ++xv, ++nL) {
720f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + xv + nC;
721f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
722f5eeb527SMatthew G Knepley 
723f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
724f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
725f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
726f5eeb527SMatthew G Knepley                 }
72788ed4aceSMatthew G Knepley               } else {
72888ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVz; /* bottom vertices */
729f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
730f5eeb527SMatthew G Knepley                   for (xv = 0; xv < nVx; ++xv, ++nL) {
731f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy +     0)*nVx + xv + nC;
732f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
733f5eeb527SMatthew G Knepley 
734f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
735f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
736f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
737f5eeb527SMatthew G Knepley                   }
738f5eeb527SMatthew G Knepley                 }
73988ed4aceSMatthew G Knepley                 nleavesCheck += nyF;     /* bottom faces */
740f5eeb527SMatthew G Knepley                 for (yf = 0; yf < nyF; ++yf, ++nL) {
741f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
742f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
743f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
744f5eeb527SMatthew G Knepley 
745f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
746f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
747f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
748f5eeb527SMatthew G Knepley                 }
74988ed4aceSMatthew G Knepley               }
75088ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
75188ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
75288ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* top back vertices */
753f5eeb527SMatthew G Knepley                 for (xv = 0; xv < nVx; ++xv, ++nL) {
754f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + xv + nC;
755f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
756f5eeb527SMatthew G Knepley 
757f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
758f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
759f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
760f5eeb527SMatthew G Knepley                 }
76188ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
76288ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* top front vertices */
763f5eeb527SMatthew G Knepley                 for (xv = 0; xv < nVx; ++xv, ++nL) {
764f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC;
765f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
766f5eeb527SMatthew G Knepley 
767f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
768f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
769f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
770f5eeb527SMatthew G Knepley                 }
77188ed4aceSMatthew G Knepley               } else {
77288ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVz; /* top vertices */
773f5eeb527SMatthew G Knepley                 for (zv = 0; zv < nVz; ++zv) {
774f5eeb527SMatthew G Knepley                   for (xv = 0; xv < nVx; ++xv, ++nL) {
775f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + xv + nC;
776f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
777f5eeb527SMatthew G Knepley 
778f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
779f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
780f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
781f5eeb527SMatthew G Knepley                   }
782f5eeb527SMatthew G Knepley                 }
78388ed4aceSMatthew G Knepley                 nleavesCheck += nyF;     /* top faces */
784f5eeb527SMatthew G Knepley                 for (yf = 0; yf < nyF; ++yf, ++nL) {
785f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
786f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
787f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
788f5eeb527SMatthew G Knepley 
789f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
790f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
791f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
792f5eeb527SMatthew G Knepley                 }
79388ed4aceSMatthew G Knepley               }
79488ed4aceSMatthew G Knepley             } else {
79588ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
79688ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVy; /* back vertices */
797f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv) {
798f5eeb527SMatthew G Knepley                   for (xv = 0; xv < nVx; ++xv, ++nL) {
799f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (      0*nVy + yv)*nVx + xv + nC;
800f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
801f5eeb527SMatthew G Knepley 
802f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
803f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
804f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
805f5eeb527SMatthew G Knepley                   }
806f5eeb527SMatthew G Knepley                 }
80788ed4aceSMatthew G Knepley                 nleavesCheck += nzF;     /* back faces */
808f5eeb527SMatthew G Knepley                 for (zf = 0; zf < nzF; ++zf, ++nL) {
809f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
810f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
811f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
812f5eeb527SMatthew G Knepley 
813f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
814f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
815f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
816f5eeb527SMatthew G Knepley                 }
81788ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
81888ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVy; /* front vertices */
819f5eeb527SMatthew G Knepley                 for (yv = 0; yv < nVy; ++yv) {
820f5eeb527SMatthew G Knepley                   for (xv = 0; xv < nVx; ++xv, ++nL) {
821f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + xv + nC;
822f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (      0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
823f5eeb527SMatthew G Knepley 
824f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
825f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
826f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
827f5eeb527SMatthew G Knepley                   }
828f5eeb527SMatthew G Knepley                 }
82988ed4aceSMatthew G Knepley                 nleavesCheck += nzF;     /* front faces */
830f5eeb527SMatthew G Knepley                 for (zf = 0; zf < nzF; ++zf, ++nL) {
831f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
832f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
833f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
834f5eeb527SMatthew G Knepley 
835f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
836f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
837f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
838f5eeb527SMatthew G Knepley                 }
83988ed4aceSMatthew G Knepley               } else {
84088ed4aceSMatthew G Knepley                 /* Nothing is shared from the interior */
84188ed4aceSMatthew G Knepley               }
84288ed4aceSMatthew G Knepley             }
84388ed4aceSMatthew G Knepley           }
84488ed4aceSMatthew G Knepley         }
84588ed4aceSMatthew G Knepley       }
84688ed4aceSMatthew G Knepley     }
84788ed4aceSMatthew G Knepley   }
8483814d604SMatthew G Knepley   /* TODO: Remove duplication in leaf determination */
84982f516ccSBarry Smith   if (nleaves != nleavesCheck) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "The number of leaves %d did not match the number of remote leaves %d", nleaves, nleavesCheck);
85082f516ccSBarry Smith   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), &sf);CHKERRQ(ierr);
85188ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr);
852a4b60ecfSMatthew G. Knepley   ierr = DMSetPointSF(dm, sf);CHKERRQ(ierr);
85388ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&sf);CHKERRQ(ierr);
854a4b60ecfSMatthew G. Knepley   ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr);
855*3385ff7eSMatthew G. Knepley #undef __FUNCT__
856*3385ff7eSMatthew G. Knepley #define __FUNCT__ "DMDASetVertexCoordinates"
857*3385ff7eSMatthew G. Knepley PetscErrorCode DMDASetVertexCoordinates(DM dm, PetscReal xl, PetscReal xu, PetscReal yl, PetscReal yu, PetscReal zl, PetscReal zu)
858*3385ff7eSMatthew G. Knepley {
859*3385ff7eSMatthew G. Knepley   DM_DA         *da = (DM_DA *) dm->data;
860*3385ff7eSMatthew G. Knepley   Vec            coordinates;
861*3385ff7eSMatthew G. Knepley   PetscSection   section;
862*3385ff7eSMatthew G. Knepley   PetscScalar   *coords;
863*3385ff7eSMatthew G. Knepley   PetscReal      h[3];
864*3385ff7eSMatthew G. Knepley   PetscInt       dim, size, M, N, P, nVx, nVy, nVz, nV, vStart, vEnd, v, i, j, k;
865*3385ff7eSMatthew G. Knepley   PetscErrorCode ierr;
866*3385ff7eSMatthew G. Knepley 
867*3385ff7eSMatthew G. Knepley   PetscFunctionBegin;
868*3385ff7eSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
869*3385ff7eSMatthew G. Knepley   ierr = DMDAGetInfo(dm, &dim, &M, &N, &P, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
870*3385ff7eSMatthew G. Knepley   h[0] = (xu - xl)/M;
871*3385ff7eSMatthew G. Knepley   h[1] = (yu - yl)/N;
872*3385ff7eSMatthew G. Knepley   h[2] = (zu - zl)/P;
873*3385ff7eSMatthew G. Knepley   ierr = DMDAGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
874*3385ff7eSMatthew G. Knepley   ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr);
875*3385ff7eSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &section);CHKERRQ(ierr);
876*3385ff7eSMatthew G. Knepley   ierr = PetscSectionSetNumFields(section, 1);CHKERRQ(ierr);
877*3385ff7eSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(section, 0, dim);CHKERRQ(ierr);
878*3385ff7eSMatthew G. Knepley   ierr = PetscSectionSetChart(section, vStart, vEnd);CHKERRQ(ierr);
879*3385ff7eSMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
880*3385ff7eSMatthew G. Knepley     ierr = PetscSectionSetDof(section, v, dim);CHKERRQ(ierr);
881*3385ff7eSMatthew G. Knepley   }
882*3385ff7eSMatthew G. Knepley   ierr = PetscSectionSetUp(section);CHKERRQ(ierr);
883*3385ff7eSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
884*3385ff7eSMatthew G. Knepley   ierr = VecCreateSeq(PETSC_COMM_SELF, size, &coordinates);CHKERRQ(ierr);
885*3385ff7eSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
886*3385ff7eSMatthew G. Knepley   for (k = 0; k < nVz; ++k) {
887*3385ff7eSMatthew G. Knepley     PetscInt ind[3] = {0, 0, k + da->zs}, d, off;
888*3385ff7eSMatthew G. Knepley 
889*3385ff7eSMatthew G. Knepley     for (j = 0; j < nVy; ++j) {
890*3385ff7eSMatthew G. Knepley       ind[1] = j + da->ys;
891*3385ff7eSMatthew G. Knepley       for (i = 0; i < nVx; ++i) {
892*3385ff7eSMatthew G. Knepley         const PetscInt vertex = (k*nVy + j)*nVx + i + vStart;
893*3385ff7eSMatthew G. Knepley 
894*3385ff7eSMatthew G. Knepley         ierr = PetscSectionGetOffset(section, vertex, &off);CHKERRQ(ierr);
895*3385ff7eSMatthew G. Knepley         ind[0] = i + da->xs;
896*3385ff7eSMatthew G. Knepley         for (d = 0; d < dim; ++d) {
897*3385ff7eSMatthew G. Knepley           coords[off+d] = h[d]*ind[d];
898*3385ff7eSMatthew G. Knepley         }
899*3385ff7eSMatthew G. Knepley       }
900*3385ff7eSMatthew G. Knepley     }
901*3385ff7eSMatthew G. Knepley   }
902*3385ff7eSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
903*3385ff7eSMatthew G. Knepley   ierr = DMSetCoordinateSection(dm, section);CHKERRQ(ierr);
904*3385ff7eSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr);
905a4b60ecfSMatthew G. Knepley   ierr = PetscSectionDestroy(&section);CHKERRQ(ierr);
906*3385ff7eSMatthew G. Knepley   ierr = VecDestroy(&coordinates);CHKERRQ(ierr);
907*3385ff7eSMatthew G. Knepley   PetscFunctionReturn(0);
908*3385ff7eSMatthew G. Knepley }
909a66d4d66SMatthew G Knepley   PetscFunctionReturn(0);
910a66d4d66SMatthew G Knepley }
911a66d4d66SMatthew G Knepley 
91247c6ae99SBarry Smith /* ------------------------------------------------------------------- */
91347c6ae99SBarry Smith 
91447c6ae99SBarry Smith #undef __FUNCT__
915aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
91647c6ae99SBarry Smith /*@C
917aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
91847c6ae99SBarry Smith 
91947c6ae99SBarry Smith     Input Parameter:
92047c6ae99SBarry Smith +    da - information about my local patch
92147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
92247c6ae99SBarry Smith 
92347c6ae99SBarry Smith     Output Parameters:
92447c6ae99SBarry Smith .    vptr - array data structured
92547c6ae99SBarry Smith 
92647c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
92747c6ae99SBarry Smith            to zero them.
92847c6ae99SBarry Smith 
92947c6ae99SBarry Smith   Level: advanced
93047c6ae99SBarry Smith 
931bcaeba4dSBarry Smith .seealso: DMDARestoreArray()
93247c6ae99SBarry Smith 
93347c6ae99SBarry Smith @*/
9347087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool ghosted,void *vptr)
93547c6ae99SBarry Smith {
93647c6ae99SBarry Smith   PetscErrorCode ierr;
93747c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
93847c6ae99SBarry Smith   char           *iarray_start;
93947c6ae99SBarry Smith   void           **iptr = (void**)vptr;
94047c6ae99SBarry Smith   DM_DA          *dd    = (DM_DA*)da->data;
94147c6ae99SBarry Smith 
94247c6ae99SBarry Smith   PetscFunctionBegin;
94347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
94447c6ae99SBarry Smith   if (ghosted) {
945aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
94647c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
94747c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
94847c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
9490298fd71SBarry Smith         dd->arrayghostedin[i] = NULL;
9500298fd71SBarry Smith         dd->startghostedin[i] = NULL;
95147c6ae99SBarry Smith 
95247c6ae99SBarry Smith         goto done;
95347c6ae99SBarry Smith       }
95447c6ae99SBarry Smith     }
95547c6ae99SBarry Smith     xs = dd->Xs;
95647c6ae99SBarry Smith     ys = dd->Ys;
95747c6ae99SBarry Smith     zs = dd->Zs;
95847c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
95947c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
96047c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
96147c6ae99SBarry Smith   } else {
962aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
96347c6ae99SBarry Smith       if (dd->arrayin[i]) {
96447c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
96547c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
9660298fd71SBarry Smith         dd->arrayin[i] = NULL;
9670298fd71SBarry Smith         dd->startin[i] = NULL;
96847c6ae99SBarry Smith 
96947c6ae99SBarry Smith         goto done;
97047c6ae99SBarry Smith       }
97147c6ae99SBarry Smith     }
97247c6ae99SBarry Smith     xs = dd->xs;
97347c6ae99SBarry Smith     ys = dd->ys;
97447c6ae99SBarry Smith     zs = dd->zs;
97547c6ae99SBarry Smith     xm = dd->xe-dd->xs;
97647c6ae99SBarry Smith     ym = dd->ye-dd->ys;
97747c6ae99SBarry Smith     zm = dd->ze-dd->zs;
97847c6ae99SBarry Smith   }
97947c6ae99SBarry Smith 
98047c6ae99SBarry Smith   switch (dd->dim) {
98147c6ae99SBarry Smith   case 1: {
98247c6ae99SBarry Smith     void *ptr;
98347c6ae99SBarry Smith 
984901f1932SJed Brown     ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
98547c6ae99SBarry Smith 
98647c6ae99SBarry Smith     ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
98747c6ae99SBarry Smith     *iptr = (void*)ptr;
9888865f1eaSKarl Rupp     break;
9898865f1eaSKarl Rupp   }
99047c6ae99SBarry Smith   case 2: {
99147c6ae99SBarry Smith     void **ptr;
99247c6ae99SBarry Smith 
993901f1932SJed Brown     ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
99447c6ae99SBarry Smith 
99547c6ae99SBarry Smith     ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
9968865f1eaSKarl Rupp     for (j=ys; j<ys+ym; j++) ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
99747c6ae99SBarry Smith     *iptr = (void*)ptr;
9988865f1eaSKarl Rupp     break;
9998865f1eaSKarl Rupp   }
100047c6ae99SBarry Smith   case 3: {
100147c6ae99SBarry Smith     void ***ptr,**bptr;
100247c6ae99SBarry Smith 
1003901f1932SJed Brown     ierr = PetscMalloc((zm+1)*sizeof(void**)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
100447c6ae99SBarry Smith 
100547c6ae99SBarry Smith     ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
100647c6ae99SBarry Smith     bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
10078865f1eaSKarl Rupp     for (i=zs; i<zs+zm; i++) ptr[i] = bptr + ((i-zs)*ym - ys);
100847c6ae99SBarry Smith     for (i=zs; i<zs+zm; i++) {
100947c6ae99SBarry Smith       for (j=ys; j<ys+ym; j++) {
101047c6ae99SBarry Smith         ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
101147c6ae99SBarry Smith       }
101247c6ae99SBarry Smith     }
101347c6ae99SBarry Smith     *iptr = (void*)ptr;
10148865f1eaSKarl Rupp     break;
10158865f1eaSKarl Rupp   }
101647c6ae99SBarry Smith   default:
1017ce94432eSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
101847c6ae99SBarry Smith   }
101947c6ae99SBarry Smith 
102047c6ae99SBarry Smith done:
102147c6ae99SBarry Smith   /* add arrays to the checked out list */
102247c6ae99SBarry Smith   if (ghosted) {
1023aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
102447c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
102547c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr;
102647c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
102747c6ae99SBarry Smith         break;
102847c6ae99SBarry Smith       }
102947c6ae99SBarry Smith     }
103047c6ae99SBarry Smith   } else {
1031aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
103247c6ae99SBarry Smith       if (!dd->arrayout[i]) {
103347c6ae99SBarry Smith         dd->arrayout[i] = *iptr;
103447c6ae99SBarry Smith         dd->startout[i] = iarray_start;
103547c6ae99SBarry Smith         break;
103647c6ae99SBarry Smith       }
103747c6ae99SBarry Smith     }
103847c6ae99SBarry Smith   }
103947c6ae99SBarry Smith   PetscFunctionReturn(0);
104047c6ae99SBarry Smith }
104147c6ae99SBarry Smith 
104247c6ae99SBarry Smith #undef __FUNCT__
1043aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
104447c6ae99SBarry Smith /*@C
1045aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
104647c6ae99SBarry Smith 
104747c6ae99SBarry Smith     Input Parameter:
104847c6ae99SBarry Smith +    da - information about my local patch
104947c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
105047c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
105147c6ae99SBarry Smith 
105247c6ae99SBarry Smith      Level: advanced
105347c6ae99SBarry Smith 
1054bcaeba4dSBarry Smith .seealso: DMDAGetArray()
105547c6ae99SBarry Smith 
105647c6ae99SBarry Smith @*/
10577087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool ghosted,void *vptr)
105847c6ae99SBarry Smith {
105947c6ae99SBarry Smith   PetscInt i;
106047c6ae99SBarry Smith   void     **iptr = (void**)vptr,*iarray_start = 0;
106147c6ae99SBarry Smith   DM_DA    *dd    = (DM_DA*)da->data;
106247c6ae99SBarry Smith 
106347c6ae99SBarry Smith   PetscFunctionBegin;
106447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
106547c6ae99SBarry Smith   if (ghosted) {
1066aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
106747c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
106847c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
10690298fd71SBarry Smith         dd->arrayghostedout[i] = NULL;
10700298fd71SBarry Smith         dd->startghostedout[i] = NULL;
107147c6ae99SBarry Smith         break;
107247c6ae99SBarry Smith       }
107347c6ae99SBarry Smith     }
1074aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
107547c6ae99SBarry Smith       if (!dd->arrayghostedin[i]) {
107647c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
107747c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
107847c6ae99SBarry Smith         break;
107947c6ae99SBarry Smith       }
108047c6ae99SBarry Smith     }
108147c6ae99SBarry Smith   } else {
1082aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
108347c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
108447c6ae99SBarry Smith         iarray_start    = dd->startout[i];
10850298fd71SBarry Smith         dd->arrayout[i] = NULL;
10860298fd71SBarry Smith         dd->startout[i] = NULL;
108747c6ae99SBarry Smith         break;
108847c6ae99SBarry Smith       }
108947c6ae99SBarry Smith     }
1090aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
109147c6ae99SBarry Smith       if (!dd->arrayin[i]) {
109247c6ae99SBarry Smith         dd->arrayin[i] = *iptr;
109347c6ae99SBarry Smith         dd->startin[i] = iarray_start;
109447c6ae99SBarry Smith         break;
109547c6ae99SBarry Smith       }
109647c6ae99SBarry Smith     }
109747c6ae99SBarry Smith   }
109847c6ae99SBarry Smith   PetscFunctionReturn(0);
109947c6ae99SBarry Smith }
110047c6ae99SBarry Smith 
1101