xref: /petsc/src/dm/impls/da/dalocal.c (revision 9a42bb27a39f0cdf3306a1e22d33cd9809484eaa)
147c6ae99SBarry Smith #define PETSCDM_DLL
247c6ae99SBarry Smith 
347c6ae99SBarry Smith /*
447c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
547c6ae99SBarry Smith */
647c6ae99SBarry Smith 
747c6ae99SBarry Smith #include "private/daimpl.h"    /*I   "petscda.h"   I*/
847c6ae99SBarry Smith 
947c6ae99SBarry Smith /*
1047c6ae99SBarry Smith    This allows the DA vectors to properly tell Matlab their dimensions
1147c6ae99SBarry Smith */
1247c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
1347c6ae99SBarry Smith #include "engine.h"   /* Matlab include file */
1447c6ae99SBarry Smith #include "mex.h"      /* Matlab include file */
1547c6ae99SBarry Smith EXTERN_C_BEGIN
1647c6ae99SBarry Smith #undef __FUNCT__
1747c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d"
1847c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT 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;
25*9a42bb27SBarry Smith   DM             da;
2647c6ae99SBarry Smith 
2747c6ae99SBarry Smith   PetscFunctionBegin;
2847c6ae99SBarry Smith   ierr = PetscObjectQuery((PetscObject)vec,"DA",(PetscObject*)&da);CHKERRQ(ierr);
2947c6ae99SBarry Smith   if (!da) SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DA");
3047c6ae99SBarry Smith   ierr = DAGetGhostCorners(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__
5047c6ae99SBarry Smith #define __FUNCT__ "DACreateLocalVector"
5147c6ae99SBarry Smith /*@
5247c6ae99SBarry Smith    DACreateLocalVector - Creates a Seq PETSc vector that
5347c6ae99SBarry Smith    may be used with the DAXXX routines.
5447c6ae99SBarry Smith 
5547c6ae99SBarry Smith    Not Collective
5647c6ae99SBarry Smith 
5747c6ae99SBarry Smith    Input Parameter:
5847c6ae99SBarry Smith .  da - the distributed array
5947c6ae99SBarry Smith 
6047c6ae99SBarry Smith    Output Parameter:
6147c6ae99SBarry Smith .  g - the local vector
6247c6ae99SBarry Smith 
6347c6ae99SBarry Smith    Level: beginner
6447c6ae99SBarry Smith 
6547c6ae99SBarry Smith    Note:
6647c6ae99SBarry Smith    The output parameter, g, is a regular PETSc vector that should be destroyed
6747c6ae99SBarry Smith    with a call to VecDestroy() when usage is finished.
6847c6ae99SBarry Smith 
6947c6ae99SBarry Smith .keywords: distributed array, create, local, vector
7047c6ae99SBarry Smith 
7147c6ae99SBarry Smith .seealso: DACreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
72*9a42bb27SBarry Smith           DACreate1d(), DACreate2d(), DACreate3d(), DMGlobalToLocalBegin(),
73*9a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMGetLocalVector(), DMRestoreLocalVector()
7447c6ae99SBarry Smith @*/
75*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DACreateLocalVector(DM da,Vec* g)
7647c6ae99SBarry Smith {
7747c6ae99SBarry Smith   PetscErrorCode ierr;
7847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
7947c6ae99SBarry Smith 
8047c6ae99SBarry Smith   PetscFunctionBegin;
8147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
8247c6ae99SBarry Smith   PetscValidPointer(g,2);
8347c6ae99SBarry Smith   ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr);
8447c6ae99SBarry Smith   ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
8547c6ae99SBarry Smith   ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
8647c6ae99SBarry Smith   ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
8747c6ae99SBarry Smith   ierr = PetscObjectCompose((PetscObject)*g,"DA",(PetscObject)da);CHKERRQ(ierr);
8847c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
8947c6ae99SBarry Smith   if (dd->w == 1  && dd->dim == 2) {
9047c6ae99SBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
9147c6ae99SBarry Smith   }
9247c6ae99SBarry Smith #endif
9347c6ae99SBarry Smith   PetscFunctionReturn(0);
9447c6ae99SBarry Smith }
9547c6ae99SBarry Smith 
9647c6ae99SBarry Smith #undef __FUNCT__
9747c6ae99SBarry Smith #define __FUNCT__ "DMGetLocalVector"
9847c6ae99SBarry Smith /*@
9947c6ae99SBarry Smith    DMGetLocalVector - Gets a Seq PETSc vector that
10047c6ae99SBarry Smith    may be used with the DMXXX routines. This vector has spaces for the ghost values.
10147c6ae99SBarry Smith 
10247c6ae99SBarry Smith    Not Collective
10347c6ae99SBarry Smith 
10447c6ae99SBarry Smith    Input Parameter:
10547c6ae99SBarry Smith .  dm - the distributed array
10647c6ae99SBarry Smith 
10747c6ae99SBarry Smith    Output Parameter:
10847c6ae99SBarry Smith .  g - the local vector
10947c6ae99SBarry Smith 
11047c6ae99SBarry Smith    Level: beginner
11147c6ae99SBarry Smith 
11247c6ae99SBarry Smith    Note:
11347c6ae99SBarry Smith    The vector values are NOT initialized and may have garbage in them, so you may need
11447c6ae99SBarry Smith    to zero them.
11547c6ae99SBarry Smith 
11647c6ae99SBarry Smith    The output parameter, g, is a regular PETSc vector that should be returned with
11747c6ae99SBarry Smith    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
11847c6ae99SBarry Smith 
11947c6ae99SBarry Smith    VecStride*() operations can be useful when using DM with dof > 1
12047c6ae99SBarry Smith 
12147c6ae99SBarry Smith .keywords: distributed array, create, local, vector
12247c6ae99SBarry Smith 
12347c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
12447c6ae99SBarry Smith           DACreate1d(), DACreate2d(), DACreate3d(), DMGlobalToLocalBegin(),
125*9a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
12647c6ae99SBarry Smith           VecStrideMax(), VecStrideMin(), VecStrideNorm()
12747c6ae99SBarry Smith @*/
12847c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMGetLocalVector(DM dm,Vec* g)
12947c6ae99SBarry Smith {
13047c6ae99SBarry Smith   PetscErrorCode ierr,i;
13147c6ae99SBarry Smith 
13247c6ae99SBarry Smith   PetscFunctionBegin;
13347c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13447c6ae99SBarry Smith   PetscValidPointer(g,2);
13547c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
13647c6ae99SBarry Smith     if (dm->localin[i]) {
13747c6ae99SBarry Smith       *g             = dm->localin[i];
13847c6ae99SBarry Smith       dm->localin[i] = PETSC_NULL;
13947c6ae99SBarry Smith       goto alldone;
14047c6ae99SBarry Smith     }
14147c6ae99SBarry Smith   }
14247c6ae99SBarry Smith   ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr);
14347c6ae99SBarry Smith 
14447c6ae99SBarry Smith   alldone:
14547c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
14647c6ae99SBarry Smith     if (!dm->localout[i]) {
14747c6ae99SBarry Smith       dm->localout[i] = *g;
14847c6ae99SBarry Smith       break;
14947c6ae99SBarry Smith     }
15047c6ae99SBarry Smith   }
15147c6ae99SBarry Smith   PetscFunctionReturn(0);
15247c6ae99SBarry Smith }
15347c6ae99SBarry Smith 
15447c6ae99SBarry Smith #undef __FUNCT__
15547c6ae99SBarry Smith #define __FUNCT__ "DMRestoreLocalVector"
15647c6ae99SBarry Smith /*@
15747c6ae99SBarry Smith    DMRestoreLocalVector - Returns a Seq PETSc vector that
15847c6ae99SBarry Smith      obtained from DMGetLocalVector(). Do not use with vector obtained via
15947c6ae99SBarry Smith      DMCreateLocalVector().
16047c6ae99SBarry Smith 
16147c6ae99SBarry Smith    Not Collective
16247c6ae99SBarry Smith 
16347c6ae99SBarry Smith    Input Parameter:
16447c6ae99SBarry Smith +  dm - the distributed array
16547c6ae99SBarry Smith -  g - the local vector
16647c6ae99SBarry Smith 
16747c6ae99SBarry Smith    Level: beginner
16847c6ae99SBarry Smith 
16947c6ae99SBarry Smith .keywords: distributed array, create, local, vector
17047c6ae99SBarry Smith 
17147c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
17247c6ae99SBarry Smith           DACreate1d(), DACreate2d(), DACreate3d(), DMGlobalToLocalBegin(),
173*9a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
17447c6ae99SBarry Smith @*/
17547c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMRestoreLocalVector(DM dm,Vec* g)
17647c6ae99SBarry Smith {
17747c6ae99SBarry Smith   PetscErrorCode ierr;
17847c6ae99SBarry Smith   PetscInt       i,j;
17947c6ae99SBarry Smith 
18047c6ae99SBarry Smith   PetscFunctionBegin;
18147c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18247c6ae99SBarry Smith   PetscValidPointer(g,2);
18347c6ae99SBarry Smith   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
18447c6ae99SBarry Smith     if (*g == dm->localout[j]) {
18547c6ae99SBarry Smith       dm->localout[j] = PETSC_NULL;
18647c6ae99SBarry Smith       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
18747c6ae99SBarry Smith         if (!dm->localin[i]) {
18847c6ae99SBarry Smith           dm->localin[i] = *g;
18947c6ae99SBarry Smith           goto alldone;
19047c6ae99SBarry Smith         }
19147c6ae99SBarry Smith       }
19247c6ae99SBarry Smith     }
19347c6ae99SBarry Smith   }
19447c6ae99SBarry Smith   ierr = VecDestroy(*g);CHKERRQ(ierr);
19547c6ae99SBarry Smith   alldone:
19647c6ae99SBarry Smith   PetscFunctionReturn(0);
19747c6ae99SBarry Smith }
19847c6ae99SBarry Smith 
19947c6ae99SBarry Smith #undef __FUNCT__
20047c6ae99SBarry Smith #define __FUNCT__ "DMGetGlobalVector"
20147c6ae99SBarry Smith /*@
20247c6ae99SBarry Smith    DMGetGlobalVector - Gets a MPI PETSc vector that
20347c6ae99SBarry Smith    may be used with the DMXXX routines.
20447c6ae99SBarry Smith 
20547c6ae99SBarry Smith    Collective on DM
20647c6ae99SBarry Smith 
20747c6ae99SBarry Smith    Input Parameter:
20847c6ae99SBarry Smith .  dm - the distributed array
20947c6ae99SBarry Smith 
21047c6ae99SBarry Smith    Output Parameter:
21147c6ae99SBarry Smith .  g - the global vector
21247c6ae99SBarry Smith 
21347c6ae99SBarry Smith    Level: beginner
21447c6ae99SBarry Smith 
21547c6ae99SBarry Smith    Note:
21647c6ae99SBarry Smith    The vector values are NOT initialized and may have garbage in them, so you may need
21747c6ae99SBarry Smith    to zero them.
21847c6ae99SBarry Smith 
21947c6ae99SBarry Smith    The output parameter, g, is a regular PETSc vector that should be returned with
22047c6ae99SBarry Smith    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
22147c6ae99SBarry Smith 
22247c6ae99SBarry Smith    VecStride*() operations can be useful when using DM with dof > 1
22347c6ae99SBarry Smith 
22447c6ae99SBarry Smith .keywords: distributed array, create, Global, vector
22547c6ae99SBarry Smith 
22647c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
22747c6ae99SBarry Smith           DACreate1d(), DACreate2d(), DACreate3d(), DMGlobalToLocalBegin(),
228*9a42bb27SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
22947c6ae99SBarry Smith           VecStrideMax(), VecStrideMin(), VecStrideNorm()
23047c6ae99SBarry Smith 
23147c6ae99SBarry Smith @*/
23247c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMGetGlobalVector(DM dm,Vec* g)
23347c6ae99SBarry Smith {
23447c6ae99SBarry Smith   PetscErrorCode ierr;
23547c6ae99SBarry Smith   PetscInt       i;
23647c6ae99SBarry Smith 
23747c6ae99SBarry Smith   PetscFunctionBegin;
23847c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
23947c6ae99SBarry Smith   PetscValidPointer(g,2);
24047c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
24147c6ae99SBarry Smith     if (dm->globalin[i]) {
24247c6ae99SBarry Smith       *g             = dm->globalin[i];
24347c6ae99SBarry Smith       dm->globalin[i] = PETSC_NULL;
24447c6ae99SBarry Smith       goto alldone;
24547c6ae99SBarry Smith     }
24647c6ae99SBarry Smith   }
24747c6ae99SBarry Smith   ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
24847c6ae99SBarry Smith 
24947c6ae99SBarry Smith   alldone:
25047c6ae99SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
25147c6ae99SBarry Smith     if (!dm->globalout[i]) {
25247c6ae99SBarry Smith       dm->globalout[i] = *g;
25347c6ae99SBarry Smith       break;
25447c6ae99SBarry Smith     }
25547c6ae99SBarry Smith   }
25647c6ae99SBarry Smith   PetscFunctionReturn(0);
25747c6ae99SBarry Smith }
25847c6ae99SBarry Smith 
25947c6ae99SBarry Smith #undef __FUNCT__
26047c6ae99SBarry Smith #define __FUNCT__ "DMRestoreGlobalVector"
26147c6ae99SBarry Smith /*@
26247c6ae99SBarry Smith    DMRestoreGlobalVector - Returns a Seq PETSc vector that
26347c6ae99SBarry Smith      obtained from DMGetGlobalVector(). Do not use with vector obtained via
26447c6ae99SBarry Smith      DMCreateGlobalVector().
26547c6ae99SBarry Smith 
26647c6ae99SBarry Smith    Not Collective
26747c6ae99SBarry Smith 
26847c6ae99SBarry Smith    Input Parameter:
26947c6ae99SBarry Smith +  dm - the distributed array
27047c6ae99SBarry Smith -  g - the global vector
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith    Level: beginner
27347c6ae99SBarry Smith 
27447c6ae99SBarry Smith .keywords: distributed array, create, global, vector
27547c6ae99SBarry Smith 
27647c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
27747c6ae99SBarry Smith           DACreate1d(), DACreate2d(), DACreate3d(), DMGlobalToGlobalBegin(),
27847c6ae99SBarry Smith           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
27947c6ae99SBarry Smith @*/
28047c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMRestoreGlobalVector(DM dm,Vec* g)
28147c6ae99SBarry Smith {
28247c6ae99SBarry Smith   PetscErrorCode ierr;
28347c6ae99SBarry Smith   PetscInt       i,j;
28447c6ae99SBarry Smith 
28547c6ae99SBarry Smith   PetscFunctionBegin;
28647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
28747c6ae99SBarry Smith   PetscValidPointer(g,2);
28847c6ae99SBarry Smith   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
28947c6ae99SBarry Smith     if (*g == dm->globalout[j]) {
29047c6ae99SBarry Smith       dm->globalout[j] = PETSC_NULL;
29147c6ae99SBarry Smith       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
29247c6ae99SBarry Smith         if (!dm->globalin[i]) {
29347c6ae99SBarry Smith           dm->globalin[i] = *g;
29447c6ae99SBarry Smith           goto alldone;
29547c6ae99SBarry Smith         }
29647c6ae99SBarry Smith       }
29747c6ae99SBarry Smith     }
29847c6ae99SBarry Smith   }
29947c6ae99SBarry Smith   ierr = VecDestroy(*g);CHKERRQ(ierr);
30047c6ae99SBarry Smith   alldone:
30147c6ae99SBarry Smith   PetscFunctionReturn(0);
30247c6ae99SBarry Smith }
30347c6ae99SBarry Smith 
30447c6ae99SBarry Smith /* ------------------------------------------------------------------- */
30547c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
30647c6ae99SBarry Smith 
30747c6ae99SBarry Smith EXTERN_C_BEGIN
30847c6ae99SBarry Smith #include "adic/ad_utils.h"
30947c6ae99SBarry Smith EXTERN_C_END
31047c6ae99SBarry Smith 
31147c6ae99SBarry Smith #undef __FUNCT__
31247c6ae99SBarry Smith #define __FUNCT__ "DAGetAdicArray"
31347c6ae99SBarry Smith /*@C
31447c6ae99SBarry Smith      DAGetAdicArray - Gets an array of derivative types for a DA
31547c6ae99SBarry Smith 
31647c6ae99SBarry Smith     Input Parameter:
31747c6ae99SBarry Smith +    da - information about my local patch
31847c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith     Output Parameters:
32147c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
32247c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
32347c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
32447c6ae99SBarry Smith 
32547c6ae99SBarry Smith      Notes:
32647c6ae99SBarry Smith        The vector values are NOT initialized and may have garbage in them, so you may need
32747c6ae99SBarry Smith        to zero them.
32847c6ae99SBarry Smith 
32947c6ae99SBarry Smith        Returns the same type of object as the DAVecGetArray() except its elements are
33047c6ae99SBarry Smith            derivative types instead of PetscScalars
33147c6ae99SBarry Smith 
33247c6ae99SBarry Smith      Level: advanced
33347c6ae99SBarry Smith 
33447c6ae99SBarry Smith .seealso: DARestoreAdicArray()
33547c6ae99SBarry Smith 
33647c6ae99SBarry Smith @*/
337*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
33847c6ae99SBarry Smith {
33947c6ae99SBarry Smith   PetscErrorCode ierr;
34047c6ae99SBarry Smith   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
34147c6ae99SBarry Smith   char           *iarray_start;
34247c6ae99SBarry Smith   void           **iptr = (void**)vptr;
34347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
34447c6ae99SBarry Smith 
34547c6ae99SBarry Smith   PetscFunctionBegin;
34647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
34747c6ae99SBarry Smith   if (ghosted) {
34847c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
34947c6ae99SBarry Smith       if (dd->adarrayghostedin[i]) {
35047c6ae99SBarry Smith         *iptr                   = dd->adarrayghostedin[i];
35147c6ae99SBarry Smith         iarray_start            = (char*)dd->adstartghostedin[i];
35247c6ae99SBarry Smith         itdof                   = dd->ghostedtdof;
35347c6ae99SBarry Smith         dd->adarrayghostedin[i] = PETSC_NULL;
35447c6ae99SBarry Smith         dd->adstartghostedin[i] = PETSC_NULL;
35547c6ae99SBarry Smith 
35647c6ae99SBarry Smith         goto done;
35747c6ae99SBarry Smith       }
35847c6ae99SBarry Smith     }
35947c6ae99SBarry Smith     xs = dd->Xs;
36047c6ae99SBarry Smith     ys = dd->Ys;
36147c6ae99SBarry Smith     zs = dd->Zs;
36247c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
36347c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
36447c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
36547c6ae99SBarry Smith   } else {
36647c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
36747c6ae99SBarry Smith       if (dd->adarrayin[i]) {
36847c6ae99SBarry Smith         *iptr            = dd->adarrayin[i];
36947c6ae99SBarry Smith         iarray_start     = (char*)dd->adstartin[i];
37047c6ae99SBarry Smith         itdof            = dd->tdof;
37147c6ae99SBarry Smith         dd->adarrayin[i] = PETSC_NULL;
37247c6ae99SBarry Smith         dd->adstartin[i] = PETSC_NULL;
37347c6ae99SBarry Smith 
37447c6ae99SBarry Smith         goto done;
37547c6ae99SBarry Smith       }
37647c6ae99SBarry Smith     }
37747c6ae99SBarry Smith     xs = dd->xs;
37847c6ae99SBarry Smith     ys = dd->ys;
37947c6ae99SBarry Smith     zs = dd->zs;
38047c6ae99SBarry Smith     xm = dd->xe-dd->xs;
38147c6ae99SBarry Smith     ym = dd->ye-dd->ys;
38247c6ae99SBarry Smith     zm = dd->ze-dd->zs;
38347c6ae99SBarry Smith   }
38447c6ae99SBarry Smith   deriv_type_size = PetscADGetDerivTypeSize();
38547c6ae99SBarry Smith 
38647c6ae99SBarry Smith   switch (dd->dim) {
38747c6ae99SBarry Smith     case 1: {
38847c6ae99SBarry Smith       void *ptr;
38947c6ae99SBarry Smith       itdof = xm;
39047c6ae99SBarry Smith 
39147c6ae99SBarry Smith       ierr  = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
39247c6ae99SBarry Smith 
39347c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*deriv_type_size);
39447c6ae99SBarry Smith       *iptr = (void*)ptr;
39547c6ae99SBarry Smith       break;}
39647c6ae99SBarry Smith     case 2: {
39747c6ae99SBarry Smith       void **ptr;
39847c6ae99SBarry Smith       itdof = xm*ym;
39947c6ae99SBarry Smith 
40047c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr);
40147c6ae99SBarry Smith 
40247c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
40347c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
40447c6ae99SBarry Smith         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
40547c6ae99SBarry Smith       }
40647c6ae99SBarry Smith       *iptr = (void*)ptr;
40747c6ae99SBarry Smith       break;}
40847c6ae99SBarry Smith     case 3: {
40947c6ae99SBarry Smith       void ***ptr,**bptr;
41047c6ae99SBarry Smith       itdof = xm*ym*zm;
41147c6ae99SBarry Smith 
41247c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
41347c6ae99SBarry Smith 
41447c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
41547c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
41647c6ae99SBarry Smith 
41747c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
41847c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
41947c6ae99SBarry Smith       }
42047c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
42147c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
42247c6ae99SBarry Smith           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
42347c6ae99SBarry Smith         }
42447c6ae99SBarry Smith       }
42547c6ae99SBarry Smith 
42647c6ae99SBarry Smith       *iptr = (void*)ptr;
42747c6ae99SBarry Smith       break;}
42847c6ae99SBarry Smith     default:
42947c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
43047c6ae99SBarry Smith   }
43147c6ae99SBarry Smith 
43247c6ae99SBarry Smith   done:
43347c6ae99SBarry Smith   /* add arrays to the checked out list */
43447c6ae99SBarry Smith   if (ghosted) {
43547c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
43647c6ae99SBarry Smith       if (!dd->adarrayghostedout[i]) {
43747c6ae99SBarry Smith         dd->adarrayghostedout[i] = *iptr ;
43847c6ae99SBarry Smith         dd->adstartghostedout[i] = iarray_start;
43947c6ae99SBarry Smith         dd->ghostedtdof          = itdof;
44047c6ae99SBarry Smith         break;
44147c6ae99SBarry Smith       }
44247c6ae99SBarry Smith     }
44347c6ae99SBarry Smith   } else {
44447c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
44547c6ae99SBarry Smith       if (!dd->adarrayout[i]) {
44647c6ae99SBarry Smith         dd->adarrayout[i] = *iptr ;
44747c6ae99SBarry Smith         dd->adstartout[i] = iarray_start;
44847c6ae99SBarry Smith         dd->tdof          = itdof;
44947c6ae99SBarry Smith         break;
45047c6ae99SBarry Smith       }
45147c6ae99SBarry Smith     }
45247c6ae99SBarry Smith   }
45347c6ae99SBarry Smith   if (i == DA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DA ADIC arrays obtained");
45447c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
45547c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
45647c6ae99SBarry Smith   PetscFunctionReturn(0);
45747c6ae99SBarry Smith }
45847c6ae99SBarry Smith 
45947c6ae99SBarry Smith #undef __FUNCT__
46047c6ae99SBarry Smith #define __FUNCT__ "DARestoreAdicArray"
46147c6ae99SBarry Smith /*@C
46247c6ae99SBarry Smith      DARestoreAdicArray - Restores an array of derivative types for a DA
46347c6ae99SBarry Smith 
46447c6ae99SBarry Smith     Input Parameter:
46547c6ae99SBarry Smith +    da - information about my local patch
46647c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
46747c6ae99SBarry Smith 
46847c6ae99SBarry Smith     Output Parameters:
46947c6ae99SBarry Smith +    ptr - array data structured to be passed to ad_FormFunctionLocal()
47047c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
47147c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
47247c6ae99SBarry Smith 
47347c6ae99SBarry Smith      Level: advanced
47447c6ae99SBarry Smith 
47547c6ae99SBarry Smith .seealso: DAGetAdicArray()
47647c6ae99SBarry Smith 
47747c6ae99SBarry Smith @*/
478*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
47947c6ae99SBarry Smith {
48047c6ae99SBarry Smith   PetscInt  i;
48147c6ae99SBarry Smith   void      **iptr = (void**)ptr,iarray_start = 0;
48247c6ae99SBarry Smith 
48347c6ae99SBarry Smith   PetscFunctionBegin;
48447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
48547c6ae99SBarry Smith   if (ghosted) {
48647c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
48747c6ae99SBarry Smith       if (dd->adarrayghostedout[i] == *iptr) {
48847c6ae99SBarry Smith         iarray_start             = dd->adstartghostedout[i];
48947c6ae99SBarry Smith         dd->adarrayghostedout[i] = PETSC_NULL;
49047c6ae99SBarry Smith         dd->adstartghostedout[i] = PETSC_NULL;
49147c6ae99SBarry Smith         break;
49247c6ae99SBarry Smith       }
49347c6ae99SBarry Smith     }
49447c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
49547c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
49647c6ae99SBarry Smith       if (!dd->adarrayghostedin[i]){
49747c6ae99SBarry Smith         dd->adarrayghostedin[i] = *iptr;
49847c6ae99SBarry Smith         dd->adstartghostedin[i] = iarray_start;
49947c6ae99SBarry Smith         break;
50047c6ae99SBarry Smith       }
50147c6ae99SBarry Smith     }
50247c6ae99SBarry Smith   } else {
50347c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
50447c6ae99SBarry Smith       if (dd->adarrayout[i] == *iptr) {
50547c6ae99SBarry Smith         iarray_start      = dd->adstartout[i];
50647c6ae99SBarry Smith         dd->adarrayout[i] = PETSC_NULL;
50747c6ae99SBarry Smith         dd->adstartout[i] = PETSC_NULL;
50847c6ae99SBarry Smith         break;
50947c6ae99SBarry Smith       }
51047c6ae99SBarry Smith     }
51147c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
51247c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
51347c6ae99SBarry Smith       if (!dd->adarrayin[i]){
51447c6ae99SBarry Smith         dd->adarrayin[i]   = *iptr;
51547c6ae99SBarry Smith         dd->adstartin[i]   = iarray_start;
51647c6ae99SBarry Smith         break;
51747c6ae99SBarry Smith       }
51847c6ae99SBarry Smith     }
51947c6ae99SBarry Smith   }
52047c6ae99SBarry Smith   PetscFunctionReturn(0);
52147c6ae99SBarry Smith }
52247c6ae99SBarry Smith 
52347c6ae99SBarry Smith #undef __FUNCT__
52447c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray"
525*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
52647c6ae99SBarry Smith {
52747c6ae99SBarry Smith   PetscErrorCode ierr;
52847c6ae99SBarry Smith   PetscFunctionBegin;
52947c6ae99SBarry Smith   ierr = DAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
53047c6ae99SBarry Smith   PetscFunctionReturn(0);
53147c6ae99SBarry Smith }
53247c6ae99SBarry Smith 
53347c6ae99SBarry Smith #undef __FUNCT__
53447c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray"
535*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
53647c6ae99SBarry Smith {
53747c6ae99SBarry Smith   PetscErrorCode ierr;
53847c6ae99SBarry Smith   PetscFunctionBegin;
53947c6ae99SBarry Smith   ierr = DARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
54047c6ae99SBarry Smith   PetscFunctionReturn(0);
54147c6ae99SBarry Smith }
54247c6ae99SBarry Smith 
54347c6ae99SBarry Smith #endif
54447c6ae99SBarry Smith 
54547c6ae99SBarry Smith #undef __FUNCT__
54647c6ae99SBarry Smith #define __FUNCT__ "DAGetArray"
54747c6ae99SBarry Smith /*@C
54847c6ae99SBarry Smith      DAGetArray - Gets a work array for a DA
54947c6ae99SBarry Smith 
55047c6ae99SBarry Smith     Input Parameter:
55147c6ae99SBarry Smith +    da - information about my local patch
55247c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
55347c6ae99SBarry Smith 
55447c6ae99SBarry Smith     Output Parameters:
55547c6ae99SBarry Smith .    vptr - array data structured
55647c6ae99SBarry Smith 
55747c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
55847c6ae99SBarry Smith            to zero them.
55947c6ae99SBarry Smith 
56047c6ae99SBarry Smith   Level: advanced
56147c6ae99SBarry Smith 
56247c6ae99SBarry Smith .seealso: DARestoreArray(), DAGetAdicArray()
56347c6ae99SBarry Smith 
56447c6ae99SBarry Smith @*/
565*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetArray(DM da,PetscBool  ghosted,void *vptr)
56647c6ae99SBarry Smith {
56747c6ae99SBarry Smith   PetscErrorCode ierr;
56847c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
56947c6ae99SBarry Smith   char           *iarray_start;
57047c6ae99SBarry Smith   void           **iptr = (void**)vptr;
57147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
57247c6ae99SBarry Smith 
57347c6ae99SBarry Smith   PetscFunctionBegin;
57447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
57547c6ae99SBarry Smith   if (ghosted) {
57647c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
57747c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
57847c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
57947c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
58047c6ae99SBarry Smith         dd->arrayghostedin[i] = PETSC_NULL;
58147c6ae99SBarry Smith         dd->startghostedin[i] = PETSC_NULL;
58247c6ae99SBarry Smith 
58347c6ae99SBarry Smith         goto done;
58447c6ae99SBarry Smith       }
58547c6ae99SBarry Smith     }
58647c6ae99SBarry Smith     xs = dd->Xs;
58747c6ae99SBarry Smith     ys = dd->Ys;
58847c6ae99SBarry Smith     zs = dd->Zs;
58947c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
59047c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
59147c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
59247c6ae99SBarry Smith   } else {
59347c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
59447c6ae99SBarry Smith       if (dd->arrayin[i]) {
59547c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
59647c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
59747c6ae99SBarry Smith         dd->arrayin[i] = PETSC_NULL;
59847c6ae99SBarry Smith         dd->startin[i] = PETSC_NULL;
59947c6ae99SBarry Smith 
60047c6ae99SBarry Smith         goto done;
60147c6ae99SBarry Smith       }
60247c6ae99SBarry Smith     }
60347c6ae99SBarry Smith     xs = dd->xs;
60447c6ae99SBarry Smith     ys = dd->ys;
60547c6ae99SBarry Smith     zs = dd->zs;
60647c6ae99SBarry Smith     xm = dd->xe-dd->xs;
60747c6ae99SBarry Smith     ym = dd->ye-dd->ys;
60847c6ae99SBarry Smith     zm = dd->ze-dd->zs;
60947c6ae99SBarry Smith   }
61047c6ae99SBarry Smith 
61147c6ae99SBarry Smith   switch (dd->dim) {
61247c6ae99SBarry Smith     case 1: {
61347c6ae99SBarry Smith       void *ptr;
61447c6ae99SBarry Smith 
61547c6ae99SBarry Smith       ierr  = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
61647c6ae99SBarry Smith 
61747c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
61847c6ae99SBarry Smith       *iptr = (void*)ptr;
61947c6ae99SBarry Smith       break;}
62047c6ae99SBarry Smith     case 2: {
62147c6ae99SBarry Smith       void **ptr;
62247c6ae99SBarry Smith 
62347c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
62447c6ae99SBarry Smith 
62547c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
62647c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
62747c6ae99SBarry Smith         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
62847c6ae99SBarry Smith       }
62947c6ae99SBarry Smith       *iptr = (void*)ptr;
63047c6ae99SBarry Smith       break;}
63147c6ae99SBarry Smith     case 3: {
63247c6ae99SBarry Smith       void ***ptr,**bptr;
63347c6ae99SBarry Smith 
63447c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
63547c6ae99SBarry Smith 
63647c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
63747c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
63847c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
63947c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
64047c6ae99SBarry Smith       }
64147c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
64247c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
64347c6ae99SBarry Smith           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
64447c6ae99SBarry Smith         }
64547c6ae99SBarry Smith       }
64647c6ae99SBarry Smith 
64747c6ae99SBarry Smith       *iptr = (void*)ptr;
64847c6ae99SBarry Smith       break;}
64947c6ae99SBarry Smith     default:
65047c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
65147c6ae99SBarry Smith   }
65247c6ae99SBarry Smith 
65347c6ae99SBarry Smith   done:
65447c6ae99SBarry Smith   /* add arrays to the checked out list */
65547c6ae99SBarry Smith   if (ghosted) {
65647c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
65747c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
65847c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr ;
65947c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
66047c6ae99SBarry Smith         break;
66147c6ae99SBarry Smith       }
66247c6ae99SBarry Smith     }
66347c6ae99SBarry Smith   } else {
66447c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
66547c6ae99SBarry Smith       if (!dd->arrayout[i]) {
66647c6ae99SBarry Smith         dd->arrayout[i] = *iptr ;
66747c6ae99SBarry Smith         dd->startout[i] = iarray_start;
66847c6ae99SBarry Smith         break;
66947c6ae99SBarry Smith       }
67047c6ae99SBarry Smith     }
67147c6ae99SBarry Smith   }
67247c6ae99SBarry Smith   PetscFunctionReturn(0);
67347c6ae99SBarry Smith }
67447c6ae99SBarry Smith 
67547c6ae99SBarry Smith #undef __FUNCT__
67647c6ae99SBarry Smith #define __FUNCT__ "DARestoreArray"
67747c6ae99SBarry Smith /*@C
67847c6ae99SBarry Smith      DARestoreArray - Restores an array of derivative types for a DA
67947c6ae99SBarry Smith 
68047c6ae99SBarry Smith     Input Parameter:
68147c6ae99SBarry Smith +    da - information about my local patch
68247c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
68347c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
68447c6ae99SBarry Smith 
68547c6ae99SBarry Smith      Level: advanced
68647c6ae99SBarry Smith 
68747c6ae99SBarry Smith .seealso: DAGetArray(), DAGetAdicArray()
68847c6ae99SBarry Smith 
68947c6ae99SBarry Smith @*/
690*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DARestoreArray(DM da,PetscBool  ghosted,void *vptr)
69147c6ae99SBarry Smith {
69247c6ae99SBarry Smith   PetscInt  i;
69347c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
69447c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
69547c6ae99SBarry Smith 
69647c6ae99SBarry Smith   PetscFunctionBegin;
69747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
69847c6ae99SBarry Smith   if (ghosted) {
69947c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
70047c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
70147c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
70247c6ae99SBarry Smith         dd->arrayghostedout[i] = PETSC_NULL;
70347c6ae99SBarry Smith         dd->startghostedout[i] = PETSC_NULL;
70447c6ae99SBarry Smith         break;
70547c6ae99SBarry Smith       }
70647c6ae99SBarry Smith     }
70747c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
70847c6ae99SBarry Smith       if (!dd->arrayghostedin[i]){
70947c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
71047c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
71147c6ae99SBarry Smith         break;
71247c6ae99SBarry Smith       }
71347c6ae99SBarry Smith     }
71447c6ae99SBarry Smith   } else {
71547c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
71647c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
71747c6ae99SBarry Smith         iarray_start    = dd->startout[i];
71847c6ae99SBarry Smith         dd->arrayout[i] = PETSC_NULL;
71947c6ae99SBarry Smith         dd->startout[i] = PETSC_NULL;
72047c6ae99SBarry Smith         break;
72147c6ae99SBarry Smith       }
72247c6ae99SBarry Smith     }
72347c6ae99SBarry Smith     for (i=0; i<DA_MAX_WORK_ARRAYS; i++) {
72447c6ae99SBarry Smith       if (!dd->arrayin[i]){
72547c6ae99SBarry Smith         dd->arrayin[i]  = *iptr;
72647c6ae99SBarry Smith         dd->startin[i]  = iarray_start;
72747c6ae99SBarry Smith         break;
72847c6ae99SBarry Smith       }
72947c6ae99SBarry Smith     }
73047c6ae99SBarry Smith   }
73147c6ae99SBarry Smith   PetscFunctionReturn(0);
73247c6ae99SBarry Smith }
73347c6ae99SBarry Smith 
73447c6ae99SBarry Smith #undef __FUNCT__
73547c6ae99SBarry Smith #define __FUNCT__ "DAGetAdicMFArray"
73647c6ae99SBarry Smith /*@C
73747c6ae99SBarry Smith      DAGetAdicMFArray - Gets an array of derivative types for a DA for matrix-free ADIC.
73847c6ae99SBarry Smith 
73947c6ae99SBarry Smith      Input Parameter:
74047c6ae99SBarry Smith +    da - information about my local patch
74147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
74247c6ae99SBarry Smith 
74347c6ae99SBarry Smith      Output Parameters:
74447c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
74547c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
74647c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
74747c6ae99SBarry Smith 
74847c6ae99SBarry Smith      Notes:
74947c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
75047c6ae99SBarry Smith      to zero them.
75147c6ae99SBarry Smith 
75247c6ae99SBarry Smith      This routine returns the same type of object as the DAVecGetArray(), except its
75347c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
75447c6ae99SBarry Smith 
75547c6ae99SBarry Smith      Level: advanced
75647c6ae99SBarry Smith 
75747c6ae99SBarry Smith .seealso: DARestoreAdicMFArray(), DAGetArray(), DAGetAdicArray()
75847c6ae99SBarry Smith 
75947c6ae99SBarry Smith @*/
760*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
76147c6ae99SBarry Smith {
76247c6ae99SBarry Smith   PetscErrorCode ierr;
76347c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
76447c6ae99SBarry Smith   char           *iarray_start;
76547c6ae99SBarry Smith   void           **iptr = (void**)vptr;
76647c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
76747c6ae99SBarry Smith 
76847c6ae99SBarry Smith   PetscFunctionBegin;
76947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
77047c6ae99SBarry Smith   if (ghosted) {
77147c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
77247c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
77347c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
77447c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
77547c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
77647c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
77747c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
77847c6ae99SBarry Smith 
77947c6ae99SBarry Smith         goto done;
78047c6ae99SBarry Smith       }
78147c6ae99SBarry Smith     }
78247c6ae99SBarry Smith     xs = dd->Xs;
78347c6ae99SBarry Smith     ys = dd->Ys;
78447c6ae99SBarry Smith     zs = dd->Zs;
78547c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
78647c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
78747c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
78847c6ae99SBarry Smith   } else {
78947c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
79047c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
79147c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
79247c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
79347c6ae99SBarry Smith         itdof              = dd->tdof;
79447c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
79547c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
79647c6ae99SBarry Smith 
79747c6ae99SBarry Smith         goto done;
79847c6ae99SBarry Smith       }
79947c6ae99SBarry Smith     }
80047c6ae99SBarry Smith     xs = dd->xs;
80147c6ae99SBarry Smith     ys = dd->ys;
80247c6ae99SBarry Smith     zs = dd->zs;
80347c6ae99SBarry Smith     xm = dd->xe-dd->xs;
80447c6ae99SBarry Smith     ym = dd->ye-dd->ys;
80547c6ae99SBarry Smith     zm = dd->ze-dd->zs;
80647c6ae99SBarry Smith   }
80747c6ae99SBarry Smith 
80847c6ae99SBarry Smith   switch (dd->dim) {
80947c6ae99SBarry Smith     case 1: {
81047c6ae99SBarry Smith       void *ptr;
81147c6ae99SBarry Smith       itdof = xm;
81247c6ae99SBarry Smith 
81347c6ae99SBarry Smith       ierr  = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
81447c6ae99SBarry Smith 
81547c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
81647c6ae99SBarry Smith       *iptr = (void*)ptr;
81747c6ae99SBarry Smith       break;}
81847c6ae99SBarry Smith     case 2: {
81947c6ae99SBarry Smith       void **ptr;
82047c6ae99SBarry Smith       itdof = xm*ym;
82147c6ae99SBarry Smith 
82247c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
82347c6ae99SBarry Smith 
82447c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
82547c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
82647c6ae99SBarry Smith         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
82747c6ae99SBarry Smith       }
82847c6ae99SBarry Smith       *iptr = (void*)ptr;
82947c6ae99SBarry Smith       break;}
83047c6ae99SBarry Smith     case 3: {
83147c6ae99SBarry Smith       void ***ptr,**bptr;
83247c6ae99SBarry Smith       itdof = xm*ym*zm;
83347c6ae99SBarry Smith 
83447c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
83547c6ae99SBarry Smith 
83647c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
83747c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
83847c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
83947c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
84047c6ae99SBarry Smith       }
84147c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
84247c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
84347c6ae99SBarry Smith           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
84447c6ae99SBarry Smith         }
84547c6ae99SBarry Smith       }
84647c6ae99SBarry Smith 
84747c6ae99SBarry Smith       *iptr = (void*)ptr;
84847c6ae99SBarry Smith       break;}
84947c6ae99SBarry Smith     default:
85047c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
85147c6ae99SBarry Smith   }
85247c6ae99SBarry Smith 
85347c6ae99SBarry Smith   done:
85447c6ae99SBarry Smith   /* add arrays to the checked out list */
85547c6ae99SBarry Smith   if (ghosted) {
85647c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
85747c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
85847c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
85947c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
86047c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
86147c6ae99SBarry Smith         break;
86247c6ae99SBarry Smith       }
86347c6ae99SBarry Smith     }
86447c6ae99SBarry Smith   } else {
86547c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
86647c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
86747c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
86847c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
86947c6ae99SBarry Smith         dd->tdof            = itdof;
87047c6ae99SBarry Smith         break;
87147c6ae99SBarry Smith       }
87247c6ae99SBarry Smith     }
87347c6ae99SBarry Smith   }
87447c6ae99SBarry Smith   if (i == DA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DA ADIC arrays obtained");
87547c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
87647c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
87747c6ae99SBarry Smith   PetscFunctionReturn(0);
87847c6ae99SBarry Smith }
87947c6ae99SBarry Smith 
88047c6ae99SBarry Smith #undef __FUNCT__
88147c6ae99SBarry Smith #define __FUNCT__ "DAGetAdicMFArray4"
882*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
88347c6ae99SBarry Smith {
88447c6ae99SBarry Smith   PetscErrorCode ierr;
88547c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
88647c6ae99SBarry Smith   char           *iarray_start;
88747c6ae99SBarry Smith   void           **iptr = (void**)vptr;
88847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
88947c6ae99SBarry Smith 
89047c6ae99SBarry Smith   PetscFunctionBegin;
89147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
89247c6ae99SBarry Smith   if (ghosted) {
89347c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
89447c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
89547c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
89647c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
89747c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
89847c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
89947c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
90047c6ae99SBarry Smith 
90147c6ae99SBarry Smith         goto done;
90247c6ae99SBarry Smith       }
90347c6ae99SBarry Smith     }
90447c6ae99SBarry Smith     xs = dd->Xs;
90547c6ae99SBarry Smith     ys = dd->Ys;
90647c6ae99SBarry Smith     zs = dd->Zs;
90747c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
90847c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
90947c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
91047c6ae99SBarry Smith   } else {
91147c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
91247c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
91347c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
91447c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
91547c6ae99SBarry Smith         itdof              = dd->tdof;
91647c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
91747c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
91847c6ae99SBarry Smith 
91947c6ae99SBarry Smith         goto done;
92047c6ae99SBarry Smith       }
92147c6ae99SBarry Smith     }
92247c6ae99SBarry Smith     xs = dd->xs;
92347c6ae99SBarry Smith     ys = dd->ys;
92447c6ae99SBarry Smith     zs = dd->zs;
92547c6ae99SBarry Smith     xm = dd->xe-dd->xs;
92647c6ae99SBarry Smith     ym = dd->ye-dd->ys;
92747c6ae99SBarry Smith     zm = dd->ze-dd->zs;
92847c6ae99SBarry Smith   }
92947c6ae99SBarry Smith 
93047c6ae99SBarry Smith   switch (dd->dim) {
93147c6ae99SBarry Smith     case 2: {
93247c6ae99SBarry Smith       void **ptr;
93347c6ae99SBarry Smith       itdof = xm*ym;
93447c6ae99SBarry Smith 
93547c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
93647c6ae99SBarry Smith 
93747c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
93847c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
93947c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
94047c6ae99SBarry Smith       }
94147c6ae99SBarry Smith       *iptr = (void*)ptr;
94247c6ae99SBarry Smith       break;}
94347c6ae99SBarry Smith     default:
94447c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
94547c6ae99SBarry Smith   }
94647c6ae99SBarry Smith 
94747c6ae99SBarry Smith   done:
94847c6ae99SBarry Smith   /* add arrays to the checked out list */
94947c6ae99SBarry Smith   if (ghosted) {
95047c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
95147c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
95247c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
95347c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
95447c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
95547c6ae99SBarry Smith         break;
95647c6ae99SBarry Smith       }
95747c6ae99SBarry Smith     }
95847c6ae99SBarry Smith   } else {
95947c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
96047c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
96147c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
96247c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
96347c6ae99SBarry Smith         dd->tdof            = itdof;
96447c6ae99SBarry Smith         break;
96547c6ae99SBarry Smith       }
96647c6ae99SBarry Smith     }
96747c6ae99SBarry Smith   }
96847c6ae99SBarry Smith   if (i == DA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DA ADIC arrays obtained");
96947c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
97047c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
97147c6ae99SBarry Smith   PetscFunctionReturn(0);
97247c6ae99SBarry Smith }
97347c6ae99SBarry Smith 
97447c6ae99SBarry Smith #undef __FUNCT__
97547c6ae99SBarry Smith #define __FUNCT__ "DAGetAdicMFArray9"
976*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
97747c6ae99SBarry Smith {
97847c6ae99SBarry Smith   PetscErrorCode ierr;
97947c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
98047c6ae99SBarry Smith   char           *iarray_start;
98147c6ae99SBarry Smith   void           **iptr = (void**)vptr;
98247c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
98347c6ae99SBarry Smith 
98447c6ae99SBarry Smith   PetscFunctionBegin;
98547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
98647c6ae99SBarry Smith   if (ghosted) {
98747c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
98847c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
98947c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
99047c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
99147c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
99247c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
99347c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
99447c6ae99SBarry Smith 
99547c6ae99SBarry Smith         goto done;
99647c6ae99SBarry Smith       }
99747c6ae99SBarry Smith     }
99847c6ae99SBarry Smith     xs = dd->Xs;
99947c6ae99SBarry Smith     ys = dd->Ys;
100047c6ae99SBarry Smith     zs = dd->Zs;
100147c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
100247c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
100347c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
100447c6ae99SBarry Smith   } else {
100547c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
100647c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
100747c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
100847c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
100947c6ae99SBarry Smith         itdof              = dd->tdof;
101047c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
101147c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
101247c6ae99SBarry Smith 
101347c6ae99SBarry Smith         goto done;
101447c6ae99SBarry Smith       }
101547c6ae99SBarry Smith     }
101647c6ae99SBarry Smith     xs = dd->xs;
101747c6ae99SBarry Smith     ys = dd->ys;
101847c6ae99SBarry Smith     zs = dd->zs;
101947c6ae99SBarry Smith     xm = dd->xe-dd->xs;
102047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
102147c6ae99SBarry Smith     zm = dd->ze-dd->zs;
102247c6ae99SBarry Smith   }
102347c6ae99SBarry Smith 
102447c6ae99SBarry Smith   switch (dd->dim) {
102547c6ae99SBarry Smith     case 2: {
102647c6ae99SBarry Smith       void **ptr;
102747c6ae99SBarry Smith       itdof = xm*ym;
102847c6ae99SBarry Smith 
102947c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
103047c6ae99SBarry Smith 
103147c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
103247c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
103347c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
103447c6ae99SBarry Smith       }
103547c6ae99SBarry Smith       *iptr = (void*)ptr;
103647c6ae99SBarry Smith       break;}
103747c6ae99SBarry Smith     default:
103847c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
103947c6ae99SBarry Smith   }
104047c6ae99SBarry Smith 
104147c6ae99SBarry Smith   done:
104247c6ae99SBarry Smith   /* add arrays to the checked out list */
104347c6ae99SBarry Smith   if (ghosted) {
104447c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
104547c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
104647c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
104747c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
104847c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
104947c6ae99SBarry Smith         break;
105047c6ae99SBarry Smith       }
105147c6ae99SBarry Smith     }
105247c6ae99SBarry Smith   } else {
105347c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
105447c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
105547c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
105647c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
105747c6ae99SBarry Smith         dd->tdof            = itdof;
105847c6ae99SBarry Smith         break;
105947c6ae99SBarry Smith       }
106047c6ae99SBarry Smith     }
106147c6ae99SBarry Smith   }
106247c6ae99SBarry Smith   if (i == DA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DA ADIC arrays obtained");
106347c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
106447c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
106547c6ae99SBarry Smith   PetscFunctionReturn(0);
106647c6ae99SBarry Smith }
106747c6ae99SBarry Smith 
106847c6ae99SBarry Smith #undef __FUNCT__
106947c6ae99SBarry Smith #define __FUNCT__ "DAGetAdicMFArrayb"
107047c6ae99SBarry Smith /*@C
107147c6ae99SBarry Smith      DAGetAdicMFArrayb - Gets an array of derivative types for a DA for matrix-free ADIC.
107247c6ae99SBarry Smith 
107347c6ae99SBarry Smith      Input Parameter:
107447c6ae99SBarry Smith +    da - information about my local patch
107547c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
107647c6ae99SBarry Smith 
107747c6ae99SBarry Smith      Output Parameters:
107847c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
107947c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
108047c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
108147c6ae99SBarry Smith 
108247c6ae99SBarry Smith      Notes:
108347c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
108447c6ae99SBarry Smith      to zero them.
108547c6ae99SBarry Smith 
108647c6ae99SBarry Smith      This routine returns the same type of object as the DAVecGetArray(), except its
108747c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
108847c6ae99SBarry Smith 
108947c6ae99SBarry Smith      Level: advanced
109047c6ae99SBarry Smith 
109147c6ae99SBarry Smith .seealso: DARestoreAdicMFArray(), DAGetArray(), DAGetAdicArray()
109247c6ae99SBarry Smith 
109347c6ae99SBarry Smith @*/
1094*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
109547c6ae99SBarry Smith {
109647c6ae99SBarry Smith   PetscErrorCode ierr;
109747c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
109847c6ae99SBarry Smith   char           *iarray_start;
109947c6ae99SBarry Smith   void           **iptr = (void**)vptr;
110047c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
110147c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
110247c6ae99SBarry Smith 
110347c6ae99SBarry Smith   PetscFunctionBegin;
110447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
110547c6ae99SBarry Smith   if (ghosted) {
110647c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
110747c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
110847c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
110947c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
111047c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
111147c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
111247c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
111347c6ae99SBarry Smith 
111447c6ae99SBarry Smith         goto done;
111547c6ae99SBarry Smith       }
111647c6ae99SBarry Smith     }
111747c6ae99SBarry Smith     xs = dd->Xs;
111847c6ae99SBarry Smith     ys = dd->Ys;
111947c6ae99SBarry Smith     zs = dd->Zs;
112047c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
112147c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
112247c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
112347c6ae99SBarry Smith   } else {
112447c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
112547c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
112647c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
112747c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
112847c6ae99SBarry Smith         itdof              = dd->tdof;
112947c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
113047c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
113147c6ae99SBarry Smith 
113247c6ae99SBarry Smith         goto done;
113347c6ae99SBarry Smith       }
113447c6ae99SBarry Smith     }
113547c6ae99SBarry Smith     xs = dd->xs;
113647c6ae99SBarry Smith     ys = dd->ys;
113747c6ae99SBarry Smith     zs = dd->zs;
113847c6ae99SBarry Smith     xm = dd->xe-dd->xs;
113947c6ae99SBarry Smith     ym = dd->ye-dd->ys;
114047c6ae99SBarry Smith     zm = dd->ze-dd->zs;
114147c6ae99SBarry Smith   }
114247c6ae99SBarry Smith 
114347c6ae99SBarry Smith   switch (dd->dim) {
114447c6ae99SBarry Smith     case 1: {
114547c6ae99SBarry Smith       void *ptr;
114647c6ae99SBarry Smith       itdof = xm;
114747c6ae99SBarry Smith 
114847c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
114947c6ae99SBarry Smith 
115047c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
115147c6ae99SBarry Smith       *iptr = (void*)ptr;
115247c6ae99SBarry Smith       break;}
115347c6ae99SBarry Smith     case 2: {
115447c6ae99SBarry Smith       void **ptr;
115547c6ae99SBarry Smith       itdof = xm*ym;
115647c6ae99SBarry Smith 
115747c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
115847c6ae99SBarry Smith 
115947c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
116047c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
116147c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
116247c6ae99SBarry Smith       }
116347c6ae99SBarry Smith       *iptr = (void*)ptr;
116447c6ae99SBarry Smith       break;}
116547c6ae99SBarry Smith     case 3: {
116647c6ae99SBarry Smith       void ***ptr,**bptr;
116747c6ae99SBarry Smith       itdof = xm*ym*zm;
116847c6ae99SBarry Smith 
116947c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
117047c6ae99SBarry Smith 
117147c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
117247c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
117347c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
117447c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
117547c6ae99SBarry Smith       }
117647c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
117747c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
117847c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
117947c6ae99SBarry Smith         }
118047c6ae99SBarry Smith       }
118147c6ae99SBarry Smith 
118247c6ae99SBarry Smith       *iptr = (void*)ptr;
118347c6ae99SBarry Smith       break;}
118447c6ae99SBarry Smith     default:
118547c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
118647c6ae99SBarry Smith   }
118747c6ae99SBarry Smith 
118847c6ae99SBarry Smith   done:
118947c6ae99SBarry Smith   /* add arrays to the checked out list */
119047c6ae99SBarry Smith   if (ghosted) {
119147c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
119247c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
119347c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
119447c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
119547c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
119647c6ae99SBarry Smith         break;
119747c6ae99SBarry Smith       }
119847c6ae99SBarry Smith     }
119947c6ae99SBarry Smith   } else {
120047c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
120147c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
120247c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
120347c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
120447c6ae99SBarry Smith         dd->tdof            = itdof;
120547c6ae99SBarry Smith         break;
120647c6ae99SBarry Smith       }
120747c6ae99SBarry Smith     }
120847c6ae99SBarry Smith   }
120947c6ae99SBarry Smith   if (i == DA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DA ADIC arrays obtained");
121047c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
121147c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
121247c6ae99SBarry Smith   PetscFunctionReturn(0);
121347c6ae99SBarry Smith }
121447c6ae99SBarry Smith 
121547c6ae99SBarry Smith #undef __FUNCT__
121647c6ae99SBarry Smith #define __FUNCT__ "DARestoreAdicMFArray"
121747c6ae99SBarry Smith /*@C
121847c6ae99SBarry Smith      DARestoreAdicMFArray - Restores an array of derivative types for a DA.
121947c6ae99SBarry Smith 
122047c6ae99SBarry Smith      Input Parameter:
122147c6ae99SBarry Smith +    da - information about my local patch
122247c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
122347c6ae99SBarry Smith 
122447c6ae99SBarry Smith      Output Parameters:
122547c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
122647c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
122747c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
122847c6ae99SBarry Smith 
122947c6ae99SBarry Smith      Level: advanced
123047c6ae99SBarry Smith 
123147c6ae99SBarry Smith .seealso: DAGetAdicArray()
123247c6ae99SBarry Smith 
123347c6ae99SBarry Smith @*/
1234*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
123547c6ae99SBarry Smith {
123647c6ae99SBarry Smith   PetscInt  i;
123747c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
123847c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
123947c6ae99SBarry Smith 
124047c6ae99SBarry Smith   PetscFunctionBegin;
124147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
124247c6ae99SBarry Smith   if (ghosted) {
124347c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
124447c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
124547c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
124647c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
124747c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
124847c6ae99SBarry Smith         break;
124947c6ae99SBarry Smith       }
125047c6ae99SBarry Smith     }
125147c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
125247c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
125347c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
125447c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
125547c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
125647c6ae99SBarry Smith         break;
125747c6ae99SBarry Smith       }
125847c6ae99SBarry Smith     }
125947c6ae99SBarry Smith   } else {
126047c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
126147c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
126247c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
126347c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
126447c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
126547c6ae99SBarry Smith         break;
126647c6ae99SBarry Smith       }
126747c6ae99SBarry Smith     }
126847c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
126947c6ae99SBarry Smith     for (i=0; i<DA_MAX_AD_ARRAYS; i++) {
127047c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
127147c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
127247c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
127347c6ae99SBarry Smith         break;
127447c6ae99SBarry Smith       }
127547c6ae99SBarry Smith     }
127647c6ae99SBarry Smith   }
127747c6ae99SBarry Smith   PetscFunctionReturn(0);
127847c6ae99SBarry Smith }
127947c6ae99SBarry Smith 
128047c6ae99SBarry Smith #undef __FUNCT__
128147c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
1282*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
128347c6ae99SBarry Smith {
128447c6ae99SBarry Smith   PetscErrorCode ierr;
128547c6ae99SBarry Smith   PetscFunctionBegin;
128647c6ae99SBarry Smith   ierr = DAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
128747c6ae99SBarry Smith   PetscFunctionReturn(0);
128847c6ae99SBarry Smith }
128947c6ae99SBarry Smith 
129047c6ae99SBarry Smith #undef __FUNCT__
129147c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
1292*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
129347c6ae99SBarry Smith {
129447c6ae99SBarry Smith   PetscErrorCode ierr;
129547c6ae99SBarry Smith   PetscFunctionBegin;
129647c6ae99SBarry Smith   ierr = DARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
129747c6ae99SBarry Smith   PetscFunctionReturn(0);
129847c6ae99SBarry Smith }
129947c6ae99SBarry Smith 
1300