xref: /petsc/src/dm/impls/da/dalocal.c (revision 80800b1a75cc5195fdbf61595e4ed55ad33c8763)
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);
59*80800b1aSMatthew G Knepley   if (dd->defaultSection) {
60*80800b1aSMatthew G Knepley     PetscInt localSize;
61*80800b1aSMatthew G Knepley 
62*80800b1aSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dd->defaultSection, &localSize);CHKERRQ(ierr);
63*80800b1aSMatthew G Knepley     ierr = VecSetSizes(*g, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
64*80800b1aSMatthew G Knepley   } else {
6547c6ae99SBarry Smith     ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
6647c6ae99SBarry Smith     ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
67*80800b1aSMatthew G Knepley   }
68401ddaa8SBarry Smith   ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
693c0c59f3SBarry Smith   ierr = PetscObjectCompose((PetscObject)*g,"DM",(PetscObject)da);CHKERRQ(ierr);
7047c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
7147c6ae99SBarry Smith   if (dd->w == 1  && dd->dim == 2) {
7247c6ae99SBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
7347c6ae99SBarry Smith   }
7447c6ae99SBarry Smith #endif
7547c6ae99SBarry Smith   PetscFunctionReturn(0);
7647c6ae99SBarry Smith }
7747c6ae99SBarry Smith 
78a66d4d66SMatthew G Knepley #undef __FUNCT__
79a66d4d66SMatthew G Knepley #define __FUNCT__ "DMDACreateSection"
80a66d4d66SMatthew G Knepley /*@C
81a66d4d66SMatthew G Knepley   DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with
82a66d4d66SMatthew G Knepley   different numbers of dofs on vertices, cells, and faces in each direction.
83a66d4d66SMatthew G Knepley 
84a66d4d66SMatthew G Knepley   Input Parameters:
85a66d4d66SMatthew G Knepley + dm- The DMDA
86a66d4d66SMatthew G Knepley . numFields - The number of fields
87a66d4d66SMatthew G Knepley . numComp - The number of components in each field, or PETSC_NULL for 1
88a66d4d66SMatthew G Knepley . numVertexDof - The number of dofs per vertex for each field, or PETSC_NULL
89a66d4d66SMatthew G Knepley . numFaceDof - The number of dofs per face for each field and direction, or PETSC_NULL
90a66d4d66SMatthew G Knepley - numCellDof - The number of dofs per cell for each field, or PETSC_NULL
91a66d4d66SMatthew G Knepley 
92a66d4d66SMatthew G Knepley   Level: developer
93a66d4d66SMatthew G Knepley 
94a66d4d66SMatthew G Knepley   Note:
95a66d4d66SMatthew G Knepley   The default DMDA numbering is as follows:
96a66d4d66SMatthew G Knepley 
97a66d4d66SMatthew G Knepley     - Cells:    [0,             nC)
98a66d4d66SMatthew G Knepley     - Vertices: [nC,            nC+nV)
99a66d4d66SMatthew G Knepley     - X-Faces:  [nC+nV,         nC+nV+nXF)
100a66d4d66SMatthew G Knepley     - Y-Faces:  [nC+nV+nXF,     nC+nV+nXF+nYF)
101a66d4d66SMatthew G Knepley     - Z-Faces:  [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF)
102a66d4d66SMatthew G Knepley 
103a66d4d66SMatthew G Knepley   We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment.
104a66d4d66SMatthew G Knepley @*/
105*80800b1aSMatthew G Knepley PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[])
106a66d4d66SMatthew G Knepley {
107a66d4d66SMatthew G Knepley   DM_DA         *da  = (DM_DA *) dm->data;
108*80800b1aSMatthew G Knepley   PetscInt       mx  = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
109a66d4d66SMatthew G Knepley   PetscInt       nC  = (mx  )*(da->dim > 1 ? (my  )*(da->dim > 2 ? (mz  ) : 1) : 1);
110a66d4d66SMatthew G Knepley   PetscInt       nV  = (mx+1)*(da->dim > 1 ? (my+1)*(da->dim > 2 ? (mz+1) : 1) : 1);
111a66d4d66SMatthew G Knepley   PetscInt       nXF = (mx+1)*(da->dim > 1 ? (my  )*(da->dim > 2 ? (mz  ) : 1) : 1);
112*80800b1aSMatthew G Knepley   PetscInt       nYF = (mx  )*(da->dim > 1 ? (my+1)*(da->dim > 2 ? (mz  ) : 1) : 0);
113a66d4d66SMatthew G Knepley   PetscInt       nZF = (mx  )*(da->dim > 1 ? (my  )*(da->dim > 2 ? (mz+1) : 0) : 0);
114a66d4d66SMatthew G Knepley   PetscInt       cStart  = 0,     cEnd  = cStart+nC;
115a66d4d66SMatthew G Knepley   PetscInt       vStart  = cEnd,  vEnd  = vStart+nV;
116a66d4d66SMatthew G Knepley   PetscInt       xfStart = vEnd,  xfEnd = xfStart+nXF;
117a66d4d66SMatthew G Knepley   PetscInt       yfStart = xfEnd, yfEnd = yfStart+nYF;
118a66d4d66SMatthew G Knepley   PetscInt       zfStart = yfEnd, zfEnd = zfStart+nZF;
119a66d4d66SMatthew G Knepley   PetscInt       pStart  = 0,     pEnd  = zfEnd;
120*80800b1aSMatthew G Knepley   PetscInt       numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0};
121a66d4d66SMatthew G Knepley   PetscInt       f, v, c, xf, yf, zf;
122a66d4d66SMatthew G Knepley   PetscErrorCode ierr;
123a66d4d66SMatthew G Knepley 
124a66d4d66SMatthew G Knepley   PetscFunctionBegin;
125a66d4d66SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
126*80800b1aSMatthew G Knepley   ierr = DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);CHKERRQ(ierr);
127a66d4d66SMatthew G Knepley   for(f = 0; f < numFields; ++f) {
128a66d4d66SMatthew G Knepley     if (numVertexDof) {numVertexTotDof  += numVertexDof[f];}
129a66d4d66SMatthew G Knepley     if (numCellDof)   {numCellTotDof    += numCellDof[f];}
130a66d4d66SMatthew G Knepley     if (numFaceDof)   {numFaceTotDof[0] += numFaceDof[f*da->dim+0];
131a66d4d66SMatthew G Knepley                        numFaceTotDof[1] += da->dim > 1 ? numFaceDof[f*da->dim+1] : 0;
132a66d4d66SMatthew G Knepley                        numFaceTotDof[2] += da->dim > 2 ? numFaceDof[f*da->dim+2] : 0;}
133a66d4d66SMatthew G Knepley   }
134a66d4d66SMatthew G Knepley   ierr = PetscSectionCreate(((PetscObject) dm)->comm, &da->defaultSection);CHKERRQ(ierr);
135a66d4d66SMatthew G Knepley   if (numFields > 1) {
136a66d4d66SMatthew G Knepley     ierr = PetscSectionSetNumFields(da->defaultSection, numFields);CHKERRQ(ierr);
137a66d4d66SMatthew G Knepley     for(f = 0; f < numFields; ++f) {
138*80800b1aSMatthew G Knepley       const char *name;
139*80800b1aSMatthew G Knepley 
140*80800b1aSMatthew G Knepley       ierr = DMDAGetFieldName(dm, f, &name);CHKERRQ(ierr);
141*80800b1aSMatthew G Knepley       ierr = PetscSectionSetFieldName(da->defaultSection, f, name);CHKERRQ(ierr);
142*80800b1aSMatthew G Knepley       if (numComp) {
143a66d4d66SMatthew G Knepley         ierr = PetscSectionSetFieldComponents(da->defaultSection, f, numComp[f]);CHKERRQ(ierr);
144a66d4d66SMatthew G Knepley       }
145a66d4d66SMatthew G Knepley     }
146a66d4d66SMatthew G Knepley   } else {
147a66d4d66SMatthew G Knepley     numFields = 0;
148a66d4d66SMatthew G Knepley   }
149a66d4d66SMatthew G Knepley   ierr = PetscSectionSetChart(da->defaultSection, pStart, pEnd);CHKERRQ(ierr);
150a66d4d66SMatthew G Knepley   if (numVertexDof) {
151a66d4d66SMatthew G Knepley     for(v = vStart; v < vEnd; ++v) {
152a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
153a66d4d66SMatthew G Knepley         ierr = PetscSectionSetFieldDof(da->defaultSection, v, f, numVertexDof[f]);CHKERRQ(ierr);
154a66d4d66SMatthew G Knepley       }
155a66d4d66SMatthew G Knepley       ierr = PetscSectionSetDof(da->defaultSection, v, numVertexTotDof);CHKERRQ(ierr);
156a66d4d66SMatthew G Knepley     }
157a66d4d66SMatthew G Knepley   }
158a66d4d66SMatthew G Knepley   if (numFaceDof) {
159a66d4d66SMatthew G Knepley     for(xf = xfStart; xf < xfEnd; ++xf) {
160a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
161a66d4d66SMatthew G Knepley         ierr = PetscSectionSetFieldDof(da->defaultSection, xf, f, numFaceDof[f*da->dim+0]);CHKERRQ(ierr);
162a66d4d66SMatthew G Knepley       }
163a66d4d66SMatthew G Knepley       ierr = PetscSectionSetDof(da->defaultSection, xf, numFaceTotDof[0]);CHKERRQ(ierr);
164a66d4d66SMatthew G Knepley     }
165a66d4d66SMatthew G Knepley     for(yf = yfStart; yf < yfEnd; ++yf) {
166a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
167a66d4d66SMatthew G Knepley         ierr = PetscSectionSetFieldDof(da->defaultSection, yf, f, numFaceDof[f*da->dim+1]);CHKERRQ(ierr);
168a66d4d66SMatthew G Knepley       }
169a66d4d66SMatthew G Knepley       ierr = PetscSectionSetDof(da->defaultSection, yf, numFaceTotDof[1]);CHKERRQ(ierr);
170a66d4d66SMatthew G Knepley     }
171a66d4d66SMatthew G Knepley     for(zf = zfStart; zf < zfEnd; ++zf) {
172a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
173a66d4d66SMatthew G Knepley         ierr = PetscSectionSetFieldDof(da->defaultSection, zf, f, numFaceDof[f*da->dim+2]);CHKERRQ(ierr);
174a66d4d66SMatthew G Knepley       }
175a66d4d66SMatthew G Knepley       ierr = PetscSectionSetDof(da->defaultSection, zf, numFaceTotDof[2]);CHKERRQ(ierr);
176a66d4d66SMatthew G Knepley     }
177a66d4d66SMatthew G Knepley   }
178a66d4d66SMatthew G Knepley   if (numCellDof) {
179a66d4d66SMatthew G Knepley     for(c = cStart; c < cEnd; ++c) {
180a66d4d66SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
181a66d4d66SMatthew G Knepley         ierr = PetscSectionSetFieldDof(da->defaultSection, c, f, numCellDof[f]);CHKERRQ(ierr);
182a66d4d66SMatthew G Knepley       }
183a66d4d66SMatthew G Knepley       ierr = PetscSectionSetDof(da->defaultSection, c, numCellTotDof);CHKERRQ(ierr);
184a66d4d66SMatthew G Knepley     }
185a66d4d66SMatthew G Knepley   }
186a66d4d66SMatthew G Knepley   ierr = PetscSectionSetUp(da->defaultSection);CHKERRQ(ierr);
187a66d4d66SMatthew G Knepley   da->defaultGlobalSection = da->defaultSection;
188a66d4d66SMatthew G Knepley   PetscFunctionReturn(0);
189a66d4d66SMatthew G Knepley }
190a66d4d66SMatthew G Knepley 
19147c6ae99SBarry Smith /* ------------------------------------------------------------------- */
19247c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
19347c6ae99SBarry Smith 
19447c6ae99SBarry Smith EXTERN_C_BEGIN
195c6db04a5SJed Brown #include <adic/ad_utils.h>
19647c6ae99SBarry Smith EXTERN_C_END
19747c6ae99SBarry Smith 
19847c6ae99SBarry Smith #undef __FUNCT__
199aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicArray"
20047c6ae99SBarry Smith /*@C
201aa219208SBarry Smith      DMDAGetAdicArray - Gets an array of derivative types for a DMDA
20247c6ae99SBarry Smith 
20347c6ae99SBarry Smith     Input Parameter:
20447c6ae99SBarry Smith +    da - information about my local patch
20547c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
20647c6ae99SBarry Smith 
20747c6ae99SBarry Smith     Output Parameters:
20847c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
20947c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
21047c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
21147c6ae99SBarry Smith 
21247c6ae99SBarry Smith      Notes:
21347c6ae99SBarry Smith        The vector values are NOT initialized and may have garbage in them, so you may need
21447c6ae99SBarry Smith        to zero them.
21547c6ae99SBarry Smith 
216aa219208SBarry Smith        Returns the same type of object as the DMDAVecGetArray() except its elements are
21747c6ae99SBarry Smith            derivative types instead of PetscScalars
21847c6ae99SBarry Smith 
21947c6ae99SBarry Smith      Level: advanced
22047c6ae99SBarry Smith 
221aa219208SBarry Smith .seealso: DMDARestoreAdicArray()
22247c6ae99SBarry Smith 
22347c6ae99SBarry Smith @*/
2247087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
22547c6ae99SBarry Smith {
22647c6ae99SBarry Smith   PetscErrorCode ierr;
22747c6ae99SBarry Smith   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
22847c6ae99SBarry Smith   char           *iarray_start;
22947c6ae99SBarry Smith   void           **iptr = (void**)vptr;
23047c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
23147c6ae99SBarry Smith 
23247c6ae99SBarry Smith   PetscFunctionBegin;
23347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
23447c6ae99SBarry Smith   if (ghosted) {
235aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
23647c6ae99SBarry Smith       if (dd->adarrayghostedin[i]) {
23747c6ae99SBarry Smith         *iptr                   = dd->adarrayghostedin[i];
23847c6ae99SBarry Smith         iarray_start            = (char*)dd->adstartghostedin[i];
23947c6ae99SBarry Smith         itdof                   = dd->ghostedtdof;
24047c6ae99SBarry Smith         dd->adarrayghostedin[i] = PETSC_NULL;
24147c6ae99SBarry Smith         dd->adstartghostedin[i] = PETSC_NULL;
24247c6ae99SBarry Smith 
24347c6ae99SBarry Smith         goto done;
24447c6ae99SBarry Smith       }
24547c6ae99SBarry Smith     }
24647c6ae99SBarry Smith     xs = dd->Xs;
24747c6ae99SBarry Smith     ys = dd->Ys;
24847c6ae99SBarry Smith     zs = dd->Zs;
24947c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
25047c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
25147c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
25247c6ae99SBarry Smith   } else {
253aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
25447c6ae99SBarry Smith       if (dd->adarrayin[i]) {
25547c6ae99SBarry Smith         *iptr            = dd->adarrayin[i];
25647c6ae99SBarry Smith         iarray_start     = (char*)dd->adstartin[i];
25747c6ae99SBarry Smith         itdof            = dd->tdof;
25847c6ae99SBarry Smith         dd->adarrayin[i] = PETSC_NULL;
25947c6ae99SBarry Smith         dd->adstartin[i] = PETSC_NULL;
26047c6ae99SBarry Smith 
26147c6ae99SBarry Smith         goto done;
26247c6ae99SBarry Smith       }
26347c6ae99SBarry Smith     }
26447c6ae99SBarry Smith     xs = dd->xs;
26547c6ae99SBarry Smith     ys = dd->ys;
26647c6ae99SBarry Smith     zs = dd->zs;
26747c6ae99SBarry Smith     xm = dd->xe-dd->xs;
26847c6ae99SBarry Smith     ym = dd->ye-dd->ys;
26947c6ae99SBarry Smith     zm = dd->ze-dd->zs;
27047c6ae99SBarry Smith   }
27147c6ae99SBarry Smith   deriv_type_size = PetscADGetDerivTypeSize();
27247c6ae99SBarry Smith 
27347c6ae99SBarry Smith   switch (dd->dim) {
27447c6ae99SBarry Smith     case 1: {
27547c6ae99SBarry Smith       void *ptr;
27647c6ae99SBarry Smith       itdof = xm;
27747c6ae99SBarry Smith 
27847c6ae99SBarry Smith       ierr  = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
27947c6ae99SBarry Smith 
28047c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*deriv_type_size);
28147c6ae99SBarry Smith       *iptr = (void*)ptr;
28247c6ae99SBarry Smith       break;}
28347c6ae99SBarry Smith     case 2: {
28447c6ae99SBarry Smith       void **ptr;
28547c6ae99SBarry Smith       itdof = xm*ym;
28647c6ae99SBarry Smith 
28747c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr);
28847c6ae99SBarry Smith 
28947c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
29047c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
29147c6ae99SBarry Smith         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
29247c6ae99SBarry Smith       }
29347c6ae99SBarry Smith       *iptr = (void*)ptr;
29447c6ae99SBarry Smith       break;}
29547c6ae99SBarry Smith     case 3: {
29647c6ae99SBarry Smith       void ***ptr,**bptr;
29747c6ae99SBarry Smith       itdof = xm*ym*zm;
29847c6ae99SBarry Smith 
29947c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
30047c6ae99SBarry Smith 
30147c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
30247c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
30347c6ae99SBarry Smith 
30447c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
30547c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
30647c6ae99SBarry Smith       }
30747c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
30847c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
30947c6ae99SBarry Smith           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
31047c6ae99SBarry Smith         }
31147c6ae99SBarry Smith       }
31247c6ae99SBarry Smith 
31347c6ae99SBarry Smith       *iptr = (void*)ptr;
31447c6ae99SBarry Smith       break;}
31547c6ae99SBarry Smith     default:
31647c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
31747c6ae99SBarry Smith   }
31847c6ae99SBarry Smith 
31947c6ae99SBarry Smith   done:
32047c6ae99SBarry Smith   /* add arrays to the checked out list */
32147c6ae99SBarry Smith   if (ghosted) {
322aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
32347c6ae99SBarry Smith       if (!dd->adarrayghostedout[i]) {
32447c6ae99SBarry Smith         dd->adarrayghostedout[i] = *iptr ;
32547c6ae99SBarry Smith         dd->adstartghostedout[i] = iarray_start;
32647c6ae99SBarry Smith         dd->ghostedtdof          = itdof;
32747c6ae99SBarry Smith         break;
32847c6ae99SBarry Smith       }
32947c6ae99SBarry Smith     }
33047c6ae99SBarry Smith   } else {
331aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
33247c6ae99SBarry Smith       if (!dd->adarrayout[i]) {
33347c6ae99SBarry Smith         dd->adarrayout[i] = *iptr ;
33447c6ae99SBarry Smith         dd->adstartout[i] = iarray_start;
33547c6ae99SBarry Smith         dd->tdof          = itdof;
33647c6ae99SBarry Smith         break;
33747c6ae99SBarry Smith       }
33847c6ae99SBarry Smith     }
33947c6ae99SBarry Smith   }
340aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
34147c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
34247c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
34347c6ae99SBarry Smith   PetscFunctionReturn(0);
34447c6ae99SBarry Smith }
34547c6ae99SBarry Smith 
34647c6ae99SBarry Smith #undef __FUNCT__
347aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicArray"
34847c6ae99SBarry Smith /*@C
349aa219208SBarry Smith      DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
35047c6ae99SBarry Smith 
35147c6ae99SBarry Smith     Input Parameter:
35247c6ae99SBarry Smith +    da - information about my local patch
35347c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
35447c6ae99SBarry Smith 
35547c6ae99SBarry Smith     Output Parameters:
35647c6ae99SBarry Smith +    ptr - array data structured to be passed to ad_FormFunctionLocal()
35747c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
35847c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
35947c6ae99SBarry Smith 
36047c6ae99SBarry Smith      Level: advanced
36147c6ae99SBarry Smith 
362aa219208SBarry Smith .seealso: DMDAGetAdicArray()
36347c6ae99SBarry Smith 
36447c6ae99SBarry Smith @*/
3657087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
36647c6ae99SBarry Smith {
36747c6ae99SBarry Smith   PetscInt  i;
36847c6ae99SBarry Smith   void      **iptr = (void**)ptr,iarray_start = 0;
36947c6ae99SBarry Smith 
37047c6ae99SBarry Smith   PetscFunctionBegin;
37147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
37247c6ae99SBarry Smith   if (ghosted) {
373aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
37447c6ae99SBarry Smith       if (dd->adarrayghostedout[i] == *iptr) {
37547c6ae99SBarry Smith         iarray_start             = dd->adstartghostedout[i];
37647c6ae99SBarry Smith         dd->adarrayghostedout[i] = PETSC_NULL;
37747c6ae99SBarry Smith         dd->adstartghostedout[i] = PETSC_NULL;
37847c6ae99SBarry Smith         break;
37947c6ae99SBarry Smith       }
38047c6ae99SBarry Smith     }
38147c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
382aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
38347c6ae99SBarry Smith       if (!dd->adarrayghostedin[i]){
38447c6ae99SBarry Smith         dd->adarrayghostedin[i] = *iptr;
38547c6ae99SBarry Smith         dd->adstartghostedin[i] = iarray_start;
38647c6ae99SBarry Smith         break;
38747c6ae99SBarry Smith       }
38847c6ae99SBarry Smith     }
38947c6ae99SBarry Smith   } else {
390aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
39147c6ae99SBarry Smith       if (dd->adarrayout[i] == *iptr) {
39247c6ae99SBarry Smith         iarray_start      = dd->adstartout[i];
39347c6ae99SBarry Smith         dd->adarrayout[i] = PETSC_NULL;
39447c6ae99SBarry Smith         dd->adstartout[i] = PETSC_NULL;
39547c6ae99SBarry Smith         break;
39647c6ae99SBarry Smith       }
39747c6ae99SBarry Smith     }
39847c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
399aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
40047c6ae99SBarry Smith       if (!dd->adarrayin[i]){
40147c6ae99SBarry Smith         dd->adarrayin[i]   = *iptr;
40247c6ae99SBarry Smith         dd->adstartin[i]   = iarray_start;
40347c6ae99SBarry Smith         break;
40447c6ae99SBarry Smith       }
40547c6ae99SBarry Smith     }
40647c6ae99SBarry Smith   }
40747c6ae99SBarry Smith   PetscFunctionReturn(0);
40847c6ae99SBarry Smith }
40947c6ae99SBarry Smith 
41047c6ae99SBarry Smith #undef __FUNCT__
41147c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray"
4127087cfbeSBarry Smith PetscErrorCode  ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
41347c6ae99SBarry Smith {
41447c6ae99SBarry Smith   PetscErrorCode ierr;
41547c6ae99SBarry Smith   PetscFunctionBegin;
416aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
41747c6ae99SBarry Smith   PetscFunctionReturn(0);
41847c6ae99SBarry Smith }
41947c6ae99SBarry Smith 
42047c6ae99SBarry Smith #undef __FUNCT__
42147c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray"
4227087cfbeSBarry Smith PetscErrorCode  ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
42347c6ae99SBarry Smith {
42447c6ae99SBarry Smith   PetscErrorCode ierr;
42547c6ae99SBarry Smith   PetscFunctionBegin;
426aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
42747c6ae99SBarry Smith   PetscFunctionReturn(0);
42847c6ae99SBarry Smith }
42947c6ae99SBarry Smith 
43047c6ae99SBarry Smith #endif
43147c6ae99SBarry Smith 
43247c6ae99SBarry Smith #undef __FUNCT__
433aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
43447c6ae99SBarry Smith /*@C
435aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
43647c6ae99SBarry Smith 
43747c6ae99SBarry Smith     Input Parameter:
43847c6ae99SBarry Smith +    da - information about my local patch
43947c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
44047c6ae99SBarry Smith 
44147c6ae99SBarry Smith     Output Parameters:
44247c6ae99SBarry Smith .    vptr - array data structured
44347c6ae99SBarry Smith 
44447c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
44547c6ae99SBarry Smith            to zero them.
44647c6ae99SBarry Smith 
44747c6ae99SBarry Smith   Level: advanced
44847c6ae99SBarry Smith 
449aa219208SBarry Smith .seealso: DMDARestoreArray(), DMDAGetAdicArray()
45047c6ae99SBarry Smith 
45147c6ae99SBarry Smith @*/
4527087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool  ghosted,void *vptr)
45347c6ae99SBarry Smith {
45447c6ae99SBarry Smith   PetscErrorCode ierr;
45547c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
45647c6ae99SBarry Smith   char           *iarray_start;
45747c6ae99SBarry Smith   void           **iptr = (void**)vptr;
45847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
45947c6ae99SBarry Smith 
46047c6ae99SBarry Smith   PetscFunctionBegin;
46147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
46247c6ae99SBarry Smith   if (ghosted) {
463aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
46447c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
46547c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
46647c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
46747c6ae99SBarry Smith         dd->arrayghostedin[i] = PETSC_NULL;
46847c6ae99SBarry Smith         dd->startghostedin[i] = PETSC_NULL;
46947c6ae99SBarry Smith 
47047c6ae99SBarry Smith         goto done;
47147c6ae99SBarry Smith       }
47247c6ae99SBarry Smith     }
47347c6ae99SBarry Smith     xs = dd->Xs;
47447c6ae99SBarry Smith     ys = dd->Ys;
47547c6ae99SBarry Smith     zs = dd->Zs;
47647c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
47747c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
47847c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
47947c6ae99SBarry Smith   } else {
480aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
48147c6ae99SBarry Smith       if (dd->arrayin[i]) {
48247c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
48347c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
48447c6ae99SBarry Smith         dd->arrayin[i] = PETSC_NULL;
48547c6ae99SBarry Smith         dd->startin[i] = PETSC_NULL;
48647c6ae99SBarry Smith 
48747c6ae99SBarry Smith         goto done;
48847c6ae99SBarry Smith       }
48947c6ae99SBarry Smith     }
49047c6ae99SBarry Smith     xs = dd->xs;
49147c6ae99SBarry Smith     ys = dd->ys;
49247c6ae99SBarry Smith     zs = dd->zs;
49347c6ae99SBarry Smith     xm = dd->xe-dd->xs;
49447c6ae99SBarry Smith     ym = dd->ye-dd->ys;
49547c6ae99SBarry Smith     zm = dd->ze-dd->zs;
49647c6ae99SBarry Smith   }
49747c6ae99SBarry Smith 
49847c6ae99SBarry Smith   switch (dd->dim) {
49947c6ae99SBarry Smith     case 1: {
50047c6ae99SBarry Smith       void *ptr;
50147c6ae99SBarry Smith 
50247c6ae99SBarry Smith       ierr  = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
50347c6ae99SBarry Smith 
50447c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
50547c6ae99SBarry Smith       *iptr = (void*)ptr;
50647c6ae99SBarry Smith       break;}
50747c6ae99SBarry Smith     case 2: {
50847c6ae99SBarry Smith       void **ptr;
50947c6ae99SBarry Smith 
51047c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
51147c6ae99SBarry Smith 
51247c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
51347c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
51447c6ae99SBarry Smith         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
51547c6ae99SBarry Smith       }
51647c6ae99SBarry Smith       *iptr = (void*)ptr;
51747c6ae99SBarry Smith       break;}
51847c6ae99SBarry Smith     case 3: {
51947c6ae99SBarry Smith       void ***ptr,**bptr;
52047c6ae99SBarry Smith 
52147c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
52247c6ae99SBarry Smith 
52347c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
52447c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
52547c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
52647c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
52747c6ae99SBarry Smith       }
52847c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
52947c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
53047c6ae99SBarry Smith           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
53147c6ae99SBarry Smith         }
53247c6ae99SBarry Smith       }
53347c6ae99SBarry Smith 
53447c6ae99SBarry Smith       *iptr = (void*)ptr;
53547c6ae99SBarry Smith       break;}
53647c6ae99SBarry Smith     default:
53747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
53847c6ae99SBarry Smith   }
53947c6ae99SBarry Smith 
54047c6ae99SBarry Smith   done:
54147c6ae99SBarry Smith   /* add arrays to the checked out list */
54247c6ae99SBarry Smith   if (ghosted) {
543aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
54447c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
54547c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr ;
54647c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
54747c6ae99SBarry Smith         break;
54847c6ae99SBarry Smith       }
54947c6ae99SBarry Smith     }
55047c6ae99SBarry Smith   } else {
551aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
55247c6ae99SBarry Smith       if (!dd->arrayout[i]) {
55347c6ae99SBarry Smith         dd->arrayout[i] = *iptr ;
55447c6ae99SBarry Smith         dd->startout[i] = iarray_start;
55547c6ae99SBarry Smith         break;
55647c6ae99SBarry Smith       }
55747c6ae99SBarry Smith     }
55847c6ae99SBarry Smith   }
55947c6ae99SBarry Smith   PetscFunctionReturn(0);
56047c6ae99SBarry Smith }
56147c6ae99SBarry Smith 
56247c6ae99SBarry Smith #undef __FUNCT__
563aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
56447c6ae99SBarry Smith /*@C
565aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
56647c6ae99SBarry Smith 
56747c6ae99SBarry Smith     Input Parameter:
56847c6ae99SBarry Smith +    da - information about my local patch
56947c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
57047c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
57147c6ae99SBarry Smith 
57247c6ae99SBarry Smith      Level: advanced
57347c6ae99SBarry Smith 
574aa219208SBarry Smith .seealso: DMDAGetArray(), DMDAGetAdicArray()
57547c6ae99SBarry Smith 
57647c6ae99SBarry Smith @*/
5777087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool  ghosted,void *vptr)
57847c6ae99SBarry Smith {
57947c6ae99SBarry Smith   PetscInt  i;
58047c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
58147c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
58247c6ae99SBarry Smith 
58347c6ae99SBarry Smith   PetscFunctionBegin;
58447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
58547c6ae99SBarry Smith   if (ghosted) {
586aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
58747c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
58847c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
58947c6ae99SBarry Smith         dd->arrayghostedout[i] = PETSC_NULL;
59047c6ae99SBarry Smith         dd->startghostedout[i] = PETSC_NULL;
59147c6ae99SBarry Smith         break;
59247c6ae99SBarry Smith       }
59347c6ae99SBarry Smith     }
594aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
59547c6ae99SBarry Smith       if (!dd->arrayghostedin[i]){
59647c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
59747c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
59847c6ae99SBarry Smith         break;
59947c6ae99SBarry Smith       }
60047c6ae99SBarry Smith     }
60147c6ae99SBarry Smith   } else {
602aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
60347c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
60447c6ae99SBarry Smith         iarray_start    = dd->startout[i];
60547c6ae99SBarry Smith         dd->arrayout[i] = PETSC_NULL;
60647c6ae99SBarry Smith         dd->startout[i] = PETSC_NULL;
60747c6ae99SBarry Smith         break;
60847c6ae99SBarry Smith       }
60947c6ae99SBarry Smith     }
610aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
61147c6ae99SBarry Smith       if (!dd->arrayin[i]){
61247c6ae99SBarry Smith         dd->arrayin[i]  = *iptr;
61347c6ae99SBarry Smith         dd->startin[i]  = iarray_start;
61447c6ae99SBarry Smith         break;
61547c6ae99SBarry Smith       }
61647c6ae99SBarry Smith     }
61747c6ae99SBarry Smith   }
61847c6ae99SBarry Smith   PetscFunctionReturn(0);
61947c6ae99SBarry Smith }
62047c6ae99SBarry Smith 
62147c6ae99SBarry Smith #undef __FUNCT__
622aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray"
62347c6ae99SBarry Smith /*@C
624aa219208SBarry Smith      DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
62547c6ae99SBarry Smith 
62647c6ae99SBarry Smith      Input Parameter:
62747c6ae99SBarry Smith +    da - information about my local patch
62847c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
62947c6ae99SBarry Smith 
63047c6ae99SBarry Smith      Output Parameters:
63147c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
63247c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
63347c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
63447c6ae99SBarry Smith 
63547c6ae99SBarry Smith      Notes:
63647c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
63747c6ae99SBarry Smith      to zero them.
63847c6ae99SBarry Smith 
639aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
64047c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
64147c6ae99SBarry Smith 
64247c6ae99SBarry Smith      Level: advanced
64347c6ae99SBarry Smith 
644aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
64547c6ae99SBarry Smith 
64647c6ae99SBarry Smith @*/
6477087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
64847c6ae99SBarry Smith {
64947c6ae99SBarry Smith   PetscErrorCode ierr;
65047c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
65147c6ae99SBarry Smith   char           *iarray_start;
65247c6ae99SBarry Smith   void           **iptr = (void**)vptr;
65347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
65447c6ae99SBarry Smith 
65547c6ae99SBarry Smith   PetscFunctionBegin;
65647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
65747c6ae99SBarry Smith   if (ghosted) {
658aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
65947c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
66047c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
66147c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
66247c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
66347c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
66447c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
66547c6ae99SBarry Smith 
66647c6ae99SBarry Smith         goto done;
66747c6ae99SBarry Smith       }
66847c6ae99SBarry Smith     }
66947c6ae99SBarry Smith     xs = dd->Xs;
67047c6ae99SBarry Smith     ys = dd->Ys;
67147c6ae99SBarry Smith     zs = dd->Zs;
67247c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
67347c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
67447c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
67547c6ae99SBarry Smith   } else {
676aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
67747c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
67847c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
67947c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
68047c6ae99SBarry Smith         itdof              = dd->tdof;
68147c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
68247c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
68347c6ae99SBarry Smith 
68447c6ae99SBarry Smith         goto done;
68547c6ae99SBarry Smith       }
68647c6ae99SBarry Smith     }
68747c6ae99SBarry Smith     xs = dd->xs;
68847c6ae99SBarry Smith     ys = dd->ys;
68947c6ae99SBarry Smith     zs = dd->zs;
69047c6ae99SBarry Smith     xm = dd->xe-dd->xs;
69147c6ae99SBarry Smith     ym = dd->ye-dd->ys;
69247c6ae99SBarry Smith     zm = dd->ze-dd->zs;
69347c6ae99SBarry Smith   }
69447c6ae99SBarry Smith 
69547c6ae99SBarry Smith   switch (dd->dim) {
69647c6ae99SBarry Smith     case 1: {
69747c6ae99SBarry Smith       void *ptr;
69847c6ae99SBarry Smith       itdof = xm;
69947c6ae99SBarry Smith 
70047c6ae99SBarry Smith       ierr  = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
70147c6ae99SBarry Smith 
70247c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
70347c6ae99SBarry Smith       *iptr = (void*)ptr;
70447c6ae99SBarry Smith       break;}
70547c6ae99SBarry Smith     case 2: {
70647c6ae99SBarry Smith       void **ptr;
70747c6ae99SBarry Smith       itdof = xm*ym;
70847c6ae99SBarry Smith 
70947c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
71047c6ae99SBarry Smith 
71147c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
71247c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
71347c6ae99SBarry Smith         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
71447c6ae99SBarry Smith       }
71547c6ae99SBarry Smith       *iptr = (void*)ptr;
71647c6ae99SBarry Smith       break;}
71747c6ae99SBarry Smith     case 3: {
71847c6ae99SBarry Smith       void ***ptr,**bptr;
71947c6ae99SBarry Smith       itdof = xm*ym*zm;
72047c6ae99SBarry Smith 
72147c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
72247c6ae99SBarry Smith 
72347c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
72447c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
72547c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
72647c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
72747c6ae99SBarry Smith       }
72847c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
72947c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
73047c6ae99SBarry Smith           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
73147c6ae99SBarry Smith         }
73247c6ae99SBarry Smith       }
73347c6ae99SBarry Smith 
73447c6ae99SBarry Smith       *iptr = (void*)ptr;
73547c6ae99SBarry Smith       break;}
73647c6ae99SBarry Smith     default:
73747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
73847c6ae99SBarry Smith   }
73947c6ae99SBarry Smith 
74047c6ae99SBarry Smith   done:
74147c6ae99SBarry Smith   /* add arrays to the checked out list */
74247c6ae99SBarry Smith   if (ghosted) {
743aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
74447c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
74547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
74647c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
74747c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
74847c6ae99SBarry Smith         break;
74947c6ae99SBarry Smith       }
75047c6ae99SBarry Smith     }
75147c6ae99SBarry Smith   } else {
752aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
75347c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
75447c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
75547c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
75647c6ae99SBarry Smith         dd->tdof            = itdof;
75747c6ae99SBarry Smith         break;
75847c6ae99SBarry Smith       }
75947c6ae99SBarry Smith     }
76047c6ae99SBarry Smith   }
761aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
76247c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
76347c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
76447c6ae99SBarry Smith   PetscFunctionReturn(0);
76547c6ae99SBarry Smith }
76647c6ae99SBarry Smith 
76747c6ae99SBarry Smith #undef __FUNCT__
768aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray4"
7697087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
77047c6ae99SBarry Smith {
77147c6ae99SBarry Smith   PetscErrorCode ierr;
77287130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
77347c6ae99SBarry Smith   char           *iarray_start;
77447c6ae99SBarry Smith   void           **iptr = (void**)vptr;
77547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
77647c6ae99SBarry Smith 
77747c6ae99SBarry Smith   PetscFunctionBegin;
77847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
77947c6ae99SBarry Smith   if (ghosted) {
780aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
78147c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
78247c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
78347c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
78447c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
78547c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
78647c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
78747c6ae99SBarry Smith 
78847c6ae99SBarry Smith         goto done;
78947c6ae99SBarry Smith       }
79047c6ae99SBarry Smith     }
79147c6ae99SBarry Smith     xs = dd->Xs;
79247c6ae99SBarry Smith     ys = dd->Ys;
79347c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
79447c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
79547c6ae99SBarry Smith   } else {
796aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
79747c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
79847c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
79947c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
80047c6ae99SBarry Smith         itdof              = dd->tdof;
80147c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
80247c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
80347c6ae99SBarry Smith 
80447c6ae99SBarry Smith         goto done;
80547c6ae99SBarry Smith       }
80647c6ae99SBarry Smith     }
80747c6ae99SBarry Smith     xs = dd->xs;
80847c6ae99SBarry Smith     ys = dd->ys;
80947c6ae99SBarry Smith     xm = dd->xe-dd->xs;
81047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
81147c6ae99SBarry Smith   }
81247c6ae99SBarry Smith 
81347c6ae99SBarry Smith   switch (dd->dim) {
81447c6ae99SBarry Smith     case 2: {
81547c6ae99SBarry Smith       void **ptr;
81647c6ae99SBarry Smith       itdof = xm*ym;
81747c6ae99SBarry Smith 
81847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
81947c6ae99SBarry Smith 
82047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
82147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
82247c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
82347c6ae99SBarry Smith       }
82447c6ae99SBarry Smith       *iptr = (void*)ptr;
82547c6ae99SBarry Smith       break;}
82647c6ae99SBarry Smith     default:
82747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
82847c6ae99SBarry Smith   }
82947c6ae99SBarry Smith 
83047c6ae99SBarry Smith   done:
83147c6ae99SBarry Smith   /* add arrays to the checked out list */
83247c6ae99SBarry Smith   if (ghosted) {
833aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
83447c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
83547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
83647c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
83747c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
83847c6ae99SBarry Smith         break;
83947c6ae99SBarry Smith       }
84047c6ae99SBarry Smith     }
84147c6ae99SBarry Smith   } else {
842aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
84347c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
84447c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
84547c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
84647c6ae99SBarry Smith         dd->tdof            = itdof;
84747c6ae99SBarry Smith         break;
84847c6ae99SBarry Smith       }
84947c6ae99SBarry Smith     }
85047c6ae99SBarry Smith   }
851aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
85247c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
85347c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
85447c6ae99SBarry Smith   PetscFunctionReturn(0);
85547c6ae99SBarry Smith }
85647c6ae99SBarry Smith 
85747c6ae99SBarry Smith #undef __FUNCT__
858aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9"
8597087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
86047c6ae99SBarry Smith {
86147c6ae99SBarry Smith   PetscErrorCode ierr;
86287130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
86347c6ae99SBarry Smith   char           *iarray_start;
86447c6ae99SBarry Smith   void           **iptr = (void**)vptr;
86547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
86647c6ae99SBarry Smith 
86747c6ae99SBarry Smith   PetscFunctionBegin;
86847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
86947c6ae99SBarry Smith   if (ghosted) {
870aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
87147c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
87247c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
87347c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
87447c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
87547c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
87647c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
87747c6ae99SBarry Smith 
87847c6ae99SBarry Smith         goto done;
87947c6ae99SBarry Smith       }
88047c6ae99SBarry Smith     }
88147c6ae99SBarry Smith     xs = dd->Xs;
88247c6ae99SBarry Smith     ys = dd->Ys;
88347c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
88447c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
88547c6ae99SBarry Smith   } else {
886aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
88747c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
88847c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
88947c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
89047c6ae99SBarry Smith         itdof              = dd->tdof;
89147c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
89247c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith         goto done;
89547c6ae99SBarry Smith       }
89647c6ae99SBarry Smith     }
89747c6ae99SBarry Smith     xs = dd->xs;
89847c6ae99SBarry Smith     ys = dd->ys;
89947c6ae99SBarry Smith     xm = dd->xe-dd->xs;
90047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
90147c6ae99SBarry Smith   }
90247c6ae99SBarry Smith 
90347c6ae99SBarry Smith   switch (dd->dim) {
90447c6ae99SBarry Smith     case 2: {
90547c6ae99SBarry Smith       void **ptr;
90647c6ae99SBarry Smith       itdof = xm*ym;
90747c6ae99SBarry Smith 
90847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
90947c6ae99SBarry Smith 
91047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
91147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
91247c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
91347c6ae99SBarry Smith       }
91447c6ae99SBarry Smith       *iptr = (void*)ptr;
91547c6ae99SBarry Smith       break;}
91647c6ae99SBarry Smith     default:
91747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
91847c6ae99SBarry Smith   }
91947c6ae99SBarry Smith 
92047c6ae99SBarry Smith   done:
92147c6ae99SBarry Smith   /* add arrays to the checked out list */
92247c6ae99SBarry Smith   if (ghosted) {
923aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
92447c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
92547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
92647c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
92747c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
92847c6ae99SBarry Smith         break;
92947c6ae99SBarry Smith       }
93047c6ae99SBarry Smith     }
93147c6ae99SBarry Smith   } else {
932aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
93347c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
93447c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
93547c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
93647c6ae99SBarry Smith         dd->tdof            = itdof;
93747c6ae99SBarry Smith         break;
93847c6ae99SBarry Smith       }
93947c6ae99SBarry Smith     }
94047c6ae99SBarry Smith   }
941aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
94247c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
94347c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
94447c6ae99SBarry Smith   PetscFunctionReturn(0);
94547c6ae99SBarry Smith }
94647c6ae99SBarry Smith 
94747c6ae99SBarry Smith #undef __FUNCT__
948aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb"
94947c6ae99SBarry Smith /*@C
950aa219208SBarry Smith      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
95147c6ae99SBarry Smith 
95247c6ae99SBarry Smith      Input Parameter:
95347c6ae99SBarry Smith +    da - information about my local patch
95447c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
95547c6ae99SBarry Smith 
95647c6ae99SBarry Smith      Output Parameters:
95747c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
95847c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
95947c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
96047c6ae99SBarry Smith 
96147c6ae99SBarry Smith      Notes:
96247c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
96347c6ae99SBarry Smith      to zero them.
96447c6ae99SBarry Smith 
965aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
96647c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
96747c6ae99SBarry Smith 
96847c6ae99SBarry Smith      Level: advanced
96947c6ae99SBarry Smith 
970aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
97147c6ae99SBarry Smith 
97247c6ae99SBarry Smith @*/
9737087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
97447c6ae99SBarry Smith {
97547c6ae99SBarry Smith   PetscErrorCode ierr;
97647c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
97747c6ae99SBarry Smith   char           *iarray_start;
97847c6ae99SBarry Smith   void           **iptr = (void**)vptr;
97947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
98047c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
98147c6ae99SBarry Smith 
98247c6ae99SBarry Smith   PetscFunctionBegin;
98347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
98447c6ae99SBarry Smith   if (ghosted) {
985aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
98647c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
98747c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
98847c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
98947c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
99047c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
99147c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
99247c6ae99SBarry Smith 
99347c6ae99SBarry Smith         goto done;
99447c6ae99SBarry Smith       }
99547c6ae99SBarry Smith     }
99647c6ae99SBarry Smith     xs = dd->Xs;
99747c6ae99SBarry Smith     ys = dd->Ys;
99847c6ae99SBarry Smith     zs = dd->Zs;
99947c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
100047c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
100147c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
100247c6ae99SBarry Smith   } else {
1003aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
100447c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
100547c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
100647c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
100747c6ae99SBarry Smith         itdof              = dd->tdof;
100847c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
100947c6ae99SBarry Smith         dd->admfstartin[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       itdof = xm;
102647c6ae99SBarry Smith 
102747c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
102847c6ae99SBarry Smith 
102947c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
103047c6ae99SBarry Smith       *iptr = (void*)ptr;
103147c6ae99SBarry Smith       break;}
103247c6ae99SBarry Smith     case 2: {
103347c6ae99SBarry Smith       void **ptr;
103447c6ae99SBarry Smith       itdof = xm*ym;
103547c6ae99SBarry Smith 
103647c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
103747c6ae99SBarry Smith 
103847c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
103947c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
104047c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
104147c6ae99SBarry Smith       }
104247c6ae99SBarry Smith       *iptr = (void*)ptr;
104347c6ae99SBarry Smith       break;}
104447c6ae99SBarry Smith     case 3: {
104547c6ae99SBarry Smith       void ***ptr,**bptr;
104647c6ae99SBarry Smith       itdof = xm*ym*zm;
104747c6ae99SBarry Smith 
104847c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
104947c6ae99SBarry Smith 
105047c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
105147c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
105247c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
105347c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
105447c6ae99SBarry Smith       }
105547c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
105647c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
105747c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
105847c6ae99SBarry Smith         }
105947c6ae99SBarry Smith       }
106047c6ae99SBarry Smith 
106147c6ae99SBarry Smith       *iptr = (void*)ptr;
106247c6ae99SBarry Smith       break;}
106347c6ae99SBarry Smith     default:
106447c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
106547c6ae99SBarry Smith   }
106647c6ae99SBarry Smith 
106747c6ae99SBarry Smith   done:
106847c6ae99SBarry Smith   /* add arrays to the checked out list */
106947c6ae99SBarry Smith   if (ghosted) {
1070aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
107147c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
107247c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
107347c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
107447c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
107547c6ae99SBarry Smith         break;
107647c6ae99SBarry Smith       }
107747c6ae99SBarry Smith     }
107847c6ae99SBarry Smith   } else {
1079aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
108047c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
108147c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
108247c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
108347c6ae99SBarry Smith         dd->tdof            = itdof;
108447c6ae99SBarry Smith         break;
108547c6ae99SBarry Smith       }
108647c6ae99SBarry Smith     }
108747c6ae99SBarry Smith   }
1088aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
108947c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
109047c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
109147c6ae99SBarry Smith   PetscFunctionReturn(0);
109247c6ae99SBarry Smith }
109347c6ae99SBarry Smith 
109447c6ae99SBarry Smith #undef __FUNCT__
1095aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray"
109647c6ae99SBarry Smith /*@C
1097aa219208SBarry Smith      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
109847c6ae99SBarry Smith 
109947c6ae99SBarry Smith      Input Parameter:
110047c6ae99SBarry Smith +    da - information about my local patch
110147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
110247c6ae99SBarry Smith 
110347c6ae99SBarry Smith      Output Parameters:
110447c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
110547c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
110647c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
110747c6ae99SBarry Smith 
110847c6ae99SBarry Smith      Level: advanced
110947c6ae99SBarry Smith 
1110aa219208SBarry Smith .seealso: DMDAGetAdicArray()
111147c6ae99SBarry Smith 
111247c6ae99SBarry Smith @*/
11137087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
111447c6ae99SBarry Smith {
111547c6ae99SBarry Smith   PetscInt  i;
111647c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
111747c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
111847c6ae99SBarry Smith 
111947c6ae99SBarry Smith   PetscFunctionBegin;
112047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
112147c6ae99SBarry Smith   if (ghosted) {
1122aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
112347c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
112447c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
112547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
112647c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
112747c6ae99SBarry Smith         break;
112847c6ae99SBarry Smith       }
112947c6ae99SBarry Smith     }
113047c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1131aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
113247c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
113347c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
113447c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
113547c6ae99SBarry Smith         break;
113647c6ae99SBarry Smith       }
113747c6ae99SBarry Smith     }
113847c6ae99SBarry Smith   } else {
1139aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
114047c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
114147c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
114247c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
114347c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
114447c6ae99SBarry Smith         break;
114547c6ae99SBarry Smith       }
114647c6ae99SBarry Smith     }
114747c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1148aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
114947c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
115047c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
115147c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
115247c6ae99SBarry Smith         break;
115347c6ae99SBarry Smith       }
115447c6ae99SBarry Smith     }
115547c6ae99SBarry Smith   }
115647c6ae99SBarry Smith   PetscFunctionReturn(0);
115747c6ae99SBarry Smith }
115847c6ae99SBarry Smith 
115947c6ae99SBarry Smith #undef __FUNCT__
116047c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
11617087cfbeSBarry Smith PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
116247c6ae99SBarry Smith {
116347c6ae99SBarry Smith   PetscErrorCode ierr;
116447c6ae99SBarry Smith   PetscFunctionBegin;
1165aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
116647c6ae99SBarry Smith   PetscFunctionReturn(0);
116747c6ae99SBarry Smith }
116847c6ae99SBarry Smith 
116947c6ae99SBarry Smith #undef __FUNCT__
117047c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
11717087cfbeSBarry Smith PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
117247c6ae99SBarry Smith {
117347c6ae99SBarry Smith   PetscErrorCode ierr;
117447c6ae99SBarry Smith   PetscFunctionBegin;
1175aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
117647c6ae99SBarry Smith   PetscFunctionReturn(0);
117747c6ae99SBarry Smith }
117847c6ae99SBarry Smith 
1179