xref: /petsc/src/dm/impls/da/dacorn.c (revision cc76e2cf431159542183a8ce4d40268042df5f06)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6b45d2f2cSJed Brown #include <petsc-private/daimpl.h>    /*I   "petscdmda.h"   I*/
747c6ae99SBarry Smith 
847c6ae99SBarry Smith #undef __FUNCT__
96636e97aSMatthew G Knepley #define __FUNCT__ "DMCreateCoordinateDM_DA"
106636e97aSMatthew G Knepley PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
1147c6ae99SBarry Smith {
126636e97aSMatthew G Knepley   DM_DA         *da = (DM_DA *) dm->data;
1347c6ae99SBarry Smith   PetscMPIInt    size;
1447c6ae99SBarry Smith   PetscErrorCode ierr;
1547c6ae99SBarry Smith 
1647c6ae99SBarry Smith   PetscFunctionBegin;
176636e97aSMatthew G Knepley   ierr = MPI_Comm_size(((PetscObject) dm)->comm, &size);CHKERRQ(ierr);
186636e97aSMatthew G Knepley   if (da->dim == 1) {
1947c6ae99SBarry Smith     PetscInt         s,m,*lc,l;
201321219cSEthan Coon     DMDABoundaryType bx;
216636e97aSMatthew G Knepley 
226636e97aSMatthew G Knepley     ierr = DMDAGetInfo(dm,0,&m,0,0,0,0,0,0,&s,&bx,0,0,0);CHKERRQ(ierr);
236636e97aSMatthew G Knepley     ierr = DMDAGetCorners(dm,0,0,0,&l,0,0);CHKERRQ(ierr);
2447c6ae99SBarry Smith     ierr = PetscMalloc(size * sizeof(PetscInt), &lc);CHKERRQ(ierr);
256636e97aSMatthew G Knepley     ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
266636e97aSMatthew G Knepley     ierr = DMDACreate1d(((PetscObject)dm)->comm,bx,m,1,s,lc,cdm);CHKERRQ(ierr);
2747c6ae99SBarry Smith     ierr = PetscFree(lc);CHKERRQ(ierr);
286636e97aSMatthew G Knepley   } else if (da->dim == 2) {
2947c6ae99SBarry Smith     PetscInt         i,s,m,*lc,*ld,l,k,n,M,N;
301321219cSEthan Coon     DMDABoundaryType bx,by;
316636e97aSMatthew G Knepley 
326636e97aSMatthew G Knepley     ierr = DMDAGetInfo(dm,0,&m,&n,0,&M,&N,0,0,&s,&bx,&by,0,0);CHKERRQ(ierr);
336636e97aSMatthew G Knepley     ierr = DMDAGetCorners(dm,0,0,0,&l,&k,0);CHKERRQ(ierr);
3447c6ae99SBarry Smith     ierr = PetscMalloc2(size,PetscInt,&lc,size,PetscInt,&ld);CHKERRQ(ierr);
3547c6ae99SBarry Smith     /* only first M values in lc matter */
366636e97aSMatthew G Knepley     ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
3747c6ae99SBarry Smith     /* every Mth value in ld matters */
386636e97aSMatthew G Knepley       ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
396636e97aSMatthew G Knepley       for(i = 0; i < N; ++i) {
4047c6ae99SBarry Smith         ld[i] = ld[M*i];
4147c6ae99SBarry Smith       }
42*cc76e2cfSBarry Smith       if (bx == DMDA_BOUNDARY_MIRROR || by == DMDA_BOUNDARY_MIRROR) {
43*cc76e2cfSBarry Smith         ierr = DMDACreate2d(((PetscObject)dm)->comm,bx,by,DMDA_STENCIL_STAR,m,n,M,N,2,s,lc,ld,cdm);CHKERRQ(ierr);
44*cc76e2cfSBarry Smith       } else {
456636e97aSMatthew G Knepley         ierr = DMDACreate2d(((PetscObject)dm)->comm,bx,by,DMDA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,cdm);CHKERRQ(ierr);
46*cc76e2cfSBarry Smith       }
4747c6ae99SBarry Smith       ierr = PetscFree2(lc,ld);CHKERRQ(ierr);
486636e97aSMatthew G Knepley   } else if (da->dim == 3) {
4947c6ae99SBarry Smith     PetscInt         i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p;
501321219cSEthan Coon     DMDABoundaryType bx,by,bz;
516636e97aSMatthew G Knepley 
526636e97aSMatthew G Knepley     ierr = DMDAGetInfo(dm,0,&m,&n,&p,&M,&N,&P,0,&s,&bx,&by,&bz,0);CHKERRQ(ierr);
536636e97aSMatthew G Knepley     ierr = DMDAGetCorners(dm,0,0,0,&l,&k,&q);CHKERRQ(ierr);
5447c6ae99SBarry Smith     ierr = PetscMalloc3(size,PetscInt,&lc,size,PetscInt,&ld,size,PetscInt,&le);CHKERRQ(ierr);
5547c6ae99SBarry Smith     /* only first M values in lc matter */
566636e97aSMatthew G Knepley     ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
5747c6ae99SBarry Smith     /* every Mth value in ld matters */
586636e97aSMatthew G Knepley     ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
596636e97aSMatthew G Knepley     for(i = 0; i < N; ++i) {
6047c6ae99SBarry Smith       ld[i] = ld[M*i];
6147c6ae99SBarry Smith     }
626636e97aSMatthew G Knepley     ierr = MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
636636e97aSMatthew G Knepley     for(i = 0; i < P; ++i) {
6447c6ae99SBarry Smith       le[i] = le[M*N*i];
6547c6ae99SBarry Smith     }
666636e97aSMatthew G Knepley     ierr = DMDACreate3d(((PetscObject)dm)->comm,bx,by,bz,DMDA_STENCIL_BOX,m,n,p,M,N,P,3,s,lc,ld,le,cdm);CHKERRQ(ierr);
6747c6ae99SBarry Smith     ierr = PetscFree3(lc,ld,le);CHKERRQ(ierr);
6847c6ae99SBarry Smith   }
6947c6ae99SBarry Smith   PetscFunctionReturn(0);
7047c6ae99SBarry Smith }
7147c6ae99SBarry Smith 
7247c6ae99SBarry Smith #undef __FUNCT__
73aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName"
7447c6ae99SBarry Smith /*@C
75aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
76aa219208SBarry Smith    vectors associated with a DMDA.
7747c6ae99SBarry Smith 
7847c6ae99SBarry Smith    Not Collective
7947c6ae99SBarry Smith 
8047c6ae99SBarry Smith    Input Parameters:
8147c6ae99SBarry Smith +  da - the distributed array
82aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
83aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
8447c6ae99SBarry Smith -  names - the name of the field (component)
8547c6ae99SBarry Smith 
8647c6ae99SBarry Smith   Level: intermediate
8747c6ae99SBarry Smith 
8847c6ae99SBarry Smith .keywords: distributed array, get, component name
8947c6ae99SBarry Smith 
90aa219208SBarry Smith .seealso: DMDAGetFieldName()
9147c6ae99SBarry Smith @*/
927087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
9347c6ae99SBarry Smith {
9447c6ae99SBarry Smith   PetscErrorCode ierr;
9547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
9647c6ae99SBarry Smith 
9747c6ae99SBarry Smith   PetscFunctionBegin;
9847c6ae99SBarry Smith    PetscValidHeaderSpecific(da,DM_CLASSID,1);
9947c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
100c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
10147c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
10247c6ae99SBarry Smith   PetscFunctionReturn(0);
10347c6ae99SBarry Smith }
10447c6ae99SBarry Smith 
10547c6ae99SBarry Smith #undef __FUNCT__
106aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName"
10747c6ae99SBarry Smith /*@C
108aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
109aa219208SBarry Smith    vectors associated with a DMDA.
11047c6ae99SBarry Smith 
11147c6ae99SBarry Smith    Not Collective
11247c6ae99SBarry Smith 
11347c6ae99SBarry Smith    Input Parameter:
11447c6ae99SBarry Smith +  da - the distributed array
115aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
116aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
11747c6ae99SBarry Smith 
11847c6ae99SBarry Smith    Output Parameter:
11947c6ae99SBarry Smith .  names - the name of the field (component)
12047c6ae99SBarry Smith 
12147c6ae99SBarry Smith   Level: intermediate
12247c6ae99SBarry Smith 
12347c6ae99SBarry Smith .keywords: distributed array, get, component name
12447c6ae99SBarry Smith 
125aa219208SBarry Smith .seealso: DMDASetFieldName()
12647c6ae99SBarry Smith @*/
1277087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
12847c6ae99SBarry Smith {
12947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
13047c6ae99SBarry Smith 
13147c6ae99SBarry Smith   PetscFunctionBegin;
13247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
13347c6ae99SBarry Smith   PetscValidPointer(name,3);
13447c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
13547c6ae99SBarry Smith   *name = dd->fieldname[nf];
13647c6ae99SBarry Smith   PetscFunctionReturn(0);
13747c6ae99SBarry Smith }
13847c6ae99SBarry Smith 
13947c6ae99SBarry Smith #undef __FUNCT__
140aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners"
14147c6ae99SBarry Smith /*@
142aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
14347c6ae99SBarry Smith    corner of the local region, excluding ghost points.
14447c6ae99SBarry Smith 
14547c6ae99SBarry Smith    Not Collective
14647c6ae99SBarry Smith 
14747c6ae99SBarry Smith    Input Parameter:
14847c6ae99SBarry Smith .  da - the distributed array
14947c6ae99SBarry Smith 
15047c6ae99SBarry Smith    Output Parameters:
15147c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
15247c6ae99SBarry Smith            for 2D and 3D problems)
15347c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
15447c6ae99SBarry Smith            these are used for 2D and 3D problems)
15547c6ae99SBarry Smith 
15647c6ae99SBarry Smith    Note:
15747c6ae99SBarry Smith    The corner information is independent of the number of degrees of
158aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
15947c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
16047c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
16147c6ae99SBarry Smith    Any of y, z, n, and p can be passed in as PETSC_NULL if not needed.
16247c6ae99SBarry Smith 
16347c6ae99SBarry Smith   Level: beginner
16447c6ae99SBarry Smith 
16547c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
16647c6ae99SBarry Smith 
167aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
16847c6ae99SBarry Smith @*/
1697087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
17047c6ae99SBarry Smith {
17147c6ae99SBarry Smith   PetscInt w;
17247c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
17347c6ae99SBarry Smith 
17447c6ae99SBarry Smith   PetscFunctionBegin;
17547c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
17647c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
17747c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
17847c6ae99SBarry Smith   w = dd->w;
179d886c4f4SPeter Brune   if (x) *x = dd->xs/w + dd->xo; if (m) *m = (dd->xe - dd->xs)/w;
18047c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
181d886c4f4SPeter Brune   if (y) *y = dd->ys + dd->yo;   if (n) *n = (dd->ye - dd->ys);
182d886c4f4SPeter Brune   if (z) *z = dd->zs + dd->zo;   if (p) *p = (dd->ze - dd->zs);
18347c6ae99SBarry Smith   PetscFunctionReturn(0);
18447c6ae99SBarry Smith }
18547c6ae99SBarry Smith 
18647c6ae99SBarry Smith #undef __FUNCT__
187aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox"
18847c6ae99SBarry Smith /*@
189aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
19047c6ae99SBarry Smith 
19147c6ae99SBarry Smith    Not Collective
19247c6ae99SBarry Smith 
19347c6ae99SBarry Smith    Input Parameter:
19447c6ae99SBarry Smith .  da - the distributed array
19547c6ae99SBarry Smith 
19647c6ae99SBarry Smith    Output Parameters:
19747c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
19847c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
19947c6ae99SBarry Smith 
20047c6ae99SBarry Smith   Level: beginner
20147c6ae99SBarry Smith 
20247c6ae99SBarry Smith .keywords: distributed array, get, coordinates
20347c6ae99SBarry Smith 
2042150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
20547c6ae99SBarry Smith @*/
2067087cfbeSBarry Smith PetscErrorCode  DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[])
20747c6ae99SBarry Smith {
20847c6ae99SBarry Smith   PetscErrorCode    ierr;
20947c6ae99SBarry Smith   Vec               coords  = PETSC_NULL;
21047c6ae99SBarry Smith   PetscInt          dim,i,j;
21147c6ae99SBarry Smith   const PetscScalar *local_coords;
212ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
21347c6ae99SBarry Smith   PetscInt          N,Ni;
21447c6ae99SBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
21547c6ae99SBarry Smith 
21647c6ae99SBarry Smith   PetscFunctionBegin;
21747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
21847c6ae99SBarry Smith   dim = dd->dim;
2196636e97aSMatthew G Knepley   ierr = DMGetCoordinates(da,&coords);CHKERRQ(ierr);
2207324c66bSJed Brown   if (coords) {
22147c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
22247c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
22347c6ae99SBarry Smith     Ni = N/dim;
22447c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
2257324c66bSJed Brown       for (j=0; j<3; j++) {
2267324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
2277324c66bSJed Brown         max[j] = j < dim ? PetscMax(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
22847c6ae99SBarry Smith       }
22947c6ae99SBarry Smith     }
23047c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
2317324c66bSJed Brown   } else {                      /* Just use grid indices */
2327324c66bSJed Brown     DMDALocalInfo info;
2337324c66bSJed Brown     ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
2347324c66bSJed Brown     min[0] = info.xs;
2357324c66bSJed Brown     min[1] = info.ys;
2367324c66bSJed Brown     min[2] = info.zs;
2377324c66bSJed Brown     max[0] = info.xs + info.xm-1;
2387324c66bSJed Brown     max[1] = info.ys + info.ym-1;
2397324c66bSJed Brown     max[2] = info.zs + info.zm-1;
2407324c66bSJed Brown   }
24147c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
24247c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
24347c6ae99SBarry Smith   PetscFunctionReturn(0);
24447c6ae99SBarry Smith }
24547c6ae99SBarry Smith 
24647c6ae99SBarry Smith #undef __FUNCT__
247aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox"
24847c6ae99SBarry Smith /*@
249aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
25047c6ae99SBarry Smith 
251aa219208SBarry Smith    Collective on DMDA
25247c6ae99SBarry Smith 
25347c6ae99SBarry Smith    Input Parameter:
25447c6ae99SBarry Smith .  da - the distributed array
25547c6ae99SBarry Smith 
25647c6ae99SBarry Smith    Output Parameters:
25747c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
25847c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
25947c6ae99SBarry Smith 
26047c6ae99SBarry Smith   Level: beginner
26147c6ae99SBarry Smith 
26247c6ae99SBarry Smith .keywords: distributed array, get, coordinates
26347c6ae99SBarry Smith 
2642150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
26547c6ae99SBarry Smith @*/
2667087cfbeSBarry Smith PetscErrorCode  DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[])
26747c6ae99SBarry Smith {
26847c6ae99SBarry Smith   PetscErrorCode ierr;
26947c6ae99SBarry Smith   PetscMPIInt    count;
27047c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
27147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
27247c6ae99SBarry Smith 
27347c6ae99SBarry Smith   PetscFunctionBegin;
27447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
27547c6ae99SBarry Smith   count = PetscMPIIntCast(dd->dim);
276aa219208SBarry Smith   ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr);
277d9822059SBarry Smith   if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);}
278d9822059SBarry Smith   if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);}
27947c6ae99SBarry Smith   PetscFunctionReturn(0);
28047c6ae99SBarry Smith }
281bc2bf880SBarry Smith 
282bc2bf880SBarry Smith #undef __FUNCT__
283bc2bf880SBarry Smith #define __FUNCT__ "DMDAGetReducedDA"
284bc2bf880SBarry Smith /*@
285bc2bf880SBarry Smith    DMDAGetReducedDA - Gets the DMDA with the same layout but with fewer or more fields
286bc2bf880SBarry Smith 
287bc2bf880SBarry Smith    Collective on DMDA
288bc2bf880SBarry Smith 
289bc2bf880SBarry Smith    Input Parameter:
290bc2bf880SBarry Smith +  da - the distributed array
291bc2bf880SBarry Smith .  nfields - number of fields in new DMDA
292bc2bf880SBarry Smith 
293bc2bf880SBarry Smith    Output Parameter:
294bc2bf880SBarry Smith .  nda - the new DMDA
295bc2bf880SBarry Smith 
296bc2bf880SBarry Smith   Level: intermediate
297bc2bf880SBarry Smith 
298bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
299bc2bf880SBarry Smith 
3002150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
301bc2bf880SBarry Smith @*/
302bc2bf880SBarry Smith PetscErrorCode  DMDAGetReducedDA(DM da,PetscInt nfields,DM *nda)
303bc2bf880SBarry Smith {
304bc2bf880SBarry Smith   PetscErrorCode   ierr;
305bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
306320964c4SBlaise Bourdin   PetscInt         s,m,n,p,M,N,P,dim;
307320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
308bc2bf880SBarry Smith   DMDABoundaryType bx,by,bz;
309320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
310320964c4SBlaise Bourdin 
311320964c4SBlaise Bourdin   PetscFunctionBegin;
312320964c4SBlaise Bourdin   ierr = DMDAGetInfo(da,&dim,&M,&N,&P,&m,&n,&p,0,&s,&bx,&by,&bz,&stencil_type);CHKERRQ(ierr);
313320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
314320964c4SBlaise Bourdin   if (dim == 1) {
315320964c4SBlaise Bourdin     ierr = DMDACreate1d(((PetscObject)da)->comm,bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
316320964c4SBlaise Bourdin   } else if (dim == 2) {
317320964c4SBlaise Bourdin     ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
318320964c4SBlaise Bourdin   } else if (dim == 3) {
319320964c4SBlaise Bourdin     ierr = DMDACreate3d(((PetscObject)da)->comm,bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);CHKERRQ(ierr);
320bc2bf880SBarry Smith   }
3216636e97aSMatthew G Knepley   if (da->coordinates) {
3226636e97aSMatthew G Knepley     ierr        = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
3236636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
324bc2bf880SBarry Smith   }
325bc2bf880SBarry Smith   PetscFunctionReturn(0);
326bc2bf880SBarry Smith }
327bc2bf880SBarry Smith 
328