xref: /petsc/src/dm/impls/da/dalocal.c (revision 401ddaa85c8cafaabd61e88cdb9930be0fe05a79)
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);
61*401ddaa8SBarry 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 
7147c6ae99SBarry Smith /* ------------------------------------------------------------------- */
7247c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
7347c6ae99SBarry Smith 
7447c6ae99SBarry Smith EXTERN_C_BEGIN
75c6db04a5SJed Brown #include <adic/ad_utils.h>
7647c6ae99SBarry Smith EXTERN_C_END
7747c6ae99SBarry Smith 
7847c6ae99SBarry Smith #undef __FUNCT__
79aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicArray"
8047c6ae99SBarry Smith /*@C
81aa219208SBarry Smith      DMDAGetAdicArray - Gets an array of derivative types for a DMDA
8247c6ae99SBarry Smith 
8347c6ae99SBarry Smith     Input Parameter:
8447c6ae99SBarry Smith +    da - information about my local patch
8547c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
8647c6ae99SBarry Smith 
8747c6ae99SBarry Smith     Output Parameters:
8847c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
8947c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
9047c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
9147c6ae99SBarry Smith 
9247c6ae99SBarry Smith      Notes:
9347c6ae99SBarry Smith        The vector values are NOT initialized and may have garbage in them, so you may need
9447c6ae99SBarry Smith        to zero them.
9547c6ae99SBarry Smith 
96aa219208SBarry Smith        Returns the same type of object as the DMDAVecGetArray() except its elements are
9747c6ae99SBarry Smith            derivative types instead of PetscScalars
9847c6ae99SBarry Smith 
9947c6ae99SBarry Smith      Level: advanced
10047c6ae99SBarry Smith 
101aa219208SBarry Smith .seealso: DMDARestoreAdicArray()
10247c6ae99SBarry Smith 
10347c6ae99SBarry Smith @*/
1047087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
10547c6ae99SBarry Smith {
10647c6ae99SBarry Smith   PetscErrorCode ierr;
10747c6ae99SBarry Smith   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
10847c6ae99SBarry Smith   char           *iarray_start;
10947c6ae99SBarry Smith   void           **iptr = (void**)vptr;
11047c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
11147c6ae99SBarry Smith 
11247c6ae99SBarry Smith   PetscFunctionBegin;
11347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
11447c6ae99SBarry Smith   if (ghosted) {
115aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
11647c6ae99SBarry Smith       if (dd->adarrayghostedin[i]) {
11747c6ae99SBarry Smith         *iptr                   = dd->adarrayghostedin[i];
11847c6ae99SBarry Smith         iarray_start            = (char*)dd->adstartghostedin[i];
11947c6ae99SBarry Smith         itdof                   = dd->ghostedtdof;
12047c6ae99SBarry Smith         dd->adarrayghostedin[i] = PETSC_NULL;
12147c6ae99SBarry Smith         dd->adstartghostedin[i] = PETSC_NULL;
12247c6ae99SBarry Smith 
12347c6ae99SBarry Smith         goto done;
12447c6ae99SBarry Smith       }
12547c6ae99SBarry Smith     }
12647c6ae99SBarry Smith     xs = dd->Xs;
12747c6ae99SBarry Smith     ys = dd->Ys;
12847c6ae99SBarry Smith     zs = dd->Zs;
12947c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
13047c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
13147c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
13247c6ae99SBarry Smith   } else {
133aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
13447c6ae99SBarry Smith       if (dd->adarrayin[i]) {
13547c6ae99SBarry Smith         *iptr            = dd->adarrayin[i];
13647c6ae99SBarry Smith         iarray_start     = (char*)dd->adstartin[i];
13747c6ae99SBarry Smith         itdof            = dd->tdof;
13847c6ae99SBarry Smith         dd->adarrayin[i] = PETSC_NULL;
13947c6ae99SBarry Smith         dd->adstartin[i] = PETSC_NULL;
14047c6ae99SBarry Smith 
14147c6ae99SBarry Smith         goto done;
14247c6ae99SBarry Smith       }
14347c6ae99SBarry Smith     }
14447c6ae99SBarry Smith     xs = dd->xs;
14547c6ae99SBarry Smith     ys = dd->ys;
14647c6ae99SBarry Smith     zs = dd->zs;
14747c6ae99SBarry Smith     xm = dd->xe-dd->xs;
14847c6ae99SBarry Smith     ym = dd->ye-dd->ys;
14947c6ae99SBarry Smith     zm = dd->ze-dd->zs;
15047c6ae99SBarry Smith   }
15147c6ae99SBarry Smith   deriv_type_size = PetscADGetDerivTypeSize();
15247c6ae99SBarry Smith 
15347c6ae99SBarry Smith   switch (dd->dim) {
15447c6ae99SBarry Smith     case 1: {
15547c6ae99SBarry Smith       void *ptr;
15647c6ae99SBarry Smith       itdof = xm;
15747c6ae99SBarry Smith 
15847c6ae99SBarry Smith       ierr  = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
15947c6ae99SBarry Smith 
16047c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*deriv_type_size);
16147c6ae99SBarry Smith       *iptr = (void*)ptr;
16247c6ae99SBarry Smith       break;}
16347c6ae99SBarry Smith     case 2: {
16447c6ae99SBarry Smith       void **ptr;
16547c6ae99SBarry Smith       itdof = xm*ym;
16647c6ae99SBarry Smith 
16747c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr);
16847c6ae99SBarry Smith 
16947c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
17047c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
17147c6ae99SBarry Smith         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
17247c6ae99SBarry Smith       }
17347c6ae99SBarry Smith       *iptr = (void*)ptr;
17447c6ae99SBarry Smith       break;}
17547c6ae99SBarry Smith     case 3: {
17647c6ae99SBarry Smith       void ***ptr,**bptr;
17747c6ae99SBarry Smith       itdof = xm*ym*zm;
17847c6ae99SBarry Smith 
17947c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
18047c6ae99SBarry Smith 
18147c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
18247c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
18347c6ae99SBarry Smith 
18447c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
18547c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
18647c6ae99SBarry Smith       }
18747c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
18847c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
18947c6ae99SBarry Smith           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
19047c6ae99SBarry Smith         }
19147c6ae99SBarry Smith       }
19247c6ae99SBarry Smith 
19347c6ae99SBarry Smith       *iptr = (void*)ptr;
19447c6ae99SBarry Smith       break;}
19547c6ae99SBarry Smith     default:
19647c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
19747c6ae99SBarry Smith   }
19847c6ae99SBarry Smith 
19947c6ae99SBarry Smith   done:
20047c6ae99SBarry Smith   /* add arrays to the checked out list */
20147c6ae99SBarry Smith   if (ghosted) {
202aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
20347c6ae99SBarry Smith       if (!dd->adarrayghostedout[i]) {
20447c6ae99SBarry Smith         dd->adarrayghostedout[i] = *iptr ;
20547c6ae99SBarry Smith         dd->adstartghostedout[i] = iarray_start;
20647c6ae99SBarry Smith         dd->ghostedtdof          = itdof;
20747c6ae99SBarry Smith         break;
20847c6ae99SBarry Smith       }
20947c6ae99SBarry Smith     }
21047c6ae99SBarry Smith   } else {
211aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
21247c6ae99SBarry Smith       if (!dd->adarrayout[i]) {
21347c6ae99SBarry Smith         dd->adarrayout[i] = *iptr ;
21447c6ae99SBarry Smith         dd->adstartout[i] = iarray_start;
21547c6ae99SBarry Smith         dd->tdof          = itdof;
21647c6ae99SBarry Smith         break;
21747c6ae99SBarry Smith       }
21847c6ae99SBarry Smith     }
21947c6ae99SBarry Smith   }
220aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
22147c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
22247c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
22347c6ae99SBarry Smith   PetscFunctionReturn(0);
22447c6ae99SBarry Smith }
22547c6ae99SBarry Smith 
22647c6ae99SBarry Smith #undef __FUNCT__
227aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicArray"
22847c6ae99SBarry Smith /*@C
229aa219208SBarry Smith      DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
23047c6ae99SBarry Smith 
23147c6ae99SBarry Smith     Input Parameter:
23247c6ae99SBarry Smith +    da - information about my local patch
23347c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
23447c6ae99SBarry Smith 
23547c6ae99SBarry Smith     Output Parameters:
23647c6ae99SBarry Smith +    ptr - array data structured to be passed to ad_FormFunctionLocal()
23747c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
23847c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
23947c6ae99SBarry Smith 
24047c6ae99SBarry Smith      Level: advanced
24147c6ae99SBarry Smith 
242aa219208SBarry Smith .seealso: DMDAGetAdicArray()
24347c6ae99SBarry Smith 
24447c6ae99SBarry Smith @*/
2457087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
24647c6ae99SBarry Smith {
24747c6ae99SBarry Smith   PetscInt  i;
24847c6ae99SBarry Smith   void      **iptr = (void**)ptr,iarray_start = 0;
24947c6ae99SBarry Smith 
25047c6ae99SBarry Smith   PetscFunctionBegin;
25147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
25247c6ae99SBarry Smith   if (ghosted) {
253aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
25447c6ae99SBarry Smith       if (dd->adarrayghostedout[i] == *iptr) {
25547c6ae99SBarry Smith         iarray_start             = dd->adstartghostedout[i];
25647c6ae99SBarry Smith         dd->adarrayghostedout[i] = PETSC_NULL;
25747c6ae99SBarry Smith         dd->adstartghostedout[i] = PETSC_NULL;
25847c6ae99SBarry Smith         break;
25947c6ae99SBarry Smith       }
26047c6ae99SBarry Smith     }
26147c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
262aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
26347c6ae99SBarry Smith       if (!dd->adarrayghostedin[i]){
26447c6ae99SBarry Smith         dd->adarrayghostedin[i] = *iptr;
26547c6ae99SBarry Smith         dd->adstartghostedin[i] = iarray_start;
26647c6ae99SBarry Smith         break;
26747c6ae99SBarry Smith       }
26847c6ae99SBarry Smith     }
26947c6ae99SBarry Smith   } else {
270aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
27147c6ae99SBarry Smith       if (dd->adarrayout[i] == *iptr) {
27247c6ae99SBarry Smith         iarray_start      = dd->adstartout[i];
27347c6ae99SBarry Smith         dd->adarrayout[i] = PETSC_NULL;
27447c6ae99SBarry Smith         dd->adstartout[i] = PETSC_NULL;
27547c6ae99SBarry Smith         break;
27647c6ae99SBarry Smith       }
27747c6ae99SBarry Smith     }
27847c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
279aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
28047c6ae99SBarry Smith       if (!dd->adarrayin[i]){
28147c6ae99SBarry Smith         dd->adarrayin[i]   = *iptr;
28247c6ae99SBarry Smith         dd->adstartin[i]   = iarray_start;
28347c6ae99SBarry Smith         break;
28447c6ae99SBarry Smith       }
28547c6ae99SBarry Smith     }
28647c6ae99SBarry Smith   }
28747c6ae99SBarry Smith   PetscFunctionReturn(0);
28847c6ae99SBarry Smith }
28947c6ae99SBarry Smith 
29047c6ae99SBarry Smith #undef __FUNCT__
29147c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray"
2927087cfbeSBarry Smith PetscErrorCode  ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
29347c6ae99SBarry Smith {
29447c6ae99SBarry Smith   PetscErrorCode ierr;
29547c6ae99SBarry Smith   PetscFunctionBegin;
296aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
29747c6ae99SBarry Smith   PetscFunctionReturn(0);
29847c6ae99SBarry Smith }
29947c6ae99SBarry Smith 
30047c6ae99SBarry Smith #undef __FUNCT__
30147c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray"
3027087cfbeSBarry Smith PetscErrorCode  ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
30347c6ae99SBarry Smith {
30447c6ae99SBarry Smith   PetscErrorCode ierr;
30547c6ae99SBarry Smith   PetscFunctionBegin;
306aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
30747c6ae99SBarry Smith   PetscFunctionReturn(0);
30847c6ae99SBarry Smith }
30947c6ae99SBarry Smith 
31047c6ae99SBarry Smith #endif
31147c6ae99SBarry Smith 
31247c6ae99SBarry Smith #undef __FUNCT__
313aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
31447c6ae99SBarry Smith /*@C
315aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
31647c6ae99SBarry Smith 
31747c6ae99SBarry Smith     Input Parameter:
31847c6ae99SBarry Smith +    da - information about my local patch
31947c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
32047c6ae99SBarry Smith 
32147c6ae99SBarry Smith     Output Parameters:
32247c6ae99SBarry Smith .    vptr - array data structured
32347c6ae99SBarry Smith 
32447c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
32547c6ae99SBarry Smith            to zero them.
32647c6ae99SBarry Smith 
32747c6ae99SBarry Smith   Level: advanced
32847c6ae99SBarry Smith 
329aa219208SBarry Smith .seealso: DMDARestoreArray(), DMDAGetAdicArray()
33047c6ae99SBarry Smith 
33147c6ae99SBarry Smith @*/
3327087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool  ghosted,void *vptr)
33347c6ae99SBarry Smith {
33447c6ae99SBarry Smith   PetscErrorCode ierr;
33547c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
33647c6ae99SBarry Smith   char           *iarray_start;
33747c6ae99SBarry Smith   void           **iptr = (void**)vptr;
33847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
33947c6ae99SBarry Smith 
34047c6ae99SBarry Smith   PetscFunctionBegin;
34147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
34247c6ae99SBarry Smith   if (ghosted) {
343aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
34447c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
34547c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
34647c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
34747c6ae99SBarry Smith         dd->arrayghostedin[i] = PETSC_NULL;
34847c6ae99SBarry Smith         dd->startghostedin[i] = PETSC_NULL;
34947c6ae99SBarry Smith 
35047c6ae99SBarry Smith         goto done;
35147c6ae99SBarry Smith       }
35247c6ae99SBarry Smith     }
35347c6ae99SBarry Smith     xs = dd->Xs;
35447c6ae99SBarry Smith     ys = dd->Ys;
35547c6ae99SBarry Smith     zs = dd->Zs;
35647c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
35747c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
35847c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
35947c6ae99SBarry Smith   } else {
360aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
36147c6ae99SBarry Smith       if (dd->arrayin[i]) {
36247c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
36347c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
36447c6ae99SBarry Smith         dd->arrayin[i] = PETSC_NULL;
36547c6ae99SBarry Smith         dd->startin[i] = PETSC_NULL;
36647c6ae99SBarry Smith 
36747c6ae99SBarry Smith         goto done;
36847c6ae99SBarry Smith       }
36947c6ae99SBarry Smith     }
37047c6ae99SBarry Smith     xs = dd->xs;
37147c6ae99SBarry Smith     ys = dd->ys;
37247c6ae99SBarry Smith     zs = dd->zs;
37347c6ae99SBarry Smith     xm = dd->xe-dd->xs;
37447c6ae99SBarry Smith     ym = dd->ye-dd->ys;
37547c6ae99SBarry Smith     zm = dd->ze-dd->zs;
37647c6ae99SBarry Smith   }
37747c6ae99SBarry Smith 
37847c6ae99SBarry Smith   switch (dd->dim) {
37947c6ae99SBarry Smith     case 1: {
38047c6ae99SBarry Smith       void *ptr;
38147c6ae99SBarry Smith 
38247c6ae99SBarry Smith       ierr  = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
38347c6ae99SBarry Smith 
38447c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
38547c6ae99SBarry Smith       *iptr = (void*)ptr;
38647c6ae99SBarry Smith       break;}
38747c6ae99SBarry Smith     case 2: {
38847c6ae99SBarry Smith       void **ptr;
38947c6ae99SBarry Smith 
39047c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
39147c6ae99SBarry Smith 
39247c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
39347c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
39447c6ae99SBarry Smith         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
39547c6ae99SBarry Smith       }
39647c6ae99SBarry Smith       *iptr = (void*)ptr;
39747c6ae99SBarry Smith       break;}
39847c6ae99SBarry Smith     case 3: {
39947c6ae99SBarry Smith       void ***ptr,**bptr;
40047c6ae99SBarry Smith 
40147c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
40247c6ae99SBarry Smith 
40347c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
40447c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
40547c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
40647c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
40747c6ae99SBarry Smith       }
40847c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
40947c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
41047c6ae99SBarry Smith           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
41147c6ae99SBarry Smith         }
41247c6ae99SBarry Smith       }
41347c6ae99SBarry Smith 
41447c6ae99SBarry Smith       *iptr = (void*)ptr;
41547c6ae99SBarry Smith       break;}
41647c6ae99SBarry Smith     default:
41747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
41847c6ae99SBarry Smith   }
41947c6ae99SBarry Smith 
42047c6ae99SBarry Smith   done:
42147c6ae99SBarry Smith   /* add arrays to the checked out list */
42247c6ae99SBarry Smith   if (ghosted) {
423aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
42447c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
42547c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr ;
42647c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
42747c6ae99SBarry Smith         break;
42847c6ae99SBarry Smith       }
42947c6ae99SBarry Smith     }
43047c6ae99SBarry Smith   } else {
431aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
43247c6ae99SBarry Smith       if (!dd->arrayout[i]) {
43347c6ae99SBarry Smith         dd->arrayout[i] = *iptr ;
43447c6ae99SBarry Smith         dd->startout[i] = iarray_start;
43547c6ae99SBarry Smith         break;
43647c6ae99SBarry Smith       }
43747c6ae99SBarry Smith     }
43847c6ae99SBarry Smith   }
43947c6ae99SBarry Smith   PetscFunctionReturn(0);
44047c6ae99SBarry Smith }
44147c6ae99SBarry Smith 
44247c6ae99SBarry Smith #undef __FUNCT__
443aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
44447c6ae99SBarry Smith /*@C
445aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
44647c6ae99SBarry Smith 
44747c6ae99SBarry Smith     Input Parameter:
44847c6ae99SBarry Smith +    da - information about my local patch
44947c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
45047c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
45147c6ae99SBarry Smith 
45247c6ae99SBarry Smith      Level: advanced
45347c6ae99SBarry Smith 
454aa219208SBarry Smith .seealso: DMDAGetArray(), DMDAGetAdicArray()
45547c6ae99SBarry Smith 
45647c6ae99SBarry Smith @*/
4577087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool  ghosted,void *vptr)
45847c6ae99SBarry Smith {
45947c6ae99SBarry Smith   PetscInt  i;
46047c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
46147c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
46247c6ae99SBarry Smith 
46347c6ae99SBarry Smith   PetscFunctionBegin;
46447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
46547c6ae99SBarry Smith   if (ghosted) {
466aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
46747c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
46847c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
46947c6ae99SBarry Smith         dd->arrayghostedout[i] = PETSC_NULL;
47047c6ae99SBarry Smith         dd->startghostedout[i] = PETSC_NULL;
47147c6ae99SBarry Smith         break;
47247c6ae99SBarry Smith       }
47347c6ae99SBarry Smith     }
474aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
47547c6ae99SBarry Smith       if (!dd->arrayghostedin[i]){
47647c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
47747c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
47847c6ae99SBarry Smith         break;
47947c6ae99SBarry Smith       }
48047c6ae99SBarry Smith     }
48147c6ae99SBarry Smith   } else {
482aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
48347c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
48447c6ae99SBarry Smith         iarray_start    = dd->startout[i];
48547c6ae99SBarry Smith         dd->arrayout[i] = PETSC_NULL;
48647c6ae99SBarry Smith         dd->startout[i] = PETSC_NULL;
48747c6ae99SBarry Smith         break;
48847c6ae99SBarry Smith       }
48947c6ae99SBarry Smith     }
490aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
49147c6ae99SBarry Smith       if (!dd->arrayin[i]){
49247c6ae99SBarry Smith         dd->arrayin[i]  = *iptr;
49347c6ae99SBarry Smith         dd->startin[i]  = iarray_start;
49447c6ae99SBarry Smith         break;
49547c6ae99SBarry Smith       }
49647c6ae99SBarry Smith     }
49747c6ae99SBarry Smith   }
49847c6ae99SBarry Smith   PetscFunctionReturn(0);
49947c6ae99SBarry Smith }
50047c6ae99SBarry Smith 
50147c6ae99SBarry Smith #undef __FUNCT__
502aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray"
50347c6ae99SBarry Smith /*@C
504aa219208SBarry Smith      DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
50547c6ae99SBarry Smith 
50647c6ae99SBarry Smith      Input Parameter:
50747c6ae99SBarry Smith +    da - information about my local patch
50847c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
50947c6ae99SBarry Smith 
51047c6ae99SBarry Smith      Output Parameters:
51147c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
51247c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
51347c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
51447c6ae99SBarry Smith 
51547c6ae99SBarry Smith      Notes:
51647c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
51747c6ae99SBarry Smith      to zero them.
51847c6ae99SBarry Smith 
519aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
52047c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
52147c6ae99SBarry Smith 
52247c6ae99SBarry Smith      Level: advanced
52347c6ae99SBarry Smith 
524aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
52547c6ae99SBarry Smith 
52647c6ae99SBarry Smith @*/
5277087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
52847c6ae99SBarry Smith {
52947c6ae99SBarry Smith   PetscErrorCode ierr;
53047c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
53147c6ae99SBarry Smith   char           *iarray_start;
53247c6ae99SBarry Smith   void           **iptr = (void**)vptr;
53347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
53447c6ae99SBarry Smith 
53547c6ae99SBarry Smith   PetscFunctionBegin;
53647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
53747c6ae99SBarry Smith   if (ghosted) {
538aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
53947c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
54047c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
54147c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
54247c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
54347c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
54447c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
54547c6ae99SBarry Smith 
54647c6ae99SBarry Smith         goto done;
54747c6ae99SBarry Smith       }
54847c6ae99SBarry Smith     }
54947c6ae99SBarry Smith     xs = dd->Xs;
55047c6ae99SBarry Smith     ys = dd->Ys;
55147c6ae99SBarry Smith     zs = dd->Zs;
55247c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
55347c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
55447c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
55547c6ae99SBarry Smith   } else {
556aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
55747c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
55847c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
55947c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
56047c6ae99SBarry Smith         itdof              = dd->tdof;
56147c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
56247c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
56347c6ae99SBarry Smith 
56447c6ae99SBarry Smith         goto done;
56547c6ae99SBarry Smith       }
56647c6ae99SBarry Smith     }
56747c6ae99SBarry Smith     xs = dd->xs;
56847c6ae99SBarry Smith     ys = dd->ys;
56947c6ae99SBarry Smith     zs = dd->zs;
57047c6ae99SBarry Smith     xm = dd->xe-dd->xs;
57147c6ae99SBarry Smith     ym = dd->ye-dd->ys;
57247c6ae99SBarry Smith     zm = dd->ze-dd->zs;
57347c6ae99SBarry Smith   }
57447c6ae99SBarry Smith 
57547c6ae99SBarry Smith   switch (dd->dim) {
57647c6ae99SBarry Smith     case 1: {
57747c6ae99SBarry Smith       void *ptr;
57847c6ae99SBarry Smith       itdof = xm;
57947c6ae99SBarry Smith 
58047c6ae99SBarry Smith       ierr  = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
58147c6ae99SBarry Smith 
58247c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
58347c6ae99SBarry Smith       *iptr = (void*)ptr;
58447c6ae99SBarry Smith       break;}
58547c6ae99SBarry Smith     case 2: {
58647c6ae99SBarry Smith       void **ptr;
58747c6ae99SBarry Smith       itdof = xm*ym;
58847c6ae99SBarry Smith 
58947c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
59047c6ae99SBarry Smith 
59147c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
59247c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
59347c6ae99SBarry Smith         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
59447c6ae99SBarry Smith       }
59547c6ae99SBarry Smith       *iptr = (void*)ptr;
59647c6ae99SBarry Smith       break;}
59747c6ae99SBarry Smith     case 3: {
59847c6ae99SBarry Smith       void ***ptr,**bptr;
59947c6ae99SBarry Smith       itdof = xm*ym*zm;
60047c6ae99SBarry Smith 
60147c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
60247c6ae99SBarry Smith 
60347c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
60447c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
60547c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
60647c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
60747c6ae99SBarry Smith       }
60847c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
60947c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
61047c6ae99SBarry Smith           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
61147c6ae99SBarry Smith         }
61247c6ae99SBarry Smith       }
61347c6ae99SBarry Smith 
61447c6ae99SBarry Smith       *iptr = (void*)ptr;
61547c6ae99SBarry Smith       break;}
61647c6ae99SBarry Smith     default:
61747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
61847c6ae99SBarry Smith   }
61947c6ae99SBarry Smith 
62047c6ae99SBarry Smith   done:
62147c6ae99SBarry Smith   /* add arrays to the checked out list */
62247c6ae99SBarry Smith   if (ghosted) {
623aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
62447c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
62547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
62647c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
62747c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
62847c6ae99SBarry Smith         break;
62947c6ae99SBarry Smith       }
63047c6ae99SBarry Smith     }
63147c6ae99SBarry Smith   } else {
632aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
63347c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
63447c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
63547c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
63647c6ae99SBarry Smith         dd->tdof            = itdof;
63747c6ae99SBarry Smith         break;
63847c6ae99SBarry Smith       }
63947c6ae99SBarry Smith     }
64047c6ae99SBarry Smith   }
641aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
64247c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
64347c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
64447c6ae99SBarry Smith   PetscFunctionReturn(0);
64547c6ae99SBarry Smith }
64647c6ae99SBarry Smith 
64747c6ae99SBarry Smith #undef __FUNCT__
648aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray4"
6497087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
65047c6ae99SBarry Smith {
65147c6ae99SBarry Smith   PetscErrorCode ierr;
65287130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
65347c6ae99SBarry Smith   char           *iarray_start;
65447c6ae99SBarry Smith   void           **iptr = (void**)vptr;
65547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
65647c6ae99SBarry Smith 
65747c6ae99SBarry Smith   PetscFunctionBegin;
65847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
65947c6ae99SBarry Smith   if (ghosted) {
660aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
66147c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
66247c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
66347c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
66447c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
66547c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
66647c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
66747c6ae99SBarry Smith 
66847c6ae99SBarry Smith         goto done;
66947c6ae99SBarry Smith       }
67047c6ae99SBarry Smith     }
67147c6ae99SBarry Smith     xs = dd->Xs;
67247c6ae99SBarry Smith     ys = dd->Ys;
67347c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
67447c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
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     xm = dd->xe-dd->xs;
69047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
69147c6ae99SBarry Smith   }
69247c6ae99SBarry Smith 
69347c6ae99SBarry Smith   switch (dd->dim) {
69447c6ae99SBarry Smith     case 2: {
69547c6ae99SBarry Smith       void **ptr;
69647c6ae99SBarry Smith       itdof = xm*ym;
69747c6ae99SBarry Smith 
69847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
69947c6ae99SBarry Smith 
70047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
70147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
70247c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
70347c6ae99SBarry Smith       }
70447c6ae99SBarry Smith       *iptr = (void*)ptr;
70547c6ae99SBarry Smith       break;}
70647c6ae99SBarry Smith     default:
70747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
70847c6ae99SBarry Smith   }
70947c6ae99SBarry Smith 
71047c6ae99SBarry Smith   done:
71147c6ae99SBarry Smith   /* add arrays to the checked out list */
71247c6ae99SBarry Smith   if (ghosted) {
713aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
71447c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
71547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
71647c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
71747c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
71847c6ae99SBarry Smith         break;
71947c6ae99SBarry Smith       }
72047c6ae99SBarry Smith     }
72147c6ae99SBarry Smith   } else {
722aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
72347c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
72447c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
72547c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
72647c6ae99SBarry Smith         dd->tdof            = itdof;
72747c6ae99SBarry Smith         break;
72847c6ae99SBarry Smith       }
72947c6ae99SBarry Smith     }
73047c6ae99SBarry Smith   }
731aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
73247c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
73347c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
73447c6ae99SBarry Smith   PetscFunctionReturn(0);
73547c6ae99SBarry Smith }
73647c6ae99SBarry Smith 
73747c6ae99SBarry Smith #undef __FUNCT__
738aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9"
7397087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
74047c6ae99SBarry Smith {
74147c6ae99SBarry Smith   PetscErrorCode ierr;
74287130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
74347c6ae99SBarry Smith   char           *iarray_start;
74447c6ae99SBarry Smith   void           **iptr = (void**)vptr;
74547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
74647c6ae99SBarry Smith 
74747c6ae99SBarry Smith   PetscFunctionBegin;
74847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
74947c6ae99SBarry Smith   if (ghosted) {
750aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
75147c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
75247c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
75347c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
75447c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
75547c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
75647c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
75747c6ae99SBarry Smith 
75847c6ae99SBarry Smith         goto done;
75947c6ae99SBarry Smith       }
76047c6ae99SBarry Smith     }
76147c6ae99SBarry Smith     xs = dd->Xs;
76247c6ae99SBarry Smith     ys = dd->Ys;
76347c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
76447c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
76547c6ae99SBarry Smith   } else {
766aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
76747c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
76847c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
76947c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
77047c6ae99SBarry Smith         itdof              = dd->tdof;
77147c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
77247c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
77347c6ae99SBarry Smith 
77447c6ae99SBarry Smith         goto done;
77547c6ae99SBarry Smith       }
77647c6ae99SBarry Smith     }
77747c6ae99SBarry Smith     xs = dd->xs;
77847c6ae99SBarry Smith     ys = dd->ys;
77947c6ae99SBarry Smith     xm = dd->xe-dd->xs;
78047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
78147c6ae99SBarry Smith   }
78247c6ae99SBarry Smith 
78347c6ae99SBarry Smith   switch (dd->dim) {
78447c6ae99SBarry Smith     case 2: {
78547c6ae99SBarry Smith       void **ptr;
78647c6ae99SBarry Smith       itdof = xm*ym;
78747c6ae99SBarry Smith 
78847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
78947c6ae99SBarry Smith 
79047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
79147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
79247c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
79347c6ae99SBarry Smith       }
79447c6ae99SBarry Smith       *iptr = (void*)ptr;
79547c6ae99SBarry Smith       break;}
79647c6ae99SBarry Smith     default:
79747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
79847c6ae99SBarry Smith   }
79947c6ae99SBarry Smith 
80047c6ae99SBarry Smith   done:
80147c6ae99SBarry Smith   /* add arrays to the checked out list */
80247c6ae99SBarry Smith   if (ghosted) {
803aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
80447c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
80547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
80647c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
80747c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
80847c6ae99SBarry Smith         break;
80947c6ae99SBarry Smith       }
81047c6ae99SBarry Smith     }
81147c6ae99SBarry Smith   } else {
812aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
81347c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
81447c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
81547c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
81647c6ae99SBarry Smith         dd->tdof            = itdof;
81747c6ae99SBarry Smith         break;
81847c6ae99SBarry Smith       }
81947c6ae99SBarry Smith     }
82047c6ae99SBarry Smith   }
821aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
82247c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
82347c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
82447c6ae99SBarry Smith   PetscFunctionReturn(0);
82547c6ae99SBarry Smith }
82647c6ae99SBarry Smith 
82747c6ae99SBarry Smith #undef __FUNCT__
828aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb"
82947c6ae99SBarry Smith /*@C
830aa219208SBarry Smith      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
83147c6ae99SBarry Smith 
83247c6ae99SBarry Smith      Input Parameter:
83347c6ae99SBarry Smith +    da - information about my local patch
83447c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
83547c6ae99SBarry Smith 
83647c6ae99SBarry Smith      Output Parameters:
83747c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
83847c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
83947c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
84047c6ae99SBarry Smith 
84147c6ae99SBarry Smith      Notes:
84247c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
84347c6ae99SBarry Smith      to zero them.
84447c6ae99SBarry Smith 
845aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
84647c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
84747c6ae99SBarry Smith 
84847c6ae99SBarry Smith      Level: advanced
84947c6ae99SBarry Smith 
850aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
85147c6ae99SBarry Smith 
85247c6ae99SBarry Smith @*/
8537087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
85447c6ae99SBarry Smith {
85547c6ae99SBarry Smith   PetscErrorCode ierr;
85647c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
85747c6ae99SBarry Smith   char           *iarray_start;
85847c6ae99SBarry Smith   void           **iptr = (void**)vptr;
85947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
86047c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
86147c6ae99SBarry Smith 
86247c6ae99SBarry Smith   PetscFunctionBegin;
86347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
86447c6ae99SBarry Smith   if (ghosted) {
865aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
86647c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
86747c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
86847c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
86947c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
87047c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
87147c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
87247c6ae99SBarry Smith 
87347c6ae99SBarry Smith         goto done;
87447c6ae99SBarry Smith       }
87547c6ae99SBarry Smith     }
87647c6ae99SBarry Smith     xs = dd->Xs;
87747c6ae99SBarry Smith     ys = dd->Ys;
87847c6ae99SBarry Smith     zs = dd->Zs;
87947c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
88047c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
88147c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
88247c6ae99SBarry Smith   } else {
883aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
88447c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
88547c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
88647c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
88747c6ae99SBarry Smith         itdof              = dd->tdof;
88847c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
88947c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
89047c6ae99SBarry Smith 
89147c6ae99SBarry Smith         goto done;
89247c6ae99SBarry Smith       }
89347c6ae99SBarry Smith     }
89447c6ae99SBarry Smith     xs = dd->xs;
89547c6ae99SBarry Smith     ys = dd->ys;
89647c6ae99SBarry Smith     zs = dd->zs;
89747c6ae99SBarry Smith     xm = dd->xe-dd->xs;
89847c6ae99SBarry Smith     ym = dd->ye-dd->ys;
89947c6ae99SBarry Smith     zm = dd->ze-dd->zs;
90047c6ae99SBarry Smith   }
90147c6ae99SBarry Smith 
90247c6ae99SBarry Smith   switch (dd->dim) {
90347c6ae99SBarry Smith     case 1: {
90447c6ae99SBarry Smith       void *ptr;
90547c6ae99SBarry Smith       itdof = xm;
90647c6ae99SBarry Smith 
90747c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
90847c6ae99SBarry Smith 
90947c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
91047c6ae99SBarry Smith       *iptr = (void*)ptr;
91147c6ae99SBarry Smith       break;}
91247c6ae99SBarry Smith     case 2: {
91347c6ae99SBarry Smith       void **ptr;
91447c6ae99SBarry Smith       itdof = xm*ym;
91547c6ae99SBarry Smith 
91647c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
91747c6ae99SBarry Smith 
91847c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
91947c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
92047c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
92147c6ae99SBarry Smith       }
92247c6ae99SBarry Smith       *iptr = (void*)ptr;
92347c6ae99SBarry Smith       break;}
92447c6ae99SBarry Smith     case 3: {
92547c6ae99SBarry Smith       void ***ptr,**bptr;
92647c6ae99SBarry Smith       itdof = xm*ym*zm;
92747c6ae99SBarry Smith 
92847c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
92947c6ae99SBarry Smith 
93047c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
93147c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
93247c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
93347c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
93447c6ae99SBarry Smith       }
93547c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
93647c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
93747c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
93847c6ae99SBarry Smith         }
93947c6ae99SBarry Smith       }
94047c6ae99SBarry Smith 
94147c6ae99SBarry Smith       *iptr = (void*)ptr;
94247c6ae99SBarry Smith       break;}
94347c6ae99SBarry Smith     default:
94447c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
94547c6ae99SBarry Smith   }
94647c6ae99SBarry Smith 
94747c6ae99SBarry Smith   done:
94847c6ae99SBarry Smith   /* add arrays to the checked out list */
94947c6ae99SBarry Smith   if (ghosted) {
950aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
95147c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
95247c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
95347c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
95447c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
95547c6ae99SBarry Smith         break;
95647c6ae99SBarry Smith       }
95747c6ae99SBarry Smith     }
95847c6ae99SBarry Smith   } else {
959aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
96047c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
96147c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
96247c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
96347c6ae99SBarry Smith         dd->tdof            = itdof;
96447c6ae99SBarry Smith         break;
96547c6ae99SBarry Smith       }
96647c6ae99SBarry Smith     }
96747c6ae99SBarry Smith   }
968aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
96947c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
97047c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
97147c6ae99SBarry Smith   PetscFunctionReturn(0);
97247c6ae99SBarry Smith }
97347c6ae99SBarry Smith 
97447c6ae99SBarry Smith #undef __FUNCT__
975aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray"
97647c6ae99SBarry Smith /*@C
977aa219208SBarry Smith      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
97847c6ae99SBarry Smith 
97947c6ae99SBarry Smith      Input Parameter:
98047c6ae99SBarry Smith +    da - information about my local patch
98147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
98247c6ae99SBarry Smith 
98347c6ae99SBarry Smith      Output Parameters:
98447c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
98547c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
98647c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
98747c6ae99SBarry Smith 
98847c6ae99SBarry Smith      Level: advanced
98947c6ae99SBarry Smith 
990aa219208SBarry Smith .seealso: DMDAGetAdicArray()
99147c6ae99SBarry Smith 
99247c6ae99SBarry Smith @*/
9937087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
99447c6ae99SBarry Smith {
99547c6ae99SBarry Smith   PetscInt  i;
99647c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
99747c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
99847c6ae99SBarry Smith 
99947c6ae99SBarry Smith   PetscFunctionBegin;
100047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
100147c6ae99SBarry Smith   if (ghosted) {
1002aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
100347c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
100447c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
100547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
100647c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
100747c6ae99SBarry Smith         break;
100847c6ae99SBarry Smith       }
100947c6ae99SBarry Smith     }
101047c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1011aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
101247c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
101347c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
101447c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
101547c6ae99SBarry Smith         break;
101647c6ae99SBarry Smith       }
101747c6ae99SBarry Smith     }
101847c6ae99SBarry Smith   } else {
1019aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
102047c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
102147c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
102247c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
102347c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
102447c6ae99SBarry Smith         break;
102547c6ae99SBarry Smith       }
102647c6ae99SBarry Smith     }
102747c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1028aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
102947c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
103047c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
103147c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
103247c6ae99SBarry Smith         break;
103347c6ae99SBarry Smith       }
103447c6ae99SBarry Smith     }
103547c6ae99SBarry Smith   }
103647c6ae99SBarry Smith   PetscFunctionReturn(0);
103747c6ae99SBarry Smith }
103847c6ae99SBarry Smith 
103947c6ae99SBarry Smith #undef __FUNCT__
104047c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
10417087cfbeSBarry Smith PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
104247c6ae99SBarry Smith {
104347c6ae99SBarry Smith   PetscErrorCode ierr;
104447c6ae99SBarry Smith   PetscFunctionBegin;
1045aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
104647c6ae99SBarry Smith   PetscFunctionReturn(0);
104747c6ae99SBarry Smith }
104847c6ae99SBarry Smith 
104947c6ae99SBarry Smith #undef __FUNCT__
105047c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
10517087cfbeSBarry Smith PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
105247c6ae99SBarry Smith {
105347c6ae99SBarry Smith   PetscErrorCode ierr;
105447c6ae99SBarry Smith   PetscFunctionBegin;
1055aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
105647c6ae99SBarry Smith   PetscFunctionReturn(0);
105747c6ae99SBarry Smith }
105847c6ae99SBarry Smith 
1059