xref: /petsc/src/dm/impls/da/dalocal.c (revision e3c5b3bad8a8c55ce6fdc25c1dde664f52a31a1c)
147c6ae99SBarry Smith #define PETSCDM_DLL
247c6ae99SBarry Smith 
347c6ae99SBarry Smith /*
447c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
547c6ae99SBarry Smith */
647c6ae99SBarry Smith 
7e1589f56SBarry Smith #include "private/daimpl.h"    /*I   "petscdm.h"   I*/
847c6ae99SBarry Smith 
947c6ae99SBarry Smith /*
10*e3c5b3baSBarry Smith    This allows the DMDA vectors to properly tell MATLAB their dimensions
1147c6ae99SBarry Smith */
1247c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
13*e3c5b3baSBarry Smith #include "engine.h"   /* MATLAB include file */
14*e3c5b3baSBarry Smith #include "mex.h"      /* MATLAB include file */
1547c6ae99SBarry Smith EXTERN_C_BEGIN
1647c6ae99SBarry Smith #undef __FUNCT__
1747c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d"
187087cfbeSBarry Smith PetscErrorCode  VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine)
1947c6ae99SBarry Smith {
2047c6ae99SBarry Smith   PetscErrorCode ierr;
2147c6ae99SBarry Smith   PetscInt       n,m;
2247c6ae99SBarry Smith   Vec            vec = (Vec)obj;
2347c6ae99SBarry Smith   PetscScalar    *array;
2447c6ae99SBarry Smith   mxArray        *mat;
259a42bb27SBarry Smith   DM             da;
2647c6ae99SBarry Smith 
2747c6ae99SBarry Smith   PetscFunctionBegin;
28aa219208SBarry Smith   ierr = PetscObjectQuery((PetscObject)vec,"DMDA",(PetscObject*)&da);CHKERRQ(ierr);
29aa219208SBarry Smith   if (!da) SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA");
30aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr);
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith   ierr = VecGetArray(vec,&array);CHKERRQ(ierr);
3347c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
3447c6ae99SBarry Smith   mat  = mxCreateDoubleMatrix(m,n,mxREAL);
3547c6ae99SBarry Smith #else
3647c6ae99SBarry Smith   mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3747c6ae99SBarry Smith #endif
3847c6ae99SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr);
3947c6ae99SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
4047c6ae99SBarry Smith   engPutVariable((Engine *)mengine,obj->name,mat);
4147c6ae99SBarry Smith 
4247c6ae99SBarry Smith   ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr);
4347c6ae99SBarry Smith   PetscFunctionReturn(0);
4447c6ae99SBarry Smith }
4547c6ae99SBarry Smith EXTERN_C_END
4647c6ae99SBarry Smith #endif
4747c6ae99SBarry Smith 
4847c6ae99SBarry Smith 
4947c6ae99SBarry Smith #undef __FUNCT__
50564755cdSBarry Smith #define __FUNCT__ "DMCreateLocalVector_DA"
517087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_DA(DM da,Vec* g)
5247c6ae99SBarry Smith {
5347c6ae99SBarry Smith   PetscErrorCode ierr;
5447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
5547c6ae99SBarry Smith 
5647c6ae99SBarry Smith   PetscFunctionBegin;
5747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
5847c6ae99SBarry Smith   PetscValidPointer(g,2);
5947c6ae99SBarry Smith   ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr);
6047c6ae99SBarry Smith   ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
6147c6ae99SBarry Smith   ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
6247c6ae99SBarry Smith   ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
63aa219208SBarry Smith   ierr = PetscObjectCompose((PetscObject)*g,"DMDA",(PetscObject)da);CHKERRQ(ierr);
6447c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
6547c6ae99SBarry Smith   if (dd->w == 1  && dd->dim == 2) {
6647c6ae99SBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
6747c6ae99SBarry Smith   }
6847c6ae99SBarry Smith #endif
6947c6ae99SBarry Smith   PetscFunctionReturn(0);
7047c6ae99SBarry Smith }
7147c6ae99SBarry Smith 
7247c6ae99SBarry Smith #undef __FUNCT__
7347c6ae99SBarry Smith #define __FUNCT__ "DMGetLocalVector"
7447c6ae99SBarry Smith /*@
7547c6ae99SBarry Smith    DMGetLocalVector - Gets a Seq PETSc vector that
7647c6ae99SBarry Smith    may be used with the DMXXX routines. This vector has spaces for the ghost values.
7747c6ae99SBarry Smith 
7847c6ae99SBarry Smith    Not Collective
7947c6ae99SBarry Smith 
8047c6ae99SBarry Smith    Input Parameter:
8147c6ae99SBarry Smith .  dm - the distributed array
8247c6ae99SBarry Smith 
8347c6ae99SBarry Smith    Output Parameter:
8447c6ae99SBarry Smith .  g - the local vector
8547c6ae99SBarry Smith 
8647c6ae99SBarry Smith    Level: beginner
8747c6ae99SBarry Smith 
8847c6ae99SBarry Smith    Note:
8947c6ae99SBarry Smith    The vector values are NOT initialized and may have garbage in them, so you may need
9047c6ae99SBarry Smith    to zero them.
9147c6ae99SBarry Smith 
9247c6ae99SBarry Smith    The output parameter, g, is a regular PETSc vector that should be returned with
9347c6ae99SBarry Smith    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
9447c6ae99SBarry Smith 
9547c6ae99SBarry Smith    VecStride*() operations can be useful when using DM with dof > 1
9647c6ae99SBarry Smith 
9747c6ae99SBarry Smith .keywords: distributed array, create, local, vector
9847c6ae99SBarry Smith 
9947c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
100aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
1019a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
10247c6ae99SBarry Smith           VecStrideMax(), VecStrideMin(), VecStrideNorm()
10347c6ae99SBarry Smith @*/
1047087cfbeSBarry Smith PetscErrorCode  DMGetLocalVector(DM dm,Vec* g)
10547c6ae99SBarry Smith {
10647c6ae99SBarry Smith   PetscErrorCode ierr,i;
10747c6ae99SBarry Smith 
10847c6ae99SBarry Smith   PetscFunctionBegin;
10947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11047c6ae99SBarry Smith   PetscValidPointer(g,2);
11147c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
11247c6ae99SBarry Smith     if (dm->localin[i]) {
11347c6ae99SBarry Smith       *g             = dm->localin[i];
11447c6ae99SBarry Smith       dm->localin[i] = PETSC_NULL;
11547c6ae99SBarry Smith       goto alldone;
11647c6ae99SBarry Smith     }
11747c6ae99SBarry Smith   }
11847c6ae99SBarry Smith   ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr);
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith   alldone:
12147c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
12247c6ae99SBarry Smith     if (!dm->localout[i]) {
12347c6ae99SBarry Smith       dm->localout[i] = *g;
12447c6ae99SBarry Smith       break;
12547c6ae99SBarry Smith     }
12647c6ae99SBarry Smith   }
12747c6ae99SBarry Smith   PetscFunctionReturn(0);
12847c6ae99SBarry Smith }
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith #undef __FUNCT__
13147c6ae99SBarry Smith #define __FUNCT__ "DMRestoreLocalVector"
13247c6ae99SBarry Smith /*@
13347c6ae99SBarry Smith    DMRestoreLocalVector - Returns a Seq PETSc vector that
13447c6ae99SBarry Smith      obtained from DMGetLocalVector(). Do not use with vector obtained via
13547c6ae99SBarry Smith      DMCreateLocalVector().
13647c6ae99SBarry Smith 
13747c6ae99SBarry Smith    Not Collective
13847c6ae99SBarry Smith 
13947c6ae99SBarry Smith    Input Parameter:
14047c6ae99SBarry Smith +  dm - the distributed array
14147c6ae99SBarry Smith -  g - the local vector
14247c6ae99SBarry Smith 
14347c6ae99SBarry Smith    Level: beginner
14447c6ae99SBarry Smith 
14547c6ae99SBarry Smith .keywords: distributed array, create, local, vector
14647c6ae99SBarry Smith 
14747c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
148aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
1499a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
15047c6ae99SBarry Smith @*/
1517087cfbeSBarry Smith PetscErrorCode  DMRestoreLocalVector(DM dm,Vec* g)
15247c6ae99SBarry Smith {
15347c6ae99SBarry Smith   PetscErrorCode ierr;
15447c6ae99SBarry Smith   PetscInt       i,j;
15547c6ae99SBarry Smith 
15647c6ae99SBarry Smith   PetscFunctionBegin;
15747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15847c6ae99SBarry Smith   PetscValidPointer(g,2);
15947c6ae99SBarry Smith   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
16047c6ae99SBarry Smith     if (*g == dm->localout[j]) {
16147c6ae99SBarry Smith       dm->localout[j] = PETSC_NULL;
16247c6ae99SBarry Smith       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
16347c6ae99SBarry Smith         if (!dm->localin[i]) {
16447c6ae99SBarry Smith           dm->localin[i] = *g;
16547c6ae99SBarry Smith           goto alldone;
16647c6ae99SBarry Smith         }
16747c6ae99SBarry Smith       }
16847c6ae99SBarry Smith     }
16947c6ae99SBarry Smith   }
17047c6ae99SBarry Smith   ierr = VecDestroy(*g);CHKERRQ(ierr);
17147c6ae99SBarry Smith   alldone:
17247c6ae99SBarry Smith   PetscFunctionReturn(0);
17347c6ae99SBarry Smith }
17447c6ae99SBarry Smith 
17547c6ae99SBarry Smith #undef __FUNCT__
17647c6ae99SBarry Smith #define __FUNCT__ "DMGetGlobalVector"
17747c6ae99SBarry Smith /*@
17847c6ae99SBarry Smith    DMGetGlobalVector - Gets a MPI PETSc vector that
17947c6ae99SBarry Smith    may be used with the DMXXX routines.
18047c6ae99SBarry Smith 
18147c6ae99SBarry Smith    Collective on DM
18247c6ae99SBarry Smith 
18347c6ae99SBarry Smith    Input Parameter:
18447c6ae99SBarry Smith .  dm - the distributed array
18547c6ae99SBarry Smith 
18647c6ae99SBarry Smith    Output Parameter:
18747c6ae99SBarry Smith .  g - the global vector
18847c6ae99SBarry Smith 
18947c6ae99SBarry Smith    Level: beginner
19047c6ae99SBarry Smith 
19147c6ae99SBarry Smith    Note:
19247c6ae99SBarry Smith    The vector values are NOT initialized and may have garbage in them, so you may need
19347c6ae99SBarry Smith    to zero them.
19447c6ae99SBarry Smith 
19547c6ae99SBarry Smith    The output parameter, g, is a regular PETSc vector that should be returned with
19647c6ae99SBarry Smith    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
19747c6ae99SBarry Smith 
19847c6ae99SBarry Smith    VecStride*() operations can be useful when using DM with dof > 1
19947c6ae99SBarry Smith 
20047c6ae99SBarry Smith .keywords: distributed array, create, Global, vector
20147c6ae99SBarry Smith 
20247c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
203aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
2049a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
20547c6ae99SBarry Smith           VecStrideMax(), VecStrideMin(), VecStrideNorm()
20647c6ae99SBarry Smith 
20747c6ae99SBarry Smith @*/
2087087cfbeSBarry Smith PetscErrorCode  DMGetGlobalVector(DM dm,Vec* g)
20947c6ae99SBarry Smith {
21047c6ae99SBarry Smith   PetscErrorCode ierr;
21147c6ae99SBarry Smith   PetscInt       i;
21247c6ae99SBarry Smith 
21347c6ae99SBarry Smith   PetscFunctionBegin;
21447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21547c6ae99SBarry Smith   PetscValidPointer(g,2);
21647c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
21747c6ae99SBarry Smith     if (dm->globalin[i]) {
21847c6ae99SBarry Smith       *g             = dm->globalin[i];
21947c6ae99SBarry Smith       dm->globalin[i] = PETSC_NULL;
22047c6ae99SBarry Smith       goto alldone;
22147c6ae99SBarry Smith     }
22247c6ae99SBarry Smith   }
22347c6ae99SBarry Smith   ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
22447c6ae99SBarry Smith 
22547c6ae99SBarry Smith   alldone:
22647c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
22747c6ae99SBarry Smith     if (!dm->globalout[i]) {
22847c6ae99SBarry Smith       dm->globalout[i] = *g;
22947c6ae99SBarry Smith       break;
23047c6ae99SBarry Smith     }
23147c6ae99SBarry Smith   }
23247c6ae99SBarry Smith   PetscFunctionReturn(0);
23347c6ae99SBarry Smith }
23447c6ae99SBarry Smith 
23547c6ae99SBarry Smith #undef __FUNCT__
23647c6ae99SBarry Smith #define __FUNCT__ "DMRestoreGlobalVector"
23747c6ae99SBarry Smith /*@
23847c6ae99SBarry Smith    DMRestoreGlobalVector - Returns a Seq PETSc vector that
23947c6ae99SBarry Smith      obtained from DMGetGlobalVector(). Do not use with vector obtained via
24047c6ae99SBarry Smith      DMCreateGlobalVector().
24147c6ae99SBarry Smith 
24247c6ae99SBarry Smith    Not Collective
24347c6ae99SBarry Smith 
24447c6ae99SBarry Smith    Input Parameter:
24547c6ae99SBarry Smith +  dm - the distributed array
24647c6ae99SBarry Smith -  g - the global vector
24747c6ae99SBarry Smith 
24847c6ae99SBarry Smith    Level: beginner
24947c6ae99SBarry Smith 
25047c6ae99SBarry Smith .keywords: distributed array, create, global, vector
25147c6ae99SBarry Smith 
25247c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
253aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
25447c6ae99SBarry Smith           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
25547c6ae99SBarry Smith @*/
2567087cfbeSBarry Smith PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec* g)
25747c6ae99SBarry Smith {
25847c6ae99SBarry Smith   PetscErrorCode ierr;
25947c6ae99SBarry Smith   PetscInt       i,j;
26047c6ae99SBarry Smith 
26147c6ae99SBarry Smith   PetscFunctionBegin;
26247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
26347c6ae99SBarry Smith   PetscValidPointer(g,2);
26447c6ae99SBarry Smith   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
26547c6ae99SBarry Smith     if (*g == dm->globalout[j]) {
26647c6ae99SBarry Smith       dm->globalout[j] = PETSC_NULL;
26747c6ae99SBarry Smith       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
26847c6ae99SBarry Smith         if (!dm->globalin[i]) {
26947c6ae99SBarry Smith           dm->globalin[i] = *g;
27047c6ae99SBarry Smith           goto alldone;
27147c6ae99SBarry Smith         }
27247c6ae99SBarry Smith       }
27347c6ae99SBarry Smith     }
27447c6ae99SBarry Smith   }
27547c6ae99SBarry Smith   ierr = VecDestroy(*g);CHKERRQ(ierr);
27647c6ae99SBarry Smith   alldone:
27747c6ae99SBarry Smith   PetscFunctionReturn(0);
27847c6ae99SBarry Smith }
27947c6ae99SBarry Smith 
28047c6ae99SBarry Smith /* ------------------------------------------------------------------- */
28147c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
28247c6ae99SBarry Smith 
28347c6ae99SBarry Smith EXTERN_C_BEGIN
28447c6ae99SBarry Smith #include "adic/ad_utils.h"
28547c6ae99SBarry Smith EXTERN_C_END
28647c6ae99SBarry Smith 
28747c6ae99SBarry Smith #undef __FUNCT__
288aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicArray"
28947c6ae99SBarry Smith /*@C
290aa219208SBarry Smith      DMDAGetAdicArray - Gets an array of derivative types for a DMDA
29147c6ae99SBarry Smith 
29247c6ae99SBarry Smith     Input Parameter:
29347c6ae99SBarry Smith +    da - information about my local patch
29447c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
29547c6ae99SBarry Smith 
29647c6ae99SBarry Smith     Output Parameters:
29747c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
29847c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
29947c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
30047c6ae99SBarry Smith 
30147c6ae99SBarry Smith      Notes:
30247c6ae99SBarry Smith        The vector values are NOT initialized and may have garbage in them, so you may need
30347c6ae99SBarry Smith        to zero them.
30447c6ae99SBarry Smith 
305aa219208SBarry Smith        Returns the same type of object as the DMDAVecGetArray() except its elements are
30647c6ae99SBarry Smith            derivative types instead of PetscScalars
30747c6ae99SBarry Smith 
30847c6ae99SBarry Smith      Level: advanced
30947c6ae99SBarry Smith 
310aa219208SBarry Smith .seealso: DMDARestoreAdicArray()
31147c6ae99SBarry Smith 
31247c6ae99SBarry Smith @*/
3137087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
31447c6ae99SBarry Smith {
31547c6ae99SBarry Smith   PetscErrorCode ierr;
31647c6ae99SBarry Smith   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
31747c6ae99SBarry Smith   char           *iarray_start;
31847c6ae99SBarry Smith   void           **iptr = (void**)vptr;
31947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
32047c6ae99SBarry Smith 
32147c6ae99SBarry Smith   PetscFunctionBegin;
32247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
32347c6ae99SBarry Smith   if (ghosted) {
324aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
32547c6ae99SBarry Smith       if (dd->adarrayghostedin[i]) {
32647c6ae99SBarry Smith         *iptr                   = dd->adarrayghostedin[i];
32747c6ae99SBarry Smith         iarray_start            = (char*)dd->adstartghostedin[i];
32847c6ae99SBarry Smith         itdof                   = dd->ghostedtdof;
32947c6ae99SBarry Smith         dd->adarrayghostedin[i] = PETSC_NULL;
33047c6ae99SBarry Smith         dd->adstartghostedin[i] = PETSC_NULL;
33147c6ae99SBarry Smith 
33247c6ae99SBarry Smith         goto done;
33347c6ae99SBarry Smith       }
33447c6ae99SBarry Smith     }
33547c6ae99SBarry Smith     xs = dd->Xs;
33647c6ae99SBarry Smith     ys = dd->Ys;
33747c6ae99SBarry Smith     zs = dd->Zs;
33847c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
33947c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
34047c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
34147c6ae99SBarry Smith   } else {
342aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
34347c6ae99SBarry Smith       if (dd->adarrayin[i]) {
34447c6ae99SBarry Smith         *iptr            = dd->adarrayin[i];
34547c6ae99SBarry Smith         iarray_start     = (char*)dd->adstartin[i];
34647c6ae99SBarry Smith         itdof            = dd->tdof;
34747c6ae99SBarry Smith         dd->adarrayin[i] = PETSC_NULL;
34847c6ae99SBarry Smith         dd->adstartin[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   }
36047c6ae99SBarry Smith   deriv_type_size = PetscADGetDerivTypeSize();
36147c6ae99SBarry Smith 
36247c6ae99SBarry Smith   switch (dd->dim) {
36347c6ae99SBarry Smith     case 1: {
36447c6ae99SBarry Smith       void *ptr;
36547c6ae99SBarry Smith       itdof = xm;
36647c6ae99SBarry Smith 
36747c6ae99SBarry Smith       ierr  = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
36847c6ae99SBarry Smith 
36947c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*deriv_type_size);
37047c6ae99SBarry Smith       *iptr = (void*)ptr;
37147c6ae99SBarry Smith       break;}
37247c6ae99SBarry Smith     case 2: {
37347c6ae99SBarry Smith       void **ptr;
37447c6ae99SBarry Smith       itdof = xm*ym;
37547c6ae99SBarry Smith 
37647c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr);
37747c6ae99SBarry Smith 
37847c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
37947c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
38047c6ae99SBarry Smith         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
38147c6ae99SBarry Smith       }
38247c6ae99SBarry Smith       *iptr = (void*)ptr;
38347c6ae99SBarry Smith       break;}
38447c6ae99SBarry Smith     case 3: {
38547c6ae99SBarry Smith       void ***ptr,**bptr;
38647c6ae99SBarry Smith       itdof = xm*ym*zm;
38747c6ae99SBarry Smith 
38847c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
38947c6ae99SBarry Smith 
39047c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
39147c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
39247c6ae99SBarry Smith 
39347c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
39447c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
39547c6ae99SBarry Smith       }
39647c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
39747c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
39847c6ae99SBarry Smith           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
39947c6ae99SBarry Smith         }
40047c6ae99SBarry Smith       }
40147c6ae99SBarry Smith 
40247c6ae99SBarry Smith       *iptr = (void*)ptr;
40347c6ae99SBarry Smith       break;}
40447c6ae99SBarry Smith     default:
40547c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
40647c6ae99SBarry Smith   }
40747c6ae99SBarry Smith 
40847c6ae99SBarry Smith   done:
40947c6ae99SBarry Smith   /* add arrays to the checked out list */
41047c6ae99SBarry Smith   if (ghosted) {
411aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
41247c6ae99SBarry Smith       if (!dd->adarrayghostedout[i]) {
41347c6ae99SBarry Smith         dd->adarrayghostedout[i] = *iptr ;
41447c6ae99SBarry Smith         dd->adstartghostedout[i] = iarray_start;
41547c6ae99SBarry Smith         dd->ghostedtdof          = itdof;
41647c6ae99SBarry Smith         break;
41747c6ae99SBarry Smith       }
41847c6ae99SBarry Smith     }
41947c6ae99SBarry Smith   } else {
420aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
42147c6ae99SBarry Smith       if (!dd->adarrayout[i]) {
42247c6ae99SBarry Smith         dd->adarrayout[i] = *iptr ;
42347c6ae99SBarry Smith         dd->adstartout[i] = iarray_start;
42447c6ae99SBarry Smith         dd->tdof          = itdof;
42547c6ae99SBarry Smith         break;
42647c6ae99SBarry Smith       }
42747c6ae99SBarry Smith     }
42847c6ae99SBarry Smith   }
429aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
43047c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
43147c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
43247c6ae99SBarry Smith   PetscFunctionReturn(0);
43347c6ae99SBarry Smith }
43447c6ae99SBarry Smith 
43547c6ae99SBarry Smith #undef __FUNCT__
436aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicArray"
43747c6ae99SBarry Smith /*@C
438aa219208SBarry Smith      DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
43947c6ae99SBarry Smith 
44047c6ae99SBarry Smith     Input Parameter:
44147c6ae99SBarry Smith +    da - information about my local patch
44247c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
44347c6ae99SBarry Smith 
44447c6ae99SBarry Smith     Output Parameters:
44547c6ae99SBarry Smith +    ptr - array data structured to be passed to ad_FormFunctionLocal()
44647c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
44747c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
44847c6ae99SBarry Smith 
44947c6ae99SBarry Smith      Level: advanced
45047c6ae99SBarry Smith 
451aa219208SBarry Smith .seealso: DMDAGetAdicArray()
45247c6ae99SBarry Smith 
45347c6ae99SBarry Smith @*/
4547087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
45547c6ae99SBarry Smith {
45647c6ae99SBarry Smith   PetscInt  i;
45747c6ae99SBarry Smith   void      **iptr = (void**)ptr,iarray_start = 0;
45847c6ae99SBarry Smith 
45947c6ae99SBarry Smith   PetscFunctionBegin;
46047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
46147c6ae99SBarry Smith   if (ghosted) {
462aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
46347c6ae99SBarry Smith       if (dd->adarrayghostedout[i] == *iptr) {
46447c6ae99SBarry Smith         iarray_start             = dd->adstartghostedout[i];
46547c6ae99SBarry Smith         dd->adarrayghostedout[i] = PETSC_NULL;
46647c6ae99SBarry Smith         dd->adstartghostedout[i] = PETSC_NULL;
46747c6ae99SBarry Smith         break;
46847c6ae99SBarry Smith       }
46947c6ae99SBarry Smith     }
47047c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
471aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
47247c6ae99SBarry Smith       if (!dd->adarrayghostedin[i]){
47347c6ae99SBarry Smith         dd->adarrayghostedin[i] = *iptr;
47447c6ae99SBarry Smith         dd->adstartghostedin[i] = iarray_start;
47547c6ae99SBarry Smith         break;
47647c6ae99SBarry Smith       }
47747c6ae99SBarry Smith     }
47847c6ae99SBarry Smith   } else {
479aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
48047c6ae99SBarry Smith       if (dd->adarrayout[i] == *iptr) {
48147c6ae99SBarry Smith         iarray_start      = dd->adstartout[i];
48247c6ae99SBarry Smith         dd->adarrayout[i] = PETSC_NULL;
48347c6ae99SBarry Smith         dd->adstartout[i] = PETSC_NULL;
48447c6ae99SBarry Smith         break;
48547c6ae99SBarry Smith       }
48647c6ae99SBarry Smith     }
48747c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
488aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
48947c6ae99SBarry Smith       if (!dd->adarrayin[i]){
49047c6ae99SBarry Smith         dd->adarrayin[i]   = *iptr;
49147c6ae99SBarry Smith         dd->adstartin[i]   = iarray_start;
49247c6ae99SBarry Smith         break;
49347c6ae99SBarry Smith       }
49447c6ae99SBarry Smith     }
49547c6ae99SBarry Smith   }
49647c6ae99SBarry Smith   PetscFunctionReturn(0);
49747c6ae99SBarry Smith }
49847c6ae99SBarry Smith 
49947c6ae99SBarry Smith #undef __FUNCT__
50047c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray"
5017087cfbeSBarry Smith PetscErrorCode  ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
50247c6ae99SBarry Smith {
50347c6ae99SBarry Smith   PetscErrorCode ierr;
50447c6ae99SBarry Smith   PetscFunctionBegin;
505aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
50647c6ae99SBarry Smith   PetscFunctionReturn(0);
50747c6ae99SBarry Smith }
50847c6ae99SBarry Smith 
50947c6ae99SBarry Smith #undef __FUNCT__
51047c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray"
5117087cfbeSBarry Smith PetscErrorCode  ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
51247c6ae99SBarry Smith {
51347c6ae99SBarry Smith   PetscErrorCode ierr;
51447c6ae99SBarry Smith   PetscFunctionBegin;
515aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
51647c6ae99SBarry Smith   PetscFunctionReturn(0);
51747c6ae99SBarry Smith }
51847c6ae99SBarry Smith 
51947c6ae99SBarry Smith #endif
52047c6ae99SBarry Smith 
52147c6ae99SBarry Smith #undef __FUNCT__
522aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
52347c6ae99SBarry Smith /*@C
524aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
52547c6ae99SBarry Smith 
52647c6ae99SBarry Smith     Input Parameter:
52747c6ae99SBarry Smith +    da - information about my local patch
52847c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
52947c6ae99SBarry Smith 
53047c6ae99SBarry Smith     Output Parameters:
53147c6ae99SBarry Smith .    vptr - array data structured
53247c6ae99SBarry Smith 
53347c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
53447c6ae99SBarry Smith            to zero them.
53547c6ae99SBarry Smith 
53647c6ae99SBarry Smith   Level: advanced
53747c6ae99SBarry Smith 
538aa219208SBarry Smith .seealso: DMDARestoreArray(), DMDAGetAdicArray()
53947c6ae99SBarry Smith 
54047c6ae99SBarry Smith @*/
5417087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool  ghosted,void *vptr)
54247c6ae99SBarry Smith {
54347c6ae99SBarry Smith   PetscErrorCode ierr;
54447c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
54547c6ae99SBarry Smith   char           *iarray_start;
54647c6ae99SBarry Smith   void           **iptr = (void**)vptr;
54747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
54847c6ae99SBarry Smith 
54947c6ae99SBarry Smith   PetscFunctionBegin;
55047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
55147c6ae99SBarry Smith   if (ghosted) {
552aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
55347c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
55447c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
55547c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
55647c6ae99SBarry Smith         dd->arrayghostedin[i] = PETSC_NULL;
55747c6ae99SBarry Smith         dd->startghostedin[i] = PETSC_NULL;
55847c6ae99SBarry Smith 
55947c6ae99SBarry Smith         goto done;
56047c6ae99SBarry Smith       }
56147c6ae99SBarry Smith     }
56247c6ae99SBarry Smith     xs = dd->Xs;
56347c6ae99SBarry Smith     ys = dd->Ys;
56447c6ae99SBarry Smith     zs = dd->Zs;
56547c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
56647c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
56747c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
56847c6ae99SBarry Smith   } else {
569aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
57047c6ae99SBarry Smith       if (dd->arrayin[i]) {
57147c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
57247c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
57347c6ae99SBarry Smith         dd->arrayin[i] = PETSC_NULL;
57447c6ae99SBarry Smith         dd->startin[i] = PETSC_NULL;
57547c6ae99SBarry Smith 
57647c6ae99SBarry Smith         goto done;
57747c6ae99SBarry Smith       }
57847c6ae99SBarry Smith     }
57947c6ae99SBarry Smith     xs = dd->xs;
58047c6ae99SBarry Smith     ys = dd->ys;
58147c6ae99SBarry Smith     zs = dd->zs;
58247c6ae99SBarry Smith     xm = dd->xe-dd->xs;
58347c6ae99SBarry Smith     ym = dd->ye-dd->ys;
58447c6ae99SBarry Smith     zm = dd->ze-dd->zs;
58547c6ae99SBarry Smith   }
58647c6ae99SBarry Smith 
58747c6ae99SBarry Smith   switch (dd->dim) {
58847c6ae99SBarry Smith     case 1: {
58947c6ae99SBarry Smith       void *ptr;
59047c6ae99SBarry Smith 
59147c6ae99SBarry Smith       ierr  = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
59247c6ae99SBarry Smith 
59347c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
59447c6ae99SBarry Smith       *iptr = (void*)ptr;
59547c6ae99SBarry Smith       break;}
59647c6ae99SBarry Smith     case 2: {
59747c6ae99SBarry Smith       void **ptr;
59847c6ae99SBarry Smith 
59947c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
60047c6ae99SBarry Smith 
60147c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
60247c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
60347c6ae99SBarry Smith         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
60447c6ae99SBarry Smith       }
60547c6ae99SBarry Smith       *iptr = (void*)ptr;
60647c6ae99SBarry Smith       break;}
60747c6ae99SBarry Smith     case 3: {
60847c6ae99SBarry Smith       void ***ptr,**bptr;
60947c6ae99SBarry Smith 
61047c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
61147c6ae99SBarry Smith 
61247c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
61347c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
61447c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
61547c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
61647c6ae99SBarry Smith       }
61747c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
61847c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
61947c6ae99SBarry Smith           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
62047c6ae99SBarry Smith         }
62147c6ae99SBarry Smith       }
62247c6ae99SBarry Smith 
62347c6ae99SBarry Smith       *iptr = (void*)ptr;
62447c6ae99SBarry Smith       break;}
62547c6ae99SBarry Smith     default:
62647c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
62747c6ae99SBarry Smith   }
62847c6ae99SBarry Smith 
62947c6ae99SBarry Smith   done:
63047c6ae99SBarry Smith   /* add arrays to the checked out list */
63147c6ae99SBarry Smith   if (ghosted) {
632aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
63347c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
63447c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr ;
63547c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
63647c6ae99SBarry Smith         break;
63747c6ae99SBarry Smith       }
63847c6ae99SBarry Smith     }
63947c6ae99SBarry Smith   } else {
640aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
64147c6ae99SBarry Smith       if (!dd->arrayout[i]) {
64247c6ae99SBarry Smith         dd->arrayout[i] = *iptr ;
64347c6ae99SBarry Smith         dd->startout[i] = iarray_start;
64447c6ae99SBarry Smith         break;
64547c6ae99SBarry Smith       }
64647c6ae99SBarry Smith     }
64747c6ae99SBarry Smith   }
64847c6ae99SBarry Smith   PetscFunctionReturn(0);
64947c6ae99SBarry Smith }
65047c6ae99SBarry Smith 
65147c6ae99SBarry Smith #undef __FUNCT__
652aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
65347c6ae99SBarry Smith /*@C
654aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
65547c6ae99SBarry Smith 
65647c6ae99SBarry Smith     Input Parameter:
65747c6ae99SBarry Smith +    da - information about my local patch
65847c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
65947c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
66047c6ae99SBarry Smith 
66147c6ae99SBarry Smith      Level: advanced
66247c6ae99SBarry Smith 
663aa219208SBarry Smith .seealso: DMDAGetArray(), DMDAGetAdicArray()
66447c6ae99SBarry Smith 
66547c6ae99SBarry Smith @*/
6667087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool  ghosted,void *vptr)
66747c6ae99SBarry Smith {
66847c6ae99SBarry Smith   PetscInt  i;
66947c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
67047c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
67147c6ae99SBarry Smith 
67247c6ae99SBarry Smith   PetscFunctionBegin;
67347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
67447c6ae99SBarry Smith   if (ghosted) {
675aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
67647c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
67747c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
67847c6ae99SBarry Smith         dd->arrayghostedout[i] = PETSC_NULL;
67947c6ae99SBarry Smith         dd->startghostedout[i] = PETSC_NULL;
68047c6ae99SBarry Smith         break;
68147c6ae99SBarry Smith       }
68247c6ae99SBarry Smith     }
683aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
68447c6ae99SBarry Smith       if (!dd->arrayghostedin[i]){
68547c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
68647c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
68747c6ae99SBarry Smith         break;
68847c6ae99SBarry Smith       }
68947c6ae99SBarry Smith     }
69047c6ae99SBarry Smith   } else {
691aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
69247c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
69347c6ae99SBarry Smith         iarray_start    = dd->startout[i];
69447c6ae99SBarry Smith         dd->arrayout[i] = PETSC_NULL;
69547c6ae99SBarry Smith         dd->startout[i] = PETSC_NULL;
69647c6ae99SBarry Smith         break;
69747c6ae99SBarry Smith       }
69847c6ae99SBarry Smith     }
699aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
70047c6ae99SBarry Smith       if (!dd->arrayin[i]){
70147c6ae99SBarry Smith         dd->arrayin[i]  = *iptr;
70247c6ae99SBarry Smith         dd->startin[i]  = iarray_start;
70347c6ae99SBarry Smith         break;
70447c6ae99SBarry Smith       }
70547c6ae99SBarry Smith     }
70647c6ae99SBarry Smith   }
70747c6ae99SBarry Smith   PetscFunctionReturn(0);
70847c6ae99SBarry Smith }
70947c6ae99SBarry Smith 
71047c6ae99SBarry Smith #undef __FUNCT__
711aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray"
71247c6ae99SBarry Smith /*@C
713aa219208SBarry Smith      DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
71447c6ae99SBarry Smith 
71547c6ae99SBarry Smith      Input Parameter:
71647c6ae99SBarry Smith +    da - information about my local patch
71747c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
71847c6ae99SBarry Smith 
71947c6ae99SBarry Smith      Output Parameters:
72047c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
72147c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
72247c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
72347c6ae99SBarry Smith 
72447c6ae99SBarry Smith      Notes:
72547c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
72647c6ae99SBarry Smith      to zero them.
72747c6ae99SBarry Smith 
728aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
72947c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
73047c6ae99SBarry Smith 
73147c6ae99SBarry Smith      Level: advanced
73247c6ae99SBarry Smith 
733aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
73447c6ae99SBarry Smith 
73547c6ae99SBarry Smith @*/
7367087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
73747c6ae99SBarry Smith {
73847c6ae99SBarry Smith   PetscErrorCode ierr;
73947c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
74047c6ae99SBarry Smith   char           *iarray_start;
74147c6ae99SBarry Smith   void           **iptr = (void**)vptr;
74247c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
74347c6ae99SBarry Smith 
74447c6ae99SBarry Smith   PetscFunctionBegin;
74547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
74647c6ae99SBarry Smith   if (ghosted) {
747aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
74847c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
74947c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
75047c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
75147c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
75247c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
75347c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
75447c6ae99SBarry Smith 
75547c6ae99SBarry Smith         goto done;
75647c6ae99SBarry Smith       }
75747c6ae99SBarry Smith     }
75847c6ae99SBarry Smith     xs = dd->Xs;
75947c6ae99SBarry Smith     ys = dd->Ys;
76047c6ae99SBarry Smith     zs = dd->Zs;
76147c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
76247c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
76347c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
76447c6ae99SBarry Smith   } else {
765aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
76647c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
76747c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
76847c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
76947c6ae99SBarry Smith         itdof              = dd->tdof;
77047c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
77147c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
77247c6ae99SBarry Smith 
77347c6ae99SBarry Smith         goto done;
77447c6ae99SBarry Smith       }
77547c6ae99SBarry Smith     }
77647c6ae99SBarry Smith     xs = dd->xs;
77747c6ae99SBarry Smith     ys = dd->ys;
77847c6ae99SBarry Smith     zs = dd->zs;
77947c6ae99SBarry Smith     xm = dd->xe-dd->xs;
78047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
78147c6ae99SBarry Smith     zm = dd->ze-dd->zs;
78247c6ae99SBarry Smith   }
78347c6ae99SBarry Smith 
78447c6ae99SBarry Smith   switch (dd->dim) {
78547c6ae99SBarry Smith     case 1: {
78647c6ae99SBarry Smith       void *ptr;
78747c6ae99SBarry Smith       itdof = xm;
78847c6ae99SBarry Smith 
78947c6ae99SBarry Smith       ierr  = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
79047c6ae99SBarry Smith 
79147c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
79247c6ae99SBarry Smith       *iptr = (void*)ptr;
79347c6ae99SBarry Smith       break;}
79447c6ae99SBarry Smith     case 2: {
79547c6ae99SBarry Smith       void **ptr;
79647c6ae99SBarry Smith       itdof = xm*ym;
79747c6ae99SBarry Smith 
79847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
79947c6ae99SBarry Smith 
80047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
80147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
80247c6ae99SBarry Smith         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
80347c6ae99SBarry Smith       }
80447c6ae99SBarry Smith       *iptr = (void*)ptr;
80547c6ae99SBarry Smith       break;}
80647c6ae99SBarry Smith     case 3: {
80747c6ae99SBarry Smith       void ***ptr,**bptr;
80847c6ae99SBarry Smith       itdof = xm*ym*zm;
80947c6ae99SBarry Smith 
81047c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
81147c6ae99SBarry Smith 
81247c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
81347c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
81447c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
81547c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
81647c6ae99SBarry Smith       }
81747c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
81847c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
81947c6ae99SBarry Smith           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
82047c6ae99SBarry Smith         }
82147c6ae99SBarry Smith       }
82247c6ae99SBarry Smith 
82347c6ae99SBarry Smith       *iptr = (void*)ptr;
82447c6ae99SBarry Smith       break;}
82547c6ae99SBarry Smith     default:
82647c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
82747c6ae99SBarry Smith   }
82847c6ae99SBarry Smith 
82947c6ae99SBarry Smith   done:
83047c6ae99SBarry Smith   /* add arrays to the checked out list */
83147c6ae99SBarry Smith   if (ghosted) {
832aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
83347c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
83447c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
83547c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
83647c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
83747c6ae99SBarry Smith         break;
83847c6ae99SBarry Smith       }
83947c6ae99SBarry Smith     }
84047c6ae99SBarry Smith   } else {
841aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
84247c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
84347c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
84447c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
84547c6ae99SBarry Smith         dd->tdof            = itdof;
84647c6ae99SBarry Smith         break;
84747c6ae99SBarry Smith       }
84847c6ae99SBarry Smith     }
84947c6ae99SBarry Smith   }
850aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
85147c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
85247c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
85347c6ae99SBarry Smith   PetscFunctionReturn(0);
85447c6ae99SBarry Smith }
85547c6ae99SBarry Smith 
85647c6ae99SBarry Smith #undef __FUNCT__
857aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray4"
8587087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
85947c6ae99SBarry Smith {
86047c6ae99SBarry Smith   PetscErrorCode ierr;
86147c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
86247c6ae99SBarry Smith   char           *iarray_start;
86347c6ae99SBarry Smith   void           **iptr = (void**)vptr;
86447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
86547c6ae99SBarry Smith 
86647c6ae99SBarry Smith   PetscFunctionBegin;
86747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
86847c6ae99SBarry Smith   if (ghosted) {
869aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
87047c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
87147c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
87247c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
87347c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
87447c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
87547c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
87647c6ae99SBarry Smith 
87747c6ae99SBarry Smith         goto done;
87847c6ae99SBarry Smith       }
87947c6ae99SBarry Smith     }
88047c6ae99SBarry Smith     xs = dd->Xs;
88147c6ae99SBarry Smith     ys = dd->Ys;
88247c6ae99SBarry Smith     zs = dd->Zs;
88347c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
88447c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
88547c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
88647c6ae99SBarry Smith   } else {
887aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
88847c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
88947c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
89047c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
89147c6ae99SBarry Smith         itdof              = dd->tdof;
89247c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
89347c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
89447c6ae99SBarry Smith 
89547c6ae99SBarry Smith         goto done;
89647c6ae99SBarry Smith       }
89747c6ae99SBarry Smith     }
89847c6ae99SBarry Smith     xs = dd->xs;
89947c6ae99SBarry Smith     ys = dd->ys;
90047c6ae99SBarry Smith     zs = dd->zs;
90147c6ae99SBarry Smith     xm = dd->xe-dd->xs;
90247c6ae99SBarry Smith     ym = dd->ye-dd->ys;
90347c6ae99SBarry Smith     zm = dd->ze-dd->zs;
90447c6ae99SBarry Smith   }
90547c6ae99SBarry Smith 
90647c6ae99SBarry Smith   switch (dd->dim) {
90747c6ae99SBarry Smith     case 2: {
90847c6ae99SBarry Smith       void **ptr;
90947c6ae99SBarry Smith       itdof = xm*ym;
91047c6ae99SBarry Smith 
91147c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
91247c6ae99SBarry Smith 
91347c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
91447c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
91547c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
91647c6ae99SBarry Smith       }
91747c6ae99SBarry Smith       *iptr = (void*)ptr;
91847c6ae99SBarry Smith       break;}
91947c6ae99SBarry Smith     default:
92047c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
92147c6ae99SBarry Smith   }
92247c6ae99SBarry Smith 
92347c6ae99SBarry Smith   done:
92447c6ae99SBarry Smith   /* add arrays to the checked out list */
92547c6ae99SBarry Smith   if (ghosted) {
926aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
92747c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
92847c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
92947c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
93047c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
93147c6ae99SBarry Smith         break;
93247c6ae99SBarry Smith       }
93347c6ae99SBarry Smith     }
93447c6ae99SBarry Smith   } else {
935aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
93647c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
93747c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
93847c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
93947c6ae99SBarry Smith         dd->tdof            = itdof;
94047c6ae99SBarry Smith         break;
94147c6ae99SBarry Smith       }
94247c6ae99SBarry Smith     }
94347c6ae99SBarry Smith   }
944aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
94547c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
94647c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
94747c6ae99SBarry Smith   PetscFunctionReturn(0);
94847c6ae99SBarry Smith }
94947c6ae99SBarry Smith 
95047c6ae99SBarry Smith #undef __FUNCT__
951aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9"
9527087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
95347c6ae99SBarry Smith {
95447c6ae99SBarry Smith   PetscErrorCode ierr;
95547c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
95647c6ae99SBarry Smith   char           *iarray_start;
95747c6ae99SBarry Smith   void           **iptr = (void**)vptr;
95847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
95947c6ae99SBarry Smith 
96047c6ae99SBarry Smith   PetscFunctionBegin;
96147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
96247c6ae99SBarry Smith   if (ghosted) {
963aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
96447c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
96547c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
96647c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
96747c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
96847c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
96947c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
97047c6ae99SBarry Smith 
97147c6ae99SBarry Smith         goto done;
97247c6ae99SBarry Smith       }
97347c6ae99SBarry Smith     }
97447c6ae99SBarry Smith     xs = dd->Xs;
97547c6ae99SBarry Smith     ys = dd->Ys;
97647c6ae99SBarry Smith     zs = dd->Zs;
97747c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
97847c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
97947c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
98047c6ae99SBarry Smith   } else {
981aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
98247c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
98347c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
98447c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
98547c6ae99SBarry Smith         itdof              = dd->tdof;
98647c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
98747c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
98847c6ae99SBarry Smith 
98947c6ae99SBarry Smith         goto done;
99047c6ae99SBarry Smith       }
99147c6ae99SBarry Smith     }
99247c6ae99SBarry Smith     xs = dd->xs;
99347c6ae99SBarry Smith     ys = dd->ys;
99447c6ae99SBarry Smith     zs = dd->zs;
99547c6ae99SBarry Smith     xm = dd->xe-dd->xs;
99647c6ae99SBarry Smith     ym = dd->ye-dd->ys;
99747c6ae99SBarry Smith     zm = dd->ze-dd->zs;
99847c6ae99SBarry Smith   }
99947c6ae99SBarry Smith 
100047c6ae99SBarry Smith   switch (dd->dim) {
100147c6ae99SBarry Smith     case 2: {
100247c6ae99SBarry Smith       void **ptr;
100347c6ae99SBarry Smith       itdof = xm*ym;
100447c6ae99SBarry Smith 
100547c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
100647c6ae99SBarry Smith 
100747c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
100847c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
100947c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
101047c6ae99SBarry Smith       }
101147c6ae99SBarry Smith       *iptr = (void*)ptr;
101247c6ae99SBarry Smith       break;}
101347c6ae99SBarry Smith     default:
101447c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
101547c6ae99SBarry Smith   }
101647c6ae99SBarry Smith 
101747c6ae99SBarry Smith   done:
101847c6ae99SBarry Smith   /* add arrays to the checked out list */
101947c6ae99SBarry Smith   if (ghosted) {
1020aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
102147c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
102247c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
102347c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
102447c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
102547c6ae99SBarry Smith         break;
102647c6ae99SBarry Smith       }
102747c6ae99SBarry Smith     }
102847c6ae99SBarry Smith   } else {
1029aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
103047c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
103147c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
103247c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
103347c6ae99SBarry Smith         dd->tdof            = itdof;
103447c6ae99SBarry Smith         break;
103547c6ae99SBarry Smith       }
103647c6ae99SBarry Smith     }
103747c6ae99SBarry Smith   }
1038aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
103947c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
104047c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
104147c6ae99SBarry Smith   PetscFunctionReturn(0);
104247c6ae99SBarry Smith }
104347c6ae99SBarry Smith 
104447c6ae99SBarry Smith #undef __FUNCT__
1045aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb"
104647c6ae99SBarry Smith /*@C
1047aa219208SBarry Smith      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
104847c6ae99SBarry Smith 
104947c6ae99SBarry Smith      Input Parameter:
105047c6ae99SBarry Smith +    da - information about my local patch
105147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
105247c6ae99SBarry Smith 
105347c6ae99SBarry Smith      Output Parameters:
105447c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
105547c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
105647c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
105747c6ae99SBarry Smith 
105847c6ae99SBarry Smith      Notes:
105947c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
106047c6ae99SBarry Smith      to zero them.
106147c6ae99SBarry Smith 
1062aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
106347c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
106447c6ae99SBarry Smith 
106547c6ae99SBarry Smith      Level: advanced
106647c6ae99SBarry Smith 
1067aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
106847c6ae99SBarry Smith 
106947c6ae99SBarry Smith @*/
10707087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
107147c6ae99SBarry Smith {
107247c6ae99SBarry Smith   PetscErrorCode ierr;
107347c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
107447c6ae99SBarry Smith   char           *iarray_start;
107547c6ae99SBarry Smith   void           **iptr = (void**)vptr;
107647c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
107747c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
107847c6ae99SBarry Smith 
107947c6ae99SBarry Smith   PetscFunctionBegin;
108047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
108147c6ae99SBarry Smith   if (ghosted) {
1082aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
108347c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
108447c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
108547c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
108647c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
108747c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
108847c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
108947c6ae99SBarry Smith 
109047c6ae99SBarry Smith         goto done;
109147c6ae99SBarry Smith       }
109247c6ae99SBarry Smith     }
109347c6ae99SBarry Smith     xs = dd->Xs;
109447c6ae99SBarry Smith     ys = dd->Ys;
109547c6ae99SBarry Smith     zs = dd->Zs;
109647c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
109747c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
109847c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
109947c6ae99SBarry Smith   } else {
1100aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
110147c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
110247c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
110347c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
110447c6ae99SBarry Smith         itdof              = dd->tdof;
110547c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
110647c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
110747c6ae99SBarry Smith 
110847c6ae99SBarry Smith         goto done;
110947c6ae99SBarry Smith       }
111047c6ae99SBarry Smith     }
111147c6ae99SBarry Smith     xs = dd->xs;
111247c6ae99SBarry Smith     ys = dd->ys;
111347c6ae99SBarry Smith     zs = dd->zs;
111447c6ae99SBarry Smith     xm = dd->xe-dd->xs;
111547c6ae99SBarry Smith     ym = dd->ye-dd->ys;
111647c6ae99SBarry Smith     zm = dd->ze-dd->zs;
111747c6ae99SBarry Smith   }
111847c6ae99SBarry Smith 
111947c6ae99SBarry Smith   switch (dd->dim) {
112047c6ae99SBarry Smith     case 1: {
112147c6ae99SBarry Smith       void *ptr;
112247c6ae99SBarry Smith       itdof = xm;
112347c6ae99SBarry Smith 
112447c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
112547c6ae99SBarry Smith 
112647c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
112747c6ae99SBarry Smith       *iptr = (void*)ptr;
112847c6ae99SBarry Smith       break;}
112947c6ae99SBarry Smith     case 2: {
113047c6ae99SBarry Smith       void **ptr;
113147c6ae99SBarry Smith       itdof = xm*ym;
113247c6ae99SBarry Smith 
113347c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
113447c6ae99SBarry Smith 
113547c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
113647c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
113747c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
113847c6ae99SBarry Smith       }
113947c6ae99SBarry Smith       *iptr = (void*)ptr;
114047c6ae99SBarry Smith       break;}
114147c6ae99SBarry Smith     case 3: {
114247c6ae99SBarry Smith       void ***ptr,**bptr;
114347c6ae99SBarry Smith       itdof = xm*ym*zm;
114447c6ae99SBarry Smith 
114547c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
114647c6ae99SBarry Smith 
114747c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
114847c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
114947c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
115047c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
115147c6ae99SBarry Smith       }
115247c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
115347c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
115447c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
115547c6ae99SBarry Smith         }
115647c6ae99SBarry Smith       }
115747c6ae99SBarry Smith 
115847c6ae99SBarry Smith       *iptr = (void*)ptr;
115947c6ae99SBarry Smith       break;}
116047c6ae99SBarry Smith     default:
116147c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
116247c6ae99SBarry Smith   }
116347c6ae99SBarry Smith 
116447c6ae99SBarry Smith   done:
116547c6ae99SBarry Smith   /* add arrays to the checked out list */
116647c6ae99SBarry Smith   if (ghosted) {
1167aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
116847c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
116947c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
117047c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
117147c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
117247c6ae99SBarry Smith         break;
117347c6ae99SBarry Smith       }
117447c6ae99SBarry Smith     }
117547c6ae99SBarry Smith   } else {
1176aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
117747c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
117847c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
117947c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
118047c6ae99SBarry Smith         dd->tdof            = itdof;
118147c6ae99SBarry Smith         break;
118247c6ae99SBarry Smith       }
118347c6ae99SBarry Smith     }
118447c6ae99SBarry Smith   }
1185aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
118647c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
118747c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
118847c6ae99SBarry Smith   PetscFunctionReturn(0);
118947c6ae99SBarry Smith }
119047c6ae99SBarry Smith 
119147c6ae99SBarry Smith #undef __FUNCT__
1192aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray"
119347c6ae99SBarry Smith /*@C
1194aa219208SBarry Smith      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
119547c6ae99SBarry Smith 
119647c6ae99SBarry Smith      Input Parameter:
119747c6ae99SBarry Smith +    da - information about my local patch
119847c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
119947c6ae99SBarry Smith 
120047c6ae99SBarry Smith      Output Parameters:
120147c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
120247c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
120347c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
120447c6ae99SBarry Smith 
120547c6ae99SBarry Smith      Level: advanced
120647c6ae99SBarry Smith 
1207aa219208SBarry Smith .seealso: DMDAGetAdicArray()
120847c6ae99SBarry Smith 
120947c6ae99SBarry Smith @*/
12107087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
121147c6ae99SBarry Smith {
121247c6ae99SBarry Smith   PetscInt  i;
121347c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
121447c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
121547c6ae99SBarry Smith 
121647c6ae99SBarry Smith   PetscFunctionBegin;
121747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
121847c6ae99SBarry Smith   if (ghosted) {
1219aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
122047c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
122147c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
122247c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
122347c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
122447c6ae99SBarry Smith         break;
122547c6ae99SBarry Smith       }
122647c6ae99SBarry Smith     }
122747c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1228aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
122947c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
123047c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
123147c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
123247c6ae99SBarry Smith         break;
123347c6ae99SBarry Smith       }
123447c6ae99SBarry Smith     }
123547c6ae99SBarry Smith   } else {
1236aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
123747c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
123847c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
123947c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
124047c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
124147c6ae99SBarry Smith         break;
124247c6ae99SBarry Smith       }
124347c6ae99SBarry Smith     }
124447c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1245aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
124647c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
124747c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
124847c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
124947c6ae99SBarry Smith         break;
125047c6ae99SBarry Smith       }
125147c6ae99SBarry Smith     }
125247c6ae99SBarry Smith   }
125347c6ae99SBarry Smith   PetscFunctionReturn(0);
125447c6ae99SBarry Smith }
125547c6ae99SBarry Smith 
125647c6ae99SBarry Smith #undef __FUNCT__
125747c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
12587087cfbeSBarry Smith PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
125947c6ae99SBarry Smith {
126047c6ae99SBarry Smith   PetscErrorCode ierr;
126147c6ae99SBarry Smith   PetscFunctionBegin;
1262aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
126347c6ae99SBarry Smith   PetscFunctionReturn(0);
126447c6ae99SBarry Smith }
126547c6ae99SBarry Smith 
126647c6ae99SBarry Smith #undef __FUNCT__
126747c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
12687087cfbeSBarry Smith PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
126947c6ae99SBarry Smith {
127047c6ae99SBarry Smith   PetscErrorCode ierr;
127147c6ae99SBarry Smith   PetscFunctionBegin;
1272aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
127347c6ae99SBarry Smith   PetscFunctionReturn(0);
127447c6ae99SBarry Smith }
127547c6ae99SBarry Smith 
1276