xref: /petsc/src/dm/impls/da/da2.c (revision 6636e97a9dbd9dfa567780c5ec4fb4018c0e427e)
19a42bb27SBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/daimpl.h>    /*I   "petscdmda.h"   I*/
347c6ae99SBarry Smith 
447c6ae99SBarry Smith #undef __FUNCT__
59a42bb27SBarry Smith #define __FUNCT__ "DMView_DA_2d"
69a42bb27SBarry Smith PetscErrorCode DMView_DA_2d(DM da,PetscViewer viewer)
747c6ae99SBarry Smith {
847c6ae99SBarry Smith   PetscErrorCode ierr;
947c6ae99SBarry Smith   PetscMPIInt    rank;
109a42bb27SBarry Smith   PetscBool      iascii,isdraw,isbinary;
1147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
129a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
139a42bb27SBarry Smith   PetscBool      ismatlab;
149a42bb27SBarry Smith #endif
1547c6ae99SBarry Smith 
1647c6ae99SBarry Smith   PetscFunctionBegin;
1747c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)da)->comm,&rank);CHKERRQ(ierr);
1847c6ae99SBarry Smith 
19251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
20251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
21251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
229a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
23251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERMATLAB,&ismatlab);CHKERRQ(ierr);
249a42bb27SBarry Smith #endif
2547c6ae99SBarry Smith   if (iascii) {
2647c6ae99SBarry Smith     PetscViewerFormat format;
2747c6ae99SBarry Smith 
2847c6ae99SBarry Smith     ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
2947c6ae99SBarry Smith     if (format != PETSC_VIEWER_ASCII_VTK && format != PETSC_VIEWER_ASCII_VTK_CELL) {
30aa219208SBarry Smith       DMDALocalInfo info;
31aa219208SBarry Smith       ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
327b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr);
3347c6ae99SBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Processor [%d] M %D N %D m %D n %D w %D s %D\n",rank,dd->M,dd->N,dd->m,dd->n,dd->w,dd->s);CHKERRQ(ierr);
3447c6ae99SBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"X range of indices: %D %D, Y range of indices: %D %D\n",info.xs,info.xs+info.xm,info.ys,info.ys+info.ym);CHKERRQ(ierr);
3547c6ae99SBarry Smith       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
367b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr);
373da9ae13SJed Brown     } else {
383da9ae13SJed Brown       ierr = DMView_DA_VTK(da,viewer);CHKERRQ(ierr);
3947c6ae99SBarry Smith     }
4047c6ae99SBarry Smith   } else if (isdraw) {
4147c6ae99SBarry Smith     PetscDraw  draw;
4247c6ae99SBarry Smith     double     ymin = -1*dd->s-1,ymax = dd->N+dd->s;
4347c6ae99SBarry Smith     double     xmin = -1*dd->s-1,xmax = dd->M+dd->s;
4447c6ae99SBarry Smith     double     x,y;
4547c6ae99SBarry Smith     PetscInt   base,*idx;
4647c6ae99SBarry Smith     char       node[10];
4747c6ae99SBarry Smith     PetscBool  isnull;
4847c6ae99SBarry Smith 
4947c6ae99SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
5047c6ae99SBarry Smith     ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
51*6636e97aSMatthew G Knepley     if (!da->coordinates) {
5247c6ae99SBarry Smith       ierr = PetscDrawSetCoordinates(draw,xmin,ymin,xmax,ymax);CHKERRQ(ierr);
5347c6ae99SBarry Smith     }
5447c6ae99SBarry Smith     ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr);
5547c6ae99SBarry Smith 
5647c6ae99SBarry Smith     /* first processor draw all node lines */
5747c6ae99SBarry Smith     if (!rank) {
5847c6ae99SBarry Smith       ymin = 0.0; ymax = dd->N - 1;
5947c6ae99SBarry Smith       for (xmin=0; xmin<dd->M; xmin++) {
6047c6ae99SBarry Smith         ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_BLACK);CHKERRQ(ierr);
6147c6ae99SBarry Smith       }
6247c6ae99SBarry Smith       xmin = 0.0; xmax = dd->M - 1;
6347c6ae99SBarry Smith       for (ymin=0; ymin<dd->N; ymin++) {
6447c6ae99SBarry Smith         ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_BLACK);CHKERRQ(ierr);
6547c6ae99SBarry Smith       }
6647c6ae99SBarry Smith     }
6747c6ae99SBarry Smith     ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
6847c6ae99SBarry Smith     ierr = PetscDrawPause(draw);CHKERRQ(ierr);
6947c6ae99SBarry Smith 
7047c6ae99SBarry Smith     /* draw my box */
7147c6ae99SBarry Smith     ymin = dd->ys; ymax = dd->ye - 1; xmin = dd->xs/dd->w;
7247c6ae99SBarry Smith     xmax =(dd->xe-1)/dd->w;
7347c6ae99SBarry Smith     ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_RED);CHKERRQ(ierr);
7447c6ae99SBarry Smith     ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_RED);CHKERRQ(ierr);
7547c6ae99SBarry Smith     ierr = PetscDrawLine(draw,xmin,ymax,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr);
7647c6ae99SBarry Smith     ierr = PetscDrawLine(draw,xmax,ymin,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr);
7747c6ae99SBarry Smith 
7847c6ae99SBarry Smith     /* put in numbers */
7947c6ae99SBarry Smith     base = (dd->base)/dd->w;
8047c6ae99SBarry Smith     for (y=ymin; y<=ymax; y++) {
8147c6ae99SBarry Smith       for (x=xmin; x<=xmax; x++) {
8247c6ae99SBarry Smith         sprintf(node,"%d",(int)base++);
8347c6ae99SBarry Smith         ierr = PetscDrawString(draw,x,y,PETSC_DRAW_BLACK,node);CHKERRQ(ierr);
8447c6ae99SBarry Smith       }
8547c6ae99SBarry Smith     }
8647c6ae99SBarry Smith 
8747c6ae99SBarry Smith     ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
8847c6ae99SBarry Smith     ierr = PetscDrawPause(draw);CHKERRQ(ierr);
8947c6ae99SBarry Smith     /* overlay ghost numbers, useful for error checking */
9047c6ae99SBarry Smith     /* put in numbers */
9147c6ae99SBarry Smith 
9247c6ae99SBarry Smith     base = 0; idx = dd->idx;
9347c6ae99SBarry Smith     ymin = dd->Ys; ymax = dd->Ye; xmin = dd->Xs; xmax = dd->Xe;
9447c6ae99SBarry Smith     for (y=ymin; y<ymax; y++) {
9547c6ae99SBarry Smith       for (x=xmin; x<xmax; x++) {
9647c6ae99SBarry Smith         if ((base % dd->w) == 0) {
9747c6ae99SBarry Smith           sprintf(node,"%d",(int)(idx[base]/dd->w));
9847c6ae99SBarry Smith           ierr = PetscDrawString(draw,x/dd->w,y,PETSC_DRAW_BLUE,node);CHKERRQ(ierr);
9947c6ae99SBarry Smith         }
10047c6ae99SBarry Smith         base++;
10147c6ae99SBarry Smith       }
10247c6ae99SBarry Smith     }
10347c6ae99SBarry Smith     ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
10447c6ae99SBarry Smith     ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1059a42bb27SBarry Smith   } else if (isbinary){
1069a42bb27SBarry Smith     ierr = DMView_DA_Binary(da,viewer);CHKERRQ(ierr);
1079a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
1089a42bb27SBarry Smith   } else if (ismatlab) {
1099a42bb27SBarry Smith     ierr = DMView_DA_Matlab(da,viewer);CHKERRQ(ierr);
1109a42bb27SBarry Smith #endif
111aa219208SBarry Smith   } else SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for DMDA 1d",((PetscObject)viewer)->type_name);
11247c6ae99SBarry Smith   PetscFunctionReturn(0);
11347c6ae99SBarry Smith }
11447c6ae99SBarry Smith 
11547c6ae99SBarry Smith /*
11647c6ae99SBarry Smith       M is number of grid points
11747c6ae99SBarry Smith       m is number of processors
11847c6ae99SBarry Smith 
11947c6ae99SBarry Smith */
12047c6ae99SBarry Smith #undef __FUNCT__
121aa219208SBarry Smith #define __FUNCT__ "DMDASplitComm2d"
1227087cfbeSBarry Smith PetscErrorCode  DMDASplitComm2d(MPI_Comm comm,PetscInt M,PetscInt N,PetscInt sw,MPI_Comm *outcomm)
12347c6ae99SBarry Smith {
12447c6ae99SBarry Smith   PetscErrorCode ierr;
12547c6ae99SBarry Smith   PetscInt       m,n = 0,x = 0,y = 0;
12647c6ae99SBarry Smith   PetscMPIInt    size,csize,rank;
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith   PetscFunctionBegin;
12947c6ae99SBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
13047c6ae99SBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
13147c6ae99SBarry Smith 
13247c6ae99SBarry Smith   csize = 4*size;
13347c6ae99SBarry Smith   do {
13447c6ae99SBarry Smith     if (csize % 4) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot split communicator of size %d tried %d %D %D",size,csize,x,y);
13547c6ae99SBarry Smith     csize   = csize/4;
13647c6ae99SBarry Smith 
13747c6ae99SBarry Smith     m = (PetscInt)(0.5 + sqrt(((double)M)*((double)csize)/((double)N)));
13847c6ae99SBarry Smith     if (!m) m = 1;
13947c6ae99SBarry Smith     while (m > 0) {
14047c6ae99SBarry Smith       n = csize/m;
14147c6ae99SBarry Smith       if (m*n == csize) break;
14247c6ae99SBarry Smith       m--;
14347c6ae99SBarry Smith     }
14447c6ae99SBarry Smith     if (M > N && m < n) {PetscInt _m = m; m = n; n = _m;}
14547c6ae99SBarry Smith 
14647c6ae99SBarry Smith     x = M/m + ((M % m) > ((csize-1) % m));
14747c6ae99SBarry Smith     y = (N + (csize-1)/m)/n;
14847c6ae99SBarry Smith   } while ((x < 4 || y < 4) && csize > 1);
14947c6ae99SBarry Smith   if (size != csize) {
15047c6ae99SBarry Smith     MPI_Group    entire_group,sub_group;
15147c6ae99SBarry Smith     PetscMPIInt  i,*groupies;
15247c6ae99SBarry Smith 
15347c6ae99SBarry Smith     ierr = MPI_Comm_group(comm,&entire_group);CHKERRQ(ierr);
15447c6ae99SBarry Smith     ierr = PetscMalloc(csize*sizeof(PetscInt),&groupies);CHKERRQ(ierr);
15547c6ae99SBarry Smith     for (i=0; i<csize; i++) {
15647c6ae99SBarry Smith       groupies[i] = (rank/csize)*csize + i;
15747c6ae99SBarry Smith     }
15847c6ae99SBarry Smith     ierr = MPI_Group_incl(entire_group,csize,groupies,&sub_group);CHKERRQ(ierr);
15947c6ae99SBarry Smith     ierr = PetscFree(groupies);CHKERRQ(ierr);
16047c6ae99SBarry Smith     ierr = MPI_Comm_create(comm,sub_group,outcomm);CHKERRQ(ierr);
16147c6ae99SBarry Smith     ierr = MPI_Group_free(&entire_group);CHKERRQ(ierr);
16247c6ae99SBarry Smith     ierr = MPI_Group_free(&sub_group);CHKERRQ(ierr);
163aa219208SBarry Smith     ierr = PetscInfo1(0,"DMDASplitComm2d:Creating redundant coarse problems of size %d\n",csize);CHKERRQ(ierr);
16447c6ae99SBarry Smith   } else {
16547c6ae99SBarry Smith     *outcomm = comm;
16647c6ae99SBarry Smith   }
16747c6ae99SBarry Smith   PetscFunctionReturn(0);
16847c6ae99SBarry Smith }
16947c6ae99SBarry Smith 
17047c6ae99SBarry Smith #undef __FUNCT__
171644e2e5bSBarry Smith #define __FUNCT__ "DMDAFunction"
172644e2e5bSBarry Smith static PetscErrorCode DMDAFunction(DM dm,Vec x,Vec F)
173644e2e5bSBarry Smith {
174644e2e5bSBarry Smith   PetscErrorCode ierr;
175644e2e5bSBarry Smith   Vec            localX;
176644e2e5bSBarry Smith 
177644e2e5bSBarry Smith   PetscFunctionBegin;
178644e2e5bSBarry Smith   ierr = DMGetLocalVector(dm,&localX);CHKERRQ(ierr);
179644e2e5bSBarry Smith   ierr = DMGlobalToLocalBegin(dm,x,INSERT_VALUES,localX);CHKERRQ(ierr);
180644e2e5bSBarry Smith   ierr = DMGlobalToLocalEnd(dm,x,INSERT_VALUES,localX);CHKERRQ(ierr);
181837ad101SBarry Smith   ierr = DMDAComputeFunction1(dm,localX,F,dm->ctx);CHKERRQ(ierr);
182644e2e5bSBarry Smith   ierr = DMRestoreLocalVector(dm,&localX);CHKERRQ(ierr);
183644e2e5bSBarry Smith   PetscFunctionReturn(0);
184644e2e5bSBarry Smith }
185644e2e5bSBarry Smith 
186644e2e5bSBarry Smith #undef __FUNCT__
187aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalFunction"
18847c6ae99SBarry Smith /*@C
189aa219208SBarry Smith        DMDASetLocalFunction - Caches in a DM a local function.
19047c6ae99SBarry Smith 
191aa219208SBarry Smith    Logically Collective on DMDA
19247c6ae99SBarry Smith 
19347c6ae99SBarry Smith    Input Parameter:
19447c6ae99SBarry Smith +  da - initial distributed array
19547c6ae99SBarry Smith -  lf - the local function
19647c6ae99SBarry Smith 
19747c6ae99SBarry Smith    Level: intermediate
19847c6ae99SBarry Smith 
19931e16157SBarry Smith    Notes:
20031e16157SBarry Smith       If you use SNESSetDM() and did not use SNESSetFunction() then the context passed to your function is the context set with DMSetApplicationContext()
20131e16157SBarry Smith 
20231e16157SBarry Smith    Developer Notes: It is possibly confusing which context is passed to the user function, it would be nice to unify them somehow.
20347c6ae99SBarry Smith 
20447c6ae99SBarry Smith .keywords:  distributed array, refine
20547c6ae99SBarry Smith 
206aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunctioni()
20747c6ae99SBarry Smith @*/
2087087cfbeSBarry Smith PetscErrorCode  DMDASetLocalFunction(DM da,DMDALocalFunction1 lf)
20947c6ae99SBarry Smith {
210644e2e5bSBarry Smith   PetscErrorCode ierr;
21147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
212644e2e5bSBarry Smith 
21347c6ae99SBarry Smith   PetscFunctionBegin;
21447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
215644e2e5bSBarry Smith   ierr = DMSetFunction(da,DMDAFunction);CHKERRQ(ierr);
21647c6ae99SBarry Smith   dd->lf       = lf;
21747c6ae99SBarry Smith   PetscFunctionReturn(0);
21847c6ae99SBarry Smith }
21947c6ae99SBarry Smith 
22047c6ae99SBarry Smith #undef __FUNCT__
221aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalFunctioni"
22247c6ae99SBarry Smith /*@C
223aa219208SBarry Smith        DMDASetLocalFunctioni - Caches in a DM a local function that evaluates a single component
22447c6ae99SBarry Smith 
225aa219208SBarry Smith    Logically Collective on DMDA
22647c6ae99SBarry Smith 
22747c6ae99SBarry Smith    Input Parameter:
22847c6ae99SBarry Smith +  da - initial distributed array
22947c6ae99SBarry Smith -  lfi - the local function
23047c6ae99SBarry Smith 
23147c6ae99SBarry Smith    Level: intermediate
23247c6ae99SBarry Smith 
23347c6ae99SBarry Smith .keywords:  distributed array, refine
23447c6ae99SBarry Smith 
235aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction()
23647c6ae99SBarry Smith @*/
2377087cfbeSBarry Smith PetscErrorCode  DMDASetLocalFunctioni(DM da,PetscErrorCode (*lfi)(DMDALocalInfo*,MatStencil*,void*,PetscScalar*,void*))
23847c6ae99SBarry Smith {
23947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
24047c6ae99SBarry Smith   PetscFunctionBegin;
24147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
24247c6ae99SBarry Smith   dd->lfi = lfi;
24347c6ae99SBarry Smith   PetscFunctionReturn(0);
24447c6ae99SBarry Smith }
24547c6ae99SBarry Smith 
24647c6ae99SBarry Smith #undef __FUNCT__
247aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalFunctionib"
24847c6ae99SBarry Smith /*@C
249aa219208SBarry Smith        DMDASetLocalFunctionib - Caches in a DM a block local function that evaluates a single component
25047c6ae99SBarry Smith 
251aa219208SBarry Smith    Logically Collective on DMDA
25247c6ae99SBarry Smith 
25347c6ae99SBarry Smith    Input Parameter:
25447c6ae99SBarry Smith +  da - initial distributed array
25547c6ae99SBarry Smith -  lfi - the local function
25647c6ae99SBarry Smith 
25747c6ae99SBarry Smith    Level: intermediate
25847c6ae99SBarry Smith 
25947c6ae99SBarry Smith .keywords:  distributed array, refine
26047c6ae99SBarry Smith 
261aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction()
26247c6ae99SBarry Smith @*/
2637087cfbeSBarry Smith PetscErrorCode  DMDASetLocalFunctionib(DM da,PetscErrorCode (*lfi)(DMDALocalInfo*,MatStencil*,void*,PetscScalar*,void*))
26447c6ae99SBarry Smith {
26547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
26647c6ae99SBarry Smith   PetscFunctionBegin;
26747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
26847c6ae99SBarry Smith   dd->lfib = lfi;
26947c6ae99SBarry Smith   PetscFunctionReturn(0);
27047c6ae99SBarry Smith }
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith #undef __FUNCT__
273aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicFunction_Private"
274aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunction_Private(DM da,DMDALocalFunction1 ad_lf)
27547c6ae99SBarry Smith {
27647c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
27747c6ae99SBarry Smith   PetscFunctionBegin;
27847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
27947c6ae99SBarry Smith   dd->adic_lf = ad_lf;
28047c6ae99SBarry Smith   PetscFunctionReturn(0);
28147c6ae99SBarry Smith }
28247c6ae99SBarry Smith 
28347c6ae99SBarry Smith /*MC
284aa219208SBarry Smith        DMDASetLocalAdicFunctioni - Caches in a DM a local functioni computed by ADIC/ADIFOR
28547c6ae99SBarry Smith 
28647c6ae99SBarry Smith    Synopsis:
287aa219208SBarry Smith    PetscErrorCode DMDASetLocalAdicFunctioni(DM da,PetscInt (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*)
28847c6ae99SBarry Smith 
289aa219208SBarry Smith    Logically Collective on DMDA
29047c6ae99SBarry Smith 
29147c6ae99SBarry Smith    Input Parameter:
29247c6ae99SBarry Smith +  da - initial distributed array
29347c6ae99SBarry Smith -  ad_lfi - the local function as computed by ADIC/ADIFOR
29447c6ae99SBarry Smith 
29547c6ae99SBarry Smith    Level: intermediate
29647c6ae99SBarry Smith 
29747c6ae99SBarry Smith .keywords:  distributed array, refine
29847c6ae99SBarry Smith 
299aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(),
300aa219208SBarry Smith           DMDASetLocalJacobian(), DMDASetLocalFunctioni()
30147c6ae99SBarry Smith M*/
30247c6ae99SBarry Smith 
30347c6ae99SBarry Smith #undef __FUNCT__
304aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicFunctioni_Private"
305aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctioni_Private(DM da,PetscErrorCode (*ad_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*))
30647c6ae99SBarry Smith {
30747c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
30847c6ae99SBarry Smith   PetscFunctionBegin;
30947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
31047c6ae99SBarry Smith   dd->adic_lfi = ad_lfi;
31147c6ae99SBarry Smith   PetscFunctionReturn(0);
31247c6ae99SBarry Smith }
31347c6ae99SBarry Smith 
31447c6ae99SBarry Smith /*MC
315aa219208SBarry Smith        DMDASetLocalAdicMFFunctioni - Caches in a DM a local functioni computed by ADIC/ADIFOR
31647c6ae99SBarry Smith 
31747c6ae99SBarry Smith    Synopsis:
318aa219208SBarry Smith    PetscErrorCode  DMDASetLocalAdicFunctioni(DM da,int (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*)
31947c6ae99SBarry Smith 
320aa219208SBarry Smith    Logically Collective on DMDA
32147c6ae99SBarry Smith 
32247c6ae99SBarry Smith    Input Parameter:
32347c6ae99SBarry Smith +  da - initial distributed array
32447c6ae99SBarry Smith -  admf_lfi - the local matrix-free function as computed by ADIC/ADIFOR
32547c6ae99SBarry Smith 
32647c6ae99SBarry Smith    Level: intermediate
32747c6ae99SBarry Smith 
32847c6ae99SBarry Smith .keywords:  distributed array, refine
32947c6ae99SBarry Smith 
330aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(),
331aa219208SBarry Smith           DMDASetLocalJacobian(), DMDASetLocalFunctioni()
33247c6ae99SBarry Smith M*/
33347c6ae99SBarry Smith 
33447c6ae99SBarry Smith #undef __FUNCT__
335aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicMFFunctioni_Private"
336aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicMFFunctioni_Private(DM da,PetscErrorCode (*admf_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*))
33747c6ae99SBarry Smith {
33847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
33947c6ae99SBarry Smith   PetscFunctionBegin;
34047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
34147c6ae99SBarry Smith   dd->adicmf_lfi = admf_lfi;
34247c6ae99SBarry Smith   PetscFunctionReturn(0);
34347c6ae99SBarry Smith }
34447c6ae99SBarry Smith 
34547c6ae99SBarry Smith /*MC
346aa219208SBarry Smith        DMDASetLocalAdicFunctionib - Caches in a DM a block local functioni computed by ADIC/ADIFOR
34747c6ae99SBarry Smith 
34847c6ae99SBarry Smith    Synopsis:
349aa219208SBarry Smith    PetscErrorCode DMDASetLocalAdicFunctionib(DM da,PetscInt (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*)
35047c6ae99SBarry Smith 
351aa219208SBarry Smith    Logically Collective on DMDA
35247c6ae99SBarry Smith 
35347c6ae99SBarry Smith    Input Parameter:
35447c6ae99SBarry Smith +  da - initial distributed array
35547c6ae99SBarry Smith -  ad_lfi - the local function as computed by ADIC/ADIFOR
35647c6ae99SBarry Smith 
35747c6ae99SBarry Smith    Level: intermediate
35847c6ae99SBarry Smith 
35947c6ae99SBarry Smith .keywords:  distributed array, refine
36047c6ae99SBarry Smith 
361aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(),
362aa219208SBarry Smith           DMDASetLocalJacobian(), DMDASetLocalFunctionib()
36347c6ae99SBarry Smith M*/
36447c6ae99SBarry Smith 
36547c6ae99SBarry Smith #undef __FUNCT__
366aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicFunctionib_Private"
367aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctionib_Private(DM da,PetscErrorCode (*ad_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*))
36847c6ae99SBarry Smith {
36947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
37047c6ae99SBarry Smith   PetscFunctionBegin;
37147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
37247c6ae99SBarry Smith   dd->adic_lfib = ad_lfi;
37347c6ae99SBarry Smith   PetscFunctionReturn(0);
37447c6ae99SBarry Smith }
37547c6ae99SBarry Smith 
37647c6ae99SBarry Smith /*MC
377aa219208SBarry Smith        DMDASetLocalAdicMFFunctionib - Caches in a DM a block local functioni computed by ADIC/ADIFOR
37847c6ae99SBarry Smith 
37947c6ae99SBarry Smith    Synopsis:
380aa219208SBarry Smith    PetscErrorCode  DMDASetLocalAdicFunctionib(DM da,int (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*)
38147c6ae99SBarry Smith 
382aa219208SBarry Smith    Logically Collective on DMDA
38347c6ae99SBarry Smith 
38447c6ae99SBarry Smith    Input Parameter:
38547c6ae99SBarry Smith +  da - initial distributed array
38647c6ae99SBarry Smith -  admf_lfi - the local matrix-free function as computed by ADIC/ADIFOR
38747c6ae99SBarry Smith 
38847c6ae99SBarry Smith    Level: intermediate
38947c6ae99SBarry Smith 
39047c6ae99SBarry Smith .keywords:  distributed array, refine
39147c6ae99SBarry Smith 
392aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(),
393aa219208SBarry Smith           DMDASetLocalJacobian(), DMDASetLocalFunctionib()
39447c6ae99SBarry Smith M*/
39547c6ae99SBarry Smith 
39647c6ae99SBarry Smith #undef __FUNCT__
397aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicMFFunctionib_Private"
398aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicMFFunctionib_Private(DM da,PetscErrorCode (*admf_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*))
39947c6ae99SBarry Smith {
40047c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
40147c6ae99SBarry Smith   PetscFunctionBegin;
40247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
40347c6ae99SBarry Smith   dd->adicmf_lfib = admf_lfi;
40447c6ae99SBarry Smith   PetscFunctionReturn(0);
40547c6ae99SBarry Smith }
40647c6ae99SBarry Smith 
40747c6ae99SBarry Smith /*MC
408aa219208SBarry Smith        DMDASetLocalAdicMFFunction - Caches in a DM a local function computed by ADIC/ADIFOR
40947c6ae99SBarry Smith 
41047c6ae99SBarry Smith    Synopsis:
411aa219208SBarry Smith    PetscErrorCode DMDASetLocalAdicMFFunction(DM da,DMDALocalFunction1 ad_lf)
41247c6ae99SBarry Smith 
413aa219208SBarry Smith    Logically Collective on DMDA
41447c6ae99SBarry Smith 
41547c6ae99SBarry Smith    Input Parameter:
41647c6ae99SBarry Smith +  da - initial distributed array
41747c6ae99SBarry Smith -  ad_lf - the local function as computed by ADIC/ADIFOR
41847c6ae99SBarry Smith 
41947c6ae99SBarry Smith    Level: intermediate
42047c6ae99SBarry Smith 
42147c6ae99SBarry Smith .keywords:  distributed array, refine
42247c6ae99SBarry Smith 
423aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(),
424aa219208SBarry Smith           DMDASetLocalJacobian()
42547c6ae99SBarry Smith M*/
42647c6ae99SBarry Smith 
42747c6ae99SBarry Smith #undef __FUNCT__
428aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicMFFunction_Private"
429aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicMFFunction_Private(DM da,DMDALocalFunction1 ad_lf)
43047c6ae99SBarry Smith {
43147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
43247c6ae99SBarry Smith   PetscFunctionBegin;
43347c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
43447c6ae99SBarry Smith   dd->adicmf_lf = ad_lf;
43547c6ae99SBarry Smith   PetscFunctionReturn(0);
43647c6ae99SBarry Smith }
43747c6ae99SBarry Smith 
438644e2e5bSBarry Smith #undef __FUNCT__
4392533e041SBarry Smith #define __FUNCT__ "DMDAJacobianDefaultLocal"
4402533e041SBarry Smith PetscErrorCode DMDAJacobianLocal(DM dm,Vec x,Mat A,Mat B, MatStructure *str)
4412533e041SBarry Smith {
4422533e041SBarry Smith   PetscErrorCode ierr;
4432533e041SBarry Smith   Vec            localX;
4442533e041SBarry Smith 
4452533e041SBarry Smith   PetscFunctionBegin;
4462533e041SBarry Smith   ierr = DMGetLocalVector(dm,&localX);CHKERRQ(ierr);
4472533e041SBarry Smith   ierr = DMGlobalToLocalBegin(dm,x,INSERT_VALUES,localX);CHKERRQ(ierr);
4482533e041SBarry Smith   ierr = DMGlobalToLocalEnd(dm,x,INSERT_VALUES,localX);CHKERRQ(ierr);
4492533e041SBarry Smith   ierr = MatFDColoringApply(B,dm->fd,localX,str,dm);CHKERRQ(ierr);
4502533e041SBarry Smith   ierr = DMRestoreLocalVector(dm,&localX);CHKERRQ(ierr);
4512533e041SBarry Smith   /* Assemble true Jacobian; if it is different */
4522533e041SBarry Smith   if (A != B) {
4532533e041SBarry Smith     ierr  = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4542533e041SBarry Smith     ierr  = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4552533e041SBarry Smith   }
4562533e041SBarry Smith   ierr  = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
4572533e041SBarry Smith   *str = SAME_NONZERO_PATTERN;
4582533e041SBarry Smith   PetscFunctionReturn(0);
4592533e041SBarry Smith }
4602533e041SBarry Smith 
4612533e041SBarry Smith 
4622533e041SBarry Smith #undef __FUNCT__
463644e2e5bSBarry Smith #define __FUNCT__ "DMDAJacobian"
464644e2e5bSBarry Smith static PetscErrorCode DMDAJacobian(DM dm,Vec x,Mat A,Mat B, MatStructure *str)
465644e2e5bSBarry Smith {
466644e2e5bSBarry Smith   PetscErrorCode ierr;
467644e2e5bSBarry Smith   Vec            localX;
468644e2e5bSBarry Smith 
469644e2e5bSBarry Smith   PetscFunctionBegin;
470644e2e5bSBarry Smith   ierr = DMGetLocalVector(dm,&localX);CHKERRQ(ierr);
471644e2e5bSBarry Smith   ierr = DMGlobalToLocalBegin(dm,x,INSERT_VALUES,localX);CHKERRQ(ierr);
472644e2e5bSBarry Smith   ierr = DMGlobalToLocalEnd(dm,x,INSERT_VALUES,localX);CHKERRQ(ierr);
473644e2e5bSBarry Smith   ierr = DMDAComputeJacobian1(dm,localX,B,dm->ctx);CHKERRQ(ierr);
474644e2e5bSBarry Smith   ierr = DMRestoreLocalVector(dm,&localX);CHKERRQ(ierr);
475644e2e5bSBarry Smith   /* Assemble true Jacobian; if it is different */
476644e2e5bSBarry Smith   if (A != B) {
477644e2e5bSBarry Smith     ierr  = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
478644e2e5bSBarry Smith     ierr  = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
479644e2e5bSBarry Smith   }
480644e2e5bSBarry Smith   ierr  = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
481644e2e5bSBarry Smith   *str = SAME_NONZERO_PATTERN;
482644e2e5bSBarry Smith   PetscFunctionReturn(0);
483644e2e5bSBarry Smith }
484644e2e5bSBarry Smith 
48547c6ae99SBarry Smith /*@C
486aa219208SBarry Smith        DMDASetLocalJacobian - Caches in a DM a local Jacobian computation function
48747c6ae99SBarry Smith 
488aa219208SBarry Smith    Logically Collective on DMDA
48947c6ae99SBarry Smith 
49047c6ae99SBarry Smith 
49147c6ae99SBarry Smith    Input Parameter:
49247c6ae99SBarry Smith +  da - initial distributed array
49347c6ae99SBarry Smith -  lj - the local Jacobian
49447c6ae99SBarry Smith 
49547c6ae99SBarry Smith    Level: intermediate
49647c6ae99SBarry Smith 
49747c6ae99SBarry Smith .keywords:  distributed array, refine
49847c6ae99SBarry Smith 
499aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction()
50047c6ae99SBarry Smith @*/
50147c6ae99SBarry Smith #undef __FUNCT__
502aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalJacobian"
5037087cfbeSBarry Smith PetscErrorCode  DMDASetLocalJacobian(DM da,DMDALocalFunction1 lj)
50447c6ae99SBarry Smith {
505644e2e5bSBarry Smith   PetscErrorCode ierr;
50647c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
507644e2e5bSBarry Smith 
50847c6ae99SBarry Smith   PetscFunctionBegin;
50947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
510644e2e5bSBarry Smith   ierr = DMSetJacobian(da,DMDAJacobian);CHKERRQ(ierr);
51147c6ae99SBarry Smith   dd->lj    = lj;
51247c6ae99SBarry Smith   PetscFunctionReturn(0);
51347c6ae99SBarry Smith }
51447c6ae99SBarry Smith 
51547c6ae99SBarry Smith #undef __FUNCT__
516aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalFunction"
51747c6ae99SBarry Smith /*@C
518aa219208SBarry Smith        DMDAGetLocalFunction - Gets from a DM a local function and its ADIC/ADIFOR Jacobian
51947c6ae99SBarry Smith 
52047c6ae99SBarry Smith    Note Collective
52147c6ae99SBarry Smith 
52247c6ae99SBarry Smith    Input Parameter:
52347c6ae99SBarry Smith .  da - initial distributed array
52447c6ae99SBarry Smith 
52547c6ae99SBarry Smith    Output Parameter:
52647c6ae99SBarry Smith .  lf - the local function
52747c6ae99SBarry Smith 
52847c6ae99SBarry Smith    Level: intermediate
52947c6ae99SBarry Smith 
53047c6ae99SBarry Smith .keywords:  distributed array, refine
53147c6ae99SBarry Smith 
532aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalJacobian(), DMDASetLocalFunction()
53347c6ae99SBarry Smith @*/
5347087cfbeSBarry Smith PetscErrorCode  DMDAGetLocalFunction(DM da,DMDALocalFunction1 *lf)
53547c6ae99SBarry Smith {
53647c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
53747c6ae99SBarry Smith   PetscFunctionBegin;
53847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
53947c6ae99SBarry Smith   if (lf) *lf = dd->lf;
54047c6ae99SBarry Smith   PetscFunctionReturn(0);
54147c6ae99SBarry Smith }
54247c6ae99SBarry Smith 
54347c6ae99SBarry Smith #undef __FUNCT__
544aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalJacobian"
54547c6ae99SBarry Smith /*@C
546aa219208SBarry Smith        DMDAGetLocalJacobian - Gets from a DM a local jacobian
54747c6ae99SBarry Smith 
54847c6ae99SBarry Smith    Not Collective
54947c6ae99SBarry Smith 
55047c6ae99SBarry Smith    Input Parameter:
55147c6ae99SBarry Smith .  da - initial distributed array
55247c6ae99SBarry Smith 
55347c6ae99SBarry Smith    Output Parameter:
55447c6ae99SBarry Smith .  lj - the local jacobian
55547c6ae99SBarry Smith 
55647c6ae99SBarry Smith    Level: intermediate
55747c6ae99SBarry Smith 
55847c6ae99SBarry Smith .keywords:  distributed array, refine
55947c6ae99SBarry Smith 
560aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalJacobian()
56147c6ae99SBarry Smith @*/
5627087cfbeSBarry Smith PetscErrorCode  DMDAGetLocalJacobian(DM da,DMDALocalFunction1 *lj)
56347c6ae99SBarry Smith {
56447c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
56547c6ae99SBarry Smith   PetscFunctionBegin;
56647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
56747c6ae99SBarry Smith   if (lj) *lj = dd->lj;
56847c6ae99SBarry Smith   PetscFunctionReturn(0);
56947c6ae99SBarry Smith }
57047c6ae99SBarry Smith 
57147c6ae99SBarry Smith #undef __FUNCT__
572837ad101SBarry Smith #define __FUNCT__ "DMDAComputeFunction"
57347c6ae99SBarry Smith /*@
574837ad101SBarry Smith     DMDAComputeFunction - Evaluates a user provided function on each processor that
575aa219208SBarry Smith         share a DMDA
57647c6ae99SBarry Smith 
57747c6ae99SBarry Smith    Input Parameters:
5789a42bb27SBarry Smith +    da - the DM that defines the grid
57947c6ae99SBarry Smith .    vu - input vector
58047c6ae99SBarry Smith .    vfu - output vector
58147c6ae99SBarry Smith -    w - any user data
58247c6ae99SBarry Smith 
58347c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu upon entry
58447c6ae99SBarry Smith 
585837ad101SBarry Smith            This should eventually replace DMDAComputeFunction1
58647c6ae99SBarry Smith 
58747c6ae99SBarry Smith     Level: advanced
58847c6ae99SBarry Smith 
589aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic()
59047c6ae99SBarry Smith 
59147c6ae99SBarry Smith @*/
592837ad101SBarry Smith PetscErrorCode  DMDAComputeFunction(DM da,PetscErrorCode (*lf)(void),Vec vu,Vec vfu,void *w)
59347c6ae99SBarry Smith {
59447c6ae99SBarry Smith   PetscErrorCode ierr;
59547c6ae99SBarry Smith   void           *u,*fu;
596aa219208SBarry Smith   DMDALocalInfo  info;
597aa219208SBarry Smith   PetscErrorCode (*f)(DMDALocalInfo*,void*,void*,void*) = (PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))lf;
59847c6ae99SBarry Smith 
59947c6ae99SBarry Smith   PetscFunctionBegin;
600aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
601aa219208SBarry Smith   ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr);
602aa219208SBarry Smith   ierr = DMDAVecGetArray(da,vfu,&fu);CHKERRQ(ierr);
60347c6ae99SBarry Smith 
60439d508bbSBarry Smith   ierr = (*f)(&info,u,fu,w);CHKERRQ(ierr);
60547c6ae99SBarry Smith 
606aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr);
607aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,vfu,&fu);CHKERRQ(ierr);
60847c6ae99SBarry Smith   PetscFunctionReturn(0);
60947c6ae99SBarry Smith }
61047c6ae99SBarry Smith 
61147c6ae99SBarry Smith #undef __FUNCT__
612837ad101SBarry Smith #define __FUNCT__ "DMDAComputeFunctionLocal"
61347c6ae99SBarry Smith /*@C
614837ad101SBarry Smith    DMDAComputeFunctionLocal - This is a universal function evaluation routine for
6159a42bb27SBarry Smith    a local DM function.
61647c6ae99SBarry Smith 
617aa219208SBarry Smith    Collective on DMDA
61847c6ae99SBarry Smith 
61947c6ae99SBarry Smith    Input Parameters:
6209a42bb27SBarry Smith +  da - the DM context
62147c6ae99SBarry Smith .  func - The local function
62247c6ae99SBarry Smith .  X - input vector
62347c6ae99SBarry Smith .  F - function vector
62447c6ae99SBarry Smith -  ctx - A user context
62547c6ae99SBarry Smith 
62647c6ae99SBarry Smith    Level: intermediate
62747c6ae99SBarry Smith 
628aa219208SBarry Smith .seealso: DMDASetLocalFunction(), DMDASetLocalJacobian(), DMDASetLocalAdicFunction(), DMDASetLocalAdicMFFunction(),
62947c6ae99SBarry Smith           SNESSetFunction(), SNESSetJacobian()
63047c6ae99SBarry Smith 
63147c6ae99SBarry Smith @*/
632837ad101SBarry Smith PetscErrorCode  DMDAComputeFunctionLocal(DM da, DMDALocalFunction1 func, Vec X, Vec F, void *ctx)
63347c6ae99SBarry Smith {
63447c6ae99SBarry Smith   Vec            localX;
635aa219208SBarry Smith   DMDALocalInfo  info;
63647c6ae99SBarry Smith   void           *u;
63747c6ae99SBarry Smith   void           *fu;
63847c6ae99SBarry Smith   PetscErrorCode ierr;
63947c6ae99SBarry Smith 
64047c6ae99SBarry Smith   PetscFunctionBegin;
6419a42bb27SBarry Smith   ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr);
64247c6ae99SBarry Smith   /*
64347c6ae99SBarry Smith      Scatter ghost points to local vector, using the 2-step process
6449a42bb27SBarry Smith         DMGlobalToLocalBegin(), DMGlobalToLocalEnd().
64547c6ae99SBarry Smith   */
6469a42bb27SBarry Smith   ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
6479a42bb27SBarry Smith   ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
648aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
649aa219208SBarry Smith   ierr = DMDAVecGetArray(da,localX,&u);CHKERRQ(ierr);
650aa219208SBarry Smith   ierr = DMDAVecGetArray(da,F,&fu);CHKERRQ(ierr);
65139d508bbSBarry Smith   ierr = (*func)(&info,u,fu,ctx);CHKERRQ(ierr);
652aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,localX,&u);CHKERRQ(ierr);
653aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,F,&fu);CHKERRQ(ierr);
6549a42bb27SBarry Smith   ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr);
65547c6ae99SBarry Smith   PetscFunctionReturn(0);
65647c6ae99SBarry Smith }
65747c6ae99SBarry Smith 
65847c6ae99SBarry Smith #undef __FUNCT__
659837ad101SBarry Smith #define __FUNCT__ "DMDAComputeFunctionLocalGhost"
66047c6ae99SBarry Smith /*@C
661837ad101SBarry Smith    DMDAComputeFunctionLocalGhost - This is a universal function evaluation routine for
6629a42bb27SBarry Smith    a local DM function, but the ghost values of the output are communicated and added.
66347c6ae99SBarry Smith 
664aa219208SBarry Smith    Collective on DMDA
66547c6ae99SBarry Smith 
66647c6ae99SBarry Smith    Input Parameters:
6679a42bb27SBarry Smith +  da - the DM context
66847c6ae99SBarry Smith .  func - The local function
66947c6ae99SBarry Smith .  X - input vector
67047c6ae99SBarry Smith .  F - function vector
67147c6ae99SBarry Smith -  ctx - A user context
67247c6ae99SBarry Smith 
67347c6ae99SBarry Smith    Level: intermediate
67447c6ae99SBarry Smith 
675aa219208SBarry Smith .seealso: DMDASetLocalFunction(), DMDASetLocalJacobian(), DMDASetLocalAdicFunction(), DMDASetLocalAdicMFFunction(),
67647c6ae99SBarry Smith           SNESSetFunction(), SNESSetJacobian()
67747c6ae99SBarry Smith 
67847c6ae99SBarry Smith @*/
679837ad101SBarry Smith PetscErrorCode  DMDAComputeFunctionLocalGhost(DM da, DMDALocalFunction1 func, Vec X, Vec F, void *ctx)
68047c6ae99SBarry Smith {
68147c6ae99SBarry Smith   Vec            localX, localF;
682aa219208SBarry Smith   DMDALocalInfo  info;
68347c6ae99SBarry Smith   void           *u;
68447c6ae99SBarry Smith   void           *fu;
68547c6ae99SBarry Smith   PetscErrorCode ierr;
68647c6ae99SBarry Smith 
68747c6ae99SBarry Smith   PetscFunctionBegin;
6889a42bb27SBarry Smith   ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr);
6899a42bb27SBarry Smith   ierr = DMGetLocalVector(da,&localF);CHKERRQ(ierr);
69047c6ae99SBarry Smith   /*
69147c6ae99SBarry Smith      Scatter ghost points to local vector, using the 2-step process
6929a42bb27SBarry Smith         DMGlobalToLocalBegin(), DMGlobalToLocalEnd().
69347c6ae99SBarry Smith   */
6949a42bb27SBarry Smith   ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
6959a42bb27SBarry Smith   ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
69647c6ae99SBarry Smith   ierr = VecSet(F, 0.0);CHKERRQ(ierr);
69747c6ae99SBarry Smith   ierr = VecSet(localF, 0.0);CHKERRQ(ierr);
698aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
699aa219208SBarry Smith   ierr = DMDAVecGetArray(da,localX,&u);CHKERRQ(ierr);
700aa219208SBarry Smith   ierr = DMDAVecGetArray(da,localF,&fu);CHKERRQ(ierr);
70139d508bbSBarry Smith   ierr = (*func)(&info,u,fu,ctx);CHKERRQ(ierr);
7029a42bb27SBarry Smith   ierr = DMLocalToGlobalBegin(da,localF,ADD_VALUES,F);CHKERRQ(ierr);
7039a42bb27SBarry Smith   ierr = DMLocalToGlobalEnd(da,localF,ADD_VALUES,F);CHKERRQ(ierr);
704aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,localX,&u);CHKERRQ(ierr);
705aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,localF,&fu);CHKERRQ(ierr);
7069a42bb27SBarry Smith   ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr);
7079a42bb27SBarry Smith   ierr = DMRestoreLocalVector(da,&localF);CHKERRQ(ierr);
70847c6ae99SBarry Smith   PetscFunctionReturn(0);
70947c6ae99SBarry Smith }
71047c6ae99SBarry Smith 
71147c6ae99SBarry Smith #undef __FUNCT__
712837ad101SBarry Smith #define __FUNCT__ "DMDAComputeFunction1"
71347c6ae99SBarry Smith /*@
714837ad101SBarry Smith     DMDAComputeFunction1 - Evaluates a user provided function on each processor that
715aa219208SBarry Smith         share a DMDA
71647c6ae99SBarry Smith 
71747c6ae99SBarry Smith    Input Parameters:
7189a42bb27SBarry Smith +    da - the DM that defines the grid
71947c6ae99SBarry Smith .    vu - input vector
72047c6ae99SBarry Smith .    vfu - output vector
72147c6ae99SBarry Smith -    w - any user data
72247c6ae99SBarry Smith 
72347c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu upon entry
72447c6ae99SBarry Smith 
72547c6ae99SBarry Smith     Level: advanced
72647c6ae99SBarry Smith 
727aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic()
72847c6ae99SBarry Smith 
72947c6ae99SBarry Smith @*/
730837ad101SBarry Smith PetscErrorCode  DMDAComputeFunction1(DM da,Vec vu,Vec vfu,void *w)
73147c6ae99SBarry Smith {
73247c6ae99SBarry Smith   PetscErrorCode ierr;
73347c6ae99SBarry Smith   void           *u,*fu;
734aa219208SBarry Smith   DMDALocalInfo  info;
73547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
73647c6ae99SBarry Smith 
73747c6ae99SBarry Smith   PetscFunctionBegin;
7388b0a5094SBarry Smith   if (!dd->lf) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_NULL,"DMDASetLocalFunction() never called");
739aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
740aa219208SBarry Smith   ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr);
741aa219208SBarry Smith   ierr = DMDAVecGetArray(da,vfu,&fu);CHKERRQ(ierr);
74247c6ae99SBarry Smith 
74347c6ae99SBarry Smith   CHKMEMQ;
74439d508bbSBarry Smith   ierr = (*dd->lf)(&info,u,fu,w);CHKERRQ(ierr);
74547c6ae99SBarry Smith   CHKMEMQ;
74647c6ae99SBarry Smith 
747aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr);
748aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,vfu,&fu);CHKERRQ(ierr);
74947c6ae99SBarry Smith   PetscFunctionReturn(0);
75047c6ae99SBarry Smith }
75147c6ae99SBarry Smith 
75247c6ae99SBarry Smith #undef __FUNCT__
753837ad101SBarry Smith #define __FUNCT__ "DMDAComputeFunctioniTest1"
754837ad101SBarry Smith PetscErrorCode  DMDAComputeFunctioniTest1(DM da,void *w)
75547c6ae99SBarry Smith {
75647c6ae99SBarry Smith   Vec            vu,fu,fui;
75747c6ae99SBarry Smith   PetscErrorCode ierr;
75847c6ae99SBarry Smith   PetscInt       i,n;
75947c6ae99SBarry Smith   PetscScalar    *ui;
76047c6ae99SBarry Smith   PetscRandom    rnd;
76147c6ae99SBarry Smith   PetscReal      norm;
76247c6ae99SBarry Smith 
76347c6ae99SBarry Smith   PetscFunctionBegin;
7649a42bb27SBarry Smith   ierr = DMGetLocalVector(da,&vu);CHKERRQ(ierr);
76547c6ae99SBarry Smith   ierr = PetscRandomCreate(PETSC_COMM_SELF,&rnd);CHKERRQ(ierr);
76647c6ae99SBarry Smith   ierr = PetscRandomSetFromOptions(rnd);CHKERRQ(ierr);
76747c6ae99SBarry Smith   ierr = VecSetRandom(vu,rnd);CHKERRQ(ierr);
768fcfd50ebSBarry Smith   ierr = PetscRandomDestroy(&rnd);CHKERRQ(ierr);
76947c6ae99SBarry Smith 
7709a42bb27SBarry Smith   ierr = DMGetGlobalVector(da,&fu);CHKERRQ(ierr);
7719a42bb27SBarry Smith   ierr = DMGetGlobalVector(da,&fui);CHKERRQ(ierr);
77247c6ae99SBarry Smith 
773837ad101SBarry Smith   ierr = DMDAComputeFunction1(da,vu,fu,w);CHKERRQ(ierr);
77447c6ae99SBarry Smith 
77547c6ae99SBarry Smith   ierr = VecGetArray(fui,&ui);CHKERRQ(ierr);
77647c6ae99SBarry Smith   ierr = VecGetLocalSize(fui,&n);CHKERRQ(ierr);
77747c6ae99SBarry Smith   for (i=0; i<n; i++) {
778837ad101SBarry Smith     ierr = DMDAComputeFunctioni1(da,i,vu,ui+i,w);CHKERRQ(ierr);
77947c6ae99SBarry Smith   }
78047c6ae99SBarry Smith   ierr = VecRestoreArray(fui,&ui);CHKERRQ(ierr);
78147c6ae99SBarry Smith 
78247c6ae99SBarry Smith   ierr = VecAXPY(fui,-1.0,fu);CHKERRQ(ierr);
78347c6ae99SBarry Smith   ierr = VecNorm(fui,NORM_2,&norm);CHKERRQ(ierr);
78447c6ae99SBarry Smith   ierr = PetscPrintf(((PetscObject)da)->comm,"Norm of difference in vectors %G\n",norm);CHKERRQ(ierr);
78547c6ae99SBarry Smith   ierr = VecView(fu,0);CHKERRQ(ierr);
78647c6ae99SBarry Smith   ierr = VecView(fui,0);CHKERRQ(ierr);
78747c6ae99SBarry Smith 
7889a42bb27SBarry Smith   ierr = DMRestoreLocalVector(da,&vu);CHKERRQ(ierr);
7899a42bb27SBarry Smith   ierr = DMRestoreGlobalVector(da,&fu);CHKERRQ(ierr);
7909a42bb27SBarry Smith   ierr = DMRestoreGlobalVector(da,&fui);CHKERRQ(ierr);
79147c6ae99SBarry Smith   PetscFunctionReturn(0);
79247c6ae99SBarry Smith }
79347c6ae99SBarry Smith 
79447c6ae99SBarry Smith #undef __FUNCT__
795837ad101SBarry Smith #define __FUNCT__ "DMDAComputeFunctioni1"
79647c6ae99SBarry Smith /*@
797837ad101SBarry Smith     DMDAComputeFunctioni1 - Evaluates a user provided point-wise function
79847c6ae99SBarry Smith 
79947c6ae99SBarry Smith    Input Parameters:
8009a42bb27SBarry Smith +    da - the DM that defines the grid
80147c6ae99SBarry Smith .    i - the component of the function we wish to compute (must be local)
80247c6ae99SBarry Smith .    vu - input vector
80347c6ae99SBarry Smith .    vfu - output value
80447c6ae99SBarry Smith -    w - any user data
80547c6ae99SBarry Smith 
80647c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu upon entry
80747c6ae99SBarry Smith 
80847c6ae99SBarry Smith     Level: advanced
80947c6ae99SBarry Smith 
810aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic()
81147c6ae99SBarry Smith 
81247c6ae99SBarry Smith @*/
813837ad101SBarry Smith PetscErrorCode  DMDAComputeFunctioni1(DM da,PetscInt i,Vec vu,PetscScalar *vfu,void *w)
81447c6ae99SBarry Smith {
81547c6ae99SBarry Smith   PetscErrorCode ierr;
81647c6ae99SBarry Smith   void           *u;
817aa219208SBarry Smith   DMDALocalInfo  info;
81847c6ae99SBarry Smith   MatStencil     stencil;
81947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
82047c6ae99SBarry Smith 
82147c6ae99SBarry Smith   PetscFunctionBegin;
82247c6ae99SBarry Smith 
823aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
824aa219208SBarry Smith   ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr);
82547c6ae99SBarry Smith 
82647c6ae99SBarry Smith   /* figure out stencil value from i */
82747c6ae99SBarry Smith   stencil.c = i % info.dof;
82847c6ae99SBarry Smith   stencil.i = (i % (info.xm*info.dof))/info.dof;
82947c6ae99SBarry Smith   stencil.j = (i % (info.xm*info.ym*info.dof))/(info.xm*info.dof);
83047c6ae99SBarry Smith   stencil.k = i/(info.xm*info.ym*info.dof);
83147c6ae99SBarry Smith 
83247c6ae99SBarry Smith   ierr = (*dd->lfi)(&info,&stencil,u,vfu,w);CHKERRQ(ierr);
83347c6ae99SBarry Smith 
834aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr);
83547c6ae99SBarry Smith   PetscFunctionReturn(0);
83647c6ae99SBarry Smith }
83747c6ae99SBarry Smith 
83847c6ae99SBarry Smith #undef __FUNCT__
839837ad101SBarry Smith #define __FUNCT__ "DMDAComputeFunctionib1"
84047c6ae99SBarry Smith /*@
841837ad101SBarry Smith     DMDAComputeFunctionib1 - Evaluates a user provided point-block function
84247c6ae99SBarry Smith 
84347c6ae99SBarry Smith    Input Parameters:
8449a42bb27SBarry Smith +    da - the DM that defines the grid
84547c6ae99SBarry Smith .    i - the component of the function we wish to compute (must be local)
84647c6ae99SBarry Smith .    vu - input vector
84747c6ae99SBarry Smith .    vfu - output value
84847c6ae99SBarry Smith -    w - any user data
84947c6ae99SBarry Smith 
85047c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu upon entry
85147c6ae99SBarry Smith 
85247c6ae99SBarry Smith     Level: advanced
85347c6ae99SBarry Smith 
854aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic()
85547c6ae99SBarry Smith 
85647c6ae99SBarry Smith @*/
857837ad101SBarry Smith PetscErrorCode  DMDAComputeFunctionib1(DM da,PetscInt i,Vec vu,PetscScalar *vfu,void *w)
85847c6ae99SBarry Smith {
85947c6ae99SBarry Smith   PetscErrorCode ierr;
86047c6ae99SBarry Smith   void           *u;
861aa219208SBarry Smith   DMDALocalInfo  info;
86247c6ae99SBarry Smith   MatStencil     stencil;
86347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
86447c6ae99SBarry Smith 
86547c6ae99SBarry Smith   PetscFunctionBegin;
866aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
867aa219208SBarry Smith   ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr);
86847c6ae99SBarry Smith 
86947c6ae99SBarry Smith   /* figure out stencil value from i */
87047c6ae99SBarry Smith   stencil.c = i % info.dof;
87147c6ae99SBarry Smith   if (stencil.c) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Point-block functions can only be called for the entire block");
87247c6ae99SBarry Smith   stencil.i = (i % (info.xm*info.dof))/info.dof;
87347c6ae99SBarry Smith   stencil.j = (i % (info.xm*info.ym*info.dof))/(info.xm*info.dof);
87447c6ae99SBarry Smith   stencil.k = i/(info.xm*info.ym*info.dof);
87547c6ae99SBarry Smith 
87647c6ae99SBarry Smith   ierr = (*dd->lfib)(&info,&stencil,u,vfu,w);CHKERRQ(ierr);
87747c6ae99SBarry Smith 
878aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr);
87947c6ae99SBarry Smith   PetscFunctionReturn(0);
88047c6ae99SBarry Smith }
88147c6ae99SBarry Smith 
88247c6ae99SBarry Smith #if defined(new)
88347c6ae99SBarry Smith #undef __FUNCT__
884aa219208SBarry Smith #define __FUNCT__ "DMDAGetDiagonal_MFFD"
88547c6ae99SBarry Smith /*
886aa219208SBarry Smith   DMDAGetDiagonal_MFFD - Gets the diagonal for a matrix free matrix where local
887aa219208SBarry Smith     function lives on a DMDA
88847c6ae99SBarry Smith 
88947c6ae99SBarry Smith         y ~= (F(u + ha) - F(u))/h,
89047c6ae99SBarry Smith   where F = nonlinear function, as set by SNESSetFunction()
89147c6ae99SBarry Smith         u = current iterate
89247c6ae99SBarry Smith         h = difference interval
89347c6ae99SBarry Smith */
894aa219208SBarry Smith PetscErrorCode DMDAGetDiagonal_MFFD(DM da,Vec U,Vec a)
89547c6ae99SBarry Smith {
89647c6ae99SBarry Smith   PetscScalar    h,*aa,*ww,v;
89747c6ae99SBarry Smith   PetscReal      epsilon = PETSC_SQRT_MACHINE_EPSILON,umin = 100.0*PETSC_SQRT_MACHINE_EPSILON;
89847c6ae99SBarry Smith   PetscErrorCode ierr;
89947c6ae99SBarry Smith   PetscInt       gI,nI;
90047c6ae99SBarry Smith   MatStencil     stencil;
901aa219208SBarry Smith   DMDALocalInfo  info;
90247c6ae99SBarry Smith 
90347c6ae99SBarry Smith   PetscFunctionBegin;
90447c6ae99SBarry Smith   ierr = (*ctx->func)(0,U,a,ctx->funcctx);CHKERRQ(ierr);
90547c6ae99SBarry Smith   ierr = (*ctx->funcisetbase)(U,ctx->funcctx);CHKERRQ(ierr);
90647c6ae99SBarry Smith 
90747c6ae99SBarry Smith   ierr = VecGetArray(U,&ww);CHKERRQ(ierr);
90847c6ae99SBarry Smith   ierr = VecGetArray(a,&aa);CHKERRQ(ierr);
90947c6ae99SBarry Smith 
91047c6ae99SBarry Smith   nI = 0;
91147c6ae99SBarry Smith     h  = ww[gI];
91247c6ae99SBarry Smith     if (h == 0.0) h = 1.0;
91347c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
91447c6ae99SBarry Smith     if (h < umin && h >= 0.0)      h = umin;
91547c6ae99SBarry Smith     else if (h < 0.0 && h > -umin) h = -umin;
91647c6ae99SBarry Smith #else
91747c6ae99SBarry Smith     if (PetscAbsScalar(h) < umin && PetscRealPart(h) >= 0.0)     h = umin;
91847c6ae99SBarry Smith     else if (PetscRealPart(h) < 0.0 && PetscAbsScalar(h) < umin) h = -umin;
91947c6ae99SBarry Smith #endif
92047c6ae99SBarry Smith     h     *= epsilon;
92147c6ae99SBarry Smith 
92247c6ae99SBarry Smith     ww[gI] += h;
92347c6ae99SBarry Smith     ierr          = (*ctx->funci)(i,w,&v,ctx->funcctx);CHKERRQ(ierr);
92447c6ae99SBarry Smith     aa[nI]  = (v - aa[nI])/h;
92547c6ae99SBarry Smith     ww[gI] -= h;
92647c6ae99SBarry Smith     nI++;
92747c6ae99SBarry Smith   }
92847c6ae99SBarry Smith   ierr = VecRestoreArray(U,&ww);CHKERRQ(ierr);
92947c6ae99SBarry Smith   ierr = VecRestoreArray(a,&aa);CHKERRQ(ierr);
93047c6ae99SBarry Smith   PetscFunctionReturn(0);
93147c6ae99SBarry Smith }
93247c6ae99SBarry Smith #endif
93347c6ae99SBarry Smith 
93447c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
93547c6ae99SBarry Smith EXTERN_C_BEGIN
936c6db04a5SJed Brown #include <adic/ad_utils.h>
93747c6ae99SBarry Smith EXTERN_C_END
93847c6ae99SBarry Smith 
93947c6ae99SBarry Smith #undef __FUNCT__
940aa219208SBarry Smith #define __FUNCT__ "DMDAComputeJacobian1WithAdic"
94147c6ae99SBarry Smith /*@C
942aa219208SBarry Smith     DMDAComputeJacobian1WithAdic - Evaluates a adiC provided Jacobian function on each processor that
943aa219208SBarry Smith         share a DMDA
94447c6ae99SBarry Smith 
94547c6ae99SBarry Smith    Input Parameters:
9469a42bb27SBarry Smith +    da - the DM that defines the grid
94747c6ae99SBarry Smith .    vu - input vector (ghosted)
94847c6ae99SBarry Smith .    J - output matrix
94947c6ae99SBarry Smith -    w - any user data
95047c6ae99SBarry Smith 
95147c6ae99SBarry Smith    Level: advanced
95247c6ae99SBarry Smith 
95347c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu upon entry
95447c6ae99SBarry Smith 
955837ad101SBarry Smith .seealso: DMDAComputeFunction1()
95647c6ae99SBarry Smith 
95747c6ae99SBarry Smith @*/
9587087cfbeSBarry Smith PetscErrorCode  DMDAComputeJacobian1WithAdic(DM da,Vec vu,Mat J,void *w)
95947c6ae99SBarry Smith {
96047c6ae99SBarry Smith   PetscErrorCode ierr;
96147c6ae99SBarry Smith   PetscInt       gtdof,tdof;
96247c6ae99SBarry Smith   PetscScalar    *ustart;
963aa219208SBarry Smith   DMDALocalInfo  info;
96447c6ae99SBarry Smith   void           *ad_u,*ad_f,*ad_ustart,*ad_fstart;
96547c6ae99SBarry Smith   ISColoring     iscoloring;
96647c6ae99SBarry Smith 
96747c6ae99SBarry Smith   PetscFunctionBegin;
968aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
96947c6ae99SBarry Smith 
97047c6ae99SBarry Smith   PetscADResetIndep();
97147c6ae99SBarry Smith 
97247c6ae99SBarry Smith   /* get space for derivative objects.  */
973aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,PETSC_TRUE,&ad_u,&ad_ustart,&gtdof);CHKERRQ(ierr);
974aa219208SBarry Smith   ierr = DMDAGetAdicArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr);
97547c6ae99SBarry Smith   ierr = VecGetArray(vu,&ustart);CHKERRQ(ierr);
976e727c939SJed Brown   ierr = DMCreateColoring(da,IS_COLORING_GHOSTED,MATAIJ,&iscoloring);CHKERRQ(ierr);
97747c6ae99SBarry Smith 
97847c6ae99SBarry Smith   PetscADSetValueAndColor(ad_ustart,gtdof,iscoloring->colors,ustart);
97947c6ae99SBarry Smith 
98047c6ae99SBarry Smith   ierr = VecRestoreArray(vu,&ustart);CHKERRQ(ierr);
981fcfd50ebSBarry Smith   ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
98247c6ae99SBarry Smith   ierr = PetscADIncrementTotalGradSize(iscoloring->n);CHKERRQ(ierr);
98347c6ae99SBarry Smith   PetscADSetIndepDone();
98447c6ae99SBarry Smith 
985aa219208SBarry Smith   ierr = PetscLogEventBegin(DMDA_LocalADFunction,0,0,0,0);CHKERRQ(ierr);
98647c6ae99SBarry Smith   ierr = (*dd->adic_lf)(&info,ad_u,ad_f,w);CHKERRQ(ierr);
987aa219208SBarry Smith   ierr = PetscLogEventEnd(DMDA_LocalADFunction,0,0,0,0);CHKERRQ(ierr);
98847c6ae99SBarry Smith 
98947c6ae99SBarry Smith   /* stick the values into the matrix */
99047c6ae99SBarry Smith   ierr = MatSetValuesAdic(J,(PetscScalar**)ad_fstart);CHKERRQ(ierr);
99147c6ae99SBarry Smith 
99247c6ae99SBarry Smith   /* return space for derivative objects.  */
993aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,PETSC_TRUE,&ad_u,&ad_ustart,&gtdof);CHKERRQ(ierr);
994aa219208SBarry Smith   ierr = DMDARestoreAdicArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr);
99547c6ae99SBarry Smith   PetscFunctionReturn(0);
99647c6ae99SBarry Smith }
99747c6ae99SBarry Smith 
99847c6ae99SBarry Smith #undef __FUNCT__
999aa219208SBarry Smith #define __FUNCT__ "DMDAMultiplyByJacobian1WithAdic"
100047c6ae99SBarry Smith /*@C
1001aa219208SBarry Smith     DMDAMultiplyByJacobian1WithAdic - Applies an ADIC-provided Jacobian function to a vector on
1002aa219208SBarry Smith     each processor that shares a DMDA.
100347c6ae99SBarry Smith 
100447c6ae99SBarry Smith     Input Parameters:
10059a42bb27SBarry Smith +   da - the DM that defines the grid
100647c6ae99SBarry Smith .   vu - Jacobian is computed at this point (ghosted)
100747c6ae99SBarry Smith .   v - product is done on this vector (ghosted)
100847c6ae99SBarry Smith .   fu - output vector = J(vu)*v (not ghosted)
100947c6ae99SBarry Smith -   w - any user data
101047c6ae99SBarry Smith 
101147c6ae99SBarry Smith     Notes:
101247c6ae99SBarry Smith     This routine does NOT do ghost updates on vu upon entry.
101347c6ae99SBarry Smith 
101447c6ae99SBarry Smith    Level: advanced
101547c6ae99SBarry Smith 
1016837ad101SBarry Smith .seealso: DMDAComputeFunction1()
101747c6ae99SBarry Smith 
101847c6ae99SBarry Smith @*/
10197087cfbeSBarry Smith PetscErrorCode  DMDAMultiplyByJacobian1WithAdic(DM da,Vec vu,Vec v,Vec f,void *w)
102047c6ae99SBarry Smith {
102147c6ae99SBarry Smith   PetscErrorCode ierr;
102247c6ae99SBarry Smith   PetscInt       i,gtdof,tdof;
102347c6ae99SBarry Smith   PetscScalar    *avu,*av,*af,*ad_vustart,*ad_fstart;
1024aa219208SBarry Smith   DMDALocalInfo  info;
102547c6ae99SBarry Smith   void           *ad_vu,*ad_f;
102647c6ae99SBarry Smith 
102747c6ae99SBarry Smith   PetscFunctionBegin;
1028aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
102947c6ae99SBarry Smith 
103047c6ae99SBarry Smith   /* get space for derivative objects.  */
1031aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,PETSC_TRUE,&ad_vu,&ad_vustart,&gtdof);CHKERRQ(ierr);
1032aa219208SBarry Smith   ierr = DMDAGetAdicMFArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr);
103347c6ae99SBarry Smith 
103447c6ae99SBarry Smith   /* copy input vector into derivative object */
103547c6ae99SBarry Smith   ierr = VecGetArray(vu,&avu);CHKERRQ(ierr);
103647c6ae99SBarry Smith   ierr = VecGetArray(v,&av);CHKERRQ(ierr);
103747c6ae99SBarry Smith   for (i=0; i<gtdof; i++) {
103847c6ae99SBarry Smith     ad_vustart[2*i]   = avu[i];
103947c6ae99SBarry Smith     ad_vustart[2*i+1] = av[i];
104047c6ae99SBarry Smith   }
104147c6ae99SBarry Smith   ierr = VecRestoreArray(vu,&avu);CHKERRQ(ierr);
104247c6ae99SBarry Smith   ierr = VecRestoreArray(v,&av);CHKERRQ(ierr);
104347c6ae99SBarry Smith 
104447c6ae99SBarry Smith   PetscADResetIndep();
104547c6ae99SBarry Smith   ierr = PetscADIncrementTotalGradSize(1);CHKERRQ(ierr);
104647c6ae99SBarry Smith   PetscADSetIndepDone();
104747c6ae99SBarry Smith 
104847c6ae99SBarry Smith   ierr = (*dd->adicmf_lf)(&info,ad_vu,ad_f,w);CHKERRQ(ierr);
104947c6ae99SBarry Smith 
105047c6ae99SBarry Smith   /* stick the values into the vector */
105147c6ae99SBarry Smith   ierr = VecGetArray(f,&af);CHKERRQ(ierr);
105247c6ae99SBarry Smith   for (i=0; i<tdof; i++) {
105347c6ae99SBarry Smith     af[i] = ad_fstart[2*i+1];
105447c6ae99SBarry Smith   }
105547c6ae99SBarry Smith   ierr = VecRestoreArray(f,&af);CHKERRQ(ierr);
105647c6ae99SBarry Smith 
105747c6ae99SBarry Smith   /* return space for derivative objects.  */
1058aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,PETSC_TRUE,&ad_vu,&ad_vustart,&gtdof);CHKERRQ(ierr);
1059aa219208SBarry Smith   ierr = DMDARestoreAdicMFArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr);
106047c6ae99SBarry Smith   PetscFunctionReturn(0);
106147c6ae99SBarry Smith }
106247c6ae99SBarry Smith #endif
106347c6ae99SBarry Smith 
106447c6ae99SBarry Smith #undef __FUNCT__
1065aa219208SBarry Smith #define __FUNCT__ "DMDAComputeJacobian1"
106647c6ae99SBarry Smith /*@
1067aa219208SBarry Smith     DMDAComputeJacobian1 - Evaluates a local Jacobian function on each processor that
1068aa219208SBarry Smith         share a DMDA
106947c6ae99SBarry Smith 
107047c6ae99SBarry Smith    Input Parameters:
10719a42bb27SBarry Smith +    da - the DM that defines the grid
107247c6ae99SBarry Smith .    vu - input vector (ghosted)
107347c6ae99SBarry Smith .    J - output matrix
107447c6ae99SBarry Smith -    w - any user data
107547c6ae99SBarry Smith 
107647c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu upon entry
107747c6ae99SBarry Smith 
107847c6ae99SBarry Smith     Level: advanced
107947c6ae99SBarry Smith 
1080837ad101SBarry Smith .seealso: DMDAComputeFunction1()
108147c6ae99SBarry Smith 
108247c6ae99SBarry Smith @*/
10837087cfbeSBarry Smith PetscErrorCode  DMDAComputeJacobian1(DM da,Vec vu,Mat J,void *w)
108447c6ae99SBarry Smith {
108547c6ae99SBarry Smith   PetscErrorCode ierr;
108647c6ae99SBarry Smith   void           *u;
1087aa219208SBarry Smith   DMDALocalInfo  info;
108847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
108947c6ae99SBarry Smith 
109047c6ae99SBarry Smith   PetscFunctionBegin;
1091aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
1092aa219208SBarry Smith   ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr);
109347c6ae99SBarry Smith   ierr = (*dd->lj)(&info,u,J,w);CHKERRQ(ierr);
1094aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr);
109547c6ae99SBarry Smith   PetscFunctionReturn(0);
109647c6ae99SBarry Smith }
109747c6ae99SBarry Smith 
109847c6ae99SBarry Smith 
109947c6ae99SBarry Smith #undef __FUNCT__
1100aa219208SBarry Smith #define __FUNCT__ "DMDAComputeJacobian1WithAdifor"
110147c6ae99SBarry Smith /*
1102aa219208SBarry Smith     DMDAComputeJacobian1WithAdifor - Evaluates a ADIFOR provided Jacobian local function on each processor that
1103aa219208SBarry Smith         share a DMDA
110447c6ae99SBarry Smith 
110547c6ae99SBarry Smith    Input Parameters:
11069a42bb27SBarry Smith +    da - the DM that defines the grid
110747c6ae99SBarry Smith .    vu - input vector (ghosted)
110847c6ae99SBarry Smith .    J - output matrix
110947c6ae99SBarry Smith -    w - any user data
111047c6ae99SBarry Smith 
111147c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu upon entry
111247c6ae99SBarry Smith 
1113837ad101SBarry Smith .seealso: DMDAComputeFunction1()
111447c6ae99SBarry Smith 
111547c6ae99SBarry Smith */
11167087cfbeSBarry Smith PetscErrorCode  DMDAComputeJacobian1WithAdifor(DM da,Vec vu,Mat J,void *w)
111747c6ae99SBarry Smith {
111847c6ae99SBarry Smith   PetscErrorCode  ierr;
111947c6ae99SBarry Smith   PetscInt        i,Nc,N;
112047c6ae99SBarry Smith   ISColoringValue *color;
1121aa219208SBarry Smith   DMDALocalInfo   info;
112247c6ae99SBarry Smith   PetscScalar     *u,*g_u,*g_f,*f = 0,*p_u;
112347c6ae99SBarry Smith   ISColoring      iscoloring;
112447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
1125aa219208SBarry Smith   void            (*lf)(PetscInt*,DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscInt*,PetscScalar*,PetscScalar*,PetscInt*,void*,PetscErrorCode*) =
1126aa219208SBarry Smith                   (void (*)(PetscInt*,DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscInt*,PetscScalar*,PetscScalar*,PetscInt*,void*,PetscErrorCode*))*dd->adifor_lf;
112747c6ae99SBarry Smith 
112847c6ae99SBarry Smith   PetscFunctionBegin;
1129e727c939SJed Brown   ierr = DMCreateColoring(da,IS_COLORING_GHOSTED,MATAIJ,&iscoloring);CHKERRQ(ierr);
113047c6ae99SBarry Smith   Nc   = iscoloring->n;
1131aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
113247c6ae99SBarry Smith   N    = info.gxm*info.gym*info.gzm*info.dof;
113347c6ae99SBarry Smith 
113447c6ae99SBarry Smith   /* get space for derivative objects.  */
113547c6ae99SBarry Smith   ierr  = PetscMalloc(Nc*info.gxm*info.gym*info.gzm*info.dof*sizeof(PetscScalar),&g_u);CHKERRQ(ierr);
113647c6ae99SBarry Smith   ierr  = PetscMemzero(g_u,Nc*info.gxm*info.gym*info.gzm*info.dof*sizeof(PetscScalar));CHKERRQ(ierr);
113747c6ae99SBarry Smith   p_u   = g_u;
113847c6ae99SBarry Smith   color = iscoloring->colors;
113947c6ae99SBarry Smith   for (i=0; i<N; i++) {
114047c6ae99SBarry Smith     p_u[*color++] = 1.0;
114147c6ae99SBarry Smith     p_u          += Nc;
114247c6ae99SBarry Smith   }
1143fcfd50ebSBarry Smith   ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
114447c6ae99SBarry Smith   ierr = PetscMalloc2(Nc*info.xm*info.ym*info.zm*info.dof,PetscScalar,&g_f,info.xm*info.ym*info.zm*info.dof,PetscScalar,&f);CHKERRQ(ierr);
114547c6ae99SBarry Smith 
114647c6ae99SBarry Smith   /* Seed the input array g_u with coloring information */
114747c6ae99SBarry Smith 
114847c6ae99SBarry Smith   ierr = VecGetArray(vu,&u);CHKERRQ(ierr);
114947c6ae99SBarry Smith   (lf)(&Nc,&info,u,g_u,&Nc,f,g_f,&Nc,w,&ierr);CHKERRQ(ierr);
115047c6ae99SBarry Smith   ierr = VecRestoreArray(vu,&u);CHKERRQ(ierr);
115147c6ae99SBarry Smith 
115247c6ae99SBarry Smith   /* stick the values into the matrix */
115347c6ae99SBarry Smith   /* PetscScalarView(Nc*info.xm*info.ym,g_f,0); */
115447c6ae99SBarry Smith   ierr = MatSetValuesAdifor(J,Nc,g_f);CHKERRQ(ierr);
115547c6ae99SBarry Smith 
115647c6ae99SBarry Smith   /* return space for derivative objects.  */
115747c6ae99SBarry Smith   ierr = PetscFree(g_u);CHKERRQ(ierr);
115847c6ae99SBarry Smith   ierr = PetscFree2(g_f,f);CHKERRQ(ierr);
115947c6ae99SBarry Smith   PetscFunctionReturn(0);
116047c6ae99SBarry Smith }
116147c6ae99SBarry Smith 
116247c6ae99SBarry Smith #undef __FUNCT__
1163aa219208SBarry Smith #define __FUNCT__ "DMDAFormJacobianLocal"
116447c6ae99SBarry Smith /*@C
1165aa219208SBarry Smith    DMDAFormjacobianLocal - This is a universal Jacobian evaluation routine for
11669a42bb27SBarry Smith    a local DM function.
116747c6ae99SBarry Smith 
1168aa219208SBarry Smith    Collective on DMDA
116947c6ae99SBarry Smith 
117047c6ae99SBarry Smith    Input Parameters:
11719a42bb27SBarry Smith +  da - the DM context
117247c6ae99SBarry Smith .  func - The local function
117347c6ae99SBarry Smith .  X - input vector
117447c6ae99SBarry Smith .  J - Jacobian matrix
117547c6ae99SBarry Smith -  ctx - A user context
117647c6ae99SBarry Smith 
117747c6ae99SBarry Smith    Level: intermediate
117847c6ae99SBarry Smith 
1179aa219208SBarry Smith .seealso: DMDASetLocalFunction(), DMDASetLocalJacobian(), DMDASetLocalAdicFunction(), DMDASetLocalAdicMFFunction(),
118047c6ae99SBarry Smith           SNESSetFunction(), SNESSetJacobian()
118147c6ae99SBarry Smith 
118247c6ae99SBarry Smith @*/
11837087cfbeSBarry Smith PetscErrorCode  DMDAFormJacobianLocal(DM da, DMDALocalFunction1 func, Vec X, Mat J, void *ctx)
118447c6ae99SBarry Smith {
118547c6ae99SBarry Smith   Vec            localX;
1186aa219208SBarry Smith   DMDALocalInfo  info;
118747c6ae99SBarry Smith   void           *u;
118847c6ae99SBarry Smith   PetscErrorCode ierr;
118947c6ae99SBarry Smith 
119047c6ae99SBarry Smith   PetscFunctionBegin;
11919a42bb27SBarry Smith   ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr);
119247c6ae99SBarry Smith   /*
119347c6ae99SBarry Smith      Scatter ghost points to local vector, using the 2-step process
11949a42bb27SBarry Smith         DMGlobalToLocalBegin(), DMGlobalToLocalEnd().
119547c6ae99SBarry Smith   */
11969a42bb27SBarry Smith   ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
11979a42bb27SBarry Smith   ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
1198aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
1199aa219208SBarry Smith   ierr = DMDAVecGetArray(da,localX,&u);CHKERRQ(ierr);
120039d508bbSBarry Smith   ierr = (*func)(&info,u,J,ctx);CHKERRQ(ierr);
1201aa219208SBarry Smith   ierr = DMDAVecRestoreArray(da,localX,&u);CHKERRQ(ierr);
12029a42bb27SBarry Smith   ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr);
120347c6ae99SBarry Smith   PetscFunctionReturn(0);
120447c6ae99SBarry Smith }
120547c6ae99SBarry Smith 
120647c6ae99SBarry Smith #undef __FUNCT__
1207aa219208SBarry Smith #define __FUNCT__ "DMDAMultiplyByJacobian1WithAD"
120847c6ae99SBarry Smith /*@C
1209aa219208SBarry Smith     DMDAMultiplyByJacobian1WithAD - Applies a Jacobian function supplied by ADIFOR or ADIC
1210aa219208SBarry Smith     to a vector on each processor that shares a DMDA.
121147c6ae99SBarry Smith 
121247c6ae99SBarry Smith    Input Parameters:
12139a42bb27SBarry Smith +    da - the DM that defines the grid
121447c6ae99SBarry Smith .    vu - Jacobian is computed at this point (ghosted)
121547c6ae99SBarry Smith .    v - product is done on this vector (ghosted)
121647c6ae99SBarry Smith .    fu - output vector = J(vu)*v (not ghosted)
121747c6ae99SBarry Smith -    w - any user data
121847c6ae99SBarry Smith 
121947c6ae99SBarry Smith     Notes:
122047c6ae99SBarry Smith     This routine does NOT do ghost updates on vu and v upon entry.
122147c6ae99SBarry Smith 
1222aa219208SBarry Smith     Automatically calls DMDAMultiplyByJacobian1WithAdifor() or DMDAMultiplyByJacobian1WithAdic()
1223aa219208SBarry Smith     depending on whether DMDASetLocalAdicMFFunction() or DMDASetLocalAdiforMFFunction() was called.
122447c6ae99SBarry Smith 
122547c6ae99SBarry Smith    Level: advanced
122647c6ae99SBarry Smith 
1227837ad101SBarry Smith .seealso: DMDAComputeFunction1(), DMDAMultiplyByJacobian1WithAdifor(), DMDAMultiplyByJacobian1WithAdic()
122847c6ae99SBarry Smith 
122947c6ae99SBarry Smith @*/
12307087cfbeSBarry Smith PetscErrorCode  DMDAMultiplyByJacobian1WithAD(DM da,Vec u,Vec v,Vec f,void *w)
123147c6ae99SBarry Smith {
123247c6ae99SBarry Smith   PetscErrorCode ierr;
123347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
123447c6ae99SBarry Smith 
123547c6ae99SBarry Smith   PetscFunctionBegin;
123647c6ae99SBarry Smith   if (dd->adicmf_lf) {
123747c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC)
1238aa219208SBarry Smith     ierr = DMDAMultiplyByJacobian1WithAdic(da,u,v,f,w);CHKERRQ(ierr);
123947c6ae99SBarry Smith #else
124047c6ae99SBarry Smith     SETERRQ(((PetscObject)da)->comm,PETSC_ERR_SUP_SYS,"Requires ADIC to be installed and cannot use complex numbers");
124147c6ae99SBarry Smith #endif
124247c6ae99SBarry Smith   } else if (dd->adiformf_lf) {
1243aa219208SBarry Smith     ierr = DMDAMultiplyByJacobian1WithAdifor(da,u,v,f,w);CHKERRQ(ierr);
124430729d88SBarry Smith   } else SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ORDER,"Must call DMDASetLocalAdiforMFFunction() or DMDASetLocalAdicMFFunction() before using");
124547c6ae99SBarry Smith   PetscFunctionReturn(0);
124647c6ae99SBarry Smith }
124747c6ae99SBarry Smith 
124847c6ae99SBarry Smith 
124947c6ae99SBarry Smith #undef __FUNCT__
1250aa219208SBarry Smith #define __FUNCT__ "DMDAMultiplyByJacobian1WithAdifor"
125147c6ae99SBarry Smith /*@C
1252aa219208SBarry Smith     DMDAMultiplyByJacobian1WithAdifor - Applies a ADIFOR provided Jacobian function on each processor that
12539a42bb27SBarry Smith         share a DM to a vector
125447c6ae99SBarry Smith 
125547c6ae99SBarry Smith    Input Parameters:
12569a42bb27SBarry Smith +    da - the DM that defines the grid
125747c6ae99SBarry Smith .    vu - Jacobian is computed at this point (ghosted)
125847c6ae99SBarry Smith .    v - product is done on this vector (ghosted)
125947c6ae99SBarry Smith .    fu - output vector = J(vu)*v (not ghosted)
126047c6ae99SBarry Smith -    w - any user data
126147c6ae99SBarry Smith 
126247c6ae99SBarry Smith     Notes: Does NOT do ghost updates on vu and v upon entry
126347c6ae99SBarry Smith 
126447c6ae99SBarry Smith    Level: advanced
126547c6ae99SBarry Smith 
1266837ad101SBarry Smith .seealso: DMDAComputeFunction1()
126747c6ae99SBarry Smith 
126847c6ae99SBarry Smith @*/
12697087cfbeSBarry Smith PetscErrorCode  DMDAMultiplyByJacobian1WithAdifor(DM da,Vec u,Vec v,Vec f,void *w)
127047c6ae99SBarry Smith {
127147c6ae99SBarry Smith   PetscErrorCode ierr;
127247c6ae99SBarry Smith   PetscScalar    *au,*av,*af,*awork;
127347c6ae99SBarry Smith   Vec            work;
1274aa219208SBarry Smith   DMDALocalInfo  info;
127547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
1276aa219208SBarry Smith   void           (*lf)(DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,void*,PetscErrorCode*) =
1277aa219208SBarry Smith                  (void (*)(DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,void*,PetscErrorCode*))*dd->adiformf_lf;
127847c6ae99SBarry Smith 
127947c6ae99SBarry Smith   PetscFunctionBegin;
1280aa219208SBarry Smith   ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
128147c6ae99SBarry Smith 
12829a42bb27SBarry Smith   ierr = DMGetGlobalVector(da,&work);CHKERRQ(ierr);
128347c6ae99SBarry Smith   ierr = VecGetArray(u,&au);CHKERRQ(ierr);
128447c6ae99SBarry Smith   ierr = VecGetArray(v,&av);CHKERRQ(ierr);
128547c6ae99SBarry Smith   ierr = VecGetArray(f,&af);CHKERRQ(ierr);
128647c6ae99SBarry Smith   ierr = VecGetArray(work,&awork);CHKERRQ(ierr);
128747c6ae99SBarry Smith   (lf)(&info,au,av,awork,af,w,&ierr);CHKERRQ(ierr);
128847c6ae99SBarry Smith   ierr = VecRestoreArray(u,&au);CHKERRQ(ierr);
128947c6ae99SBarry Smith   ierr = VecRestoreArray(v,&av);CHKERRQ(ierr);
129047c6ae99SBarry Smith   ierr = VecRestoreArray(f,&af);CHKERRQ(ierr);
129147c6ae99SBarry Smith   ierr = VecRestoreArray(work,&awork);CHKERRQ(ierr);
12929a42bb27SBarry Smith   ierr = DMRestoreGlobalVector(da,&work);CHKERRQ(ierr);
129347c6ae99SBarry Smith 
129447c6ae99SBarry Smith   PetscFunctionReturn(0);
129547c6ae99SBarry Smith }
129647c6ae99SBarry Smith 
129747c6ae99SBarry Smith #undef __FUNCT__
12989a42bb27SBarry Smith #define __FUNCT__ "DMSetUp_DA_2D"
12997087cfbeSBarry Smith PetscErrorCode  DMSetUp_DA_2D(DM da)
130047c6ae99SBarry Smith {
130147c6ae99SBarry Smith   DM_DA                  *dd = (DM_DA*)da->data;
130247c6ae99SBarry Smith   const PetscInt         M            = dd->M;
130347c6ae99SBarry Smith   const PetscInt         N            = dd->N;
130447c6ae99SBarry Smith   PetscInt               m            = dd->m;
130547c6ae99SBarry Smith   PetscInt               n            = dd->n;
130688661749SPeter Brune   PetscInt               o            = dd->overlap;
130747c6ae99SBarry Smith   const PetscInt         dof          = dd->w;
130847c6ae99SBarry Smith   const PetscInt         s            = dd->s;
13091321219cSEthan Coon   const DMDABoundaryType bx         = dd->bx;
13101321219cSEthan Coon   const DMDABoundaryType by         = dd->by;
1311aa219208SBarry Smith   const DMDAStencilType  stencil_type = dd->stencil_type;
131247c6ae99SBarry Smith   PetscInt               *lx           = dd->lx;
131347c6ae99SBarry Smith   PetscInt               *ly           = dd->ly;
131447c6ae99SBarry Smith   MPI_Comm               comm;
131547c6ae99SBarry Smith   PetscMPIInt            rank,size;
1316ce00eea3SSatish Balay   PetscInt               xs,xe,ys,ye,x,y,Xs,Xe,Ys,Ye,start,end,IXs,IXe,IYs,IYe;
1317ce00eea3SSatish Balay   PetscInt               up,down,left,right,i,n0,n1,n2,n3,n5,n6,n7,n8,*idx,nn,*idx_cpy;
1318ce00eea3SSatish Balay   const PetscInt         *idx_full;
1319db87c5ecSEthan Coon   PetscInt               xbase,*bases,*ldims,j,x_t,y_t,s_t,base,count;
132047c6ae99SBarry Smith   PetscInt               s_x,s_y; /* s proportionalized to w */
132147c6ae99SBarry Smith   PetscInt               sn0 = 0,sn2 = 0,sn6 = 0,sn8 = 0;
132247c6ae99SBarry Smith   Vec                    local,global;
132347c6ae99SBarry Smith   VecScatter             ltog,gtol;
1324ce00eea3SSatish Balay   IS                     to,from,ltogis;
132547c6ae99SBarry Smith   PetscErrorCode         ierr;
132647c6ae99SBarry Smith 
132747c6ae99SBarry Smith   PetscFunctionBegin;
13283855c12bSBarry Smith   if (dof < 1) SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have 1 or more degrees of freedom per node: %D",dof);
13293855c12bSBarry Smith   if (s < 0) SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Stencil width cannot be negative: %D",s);
133047c6ae99SBarry Smith   ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr);
13313855c12bSBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
13323855c12bSBarry Smith   if (((Petsc64bitInt) M)*((Petsc64bitInt) N)*((Petsc64bitInt) dof) > (Petsc64bitInt) PETSC_MPI_INT_MAX) SETERRQ3(comm,PETSC_ERR_INT_OVERFLOW,"Mesh of %D by %D by %D (dof) is too large for 32 bit indices",M,N,dof);
13333855c12bSBarry Smith #endif
133447c6ae99SBarry Smith 
133547c6ae99SBarry Smith   if (dof < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have 1 or more degrees of freedom per node: %D",dof);
133647c6ae99SBarry Smith   if (s < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Stencil width cannot be negative: %D",s);
133747c6ae99SBarry Smith 
133847c6ae99SBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
133947c6ae99SBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
134047c6ae99SBarry Smith 
134147c6ae99SBarry Smith   dd->dim         = 2;
134247c6ae99SBarry Smith   ierr = PetscMalloc(dof*sizeof(char*),&dd->fieldname);CHKERRQ(ierr);
134347c6ae99SBarry Smith   ierr = PetscMemzero(dd->fieldname,dof*sizeof(char*));CHKERRQ(ierr);
134447c6ae99SBarry Smith 
134547c6ae99SBarry Smith   if (m != PETSC_DECIDE) {
134647c6ae99SBarry Smith     if (m < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in X direction: %D",m);
134747c6ae99SBarry Smith     else if (m > size) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in X direction: %D %d",m,size);
134847c6ae99SBarry Smith   }
134947c6ae99SBarry Smith   if (n != PETSC_DECIDE) {
135047c6ae99SBarry Smith     if (n < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in Y direction: %D",n);
135147c6ae99SBarry Smith     else if (n > size) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in Y direction: %D %d",n,size);
135247c6ae99SBarry Smith   }
135347c6ae99SBarry Smith 
135447c6ae99SBarry Smith   if (m == PETSC_DECIDE || n == PETSC_DECIDE) {
135547c6ae99SBarry Smith     if (n != PETSC_DECIDE) {
135647c6ae99SBarry Smith       m = size/n;
135747c6ae99SBarry Smith     } else if (m != PETSC_DECIDE) {
135847c6ae99SBarry Smith       n = size/m;
135947c6ae99SBarry Smith     } else {
136047c6ae99SBarry Smith       /* try for squarish distribution */
136147c6ae99SBarry Smith       m = (PetscInt)(0.5 + sqrt(((double)M)*((double)size)/((double)N)));
136247c6ae99SBarry Smith       if (!m) m = 1;
136347c6ae99SBarry Smith       while (m > 0) {
136447c6ae99SBarry Smith 	n = size/m;
136547c6ae99SBarry Smith 	if (m*n == size) break;
136647c6ae99SBarry Smith 	m--;
136747c6ae99SBarry Smith       }
136847c6ae99SBarry Smith       if (M > N && m < n) {PetscInt _m = m; m = n; n = _m;}
136947c6ae99SBarry Smith     }
137047c6ae99SBarry Smith     if (m*n != size) SETERRQ(comm,PETSC_ERR_PLIB,"Unable to create partition, check the size of the communicator and input m and n ");
137147c6ae99SBarry Smith   } else if (m*n != size) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Given Bad partition");
137247c6ae99SBarry Smith 
137347c6ae99SBarry Smith   if (M < m) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in x direction is too fine! %D %D",M,m);
137447c6ae99SBarry Smith   if (N < n) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in y direction is too fine! %D %D",N,n);
137547c6ae99SBarry Smith 
137647c6ae99SBarry Smith   /*
137747c6ae99SBarry Smith      Determine locally owned region
137847c6ae99SBarry Smith      xs is the first local node number, x is the number of local nodes
137947c6ae99SBarry Smith   */
138047c6ae99SBarry Smith   if (!lx) {
138147c6ae99SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt), &dd->lx);CHKERRQ(ierr);
138247c6ae99SBarry Smith     lx = dd->lx;
138347c6ae99SBarry Smith     for (i=0; i<m; i++) {
138447c6ae99SBarry Smith       lx[i] = M/m + ((M % m) > i);
138547c6ae99SBarry Smith     }
138647c6ae99SBarry Smith   }
138747c6ae99SBarry Smith   x  = lx[rank % m];
138847c6ae99SBarry Smith   xs = 0;
138947c6ae99SBarry Smith   for (i=0; i<(rank % m); i++) {
139047c6ae99SBarry Smith     xs += lx[i];
139147c6ae99SBarry Smith   }
139247c6ae99SBarry Smith #if defined(PETSC_USE_DEBUG)
139347c6ae99SBarry Smith   left = xs;
139447c6ae99SBarry Smith   for (i=(rank % m); i<m; i++) {
139547c6ae99SBarry Smith     left += lx[i];
139647c6ae99SBarry Smith   }
139747c6ae99SBarry Smith   if (left != M) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Sum of lx across processors not equal to M: %D %D",left,M);
139847c6ae99SBarry Smith #endif
139947c6ae99SBarry Smith 
140047c6ae99SBarry Smith   /*
140147c6ae99SBarry Smith      Determine locally owned region
140247c6ae99SBarry Smith      ys is the first local node number, y is the number of local nodes
140347c6ae99SBarry Smith   */
140447c6ae99SBarry Smith   if (!ly) {
140547c6ae99SBarry Smith     ierr = PetscMalloc(n*sizeof(PetscInt), &dd->ly);CHKERRQ(ierr);
140647c6ae99SBarry Smith     ly = dd->ly;
140747c6ae99SBarry Smith     for (i=0; i<n; i++) {
140847c6ae99SBarry Smith       ly[i] = N/n + ((N % n) > i);
140947c6ae99SBarry Smith     }
141047c6ae99SBarry Smith   }
141147c6ae99SBarry Smith   y  = ly[rank/m];
141247c6ae99SBarry Smith   ys = 0;
141347c6ae99SBarry Smith   for (i=0; i<(rank/m); i++) {
141447c6ae99SBarry Smith     ys += ly[i];
141547c6ae99SBarry Smith   }
141647c6ae99SBarry Smith #if defined(PETSC_USE_DEBUG)
141747c6ae99SBarry Smith   left = ys;
141847c6ae99SBarry Smith   for (i=(rank/m); i<n; i++) {
141947c6ae99SBarry Smith     left += ly[i];
142047c6ae99SBarry Smith   }
142147c6ae99SBarry Smith   if (left != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Sum of ly across processors not equal to N: %D %D",left,N);
142247c6ae99SBarry Smith #endif
142347c6ae99SBarry Smith 
1424bcea557cSEthan Coon   /*
1425bcea557cSEthan Coon    check if the scatter requires more than one process neighbor or wraps around
1426bcea557cSEthan Coon    the domain more than once
1427bcea557cSEthan Coon   */
142888661749SPeter Brune   if ((x < s+o) && ((m > 1) || (bx == DMDA_BOUNDARY_PERIODIC))) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local x-width of domain x %D is smaller than stencil width s %D",x,s+o);
142988661749SPeter Brune   if ((y < s+o) && ((n > 1) || (by == DMDA_BOUNDARY_PERIODIC))) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local y-width of domain y %D is smaller than stencil width s %D",y,s+o);
143047c6ae99SBarry Smith   xe = xs + x;
143147c6ae99SBarry Smith   ye = ys + y;
143247c6ae99SBarry Smith 
1433ce00eea3SSatish Balay   /* determine ghost region (Xs) and region scattered into (IXs)  */
143488661749SPeter Brune   if (xs-s-o > 0) {
143588661749SPeter Brune     Xs = xs - s - o; IXs = xs - s - o;
143688661749SPeter Brune   } else {
143788661749SPeter Brune     if (bx) {
143888661749SPeter Brune       Xs = xs - s;
143988661749SPeter Brune     } else {
144088661749SPeter Brune       Xs = 0;
144188661749SPeter Brune     }
144288661749SPeter Brune     IXs = 0;
144388661749SPeter Brune   }
144488661749SPeter Brune   if (xe+s+o <= M) {
144588661749SPeter Brune     Xe = xe + s + o; IXe = xe + s + o;
144688661749SPeter Brune   } else {
144788661749SPeter Brune     if (bx) {
144888661749SPeter Brune       Xs = xs - s - o; Xe = xe + s;
144988661749SPeter Brune     } else {
145088661749SPeter Brune       Xe = M;
145188661749SPeter Brune     }
145288661749SPeter Brune     IXe = M;
145388661749SPeter Brune   }
145447c6ae99SBarry Smith 
145588661749SPeter Brune   if (bx == DMDA_BOUNDARY_PERIODIC) {
145688661749SPeter Brune     IXs = xs - s - o;
145788661749SPeter Brune     IXe = xe + s + o;
145888661749SPeter Brune     Xs = xs - s - o;
145988661749SPeter Brune     Xe = xe + s + o;
146088661749SPeter Brune   }
146147c6ae99SBarry Smith 
146288661749SPeter Brune   if (ys-s-o > 0) {
146388661749SPeter Brune     Ys = ys - s - o; IYs = ys - s - o;
146488661749SPeter Brune   } else {
146588661749SPeter Brune     if (by) {
146688661749SPeter Brune       Ys = ys - s;
146788661749SPeter Brune     } else {
146888661749SPeter Brune       Ys = 0;
146988661749SPeter Brune     }
147088661749SPeter Brune     IYs = 0;
147188661749SPeter Brune   }
147288661749SPeter Brune   if (ye+s+o <= N) {
147388661749SPeter Brune     Ye = ye + s + o; IYe = ye + s + o;
147488661749SPeter Brune   } else {
147588661749SPeter Brune     if (by) {
147688661749SPeter Brune       Ye = ye + s;
147788661749SPeter Brune     } else {
147888661749SPeter Brune       Ye = N;
147988661749SPeter Brune     }
148088661749SPeter Brune     IYe = N;
148188661749SPeter Brune   }
148288661749SPeter Brune 
148388661749SPeter Brune   if (by == DMDA_BOUNDARY_PERIODIC) {
148488661749SPeter Brune     IYs = ys - s - o;
148588661749SPeter Brune     IYe = ye + s + o;
148688661749SPeter Brune     Ys = ys - s - o;
148788661749SPeter Brune     Ye = ye + s + o;
148888661749SPeter Brune   }
148988661749SPeter Brune 
149088661749SPeter Brune   /* stencil length in each direction */
149188661749SPeter Brune   s_x = s + o;
149288661749SPeter Brune   s_y = s + o;
149347c6ae99SBarry Smith 
149447c6ae99SBarry Smith   /* determine starting point of each processor */
149547c6ae99SBarry Smith   nn    = x*y;
149647c6ae99SBarry Smith   ierr  = PetscMalloc2(size+1,PetscInt,&bases,size,PetscInt,&ldims);CHKERRQ(ierr);
149747c6ae99SBarry Smith   ierr  = MPI_Allgather(&nn,1,MPIU_INT,ldims,1,MPIU_INT,comm);CHKERRQ(ierr);
149847c6ae99SBarry Smith   bases[0] = 0;
149947c6ae99SBarry Smith   for (i=1; i<=size; i++) {
150047c6ae99SBarry Smith     bases[i] = ldims[i-1];
150147c6ae99SBarry Smith   }
150247c6ae99SBarry Smith   for (i=1; i<=size; i++) {
150347c6ae99SBarry Smith     bases[i] += bases[i-1];
150447c6ae99SBarry Smith   }
1505ce00eea3SSatish Balay   base = bases[rank]*dof;
150647c6ae99SBarry Smith 
150747c6ae99SBarry Smith   /* allocate the base parallel and sequential vectors */
1508ce00eea3SSatish Balay   dd->Nlocal = x*y*dof;
1509778a2246SBarry Smith   ierr = VecCreateMPIWithArray(comm,dof,dd->Nlocal,PETSC_DECIDE,0,&global);CHKERRQ(ierr);
1510ce00eea3SSatish Balay   dd->nlocal = (Xe-Xs)*(Ye-Ys)*dof;
1511778a2246SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,dof,dd->nlocal,0,&local);CHKERRQ(ierr);
151247c6ae99SBarry Smith 
151347c6ae99SBarry Smith   /* generate appropriate vector scatters */
151447c6ae99SBarry Smith   /* local to global inserts non-ghost point region into global */
151547c6ae99SBarry Smith   ierr = VecGetOwnershipRange(global,&start,&end);CHKERRQ(ierr);
1516ce00eea3SSatish Balay   ierr = ISCreateStride(comm,x*y*dof,start,1,&to);CHKERRQ(ierr);
151747c6ae99SBarry Smith 
1518db87c5ecSEthan Coon   count = x*y;
1519ce00eea3SSatish Balay   ierr = PetscMalloc(x*y*sizeof(PetscInt),&idx);CHKERRQ(ierr);
1520ce00eea3SSatish Balay   left = xs - Xs; right = left + x;
1521ce00eea3SSatish Balay   down = ys - Ys; up = down + y;
152247c6ae99SBarry Smith   count = 0;
152347c6ae99SBarry Smith   for (i=down; i<up; i++) {
1524ce00eea3SSatish Balay     for (j=left; j<right; j++) {
1525ce00eea3SSatish Balay       idx[count++] = i*(Xe-Xs) + j;
152647c6ae99SBarry Smith     }
152747c6ae99SBarry Smith   }
152847c6ae99SBarry Smith 
1529ce00eea3SSatish Balay   ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&from);CHKERRQ(ierr);
153047c6ae99SBarry Smith   ierr = VecScatterCreate(local,from,global,to,&ltog);CHKERRQ(ierr);
153147c6ae99SBarry Smith   ierr = PetscLogObjectParent(dd,ltog);CHKERRQ(ierr);
1532fcfd50ebSBarry Smith   ierr = ISDestroy(&from);CHKERRQ(ierr);
1533fcfd50ebSBarry Smith   ierr = ISDestroy(&to);CHKERRQ(ierr);
153447c6ae99SBarry Smith 
1535ce00eea3SSatish Balay   /* global to local must include ghost points within the domain,
1536ce00eea3SSatish Balay      but not ghost points outside the domain that aren't periodic */
153788661749SPeter Brune   if (stencil_type == DMDA_STENCIL_BOX || o > 0) {
1538db87c5ecSEthan Coon     count = (IXe-IXs)*(IYe-IYs);
1539db87c5ecSEthan Coon     ierr  = PetscMalloc(count*sizeof(PetscInt),&idx);CHKERRQ(ierr);
1540ce00eea3SSatish Balay 
1541ce00eea3SSatish Balay     left = IXs - Xs; right = left + (IXe-IXs);
1542ce00eea3SSatish Balay     down = IYs - Ys; up = down + (IYe-IYs);
1543ce00eea3SSatish Balay     count = 0;
1544ce00eea3SSatish Balay     for (i=down; i<up; i++) {
1545ce00eea3SSatish Balay       for (j=left; j<right; j++) {
1546ce00eea3SSatish Balay         idx[count++] = j + i*(Xe-Xs);
1547ce00eea3SSatish Balay       }
1548ce00eea3SSatish Balay     }
1549ce00eea3SSatish Balay     ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&to);CHKERRQ(ierr);
1550ce00eea3SSatish Balay 
155147c6ae99SBarry Smith   } else {
155247c6ae99SBarry Smith     /* must drop into cross shape region */
155347c6ae99SBarry Smith     /*       ---------|
155447c6ae99SBarry Smith             |  top    |
1555ce00eea3SSatish Balay          |---         ---| up
155647c6ae99SBarry Smith          |   middle      |
155747c6ae99SBarry Smith          |               |
1558ce00eea3SSatish Balay          ----         ---- down
155947c6ae99SBarry Smith             | bottom  |
156047c6ae99SBarry Smith             -----------
156147c6ae99SBarry Smith          Xs xs        xe Xe */
1562db87c5ecSEthan Coon     count = (ys-IYs)*x + y*(IXe-IXs) + (IYe-ye)*x;
1563db87c5ecSEthan Coon     ierr  = PetscMalloc(count*sizeof(PetscInt),&idx);CHKERRQ(ierr);
1564ce00eea3SSatish Balay 
1565ce00eea3SSatish Balay     left = xs - Xs; right = left + x;
1566ce00eea3SSatish Balay     down = ys - Ys; up = down + y;
156747c6ae99SBarry Smith     count = 0;
1568ce00eea3SSatish Balay     /* bottom */
1569ce00eea3SSatish Balay     for (i=(IYs-Ys); i<down; i++) {
1570ce00eea3SSatish Balay       for (j=left; j<right; j++) {
1571ce00eea3SSatish Balay         idx[count++] = j + i*(Xe-Xs);
157247c6ae99SBarry Smith       }
157347c6ae99SBarry Smith     }
157447c6ae99SBarry Smith     /* middle */
157547c6ae99SBarry Smith     for (i=down; i<up; i++) {
1576ce00eea3SSatish Balay       for (j=(IXs-Xs); j<(IXe-Xs); j++) {
1577ce00eea3SSatish Balay         idx[count++] = j + i*(Xe-Xs);
157847c6ae99SBarry Smith       }
157947c6ae99SBarry Smith     }
158047c6ae99SBarry Smith     /* top */
1581ce00eea3SSatish Balay     for (i=up; i<up+IYe-ye; i++) {
1582ce00eea3SSatish Balay       for (j=left; j<right; j++) {
1583ce00eea3SSatish Balay         idx[count++] = j + i*(Xe-Xs);
158447c6ae99SBarry Smith       }
158547c6ae99SBarry Smith     }
158647c6ae99SBarry Smith     ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&to);CHKERRQ(ierr);
158747c6ae99SBarry Smith   }
158847c6ae99SBarry Smith 
158947c6ae99SBarry Smith 
159047c6ae99SBarry Smith   /* determine who lies on each side of us stored in    n6 n7 n8
159147c6ae99SBarry Smith                                                         n3    n5
159247c6ae99SBarry Smith                                                         n0 n1 n2
159347c6ae99SBarry Smith   */
159447c6ae99SBarry Smith 
159547c6ae99SBarry Smith   /* Assume the Non-Periodic Case */
159647c6ae99SBarry Smith   n1 = rank - m;
159747c6ae99SBarry Smith   if (rank % m) {
159847c6ae99SBarry Smith     n0 = n1 - 1;
159947c6ae99SBarry Smith   } else {
160047c6ae99SBarry Smith     n0 = -1;
160147c6ae99SBarry Smith   }
160247c6ae99SBarry Smith   if ((rank+1) % m) {
160347c6ae99SBarry Smith     n2 = n1 + 1;
160447c6ae99SBarry Smith     n5 = rank + 1;
160547c6ae99SBarry Smith     n8 = rank + m + 1; if (n8 >= m*n) n8 = -1;
160647c6ae99SBarry Smith   } else {
160747c6ae99SBarry Smith     n2 = -1; n5 = -1; n8 = -1;
160847c6ae99SBarry Smith   }
160947c6ae99SBarry Smith   if (rank % m) {
161047c6ae99SBarry Smith     n3 = rank - 1;
161147c6ae99SBarry Smith     n6 = n3 + m; if (n6 >= m*n) n6 = -1;
161247c6ae99SBarry Smith   } else {
161347c6ae99SBarry Smith     n3 = -1; n6 = -1;
161447c6ae99SBarry Smith   }
161547c6ae99SBarry Smith   n7 = rank + m; if (n7 >= m*n) n7 = -1;
161647c6ae99SBarry Smith 
16171321219cSEthan Coon   if (bx == DMDA_BOUNDARY_PERIODIC && by == DMDA_BOUNDARY_PERIODIC) {
161847c6ae99SBarry Smith   /* Modify for Periodic Cases */
161947c6ae99SBarry Smith     /* Handle all four corners */
162047c6ae99SBarry Smith     if ((n6 < 0) && (n7 < 0) && (n3 < 0)) n6 = m-1;
162147c6ae99SBarry Smith     if ((n8 < 0) && (n7 < 0) && (n5 < 0)) n8 = 0;
162247c6ae99SBarry Smith     if ((n2 < 0) && (n5 < 0) && (n1 < 0)) n2 = size-m;
162347c6ae99SBarry Smith     if ((n0 < 0) && (n3 < 0) && (n1 < 0)) n0 = size-1;
162447c6ae99SBarry Smith 
162547c6ae99SBarry Smith     /* Handle Top and Bottom Sides */
162647c6ae99SBarry Smith     if (n1 < 0) n1 = rank + m * (n-1);
162747c6ae99SBarry Smith     if (n7 < 0) n7 = rank - m * (n-1);
162847c6ae99SBarry Smith     if ((n3 >= 0) && (n0 < 0)) n0 = size - m + rank - 1;
162947c6ae99SBarry Smith     if ((n3 >= 0) && (n6 < 0)) n6 = (rank%m)-1;
163047c6ae99SBarry Smith     if ((n5 >= 0) && (n2 < 0)) n2 = size - m + rank + 1;
163147c6ae99SBarry Smith     if ((n5 >= 0) && (n8 < 0)) n8 = (rank%m)+1;
163247c6ae99SBarry Smith 
163347c6ae99SBarry Smith     /* Handle Left and Right Sides */
163447c6ae99SBarry Smith     if (n3 < 0) n3 = rank + (m-1);
163547c6ae99SBarry Smith     if (n5 < 0) n5 = rank - (m-1);
163647c6ae99SBarry Smith     if ((n1 >= 0) && (n0 < 0)) n0 = rank-1;
163747c6ae99SBarry Smith     if ((n1 >= 0) && (n2 < 0)) n2 = rank-2*m+1;
163847c6ae99SBarry Smith     if ((n7 >= 0) && (n6 < 0)) n6 = rank+2*m-1;
163947c6ae99SBarry Smith     if ((n7 >= 0) && (n8 < 0)) n8 = rank+1;
16401321219cSEthan Coon   } else if (by == DMDA_BOUNDARY_PERIODIC) {  /* Handle Top and Bottom Sides */
1641ce00eea3SSatish Balay     if (n1 < 0) n1 = rank + m * (n-1);
1642ce00eea3SSatish Balay     if (n7 < 0) n7 = rank - m * (n-1);
1643ce00eea3SSatish Balay     if ((n3 >= 0) && (n0 < 0)) n0 = size - m + rank - 1;
1644ce00eea3SSatish Balay     if ((n3 >= 0) && (n6 < 0)) n6 = (rank%m)-1;
1645ce00eea3SSatish Balay     if ((n5 >= 0) && (n2 < 0)) n2 = size - m + rank + 1;
1646ce00eea3SSatish Balay     if ((n5 >= 0) && (n8 < 0)) n8 = (rank%m)+1;
16471321219cSEthan Coon   } else if (bx == DMDA_BOUNDARY_PERIODIC) { /* Handle Left and Right Sides */
1648ce00eea3SSatish Balay     if (n3 < 0) n3 = rank + (m-1);
1649ce00eea3SSatish Balay     if (n5 < 0) n5 = rank - (m-1);
1650ce00eea3SSatish Balay     if ((n1 >= 0) && (n0 < 0)) n0 = rank-1;
1651ce00eea3SSatish Balay     if ((n1 >= 0) && (n2 < 0)) n2 = rank-2*m+1;
1652ce00eea3SSatish Balay     if ((n7 >= 0) && (n6 < 0)) n6 = rank+2*m-1;
1653ce00eea3SSatish Balay     if ((n7 >= 0) && (n8 < 0)) n8 = rank+1;
165447c6ae99SBarry Smith   }
1655ce00eea3SSatish Balay 
165647c6ae99SBarry Smith   ierr = PetscMalloc(9*sizeof(PetscInt),&dd->neighbors);CHKERRQ(ierr);
165747c6ae99SBarry Smith   dd->neighbors[0] = n0;
165847c6ae99SBarry Smith   dd->neighbors[1] = n1;
165947c6ae99SBarry Smith   dd->neighbors[2] = n2;
166047c6ae99SBarry Smith   dd->neighbors[3] = n3;
166147c6ae99SBarry Smith   dd->neighbors[4] = rank;
166247c6ae99SBarry Smith   dd->neighbors[5] = n5;
166347c6ae99SBarry Smith   dd->neighbors[6] = n6;
166447c6ae99SBarry Smith   dd->neighbors[7] = n7;
166547c6ae99SBarry Smith   dd->neighbors[8] = n8;
166647c6ae99SBarry Smith 
166788661749SPeter Brune   if (stencil_type == DMDA_STENCIL_STAR && o == 0) {
166847c6ae99SBarry Smith     /* save corner processor numbers */
166947c6ae99SBarry Smith     sn0 = n0; sn2 = n2; sn6 = n6; sn8 = n8;
167047c6ae99SBarry Smith     n0 = n2 = n6 = n8 = -1;
167147c6ae99SBarry Smith   }
167247c6ae99SBarry Smith 
1673ce00eea3SSatish Balay   ierr = PetscMalloc((Xe-Xs)*(Ye-Ys)*sizeof(PetscInt),&idx);CHKERRQ(ierr);
1674ce00eea3SSatish Balay   ierr = PetscLogObjectMemory(da,(Xe-Xs)*(Ye-Ys)*sizeof(PetscInt));CHKERRQ(ierr);
167547c6ae99SBarry Smith 
1676ce00eea3SSatish Balay   nn = 0;
167747c6ae99SBarry Smith   xbase = bases[rank];
167847c6ae99SBarry Smith   for (i=1; i<=s_y; i++) {
167947c6ae99SBarry Smith     if (n0 >= 0) { /* left below */
1680ce00eea3SSatish Balay       x_t = lx[n0 % m];
168147c6ae99SBarry Smith       y_t = ly[(n0/m)];
168247c6ae99SBarry Smith       s_t = bases[n0] + x_t*y_t - (s_y-i)*x_t - s_x;
168347c6ae99SBarry Smith       for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
168447c6ae99SBarry Smith     }
168547c6ae99SBarry Smith     if (n1 >= 0) { /* directly below */
168647c6ae99SBarry Smith       x_t = x;
168747c6ae99SBarry Smith       y_t = ly[(n1/m)];
168847c6ae99SBarry Smith       s_t = bases[n1] + x_t*y_t - (s_y+1-i)*x_t;
168947c6ae99SBarry Smith       for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
169047c6ae99SBarry Smith     }
169147c6ae99SBarry Smith     if (n2 >= 0) { /* right below */
1692ce00eea3SSatish Balay       x_t = lx[n2 % m];
169347c6ae99SBarry Smith       y_t = ly[(n2/m)];
169447c6ae99SBarry Smith       s_t = bases[n2] + x_t*y_t - (s_y+1-i)*x_t;
169547c6ae99SBarry Smith       for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
169647c6ae99SBarry Smith     }
169747c6ae99SBarry Smith   }
169847c6ae99SBarry Smith 
169947c6ae99SBarry Smith   for (i=0; i<y; i++) {
170047c6ae99SBarry Smith     if (n3 >= 0) { /* directly left */
1701ce00eea3SSatish Balay       x_t = lx[n3 % m];
170247c6ae99SBarry Smith       /* y_t = y; */
170347c6ae99SBarry Smith       s_t = bases[n3] + (i+1)*x_t - s_x;
170447c6ae99SBarry Smith       for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
170547c6ae99SBarry Smith     }
170647c6ae99SBarry Smith 
170747c6ae99SBarry Smith     for (j=0; j<x; j++) { idx[nn++] = xbase++; } /* interior */
170847c6ae99SBarry Smith 
170947c6ae99SBarry Smith     if (n5 >= 0) { /* directly right */
1710ce00eea3SSatish Balay       x_t = lx[n5 % m];
171147c6ae99SBarry Smith       /* y_t = y; */
171247c6ae99SBarry Smith       s_t = bases[n5] + (i)*x_t;
171347c6ae99SBarry Smith       for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
171447c6ae99SBarry Smith     }
171547c6ae99SBarry Smith   }
171647c6ae99SBarry Smith 
171747c6ae99SBarry Smith   for (i=1; i<=s_y; i++) {
171847c6ae99SBarry Smith     if (n6 >= 0) { /* left above */
1719ce00eea3SSatish Balay       x_t = lx[n6 % m];
172047c6ae99SBarry Smith       /* y_t = ly[(n6/m)]; */
172147c6ae99SBarry Smith       s_t = bases[n6] + (i)*x_t - s_x;
172247c6ae99SBarry Smith       for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
172347c6ae99SBarry Smith     }
172447c6ae99SBarry Smith     if (n7 >= 0) { /* directly above */
172547c6ae99SBarry Smith       x_t = x;
172647c6ae99SBarry Smith       /* y_t = ly[(n7/m)]; */
172747c6ae99SBarry Smith       s_t = bases[n7] + (i-1)*x_t;
172847c6ae99SBarry Smith       for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
172947c6ae99SBarry Smith     }
173047c6ae99SBarry Smith     if (n8 >= 0) { /* right above */
1731ce00eea3SSatish Balay       x_t = lx[n8 % m];
173247c6ae99SBarry Smith       /* y_t = ly[(n8/m)]; */
173347c6ae99SBarry Smith       s_t = bases[n8] + (i-1)*x_t;
173447c6ae99SBarry Smith       for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
173547c6ae99SBarry Smith     }
173647c6ae99SBarry Smith   }
173747c6ae99SBarry Smith 
1738ce00eea3SSatish Balay   ierr = ISCreateBlock(comm,dof,nn,idx,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
173947c6ae99SBarry Smith   ierr = VecScatterCreate(global,from,local,to,&gtol);CHKERRQ(ierr);
174047c6ae99SBarry Smith   ierr = PetscLogObjectParent(da,gtol);CHKERRQ(ierr);
1741fcfd50ebSBarry Smith   ierr = ISDestroy(&to);CHKERRQ(ierr);
1742fcfd50ebSBarry Smith   ierr = ISDestroy(&from);CHKERRQ(ierr);
174347c6ae99SBarry Smith 
174488661749SPeter Brune   if (stencil_type == DMDA_STENCIL_STAR && o == 0) {
1745ce00eea3SSatish Balay     n0 = sn0; n2 = sn2; n6 = sn6; n8 = sn8;
1746ce00eea3SSatish Balay   }
1747ce00eea3SSatish Balay 
174888661749SPeter Brune   if (((stencil_type == DMDA_STENCIL_STAR) ||
17491321219cSEthan Coon        (bx && bx != DMDA_BOUNDARY_PERIODIC) ||
175088661749SPeter Brune        (by && by != DMDA_BOUNDARY_PERIODIC)) && o == 0) {
175147c6ae99SBarry Smith     /*
175247c6ae99SBarry Smith         Recompute the local to global mappings, this time keeping the
1753ce00eea3SSatish Balay       information about the cross corner processor numbers and any ghosted
1754ce00eea3SSatish Balay       but not periodic indices.
175547c6ae99SBarry Smith     */
175647c6ae99SBarry Smith     nn = 0;
175747c6ae99SBarry Smith     xbase = bases[rank];
175847c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
175947c6ae99SBarry Smith       if (n0 >= 0) { /* left below */
1760ce00eea3SSatish Balay         x_t = lx[n0 % m];
176147c6ae99SBarry Smith         y_t = ly[(n0/m)];
176247c6ae99SBarry Smith         s_t = bases[n0] + x_t*y_t - (s_y-i)*x_t - s_x;
176347c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1764ce00eea3SSatish Balay       } else if (xs-Xs > 0 && ys-Ys > 0) {
1765ce00eea3SSatish Balay         for (j=0; j<s_x; j++) { idx[nn++] = -1;}
176647c6ae99SBarry Smith       }
176747c6ae99SBarry Smith       if (n1 >= 0) { /* directly below */
176847c6ae99SBarry Smith         x_t = x;
176947c6ae99SBarry Smith         y_t = ly[(n1/m)];
177047c6ae99SBarry Smith         s_t = bases[n1] + x_t*y_t - (s_y+1-i)*x_t;
177147c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1772ce00eea3SSatish Balay       } else if (ys-Ys > 0) {
1773ce00eea3SSatish Balay         for (j=0; j<x; j++) { idx[nn++] = -1;}
177447c6ae99SBarry Smith       }
177547c6ae99SBarry Smith       if (n2 >= 0) { /* right below */
1776ce00eea3SSatish Balay         x_t = lx[n2 % m];
177747c6ae99SBarry Smith         y_t = ly[(n2/m)];
177847c6ae99SBarry Smith         s_t = bases[n2] + x_t*y_t - (s_y+1-i)*x_t;
177947c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1780ce00eea3SSatish Balay       } else if (Xe-xe> 0 && ys-Ys > 0) {
1781ce00eea3SSatish Balay         for (j=0; j<s_x; j++) { idx[nn++] = -1;}
178247c6ae99SBarry Smith       }
178347c6ae99SBarry Smith     }
178447c6ae99SBarry Smith 
178547c6ae99SBarry Smith     for (i=0; i<y; i++) {
178647c6ae99SBarry Smith       if (n3 >= 0) { /* directly left */
1787ce00eea3SSatish Balay         x_t = lx[n3 % m];
178847c6ae99SBarry Smith         /* y_t = y; */
178947c6ae99SBarry Smith         s_t = bases[n3] + (i+1)*x_t - s_x;
179047c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1791ce00eea3SSatish Balay       } else if (xs-Xs > 0) {
1792ce00eea3SSatish Balay         for (j=0; j<s_x; j++) { idx[nn++] = -1;}
179347c6ae99SBarry Smith       }
179447c6ae99SBarry Smith 
179547c6ae99SBarry Smith       for (j=0; j<x; j++) { idx[nn++] = xbase++; } /* interior */
179647c6ae99SBarry Smith 
179747c6ae99SBarry Smith       if (n5 >= 0) { /* directly right */
1798ce00eea3SSatish Balay         x_t = lx[n5 % m];
179947c6ae99SBarry Smith         /* y_t = y; */
180047c6ae99SBarry Smith         s_t = bases[n5] + (i)*x_t;
180147c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1802ce00eea3SSatish Balay       } else if (Xe-xe > 0) {
1803ce00eea3SSatish Balay         for (j=0; j<s_x; j++) { idx[nn++] = -1;}
180447c6ae99SBarry Smith       }
180547c6ae99SBarry Smith     }
180647c6ae99SBarry Smith 
180747c6ae99SBarry Smith     for (i=1; i<=s_y; i++) {
180847c6ae99SBarry Smith       if (n6 >= 0) { /* left above */
1809ce00eea3SSatish Balay         x_t = lx[n6 % m];
181047c6ae99SBarry Smith         /* y_t = ly[(n6/m)]; */
181147c6ae99SBarry Smith         s_t = bases[n6] + (i)*x_t - s_x;
181247c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1813ce00eea3SSatish Balay       } else if (xs-Xs > 0 && Ye-ye > 0) {
1814ce00eea3SSatish Balay         for (j=0; j<s_x; j++) { idx[nn++] = -1;}
181547c6ae99SBarry Smith       }
181647c6ae99SBarry Smith       if (n7 >= 0) { /* directly above */
181747c6ae99SBarry Smith         x_t = x;
181847c6ae99SBarry Smith         /* y_t = ly[(n7/m)]; */
181947c6ae99SBarry Smith         s_t = bases[n7] + (i-1)*x_t;
182047c6ae99SBarry Smith         for (j=0; j<x_t; j++) { idx[nn++] = s_t++;}
1821ce00eea3SSatish Balay       } else if (Ye-ye > 0) {
1822ce00eea3SSatish Balay         for (j=0; j<x; j++) { idx[nn++] = -1;}
182347c6ae99SBarry Smith       }
182447c6ae99SBarry Smith       if (n8 >= 0) { /* right above */
1825ce00eea3SSatish Balay         x_t = lx[n8 % m];
182647c6ae99SBarry Smith         /* y_t = ly[(n8/m)]; */
182747c6ae99SBarry Smith         s_t = bases[n8] + (i-1)*x_t;
182847c6ae99SBarry Smith         for (j=0; j<s_x; j++) { idx[nn++] = s_t++;}
1829ce00eea3SSatish Balay       } else if (Xe-xe > 0 && Ye-ye > 0) {
1830ce00eea3SSatish Balay         for (j=0; j<s_x; j++) { idx[nn++] = -1;}
183147c6ae99SBarry Smith       }
183247c6ae99SBarry Smith     }
183347c6ae99SBarry Smith   }
1834ce00eea3SSatish Balay   /*
1835ce00eea3SSatish Balay      Set the local to global ordering in the global vector, this allows use
1836ce00eea3SSatish Balay      of VecSetValuesLocal().
1837ce00eea3SSatish Balay   */
1838ce00eea3SSatish Balay   ierr = ISCreateBlock(comm,dof,nn,idx,PETSC_OWN_POINTER,&ltogis);CHKERRQ(ierr);
1839ce00eea3SSatish Balay   ierr = PetscMalloc(nn*dof*sizeof(PetscInt),&idx_cpy);CHKERRQ(ierr);
1840db87c5ecSEthan Coon   ierr = PetscLogObjectMemory(da,nn*dof*sizeof(PetscInt));CHKERRQ(ierr);
1841ce00eea3SSatish Balay   ierr = ISGetIndices(ltogis, &idx_full);
1842ce00eea3SSatish Balay   ierr = PetscMemcpy(idx_cpy,idx_full,nn*dof*sizeof(PetscInt));CHKERRQ(ierr);
1843ce00eea3SSatish Balay   ierr = ISRestoreIndices(ltogis, &idx_full);
1844ce00eea3SSatish Balay   ierr = ISLocalToGlobalMappingCreateIS(ltogis,&da->ltogmap);CHKERRQ(ierr);
1845ce00eea3SSatish Balay   ierr = PetscLogObjectParent(da,da->ltogmap);CHKERRQ(ierr);
1846fcfd50ebSBarry Smith   ierr = ISDestroy(&ltogis);CHKERRQ(ierr);
1847ce00eea3SSatish Balay   ierr = ISLocalToGlobalMappingBlock(da->ltogmap,dd->w,&da->ltogmapb);CHKERRQ(ierr);
1848ce00eea3SSatish Balay   ierr = PetscLogObjectParent(da,da->ltogmap);CHKERRQ(ierr);
184947c6ae99SBarry Smith 
1850ce00eea3SSatish Balay   ierr = PetscFree2(bases,ldims);CHKERRQ(ierr);
185147c6ae99SBarry Smith   dd->m  = m;  dd->n  = n;
1852ce00eea3SSatish Balay   /* note petsc expects xs/xe/Xs/Xe to be multiplied by #dofs in many places */
1853ce00eea3SSatish Balay   dd->xs = xs*dof; dd->xe = xe*dof; dd->ys = ys; dd->ye = ye; dd->zs = 0; dd->ze = 1;
1854ce00eea3SSatish Balay   dd->Xs = Xs*dof; dd->Xe = Xe*dof; dd->Ys = Ys; dd->Ye = Ye; dd->Zs = 0; dd->Ze = 1;
185547c6ae99SBarry Smith 
1856fcfd50ebSBarry Smith   ierr = VecDestroy(&local);CHKERRQ(ierr);
1857fcfd50ebSBarry Smith   ierr = VecDestroy(&global);CHKERRQ(ierr);
185847c6ae99SBarry Smith 
185947c6ae99SBarry Smith   dd->gtol      = gtol;
186047c6ae99SBarry Smith   dd->ltog      = ltog;
1861ce00eea3SSatish Balay   dd->idx       = idx_cpy;
1862ce00eea3SSatish Balay   dd->Nl        = nn*dof;
186347c6ae99SBarry Smith   dd->base      = base;
18649a42bb27SBarry Smith   da->ops->view = DMView_DA_2d;
186547c6ae99SBarry Smith   dd->ltol = PETSC_NULL;
186647c6ae99SBarry Smith   dd->ao   = PETSC_NULL;
186747c6ae99SBarry Smith 
186847c6ae99SBarry Smith   PetscFunctionReturn(0);
186947c6ae99SBarry Smith }
187047c6ae99SBarry Smith 
187147c6ae99SBarry Smith #undef __FUNCT__
1872aa219208SBarry Smith #define __FUNCT__ "DMDACreate2d"
187347c6ae99SBarry Smith /*@C
1874aa219208SBarry Smith    DMDACreate2d -  Creates an object that will manage the communication of  two-dimensional
187547c6ae99SBarry Smith    regular array data that is distributed across some processors.
187647c6ae99SBarry Smith 
187747c6ae99SBarry Smith    Collective on MPI_Comm
187847c6ae99SBarry Smith 
187947c6ae99SBarry Smith    Input Parameters:
188047c6ae99SBarry Smith +  comm - MPI communicator
18811321219cSEthan Coon .  bx,by - type of ghost nodes the array have.
18821321219cSEthan Coon          Use one of DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_GHOSTED, DMDA_BOUNDARY_PERIODIC.
1883aa219208SBarry Smith .  stencil_type - stencil type.  Use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR.
188447c6ae99SBarry Smith .  M,N - global dimension in each direction of the array (use -M and or -N to indicate that it may be set to a different value
188547c6ae99SBarry Smith             from the command line with -da_grid_x <M> -da_grid_y <N>)
188647c6ae99SBarry Smith .  m,n - corresponding number of processors in each dimension
188747c6ae99SBarry Smith          (or PETSC_DECIDE to have calculated)
188847c6ae99SBarry Smith .  dof - number of degrees of freedom per node
188947c6ae99SBarry Smith .  s - stencil width
189047c6ae99SBarry Smith -  lx, ly - arrays containing the number of nodes in each cell along
189147c6ae99SBarry Smith            the x and y coordinates, or PETSC_NULL. If non-null, these
189247c6ae99SBarry Smith            must be of length as m and n, and the corresponding
189347c6ae99SBarry Smith            m and n cannot be PETSC_DECIDE. The sum of the lx[] entries
189447c6ae99SBarry Smith            must be M, and the sum of the ly[] entries must be N.
189547c6ae99SBarry Smith 
189647c6ae99SBarry Smith    Output Parameter:
189747c6ae99SBarry Smith .  da - the resulting distributed array object
189847c6ae99SBarry Smith 
189947c6ae99SBarry Smith    Options Database Key:
1900aa219208SBarry Smith +  -da_view - Calls DMView() at the conclusion of DMDACreate2d()
190147c6ae99SBarry Smith .  -da_grid_x <nx> - number of grid points in x direction, if M < 0
190247c6ae99SBarry Smith .  -da_grid_y <ny> - number of grid points in y direction, if N < 0
190347c6ae99SBarry Smith .  -da_processors_x <nx> - number of processors in x direction
190447c6ae99SBarry Smith .  -da_processors_y <ny> - number of processors in y direction
1905e0f5d30fSBarry Smith .  -da_refine_x <rx> - refinement ratio in x direction
1906e0f5d30fSBarry Smith .  -da_refine_y <ry> - refinement ratio in y direction
1907e0f5d30fSBarry Smith -  -da_refine <n> - refine the DMDA n times before creating, if M or N < 0
1908e0f5d30fSBarry Smith 
190947c6ae99SBarry Smith 
191047c6ae99SBarry Smith    Level: beginner
191147c6ae99SBarry Smith 
191247c6ae99SBarry Smith    Notes:
1913aa219208SBarry Smith    The stencil type DMDA_STENCIL_STAR with width 1 corresponds to the
1914aa219208SBarry Smith    standard 5-pt stencil, while DMDA_STENCIL_BOX with width 1 denotes
191547c6ae99SBarry Smith    the standard 9-pt stencil.
191647c6ae99SBarry Smith 
1917aa219208SBarry Smith    The array data itself is NOT stored in the DMDA, it is stored in Vec objects;
1918564755cdSBarry Smith    The appropriate vector objects can be obtained with calls to DMCreateGlobalVector()
1919564755cdSBarry Smith    and DMCreateLocalVector() and calls to VecDuplicate() if more are needed.
192047c6ae99SBarry Smith 
192147c6ae99SBarry Smith .keywords: distributed array, create, two-dimensional
192247c6ae99SBarry Smith 
1923aa219208SBarry Smith .seealso: DMDestroy(), DMView(), DMDACreate1d(), DMDACreate3d(), DMGlobalToLocalBegin(), DMDAGetRefinementFactor(),
1924aa219208SBarry Smith           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMDALocalToLocalBegin(), DMDALocalToLocalEnd(), DMDASetRefinementFactor(),
1925d461ba97SBarry Smith           DMDAGetInfo(), DMCreateGlobalVector(), DMCreateLocalVector(), DMDACreateNaturalVector(), DMLoad(), DMDAGetOwnershipRanges()
192647c6ae99SBarry Smith 
192747c6ae99SBarry Smith @*/
1928fe16a2e9SBarry Smith 
19291321219cSEthan Coon PetscErrorCode  DMDACreate2d(MPI_Comm comm,DMDABoundaryType bx,DMDABoundaryType by,DMDAStencilType stencil_type,
19309a42bb27SBarry Smith                           PetscInt M,PetscInt N,PetscInt m,PetscInt n,PetscInt dof,PetscInt s,const PetscInt lx[],const PetscInt ly[],DM *da)
193147c6ae99SBarry Smith {
193247c6ae99SBarry Smith   PetscErrorCode ierr;
193347c6ae99SBarry Smith 
193447c6ae99SBarry Smith   PetscFunctionBegin;
1935aa219208SBarry Smith   ierr = DMDACreate(comm, da);CHKERRQ(ierr);
1936aa219208SBarry Smith   ierr = DMDASetDim(*da, 2);CHKERRQ(ierr);
1937aa219208SBarry Smith   ierr = DMDASetSizes(*da, M, N, 1);CHKERRQ(ierr);
1938aa219208SBarry Smith   ierr = DMDASetNumProcs(*da, m, n, PETSC_DECIDE);CHKERRQ(ierr);
1939755f258dSLisandro Dalcin   ierr = DMDASetBoundaryType(*da, bx, by, DMDA_BOUNDARY_NONE);CHKERRQ(ierr);
1940aa219208SBarry Smith   ierr = DMDASetDof(*da, dof);CHKERRQ(ierr);
1941aa219208SBarry Smith   ierr = DMDASetStencilType(*da, stencil_type);CHKERRQ(ierr);
1942aa219208SBarry Smith   ierr = DMDASetStencilWidth(*da, s);CHKERRQ(ierr);
1943aa219208SBarry Smith   ierr = DMDASetOwnershipRanges(*da, lx, ly, PETSC_NULL);CHKERRQ(ierr);
194447c6ae99SBarry Smith   /* This violates the behavior for other classes, but right now users expect negative dimensions to be handled this way */
19459a42bb27SBarry Smith   ierr = DMSetFromOptions(*da);CHKERRQ(ierr);
19469a42bb27SBarry Smith   ierr = DMSetUp(*da);CHKERRQ(ierr);
19477242296bSJed Brown   ierr = DMView_DA_Private(*da);CHKERRQ(ierr);
194847c6ae99SBarry Smith   PetscFunctionReturn(0);
194947c6ae99SBarry Smith }
1950