xref: /petsc/src/dm/impls/da/dalocal.c (revision fcfd50eb5fbe12291db06fc1b33ad004ead64926)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6c6db04a5SJed Brown #include <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;
27aa219208SBarry Smith   ierr = PetscObjectQuery((PetscObject)vec,"DMDA",(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 = VecSetType(*g,da->vectype);CHKERRQ(ierr);
6147c6ae99SBarry Smith   ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
62aa219208SBarry Smith   ierr = PetscObjectCompose((PetscObject)*g,"DMDA",(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 #undef __FUNCT__
7247c6ae99SBarry Smith #define __FUNCT__ "DMGetLocalVector"
7347c6ae99SBarry Smith /*@
7447c6ae99SBarry Smith    DMGetLocalVector - Gets a Seq PETSc vector that
7547c6ae99SBarry Smith    may be used with the DMXXX routines. This vector has spaces for the ghost values.
7647c6ae99SBarry Smith 
7747c6ae99SBarry Smith    Not Collective
7847c6ae99SBarry Smith 
7947c6ae99SBarry Smith    Input Parameter:
8047c6ae99SBarry Smith .  dm - the distributed array
8147c6ae99SBarry Smith 
8247c6ae99SBarry Smith    Output Parameter:
8347c6ae99SBarry Smith .  g - the local vector
8447c6ae99SBarry Smith 
8547c6ae99SBarry Smith    Level: beginner
8647c6ae99SBarry Smith 
8747c6ae99SBarry Smith    Note:
8847c6ae99SBarry Smith    The vector values are NOT initialized and may have garbage in them, so you may need
8947c6ae99SBarry Smith    to zero them.
9047c6ae99SBarry Smith 
9147c6ae99SBarry Smith    The output parameter, g, is a regular PETSc vector that should be returned with
9247c6ae99SBarry Smith    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
9347c6ae99SBarry Smith 
9447c6ae99SBarry Smith    VecStride*() operations can be useful when using DM with dof > 1
9547c6ae99SBarry Smith 
9647c6ae99SBarry Smith .keywords: distributed array, create, local, vector
9747c6ae99SBarry Smith 
9847c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
99aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
1009a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
10147c6ae99SBarry Smith           VecStrideMax(), VecStrideMin(), VecStrideNorm()
10247c6ae99SBarry Smith @*/
1037087cfbeSBarry Smith PetscErrorCode  DMGetLocalVector(DM dm,Vec* g)
10447c6ae99SBarry Smith {
10547c6ae99SBarry Smith   PetscErrorCode ierr,i;
10647c6ae99SBarry Smith 
10747c6ae99SBarry Smith   PetscFunctionBegin;
10847c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10947c6ae99SBarry Smith   PetscValidPointer(g,2);
11047c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
11147c6ae99SBarry Smith     if (dm->localin[i]) {
11247c6ae99SBarry Smith       *g             = dm->localin[i];
11347c6ae99SBarry Smith       dm->localin[i] = PETSC_NULL;
11447c6ae99SBarry Smith       goto alldone;
11547c6ae99SBarry Smith     }
11647c6ae99SBarry Smith   }
11747c6ae99SBarry Smith   ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr);
11847c6ae99SBarry Smith 
11947c6ae99SBarry Smith   alldone:
12047c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
12147c6ae99SBarry Smith     if (!dm->localout[i]) {
12247c6ae99SBarry Smith       dm->localout[i] = *g;
12347c6ae99SBarry Smith       break;
12447c6ae99SBarry Smith     }
12547c6ae99SBarry Smith   }
12647c6ae99SBarry Smith   PetscFunctionReturn(0);
12747c6ae99SBarry Smith }
12847c6ae99SBarry Smith 
12947c6ae99SBarry Smith #undef __FUNCT__
13047c6ae99SBarry Smith #define __FUNCT__ "DMRestoreLocalVector"
13147c6ae99SBarry Smith /*@
13247c6ae99SBarry Smith    DMRestoreLocalVector - Returns a Seq PETSc vector that
13347c6ae99SBarry Smith      obtained from DMGetLocalVector(). Do not use with vector obtained via
13447c6ae99SBarry Smith      DMCreateLocalVector().
13547c6ae99SBarry Smith 
13647c6ae99SBarry Smith    Not Collective
13747c6ae99SBarry Smith 
13847c6ae99SBarry Smith    Input Parameter:
13947c6ae99SBarry Smith +  dm - the distributed array
14047c6ae99SBarry Smith -  g - the local vector
14147c6ae99SBarry Smith 
14247c6ae99SBarry Smith    Level: beginner
14347c6ae99SBarry Smith 
14447c6ae99SBarry Smith .keywords: distributed array, create, local, vector
14547c6ae99SBarry Smith 
14647c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
147aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
1489a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
14947c6ae99SBarry Smith @*/
1507087cfbeSBarry Smith PetscErrorCode  DMRestoreLocalVector(DM dm,Vec* g)
15147c6ae99SBarry Smith {
15247c6ae99SBarry Smith   PetscErrorCode ierr;
15347c6ae99SBarry Smith   PetscInt       i,j;
15447c6ae99SBarry Smith 
15547c6ae99SBarry Smith   PetscFunctionBegin;
15647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15747c6ae99SBarry Smith   PetscValidPointer(g,2);
15847c6ae99SBarry Smith   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
15947c6ae99SBarry Smith     if (*g == dm->localout[j]) {
16047c6ae99SBarry Smith       dm->localout[j] = PETSC_NULL;
16147c6ae99SBarry Smith       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
16247c6ae99SBarry Smith         if (!dm->localin[i]) {
16347c6ae99SBarry Smith           dm->localin[i] = *g;
16447c6ae99SBarry Smith           goto alldone;
16547c6ae99SBarry Smith         }
16647c6ae99SBarry Smith       }
16747c6ae99SBarry Smith     }
16847c6ae99SBarry Smith   }
169*fcfd50ebSBarry Smith   ierr = VecDestroy(g);CHKERRQ(ierr);
17047c6ae99SBarry Smith   alldone:
17147c6ae99SBarry Smith   PetscFunctionReturn(0);
17247c6ae99SBarry Smith }
17347c6ae99SBarry Smith 
17447c6ae99SBarry Smith #undef __FUNCT__
17547c6ae99SBarry Smith #define __FUNCT__ "DMGetGlobalVector"
17647c6ae99SBarry Smith /*@
17747c6ae99SBarry Smith    DMGetGlobalVector - Gets a MPI PETSc vector that
17847c6ae99SBarry Smith    may be used with the DMXXX routines.
17947c6ae99SBarry Smith 
18047c6ae99SBarry Smith    Collective on DM
18147c6ae99SBarry Smith 
18247c6ae99SBarry Smith    Input Parameter:
18347c6ae99SBarry Smith .  dm - the distributed array
18447c6ae99SBarry Smith 
18547c6ae99SBarry Smith    Output Parameter:
18647c6ae99SBarry Smith .  g - the global vector
18747c6ae99SBarry Smith 
18847c6ae99SBarry Smith    Level: beginner
18947c6ae99SBarry Smith 
19047c6ae99SBarry Smith    Note:
19147c6ae99SBarry Smith    The vector values are NOT initialized and may have garbage in them, so you may need
19247c6ae99SBarry Smith    to zero them.
19347c6ae99SBarry Smith 
19447c6ae99SBarry Smith    The output parameter, g, is a regular PETSc vector that should be returned with
19547c6ae99SBarry Smith    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
19647c6ae99SBarry Smith 
19747c6ae99SBarry Smith    VecStride*() operations can be useful when using DM with dof > 1
19847c6ae99SBarry Smith 
19947c6ae99SBarry Smith .keywords: distributed array, create, Global, vector
20047c6ae99SBarry Smith 
20147c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
202aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
2039a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
20447c6ae99SBarry Smith           VecStrideMax(), VecStrideMin(), VecStrideNorm()
20547c6ae99SBarry Smith 
20647c6ae99SBarry Smith @*/
2077087cfbeSBarry Smith PetscErrorCode  DMGetGlobalVector(DM dm,Vec* g)
20847c6ae99SBarry Smith {
20947c6ae99SBarry Smith   PetscErrorCode ierr;
21047c6ae99SBarry Smith   PetscInt       i;
21147c6ae99SBarry Smith 
21247c6ae99SBarry Smith   PetscFunctionBegin;
21347c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21447c6ae99SBarry Smith   PetscValidPointer(g,2);
21547c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
21647c6ae99SBarry Smith     if (dm->globalin[i]) {
21747c6ae99SBarry Smith       *g             = dm->globalin[i];
21847c6ae99SBarry Smith       dm->globalin[i] = PETSC_NULL;
21947c6ae99SBarry Smith       goto alldone;
22047c6ae99SBarry Smith     }
22147c6ae99SBarry Smith   }
22247c6ae99SBarry Smith   ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
22347c6ae99SBarry Smith 
22447c6ae99SBarry Smith   alldone:
22547c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
22647c6ae99SBarry Smith     if (!dm->globalout[i]) {
22747c6ae99SBarry Smith       dm->globalout[i] = *g;
22847c6ae99SBarry Smith       break;
22947c6ae99SBarry Smith     }
23047c6ae99SBarry Smith   }
23147c6ae99SBarry Smith   PetscFunctionReturn(0);
23247c6ae99SBarry Smith }
23347c6ae99SBarry Smith 
23447c6ae99SBarry Smith #undef __FUNCT__
23547c6ae99SBarry Smith #define __FUNCT__ "DMRestoreGlobalVector"
23647c6ae99SBarry Smith /*@
23747c6ae99SBarry Smith    DMRestoreGlobalVector - Returns a Seq PETSc vector that
23847c6ae99SBarry Smith      obtained from DMGetGlobalVector(). Do not use with vector obtained via
23947c6ae99SBarry Smith      DMCreateGlobalVector().
24047c6ae99SBarry Smith 
24147c6ae99SBarry Smith    Not Collective
24247c6ae99SBarry Smith 
24347c6ae99SBarry Smith    Input Parameter:
24447c6ae99SBarry Smith +  dm - the distributed array
24547c6ae99SBarry Smith -  g - the global vector
24647c6ae99SBarry Smith 
24747c6ae99SBarry Smith    Level: beginner
24847c6ae99SBarry Smith 
24947c6ae99SBarry Smith .keywords: distributed array, create, global, vector
25047c6ae99SBarry Smith 
25147c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
252aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
25347c6ae99SBarry Smith           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
25447c6ae99SBarry Smith @*/
2557087cfbeSBarry Smith PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec* g)
25647c6ae99SBarry Smith {
25747c6ae99SBarry Smith   PetscErrorCode ierr;
25847c6ae99SBarry Smith   PetscInt       i,j;
25947c6ae99SBarry Smith 
26047c6ae99SBarry Smith   PetscFunctionBegin;
26147c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
26247c6ae99SBarry Smith   PetscValidPointer(g,2);
26347c6ae99SBarry Smith   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
26447c6ae99SBarry Smith     if (*g == dm->globalout[j]) {
26547c6ae99SBarry Smith       dm->globalout[j] = PETSC_NULL;
26647c6ae99SBarry Smith       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
26747c6ae99SBarry Smith         if (!dm->globalin[i]) {
26847c6ae99SBarry Smith           dm->globalin[i] = *g;
26947c6ae99SBarry Smith           goto alldone;
27047c6ae99SBarry Smith         }
27147c6ae99SBarry Smith       }
27247c6ae99SBarry Smith     }
27347c6ae99SBarry Smith   }
274*fcfd50ebSBarry Smith   ierr = VecDestroy(g);CHKERRQ(ierr);
27547c6ae99SBarry Smith   alldone:
27647c6ae99SBarry Smith   PetscFunctionReturn(0);
27747c6ae99SBarry Smith }
27847c6ae99SBarry Smith 
27947c6ae99SBarry Smith /* ------------------------------------------------------------------- */
28047c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
28147c6ae99SBarry Smith 
28247c6ae99SBarry Smith EXTERN_C_BEGIN
283c6db04a5SJed Brown #include <adic/ad_utils.h>
28447c6ae99SBarry Smith EXTERN_C_END
28547c6ae99SBarry Smith 
28647c6ae99SBarry Smith #undef __FUNCT__
287aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicArray"
28847c6ae99SBarry Smith /*@C
289aa219208SBarry Smith      DMDAGetAdicArray - Gets an array of derivative types for a DMDA
29047c6ae99SBarry Smith 
29147c6ae99SBarry Smith     Input Parameter:
29247c6ae99SBarry Smith +    da - information about my local patch
29347c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
29447c6ae99SBarry Smith 
29547c6ae99SBarry Smith     Output Parameters:
29647c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
29747c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
29847c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
29947c6ae99SBarry Smith 
30047c6ae99SBarry Smith      Notes:
30147c6ae99SBarry Smith        The vector values are NOT initialized and may have garbage in them, so you may need
30247c6ae99SBarry Smith        to zero them.
30347c6ae99SBarry Smith 
304aa219208SBarry Smith        Returns the same type of object as the DMDAVecGetArray() except its elements are
30547c6ae99SBarry Smith            derivative types instead of PetscScalars
30647c6ae99SBarry Smith 
30747c6ae99SBarry Smith      Level: advanced
30847c6ae99SBarry Smith 
309aa219208SBarry Smith .seealso: DMDARestoreAdicArray()
31047c6ae99SBarry Smith 
31147c6ae99SBarry Smith @*/
3127087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
31347c6ae99SBarry Smith {
31447c6ae99SBarry Smith   PetscErrorCode ierr;
31547c6ae99SBarry Smith   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
31647c6ae99SBarry Smith   char           *iarray_start;
31747c6ae99SBarry Smith   void           **iptr = (void**)vptr;
31847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith   PetscFunctionBegin;
32147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
32247c6ae99SBarry Smith   if (ghosted) {
323aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
32447c6ae99SBarry Smith       if (dd->adarrayghostedin[i]) {
32547c6ae99SBarry Smith         *iptr                   = dd->adarrayghostedin[i];
32647c6ae99SBarry Smith         iarray_start            = (char*)dd->adstartghostedin[i];
32747c6ae99SBarry Smith         itdof                   = dd->ghostedtdof;
32847c6ae99SBarry Smith         dd->adarrayghostedin[i] = PETSC_NULL;
32947c6ae99SBarry Smith         dd->adstartghostedin[i] = PETSC_NULL;
33047c6ae99SBarry Smith 
33147c6ae99SBarry Smith         goto done;
33247c6ae99SBarry Smith       }
33347c6ae99SBarry Smith     }
33447c6ae99SBarry Smith     xs = dd->Xs;
33547c6ae99SBarry Smith     ys = dd->Ys;
33647c6ae99SBarry Smith     zs = dd->Zs;
33747c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
33847c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
33947c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
34047c6ae99SBarry Smith   } else {
341aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
34247c6ae99SBarry Smith       if (dd->adarrayin[i]) {
34347c6ae99SBarry Smith         *iptr            = dd->adarrayin[i];
34447c6ae99SBarry Smith         iarray_start     = (char*)dd->adstartin[i];
34547c6ae99SBarry Smith         itdof            = dd->tdof;
34647c6ae99SBarry Smith         dd->adarrayin[i] = PETSC_NULL;
34747c6ae99SBarry Smith         dd->adstartin[i] = PETSC_NULL;
34847c6ae99SBarry Smith 
34947c6ae99SBarry Smith         goto done;
35047c6ae99SBarry Smith       }
35147c6ae99SBarry Smith     }
35247c6ae99SBarry Smith     xs = dd->xs;
35347c6ae99SBarry Smith     ys = dd->ys;
35447c6ae99SBarry Smith     zs = dd->zs;
35547c6ae99SBarry Smith     xm = dd->xe-dd->xs;
35647c6ae99SBarry Smith     ym = dd->ye-dd->ys;
35747c6ae99SBarry Smith     zm = dd->ze-dd->zs;
35847c6ae99SBarry Smith   }
35947c6ae99SBarry Smith   deriv_type_size = PetscADGetDerivTypeSize();
36047c6ae99SBarry Smith 
36147c6ae99SBarry Smith   switch (dd->dim) {
36247c6ae99SBarry Smith     case 1: {
36347c6ae99SBarry Smith       void *ptr;
36447c6ae99SBarry Smith       itdof = xm;
36547c6ae99SBarry Smith 
36647c6ae99SBarry Smith       ierr  = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
36747c6ae99SBarry Smith 
36847c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*deriv_type_size);
36947c6ae99SBarry Smith       *iptr = (void*)ptr;
37047c6ae99SBarry Smith       break;}
37147c6ae99SBarry Smith     case 2: {
37247c6ae99SBarry Smith       void **ptr;
37347c6ae99SBarry Smith       itdof = xm*ym;
37447c6ae99SBarry Smith 
37547c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr);
37647c6ae99SBarry Smith 
37747c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
37847c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
37947c6ae99SBarry Smith         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
38047c6ae99SBarry Smith       }
38147c6ae99SBarry Smith       *iptr = (void*)ptr;
38247c6ae99SBarry Smith       break;}
38347c6ae99SBarry Smith     case 3: {
38447c6ae99SBarry Smith       void ***ptr,**bptr;
38547c6ae99SBarry Smith       itdof = xm*ym*zm;
38647c6ae99SBarry Smith 
38747c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
38847c6ae99SBarry Smith 
38947c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
39047c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
39147c6ae99SBarry Smith 
39247c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
39347c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
39447c6ae99SBarry Smith       }
39547c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
39647c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
39747c6ae99SBarry Smith           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
39847c6ae99SBarry Smith         }
39947c6ae99SBarry Smith       }
40047c6ae99SBarry Smith 
40147c6ae99SBarry Smith       *iptr = (void*)ptr;
40247c6ae99SBarry Smith       break;}
40347c6ae99SBarry Smith     default:
40447c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
40547c6ae99SBarry Smith   }
40647c6ae99SBarry Smith 
40747c6ae99SBarry Smith   done:
40847c6ae99SBarry Smith   /* add arrays to the checked out list */
40947c6ae99SBarry Smith   if (ghosted) {
410aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
41147c6ae99SBarry Smith       if (!dd->adarrayghostedout[i]) {
41247c6ae99SBarry Smith         dd->adarrayghostedout[i] = *iptr ;
41347c6ae99SBarry Smith         dd->adstartghostedout[i] = iarray_start;
41447c6ae99SBarry Smith         dd->ghostedtdof          = itdof;
41547c6ae99SBarry Smith         break;
41647c6ae99SBarry Smith       }
41747c6ae99SBarry Smith     }
41847c6ae99SBarry Smith   } else {
419aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
42047c6ae99SBarry Smith       if (!dd->adarrayout[i]) {
42147c6ae99SBarry Smith         dd->adarrayout[i] = *iptr ;
42247c6ae99SBarry Smith         dd->adstartout[i] = iarray_start;
42347c6ae99SBarry Smith         dd->tdof          = itdof;
42447c6ae99SBarry Smith         break;
42547c6ae99SBarry Smith       }
42647c6ae99SBarry Smith     }
42747c6ae99SBarry Smith   }
428aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
42947c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
43047c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
43147c6ae99SBarry Smith   PetscFunctionReturn(0);
43247c6ae99SBarry Smith }
43347c6ae99SBarry Smith 
43447c6ae99SBarry Smith #undef __FUNCT__
435aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicArray"
43647c6ae99SBarry Smith /*@C
437aa219208SBarry Smith      DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
43847c6ae99SBarry Smith 
43947c6ae99SBarry Smith     Input Parameter:
44047c6ae99SBarry Smith +    da - information about my local patch
44147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
44247c6ae99SBarry Smith 
44347c6ae99SBarry Smith     Output Parameters:
44447c6ae99SBarry Smith +    ptr - array data structured to be passed to ad_FormFunctionLocal()
44547c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
44647c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
44747c6ae99SBarry Smith 
44847c6ae99SBarry Smith      Level: advanced
44947c6ae99SBarry Smith 
450aa219208SBarry Smith .seealso: DMDAGetAdicArray()
45147c6ae99SBarry Smith 
45247c6ae99SBarry Smith @*/
4537087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
45447c6ae99SBarry Smith {
45547c6ae99SBarry Smith   PetscInt  i;
45647c6ae99SBarry Smith   void      **iptr = (void**)ptr,iarray_start = 0;
45747c6ae99SBarry Smith 
45847c6ae99SBarry Smith   PetscFunctionBegin;
45947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
46047c6ae99SBarry Smith   if (ghosted) {
461aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
46247c6ae99SBarry Smith       if (dd->adarrayghostedout[i] == *iptr) {
46347c6ae99SBarry Smith         iarray_start             = dd->adstartghostedout[i];
46447c6ae99SBarry Smith         dd->adarrayghostedout[i] = PETSC_NULL;
46547c6ae99SBarry Smith         dd->adstartghostedout[i] = PETSC_NULL;
46647c6ae99SBarry Smith         break;
46747c6ae99SBarry Smith       }
46847c6ae99SBarry Smith     }
46947c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
470aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
47147c6ae99SBarry Smith       if (!dd->adarrayghostedin[i]){
47247c6ae99SBarry Smith         dd->adarrayghostedin[i] = *iptr;
47347c6ae99SBarry Smith         dd->adstartghostedin[i] = iarray_start;
47447c6ae99SBarry Smith         break;
47547c6ae99SBarry Smith       }
47647c6ae99SBarry Smith     }
47747c6ae99SBarry Smith   } else {
478aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
47947c6ae99SBarry Smith       if (dd->adarrayout[i] == *iptr) {
48047c6ae99SBarry Smith         iarray_start      = dd->adstartout[i];
48147c6ae99SBarry Smith         dd->adarrayout[i] = PETSC_NULL;
48247c6ae99SBarry Smith         dd->adstartout[i] = PETSC_NULL;
48347c6ae99SBarry Smith         break;
48447c6ae99SBarry Smith       }
48547c6ae99SBarry Smith     }
48647c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
487aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
48847c6ae99SBarry Smith       if (!dd->adarrayin[i]){
48947c6ae99SBarry Smith         dd->adarrayin[i]   = *iptr;
49047c6ae99SBarry Smith         dd->adstartin[i]   = iarray_start;
49147c6ae99SBarry Smith         break;
49247c6ae99SBarry Smith       }
49347c6ae99SBarry Smith     }
49447c6ae99SBarry Smith   }
49547c6ae99SBarry Smith   PetscFunctionReturn(0);
49647c6ae99SBarry Smith }
49747c6ae99SBarry Smith 
49847c6ae99SBarry Smith #undef __FUNCT__
49947c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray"
5007087cfbeSBarry Smith PetscErrorCode  ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
50147c6ae99SBarry Smith {
50247c6ae99SBarry Smith   PetscErrorCode ierr;
50347c6ae99SBarry Smith   PetscFunctionBegin;
504aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
50547c6ae99SBarry Smith   PetscFunctionReturn(0);
50647c6ae99SBarry Smith }
50747c6ae99SBarry Smith 
50847c6ae99SBarry Smith #undef __FUNCT__
50947c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray"
5107087cfbeSBarry Smith PetscErrorCode  ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
51147c6ae99SBarry Smith {
51247c6ae99SBarry Smith   PetscErrorCode ierr;
51347c6ae99SBarry Smith   PetscFunctionBegin;
514aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
51547c6ae99SBarry Smith   PetscFunctionReturn(0);
51647c6ae99SBarry Smith }
51747c6ae99SBarry Smith 
51847c6ae99SBarry Smith #endif
51947c6ae99SBarry Smith 
52047c6ae99SBarry Smith #undef __FUNCT__
521aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
52247c6ae99SBarry Smith /*@C
523aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
52447c6ae99SBarry Smith 
52547c6ae99SBarry Smith     Input Parameter:
52647c6ae99SBarry Smith +    da - information about my local patch
52747c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
52847c6ae99SBarry Smith 
52947c6ae99SBarry Smith     Output Parameters:
53047c6ae99SBarry Smith .    vptr - array data structured
53147c6ae99SBarry Smith 
53247c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
53347c6ae99SBarry Smith            to zero them.
53447c6ae99SBarry Smith 
53547c6ae99SBarry Smith   Level: advanced
53647c6ae99SBarry Smith 
537aa219208SBarry Smith .seealso: DMDARestoreArray(), DMDAGetAdicArray()
53847c6ae99SBarry Smith 
53947c6ae99SBarry Smith @*/
5407087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool  ghosted,void *vptr)
54147c6ae99SBarry Smith {
54247c6ae99SBarry Smith   PetscErrorCode ierr;
54347c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
54447c6ae99SBarry Smith   char           *iarray_start;
54547c6ae99SBarry Smith   void           **iptr = (void**)vptr;
54647c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
54747c6ae99SBarry Smith 
54847c6ae99SBarry Smith   PetscFunctionBegin;
54947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
55047c6ae99SBarry Smith   if (ghosted) {
551aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
55247c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
55347c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
55447c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
55547c6ae99SBarry Smith         dd->arrayghostedin[i] = PETSC_NULL;
55647c6ae99SBarry Smith         dd->startghostedin[i] = PETSC_NULL;
55747c6ae99SBarry Smith 
55847c6ae99SBarry Smith         goto done;
55947c6ae99SBarry Smith       }
56047c6ae99SBarry Smith     }
56147c6ae99SBarry Smith     xs = dd->Xs;
56247c6ae99SBarry Smith     ys = dd->Ys;
56347c6ae99SBarry Smith     zs = dd->Zs;
56447c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
56547c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
56647c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
56747c6ae99SBarry Smith   } else {
568aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
56947c6ae99SBarry Smith       if (dd->arrayin[i]) {
57047c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
57147c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
57247c6ae99SBarry Smith         dd->arrayin[i] = PETSC_NULL;
57347c6ae99SBarry Smith         dd->startin[i] = PETSC_NULL;
57447c6ae99SBarry Smith 
57547c6ae99SBarry Smith         goto done;
57647c6ae99SBarry Smith       }
57747c6ae99SBarry Smith     }
57847c6ae99SBarry Smith     xs = dd->xs;
57947c6ae99SBarry Smith     ys = dd->ys;
58047c6ae99SBarry Smith     zs = dd->zs;
58147c6ae99SBarry Smith     xm = dd->xe-dd->xs;
58247c6ae99SBarry Smith     ym = dd->ye-dd->ys;
58347c6ae99SBarry Smith     zm = dd->ze-dd->zs;
58447c6ae99SBarry Smith   }
58547c6ae99SBarry Smith 
58647c6ae99SBarry Smith   switch (dd->dim) {
58747c6ae99SBarry Smith     case 1: {
58847c6ae99SBarry Smith       void *ptr;
58947c6ae99SBarry Smith 
59047c6ae99SBarry Smith       ierr  = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
59147c6ae99SBarry Smith 
59247c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
59347c6ae99SBarry Smith       *iptr = (void*)ptr;
59447c6ae99SBarry Smith       break;}
59547c6ae99SBarry Smith     case 2: {
59647c6ae99SBarry Smith       void **ptr;
59747c6ae99SBarry Smith 
59847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
59947c6ae99SBarry Smith 
60047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
60147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
60247c6ae99SBarry Smith         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
60347c6ae99SBarry Smith       }
60447c6ae99SBarry Smith       *iptr = (void*)ptr;
60547c6ae99SBarry Smith       break;}
60647c6ae99SBarry Smith     case 3: {
60747c6ae99SBarry Smith       void ***ptr,**bptr;
60847c6ae99SBarry Smith 
60947c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
61047c6ae99SBarry Smith 
61147c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
61247c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
61347c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
61447c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
61547c6ae99SBarry Smith       }
61647c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
61747c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
61847c6ae99SBarry Smith           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
61947c6ae99SBarry Smith         }
62047c6ae99SBarry Smith       }
62147c6ae99SBarry Smith 
62247c6ae99SBarry Smith       *iptr = (void*)ptr;
62347c6ae99SBarry Smith       break;}
62447c6ae99SBarry Smith     default:
62547c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
62647c6ae99SBarry Smith   }
62747c6ae99SBarry Smith 
62847c6ae99SBarry Smith   done:
62947c6ae99SBarry Smith   /* add arrays to the checked out list */
63047c6ae99SBarry Smith   if (ghosted) {
631aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
63247c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
63347c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr ;
63447c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
63547c6ae99SBarry Smith         break;
63647c6ae99SBarry Smith       }
63747c6ae99SBarry Smith     }
63847c6ae99SBarry Smith   } else {
639aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
64047c6ae99SBarry Smith       if (!dd->arrayout[i]) {
64147c6ae99SBarry Smith         dd->arrayout[i] = *iptr ;
64247c6ae99SBarry Smith         dd->startout[i] = iarray_start;
64347c6ae99SBarry Smith         break;
64447c6ae99SBarry Smith       }
64547c6ae99SBarry Smith     }
64647c6ae99SBarry Smith   }
64747c6ae99SBarry Smith   PetscFunctionReturn(0);
64847c6ae99SBarry Smith }
64947c6ae99SBarry Smith 
65047c6ae99SBarry Smith #undef __FUNCT__
651aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
65247c6ae99SBarry Smith /*@C
653aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
65447c6ae99SBarry Smith 
65547c6ae99SBarry Smith     Input Parameter:
65647c6ae99SBarry Smith +    da - information about my local patch
65747c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
65847c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
65947c6ae99SBarry Smith 
66047c6ae99SBarry Smith      Level: advanced
66147c6ae99SBarry Smith 
662aa219208SBarry Smith .seealso: DMDAGetArray(), DMDAGetAdicArray()
66347c6ae99SBarry Smith 
66447c6ae99SBarry Smith @*/
6657087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool  ghosted,void *vptr)
66647c6ae99SBarry Smith {
66747c6ae99SBarry Smith   PetscInt  i;
66847c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
66947c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
67047c6ae99SBarry Smith 
67147c6ae99SBarry Smith   PetscFunctionBegin;
67247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
67347c6ae99SBarry Smith   if (ghosted) {
674aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
67547c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
67647c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
67747c6ae99SBarry Smith         dd->arrayghostedout[i] = PETSC_NULL;
67847c6ae99SBarry Smith         dd->startghostedout[i] = PETSC_NULL;
67947c6ae99SBarry Smith         break;
68047c6ae99SBarry Smith       }
68147c6ae99SBarry Smith     }
682aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
68347c6ae99SBarry Smith       if (!dd->arrayghostedin[i]){
68447c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
68547c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
68647c6ae99SBarry Smith         break;
68747c6ae99SBarry Smith       }
68847c6ae99SBarry Smith     }
68947c6ae99SBarry Smith   } else {
690aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
69147c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
69247c6ae99SBarry Smith         iarray_start    = dd->startout[i];
69347c6ae99SBarry Smith         dd->arrayout[i] = PETSC_NULL;
69447c6ae99SBarry Smith         dd->startout[i] = PETSC_NULL;
69547c6ae99SBarry Smith         break;
69647c6ae99SBarry Smith       }
69747c6ae99SBarry Smith     }
698aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
69947c6ae99SBarry Smith       if (!dd->arrayin[i]){
70047c6ae99SBarry Smith         dd->arrayin[i]  = *iptr;
70147c6ae99SBarry Smith         dd->startin[i]  = iarray_start;
70247c6ae99SBarry Smith         break;
70347c6ae99SBarry Smith       }
70447c6ae99SBarry Smith     }
70547c6ae99SBarry Smith   }
70647c6ae99SBarry Smith   PetscFunctionReturn(0);
70747c6ae99SBarry Smith }
70847c6ae99SBarry Smith 
70947c6ae99SBarry Smith #undef __FUNCT__
710aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray"
71147c6ae99SBarry Smith /*@C
712aa219208SBarry Smith      DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
71347c6ae99SBarry Smith 
71447c6ae99SBarry Smith      Input Parameter:
71547c6ae99SBarry Smith +    da - information about my local patch
71647c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
71747c6ae99SBarry Smith 
71847c6ae99SBarry Smith      Output Parameters:
71947c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
72047c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
72147c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
72247c6ae99SBarry Smith 
72347c6ae99SBarry Smith      Notes:
72447c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
72547c6ae99SBarry Smith      to zero them.
72647c6ae99SBarry Smith 
727aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
72847c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
72947c6ae99SBarry Smith 
73047c6ae99SBarry Smith      Level: advanced
73147c6ae99SBarry Smith 
732aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
73347c6ae99SBarry Smith 
73447c6ae99SBarry Smith @*/
7357087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
73647c6ae99SBarry Smith {
73747c6ae99SBarry Smith   PetscErrorCode ierr;
73847c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
73947c6ae99SBarry Smith   char           *iarray_start;
74047c6ae99SBarry Smith   void           **iptr = (void**)vptr;
74147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
74247c6ae99SBarry Smith 
74347c6ae99SBarry Smith   PetscFunctionBegin;
74447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
74547c6ae99SBarry Smith   if (ghosted) {
746aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
74747c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
74847c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
74947c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
75047c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
75147c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
75247c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
75347c6ae99SBarry Smith 
75447c6ae99SBarry Smith         goto done;
75547c6ae99SBarry Smith       }
75647c6ae99SBarry Smith     }
75747c6ae99SBarry Smith     xs = dd->Xs;
75847c6ae99SBarry Smith     ys = dd->Ys;
75947c6ae99SBarry Smith     zs = dd->Zs;
76047c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
76147c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
76247c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
76347c6ae99SBarry Smith   } else {
764aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
76547c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
76647c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
76747c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
76847c6ae99SBarry Smith         itdof              = dd->tdof;
76947c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
77047c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
77147c6ae99SBarry Smith 
77247c6ae99SBarry Smith         goto done;
77347c6ae99SBarry Smith       }
77447c6ae99SBarry Smith     }
77547c6ae99SBarry Smith     xs = dd->xs;
77647c6ae99SBarry Smith     ys = dd->ys;
77747c6ae99SBarry Smith     zs = dd->zs;
77847c6ae99SBarry Smith     xm = dd->xe-dd->xs;
77947c6ae99SBarry Smith     ym = dd->ye-dd->ys;
78047c6ae99SBarry Smith     zm = dd->ze-dd->zs;
78147c6ae99SBarry Smith   }
78247c6ae99SBarry Smith 
78347c6ae99SBarry Smith   switch (dd->dim) {
78447c6ae99SBarry Smith     case 1: {
78547c6ae99SBarry Smith       void *ptr;
78647c6ae99SBarry Smith       itdof = xm;
78747c6ae99SBarry Smith 
78847c6ae99SBarry Smith       ierr  = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
78947c6ae99SBarry Smith 
79047c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
79147c6ae99SBarry Smith       *iptr = (void*)ptr;
79247c6ae99SBarry Smith       break;}
79347c6ae99SBarry Smith     case 2: {
79447c6ae99SBarry Smith       void **ptr;
79547c6ae99SBarry Smith       itdof = xm*ym;
79647c6ae99SBarry Smith 
79747c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
79847c6ae99SBarry Smith 
79947c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
80047c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
80147c6ae99SBarry Smith         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
80247c6ae99SBarry Smith       }
80347c6ae99SBarry Smith       *iptr = (void*)ptr;
80447c6ae99SBarry Smith       break;}
80547c6ae99SBarry Smith     case 3: {
80647c6ae99SBarry Smith       void ***ptr,**bptr;
80747c6ae99SBarry Smith       itdof = xm*ym*zm;
80847c6ae99SBarry Smith 
80947c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
81047c6ae99SBarry Smith 
81147c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
81247c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
81347c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
81447c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
81547c6ae99SBarry Smith       }
81647c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
81747c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
81847c6ae99SBarry Smith           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
81947c6ae99SBarry Smith         }
82047c6ae99SBarry Smith       }
82147c6ae99SBarry Smith 
82247c6ae99SBarry Smith       *iptr = (void*)ptr;
82347c6ae99SBarry Smith       break;}
82447c6ae99SBarry Smith     default:
82547c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
82647c6ae99SBarry Smith   }
82747c6ae99SBarry Smith 
82847c6ae99SBarry Smith   done:
82947c6ae99SBarry Smith   /* add arrays to the checked out list */
83047c6ae99SBarry Smith   if (ghosted) {
831aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
83247c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
83347c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
83447c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
83547c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
83647c6ae99SBarry Smith         break;
83747c6ae99SBarry Smith       }
83847c6ae99SBarry Smith     }
83947c6ae99SBarry Smith   } else {
840aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
84147c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
84247c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
84347c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
84447c6ae99SBarry Smith         dd->tdof            = itdof;
84547c6ae99SBarry Smith         break;
84647c6ae99SBarry Smith       }
84747c6ae99SBarry Smith     }
84847c6ae99SBarry Smith   }
849aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
85047c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
85147c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
85247c6ae99SBarry Smith   PetscFunctionReturn(0);
85347c6ae99SBarry Smith }
85447c6ae99SBarry Smith 
85547c6ae99SBarry Smith #undef __FUNCT__
856aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray4"
8577087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
85847c6ae99SBarry Smith {
85947c6ae99SBarry Smith   PetscErrorCode ierr;
86047c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
86147c6ae99SBarry Smith   char           *iarray_start;
86247c6ae99SBarry Smith   void           **iptr = (void**)vptr;
86347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
86447c6ae99SBarry Smith 
86547c6ae99SBarry Smith   PetscFunctionBegin;
86647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
86747c6ae99SBarry Smith   if (ghosted) {
868aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
86947c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
87047c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
87147c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
87247c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
87347c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
87447c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
87547c6ae99SBarry Smith 
87647c6ae99SBarry Smith         goto done;
87747c6ae99SBarry Smith       }
87847c6ae99SBarry Smith     }
87947c6ae99SBarry Smith     xs = dd->Xs;
88047c6ae99SBarry Smith     ys = dd->Ys;
88147c6ae99SBarry Smith     zs = dd->Zs;
88247c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
88347c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
88447c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
88547c6ae99SBarry Smith   } else {
886aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
88747c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
88847c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
88947c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
89047c6ae99SBarry Smith         itdof              = dd->tdof;
89147c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
89247c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith         goto done;
89547c6ae99SBarry Smith       }
89647c6ae99SBarry Smith     }
89747c6ae99SBarry Smith     xs = dd->xs;
89847c6ae99SBarry Smith     ys = dd->ys;
89947c6ae99SBarry Smith     zs = dd->zs;
90047c6ae99SBarry Smith     xm = dd->xe-dd->xs;
90147c6ae99SBarry Smith     ym = dd->ye-dd->ys;
90247c6ae99SBarry Smith     zm = dd->ze-dd->zs;
90347c6ae99SBarry Smith   }
90447c6ae99SBarry Smith 
90547c6ae99SBarry Smith   switch (dd->dim) {
90647c6ae99SBarry Smith     case 2: {
90747c6ae99SBarry Smith       void **ptr;
90847c6ae99SBarry Smith       itdof = xm*ym;
90947c6ae99SBarry Smith 
91047c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
91147c6ae99SBarry Smith 
91247c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
91347c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
91447c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
91547c6ae99SBarry Smith       }
91647c6ae99SBarry Smith       *iptr = (void*)ptr;
91747c6ae99SBarry Smith       break;}
91847c6ae99SBarry Smith     default:
91947c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
92047c6ae99SBarry Smith   }
92147c6ae99SBarry Smith 
92247c6ae99SBarry Smith   done:
92347c6ae99SBarry Smith   /* add arrays to the checked out list */
92447c6ae99SBarry Smith   if (ghosted) {
925aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
92647c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
92747c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
92847c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
92947c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
93047c6ae99SBarry Smith         break;
93147c6ae99SBarry Smith       }
93247c6ae99SBarry Smith     }
93347c6ae99SBarry Smith   } else {
934aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
93547c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
93647c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
93747c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
93847c6ae99SBarry Smith         dd->tdof            = itdof;
93947c6ae99SBarry Smith         break;
94047c6ae99SBarry Smith       }
94147c6ae99SBarry Smith     }
94247c6ae99SBarry Smith   }
943aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
94447c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
94547c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
94647c6ae99SBarry Smith   PetscFunctionReturn(0);
94747c6ae99SBarry Smith }
94847c6ae99SBarry Smith 
94947c6ae99SBarry Smith #undef __FUNCT__
950aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9"
9517087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
95247c6ae99SBarry Smith {
95347c6ae99SBarry Smith   PetscErrorCode ierr;
95447c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
95547c6ae99SBarry Smith   char           *iarray_start;
95647c6ae99SBarry Smith   void           **iptr = (void**)vptr;
95747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
95847c6ae99SBarry Smith 
95947c6ae99SBarry Smith   PetscFunctionBegin;
96047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
96147c6ae99SBarry Smith   if (ghosted) {
962aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
96347c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
96447c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
96547c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
96647c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
96747c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
96847c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
96947c6ae99SBarry Smith 
97047c6ae99SBarry Smith         goto done;
97147c6ae99SBarry Smith       }
97247c6ae99SBarry Smith     }
97347c6ae99SBarry Smith     xs = dd->Xs;
97447c6ae99SBarry Smith     ys = dd->Ys;
97547c6ae99SBarry Smith     zs = dd->Zs;
97647c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
97747c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
97847c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
97947c6ae99SBarry Smith   } else {
980aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
98147c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
98247c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
98347c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
98447c6ae99SBarry Smith         itdof              = dd->tdof;
98547c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
98647c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
98747c6ae99SBarry Smith 
98847c6ae99SBarry Smith         goto done;
98947c6ae99SBarry Smith       }
99047c6ae99SBarry Smith     }
99147c6ae99SBarry Smith     xs = dd->xs;
99247c6ae99SBarry Smith     ys = dd->ys;
99347c6ae99SBarry Smith     zs = dd->zs;
99447c6ae99SBarry Smith     xm = dd->xe-dd->xs;
99547c6ae99SBarry Smith     ym = dd->ye-dd->ys;
99647c6ae99SBarry Smith     zm = dd->ze-dd->zs;
99747c6ae99SBarry Smith   }
99847c6ae99SBarry Smith 
99947c6ae99SBarry Smith   switch (dd->dim) {
100047c6ae99SBarry Smith     case 2: {
100147c6ae99SBarry Smith       void **ptr;
100247c6ae99SBarry Smith       itdof = xm*ym;
100347c6ae99SBarry Smith 
100447c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
100547c6ae99SBarry Smith 
100647c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
100747c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
100847c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
100947c6ae99SBarry Smith       }
101047c6ae99SBarry Smith       *iptr = (void*)ptr;
101147c6ae99SBarry Smith       break;}
101247c6ae99SBarry Smith     default:
101347c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
101447c6ae99SBarry Smith   }
101547c6ae99SBarry Smith 
101647c6ae99SBarry Smith   done:
101747c6ae99SBarry Smith   /* add arrays to the checked out list */
101847c6ae99SBarry Smith   if (ghosted) {
1019aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
102047c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
102147c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
102247c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
102347c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
102447c6ae99SBarry Smith         break;
102547c6ae99SBarry Smith       }
102647c6ae99SBarry Smith     }
102747c6ae99SBarry Smith   } else {
1028aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
102947c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
103047c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
103147c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
103247c6ae99SBarry Smith         dd->tdof            = itdof;
103347c6ae99SBarry Smith         break;
103447c6ae99SBarry Smith       }
103547c6ae99SBarry Smith     }
103647c6ae99SBarry Smith   }
1037aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
103847c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
103947c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
104047c6ae99SBarry Smith   PetscFunctionReturn(0);
104147c6ae99SBarry Smith }
104247c6ae99SBarry Smith 
104347c6ae99SBarry Smith #undef __FUNCT__
1044aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb"
104547c6ae99SBarry Smith /*@C
1046aa219208SBarry Smith      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
104747c6ae99SBarry Smith 
104847c6ae99SBarry Smith      Input Parameter:
104947c6ae99SBarry Smith +    da - information about my local patch
105047c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
105147c6ae99SBarry Smith 
105247c6ae99SBarry Smith      Output Parameters:
105347c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
105447c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
105547c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
105647c6ae99SBarry Smith 
105747c6ae99SBarry Smith      Notes:
105847c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
105947c6ae99SBarry Smith      to zero them.
106047c6ae99SBarry Smith 
1061aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
106247c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
106347c6ae99SBarry Smith 
106447c6ae99SBarry Smith      Level: advanced
106547c6ae99SBarry Smith 
1066aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
106747c6ae99SBarry Smith 
106847c6ae99SBarry Smith @*/
10697087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
107047c6ae99SBarry Smith {
107147c6ae99SBarry Smith   PetscErrorCode ierr;
107247c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
107347c6ae99SBarry Smith   char           *iarray_start;
107447c6ae99SBarry Smith   void           **iptr = (void**)vptr;
107547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
107647c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
107747c6ae99SBarry Smith 
107847c6ae99SBarry Smith   PetscFunctionBegin;
107947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
108047c6ae99SBarry Smith   if (ghosted) {
1081aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
108247c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
108347c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
108447c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
108547c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
108647c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
108747c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
108847c6ae99SBarry Smith 
108947c6ae99SBarry Smith         goto done;
109047c6ae99SBarry Smith       }
109147c6ae99SBarry Smith     }
109247c6ae99SBarry Smith     xs = dd->Xs;
109347c6ae99SBarry Smith     ys = dd->Ys;
109447c6ae99SBarry Smith     zs = dd->Zs;
109547c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
109647c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
109747c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
109847c6ae99SBarry Smith   } else {
1099aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
110047c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
110147c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
110247c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
110347c6ae99SBarry Smith         itdof              = dd->tdof;
110447c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
110547c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
110647c6ae99SBarry Smith 
110747c6ae99SBarry Smith         goto done;
110847c6ae99SBarry Smith       }
110947c6ae99SBarry Smith     }
111047c6ae99SBarry Smith     xs = dd->xs;
111147c6ae99SBarry Smith     ys = dd->ys;
111247c6ae99SBarry Smith     zs = dd->zs;
111347c6ae99SBarry Smith     xm = dd->xe-dd->xs;
111447c6ae99SBarry Smith     ym = dd->ye-dd->ys;
111547c6ae99SBarry Smith     zm = dd->ze-dd->zs;
111647c6ae99SBarry Smith   }
111747c6ae99SBarry Smith 
111847c6ae99SBarry Smith   switch (dd->dim) {
111947c6ae99SBarry Smith     case 1: {
112047c6ae99SBarry Smith       void *ptr;
112147c6ae99SBarry Smith       itdof = xm;
112247c6ae99SBarry Smith 
112347c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
112447c6ae99SBarry Smith 
112547c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
112647c6ae99SBarry Smith       *iptr = (void*)ptr;
112747c6ae99SBarry Smith       break;}
112847c6ae99SBarry Smith     case 2: {
112947c6ae99SBarry Smith       void **ptr;
113047c6ae99SBarry Smith       itdof = xm*ym;
113147c6ae99SBarry Smith 
113247c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
113347c6ae99SBarry Smith 
113447c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
113547c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
113647c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
113747c6ae99SBarry Smith       }
113847c6ae99SBarry Smith       *iptr = (void*)ptr;
113947c6ae99SBarry Smith       break;}
114047c6ae99SBarry Smith     case 3: {
114147c6ae99SBarry Smith       void ***ptr,**bptr;
114247c6ae99SBarry Smith       itdof = xm*ym*zm;
114347c6ae99SBarry Smith 
114447c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
114547c6ae99SBarry Smith 
114647c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
114747c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
114847c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
114947c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
115047c6ae99SBarry Smith       }
115147c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
115247c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
115347c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
115447c6ae99SBarry Smith         }
115547c6ae99SBarry Smith       }
115647c6ae99SBarry Smith 
115747c6ae99SBarry Smith       *iptr = (void*)ptr;
115847c6ae99SBarry Smith       break;}
115947c6ae99SBarry Smith     default:
116047c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
116147c6ae99SBarry Smith   }
116247c6ae99SBarry Smith 
116347c6ae99SBarry Smith   done:
116447c6ae99SBarry Smith   /* add arrays to the checked out list */
116547c6ae99SBarry Smith   if (ghosted) {
1166aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
116747c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
116847c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
116947c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
117047c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
117147c6ae99SBarry Smith         break;
117247c6ae99SBarry Smith       }
117347c6ae99SBarry Smith     }
117447c6ae99SBarry Smith   } else {
1175aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
117647c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
117747c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
117847c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
117947c6ae99SBarry Smith         dd->tdof            = itdof;
118047c6ae99SBarry Smith         break;
118147c6ae99SBarry Smith       }
118247c6ae99SBarry Smith     }
118347c6ae99SBarry Smith   }
1184aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
118547c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
118647c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
118747c6ae99SBarry Smith   PetscFunctionReturn(0);
118847c6ae99SBarry Smith }
118947c6ae99SBarry Smith 
119047c6ae99SBarry Smith #undef __FUNCT__
1191aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray"
119247c6ae99SBarry Smith /*@C
1193aa219208SBarry Smith      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
119447c6ae99SBarry Smith 
119547c6ae99SBarry Smith      Input Parameter:
119647c6ae99SBarry Smith +    da - information about my local patch
119747c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
119847c6ae99SBarry Smith 
119947c6ae99SBarry Smith      Output Parameters:
120047c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
120147c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
120247c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
120347c6ae99SBarry Smith 
120447c6ae99SBarry Smith      Level: advanced
120547c6ae99SBarry Smith 
1206aa219208SBarry Smith .seealso: DMDAGetAdicArray()
120747c6ae99SBarry Smith 
120847c6ae99SBarry Smith @*/
12097087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
121047c6ae99SBarry Smith {
121147c6ae99SBarry Smith   PetscInt  i;
121247c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
121347c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
121447c6ae99SBarry Smith 
121547c6ae99SBarry Smith   PetscFunctionBegin;
121647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
121747c6ae99SBarry Smith   if (ghosted) {
1218aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
121947c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
122047c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
122147c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
122247c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
122347c6ae99SBarry Smith         break;
122447c6ae99SBarry Smith       }
122547c6ae99SBarry Smith     }
122647c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1227aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
122847c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
122947c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
123047c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
123147c6ae99SBarry Smith         break;
123247c6ae99SBarry Smith       }
123347c6ae99SBarry Smith     }
123447c6ae99SBarry Smith   } else {
1235aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
123647c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
123747c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
123847c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
123947c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
124047c6ae99SBarry Smith         break;
124147c6ae99SBarry Smith       }
124247c6ae99SBarry Smith     }
124347c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1244aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
124547c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
124647c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
124747c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
124847c6ae99SBarry Smith         break;
124947c6ae99SBarry Smith       }
125047c6ae99SBarry Smith     }
125147c6ae99SBarry Smith   }
125247c6ae99SBarry Smith   PetscFunctionReturn(0);
125347c6ae99SBarry Smith }
125447c6ae99SBarry Smith 
125547c6ae99SBarry Smith #undef __FUNCT__
125647c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
12577087cfbeSBarry Smith PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
125847c6ae99SBarry Smith {
125947c6ae99SBarry Smith   PetscErrorCode ierr;
126047c6ae99SBarry Smith   PetscFunctionBegin;
1261aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
126247c6ae99SBarry Smith   PetscFunctionReturn(0);
126347c6ae99SBarry Smith }
126447c6ae99SBarry Smith 
126547c6ae99SBarry Smith #undef __FUNCT__
126647c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
12677087cfbeSBarry Smith PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
126847c6ae99SBarry Smith {
126947c6ae99SBarry Smith   PetscErrorCode ierr;
127047c6ae99SBarry Smith   PetscFunctionBegin;
1271aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
127247c6ae99SBarry Smith   PetscFunctionReturn(0);
127347c6ae99SBarry Smith }
127447c6ae99SBarry Smith 
1275