xref: /petsc/src/dm/impls/da/dalocal.c (revision 3c0c59f39ee3bd561a1b4dcbd0e58366bfa60aba)
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;
27*3c0c59f3SBarry Smith   ierr = PetscObjectQuery((PetscObject)vec,"DM",(PetscObject*)&da);CHKERRQ(ierr);
28aa219208SBarry Smith   if (!da) SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA");
29aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr);
3047c6ae99SBarry Smith 
3147c6ae99SBarry Smith   ierr = VecGetArray(vec,&array);CHKERRQ(ierr);
3247c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
3347c6ae99SBarry Smith   mat  = mxCreateDoubleMatrix(m,n,mxREAL);
3447c6ae99SBarry Smith #else
3547c6ae99SBarry Smith   mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3647c6ae99SBarry Smith #endif
3747c6ae99SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr);
3847c6ae99SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
3947c6ae99SBarry Smith   engPutVariable((Engine *)mengine,obj->name,mat);
4047c6ae99SBarry Smith 
4147c6ae99SBarry Smith   ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr);
4247c6ae99SBarry Smith   PetscFunctionReturn(0);
4347c6ae99SBarry Smith }
4447c6ae99SBarry Smith EXTERN_C_END
4547c6ae99SBarry Smith #endif
4647c6ae99SBarry Smith 
4747c6ae99SBarry Smith 
4847c6ae99SBarry Smith #undef __FUNCT__
49564755cdSBarry Smith #define __FUNCT__ "DMCreateLocalVector_DA"
507087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_DA(DM da,Vec* g)
5147c6ae99SBarry Smith {
5247c6ae99SBarry Smith   PetscErrorCode ierr;
5347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
5447c6ae99SBarry Smith 
5547c6ae99SBarry Smith   PetscFunctionBegin;
5647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
5747c6ae99SBarry Smith   PetscValidPointer(g,2);
5847c6ae99SBarry Smith   ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr);
5947c6ae99SBarry Smith   ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
6047c6ae99SBarry Smith   ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
6147c6ae99SBarry Smith   ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
62*3c0c59f3SBarry Smith   ierr = PetscObjectCompose((PetscObject)*g,"DM",(PetscObject)da);CHKERRQ(ierr);
6347c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
6447c6ae99SBarry Smith   if (dd->w == 1  && dd->dim == 2) {
6547c6ae99SBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
6647c6ae99SBarry Smith   }
6747c6ae99SBarry Smith #endif
6847c6ae99SBarry Smith   PetscFunctionReturn(0);
6947c6ae99SBarry Smith }
7047c6ae99SBarry Smith 
7147c6ae99SBarry Smith #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   }
169fcfd50ebSBarry 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__
2354dcab191SBarry Smith #define __FUNCT__ "DMClearGlobalVectors"
2364dcab191SBarry Smith /*@
2374dcab191SBarry Smith    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
2384dcab191SBarry Smith 
2394dcab191SBarry Smith    Collective on DM
2404dcab191SBarry Smith 
2414dcab191SBarry Smith    Input Parameter:
2424dcab191SBarry Smith .  dm - the distributed array
2434dcab191SBarry Smith 
2444dcab191SBarry Smith    Level: developer
2454dcab191SBarry Smith 
2464dcab191SBarry Smith .keywords: distributed array, create, Global, vector
2474dcab191SBarry Smith 
2484dcab191SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
2494dcab191SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
2504dcab191SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
2514dcab191SBarry Smith           VecStrideMax(), VecStrideMin(), VecStrideNorm()
2524dcab191SBarry Smith 
2534dcab191SBarry Smith @*/
2544dcab191SBarry Smith PetscErrorCode  DMClearGlobalVectors(DM dm)
2554dcab191SBarry Smith {
2564dcab191SBarry Smith   PetscErrorCode ierr;
2574dcab191SBarry Smith   PetscInt       i;
2584dcab191SBarry Smith 
2594dcab191SBarry Smith   PetscFunctionBegin;
2604dcab191SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2614dcab191SBarry Smith   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
2624dcab191SBarry Smith     if (dm->globalout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
2634dcab191SBarry Smith     ierr = VecDestroy(&dm->globalin[i]);CHKERRQ(ierr);
2644dcab191SBarry Smith   }
2654dcab191SBarry Smith   PetscFunctionReturn(0);
2664dcab191SBarry Smith }
2674dcab191SBarry Smith 
2684dcab191SBarry Smith #undef __FUNCT__
26947c6ae99SBarry Smith #define __FUNCT__ "DMRestoreGlobalVector"
27047c6ae99SBarry Smith /*@
27147c6ae99SBarry Smith    DMRestoreGlobalVector - Returns a Seq PETSc vector that
27247c6ae99SBarry Smith      obtained from DMGetGlobalVector(). Do not use with vector obtained via
27347c6ae99SBarry Smith      DMCreateGlobalVector().
27447c6ae99SBarry Smith 
27547c6ae99SBarry Smith    Not Collective
27647c6ae99SBarry Smith 
27747c6ae99SBarry Smith    Input Parameter:
27847c6ae99SBarry Smith +  dm - the distributed array
27947c6ae99SBarry Smith -  g - the global vector
28047c6ae99SBarry Smith 
28147c6ae99SBarry Smith    Level: beginner
28247c6ae99SBarry Smith 
28347c6ae99SBarry Smith .keywords: distributed array, create, global, vector
28447c6ae99SBarry Smith 
28547c6ae99SBarry Smith .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
286aa219208SBarry Smith           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
28747c6ae99SBarry Smith           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
28847c6ae99SBarry Smith @*/
2897087cfbeSBarry Smith PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec* g)
29047c6ae99SBarry Smith {
29147c6ae99SBarry Smith   PetscErrorCode ierr;
29247c6ae99SBarry Smith   PetscInt       i,j;
29347c6ae99SBarry Smith 
29447c6ae99SBarry Smith   PetscFunctionBegin;
29547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
29647c6ae99SBarry Smith   PetscValidPointer(g,2);
29747c6ae99SBarry Smith   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
29847c6ae99SBarry Smith     if (*g == dm->globalout[j]) {
29947c6ae99SBarry Smith       dm->globalout[j] = PETSC_NULL;
30047c6ae99SBarry Smith       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
30147c6ae99SBarry Smith         if (!dm->globalin[i]) {
30247c6ae99SBarry Smith           dm->globalin[i] = *g;
30347c6ae99SBarry Smith           goto alldone;
30447c6ae99SBarry Smith         }
30547c6ae99SBarry Smith       }
30647c6ae99SBarry Smith     }
30747c6ae99SBarry Smith   }
308fcfd50ebSBarry Smith   ierr = VecDestroy(g);CHKERRQ(ierr);
30947c6ae99SBarry Smith   alldone:
31047c6ae99SBarry Smith   PetscFunctionReturn(0);
31147c6ae99SBarry Smith }
31247c6ae99SBarry Smith 
31347c6ae99SBarry Smith /* ------------------------------------------------------------------- */
31447c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
31547c6ae99SBarry Smith 
31647c6ae99SBarry Smith EXTERN_C_BEGIN
317c6db04a5SJed Brown #include <adic/ad_utils.h>
31847c6ae99SBarry Smith EXTERN_C_END
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith #undef __FUNCT__
321aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicArray"
32247c6ae99SBarry Smith /*@C
323aa219208SBarry Smith      DMDAGetAdicArray - Gets an array of derivative types for a DMDA
32447c6ae99SBarry Smith 
32547c6ae99SBarry Smith     Input Parameter:
32647c6ae99SBarry Smith +    da - information about my local patch
32747c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
32847c6ae99SBarry Smith 
32947c6ae99SBarry Smith     Output Parameters:
33047c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
33147c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
33247c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
33347c6ae99SBarry Smith 
33447c6ae99SBarry Smith      Notes:
33547c6ae99SBarry Smith        The vector values are NOT initialized and may have garbage in them, so you may need
33647c6ae99SBarry Smith        to zero them.
33747c6ae99SBarry Smith 
338aa219208SBarry Smith        Returns the same type of object as the DMDAVecGetArray() except its elements are
33947c6ae99SBarry Smith            derivative types instead of PetscScalars
34047c6ae99SBarry Smith 
34147c6ae99SBarry Smith      Level: advanced
34247c6ae99SBarry Smith 
343aa219208SBarry Smith .seealso: DMDARestoreAdicArray()
34447c6ae99SBarry Smith 
34547c6ae99SBarry Smith @*/
3467087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
34747c6ae99SBarry Smith {
34847c6ae99SBarry Smith   PetscErrorCode ierr;
34947c6ae99SBarry Smith   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
35047c6ae99SBarry Smith   char           *iarray_start;
35147c6ae99SBarry Smith   void           **iptr = (void**)vptr;
35247c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
35347c6ae99SBarry Smith 
35447c6ae99SBarry Smith   PetscFunctionBegin;
35547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
35647c6ae99SBarry Smith   if (ghosted) {
357aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
35847c6ae99SBarry Smith       if (dd->adarrayghostedin[i]) {
35947c6ae99SBarry Smith         *iptr                   = dd->adarrayghostedin[i];
36047c6ae99SBarry Smith         iarray_start            = (char*)dd->adstartghostedin[i];
36147c6ae99SBarry Smith         itdof                   = dd->ghostedtdof;
36247c6ae99SBarry Smith         dd->adarrayghostedin[i] = PETSC_NULL;
36347c6ae99SBarry Smith         dd->adstartghostedin[i] = PETSC_NULL;
36447c6ae99SBarry Smith 
36547c6ae99SBarry Smith         goto done;
36647c6ae99SBarry Smith       }
36747c6ae99SBarry Smith     }
36847c6ae99SBarry Smith     xs = dd->Xs;
36947c6ae99SBarry Smith     ys = dd->Ys;
37047c6ae99SBarry Smith     zs = dd->Zs;
37147c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
37247c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
37347c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
37447c6ae99SBarry Smith   } else {
375aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
37647c6ae99SBarry Smith       if (dd->adarrayin[i]) {
37747c6ae99SBarry Smith         *iptr            = dd->adarrayin[i];
37847c6ae99SBarry Smith         iarray_start     = (char*)dd->adstartin[i];
37947c6ae99SBarry Smith         itdof            = dd->tdof;
38047c6ae99SBarry Smith         dd->adarrayin[i] = PETSC_NULL;
38147c6ae99SBarry Smith         dd->adstartin[i] = PETSC_NULL;
38247c6ae99SBarry Smith 
38347c6ae99SBarry Smith         goto done;
38447c6ae99SBarry Smith       }
38547c6ae99SBarry Smith     }
38647c6ae99SBarry Smith     xs = dd->xs;
38747c6ae99SBarry Smith     ys = dd->ys;
38847c6ae99SBarry Smith     zs = dd->zs;
38947c6ae99SBarry Smith     xm = dd->xe-dd->xs;
39047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
39147c6ae99SBarry Smith     zm = dd->ze-dd->zs;
39247c6ae99SBarry Smith   }
39347c6ae99SBarry Smith   deriv_type_size = PetscADGetDerivTypeSize();
39447c6ae99SBarry Smith 
39547c6ae99SBarry Smith   switch (dd->dim) {
39647c6ae99SBarry Smith     case 1: {
39747c6ae99SBarry Smith       void *ptr;
39847c6ae99SBarry Smith       itdof = xm;
39947c6ae99SBarry Smith 
40047c6ae99SBarry Smith       ierr  = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
40147c6ae99SBarry Smith 
40247c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*deriv_type_size);
40347c6ae99SBarry Smith       *iptr = (void*)ptr;
40447c6ae99SBarry Smith       break;}
40547c6ae99SBarry Smith     case 2: {
40647c6ae99SBarry Smith       void **ptr;
40747c6ae99SBarry Smith       itdof = xm*ym;
40847c6ae99SBarry Smith 
40947c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr);
41047c6ae99SBarry Smith 
41147c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
41247c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
41347c6ae99SBarry Smith         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
41447c6ae99SBarry Smith       }
41547c6ae99SBarry Smith       *iptr = (void*)ptr;
41647c6ae99SBarry Smith       break;}
41747c6ae99SBarry Smith     case 3: {
41847c6ae99SBarry Smith       void ***ptr,**bptr;
41947c6ae99SBarry Smith       itdof = xm*ym*zm;
42047c6ae99SBarry Smith 
42147c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr);
42247c6ae99SBarry Smith 
42347c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
42447c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
42547c6ae99SBarry Smith 
42647c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
42747c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
42847c6ae99SBarry Smith       }
42947c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
43047c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
43147c6ae99SBarry Smith           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
43247c6ae99SBarry Smith         }
43347c6ae99SBarry Smith       }
43447c6ae99SBarry Smith 
43547c6ae99SBarry Smith       *iptr = (void*)ptr;
43647c6ae99SBarry Smith       break;}
43747c6ae99SBarry Smith     default:
43847c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
43947c6ae99SBarry Smith   }
44047c6ae99SBarry Smith 
44147c6ae99SBarry Smith   done:
44247c6ae99SBarry Smith   /* add arrays to the checked out list */
44347c6ae99SBarry Smith   if (ghosted) {
444aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
44547c6ae99SBarry Smith       if (!dd->adarrayghostedout[i]) {
44647c6ae99SBarry Smith         dd->adarrayghostedout[i] = *iptr ;
44747c6ae99SBarry Smith         dd->adstartghostedout[i] = iarray_start;
44847c6ae99SBarry Smith         dd->ghostedtdof          = itdof;
44947c6ae99SBarry Smith         break;
45047c6ae99SBarry Smith       }
45147c6ae99SBarry Smith     }
45247c6ae99SBarry Smith   } else {
453aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
45447c6ae99SBarry Smith       if (!dd->adarrayout[i]) {
45547c6ae99SBarry Smith         dd->adarrayout[i] = *iptr ;
45647c6ae99SBarry Smith         dd->adstartout[i] = iarray_start;
45747c6ae99SBarry Smith         dd->tdof          = itdof;
45847c6ae99SBarry Smith         break;
45947c6ae99SBarry Smith       }
46047c6ae99SBarry Smith     }
46147c6ae99SBarry Smith   }
462aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
46347c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
46447c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
46547c6ae99SBarry Smith   PetscFunctionReturn(0);
46647c6ae99SBarry Smith }
46747c6ae99SBarry Smith 
46847c6ae99SBarry Smith #undef __FUNCT__
469aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicArray"
47047c6ae99SBarry Smith /*@C
471aa219208SBarry Smith      DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
47247c6ae99SBarry Smith 
47347c6ae99SBarry Smith     Input Parameter:
47447c6ae99SBarry Smith +    da - information about my local patch
47547c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
47647c6ae99SBarry Smith 
47747c6ae99SBarry Smith     Output Parameters:
47847c6ae99SBarry Smith +    ptr - array data structured to be passed to ad_FormFunctionLocal()
47947c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
48047c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
48147c6ae99SBarry Smith 
48247c6ae99SBarry Smith      Level: advanced
48347c6ae99SBarry Smith 
484aa219208SBarry Smith .seealso: DMDAGetAdicArray()
48547c6ae99SBarry Smith 
48647c6ae99SBarry Smith @*/
4877087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
48847c6ae99SBarry Smith {
48947c6ae99SBarry Smith   PetscInt  i;
49047c6ae99SBarry Smith   void      **iptr = (void**)ptr,iarray_start = 0;
49147c6ae99SBarry Smith 
49247c6ae99SBarry Smith   PetscFunctionBegin;
49347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
49447c6ae99SBarry Smith   if (ghosted) {
495aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
49647c6ae99SBarry Smith       if (dd->adarrayghostedout[i] == *iptr) {
49747c6ae99SBarry Smith         iarray_start             = dd->adstartghostedout[i];
49847c6ae99SBarry Smith         dd->adarrayghostedout[i] = PETSC_NULL;
49947c6ae99SBarry Smith         dd->adstartghostedout[i] = PETSC_NULL;
50047c6ae99SBarry Smith         break;
50147c6ae99SBarry Smith       }
50247c6ae99SBarry Smith     }
50347c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
504aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
50547c6ae99SBarry Smith       if (!dd->adarrayghostedin[i]){
50647c6ae99SBarry Smith         dd->adarrayghostedin[i] = *iptr;
50747c6ae99SBarry Smith         dd->adstartghostedin[i] = iarray_start;
50847c6ae99SBarry Smith         break;
50947c6ae99SBarry Smith       }
51047c6ae99SBarry Smith     }
51147c6ae99SBarry Smith   } else {
512aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
51347c6ae99SBarry Smith       if (dd->adarrayout[i] == *iptr) {
51447c6ae99SBarry Smith         iarray_start      = dd->adstartout[i];
51547c6ae99SBarry Smith         dd->adarrayout[i] = PETSC_NULL;
51647c6ae99SBarry Smith         dd->adstartout[i] = PETSC_NULL;
51747c6ae99SBarry Smith         break;
51847c6ae99SBarry Smith       }
51947c6ae99SBarry Smith     }
52047c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
521aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
52247c6ae99SBarry Smith       if (!dd->adarrayin[i]){
52347c6ae99SBarry Smith         dd->adarrayin[i]   = *iptr;
52447c6ae99SBarry Smith         dd->adstartin[i]   = iarray_start;
52547c6ae99SBarry Smith         break;
52647c6ae99SBarry Smith       }
52747c6ae99SBarry Smith     }
52847c6ae99SBarry Smith   }
52947c6ae99SBarry Smith   PetscFunctionReturn(0);
53047c6ae99SBarry Smith }
53147c6ae99SBarry Smith 
53247c6ae99SBarry Smith #undef __FUNCT__
53347c6ae99SBarry Smith #define __FUNCT__ "ad_DAGetArray"
5347087cfbeSBarry Smith PetscErrorCode  ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
53547c6ae99SBarry Smith {
53647c6ae99SBarry Smith   PetscErrorCode ierr;
53747c6ae99SBarry Smith   PetscFunctionBegin;
538aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
53947c6ae99SBarry Smith   PetscFunctionReturn(0);
54047c6ae99SBarry Smith }
54147c6ae99SBarry Smith 
54247c6ae99SBarry Smith #undef __FUNCT__
54347c6ae99SBarry Smith #define __FUNCT__ "ad_DARestoreArray"
5447087cfbeSBarry Smith PetscErrorCode  ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
54547c6ae99SBarry Smith {
54647c6ae99SBarry Smith   PetscErrorCode ierr;
54747c6ae99SBarry Smith   PetscFunctionBegin;
548aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
54947c6ae99SBarry Smith   PetscFunctionReturn(0);
55047c6ae99SBarry Smith }
55147c6ae99SBarry Smith 
55247c6ae99SBarry Smith #endif
55347c6ae99SBarry Smith 
55447c6ae99SBarry Smith #undef __FUNCT__
555aa219208SBarry Smith #define __FUNCT__ "DMDAGetArray"
55647c6ae99SBarry Smith /*@C
557aa219208SBarry Smith      DMDAGetArray - Gets a work array for a DMDA
55847c6ae99SBarry Smith 
55947c6ae99SBarry Smith     Input Parameter:
56047c6ae99SBarry Smith +    da - information about my local patch
56147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch
56247c6ae99SBarry Smith 
56347c6ae99SBarry Smith     Output Parameters:
56447c6ae99SBarry Smith .    vptr - array data structured
56547c6ae99SBarry Smith 
56647c6ae99SBarry Smith     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
56747c6ae99SBarry Smith            to zero them.
56847c6ae99SBarry Smith 
56947c6ae99SBarry Smith   Level: advanced
57047c6ae99SBarry Smith 
571aa219208SBarry Smith .seealso: DMDARestoreArray(), DMDAGetAdicArray()
57247c6ae99SBarry Smith 
57347c6ae99SBarry Smith @*/
5747087cfbeSBarry Smith PetscErrorCode  DMDAGetArray(DM da,PetscBool  ghosted,void *vptr)
57547c6ae99SBarry Smith {
57647c6ae99SBarry Smith   PetscErrorCode ierr;
57747c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
57847c6ae99SBarry Smith   char           *iarray_start;
57947c6ae99SBarry Smith   void           **iptr = (void**)vptr;
58047c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
58147c6ae99SBarry Smith 
58247c6ae99SBarry Smith   PetscFunctionBegin;
58347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
58447c6ae99SBarry Smith   if (ghosted) {
585aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
58647c6ae99SBarry Smith       if (dd->arrayghostedin[i]) {
58747c6ae99SBarry Smith         *iptr                 = dd->arrayghostedin[i];
58847c6ae99SBarry Smith         iarray_start          = (char*)dd->startghostedin[i];
58947c6ae99SBarry Smith         dd->arrayghostedin[i] = PETSC_NULL;
59047c6ae99SBarry Smith         dd->startghostedin[i] = PETSC_NULL;
59147c6ae99SBarry Smith 
59247c6ae99SBarry Smith         goto done;
59347c6ae99SBarry Smith       }
59447c6ae99SBarry Smith     }
59547c6ae99SBarry Smith     xs = dd->Xs;
59647c6ae99SBarry Smith     ys = dd->Ys;
59747c6ae99SBarry Smith     zs = dd->Zs;
59847c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
59947c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
60047c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
60147c6ae99SBarry Smith   } else {
602aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
60347c6ae99SBarry Smith       if (dd->arrayin[i]) {
60447c6ae99SBarry Smith         *iptr          = dd->arrayin[i];
60547c6ae99SBarry Smith         iarray_start   = (char*)dd->startin[i];
60647c6ae99SBarry Smith         dd->arrayin[i] = PETSC_NULL;
60747c6ae99SBarry Smith         dd->startin[i] = PETSC_NULL;
60847c6ae99SBarry Smith 
60947c6ae99SBarry Smith         goto done;
61047c6ae99SBarry Smith       }
61147c6ae99SBarry Smith     }
61247c6ae99SBarry Smith     xs = dd->xs;
61347c6ae99SBarry Smith     ys = dd->ys;
61447c6ae99SBarry Smith     zs = dd->zs;
61547c6ae99SBarry Smith     xm = dd->xe-dd->xs;
61647c6ae99SBarry Smith     ym = dd->ye-dd->ys;
61747c6ae99SBarry Smith     zm = dd->ze-dd->zs;
61847c6ae99SBarry Smith   }
61947c6ae99SBarry Smith 
62047c6ae99SBarry Smith   switch (dd->dim) {
62147c6ae99SBarry Smith     case 1: {
62247c6ae99SBarry Smith       void *ptr;
62347c6ae99SBarry Smith 
62447c6ae99SBarry Smith       ierr  = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
62547c6ae99SBarry Smith 
62647c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
62747c6ae99SBarry Smith       *iptr = (void*)ptr;
62847c6ae99SBarry Smith       break;}
62947c6ae99SBarry Smith     case 2: {
63047c6ae99SBarry Smith       void **ptr;
63147c6ae99SBarry Smith 
63247c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
63347c6ae99SBarry Smith 
63447c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
63547c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
63647c6ae99SBarry Smith         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
63747c6ae99SBarry Smith       }
63847c6ae99SBarry Smith       *iptr = (void*)ptr;
63947c6ae99SBarry Smith       break;}
64047c6ae99SBarry Smith     case 3: {
64147c6ae99SBarry Smith       void ***ptr,**bptr;
64247c6ae99SBarry Smith 
64347c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
64447c6ae99SBarry Smith 
64547c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
64647c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
64747c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
64847c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym - ys);
64947c6ae99SBarry Smith       }
65047c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
65147c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
65247c6ae99SBarry Smith           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
65347c6ae99SBarry Smith         }
65447c6ae99SBarry Smith       }
65547c6ae99SBarry Smith 
65647c6ae99SBarry Smith       *iptr = (void*)ptr;
65747c6ae99SBarry Smith       break;}
65847c6ae99SBarry Smith     default:
65947c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
66047c6ae99SBarry Smith   }
66147c6ae99SBarry Smith 
66247c6ae99SBarry Smith   done:
66347c6ae99SBarry Smith   /* add arrays to the checked out list */
66447c6ae99SBarry Smith   if (ghosted) {
665aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
66647c6ae99SBarry Smith       if (!dd->arrayghostedout[i]) {
66747c6ae99SBarry Smith         dd->arrayghostedout[i] = *iptr ;
66847c6ae99SBarry Smith         dd->startghostedout[i] = iarray_start;
66947c6ae99SBarry Smith         break;
67047c6ae99SBarry Smith       }
67147c6ae99SBarry Smith     }
67247c6ae99SBarry Smith   } else {
673aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
67447c6ae99SBarry Smith       if (!dd->arrayout[i]) {
67547c6ae99SBarry Smith         dd->arrayout[i] = *iptr ;
67647c6ae99SBarry Smith         dd->startout[i] = iarray_start;
67747c6ae99SBarry Smith         break;
67847c6ae99SBarry Smith       }
67947c6ae99SBarry Smith     }
68047c6ae99SBarry Smith   }
68147c6ae99SBarry Smith   PetscFunctionReturn(0);
68247c6ae99SBarry Smith }
68347c6ae99SBarry Smith 
68447c6ae99SBarry Smith #undef __FUNCT__
685aa219208SBarry Smith #define __FUNCT__ "DMDARestoreArray"
68647c6ae99SBarry Smith /*@C
687aa219208SBarry Smith      DMDARestoreArray - Restores an array of derivative types for a DMDA
68847c6ae99SBarry Smith 
68947c6ae99SBarry Smith     Input Parameter:
69047c6ae99SBarry Smith +    da - information about my local patch
69147c6ae99SBarry Smith .    ghosted - do you want arrays for the ghosted or nonghosted patch
69247c6ae99SBarry Smith -    vptr - array data structured to be passed to ad_FormFunctionLocal()
69347c6ae99SBarry Smith 
69447c6ae99SBarry Smith      Level: advanced
69547c6ae99SBarry Smith 
696aa219208SBarry Smith .seealso: DMDAGetArray(), DMDAGetAdicArray()
69747c6ae99SBarry Smith 
69847c6ae99SBarry Smith @*/
6997087cfbeSBarry Smith PetscErrorCode  DMDARestoreArray(DM da,PetscBool  ghosted,void *vptr)
70047c6ae99SBarry Smith {
70147c6ae99SBarry Smith   PetscInt  i;
70247c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
70347c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
70447c6ae99SBarry Smith 
70547c6ae99SBarry Smith   PetscFunctionBegin;
70647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
70747c6ae99SBarry Smith   if (ghosted) {
708aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
70947c6ae99SBarry Smith       if (dd->arrayghostedout[i] == *iptr) {
71047c6ae99SBarry Smith         iarray_start           = dd->startghostedout[i];
71147c6ae99SBarry Smith         dd->arrayghostedout[i] = PETSC_NULL;
71247c6ae99SBarry Smith         dd->startghostedout[i] = PETSC_NULL;
71347c6ae99SBarry Smith         break;
71447c6ae99SBarry Smith       }
71547c6ae99SBarry Smith     }
716aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
71747c6ae99SBarry Smith       if (!dd->arrayghostedin[i]){
71847c6ae99SBarry Smith         dd->arrayghostedin[i] = *iptr;
71947c6ae99SBarry Smith         dd->startghostedin[i] = iarray_start;
72047c6ae99SBarry Smith         break;
72147c6ae99SBarry Smith       }
72247c6ae99SBarry Smith     }
72347c6ae99SBarry Smith   } else {
724aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
72547c6ae99SBarry Smith       if (dd->arrayout[i] == *iptr) {
72647c6ae99SBarry Smith         iarray_start    = dd->startout[i];
72747c6ae99SBarry Smith         dd->arrayout[i] = PETSC_NULL;
72847c6ae99SBarry Smith         dd->startout[i] = PETSC_NULL;
72947c6ae99SBarry Smith         break;
73047c6ae99SBarry Smith       }
73147c6ae99SBarry Smith     }
732aa219208SBarry Smith     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
73347c6ae99SBarry Smith       if (!dd->arrayin[i]){
73447c6ae99SBarry Smith         dd->arrayin[i]  = *iptr;
73547c6ae99SBarry Smith         dd->startin[i]  = iarray_start;
73647c6ae99SBarry Smith         break;
73747c6ae99SBarry Smith       }
73847c6ae99SBarry Smith     }
73947c6ae99SBarry Smith   }
74047c6ae99SBarry Smith   PetscFunctionReturn(0);
74147c6ae99SBarry Smith }
74247c6ae99SBarry Smith 
74347c6ae99SBarry Smith #undef __FUNCT__
744aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray"
74547c6ae99SBarry Smith /*@C
746aa219208SBarry Smith      DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
74747c6ae99SBarry Smith 
74847c6ae99SBarry Smith      Input Parameter:
74947c6ae99SBarry Smith +    da - information about my local patch
75047c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
75147c6ae99SBarry Smith 
75247c6ae99SBarry Smith      Output Parameters:
75347c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
75447c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
75547c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
75647c6ae99SBarry Smith 
75747c6ae99SBarry Smith      Notes:
75847c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
75947c6ae99SBarry Smith      to zero them.
76047c6ae99SBarry Smith 
761aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
76247c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
76347c6ae99SBarry Smith 
76447c6ae99SBarry Smith      Level: advanced
76547c6ae99SBarry Smith 
766aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
76747c6ae99SBarry Smith 
76847c6ae99SBarry Smith @*/
7697087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
77047c6ae99SBarry Smith {
77147c6ae99SBarry Smith   PetscErrorCode ierr;
77247c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
77347c6ae99SBarry Smith   char           *iarray_start;
77447c6ae99SBarry Smith   void           **iptr = (void**)vptr;
77547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
77647c6ae99SBarry Smith 
77747c6ae99SBarry Smith   PetscFunctionBegin;
77847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
77947c6ae99SBarry Smith   if (ghosted) {
780aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
78147c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
78247c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
78347c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
78447c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
78547c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
78647c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
78747c6ae99SBarry Smith 
78847c6ae99SBarry Smith         goto done;
78947c6ae99SBarry Smith       }
79047c6ae99SBarry Smith     }
79147c6ae99SBarry Smith     xs = dd->Xs;
79247c6ae99SBarry Smith     ys = dd->Ys;
79347c6ae99SBarry Smith     zs = dd->Zs;
79447c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
79547c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
79647c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
79747c6ae99SBarry Smith   } else {
798aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
79947c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
80047c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
80147c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
80247c6ae99SBarry Smith         itdof              = dd->tdof;
80347c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
80447c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
80547c6ae99SBarry Smith 
80647c6ae99SBarry Smith         goto done;
80747c6ae99SBarry Smith       }
80847c6ae99SBarry Smith     }
80947c6ae99SBarry Smith     xs = dd->xs;
81047c6ae99SBarry Smith     ys = dd->ys;
81147c6ae99SBarry Smith     zs = dd->zs;
81247c6ae99SBarry Smith     xm = dd->xe-dd->xs;
81347c6ae99SBarry Smith     ym = dd->ye-dd->ys;
81447c6ae99SBarry Smith     zm = dd->ze-dd->zs;
81547c6ae99SBarry Smith   }
81647c6ae99SBarry Smith 
81747c6ae99SBarry Smith   switch (dd->dim) {
81847c6ae99SBarry Smith     case 1: {
81947c6ae99SBarry Smith       void *ptr;
82047c6ae99SBarry Smith       itdof = xm;
82147c6ae99SBarry Smith 
82247c6ae99SBarry Smith       ierr  = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
82347c6ae99SBarry Smith 
82447c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
82547c6ae99SBarry Smith       *iptr = (void*)ptr;
82647c6ae99SBarry Smith       break;}
82747c6ae99SBarry Smith     case 2: {
82847c6ae99SBarry Smith       void **ptr;
82947c6ae99SBarry Smith       itdof = xm*ym;
83047c6ae99SBarry Smith 
83147c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
83247c6ae99SBarry Smith 
83347c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
83447c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
83547c6ae99SBarry Smith         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
83647c6ae99SBarry Smith       }
83747c6ae99SBarry Smith       *iptr = (void*)ptr;
83847c6ae99SBarry Smith       break;}
83947c6ae99SBarry Smith     case 3: {
84047c6ae99SBarry Smith       void ***ptr,**bptr;
84147c6ae99SBarry Smith       itdof = xm*ym*zm;
84247c6ae99SBarry Smith 
84347c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
84447c6ae99SBarry Smith 
84547c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
84647c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
84747c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
84847c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
84947c6ae99SBarry Smith       }
85047c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
85147c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
85247c6ae99SBarry Smith           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
85347c6ae99SBarry Smith         }
85447c6ae99SBarry Smith       }
85547c6ae99SBarry Smith 
85647c6ae99SBarry Smith       *iptr = (void*)ptr;
85747c6ae99SBarry Smith       break;}
85847c6ae99SBarry Smith     default:
85947c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
86047c6ae99SBarry Smith   }
86147c6ae99SBarry Smith 
86247c6ae99SBarry Smith   done:
86347c6ae99SBarry Smith   /* add arrays to the checked out list */
86447c6ae99SBarry Smith   if (ghosted) {
865aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
86647c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
86747c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
86847c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
86947c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
87047c6ae99SBarry Smith         break;
87147c6ae99SBarry Smith       }
87247c6ae99SBarry Smith     }
87347c6ae99SBarry Smith   } else {
874aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
87547c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
87647c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
87747c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
87847c6ae99SBarry Smith         dd->tdof            = itdof;
87947c6ae99SBarry Smith         break;
88047c6ae99SBarry Smith       }
88147c6ae99SBarry Smith     }
88247c6ae99SBarry Smith   }
883aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
88447c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
88547c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
88647c6ae99SBarry Smith   PetscFunctionReturn(0);
88747c6ae99SBarry Smith }
88847c6ae99SBarry Smith 
88947c6ae99SBarry Smith #undef __FUNCT__
890aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray4"
8917087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
89247c6ae99SBarry Smith {
89347c6ae99SBarry Smith   PetscErrorCode ierr;
89447c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
89547c6ae99SBarry Smith   char           *iarray_start;
89647c6ae99SBarry Smith   void           **iptr = (void**)vptr;
89747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
89847c6ae99SBarry Smith 
89947c6ae99SBarry Smith   PetscFunctionBegin;
90047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
90147c6ae99SBarry Smith   if (ghosted) {
902aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
90347c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
90447c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
90547c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
90647c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
90747c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
90847c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
90947c6ae99SBarry Smith 
91047c6ae99SBarry Smith         goto done;
91147c6ae99SBarry Smith       }
91247c6ae99SBarry Smith     }
91347c6ae99SBarry Smith     xs = dd->Xs;
91447c6ae99SBarry Smith     ys = dd->Ys;
91547c6ae99SBarry Smith     zs = dd->Zs;
91647c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
91747c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
91847c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
91947c6ae99SBarry Smith   } else {
920aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
92147c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
92247c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
92347c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
92447c6ae99SBarry Smith         itdof              = dd->tdof;
92547c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
92647c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
92747c6ae99SBarry Smith 
92847c6ae99SBarry Smith         goto done;
92947c6ae99SBarry Smith       }
93047c6ae99SBarry Smith     }
93147c6ae99SBarry Smith     xs = dd->xs;
93247c6ae99SBarry Smith     ys = dd->ys;
93347c6ae99SBarry Smith     zs = dd->zs;
93447c6ae99SBarry Smith     xm = dd->xe-dd->xs;
93547c6ae99SBarry Smith     ym = dd->ye-dd->ys;
93647c6ae99SBarry Smith     zm = dd->ze-dd->zs;
93747c6ae99SBarry Smith   }
93847c6ae99SBarry Smith 
93947c6ae99SBarry Smith   switch (dd->dim) {
94047c6ae99SBarry Smith     case 2: {
94147c6ae99SBarry Smith       void **ptr;
94247c6ae99SBarry Smith       itdof = xm*ym;
94347c6ae99SBarry Smith 
94447c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
94547c6ae99SBarry Smith 
94647c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
94747c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
94847c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
94947c6ae99SBarry Smith       }
95047c6ae99SBarry Smith       *iptr = (void*)ptr;
95147c6ae99SBarry Smith       break;}
95247c6ae99SBarry Smith     default:
95347c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
95447c6ae99SBarry Smith   }
95547c6ae99SBarry Smith 
95647c6ae99SBarry Smith   done:
95747c6ae99SBarry Smith   /* add arrays to the checked out list */
95847c6ae99SBarry Smith   if (ghosted) {
959aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
96047c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
96147c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
96247c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
96347c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
96447c6ae99SBarry Smith         break;
96547c6ae99SBarry Smith       }
96647c6ae99SBarry Smith     }
96747c6ae99SBarry Smith   } else {
968aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
96947c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
97047c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
97147c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
97247c6ae99SBarry Smith         dd->tdof            = itdof;
97347c6ae99SBarry Smith         break;
97447c6ae99SBarry Smith       }
97547c6ae99SBarry Smith     }
97647c6ae99SBarry Smith   }
977aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
97847c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
97947c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
98047c6ae99SBarry Smith   PetscFunctionReturn(0);
98147c6ae99SBarry Smith }
98247c6ae99SBarry Smith 
98347c6ae99SBarry Smith #undef __FUNCT__
984aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9"
9857087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
98647c6ae99SBarry Smith {
98747c6ae99SBarry Smith   PetscErrorCode ierr;
98847c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
98947c6ae99SBarry Smith   char           *iarray_start;
99047c6ae99SBarry Smith   void           **iptr = (void**)vptr;
99147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
99247c6ae99SBarry Smith 
99347c6ae99SBarry Smith   PetscFunctionBegin;
99447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
99547c6ae99SBarry Smith   if (ghosted) {
996aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
99747c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
99847c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
99947c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
100047c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
100147c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
100247c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
100347c6ae99SBarry Smith 
100447c6ae99SBarry Smith         goto done;
100547c6ae99SBarry Smith       }
100647c6ae99SBarry Smith     }
100747c6ae99SBarry Smith     xs = dd->Xs;
100847c6ae99SBarry Smith     ys = dd->Ys;
100947c6ae99SBarry Smith     zs = dd->Zs;
101047c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
101147c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
101247c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
101347c6ae99SBarry Smith   } else {
1014aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
101547c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
101647c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
101747c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
101847c6ae99SBarry Smith         itdof              = dd->tdof;
101947c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
102047c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
102147c6ae99SBarry Smith 
102247c6ae99SBarry Smith         goto done;
102347c6ae99SBarry Smith       }
102447c6ae99SBarry Smith     }
102547c6ae99SBarry Smith     xs = dd->xs;
102647c6ae99SBarry Smith     ys = dd->ys;
102747c6ae99SBarry Smith     zs = dd->zs;
102847c6ae99SBarry Smith     xm = dd->xe-dd->xs;
102947c6ae99SBarry Smith     ym = dd->ye-dd->ys;
103047c6ae99SBarry Smith     zm = dd->ze-dd->zs;
103147c6ae99SBarry Smith   }
103247c6ae99SBarry Smith 
103347c6ae99SBarry Smith   switch (dd->dim) {
103447c6ae99SBarry Smith     case 2: {
103547c6ae99SBarry Smith       void **ptr;
103647c6ae99SBarry Smith       itdof = xm*ym;
103747c6ae99SBarry Smith 
103847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
103947c6ae99SBarry Smith 
104047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
104147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
104247c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
104347c6ae99SBarry Smith       }
104447c6ae99SBarry Smith       *iptr = (void*)ptr;
104547c6ae99SBarry Smith       break;}
104647c6ae99SBarry Smith     default:
104747c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
104847c6ae99SBarry Smith   }
104947c6ae99SBarry Smith 
105047c6ae99SBarry Smith   done:
105147c6ae99SBarry Smith   /* add arrays to the checked out list */
105247c6ae99SBarry Smith   if (ghosted) {
1053aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
105447c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
105547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
105647c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
105747c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
105847c6ae99SBarry Smith         break;
105947c6ae99SBarry Smith       }
106047c6ae99SBarry Smith     }
106147c6ae99SBarry Smith   } else {
1062aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
106347c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
106447c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
106547c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
106647c6ae99SBarry Smith         dd->tdof            = itdof;
106747c6ae99SBarry Smith         break;
106847c6ae99SBarry Smith       }
106947c6ae99SBarry Smith     }
107047c6ae99SBarry Smith   }
1071aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
107247c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
107347c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
107447c6ae99SBarry Smith   PetscFunctionReturn(0);
107547c6ae99SBarry Smith }
107647c6ae99SBarry Smith 
107747c6ae99SBarry Smith #undef __FUNCT__
1078aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb"
107947c6ae99SBarry Smith /*@C
1080aa219208SBarry Smith      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
108147c6ae99SBarry Smith 
108247c6ae99SBarry Smith      Input Parameter:
108347c6ae99SBarry Smith +    da - information about my local patch
108447c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
108547c6ae99SBarry Smith 
108647c6ae99SBarry Smith      Output Parameters:
108747c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
108847c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
108947c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
109047c6ae99SBarry Smith 
109147c6ae99SBarry Smith      Notes:
109247c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
109347c6ae99SBarry Smith      to zero them.
109447c6ae99SBarry Smith 
1095aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
109647c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
109747c6ae99SBarry Smith 
109847c6ae99SBarry Smith      Level: advanced
109947c6ae99SBarry Smith 
1100aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
110147c6ae99SBarry Smith 
110247c6ae99SBarry Smith @*/
11037087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
110447c6ae99SBarry Smith {
110547c6ae99SBarry Smith   PetscErrorCode ierr;
110647c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
110747c6ae99SBarry Smith   char           *iarray_start;
110847c6ae99SBarry Smith   void           **iptr = (void**)vptr;
110947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
111047c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
111147c6ae99SBarry Smith 
111247c6ae99SBarry Smith   PetscFunctionBegin;
111347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
111447c6ae99SBarry Smith   if (ghosted) {
1115aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
111647c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
111747c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
111847c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
111947c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
112047c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
112147c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
112247c6ae99SBarry Smith 
112347c6ae99SBarry Smith         goto done;
112447c6ae99SBarry Smith       }
112547c6ae99SBarry Smith     }
112647c6ae99SBarry Smith     xs = dd->Xs;
112747c6ae99SBarry Smith     ys = dd->Ys;
112847c6ae99SBarry Smith     zs = dd->Zs;
112947c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
113047c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
113147c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
113247c6ae99SBarry Smith   } else {
1133aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
113447c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
113547c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
113647c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
113747c6ae99SBarry Smith         itdof              = dd->tdof;
113847c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
113947c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
114047c6ae99SBarry Smith 
114147c6ae99SBarry Smith         goto done;
114247c6ae99SBarry Smith       }
114347c6ae99SBarry Smith     }
114447c6ae99SBarry Smith     xs = dd->xs;
114547c6ae99SBarry Smith     ys = dd->ys;
114647c6ae99SBarry Smith     zs = dd->zs;
114747c6ae99SBarry Smith     xm = dd->xe-dd->xs;
114847c6ae99SBarry Smith     ym = dd->ye-dd->ys;
114947c6ae99SBarry Smith     zm = dd->ze-dd->zs;
115047c6ae99SBarry Smith   }
115147c6ae99SBarry Smith 
115247c6ae99SBarry Smith   switch (dd->dim) {
115347c6ae99SBarry Smith     case 1: {
115447c6ae99SBarry Smith       void *ptr;
115547c6ae99SBarry Smith       itdof = xm;
115647c6ae99SBarry Smith 
115747c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
115847c6ae99SBarry Smith 
115947c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
116047c6ae99SBarry Smith       *iptr = (void*)ptr;
116147c6ae99SBarry Smith       break;}
116247c6ae99SBarry Smith     case 2: {
116347c6ae99SBarry Smith       void **ptr;
116447c6ae99SBarry Smith       itdof = xm*ym;
116547c6ae99SBarry Smith 
116647c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
116747c6ae99SBarry Smith 
116847c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
116947c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
117047c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
117147c6ae99SBarry Smith       }
117247c6ae99SBarry Smith       *iptr = (void*)ptr;
117347c6ae99SBarry Smith       break;}
117447c6ae99SBarry Smith     case 3: {
117547c6ae99SBarry Smith       void ***ptr,**bptr;
117647c6ae99SBarry Smith       itdof = xm*ym*zm;
117747c6ae99SBarry Smith 
117847c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
117947c6ae99SBarry Smith 
118047c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
118147c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
118247c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
118347c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
118447c6ae99SBarry Smith       }
118547c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
118647c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
118747c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
118847c6ae99SBarry Smith         }
118947c6ae99SBarry Smith       }
119047c6ae99SBarry Smith 
119147c6ae99SBarry Smith       *iptr = (void*)ptr;
119247c6ae99SBarry Smith       break;}
119347c6ae99SBarry Smith     default:
119447c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
119547c6ae99SBarry Smith   }
119647c6ae99SBarry Smith 
119747c6ae99SBarry Smith   done:
119847c6ae99SBarry Smith   /* add arrays to the checked out list */
119947c6ae99SBarry Smith   if (ghosted) {
1200aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
120147c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
120247c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
120347c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
120447c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
120547c6ae99SBarry Smith         break;
120647c6ae99SBarry Smith       }
120747c6ae99SBarry Smith     }
120847c6ae99SBarry Smith   } else {
1209aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
121047c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
121147c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
121247c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
121347c6ae99SBarry Smith         dd->tdof            = itdof;
121447c6ae99SBarry Smith         break;
121547c6ae99SBarry Smith       }
121647c6ae99SBarry Smith     }
121747c6ae99SBarry Smith   }
1218aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
121947c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
122047c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
122147c6ae99SBarry Smith   PetscFunctionReturn(0);
122247c6ae99SBarry Smith }
122347c6ae99SBarry Smith 
122447c6ae99SBarry Smith #undef __FUNCT__
1225aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray"
122647c6ae99SBarry Smith /*@C
1227aa219208SBarry Smith      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
122847c6ae99SBarry Smith 
122947c6ae99SBarry Smith      Input Parameter:
123047c6ae99SBarry Smith +    da - information about my local patch
123147c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
123247c6ae99SBarry Smith 
123347c6ae99SBarry Smith      Output Parameters:
123447c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
123547c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
123647c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
123747c6ae99SBarry Smith 
123847c6ae99SBarry Smith      Level: advanced
123947c6ae99SBarry Smith 
1240aa219208SBarry Smith .seealso: DMDAGetAdicArray()
124147c6ae99SBarry Smith 
124247c6ae99SBarry Smith @*/
12437087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
124447c6ae99SBarry Smith {
124547c6ae99SBarry Smith   PetscInt  i;
124647c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
124747c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
124847c6ae99SBarry Smith 
124947c6ae99SBarry Smith   PetscFunctionBegin;
125047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
125147c6ae99SBarry Smith   if (ghosted) {
1252aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
125347c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
125447c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
125547c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
125647c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
125747c6ae99SBarry Smith         break;
125847c6ae99SBarry Smith       }
125947c6ae99SBarry Smith     }
126047c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1261aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
126247c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
126347c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
126447c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
126547c6ae99SBarry Smith         break;
126647c6ae99SBarry Smith       }
126747c6ae99SBarry Smith     }
126847c6ae99SBarry Smith   } else {
1269aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
127047c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
127147c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
127247c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
127347c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
127447c6ae99SBarry Smith         break;
127547c6ae99SBarry Smith       }
127647c6ae99SBarry Smith     }
127747c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1278aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
127947c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
128047c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
128147c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
128247c6ae99SBarry Smith         break;
128347c6ae99SBarry Smith       }
128447c6ae99SBarry Smith     }
128547c6ae99SBarry Smith   }
128647c6ae99SBarry Smith   PetscFunctionReturn(0);
128747c6ae99SBarry Smith }
128847c6ae99SBarry Smith 
128947c6ae99SBarry Smith #undef __FUNCT__
129047c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
12917087cfbeSBarry Smith PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
129247c6ae99SBarry Smith {
129347c6ae99SBarry Smith   PetscErrorCode ierr;
129447c6ae99SBarry Smith   PetscFunctionBegin;
1295aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
129647c6ae99SBarry Smith   PetscFunctionReturn(0);
129747c6ae99SBarry Smith }
129847c6ae99SBarry Smith 
129947c6ae99SBarry Smith #undef __FUNCT__
130047c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
13017087cfbeSBarry Smith PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
130247c6ae99SBarry Smith {
130347c6ae99SBarry Smith   PetscErrorCode ierr;
130447c6ae99SBarry Smith   PetscFunctionBegin;
1305aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
130647c6ae99SBarry Smith   PetscFunctionReturn(0);
130747c6ae99SBarry Smith }
130847c6ae99SBarry Smith 
1309