xref: /petsc/src/dm/impls/da/dalocal.c (revision b45d2f2cb7e031d9c0de5873eca80614ca7b863b)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6*b45d2f2cSJed Brown #include <petsc-private/daimpl.h>    /*I   "petscdmda.h"   I*/
747c6ae99SBarry Smith 
847c6ae99SBarry Smith /*
9e3c5b3baSBarry Smith    This allows the DMDA vectors to properly tell MATLAB their dimensions
1047c6ae99SBarry Smith */
1147c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
12c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
13c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
1447c6ae99SBarry Smith EXTERN_C_BEGIN
1547c6ae99SBarry Smith #undef __FUNCT__
1647c6ae99SBarry Smith #define __FUNCT__ "VecMatlabEnginePut_DA2d"
177087cfbeSBarry Smith PetscErrorCode  VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine)
1847c6ae99SBarry Smith {
1947c6ae99SBarry Smith   PetscErrorCode ierr;
2047c6ae99SBarry Smith   PetscInt       n,m;
2147c6ae99SBarry Smith   Vec            vec = (Vec)obj;
2247c6ae99SBarry Smith   PetscScalar    *array;
2347c6ae99SBarry Smith   mxArray        *mat;
249a42bb27SBarry Smith   DM             da;
2547c6ae99SBarry Smith 
2647c6ae99SBarry Smith   PetscFunctionBegin;
273c0c59f3SBarry Smith   ierr = PetscObjectQuery((PetscObject)vec,"DM",(PetscObject*)&da);CHKERRQ(ierr);
28aa219208SBarry Smith   if (!da) SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA");
29aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr);
3047c6ae99SBarry Smith 
3147c6ae99SBarry Smith   ierr = VecGetArray(vec,&array);CHKERRQ(ierr);
3247c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
3347c6ae99SBarry Smith   mat  = mxCreateDoubleMatrix(m,n,mxREAL);
3447c6ae99SBarry Smith #else
3547c6ae99SBarry Smith   mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
3647c6ae99SBarry Smith #endif
3747c6ae99SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr);
3847c6ae99SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
3947c6ae99SBarry Smith   engPutVariable((Engine *)mengine,obj->name,mat);
4047c6ae99SBarry Smith 
4147c6ae99SBarry Smith   ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr);
4247c6ae99SBarry Smith   PetscFunctionReturn(0);
4347c6ae99SBarry Smith }
4447c6ae99SBarry Smith EXTERN_C_END
4547c6ae99SBarry Smith #endif
4647c6ae99SBarry Smith 
4747c6ae99SBarry Smith 
4847c6ae99SBarry Smith #undef __FUNCT__
49564755cdSBarry Smith #define __FUNCT__ "DMCreateLocalVector_DA"
507087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_DA(DM da,Vec* g)
5147c6ae99SBarry Smith {
5247c6ae99SBarry Smith   PetscErrorCode ierr;
5347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
5447c6ae99SBarry Smith 
5547c6ae99SBarry Smith   PetscFunctionBegin;
5647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
5747c6ae99SBarry Smith   PetscValidPointer(g,2);
5847c6ae99SBarry Smith   ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr);
5947c6ae99SBarry Smith   ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
6047c6ae99SBarry Smith   ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr);
6147c6ae99SBarry Smith   ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr);
623c0c59f3SBarry Smith   ierr = PetscObjectCompose((PetscObject)*g,"DM",(PetscObject)da);CHKERRQ(ierr);
6347c6ae99SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
6447c6ae99SBarry Smith   if (dd->w == 1  && dd->dim == 2) {
6547c6ae99SBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr);
6647c6ae99SBarry Smith   }
6747c6ae99SBarry Smith #endif
6847c6ae99SBarry Smith   PetscFunctionReturn(0);
6947c6ae99SBarry Smith }
7047c6ae99SBarry Smith 
7147c6ae99SBarry Smith #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;
89487130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,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     xm = dd->Xe-dd->Xs;
91647c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
91747c6ae99SBarry Smith   } else {
918aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
91947c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
92047c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
92147c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
92247c6ae99SBarry Smith         itdof              = dd->tdof;
92347c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
92447c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
92547c6ae99SBarry Smith 
92647c6ae99SBarry Smith         goto done;
92747c6ae99SBarry Smith       }
92847c6ae99SBarry Smith     }
92947c6ae99SBarry Smith     xs = dd->xs;
93047c6ae99SBarry Smith     ys = dd->ys;
93147c6ae99SBarry Smith     xm = dd->xe-dd->xs;
93247c6ae99SBarry Smith     ym = dd->ye-dd->ys;
93347c6ae99SBarry Smith   }
93447c6ae99SBarry Smith 
93547c6ae99SBarry Smith   switch (dd->dim) {
93647c6ae99SBarry Smith     case 2: {
93747c6ae99SBarry Smith       void **ptr;
93847c6ae99SBarry Smith       itdof = xm*ym;
93947c6ae99SBarry Smith 
94047c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
94147c6ae99SBarry Smith 
94247c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
94347c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
94447c6ae99SBarry Smith         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
94547c6ae99SBarry Smith       }
94647c6ae99SBarry Smith       *iptr = (void*)ptr;
94747c6ae99SBarry Smith       break;}
94847c6ae99SBarry Smith     default:
94947c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
95047c6ae99SBarry Smith   }
95147c6ae99SBarry Smith 
95247c6ae99SBarry Smith   done:
95347c6ae99SBarry Smith   /* add arrays to the checked out list */
95447c6ae99SBarry Smith   if (ghosted) {
955aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
95647c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
95747c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
95847c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
95947c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
96047c6ae99SBarry Smith         break;
96147c6ae99SBarry Smith       }
96247c6ae99SBarry Smith     }
96347c6ae99SBarry Smith   } else {
964aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
96547c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
96647c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
96747c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
96847c6ae99SBarry Smith         dd->tdof            = itdof;
96947c6ae99SBarry Smith         break;
97047c6ae99SBarry Smith       }
97147c6ae99SBarry Smith     }
97247c6ae99SBarry Smith   }
973aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
97447c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
97547c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
97647c6ae99SBarry Smith   PetscFunctionReturn(0);
97747c6ae99SBarry Smith }
97847c6ae99SBarry Smith 
97947c6ae99SBarry Smith #undef __FUNCT__
980aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArray9"
9817087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
98247c6ae99SBarry Smith {
98347c6ae99SBarry Smith   PetscErrorCode ierr;
98487130e5eSHong Zhang   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
98547c6ae99SBarry Smith   char           *iarray_start;
98647c6ae99SBarry Smith   void           **iptr = (void**)vptr;
98747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
98847c6ae99SBarry Smith 
98947c6ae99SBarry Smith   PetscFunctionBegin;
99047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
99147c6ae99SBarry Smith   if (ghosted) {
992aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
99347c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
99447c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
99547c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
99647c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
99747c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
99847c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
99947c6ae99SBarry Smith 
100047c6ae99SBarry Smith         goto done;
100147c6ae99SBarry Smith       }
100247c6ae99SBarry Smith     }
100347c6ae99SBarry Smith     xs = dd->Xs;
100447c6ae99SBarry Smith     ys = dd->Ys;
100547c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
100647c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
100747c6ae99SBarry Smith   } else {
1008aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
100947c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
101047c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
101147c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
101247c6ae99SBarry Smith         itdof              = dd->tdof;
101347c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
101447c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
101547c6ae99SBarry Smith 
101647c6ae99SBarry Smith         goto done;
101747c6ae99SBarry Smith       }
101847c6ae99SBarry Smith     }
101947c6ae99SBarry Smith     xs = dd->xs;
102047c6ae99SBarry Smith     ys = dd->ys;
102147c6ae99SBarry Smith     xm = dd->xe-dd->xs;
102247c6ae99SBarry Smith     ym = dd->ye-dd->ys;
102347c6ae99SBarry Smith   }
102447c6ae99SBarry Smith 
102547c6ae99SBarry Smith   switch (dd->dim) {
102647c6ae99SBarry Smith     case 2: {
102747c6ae99SBarry Smith       void **ptr;
102847c6ae99SBarry Smith       itdof = xm*ym;
102947c6ae99SBarry Smith 
103047c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
103147c6ae99SBarry Smith 
103247c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
103347c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
103447c6ae99SBarry Smith         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
103547c6ae99SBarry Smith       }
103647c6ae99SBarry Smith       *iptr = (void*)ptr;
103747c6ae99SBarry Smith       break;}
103847c6ae99SBarry Smith     default:
103947c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
104047c6ae99SBarry Smith   }
104147c6ae99SBarry Smith 
104247c6ae99SBarry Smith   done:
104347c6ae99SBarry Smith   /* add arrays to the checked out list */
104447c6ae99SBarry Smith   if (ghosted) {
1045aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
104647c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
104747c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
104847c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
104947c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
105047c6ae99SBarry Smith         break;
105147c6ae99SBarry Smith       }
105247c6ae99SBarry Smith     }
105347c6ae99SBarry Smith   } else {
1054aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
105547c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
105647c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
105747c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
105847c6ae99SBarry Smith         dd->tdof            = itdof;
105947c6ae99SBarry Smith         break;
106047c6ae99SBarry Smith       }
106147c6ae99SBarry Smith     }
106247c6ae99SBarry Smith   }
1063aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
106447c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
106547c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
106647c6ae99SBarry Smith   PetscFunctionReturn(0);
106747c6ae99SBarry Smith }
106847c6ae99SBarry Smith 
106947c6ae99SBarry Smith #undef __FUNCT__
1070aa219208SBarry Smith #define __FUNCT__ "DMDAGetAdicMFArrayb"
107147c6ae99SBarry Smith /*@C
1072aa219208SBarry Smith      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
107347c6ae99SBarry Smith 
107447c6ae99SBarry Smith      Input Parameter:
107547c6ae99SBarry Smith +    da - information about my local patch
107647c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
107747c6ae99SBarry Smith 
107847c6ae99SBarry Smith      Output Parameters:
107947c6ae99SBarry Smith +    vptr - array data structured to be passed to ad_FormFunctionLocal()
108047c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
108147c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start (may be null)
108247c6ae99SBarry Smith 
108347c6ae99SBarry Smith      Notes:
108447c6ae99SBarry Smith      The vector values are NOT initialized and may have garbage in them, so you may need
108547c6ae99SBarry Smith      to zero them.
108647c6ae99SBarry Smith 
1087aa219208SBarry Smith      This routine returns the same type of object as the DMDAVecGetArray(), except its
108847c6ae99SBarry Smith      elements are derivative types instead of PetscScalars.
108947c6ae99SBarry Smith 
109047c6ae99SBarry Smith      Level: advanced
109147c6ae99SBarry Smith 
1092aa219208SBarry Smith .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
109347c6ae99SBarry Smith 
109447c6ae99SBarry Smith @*/
10957087cfbeSBarry Smith PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
109647c6ae99SBarry Smith {
109747c6ae99SBarry Smith   PetscErrorCode ierr;
109847c6ae99SBarry Smith   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
109947c6ae99SBarry Smith   char           *iarray_start;
110047c6ae99SBarry Smith   void           **iptr = (void**)vptr;
110147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
110247c6ae99SBarry Smith   PetscInt       bs = dd->w,bs1 = bs+1;
110347c6ae99SBarry Smith 
110447c6ae99SBarry Smith   PetscFunctionBegin;
110547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
110647c6ae99SBarry Smith   if (ghosted) {
1107aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
110847c6ae99SBarry Smith       if (dd->admfarrayghostedin[i]) {
110947c6ae99SBarry Smith         *iptr                     = dd->admfarrayghostedin[i];
111047c6ae99SBarry Smith         iarray_start              = (char*)dd->admfstartghostedin[i];
111147c6ae99SBarry Smith         itdof                     = dd->ghostedtdof;
111247c6ae99SBarry Smith         dd->admfarrayghostedin[i] = PETSC_NULL;
111347c6ae99SBarry Smith         dd->admfstartghostedin[i] = PETSC_NULL;
111447c6ae99SBarry Smith 
111547c6ae99SBarry Smith         goto done;
111647c6ae99SBarry Smith       }
111747c6ae99SBarry Smith     }
111847c6ae99SBarry Smith     xs = dd->Xs;
111947c6ae99SBarry Smith     ys = dd->Ys;
112047c6ae99SBarry Smith     zs = dd->Zs;
112147c6ae99SBarry Smith     xm = dd->Xe-dd->Xs;
112247c6ae99SBarry Smith     ym = dd->Ye-dd->Ys;
112347c6ae99SBarry Smith     zm = dd->Ze-dd->Zs;
112447c6ae99SBarry Smith   } else {
1125aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
112647c6ae99SBarry Smith       if (dd->admfarrayin[i]) {
112747c6ae99SBarry Smith         *iptr              = dd->admfarrayin[i];
112847c6ae99SBarry Smith         iarray_start       = (char*)dd->admfstartin[i];
112947c6ae99SBarry Smith         itdof              = dd->tdof;
113047c6ae99SBarry Smith         dd->admfarrayin[i] = PETSC_NULL;
113147c6ae99SBarry Smith         dd->admfstartin[i] = PETSC_NULL;
113247c6ae99SBarry Smith 
113347c6ae99SBarry Smith         goto done;
113447c6ae99SBarry Smith       }
113547c6ae99SBarry Smith     }
113647c6ae99SBarry Smith     xs = dd->xs;
113747c6ae99SBarry Smith     ys = dd->ys;
113847c6ae99SBarry Smith     zs = dd->zs;
113947c6ae99SBarry Smith     xm = dd->xe-dd->xs;
114047c6ae99SBarry Smith     ym = dd->ye-dd->ys;
114147c6ae99SBarry Smith     zm = dd->ze-dd->zs;
114247c6ae99SBarry Smith   }
114347c6ae99SBarry Smith 
114447c6ae99SBarry Smith   switch (dd->dim) {
114547c6ae99SBarry Smith     case 1: {
114647c6ae99SBarry Smith       void *ptr;
114747c6ae99SBarry Smith       itdof = xm;
114847c6ae99SBarry Smith 
114947c6ae99SBarry Smith       ierr  = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
115047c6ae99SBarry Smith 
115147c6ae99SBarry Smith       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
115247c6ae99SBarry Smith       *iptr = (void*)ptr;
115347c6ae99SBarry Smith       break;}
115447c6ae99SBarry Smith     case 2: {
115547c6ae99SBarry Smith       void **ptr;
115647c6ae99SBarry Smith       itdof = xm*ym;
115747c6ae99SBarry Smith 
115847c6ae99SBarry Smith       ierr  = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
115947c6ae99SBarry Smith 
116047c6ae99SBarry Smith       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
116147c6ae99SBarry Smith       for(j=ys;j<ys+ym;j++) {
116247c6ae99SBarry Smith         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
116347c6ae99SBarry Smith       }
116447c6ae99SBarry Smith       *iptr = (void*)ptr;
116547c6ae99SBarry Smith       break;}
116647c6ae99SBarry Smith     case 3: {
116747c6ae99SBarry Smith       void ***ptr,**bptr;
116847c6ae99SBarry Smith       itdof = xm*ym*zm;
116947c6ae99SBarry Smith 
117047c6ae99SBarry Smith       ierr  = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr);
117147c6ae99SBarry Smith 
117247c6ae99SBarry Smith       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
117347c6ae99SBarry Smith       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
117447c6ae99SBarry Smith       for(i=zs;i<zs+zm;i++) {
117547c6ae99SBarry Smith         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
117647c6ae99SBarry Smith       }
117747c6ae99SBarry Smith       for (i=zs; i<zs+zm; i++) {
117847c6ae99SBarry Smith         for (j=ys; j<ys+ym; j++) {
117947c6ae99SBarry Smith           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
118047c6ae99SBarry Smith         }
118147c6ae99SBarry Smith       }
118247c6ae99SBarry Smith 
118347c6ae99SBarry Smith       *iptr = (void*)ptr;
118447c6ae99SBarry Smith       break;}
118547c6ae99SBarry Smith     default:
118647c6ae99SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
118747c6ae99SBarry Smith   }
118847c6ae99SBarry Smith 
118947c6ae99SBarry Smith   done:
119047c6ae99SBarry Smith   /* add arrays to the checked out list */
119147c6ae99SBarry Smith   if (ghosted) {
1192aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
119347c6ae99SBarry Smith       if (!dd->admfarrayghostedout[i]) {
119447c6ae99SBarry Smith         dd->admfarrayghostedout[i] = *iptr ;
119547c6ae99SBarry Smith         dd->admfstartghostedout[i] = iarray_start;
119647c6ae99SBarry Smith         dd->ghostedtdof            = itdof;
119747c6ae99SBarry Smith         break;
119847c6ae99SBarry Smith       }
119947c6ae99SBarry Smith     }
120047c6ae99SBarry Smith   } else {
1201aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
120247c6ae99SBarry Smith       if (!dd->admfarrayout[i]) {
120347c6ae99SBarry Smith         dd->admfarrayout[i] = *iptr ;
120447c6ae99SBarry Smith         dd->admfstartout[i] = iarray_start;
120547c6ae99SBarry Smith         dd->tdof            = itdof;
120647c6ae99SBarry Smith         break;
120747c6ae99SBarry Smith       }
120847c6ae99SBarry Smith     }
120947c6ae99SBarry Smith   }
1210aa219208SBarry Smith   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
121147c6ae99SBarry Smith   if (tdof)        *tdof = itdof;
121247c6ae99SBarry Smith   if (array_start) *(void**)array_start = iarray_start;
121347c6ae99SBarry Smith   PetscFunctionReturn(0);
121447c6ae99SBarry Smith }
121547c6ae99SBarry Smith 
121647c6ae99SBarry Smith #undef __FUNCT__
1217aa219208SBarry Smith #define __FUNCT__ "DMDARestoreAdicMFArray"
121847c6ae99SBarry Smith /*@C
1219aa219208SBarry Smith      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
122047c6ae99SBarry Smith 
122147c6ae99SBarry Smith      Input Parameter:
122247c6ae99SBarry Smith +    da - information about my local patch
122347c6ae99SBarry Smith -    ghosted - do you want arrays for the ghosted or nonghosted patch?
122447c6ae99SBarry Smith 
122547c6ae99SBarry Smith      Output Parameters:
122647c6ae99SBarry Smith +    ptr - array data structure to be passed to ad_FormFunctionLocal()
122747c6ae99SBarry Smith .    array_start - actual start of 1d array of all values that adiC can access directly
122847c6ae99SBarry Smith -    tdof - total number of degrees of freedom represented in array_start
122947c6ae99SBarry Smith 
123047c6ae99SBarry Smith      Level: advanced
123147c6ae99SBarry Smith 
1232aa219208SBarry Smith .seealso: DMDAGetAdicArray()
123347c6ae99SBarry Smith 
123447c6ae99SBarry Smith @*/
12357087cfbeSBarry Smith PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
123647c6ae99SBarry Smith {
123747c6ae99SBarry Smith   PetscInt  i;
123847c6ae99SBarry Smith   void      **iptr = (void**)vptr,*iarray_start = 0;
123947c6ae99SBarry Smith   DM_DA     *dd = (DM_DA*)da->data;
124047c6ae99SBarry Smith 
124147c6ae99SBarry Smith   PetscFunctionBegin;
124247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
124347c6ae99SBarry Smith   if (ghosted) {
1244aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
124547c6ae99SBarry Smith       if (dd->admfarrayghostedout[i] == *iptr) {
124647c6ae99SBarry Smith         iarray_start               = dd->admfstartghostedout[i];
124747c6ae99SBarry Smith         dd->admfarrayghostedout[i] = PETSC_NULL;
124847c6ae99SBarry Smith         dd->admfstartghostedout[i] = PETSC_NULL;
124947c6ae99SBarry Smith         break;
125047c6ae99SBarry Smith       }
125147c6ae99SBarry Smith     }
125247c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1253aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
125447c6ae99SBarry Smith       if (!dd->admfarrayghostedin[i]){
125547c6ae99SBarry Smith         dd->admfarrayghostedin[i] = *iptr;
125647c6ae99SBarry Smith         dd->admfstartghostedin[i] = iarray_start;
125747c6ae99SBarry Smith         break;
125847c6ae99SBarry Smith       }
125947c6ae99SBarry Smith     }
126047c6ae99SBarry Smith   } else {
1261aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
126247c6ae99SBarry Smith       if (dd->admfarrayout[i] == *iptr) {
126347c6ae99SBarry Smith         iarray_start        = dd->admfstartout[i];
126447c6ae99SBarry Smith         dd->admfarrayout[i] = PETSC_NULL;
126547c6ae99SBarry Smith         dd->admfstartout[i] = PETSC_NULL;
126647c6ae99SBarry Smith         break;
126747c6ae99SBarry Smith       }
126847c6ae99SBarry Smith     }
126947c6ae99SBarry Smith     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1270aa219208SBarry Smith     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
127147c6ae99SBarry Smith       if (!dd->admfarrayin[i]){
127247c6ae99SBarry Smith         dd->admfarrayin[i] = *iptr;
127347c6ae99SBarry Smith         dd->admfstartin[i] = iarray_start;
127447c6ae99SBarry Smith         break;
127547c6ae99SBarry Smith       }
127647c6ae99SBarry Smith     }
127747c6ae99SBarry Smith   }
127847c6ae99SBarry Smith   PetscFunctionReturn(0);
127947c6ae99SBarry Smith }
128047c6ae99SBarry Smith 
128147c6ae99SBarry Smith #undef __FUNCT__
128247c6ae99SBarry Smith #define __FUNCT__ "admf_DAGetArray"
12837087cfbeSBarry Smith PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
128447c6ae99SBarry Smith {
128547c6ae99SBarry Smith   PetscErrorCode ierr;
128647c6ae99SBarry Smith   PetscFunctionBegin;
1287aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
128847c6ae99SBarry Smith   PetscFunctionReturn(0);
128947c6ae99SBarry Smith }
129047c6ae99SBarry Smith 
129147c6ae99SBarry Smith #undef __FUNCT__
129247c6ae99SBarry Smith #define __FUNCT__ "admf_DARestoreArray"
12937087cfbeSBarry Smith PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
129447c6ae99SBarry Smith {
129547c6ae99SBarry Smith   PetscErrorCode ierr;
129647c6ae99SBarry Smith   PetscFunctionBegin;
1297aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr);
129847c6ae99SBarry Smith   PetscFunctionReturn(0);
129947c6ae99SBarry Smith }
130047c6ae99SBarry Smith 
1301