xref: /petsc/src/dm/impls/da/dacorn.c (revision 95c1318154c5a85ba7f10eb2e425da809e409add)
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       }
42cc76e2cfSBarry Smith       if (bx == DMDA_BOUNDARY_MIRROR || by == DMDA_BOUNDARY_MIRROR) {
43cc76e2cfSBarry Smith         ierr = DMDACreate2d(((PetscObject)dm)->comm,bx,by,DMDA_STENCIL_STAR,m,n,M,N,2,s,lc,ld,cdm);CHKERRQ(ierr);
44cc76e2cfSBarry 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);
46cc76e2cfSBarry 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 
90109c9344SBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName()
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 
125109c9344SBarry Smith .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName()
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__
140109c9344SBarry Smith #define __FUNCT__ "DMDASetCoordinateName"
141109c9344SBarry Smith /*@C
142109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
143109c9344SBarry Smith 
144109c9344SBarry Smith    Not Collective
145109c9344SBarry Smith 
146109c9344SBarry Smith    Input Parameters:
147109c9344SBarry Smith +  da - the distributed array
148109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
149109c9344SBarry Smith -  name - the name of the coordinate
150109c9344SBarry Smith 
151109c9344SBarry Smith   Level: intermediate
152109c9344SBarry Smith 
153109c9344SBarry Smith .keywords: distributed array, get, component name
154109c9344SBarry Smith 
155109c9344SBarry Smith .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName()
156109c9344SBarry Smith @*/
157109c9344SBarry Smith PetscErrorCode  DMDASetCoordinateName(DM da,PetscInt nf,const char name[])
158109c9344SBarry Smith {
159109c9344SBarry Smith   PetscErrorCode ierr;
160109c9344SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
161109c9344SBarry Smith 
162109c9344SBarry Smith   PetscFunctionBegin;
163109c9344SBarry Smith    PetscValidHeaderSpecific(da,DM_CLASSID,1);
164109c9344SBarry Smith   if (nf < 0 || nf >= dd->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
165109c9344SBarry Smith   ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr);
166109c9344SBarry Smith   ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr);
167109c9344SBarry Smith   PetscFunctionReturn(0);
168109c9344SBarry Smith }
169109c9344SBarry Smith 
170109c9344SBarry Smith #undef __FUNCT__
171109c9344SBarry Smith #define __FUNCT__ "DMDAGetCoordinateName"
172109c9344SBarry Smith /*@C
173109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
174109c9344SBarry Smith 
175109c9344SBarry Smith    Not Collective
176109c9344SBarry Smith 
177109c9344SBarry Smith    Input Parameter:
178109c9344SBarry Smith +  da - the distributed array
179109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
180109c9344SBarry Smith 
181109c9344SBarry Smith    Output Parameter:
182109c9344SBarry Smith .  names - the name of the coordinate direction
183109c9344SBarry Smith 
184109c9344SBarry Smith   Level: intermediate
185109c9344SBarry Smith 
186109c9344SBarry Smith .keywords: distributed array, get, component name
187109c9344SBarry Smith 
188109c9344SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName()
189109c9344SBarry Smith @*/
190109c9344SBarry Smith PetscErrorCode  DMDAGetCoordinateName(DM da,PetscInt nf,const char **name)
191109c9344SBarry Smith {
192109c9344SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
193109c9344SBarry Smith 
194109c9344SBarry Smith   PetscFunctionBegin;
195109c9344SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
196109c9344SBarry Smith   PetscValidPointer(name,3);
197109c9344SBarry Smith   if (nf < 0 || nf >= dd->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
198109c9344SBarry Smith   *name = dd->coordinatename[nf];
199109c9344SBarry Smith   PetscFunctionReturn(0);
200109c9344SBarry Smith }
201109c9344SBarry Smith 
202109c9344SBarry Smith #undef __FUNCT__
203aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners"
20447c6ae99SBarry Smith /*@
205aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
20647c6ae99SBarry Smith    corner of the local region, excluding ghost points.
20747c6ae99SBarry Smith 
20847c6ae99SBarry Smith    Not Collective
20947c6ae99SBarry Smith 
21047c6ae99SBarry Smith    Input Parameter:
21147c6ae99SBarry Smith .  da - the distributed array
21247c6ae99SBarry Smith 
21347c6ae99SBarry Smith    Output Parameters:
21447c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
21547c6ae99SBarry Smith            for 2D and 3D problems)
21647c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
21747c6ae99SBarry Smith            these are used for 2D and 3D problems)
21847c6ae99SBarry Smith 
21947c6ae99SBarry Smith    Note:
22047c6ae99SBarry Smith    The corner information is independent of the number of degrees of
221aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
22247c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
22347c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
22447c6ae99SBarry Smith    Any of y, z, n, and p can be passed in as PETSC_NULL if not needed.
22547c6ae99SBarry Smith 
22647c6ae99SBarry Smith   Level: beginner
22747c6ae99SBarry Smith 
22847c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
22947c6ae99SBarry Smith 
230aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
23147c6ae99SBarry Smith @*/
2327087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
23347c6ae99SBarry Smith {
23447c6ae99SBarry Smith   PetscInt w;
23547c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
23647c6ae99SBarry Smith 
23747c6ae99SBarry Smith   PetscFunctionBegin;
23847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
23947c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
24047c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
24147c6ae99SBarry Smith   w = dd->w;
242d886c4f4SPeter Brune   if (x) *x = dd->xs/w + dd->xo; if (m) *m = (dd->xe - dd->xs)/w;
24347c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
244d886c4f4SPeter Brune   if (y) *y = dd->ys + dd->yo;   if (n) *n = (dd->ye - dd->ys);
245d886c4f4SPeter Brune   if (z) *z = dd->zs + dd->zo;   if (p) *p = (dd->ze - dd->zs);
24647c6ae99SBarry Smith   PetscFunctionReturn(0);
24747c6ae99SBarry Smith }
24847c6ae99SBarry Smith 
24947c6ae99SBarry Smith #undef __FUNCT__
250aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox"
25147c6ae99SBarry Smith /*@
252aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
25347c6ae99SBarry Smith 
25447c6ae99SBarry Smith    Not Collective
25547c6ae99SBarry Smith 
25647c6ae99SBarry Smith    Input Parameter:
25747c6ae99SBarry Smith .  da - the distributed array
25847c6ae99SBarry Smith 
25947c6ae99SBarry Smith    Output Parameters:
26047c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
26147c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
26247c6ae99SBarry Smith 
26347c6ae99SBarry Smith   Level: beginner
26447c6ae99SBarry Smith 
26547c6ae99SBarry Smith .keywords: distributed array, get, coordinates
26647c6ae99SBarry Smith 
2672150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
26847c6ae99SBarry Smith @*/
2697087cfbeSBarry Smith PetscErrorCode  DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[])
27047c6ae99SBarry Smith {
27147c6ae99SBarry Smith   PetscErrorCode    ierr;
27247c6ae99SBarry Smith   Vec               coords  = PETSC_NULL;
27347c6ae99SBarry Smith   PetscInt          dim,i,j;
27447c6ae99SBarry Smith   const PetscScalar *local_coords;
275ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
27647c6ae99SBarry Smith   PetscInt          N,Ni;
27747c6ae99SBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
27847c6ae99SBarry Smith 
27947c6ae99SBarry Smith   PetscFunctionBegin;
28047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
28147c6ae99SBarry Smith   dim = dd->dim;
2826636e97aSMatthew G Knepley   ierr = DMGetCoordinates(da,&coords);CHKERRQ(ierr);
2837324c66bSJed Brown   if (coords) {
28447c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
28547c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
28647c6ae99SBarry Smith     Ni = N/dim;
28747c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
2887324c66bSJed Brown       for (j=0; j<3; j++) {
2897324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
2902197688cSJed Brown         max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
29147c6ae99SBarry Smith       }
29247c6ae99SBarry Smith     }
29347c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
2947324c66bSJed Brown   } else {                      /* Just use grid indices */
2957324c66bSJed Brown     DMDALocalInfo info;
2967324c66bSJed Brown     ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr);
2977324c66bSJed Brown     min[0] = info.xs;
2987324c66bSJed Brown     min[1] = info.ys;
2997324c66bSJed Brown     min[2] = info.zs;
3007324c66bSJed Brown     max[0] = info.xs + info.xm-1;
3017324c66bSJed Brown     max[1] = info.ys + info.ym-1;
3027324c66bSJed Brown     max[2] = info.zs + info.zm-1;
3037324c66bSJed Brown   }
30447c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
30547c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
30647c6ae99SBarry Smith   PetscFunctionReturn(0);
30747c6ae99SBarry Smith }
30847c6ae99SBarry Smith 
30947c6ae99SBarry Smith #undef __FUNCT__
310aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox"
31147c6ae99SBarry Smith /*@
312aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
31347c6ae99SBarry Smith 
314aa219208SBarry Smith    Collective on DMDA
31547c6ae99SBarry Smith 
31647c6ae99SBarry Smith    Input Parameter:
31747c6ae99SBarry Smith .  da - the distributed array
31847c6ae99SBarry Smith 
31947c6ae99SBarry Smith    Output Parameters:
32047c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
32147c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
32247c6ae99SBarry Smith 
32347c6ae99SBarry Smith   Level: beginner
32447c6ae99SBarry Smith 
32547c6ae99SBarry Smith .keywords: distributed array, get, coordinates
32647c6ae99SBarry Smith 
3272150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
32847c6ae99SBarry Smith @*/
3297087cfbeSBarry Smith PetscErrorCode  DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[])
33047c6ae99SBarry Smith {
33147c6ae99SBarry Smith   PetscErrorCode ierr;
33247c6ae99SBarry Smith   PetscMPIInt    count;
33347c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
33447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
33547c6ae99SBarry Smith 
33647c6ae99SBarry Smith   PetscFunctionBegin;
33747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
33847c6ae99SBarry Smith   count = PetscMPIIntCast(dd->dim);
339aa219208SBarry Smith   ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr);
340d9822059SBarry Smith   if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);}
341d9822059SBarry Smith   if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);}
34247c6ae99SBarry Smith   PetscFunctionReturn(0);
34347c6ae99SBarry Smith }
344bc2bf880SBarry Smith 
345bc2bf880SBarry Smith #undef __FUNCT__
346db05f41bSBarry Smith #define __FUNCT__ "DMDAGetReducedDMDA"
347bc2bf880SBarry Smith /*@
348db05f41bSBarry Smith    DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields
349bc2bf880SBarry Smith 
350bc2bf880SBarry Smith    Collective on DMDA
351bc2bf880SBarry Smith 
352bc2bf880SBarry Smith    Input Parameter:
353bc2bf880SBarry Smith +  da - the distributed array
354bc2bf880SBarry Smith .  nfields - number of fields in new DMDA
355bc2bf880SBarry Smith 
356bc2bf880SBarry Smith    Output Parameter:
357bc2bf880SBarry Smith .  nda - the new DMDA
358bc2bf880SBarry Smith 
359bc2bf880SBarry Smith   Level: intermediate
360bc2bf880SBarry Smith 
361bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
362bc2bf880SBarry Smith 
3632150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
364bc2bf880SBarry Smith @*/
365db05f41bSBarry Smith PetscErrorCode  DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
366bc2bf880SBarry Smith {
367bc2bf880SBarry Smith   PetscErrorCode   ierr;
368bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
369*95c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
370320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
371bc2bf880SBarry Smith   DMDABoundaryType bx,by,bz;
372320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
373*95c13181SPeter Brune   PetscInt         ox,oy,oz;
374*95c13181SPeter Brune   PetscInt         cl,rl;
375320964c4SBlaise Bourdin 
376320964c4SBlaise Bourdin   PetscFunctionBegin;
377*95c13181SPeter Brune   dim = dd->dim;
378*95c13181SPeter Brune   M   = dd->M;
379*95c13181SPeter Brune   N   = dd->N;
380*95c13181SPeter Brune   P   = dd->P;
381*95c13181SPeter Brune   m   = dd->m;
382*95c13181SPeter Brune   n   = dd->n;
383*95c13181SPeter Brune   p   = dd->p;
384*95c13181SPeter Brune   s   = dd->s;
385*95c13181SPeter Brune   bx  = dd->bx;
386*95c13181SPeter Brune   by  = dd->by;
387*95c13181SPeter Brune   bz  = dd->bz;
388*95c13181SPeter Brune   stencil_type = dd->stencil_type;
389320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
390320964c4SBlaise Bourdin   if (dim == 1) {
391320964c4SBlaise Bourdin     ierr = DMDACreate1d(((PetscObject)da)->comm,bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
392320964c4SBlaise Bourdin   } else if (dim == 2) {
393320964c4SBlaise Bourdin     ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
394320964c4SBlaise Bourdin   } else if (dim == 3) {
395320964c4SBlaise 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);
396bc2bf880SBarry Smith   }
3976636e97aSMatthew G Knepley   if (da->coordinates) {
3986636e97aSMatthew G Knepley     ierr        = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
3996636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
400bc2bf880SBarry Smith   }
401*95c13181SPeter Brune 
402*95c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
403*95c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
404*95c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
405*95c13181SPeter Brune 
406*95c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
407*95c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
408*95c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
409*95c13181SPeter Brune   (*nda)->levelup = rl;
410*95c13181SPeter Brune   (*nda)->leveldown = cl;
411*95c13181SPeter Brune 
412bc2bf880SBarry Smith   PetscFunctionReturn(0);
413bc2bf880SBarry Smith }
414bc2bf880SBarry Smith 
415