xref: /petsc/src/dm/impls/da/dalocal.c (revision eaf8d80a9d4254dc2e0df27544085fe1ea6bc7c6)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6b45d2f2cSJed Brown #include <petsc-private/daimpl.h>    /*I   "petscdmda.h"   I*/
747c6ae99SBarry Smith 
847c6ae99SBarry Smith /*
9e3c5b3baSBarry Smith    This allows the DMDA vectors to properly tell MATLAB their dimensions
1047c6ae99SBarry Smith */
1147c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
12c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
13c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
1447c6ae99SBarry Smith EXTERN_C_BEGIN
1547c6ae99SBarry Smith #undef __FUNCT__
1647c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d"
177087cfbeSBarry Smith 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;
273c0c59f3SBarry Smith   ierr = PetscObjectQuery((PetscObject)vec,"DM",(PetscObject*)&da);CHKERRQ(ierr);
28aa219208SBarry Smith   if (!da) SETERRQ(((PetscObject)vec)->comm,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 EXTERN_C_END
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);
5847c6ae99SBarry Smith   ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr);
5947c6ae99SBarry Smith   ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
6047c6ae99SBarry Smith   ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
61401ddaa8SBarry Smith   ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
623c0c59f3SBarry Smith   ierr = PetscObjectCompose((PetscObject)*g,"DM",(PetscObject)da);CHKERRQ(ierr);
6347c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
6447c6ae99SBarry Smith   if (dd->w == 1  && dd->dim == 2) {
6547c6ae99SBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
6647c6ae99SBarry Smith   }
6747c6ae99SBarry Smith #endif
6847c6ae99SBarry Smith   PetscFunctionReturn(0);
6947c6ae99SBarry Smith }
7047c6ae99SBarry Smith 
71a66d4d66SMatthew G Knepley #undef __FUNCT__
7257459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumCells"
7357459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumCells(DM dm, PetscInt *numCells)
7457459e9aSMatthew G Knepley {
7557459e9aSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
7657459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
7757459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
7857459e9aSMatthew G Knepley   const PetscInt nC  = (mx  )*(dim > 1 ? (my  )*(dim > 2 ? (mz  ) : 1) : 1);
7957459e9aSMatthew G Knepley 
8057459e9aSMatthew G Knepley   PetscFunctionBegin;
8157459e9aSMatthew G Knepley   if (numCells) {
8257459e9aSMatthew G Knepley     PetscValidIntPointer(numCells,2);
8357459e9aSMatthew G Knepley     *numCells = nC;
8457459e9aSMatthew G Knepley   }
8557459e9aSMatthew G Knepley   PetscFunctionReturn(0);
8657459e9aSMatthew G Knepley }
8757459e9aSMatthew G Knepley 
8857459e9aSMatthew G Knepley #undef __FUNCT__
8957459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumVertices"
9057459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumVertices(DM dm, PetscInt *numVerticesX, PetscInt *numVerticesY, PetscInt *numVerticesZ, PetscInt *numVertices)
9157459e9aSMatthew G Knepley {
9257459e9aSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
9357459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
9457459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
9557459e9aSMatthew G Knepley   const PetscInt nVx = mx+1;
9657459e9aSMatthew G Knepley   const PetscInt nVy = dim > 1 ? (my+1) : 1;
9757459e9aSMatthew G Knepley   const PetscInt nVz = dim > 2 ? (mz+1) : 1;
9857459e9aSMatthew G Knepley   const PetscInt nV  = nVx*nVy*nVz;
9957459e9aSMatthew G Knepley 
10057459e9aSMatthew G Knepley   PetscFunctionBegin;
10157459e9aSMatthew G Knepley   if (numVerticesX) {
10257459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesX,2);
10357459e9aSMatthew G Knepley     *numVerticesX = nVx;
10457459e9aSMatthew G Knepley   }
10557459e9aSMatthew G Knepley   if (numVerticesY) {
10657459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesY,3);
10757459e9aSMatthew G Knepley     *numVerticesY = nVy;
10857459e9aSMatthew G Knepley   }
10957459e9aSMatthew G Knepley   if (numVerticesZ) {
11057459e9aSMatthew G Knepley     PetscValidIntPointer(numVerticesZ,4);
11157459e9aSMatthew G Knepley     *numVerticesZ = nVz;
11257459e9aSMatthew G Knepley   }
11357459e9aSMatthew G Knepley   if (numVertices) {
11457459e9aSMatthew G Knepley     PetscValidIntPointer(numVertices,5);
11557459e9aSMatthew G Knepley     *numVertices = nV;
11657459e9aSMatthew G Knepley   }
11757459e9aSMatthew G Knepley   PetscFunctionReturn(0);
11857459e9aSMatthew G Knepley }
11957459e9aSMatthew G Knepley 
12057459e9aSMatthew G Knepley #undef __FUNCT__
12157459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetNumFaces"
12257459e9aSMatthew G Knepley PetscErrorCode DMDAGetNumFaces(DM dm, PetscInt *numXFacesX, PetscInt *numXFaces, PetscInt *numYFacesY, PetscInt *numYFaces, PetscInt *numZFacesZ, PetscInt *numZFaces)
12357459e9aSMatthew G Knepley {
12457459e9aSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
12557459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
12657459e9aSMatthew G Knepley   const PetscInt mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
12757459e9aSMatthew G Knepley   const PetscInt nxF = (dim > 1 ? (my  )*(dim > 2 ? (mz  ) : 1) : 1);
12857459e9aSMatthew G Knepley   const PetscInt nXF = (mx+1)*nxF;
12957459e9aSMatthew G Knepley   const PetscInt nyF = mx*(dim > 2 ? mz : 1);
13057459e9aSMatthew G Knepley   const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0;
13157459e9aSMatthew G Knepley   const PetscInt nzF = mx*(dim > 1 ? my : 0);
13257459e9aSMatthew G Knepley   const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0;
13357459e9aSMatthew G Knepley 
13457459e9aSMatthew G Knepley   PetscFunctionBegin;
13557459e9aSMatthew G Knepley   if (numXFacesX) {
13657459e9aSMatthew G Knepley     PetscValidIntPointer(numXFacesX,2);
13757459e9aSMatthew G Knepley     *numXFacesX = nxF;
13857459e9aSMatthew G Knepley   }
13957459e9aSMatthew G Knepley   if (numXFaces) {
14057459e9aSMatthew G Knepley     PetscValidIntPointer(numXFaces,3);
14157459e9aSMatthew G Knepley     *numXFaces = nXF;
14257459e9aSMatthew G Knepley   }
14357459e9aSMatthew G Knepley   if (numYFacesY) {
14457459e9aSMatthew G Knepley     PetscValidIntPointer(numYFacesY,4);
14557459e9aSMatthew G Knepley     *numYFacesY = nyF;
14657459e9aSMatthew G Knepley   }
14757459e9aSMatthew G Knepley   if (numYFaces) {
14857459e9aSMatthew G Knepley     PetscValidIntPointer(numYFaces,5);
14957459e9aSMatthew G Knepley     *numYFaces = nYF;
15057459e9aSMatthew G Knepley   }
15157459e9aSMatthew G Knepley   if (numZFacesZ) {
15257459e9aSMatthew G Knepley     PetscValidIntPointer(numZFacesZ,6);
15357459e9aSMatthew G Knepley     *numZFacesZ = nzF;
15457459e9aSMatthew G Knepley   }
15557459e9aSMatthew G Knepley   if (numZFaces) {
15657459e9aSMatthew G Knepley     PetscValidIntPointer(numZFaces,7);
15757459e9aSMatthew G Knepley     *numZFaces = nZF;
15857459e9aSMatthew G Knepley   }
15957459e9aSMatthew G Knepley   PetscFunctionReturn(0);
16057459e9aSMatthew G Knepley }
16157459e9aSMatthew G Knepley 
16257459e9aSMatthew G Knepley #undef __FUNCT__
16357459e9aSMatthew G Knepley #define __FUNCT__ "DMDAGetHeightStratum"
16457459e9aSMatthew G Knepley PetscErrorCode DMDAGetHeightStratum(DM dm, PetscInt height, PetscInt *pStart, PetscInt *pEnd)
16557459e9aSMatthew G Knepley {
16657459e9aSMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
16757459e9aSMatthew G Knepley   const PetscInt dim = da->dim;
16857459e9aSMatthew G Knepley   PetscInt       nC, nV, nXF, nYF, nZF;
16957459e9aSMatthew G Knepley   PetscErrorCode ierr;
17057459e9aSMatthew G Knepley 
17157459e9aSMatthew G Knepley   PetscFunctionBegin;
17257459e9aSMatthew G Knepley   if (pStart) {PetscValidIntPointer(pStart,3);}
17357459e9aSMatthew G Knepley   if (pEnd)   {PetscValidIntPointer(pEnd,4);}
17457459e9aSMatthew G Knepley   ierr = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr);
17557459e9aSMatthew G Knepley   ierr = DMDAGetNumVertices(dm, PETSC_NULL, PETSC_NULL, PETSC_NULL, &nV);CHKERRQ(ierr);
17657459e9aSMatthew G Knepley   ierr = DMDAGetNumFaces(dm, PETSC_NULL, &nXF, PETSC_NULL, &nYF, PETSC_NULL, &nZF);CHKERRQ(ierr);
17757459e9aSMatthew G Knepley   if (height == 0) {
17857459e9aSMatthew G Knepley     /* Cells */
17957459e9aSMatthew G Knepley     if (pStart) {*pStart = 0;}
18057459e9aSMatthew G Knepley     if (pEnd)   {*pEnd   = nC;}
18157459e9aSMatthew G Knepley   } else if (height == 1) {
18257459e9aSMatthew G Knepley     /* Faces */
18357459e9aSMatthew G Knepley     if (pStart) {*pStart = nC+nV;}
18457459e9aSMatthew G Knepley     if (pEnd)   {*pEnd   = nC+nV+nXF+nYF+nZF;}
18557459e9aSMatthew G Knepley   } else if (height == dim) {
18657459e9aSMatthew G Knepley     /* Vertices */
18757459e9aSMatthew G Knepley     if (pStart) {*pStart = nC;}
18857459e9aSMatthew G Knepley     if (pEnd)   {*pEnd   = nC+nV;}
18957459e9aSMatthew G Knepley   } else if (height < 0) {
19057459e9aSMatthew G Knepley     /* All points */
19157459e9aSMatthew G Knepley     if (pStart) {*pStart = 0;}
19257459e9aSMatthew G Knepley     if (pEnd)   {*pEnd   = nC+nV+nXF+nYF+nZF;}
19357459e9aSMatthew G Knepley   } else {
19457459e9aSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "No points of height %d in the DA", height);
19557459e9aSMatthew G Knepley   }
19657459e9aSMatthew G Knepley   PetscFunctionReturn(0);
19757459e9aSMatthew G Knepley }
19857459e9aSMatthew G Knepley 
19957459e9aSMatthew G Knepley #undef __FUNCT__
200a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection"
201a66d4d66SMatthew G Knepley /*@C
202a66d4d66SMatthew G Knepley   DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with
203a66d4d66SMatthew G Knepley   different numbers of dofs on vertices, cells, and faces in each direction.
204a66d4d66SMatthew G Knepley 
205a66d4d66SMatthew G Knepley   Input Parameters:
206a66d4d66SMatthew G Knepley + dm- The DMDA
207a66d4d66SMatthew G Knepley . numFields - The number of fields
208a66d4d66SMatthew G Knepley . numComp - The number of components in each field, or PETSC_NULL for 1
209a66d4d66SMatthew G Knepley . numVertexDof - The number of dofs per vertex for each field, or PETSC_NULL
210a66d4d66SMatthew G Knepley . numFaceDof - The number of dofs per face for each field and direction, or PETSC_NULL
211a66d4d66SMatthew G Knepley - numCellDof - The number of dofs per cell for each field, or PETSC_NULL
212a66d4d66SMatthew G Knepley 
213a66d4d66SMatthew G Knepley   Level: developer
214a66d4d66SMatthew G Knepley 
215a66d4d66SMatthew G Knepley   Note:
216a66d4d66SMatthew G Knepley   The default DMDA numbering is as follows:
217a66d4d66SMatthew G Knepley 
218a66d4d66SMatthew G Knepley     - Cells:    [0,             nC)
219a66d4d66SMatthew G Knepley     - Vertices: [nC,            nC+nV)
22088ed4aceSMatthew G Knepley     - X-Faces:  [nC+nV,         nC+nV+nXF)         normal is +- x-dir
22188ed4aceSMatthew G Knepley     - Y-Faces:  [nC+nV+nXF,     nC+nV+nXF+nYF)     normal is +- y-dir
22288ed4aceSMatthew G Knepley     - Z-Faces:  [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir
223a66d4d66SMatthew G Knepley 
224a66d4d66SMatthew G Knepley   We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment.
225a66d4d66SMatthew G Knepley @*/
22680800b1aSMatthew G Knepley PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[])
227a66d4d66SMatthew G Knepley {
228a66d4d66SMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
22988ed4aceSMatthew G Knepley   const PetscInt dim = da->dim;
23080800b1aSMatthew G Knepley   PetscInt       numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0};
23188ed4aceSMatthew G Knepley   PetscSF        sf;
232feafbc5cSMatthew G Knepley   PetscMPIInt    rank;
23388ed4aceSMatthew G Knepley   const PetscMPIInt *neighbors;
23488ed4aceSMatthew G Knepley   PetscInt      *localPoints;
23588ed4aceSMatthew G Knepley   PetscSFNode   *remotePoints;
236f5eeb527SMatthew G Knepley   PetscInt       nleaves = 0,  nleavesCheck = 0, nL = 0;
23757459e9aSMatthew G Knepley   PetscInt       nC, nVx, nVy, nVz, nV, nxF, nXF, nyF, nYF, nzF, nZF;
23857459e9aSMatthew G Knepley   PetscInt       pStart, pEnd, cStart, cEnd, vStart, vEnd, fStart, fEnd, xfStart, xfEnd, yfStart, yfEnd, zfStart, zfEnd;
23988ed4aceSMatthew G Knepley   PetscInt       f, v, c, xf, yf, zf, xn, yn, zn;
240a66d4d66SMatthew G Knepley   PetscErrorCode ierr;
241a66d4d66SMatthew G Knepley 
242a66d4d66SMatthew G Knepley   PetscFunctionBegin;
243a66d4d66SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
244feafbc5cSMatthew G Knepley   ierr = MPI_Comm_rank(((PetscObject) dm)->comm, &rank);CHKERRQ(ierr);
24557459e9aSMatthew G Knepley   ierr = DMDAGetNumCells(dm, &nC);CHKERRQ(ierr);
24657459e9aSMatthew G Knepley   ierr = DMDAGetNumVertices(dm, &nVx, &nVy, &nVz, &nV);CHKERRQ(ierr);
24757459e9aSMatthew G Knepley   ierr = DMDAGetNumFaces(dm, &nxF, &nXF, &nyF, &nYF, &nzF, &nZF);CHKERRQ(ierr);
24857459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, -1,  &pStart, &pEnd);CHKERRQ(ierr);
24957459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 0,   &cStart, &cEnd);CHKERRQ(ierr);
25057459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, 1,   &fStart, &fEnd);CHKERRQ(ierr);
25157459e9aSMatthew G Knepley   ierr = DMDAGetHeightStratum(dm, dim, &vStart, &vEnd);CHKERRQ(ierr);
25257459e9aSMatthew G Knepley   xfStart = vEnd;  xfEnd = xfStart+nXF;
25357459e9aSMatthew G Knepley   yfStart = xfEnd; yfEnd = yfStart+nYF;
25457459e9aSMatthew G Knepley   zfStart = yfEnd; zfEnd = zfStart+nZF;
25557459e9aSMatthew G Knepley   if (zfEnd != fEnd) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "Invalid face end %d, should be %d", zfEnd, fEnd);
25688ed4aceSMatthew G Knepley   /* Create local section */
25780800b1aSMatthew G Knepley   ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr);
258a66d4d66SMatthew G Knepley   for(f = 0; f < numFields; ++f) {
259a66d4d66SMatthew G Knepley     if (numVertexDof) {numVertexTotDof  += numVertexDof[f];}
260a66d4d66SMatthew G Knepley     if (numCellDof)   {numCellTotDof    += numCellDof[f];}
26188ed4aceSMatthew G Knepley     if (numFaceDof)   {numFaceTotDof[0] += numFaceDof[f*dim+0];
26288ed4aceSMatthew G Knepley                        numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0;
26388ed4aceSMatthew G Knepley                        numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0;}
264a66d4d66SMatthew G Knepley   }
26588ed4aceSMatthew G Knepley   ierr = PetscSectionCreate(((PetscObject) dm)->comm, &dm->defaultSection);CHKERRQ(ierr);
266a66d4d66SMatthew G Knepley   if (numFields > 1) {
26788ed4aceSMatthew G Knepley     ierr = PetscSectionSetNumFields(dm->defaultSection, numFields);CHKERRQ(ierr);
268a66d4d66SMatthew G Knepley     for(f = 0; f < numFields; ++f) {
26980800b1aSMatthew G Knepley       const char *name;
27080800b1aSMatthew G Knepley 
27180800b1aSMatthew G Knepley       ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr);
27288ed4aceSMatthew G Knepley       ierr = PetscSectionSetFieldName(dm->defaultSection, f, name);CHKERRQ(ierr);
27380800b1aSMatthew G Knepley       if (numComp) {
27488ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldComponents(dm->defaultSection, f, numComp[f]);CHKERRQ(ierr);
275a66d4d66SMatthew G Knepley       }
276a66d4d66SMatthew G Knepley     }
277a66d4d66SMatthew G Knepley   } else {
278a66d4d66SMatthew G Knepley     numFields = 0;
279a66d4d66SMatthew G Knepley   }
28088ed4aceSMatthew G Knepley   ierr = PetscSectionSetChart(dm->defaultSection, pStart, pEnd);CHKERRQ(ierr);
281a66d4d66SMatthew G Knepley   if (numVertexDof) {
282a66d4d66SMatthew G Knepley     for(v = vStart; v < vEnd; ++v) {
283a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
28488ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, v, f, numVertexDof[f]);CHKERRQ(ierr);
285a66d4d66SMatthew G Knepley       }
28688ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, v, numVertexTotDof);CHKERRQ(ierr);
287a66d4d66SMatthew G Knepley     }
288a66d4d66SMatthew G Knepley   }
289a66d4d66SMatthew G Knepley   if (numFaceDof) {
290a66d4d66SMatthew G Knepley     for(xf = xfStart; xf < xfEnd; ++xf) {
291a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
29288ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, xf, f, numFaceDof[f*dim+0]);CHKERRQ(ierr);
293a66d4d66SMatthew G Knepley       }
29488ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, xf, numFaceTotDof[0]);CHKERRQ(ierr);
295a66d4d66SMatthew G Knepley     }
296a66d4d66SMatthew G Knepley     for(yf = yfStart; yf < yfEnd; ++yf) {
297a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
29888ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, yf, f, numFaceDof[f*dim+1]);CHKERRQ(ierr);
299a66d4d66SMatthew G Knepley       }
30088ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, yf, numFaceTotDof[1]);CHKERRQ(ierr);
301a66d4d66SMatthew G Knepley     }
302a66d4d66SMatthew G Knepley     for(zf = zfStart; zf < zfEnd; ++zf) {
303a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
30488ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, zf, f, numFaceDof[f*dim+2]);CHKERRQ(ierr);
305a66d4d66SMatthew G Knepley       }
30688ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, zf, numFaceTotDof[2]);CHKERRQ(ierr);
307a66d4d66SMatthew G Knepley     }
308a66d4d66SMatthew G Knepley   }
309a66d4d66SMatthew G Knepley   if (numCellDof) {
310a66d4d66SMatthew G Knepley     for(c = cStart; c < cEnd; ++c) {
311a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
31288ed4aceSMatthew G Knepley         ierr = PetscSectionSetFieldDof(dm->defaultSection, c, f, numCellDof[f]);CHKERRQ(ierr);
313a66d4d66SMatthew G Knepley       }
31488ed4aceSMatthew G Knepley       ierr = PetscSectionSetDof(dm->defaultSection, c, numCellTotDof);CHKERRQ(ierr);
315a66d4d66SMatthew G Knepley     }
316a66d4d66SMatthew G Knepley   }
31788ed4aceSMatthew G Knepley   ierr = PetscSectionSetUp(dm->defaultSection);CHKERRQ(ierr);
31888ed4aceSMatthew G Knepley   /* Create mesh point SF */
31988ed4aceSMatthew G Knepley   ierr = DMDAGetNeighbors(dm, &neighbors);CHKERRQ(ierr);
32088ed4aceSMatthew G Knepley   for(zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
32188ed4aceSMatthew G Knepley     for(yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
32288ed4aceSMatthew G Knepley       for(xn = 0; xn < 3; ++xn) {
3237128ae9fSMatthew G Knepley         const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
32488ed4aceSMatthew G Knepley         const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
32588ed4aceSMatthew G Knepley 
3263814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
327feafbc5cSMatthew G Knepley           nleaves += (!xp ? nVx : 1) * (!yp ? nVy : 1) * (!zp ? nVz : 1); /* vertices */
32888ed4aceSMatthew G Knepley           if (xp && !yp && !zp) {
32988ed4aceSMatthew G Knepley             nleaves += nxF; /* x faces */
33088ed4aceSMatthew G Knepley           } else if (yp && !zp && !xp) {
33188ed4aceSMatthew G Knepley             nleaves += nyF; /* y faces */
33288ed4aceSMatthew G Knepley           } else if (zp && !xp && !yp) {
33388ed4aceSMatthew G Knepley             nleaves += nzF; /* z faces */
33488ed4aceSMatthew G Knepley           }
33588ed4aceSMatthew G Knepley         }
33688ed4aceSMatthew G Knepley       }
33788ed4aceSMatthew G Knepley     }
33888ed4aceSMatthew G Knepley   }
33988ed4aceSMatthew G Knepley   ierr = PetscMalloc2(nleaves,PetscInt,&localPoints,nleaves,PetscSFNode,&remotePoints);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];
345f5eeb527SMatthew G Knepley         PetscInt       xv, yv, zv;
34688ed4aceSMatthew G Knepley 
3473814d604SMatthew G Knepley         if (neighbor >= 0 && neighbor < rank) {
34888ed4aceSMatthew G Knepley           if (xp < 0) { /* left */
34988ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
35088ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
35188ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* left bottom back vertex */
352f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx +     0 + nC;
353f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
354f5eeb527SMatthew G Knepley 
355f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
356f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
357f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
358f5eeb527SMatthew G Knepley                 ++nL;
35988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
36088ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* left bottom front vertex */
361f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx +     0 + nC;
362f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
363f5eeb527SMatthew G Knepley 
364f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
365f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
366f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
367f5eeb527SMatthew G Knepley                 ++nL;
36888ed4aceSMatthew G Knepley               } else {
36988ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* left bottom vertices */
370f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv, ++nL) {
371f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx +     0 + nC;
372f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
373f5eeb527SMatthew G Knepley 
374f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
375f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
376f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
377f5eeb527SMatthew G Knepley                 }
37888ed4aceSMatthew G Knepley               }
37988ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
38088ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
38188ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* left top back vertex */
382f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx +     0 + nC;
383f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
384f5eeb527SMatthew G Knepley 
385f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
386f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
387f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
388f5eeb527SMatthew G Knepley                 ++nL;
38988ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
39088ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* left top front vertex */
391f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC;
392f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
393f5eeb527SMatthew G Knepley 
394f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
395f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
396f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
397f5eeb527SMatthew G Knepley                 ++nL;
39888ed4aceSMatthew G Knepley               } else {
39988ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* left top vertices */
400f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv, ++nL) {
401f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx +     0 + nC;
402f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
403f5eeb527SMatthew G Knepley 
404f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
405f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
406f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
407f5eeb527SMatthew G Knepley                 }
40888ed4aceSMatthew G Knepley               }
40988ed4aceSMatthew G Knepley             } else {
41088ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
41188ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* left back vertices */
412f5eeb527SMatthew G Knepley                 for(yv = 0; yv < nVy; ++yv, ++nL) {
413f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx +     0 + nC;
414f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
415f5eeb527SMatthew G Knepley 
416f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
417f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
418f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
419f5eeb527SMatthew G Knepley                 }
42088ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
42188ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* left front vertices */
422f5eeb527SMatthew G Knepley                 for(yv = 0; yv < nVy; ++yv, ++nL) {
423f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx +     0 + nC;
424f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
425f5eeb527SMatthew G Knepley 
426f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
427f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
428f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
429f5eeb527SMatthew G Knepley                 }
43088ed4aceSMatthew G Knepley               } else {
43188ed4aceSMatthew G Knepley                 nleavesCheck += nVy*nVz; /* left vertices */
432f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv) {
433f5eeb527SMatthew G Knepley                   for(yv = 0; yv < nVy; ++yv, ++nL) {
434f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx +     0 + nC;
435f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + nVx-1 + nC; /* TODO: Correct this for neighbor sizes */
436f5eeb527SMatthew G Knepley 
437f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
438f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
439f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
440f5eeb527SMatthew G Knepley                   }
441f5eeb527SMatthew G Knepley                 }
44288ed4aceSMatthew G Knepley                 nleavesCheck += nxF;     /* left faces */
443f5eeb527SMatthew G Knepley                 for(xf = 0; xf < nxF; ++xf, ++nL) {
444f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
445f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
446f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
447f5eeb527SMatthew G Knepley 
448f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
449f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
450f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
451f5eeb527SMatthew G Knepley                 }
45288ed4aceSMatthew G Knepley               }
45388ed4aceSMatthew G Knepley             }
45488ed4aceSMatthew G Knepley           } else if (xp > 0) { /* right */
45588ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
45688ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
45788ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* right bottom back vertex */
458f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy +     0)*nVx + nVx-1 + nC;
459f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
460f5eeb527SMatthew G Knepley 
461f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
462f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
463f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
464f5eeb527SMatthew G Knepley                 ++nL;
46588ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
46688ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* right bottom front vertex */
467f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + nVx-1 + nC;
468f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
469f5eeb527SMatthew G Knepley 
470f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
471f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
472f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
473f5eeb527SMatthew G Knepley                 ++nL;
47488ed4aceSMatthew G Knepley               } else {
47588ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* right bottom vertices */
476f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv, ++nL) {
477f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy +     0)*nVx + nVx-1 + nC;
478f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
479f5eeb527SMatthew G Knepley 
480f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
481f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
482f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
483f5eeb527SMatthew G Knepley                 }
48488ed4aceSMatthew G Knepley               }
48588ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
48688ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
48788ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* right top back vertex */
488f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + nVx-1 + nC;
489f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
490f5eeb527SMatthew G Knepley 
491f5eeb527SMatthew G Knepley                 localPoints[nL]        = localVertex;
492f5eeb527SMatthew G Knepley                 remotePoints[nL].rank  = neighbor;
493f5eeb527SMatthew G Knepley                 remotePoints[nL].index = remoteVertex;
494f5eeb527SMatthew G Knepley                 ++nL;
49588ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
49688ed4aceSMatthew G Knepley                 nleavesCheck += 1; /* right top front vertex */
497f5eeb527SMatthew G Knepley                 const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + nVx-1 + nC;
498f5eeb527SMatthew G Knepley                 const PetscInt remoteVertex = (      0*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
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 {
50588ed4aceSMatthew G Knepley                 nleavesCheck += nVz; /* right top vertices */
506f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv, ++nL) {
507f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + nVx-1 + nC;
508f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (zv*nVy +     0)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
509f5eeb527SMatthew G Knepley 
510f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
511f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
512f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
513f5eeb527SMatthew G Knepley                 }
51488ed4aceSMatthew G Knepley               }
51588ed4aceSMatthew G Knepley             } else {
51688ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
51788ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* right back vertices */
518f5eeb527SMatthew G Knepley                 for(yv = 0; yv < nVy; ++yv, ++nL) {
519f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy + yv)*nVx + nVx-1 + nC;
520f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
521f5eeb527SMatthew G Knepley 
522f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
523f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
524f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
525f5eeb527SMatthew G Knepley                 }
52688ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
52788ed4aceSMatthew G Knepley                 nleavesCheck += nVy; /* right front vertices */
528f5eeb527SMatthew G Knepley                 for(yv = 0; yv < nVy; ++yv, ++nL) {
529f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + nVx-1 + nC;
530f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + yv)*nVx +     0 + nC; /* TODO: Correct this for neighbor sizes */
531f5eeb527SMatthew G Knepley 
532f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
533f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
534f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
535f5eeb527SMatthew G Knepley                 }
53688ed4aceSMatthew G Knepley               } else {
53788ed4aceSMatthew G Knepley                 nleavesCheck += nVy*nVz; /* right vertices */
538f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv) {
539f5eeb527SMatthew G Knepley                   for(yv = 0; yv < nVy; ++yv, ++nL) {
540f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy + yv)*nVx + nVx-1 + nC;
541f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + yv)*nVx + 0     + nC; /* TODO: Correct this for neighbor sizes */
542f5eeb527SMatthew G Knepley 
543f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
544f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
545f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
546f5eeb527SMatthew G Knepley                   }
547f5eeb527SMatthew G Knepley                 }
54888ed4aceSMatthew G Knepley                 nleavesCheck += nxF;     /* right faces */
549f5eeb527SMatthew G Knepley                 for(xf = 0; xf < nxF; ++xf, ++nL) {
550f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
551f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
552f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
553f5eeb527SMatthew G Knepley 
554f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
555f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
556f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
557f5eeb527SMatthew G Knepley                 }
55888ed4aceSMatthew G Knepley               }
55988ed4aceSMatthew G Knepley             }
56088ed4aceSMatthew G Knepley           } else {
56188ed4aceSMatthew G Knepley             if (yp < 0) { /* bottom */
56288ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
56388ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* bottom back vertices */
564f5eeb527SMatthew G Knepley                 for(xv = 0; xv < nVx; ++xv, ++nL) {
565f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy +     0)*nVx + xv + nC;
566f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
567f5eeb527SMatthew G Knepley 
568f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
569f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
570f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
571f5eeb527SMatthew G Knepley                 }
57288ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
57388ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* bottom front vertices */
574f5eeb527SMatthew G Knepley                 for(xv = 0; xv < nVx; ++xv, ++nL) {
575f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy +     0)*nVx + xv + nC;
576f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
577f5eeb527SMatthew G Knepley 
578f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
579f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
580f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
581f5eeb527SMatthew G Knepley                 }
58288ed4aceSMatthew G Knepley               } else {
58388ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVz; /* bottom vertices */
584f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv) {
585f5eeb527SMatthew G Knepley                   for(xv = 0; xv < nVx; ++xv, ++nL) {
586f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy +     0)*nVx + xv + nC;
587f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy + nVy-1)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
588f5eeb527SMatthew G Knepley 
589f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
590f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
591f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
592f5eeb527SMatthew G Knepley                   }
593f5eeb527SMatthew G Knepley                 }
59488ed4aceSMatthew G Knepley                 nleavesCheck += nyF;     /* bottom faces */
595f5eeb527SMatthew G Knepley                 for(yf = 0; yf < nyF; ++yf, ++nL) {
596f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
597f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
598f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
599f5eeb527SMatthew G Knepley 
600f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
601f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
602f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
603f5eeb527SMatthew G Knepley                 }
60488ed4aceSMatthew G Knepley               }
60588ed4aceSMatthew G Knepley             } else if (yp > 0) { /* top */
60688ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
60788ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* top back vertices */
608f5eeb527SMatthew G Knepley                 for(xv = 0; xv < nVx; ++xv, ++nL) {
609f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = (      0*nVy + nVy-1)*nVx + xv + nC;
610f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = ((nVz-1)*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
611f5eeb527SMatthew G Knepley 
612f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
613f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
614f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
615f5eeb527SMatthew G Knepley                 }
61688ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
61788ed4aceSMatthew G Knepley                 nleavesCheck += nVx; /* top front vertices */
618f5eeb527SMatthew G Knepley                 for(xv = 0; xv < nVx; ++xv, ++nL) {
619f5eeb527SMatthew G Knepley                   const PetscInt localVertex  = ((nVz-1)*nVy + nVy-1)*nVx + xv + nC;
620f5eeb527SMatthew G Knepley                   const PetscInt remoteVertex = (      0*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
621f5eeb527SMatthew G Knepley 
622f5eeb527SMatthew G Knepley                   localPoints[nL]        = localVertex;
623f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
624f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteVertex;
625f5eeb527SMatthew G Knepley                 }
62688ed4aceSMatthew G Knepley               } else {
62788ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVz; /* top vertices */
628f5eeb527SMatthew G Knepley                 for(zv = 0; zv < nVz; ++zv) {
629f5eeb527SMatthew G Knepley                   for(xv = 0; xv < nVx; ++xv, ++nL) {
630f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (zv*nVy + nVy-1)*nVx + xv + nC;
631f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (zv*nVy +     0)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
632f5eeb527SMatthew G Knepley 
633f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
634f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
635f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
636f5eeb527SMatthew G Knepley                   }
637f5eeb527SMatthew G Knepley                 }
63888ed4aceSMatthew G Knepley                 nleavesCheck += nyF;     /* top faces */
639f5eeb527SMatthew G Knepley                 for(yf = 0; yf < nyF; ++yf, ++nL) {
640f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
641f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
642f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
643f5eeb527SMatthew G Knepley 
644f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
645f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
646f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
647f5eeb527SMatthew G Knepley                 }
64888ed4aceSMatthew G Knepley               }
64988ed4aceSMatthew G Knepley             } else {
65088ed4aceSMatthew G Knepley               if (zp < 0) { /* back */
65188ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVy; /* back vertices */
652f5eeb527SMatthew G Knepley                 for(yv = 0; yv < nVy; ++yv) {
653f5eeb527SMatthew G Knepley                   for(xv = 0; xv < nVx; ++xv, ++nL) {
654f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = (      0*nVy + yv)*nVx + xv + nC;
655f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = ((nVz-1)*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
656f5eeb527SMatthew G Knepley 
657f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
658f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
659f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
660f5eeb527SMatthew G Knepley                   }
661f5eeb527SMatthew G Knepley                 }
66288ed4aceSMatthew G Knepley                 nleavesCheck += nzF;     /* back faces */
663f5eeb527SMatthew G Knepley                 for(zf = 0; zf < nzF; ++zf, ++nL) {
664f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
665f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
666f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
667f5eeb527SMatthew G Knepley 
668f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
669f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
670f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
671f5eeb527SMatthew G Knepley                 }
67288ed4aceSMatthew G Knepley               } else if (zp > 0) { /* front */
67388ed4aceSMatthew G Knepley                 nleavesCheck += nVx*nVy; /* front vertices */
674f5eeb527SMatthew G Knepley                 for(yv = 0; yv < nVy; ++yv) {
675f5eeb527SMatthew G Knepley                   for(xv = 0; xv < nVx; ++xv, ++nL) {
676f5eeb527SMatthew G Knepley                     const PetscInt localVertex  = ((nVz-1)*nVy + yv)*nVx + xv + nC;
677f5eeb527SMatthew G Knepley                     const PetscInt remoteVertex = (      0*nVy + yv)*nVx + xv + nC; /* TODO: Correct this for neighbor sizes */
678f5eeb527SMatthew G Knepley 
679f5eeb527SMatthew G Knepley                     localPoints[nL]        = localVertex;
680f5eeb527SMatthew G Knepley                     remotePoints[nL].rank  = neighbor;
681f5eeb527SMatthew G Knepley                     remotePoints[nL].index = remoteVertex;
682f5eeb527SMatthew G Knepley                   }
683f5eeb527SMatthew G Knepley                 }
68488ed4aceSMatthew G Knepley                 nleavesCheck += nzF;     /* front faces */
685f5eeb527SMatthew G Knepley                 for(zf = 0; zf < nzF; ++zf, ++nL) {
686f5eeb527SMatthew G Knepley                   /* THIS IS WRONG */
687f5eeb527SMatthew G Knepley                   const PetscInt localFace  = 0 + nC+nV;
688f5eeb527SMatthew G Knepley                   const PetscInt remoteFace = 0 + nC+nV;
689f5eeb527SMatthew G Knepley 
690f5eeb527SMatthew G Knepley                   localPoints[nL]        = localFace;
691f5eeb527SMatthew G Knepley                   remotePoints[nL].rank  = neighbor;
692f5eeb527SMatthew G Knepley                   remotePoints[nL].index = remoteFace;
693f5eeb527SMatthew G Knepley                 }
69488ed4aceSMatthew G Knepley               } else {
69588ed4aceSMatthew G Knepley                 /* Nothing is shared from the interior */
69688ed4aceSMatthew G Knepley               }
69788ed4aceSMatthew G Knepley             }
69888ed4aceSMatthew G Knepley           }
69988ed4aceSMatthew G Knepley         }
70088ed4aceSMatthew G Knepley       }
70188ed4aceSMatthew G Knepley     }
70288ed4aceSMatthew G Knepley   }
7033814d604SMatthew G Knepley   /* TODO: Remove duplication in leaf determination */
70488ed4aceSMatthew G Knepley   if (nleaves != nleavesCheck) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "The number of leaves %d did not match the number of remote leaves %d", nleaves, nleavesCheck);
70588ed4aceSMatthew G Knepley   ierr = PetscSFCreate(((PetscObject) dm)->comm, &sf);CHKERRQ(ierr);
70688ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);CHKERRQ(ierr);
70788ed4aceSMatthew G Knepley   /* Create global section */
708*eaf8d80aSMatthew G Knepley   ierr = PetscSectionCreateGlobalSection(dm->defaultSection, sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
70988ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&sf);CHKERRQ(ierr);
71088ed4aceSMatthew G Knepley   /* Create default SF */
71188ed4aceSMatthew G Knepley   ierr = DMCreateDefaultSF(dm, dm->defaultSection, dm->defaultGlobalSection);CHKERRQ(ierr);
712a66d4d66SMatthew G Knepley   PetscFunctionReturn(0);
713a66d4d66SMatthew G Knepley }
714a66d4d66SMatthew G Knepley 
71547c6ae99SBarry Smith /* ------------------------------------------------------------------- */
71647c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
71747c6ae99SBarry Smith 
71847c6ae99SBarry Smith EXTERN_C_BEGIN
719c6db04a5SJed Brown #include <adic/ad_utils.h>
72047c6ae99SBarry Smith EXTERN_C_END
72147c6ae99SBarry Smith 
72247c6ae99SBarry Smith #undef __FUNCT__
723aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicArray"
72447c6ae99SBarry Smith /*@C
725aa219208SBarry Smith      DMDAGetAdicArray - Gets an array of derivative types for a DMDA
72647c6ae99SBarry Smith 
72747c6ae99SBarry Smith     Input Parameter:
72847c6ae99SBarry Smith +    da - information about my local patch
72947c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
73047c6ae99SBarry Smith 
73147c6ae99SBarry Smith     Output Parameters:
73247c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
73347c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
73447c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
73547c6ae99SBarry Smith 
73647c6ae99SBarry Smith      Notes:
73747c6ae99SBarry Smith        The vector values are NOT initialized and may have garbage in them, so you may need
73847c6ae99SBarry Smith        to zero them.
73947c6ae99SBarry Smith 
740aa219208SBarry Smith        Returns the same type of object as the DMDAVecGetArray() except its elements are
74147c6ae99SBarry Smith            derivative types instead of PetscScalars
74247c6ae99SBarry Smith 
74347c6ae99SBarry Smith      Level: advanced
74447c6ae99SBarry Smith 
745aa219208SBarry Smith .seealso: DMDARestoreAdicArray()
74647c6ae99SBarry Smith 
74747c6ae99SBarry Smith @*/
7487087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
74947c6ae99SBarry Smith {
75047c6ae99SBarry Smith   PetscErrorCode ierr;
75147c6ae99SBarry Smith   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
75247c6ae99SBarry Smith   char           *iarray_start;
75347c6ae99SBarry Smith   void           **iptr = (void**)vptr;
75447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
75547c6ae99SBarry Smith 
75647c6ae99SBarry Smith   PetscFunctionBegin;
75747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
75847c6ae99SBarry Smith   if (ghosted) {
759aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
76047c6ae99SBarry Smith       if (dd->adarrayghostedin[i]) {
76147c6ae99SBarry Smith         *iptr                   = dd->adarrayghostedin[i];
76247c6ae99SBarry Smith         iarray_start            = (char*)dd->adstartghostedin[i];
76347c6ae99SBarry Smith         itdof                   = dd->ghostedtdof;
76447c6ae99SBarry Smith         dd->adarrayghostedin[i] = PETSC_NULL;
76547c6ae99SBarry Smith         dd->adstartghostedin[i] = PETSC_NULL;
76647c6ae99SBarry Smith 
76747c6ae99SBarry Smith         goto done;
76847c6ae99SBarry Smith       }
76947c6ae99SBarry Smith     }
77047c6ae99SBarry Smith     xs = dd->Xs;
77147c6ae99SBarry Smith     ys = dd->Ys;
77247c6ae99SBarry Smith     zs = dd->Zs;
77347c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
77447c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
77547c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
77647c6ae99SBarry Smith   } else {
777aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
77847c6ae99SBarry Smith       if (dd->adarrayin[i]) {
77947c6ae99SBarry Smith         *iptr            = dd->adarrayin[i];
78047c6ae99SBarry Smith         iarray_start     = (char*)dd->adstartin[i];
78147c6ae99SBarry Smith         itdof            = dd->tdof;
78247c6ae99SBarry Smith         dd->adarrayin[i] = PETSC_NULL;
78347c6ae99SBarry Smith         dd->adstartin[i] = PETSC_NULL;
78447c6ae99SBarry Smith 
78547c6ae99SBarry Smith         goto done;
78647c6ae99SBarry Smith       }
78747c6ae99SBarry Smith     }
78847c6ae99SBarry Smith     xs = dd->xs;
78947c6ae99SBarry Smith     ys = dd->ys;
79047c6ae99SBarry Smith     zs = dd->zs;
79147c6ae99SBarry Smith     xm = dd->xe-dd->xs;
79247c6ae99SBarry Smith     ym = dd->ye-dd->ys;
79347c6ae99SBarry Smith     zm = dd->ze-dd->zs;
79447c6ae99SBarry Smith   }
79547c6ae99SBarry Smith   deriv_type_size = PetscADGetDerivTypeSize();
79647c6ae99SBarry Smith 
79747c6ae99SBarry Smith   switch (dd->dim) {
79847c6ae99SBarry Smith     case 1: {
79947c6ae99SBarry Smith       void *ptr;
80047c6ae99SBarry Smith       itdof = xm;
80147c6ae99SBarry Smith 
80247c6ae99SBarry Smith       ierr  = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
80347c6ae99SBarry Smith 
80447c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*deriv_type_size);
80547c6ae99SBarry Smith       *iptr = (void*)ptr;
80647c6ae99SBarry Smith       break;}
80747c6ae99SBarry Smith     case 2: {
80847c6ae99SBarry Smith       void **ptr;
80947c6ae99SBarry Smith       itdof = xm*ym;
81047c6ae99SBarry Smith 
81147c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr);
81247c6ae99SBarry Smith 
81347c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
81447c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
81547c6ae99SBarry Smith         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
81647c6ae99SBarry Smith       }
81747c6ae99SBarry Smith       *iptr = (void*)ptr;
81847c6ae99SBarry Smith       break;}
81947c6ae99SBarry Smith     case 3: {
82047c6ae99SBarry Smith       void ***ptr,**bptr;
82147c6ae99SBarry Smith       itdof = xm*ym*zm;
82247c6ae99SBarry Smith 
82347c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
82447c6ae99SBarry Smith 
82547c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
82647c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
82747c6ae99SBarry Smith 
82847c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
82947c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
83047c6ae99SBarry Smith       }
83147c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
83247c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
83347c6ae99SBarry Smith           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
83447c6ae99SBarry Smith         }
83547c6ae99SBarry Smith       }
83647c6ae99SBarry Smith 
83747c6ae99SBarry Smith       *iptr = (void*)ptr;
83847c6ae99SBarry Smith       break;}
83947c6ae99SBarry Smith     default:
84047c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
84147c6ae99SBarry Smith   }
84247c6ae99SBarry Smith 
84347c6ae99SBarry Smith   done:
84447c6ae99SBarry Smith   /* add arrays to the checked out list */
84547c6ae99SBarry Smith   if (ghosted) {
846aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
84747c6ae99SBarry Smith       if (!dd->adarrayghostedout[i]) {
84847c6ae99SBarry Smith         dd->adarrayghostedout[i] = *iptr ;
84947c6ae99SBarry Smith         dd->adstartghostedout[i] = iarray_start;
85047c6ae99SBarry Smith         dd->ghostedtdof          = itdof;
85147c6ae99SBarry Smith         break;
85247c6ae99SBarry Smith       }
85347c6ae99SBarry Smith     }
85447c6ae99SBarry Smith   } else {
855aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
85647c6ae99SBarry Smith       if (!dd->adarrayout[i]) {
85747c6ae99SBarry Smith         dd->adarrayout[i] = *iptr ;
85847c6ae99SBarry Smith         dd->adstartout[i] = iarray_start;
85947c6ae99SBarry Smith         dd->tdof          = itdof;
86047c6ae99SBarry Smith         break;
86147c6ae99SBarry Smith       }
86247c6ae99SBarry Smith     }
86347c6ae99SBarry Smith   }
864aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
86547c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
86647c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
86747c6ae99SBarry Smith   PetscFunctionReturn(0);
86847c6ae99SBarry Smith }
86947c6ae99SBarry Smith 
87047c6ae99SBarry Smith #undef __FUNCT__
871aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicArray"
87247c6ae99SBarry Smith /*@C
873aa219208SBarry Smith      DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
87447c6ae99SBarry Smith 
87547c6ae99SBarry Smith     Input Parameter:
87647c6ae99SBarry Smith +    da - information about my local patch
87747c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
87847c6ae99SBarry Smith 
87947c6ae99SBarry Smith     Output Parameters:
88047c6ae99SBarry Smith +    ptr - array data structured to be passed to ad_FormFunctionLocal()
88147c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
88247c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
88347c6ae99SBarry Smith 
88447c6ae99SBarry Smith      Level: advanced
88547c6ae99SBarry Smith 
886aa219208SBarry Smith .seealso: DMDAGetAdicArray()
88747c6ae99SBarry Smith 
88847c6ae99SBarry Smith @*/
8897087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
89047c6ae99SBarry Smith {
89147c6ae99SBarry Smith   PetscInt  i;
89247c6ae99SBarry Smith   void      **iptr = (void**)ptr,iarray_start = 0;
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith   PetscFunctionBegin;
89547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
89647c6ae99SBarry Smith   if (ghosted) {
897aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
89847c6ae99SBarry Smith       if (dd->adarrayghostedout[i] == *iptr) {
89947c6ae99SBarry Smith         iarray_start             = dd->adstartghostedout[i];
90047c6ae99SBarry Smith         dd->adarrayghostedout[i] = PETSC_NULL;
90147c6ae99SBarry Smith         dd->adstartghostedout[i] = PETSC_NULL;
90247c6ae99SBarry Smith         break;
90347c6ae99SBarry Smith       }
90447c6ae99SBarry Smith     }
90547c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
906aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
90747c6ae99SBarry Smith       if (!dd->adarrayghostedin[i]){
90847c6ae99SBarry Smith         dd->adarrayghostedin[i] = *iptr;
90947c6ae99SBarry Smith         dd->adstartghostedin[i] = iarray_start;
91047c6ae99SBarry Smith         break;
91147c6ae99SBarry Smith       }
91247c6ae99SBarry Smith     }
91347c6ae99SBarry Smith   } else {
914aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
91547c6ae99SBarry Smith       if (dd->adarrayout[i] == *iptr) {
91647c6ae99SBarry Smith         iarray_start      = dd->adstartout[i];
91747c6ae99SBarry Smith         dd->adarrayout[i] = PETSC_NULL;
91847c6ae99SBarry Smith         dd->adstartout[i] = PETSC_NULL;
91947c6ae99SBarry Smith         break;
92047c6ae99SBarry Smith       }
92147c6ae99SBarry Smith     }
92247c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
923aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
92447c6ae99SBarry Smith       if (!dd->adarrayin[i]){
92547c6ae99SBarry Smith         dd->adarrayin[i]   = *iptr;
92647c6ae99SBarry Smith         dd->adstartin[i]   = iarray_start;
92747c6ae99SBarry Smith         break;
92847c6ae99SBarry Smith       }
92947c6ae99SBarry Smith     }
93047c6ae99SBarry Smith   }
93147c6ae99SBarry Smith   PetscFunctionReturn(0);
93247c6ae99SBarry Smith }
93347c6ae99SBarry Smith 
93447c6ae99SBarry Smith #undef __FUNCT__
93547c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray"
9367087cfbeSBarry Smith PetscErrorCode  ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
93747c6ae99SBarry Smith {
93847c6ae99SBarry Smith   PetscErrorCode ierr;
93947c6ae99SBarry Smith   PetscFunctionBegin;
940aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
94147c6ae99SBarry Smith   PetscFunctionReturn(0);
94247c6ae99SBarry Smith }
94347c6ae99SBarry Smith 
94447c6ae99SBarry Smith #undef __FUNCT__
94547c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray"
9467087cfbeSBarry Smith PetscErrorCode  ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
94747c6ae99SBarry Smith {
94847c6ae99SBarry Smith   PetscErrorCode ierr;
94947c6ae99SBarry Smith   PetscFunctionBegin;
950aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
95147c6ae99SBarry Smith   PetscFunctionReturn(0);
95247c6ae99SBarry Smith }
95347c6ae99SBarry Smith 
95447c6ae99SBarry Smith #endif
95547c6ae99SBarry Smith 
95647c6ae99SBarry Smith #undef __FUNCT__
957aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
95847c6ae99SBarry Smith /*@C
959aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
96047c6ae99SBarry Smith 
96147c6ae99SBarry Smith     Input Parameter:
96247c6ae99SBarry Smith +    da - information about my local patch
96347c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
96447c6ae99SBarry Smith 
96547c6ae99SBarry Smith     Output Parameters:
96647c6ae99SBarry Smith .    vptr - array data structured
96747c6ae99SBarry Smith 
96847c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
96947c6ae99SBarry Smith            to zero them.
97047c6ae99SBarry Smith 
97147c6ae99SBarry Smith   Level: advanced
97247c6ae99SBarry Smith 
973aa219208SBarry Smith .seealso: DMDARestoreArray(), DMDAGetAdicArray()
97447c6ae99SBarry Smith 
97547c6ae99SBarry Smith @*/
9767087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool  ghosted,void *vptr)
97747c6ae99SBarry Smith {
97847c6ae99SBarry Smith   PetscErrorCode ierr;
97947c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
98047c6ae99SBarry Smith   char           *iarray_start;
98147c6ae99SBarry Smith   void           **iptr = (void**)vptr;
98247c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
98347c6ae99SBarry Smith 
98447c6ae99SBarry Smith   PetscFunctionBegin;
98547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
98647c6ae99SBarry Smith   if (ghosted) {
987aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
98847c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
98947c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
99047c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
99147c6ae99SBarry Smith         dd->arrayghostedin[i] = PETSC_NULL;
99247c6ae99SBarry Smith         dd->startghostedin[i] = PETSC_NULL;
99347c6ae99SBarry Smith 
99447c6ae99SBarry Smith         goto done;
99547c6ae99SBarry Smith       }
99647c6ae99SBarry Smith     }
99747c6ae99SBarry Smith     xs = dd->Xs;
99847c6ae99SBarry Smith     ys = dd->Ys;
99947c6ae99SBarry Smith     zs = dd->Zs;
100047c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
100147c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
100247c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
100347c6ae99SBarry Smith   } else {
1004aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
100547c6ae99SBarry Smith       if (dd->arrayin[i]) {
100647c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
100747c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
100847c6ae99SBarry Smith         dd->arrayin[i] = PETSC_NULL;
100947c6ae99SBarry Smith         dd->startin[i] = PETSC_NULL;
101047c6ae99SBarry Smith 
101147c6ae99SBarry Smith         goto done;
101247c6ae99SBarry Smith       }
101347c6ae99SBarry Smith     }
101447c6ae99SBarry Smith     xs = dd->xs;
101547c6ae99SBarry Smith     ys = dd->ys;
101647c6ae99SBarry Smith     zs = dd->zs;
101747c6ae99SBarry Smith     xm = dd->xe-dd->xs;
101847c6ae99SBarry Smith     ym = dd->ye-dd->ys;
101947c6ae99SBarry Smith     zm = dd->ze-dd->zs;
102047c6ae99SBarry Smith   }
102147c6ae99SBarry Smith 
102247c6ae99SBarry Smith   switch (dd->dim) {
102347c6ae99SBarry Smith     case 1: {
102447c6ae99SBarry Smith       void *ptr;
102547c6ae99SBarry Smith 
102647c6ae99SBarry Smith       ierr  = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
102747c6ae99SBarry Smith 
102847c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
102947c6ae99SBarry Smith       *iptr = (void*)ptr;
103047c6ae99SBarry Smith       break;}
103147c6ae99SBarry Smith     case 2: {
103247c6ae99SBarry Smith       void **ptr;
103347c6ae99SBarry Smith 
103447c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
103547c6ae99SBarry Smith 
103647c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
103747c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
103847c6ae99SBarry Smith         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
103947c6ae99SBarry Smith       }
104047c6ae99SBarry Smith       *iptr = (void*)ptr;
104147c6ae99SBarry Smith       break;}
104247c6ae99SBarry Smith     case 3: {
104347c6ae99SBarry Smith       void ***ptr,**bptr;
104447c6ae99SBarry Smith 
104547c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
104647c6ae99SBarry Smith 
104747c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
104847c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
104947c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
105047c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
105147c6ae99SBarry Smith       }
105247c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
105347c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
105447c6ae99SBarry Smith           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
105547c6ae99SBarry Smith         }
105647c6ae99SBarry Smith       }
105747c6ae99SBarry Smith 
105847c6ae99SBarry Smith       *iptr = (void*)ptr;
105947c6ae99SBarry Smith       break;}
106047c6ae99SBarry Smith     default:
106147c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
106247c6ae99SBarry Smith   }
106347c6ae99SBarry Smith 
106447c6ae99SBarry Smith   done:
106547c6ae99SBarry Smith   /* add arrays to the checked out list */
106647c6ae99SBarry Smith   if (ghosted) {
1067aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
106847c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
106947c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr ;
107047c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
107147c6ae99SBarry Smith         break;
107247c6ae99SBarry Smith       }
107347c6ae99SBarry Smith     }
107447c6ae99SBarry Smith   } else {
1075aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
107647c6ae99SBarry Smith       if (!dd->arrayout[i]) {
107747c6ae99SBarry Smith         dd->arrayout[i] = *iptr ;
107847c6ae99SBarry Smith         dd->startout[i] = iarray_start;
107947c6ae99SBarry Smith         break;
108047c6ae99SBarry Smith       }
108147c6ae99SBarry Smith     }
108247c6ae99SBarry Smith   }
108347c6ae99SBarry Smith   PetscFunctionReturn(0);
108447c6ae99SBarry Smith }
108547c6ae99SBarry Smith 
108647c6ae99SBarry Smith #undef __FUNCT__
1087aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
108847c6ae99SBarry Smith /*@C
1089aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
109047c6ae99SBarry Smith 
109147c6ae99SBarry Smith     Input Parameter:
109247c6ae99SBarry Smith +    da - information about my local patch
109347c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
109447c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
109547c6ae99SBarry Smith 
109647c6ae99SBarry Smith      Level: advanced
109747c6ae99SBarry Smith 
1098aa219208SBarry Smith .seealso: DMDAGetArray(), DMDAGetAdicArray()
109947c6ae99SBarry Smith 
110047c6ae99SBarry Smith @*/
11017087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool  ghosted,void *vptr)
110247c6ae99SBarry Smith {
110347c6ae99SBarry Smith   PetscInt  i;
110447c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
110547c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
110647c6ae99SBarry Smith 
110747c6ae99SBarry Smith   PetscFunctionBegin;
110847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
110947c6ae99SBarry Smith   if (ghosted) {
1110aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
111147c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
111247c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
111347c6ae99SBarry Smith         dd->arrayghostedout[i] = PETSC_NULL;
111447c6ae99SBarry Smith         dd->startghostedout[i] = PETSC_NULL;
111547c6ae99SBarry Smith         break;
111647c6ae99SBarry Smith       }
111747c6ae99SBarry Smith     }
1118aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
111947c6ae99SBarry Smith       if (!dd->arrayghostedin[i]){
112047c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
112147c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
112247c6ae99SBarry Smith         break;
112347c6ae99SBarry Smith       }
112447c6ae99SBarry Smith     }
112547c6ae99SBarry Smith   } else {
1126aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
112747c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
112847c6ae99SBarry Smith         iarray_start    = dd->startout[i];
112947c6ae99SBarry Smith         dd->arrayout[i] = PETSC_NULL;
113047c6ae99SBarry Smith         dd->startout[i] = PETSC_NULL;
113147c6ae99SBarry Smith         break;
113247c6ae99SBarry Smith       }
113347c6ae99SBarry Smith     }
1134aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
113547c6ae99SBarry Smith       if (!dd->arrayin[i]){
113647c6ae99SBarry Smith         dd->arrayin[i]  = *iptr;
113747c6ae99SBarry Smith         dd->startin[i]  = iarray_start;
113847c6ae99SBarry Smith         break;
113947c6ae99SBarry Smith       }
114047c6ae99SBarry Smith     }
114147c6ae99SBarry Smith   }
114247c6ae99SBarry Smith   PetscFunctionReturn(0);
114347c6ae99SBarry Smith }
114447c6ae99SBarry Smith 
114547c6ae99SBarry Smith #undef __FUNCT__
1146aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray"
114747c6ae99SBarry Smith /*@C
1148aa219208SBarry Smith      DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
114947c6ae99SBarry Smith 
115047c6ae99SBarry Smith      Input Parameter:
115147c6ae99SBarry Smith +    da - information about my local patch
115247c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
115347c6ae99SBarry Smith 
115447c6ae99SBarry Smith      Output Parameters:
115547c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
115647c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
115747c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
115847c6ae99SBarry Smith 
115947c6ae99SBarry Smith      Notes:
116047c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
116147c6ae99SBarry Smith      to zero them.
116247c6ae99SBarry Smith 
1163aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
116447c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
116547c6ae99SBarry Smith 
116647c6ae99SBarry Smith      Level: advanced
116747c6ae99SBarry Smith 
1168aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
116947c6ae99SBarry Smith 
117047c6ae99SBarry Smith @*/
11717087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
117247c6ae99SBarry Smith {
117347c6ae99SBarry Smith   PetscErrorCode ierr;
117447c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
117547c6ae99SBarry Smith   char           *iarray_start;
117647c6ae99SBarry Smith   void           **iptr = (void**)vptr;
117747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
117847c6ae99SBarry Smith 
117947c6ae99SBarry Smith   PetscFunctionBegin;
118047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
118147c6ae99SBarry Smith   if (ghosted) {
1182aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
118347c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
118447c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
118547c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
118647c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
118747c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
118847c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
118947c6ae99SBarry Smith 
119047c6ae99SBarry Smith         goto done;
119147c6ae99SBarry Smith       }
119247c6ae99SBarry Smith     }
119347c6ae99SBarry Smith     xs = dd->Xs;
119447c6ae99SBarry Smith     ys = dd->Ys;
119547c6ae99SBarry Smith     zs = dd->Zs;
119647c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
119747c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
119847c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
119947c6ae99SBarry Smith   } else {
1200aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
120147c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
120247c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
120347c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
120447c6ae99SBarry Smith         itdof              = dd->tdof;
120547c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
120647c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
120747c6ae99SBarry Smith 
120847c6ae99SBarry Smith         goto done;
120947c6ae99SBarry Smith       }
121047c6ae99SBarry Smith     }
121147c6ae99SBarry Smith     xs = dd->xs;
121247c6ae99SBarry Smith     ys = dd->ys;
121347c6ae99SBarry Smith     zs = dd->zs;
121447c6ae99SBarry Smith     xm = dd->xe-dd->xs;
121547c6ae99SBarry Smith     ym = dd->ye-dd->ys;
121647c6ae99SBarry Smith     zm = dd->ze-dd->zs;
121747c6ae99SBarry Smith   }
121847c6ae99SBarry Smith 
121947c6ae99SBarry Smith   switch (dd->dim) {
122047c6ae99SBarry Smith     case 1: {
122147c6ae99SBarry Smith       void *ptr;
122247c6ae99SBarry Smith       itdof = xm;
122347c6ae99SBarry Smith 
122447c6ae99SBarry Smith       ierr  = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
122547c6ae99SBarry Smith 
122647c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
122747c6ae99SBarry Smith       *iptr = (void*)ptr;
122847c6ae99SBarry Smith       break;}
122947c6ae99SBarry Smith     case 2: {
123047c6ae99SBarry Smith       void **ptr;
123147c6ae99SBarry Smith       itdof = xm*ym;
123247c6ae99SBarry Smith 
123347c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
123447c6ae99SBarry Smith 
123547c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
123647c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
123747c6ae99SBarry Smith         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
123847c6ae99SBarry Smith       }
123947c6ae99SBarry Smith       *iptr = (void*)ptr;
124047c6ae99SBarry Smith       break;}
124147c6ae99SBarry Smith     case 3: {
124247c6ae99SBarry Smith       void ***ptr,**bptr;
124347c6ae99SBarry Smith       itdof = xm*ym*zm;
124447c6ae99SBarry Smith 
124547c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
124647c6ae99SBarry Smith 
124747c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
124847c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
124947c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
125047c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
125147c6ae99SBarry Smith       }
125247c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
125347c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
125447c6ae99SBarry Smith           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
125547c6ae99SBarry Smith         }
125647c6ae99SBarry Smith       }
125747c6ae99SBarry Smith 
125847c6ae99SBarry Smith       *iptr = (void*)ptr;
125947c6ae99SBarry Smith       break;}
126047c6ae99SBarry Smith     default:
126147c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
126247c6ae99SBarry Smith   }
126347c6ae99SBarry Smith 
126447c6ae99SBarry Smith   done:
126547c6ae99SBarry Smith   /* add arrays to the checked out list */
126647c6ae99SBarry Smith   if (ghosted) {
1267aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
126847c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
126947c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
127047c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
127147c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
127247c6ae99SBarry Smith         break;
127347c6ae99SBarry Smith       }
127447c6ae99SBarry Smith     }
127547c6ae99SBarry Smith   } else {
1276aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
127747c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
127847c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
127947c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
128047c6ae99SBarry Smith         dd->tdof            = itdof;
128147c6ae99SBarry Smith         break;
128247c6ae99SBarry Smith       }
128347c6ae99SBarry Smith     }
128447c6ae99SBarry Smith   }
1285aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
128647c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
128747c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
128847c6ae99SBarry Smith   PetscFunctionReturn(0);
128947c6ae99SBarry Smith }
129047c6ae99SBarry Smith 
129147c6ae99SBarry Smith #undef __FUNCT__
1292aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray4"
12937087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
129447c6ae99SBarry Smith {
129547c6ae99SBarry Smith   PetscErrorCode ierr;
129687130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
129747c6ae99SBarry Smith   char           *iarray_start;
129847c6ae99SBarry Smith   void           **iptr = (void**)vptr;
129947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
130047c6ae99SBarry Smith 
130147c6ae99SBarry Smith   PetscFunctionBegin;
130247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
130347c6ae99SBarry Smith   if (ghosted) {
1304aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
130547c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
130647c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
130747c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
130847c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
130947c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
131047c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
131147c6ae99SBarry Smith 
131247c6ae99SBarry Smith         goto done;
131347c6ae99SBarry Smith       }
131447c6ae99SBarry Smith     }
131547c6ae99SBarry Smith     xs = dd->Xs;
131647c6ae99SBarry Smith     ys = dd->Ys;
131747c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
131847c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
131947c6ae99SBarry Smith   } else {
1320aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
132147c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
132247c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
132347c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
132447c6ae99SBarry Smith         itdof              = dd->tdof;
132547c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
132647c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
132747c6ae99SBarry Smith 
132847c6ae99SBarry Smith         goto done;
132947c6ae99SBarry Smith       }
133047c6ae99SBarry Smith     }
133147c6ae99SBarry Smith     xs = dd->xs;
133247c6ae99SBarry Smith     ys = dd->ys;
133347c6ae99SBarry Smith     xm = dd->xe-dd->xs;
133447c6ae99SBarry Smith     ym = dd->ye-dd->ys;
133547c6ae99SBarry Smith   }
133647c6ae99SBarry Smith 
133747c6ae99SBarry Smith   switch (dd->dim) {
133847c6ae99SBarry Smith     case 2: {
133947c6ae99SBarry Smith       void **ptr;
134047c6ae99SBarry Smith       itdof = xm*ym;
134147c6ae99SBarry Smith 
134247c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
134347c6ae99SBarry Smith 
134447c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
134547c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
134647c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
134747c6ae99SBarry Smith       }
134847c6ae99SBarry Smith       *iptr = (void*)ptr;
134947c6ae99SBarry Smith       break;}
135047c6ae99SBarry Smith     default:
135147c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
135247c6ae99SBarry Smith   }
135347c6ae99SBarry Smith 
135447c6ae99SBarry Smith   done:
135547c6ae99SBarry Smith   /* add arrays to the checked out list */
135647c6ae99SBarry Smith   if (ghosted) {
1357aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
135847c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
135947c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
136047c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
136147c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
136247c6ae99SBarry Smith         break;
136347c6ae99SBarry Smith       }
136447c6ae99SBarry Smith     }
136547c6ae99SBarry Smith   } else {
1366aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
136747c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
136847c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
136947c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
137047c6ae99SBarry Smith         dd->tdof            = itdof;
137147c6ae99SBarry Smith         break;
137247c6ae99SBarry Smith       }
137347c6ae99SBarry Smith     }
137447c6ae99SBarry Smith   }
1375aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
137647c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
137747c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
137847c6ae99SBarry Smith   PetscFunctionReturn(0);
137947c6ae99SBarry Smith }
138047c6ae99SBarry Smith 
138147c6ae99SBarry Smith #undef __FUNCT__
1382aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9"
13837087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
138447c6ae99SBarry Smith {
138547c6ae99SBarry Smith   PetscErrorCode ierr;
138687130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
138747c6ae99SBarry Smith   char           *iarray_start;
138847c6ae99SBarry Smith   void           **iptr = (void**)vptr;
138947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
139047c6ae99SBarry Smith 
139147c6ae99SBarry Smith   PetscFunctionBegin;
139247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
139347c6ae99SBarry Smith   if (ghosted) {
1394aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
139547c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
139647c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
139747c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
139847c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
139947c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
140047c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
140147c6ae99SBarry Smith 
140247c6ae99SBarry Smith         goto done;
140347c6ae99SBarry Smith       }
140447c6ae99SBarry Smith     }
140547c6ae99SBarry Smith     xs = dd->Xs;
140647c6ae99SBarry Smith     ys = dd->Ys;
140747c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
140847c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
140947c6ae99SBarry Smith   } else {
1410aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
141147c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
141247c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
141347c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
141447c6ae99SBarry Smith         itdof              = dd->tdof;
141547c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
141647c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
141747c6ae99SBarry Smith 
141847c6ae99SBarry Smith         goto done;
141947c6ae99SBarry Smith       }
142047c6ae99SBarry Smith     }
142147c6ae99SBarry Smith     xs = dd->xs;
142247c6ae99SBarry Smith     ys = dd->ys;
142347c6ae99SBarry Smith     xm = dd->xe-dd->xs;
142447c6ae99SBarry Smith     ym = dd->ye-dd->ys;
142547c6ae99SBarry Smith   }
142647c6ae99SBarry Smith 
142747c6ae99SBarry Smith   switch (dd->dim) {
142847c6ae99SBarry Smith     case 2: {
142947c6ae99SBarry Smith       void **ptr;
143047c6ae99SBarry Smith       itdof = xm*ym;
143147c6ae99SBarry Smith 
143247c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
143347c6ae99SBarry Smith 
143447c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
143547c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
143647c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
143747c6ae99SBarry Smith       }
143847c6ae99SBarry Smith       *iptr = (void*)ptr;
143947c6ae99SBarry Smith       break;}
144047c6ae99SBarry Smith     default:
144147c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
144247c6ae99SBarry Smith   }
144347c6ae99SBarry Smith 
144447c6ae99SBarry Smith   done:
144547c6ae99SBarry Smith   /* add arrays to the checked out list */
144647c6ae99SBarry Smith   if (ghosted) {
1447aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
144847c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
144947c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
145047c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
145147c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
145247c6ae99SBarry Smith         break;
145347c6ae99SBarry Smith       }
145447c6ae99SBarry Smith     }
145547c6ae99SBarry Smith   } else {
1456aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
145747c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
145847c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
145947c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
146047c6ae99SBarry Smith         dd->tdof            = itdof;
146147c6ae99SBarry Smith         break;
146247c6ae99SBarry Smith       }
146347c6ae99SBarry Smith     }
146447c6ae99SBarry Smith   }
1465aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
146647c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
146747c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
146847c6ae99SBarry Smith   PetscFunctionReturn(0);
146947c6ae99SBarry Smith }
147047c6ae99SBarry Smith 
147147c6ae99SBarry Smith #undef __FUNCT__
1472aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb"
147347c6ae99SBarry Smith /*@C
1474aa219208SBarry Smith      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
147547c6ae99SBarry Smith 
147647c6ae99SBarry Smith      Input Parameter:
147747c6ae99SBarry Smith +    da - information about my local patch
147847c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
147947c6ae99SBarry Smith 
148047c6ae99SBarry Smith      Output Parameters:
148147c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
148247c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
148347c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
148447c6ae99SBarry Smith 
148547c6ae99SBarry Smith      Notes:
148647c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
148747c6ae99SBarry Smith      to zero them.
148847c6ae99SBarry Smith 
1489aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
149047c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
149147c6ae99SBarry Smith 
149247c6ae99SBarry Smith      Level: advanced
149347c6ae99SBarry Smith 
1494aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
149547c6ae99SBarry Smith 
149647c6ae99SBarry Smith @*/
14977087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
149847c6ae99SBarry Smith {
149947c6ae99SBarry Smith   PetscErrorCode ierr;
150047c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
150147c6ae99SBarry Smith   char           *iarray_start;
150247c6ae99SBarry Smith   void           **iptr = (void**)vptr;
150347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
150447c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
150547c6ae99SBarry Smith 
150647c6ae99SBarry Smith   PetscFunctionBegin;
150747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
150847c6ae99SBarry Smith   if (ghosted) {
1509aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
151047c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
151147c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
151247c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
151347c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
151447c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
151547c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
151647c6ae99SBarry Smith 
151747c6ae99SBarry Smith         goto done;
151847c6ae99SBarry Smith       }
151947c6ae99SBarry Smith     }
152047c6ae99SBarry Smith     xs = dd->Xs;
152147c6ae99SBarry Smith     ys = dd->Ys;
152247c6ae99SBarry Smith     zs = dd->Zs;
152347c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
152447c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
152547c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
152647c6ae99SBarry Smith   } else {
1527aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
152847c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
152947c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
153047c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
153147c6ae99SBarry Smith         itdof              = dd->tdof;
153247c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
153347c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
153447c6ae99SBarry Smith 
153547c6ae99SBarry Smith         goto done;
153647c6ae99SBarry Smith       }
153747c6ae99SBarry Smith     }
153847c6ae99SBarry Smith     xs = dd->xs;
153947c6ae99SBarry Smith     ys = dd->ys;
154047c6ae99SBarry Smith     zs = dd->zs;
154147c6ae99SBarry Smith     xm = dd->xe-dd->xs;
154247c6ae99SBarry Smith     ym = dd->ye-dd->ys;
154347c6ae99SBarry Smith     zm = dd->ze-dd->zs;
154447c6ae99SBarry Smith   }
154547c6ae99SBarry Smith 
154647c6ae99SBarry Smith   switch (dd->dim) {
154747c6ae99SBarry Smith     case 1: {
154847c6ae99SBarry Smith       void *ptr;
154947c6ae99SBarry Smith       itdof = xm;
155047c6ae99SBarry Smith 
155147c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
155247c6ae99SBarry Smith 
155347c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
155447c6ae99SBarry Smith       *iptr = (void*)ptr;
155547c6ae99SBarry Smith       break;}
155647c6ae99SBarry Smith     case 2: {
155747c6ae99SBarry Smith       void **ptr;
155847c6ae99SBarry Smith       itdof = xm*ym;
155947c6ae99SBarry Smith 
156047c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
156147c6ae99SBarry Smith 
156247c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
156347c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
156447c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
156547c6ae99SBarry Smith       }
156647c6ae99SBarry Smith       *iptr = (void*)ptr;
156747c6ae99SBarry Smith       break;}
156847c6ae99SBarry Smith     case 3: {
156947c6ae99SBarry Smith       void ***ptr,**bptr;
157047c6ae99SBarry Smith       itdof = xm*ym*zm;
157147c6ae99SBarry Smith 
157247c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
157347c6ae99SBarry Smith 
157447c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
157547c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
157647c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
157747c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
157847c6ae99SBarry Smith       }
157947c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
158047c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
158147c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
158247c6ae99SBarry Smith         }
158347c6ae99SBarry Smith       }
158447c6ae99SBarry Smith 
158547c6ae99SBarry Smith       *iptr = (void*)ptr;
158647c6ae99SBarry Smith       break;}
158747c6ae99SBarry Smith     default:
158847c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
158947c6ae99SBarry Smith   }
159047c6ae99SBarry Smith 
159147c6ae99SBarry Smith   done:
159247c6ae99SBarry Smith   /* add arrays to the checked out list */
159347c6ae99SBarry Smith   if (ghosted) {
1594aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
159547c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
159647c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
159747c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
159847c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
159947c6ae99SBarry Smith         break;
160047c6ae99SBarry Smith       }
160147c6ae99SBarry Smith     }
160247c6ae99SBarry Smith   } else {
1603aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
160447c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
160547c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
160647c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
160747c6ae99SBarry Smith         dd->tdof            = itdof;
160847c6ae99SBarry Smith         break;
160947c6ae99SBarry Smith       }
161047c6ae99SBarry Smith     }
161147c6ae99SBarry Smith   }
1612aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
161347c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
161447c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
161547c6ae99SBarry Smith   PetscFunctionReturn(0);
161647c6ae99SBarry Smith }
161747c6ae99SBarry Smith 
161847c6ae99SBarry Smith #undef __FUNCT__
1619aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray"
162047c6ae99SBarry Smith /*@C
1621aa219208SBarry Smith      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
162247c6ae99SBarry Smith 
162347c6ae99SBarry Smith      Input Parameter:
162447c6ae99SBarry Smith +    da - information about my local patch
162547c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
162647c6ae99SBarry Smith 
162747c6ae99SBarry Smith      Output Parameters:
162847c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
162947c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
163047c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
163147c6ae99SBarry Smith 
163247c6ae99SBarry Smith      Level: advanced
163347c6ae99SBarry Smith 
1634aa219208SBarry Smith .seealso: DMDAGetAdicArray()
163547c6ae99SBarry Smith 
163647c6ae99SBarry Smith @*/
16377087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
163847c6ae99SBarry Smith {
163947c6ae99SBarry Smith   PetscInt  i;
164047c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
164147c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
164247c6ae99SBarry Smith 
164347c6ae99SBarry Smith   PetscFunctionBegin;
164447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
164547c6ae99SBarry Smith   if (ghosted) {
1646aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
164747c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
164847c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
164947c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
165047c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
165147c6ae99SBarry Smith         break;
165247c6ae99SBarry Smith       }
165347c6ae99SBarry Smith     }
165447c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1655aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
165647c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
165747c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
165847c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
165947c6ae99SBarry Smith         break;
166047c6ae99SBarry Smith       }
166147c6ae99SBarry Smith     }
166247c6ae99SBarry Smith   } else {
1663aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
166447c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
166547c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
166647c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
166747c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
166847c6ae99SBarry Smith         break;
166947c6ae99SBarry Smith       }
167047c6ae99SBarry Smith     }
167147c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1672aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
167347c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
167447c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
167547c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
167647c6ae99SBarry Smith         break;
167747c6ae99SBarry Smith       }
167847c6ae99SBarry Smith     }
167947c6ae99SBarry Smith   }
168047c6ae99SBarry Smith   PetscFunctionReturn(0);
168147c6ae99SBarry Smith }
168247c6ae99SBarry Smith 
168347c6ae99SBarry Smith #undef __FUNCT__
168447c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
16857087cfbeSBarry Smith PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
168647c6ae99SBarry Smith {
168747c6ae99SBarry Smith   PetscErrorCode ierr;
168847c6ae99SBarry Smith   PetscFunctionBegin;
1689aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
169047c6ae99SBarry Smith   PetscFunctionReturn(0);
169147c6ae99SBarry Smith }
169247c6ae99SBarry Smith 
169347c6ae99SBarry Smith #undef __FUNCT__
169447c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
16957087cfbeSBarry Smith PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
169647c6ae99SBarry Smith {
169747c6ae99SBarry Smith   PetscErrorCode ierr;
169847c6ae99SBarry Smith   PetscFunctionBegin;
1699aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
170047c6ae99SBarry Smith   PetscFunctionReturn(0);
170147c6ae99SBarry Smith }
170247c6ae99SBarry Smith 
1703