xref: /petsc/src/dm/impls/da/dacorn.c (revision f19dbd5846ffd4db2e55501a1bb9a58c867a074c)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/
7*f19dbd58SToby Isaac #include <petscdmfield.h>
847c6ae99SBarry Smith 
96636e97aSMatthew G Knepley PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
1047c6ae99SBarry Smith {
1147c6ae99SBarry Smith   PetscErrorCode ierr;
123f2d3b52SPeter Brune   PetscFunctionBegin;
13c73cfb54SMatthew G. Knepley   ierr = DMDAGetReducedDMDA(dm,dm->dim,cdm);CHKERRQ(ierr);
1447c6ae99SBarry Smith   PetscFunctionReturn(0);
1547c6ae99SBarry Smith }
1647c6ae99SBarry Smith 
17*f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_DA(DM dm, DMField *field)
18*f19dbd58SToby Isaac {
19*f19dbd58SToby Isaac   PetscReal      gmin[3], gmax[3];
20*f19dbd58SToby Isaac   PetscReal      corners[24];
21*f19dbd58SToby Isaac   PetscInt       dim;
22*f19dbd58SToby Isaac   PetscInt       i, j;
23*f19dbd58SToby Isaac   DM             cdm;
24*f19dbd58SToby Isaac   PetscErrorCode ierr;
25*f19dbd58SToby Isaac 
26*f19dbd58SToby Isaac   PetscFunctionBegin;
27*f19dbd58SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
28*f19dbd58SToby Isaac   /* TODO: this is wrong if coordinates are not rectilinear */
29*f19dbd58SToby Isaac   ierr = DMDAGetBoundingBox(dm,gmin,gmax);CHKERRQ(ierr);
30*f19dbd58SToby Isaac   for (i = 0; i < (1 << dim); i++) {
31*f19dbd58SToby Isaac     for (j = 0; j < dim; j++) {
32*f19dbd58SToby Isaac       corners[i*dim + j] = (i & (1 << j)) ? gmax[j] : gmin[j];
33*f19dbd58SToby Isaac     }
34*f19dbd58SToby Isaac   }
35*f19dbd58SToby Isaac   ierr = DMClone(dm,&cdm);CHKERRQ(ierr);
36*f19dbd58SToby Isaac   ierr = DMFieldCreateDA(cdm,dim,corners,field);CHKERRQ(ierr);
37*f19dbd58SToby Isaac   ierr = DMDestroy(&cdm);CHKERRQ(ierr);
38*f19dbd58SToby Isaac   PetscFunctionReturn(0);
39*f19dbd58SToby Isaac }
40*f19dbd58SToby Isaac 
4147c6ae99SBarry Smith /*@C
42aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
43aa219208SBarry Smith    vectors associated with a DMDA.
4447c6ae99SBarry Smith 
4547c6ae99SBarry Smith    Not Collective
4647c6ae99SBarry Smith 
4747c6ae99SBarry Smith    Input Parameters:
4847c6ae99SBarry Smith +  da - the distributed array
49aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
50aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
5147c6ae99SBarry Smith -  names - the name of the field (component)
5247c6ae99SBarry Smith 
533eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
543eac1ceeSStefano Zampini 
5547c6ae99SBarry Smith   Level: intermediate
5647c6ae99SBarry Smith 
5747c6ae99SBarry Smith .keywords: distributed array, get, component name
5847c6ae99SBarry Smith 
593eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldNames(), DMSetUp()
6047c6ae99SBarry Smith @*/
617087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
6247c6ae99SBarry Smith {
6347c6ae99SBarry Smith   PetscErrorCode ierr;
6447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
6547c6ae99SBarry Smith 
6647c6ae99SBarry Smith   PetscFunctionBegin;
6747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
6847c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
693eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
70c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
7147c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
7247c6ae99SBarry Smith   PetscFunctionReturn(0);
7347c6ae99SBarry Smith }
7447c6ae99SBarry Smith 
75c629b14aSBarry Smith /*@C
76c629b14aSBarry Smith    DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
77c629b14aSBarry Smith 
78c629b14aSBarry Smith    Collective on TS
79c629b14aSBarry Smith 
80c629b14aSBarry Smith    Input Parameter:
81c629b14aSBarry Smith .  dm - the DMDA object
82c629b14aSBarry Smith 
83c629b14aSBarry Smith    Output Parameter:
84c629b14aSBarry Smith .  names - the names of the components, final string is NULL, will have the same number of entries as the dof used in creating the DMDA
85c629b14aSBarry Smith 
86c629b14aSBarry Smith    Level: intermediate
87c629b14aSBarry Smith 
88f5f57ec0SBarry Smith    Not supported from Fortran, use DMDAGetFieldName()
89f5f57ec0SBarry Smith 
90c629b14aSBarry Smith .keywords: distributed array, get, component name
91c629b14aSBarry Smith 
92c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
93c629b14aSBarry Smith @*/
94c629b14aSBarry Smith PetscErrorCode  DMDAGetFieldNames(DM da,const char * const **names)
95c629b14aSBarry Smith {
96c629b14aSBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
97c629b14aSBarry Smith 
98c629b14aSBarry Smith   PetscFunctionBegin;
99c629b14aSBarry Smith   *names = (const char * const *) dd->fieldname;
100c629b14aSBarry Smith   PetscFunctionReturn(0);
101c629b14aSBarry Smith }
102c629b14aSBarry Smith 
103c629b14aSBarry Smith /*@C
104c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
105c629b14aSBarry Smith 
106c629b14aSBarry Smith    Collective on TS
107c629b14aSBarry Smith 
108c629b14aSBarry Smith    Input Parameters:
109c629b14aSBarry Smith +  dm - the DMDA object
110c629b14aSBarry Smith -  names - the names of the components, final string must be NULL, must have the same number of entries as the dof used in creating the DMDA
111c629b14aSBarry Smith 
1123eac1ceeSStefano Zampini    Notes: It must be called after having called DMSetUp().
1133eac1ceeSStefano Zampini 
114c629b14aSBarry Smith    Level: intermediate
115c629b14aSBarry Smith 
116f5f57ec0SBarry Smith    Not supported from Fortran, use DMDASetFieldName()
117f5f57ec0SBarry Smith 
118c629b14aSBarry Smith .keywords: distributed array, get, component name
119c629b14aSBarry Smith 
1203eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMSetUp()
121c629b14aSBarry Smith @*/
122c629b14aSBarry Smith PetscErrorCode  DMDASetFieldNames(DM da,const char * const *names)
123c629b14aSBarry Smith {
124c629b14aSBarry Smith   PetscErrorCode ierr;
125c629b14aSBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
1263eac1ceeSStefano Zampini   char           **fieldname;
1273eac1ceeSStefano Zampini   PetscInt       nf = 0;
128c629b14aSBarry Smith 
129c629b14aSBarry Smith   PetscFunctionBegin;
1303eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
1313eac1ceeSStefano Zampini   while (names[nf++]) {};
1323eac1ceeSStefano Zampini   if (nf != dd->w+1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid number of fields %D",nf-1);
1333eac1ceeSStefano Zampini   ierr = PetscStrArrayallocpy(names,&fieldname);CHKERRQ(ierr);
134c629b14aSBarry Smith   ierr = PetscStrArrayDestroy(&dd->fieldname);CHKERRQ(ierr);
1353eac1ceeSStefano Zampini   dd->fieldname = fieldname;
136c629b14aSBarry Smith   PetscFunctionReturn(0);
137c629b14aSBarry Smith }
138c629b14aSBarry Smith 
13947c6ae99SBarry Smith /*@C
140aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
141aa219208SBarry Smith    vectors associated with a DMDA.
14247c6ae99SBarry Smith 
14347c6ae99SBarry Smith    Not Collective
14447c6ae99SBarry Smith 
14547c6ae99SBarry Smith    Input Parameter:
14647c6ae99SBarry Smith +  da - the distributed array
147aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
148aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
14947c6ae99SBarry Smith 
15047c6ae99SBarry Smith    Output Parameter:
15147c6ae99SBarry Smith .  names - the name of the field (component)
15247c6ae99SBarry Smith 
1533eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
1543eac1ceeSStefano Zampini 
15547c6ae99SBarry Smith   Level: intermediate
15647c6ae99SBarry Smith 
15747c6ae99SBarry Smith .keywords: distributed array, get, component name
15847c6ae99SBarry Smith 
1593eac1ceeSStefano Zampini .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMSetUp()
16047c6ae99SBarry Smith @*/
1617087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
16247c6ae99SBarry Smith {
16347c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
16447c6ae99SBarry Smith 
16547c6ae99SBarry Smith   PetscFunctionBegin;
16647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
16747c6ae99SBarry Smith   PetscValidPointer(name,3);
16847c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
1693eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
17047c6ae99SBarry Smith   *name = dd->fieldname[nf];
17147c6ae99SBarry Smith   PetscFunctionReturn(0);
17247c6ae99SBarry Smith }
17347c6ae99SBarry Smith 
174109c9344SBarry Smith /*@C
175109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
176109c9344SBarry Smith 
177109c9344SBarry Smith    Not Collective
178109c9344SBarry Smith 
179109c9344SBarry Smith    Input Parameters:
180c73cfb54SMatthew G. Knepley +  dm - the DM
181109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
182109c9344SBarry Smith -  name - the name of the coordinate
183109c9344SBarry Smith 
1843eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
1853eac1ceeSStefano Zampini 
186109c9344SBarry Smith   Level: intermediate
187109c9344SBarry Smith 
188f5f57ec0SBarry Smith   Not supported from Fortran
189f5f57ec0SBarry Smith 
190109c9344SBarry Smith .keywords: distributed array, get, component name
191109c9344SBarry Smith 
1923eac1ceeSStefano Zampini .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
193109c9344SBarry Smith @*/
194c73cfb54SMatthew G. Knepley PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
195109c9344SBarry Smith {
196109c9344SBarry Smith   PetscErrorCode ierr;
197c73cfb54SMatthew G. Knepley   DM_DA          *dd = (DM_DA*)dm->data;
198109c9344SBarry Smith 
199109c9344SBarry Smith   PetscFunctionBegin;
200c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
201c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
2023eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
203109c9344SBarry Smith   ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr);
204109c9344SBarry Smith   ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr);
205109c9344SBarry Smith   PetscFunctionReturn(0);
206109c9344SBarry Smith }
207109c9344SBarry Smith 
208109c9344SBarry Smith /*@C
209109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
210109c9344SBarry Smith 
211109c9344SBarry Smith    Not Collective
212109c9344SBarry Smith 
213109c9344SBarry Smith    Input Parameter:
214c73cfb54SMatthew G. Knepley +  dm - the DM
215109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
216109c9344SBarry Smith 
217109c9344SBarry Smith    Output Parameter:
218109c9344SBarry Smith .  names - the name of the coordinate direction
219109c9344SBarry Smith 
2203eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
2213eac1ceeSStefano Zampini 
222109c9344SBarry Smith   Level: intermediate
223109c9344SBarry Smith 
224f5f57ec0SBarry Smith   Not supported from Fortran
225f5f57ec0SBarry Smith 
226109c9344SBarry Smith .keywords: distributed array, get, component name
227109c9344SBarry Smith 
2283eac1ceeSStefano Zampini .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
229109c9344SBarry Smith @*/
230c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
231109c9344SBarry Smith {
232c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA*)dm->data;
233109c9344SBarry Smith 
234109c9344SBarry Smith   PetscFunctionBegin;
235c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
236109c9344SBarry Smith   PetscValidPointer(name,3);
237c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
2383eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
239109c9344SBarry Smith   *name = dd->coordinatename[nf];
240109c9344SBarry Smith   PetscFunctionReturn(0);
241109c9344SBarry Smith }
242109c9344SBarry Smith 
243a5d1443cSVincent Le Chenadec /*@C
244aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
24559f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
24647c6ae99SBarry Smith 
24747c6ae99SBarry Smith    Not Collective
24847c6ae99SBarry Smith 
24947c6ae99SBarry Smith    Input Parameter:
25047c6ae99SBarry Smith .  da - the distributed array
25147c6ae99SBarry Smith 
25247c6ae99SBarry Smith    Output Parameters:
25347c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
25447c6ae99SBarry Smith            for 2D and 3D problems)
25547c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
25647c6ae99SBarry Smith            these are used for 2D and 3D problems)
25747c6ae99SBarry Smith 
25847c6ae99SBarry Smith    Note:
25947c6ae99SBarry Smith    The corner information is independent of the number of degrees of
260aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
26147c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
26247c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2630298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
26447c6ae99SBarry Smith 
26547c6ae99SBarry Smith   Level: beginner
26647c6ae99SBarry Smith 
26747c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
26847c6ae99SBarry Smith 
269aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
27047c6ae99SBarry Smith @*/
2717087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
27247c6ae99SBarry Smith {
27347c6ae99SBarry Smith   PetscInt w;
27447c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
27547c6ae99SBarry Smith 
27647c6ae99SBarry Smith   PetscFunctionBegin;
27747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
27847c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
27947c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
28047c6ae99SBarry Smith   w = dd->w;
28159bc5b24SSatish Balay   if (x) *x = dd->xs/w + dd->xo;
28247c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
28359bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
28459bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
28559bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs)/w;
28659bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
28759bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
28847c6ae99SBarry Smith   PetscFunctionReturn(0);
28947c6ae99SBarry Smith }
29047c6ae99SBarry Smith 
29147c6ae99SBarry Smith /*@
292aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
29347c6ae99SBarry Smith 
29447c6ae99SBarry Smith    Not Collective
29547c6ae99SBarry Smith 
29647c6ae99SBarry Smith    Input Parameter:
297c73cfb54SMatthew G. Knepley .  dm - the DM
29847c6ae99SBarry Smith 
29947c6ae99SBarry Smith    Output Parameters:
30047c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
30147c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
30247c6ae99SBarry Smith 
30347c6ae99SBarry Smith   Level: beginner
30447c6ae99SBarry Smith 
305f5f57ec0SBarry Smith   Not supported from Fortran
306f5f57ec0SBarry Smith 
30747c6ae99SBarry Smith .keywords: distributed array, get, coordinates
30847c6ae99SBarry Smith 
3092150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
31047c6ae99SBarry Smith @*/
311c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[])
31247c6ae99SBarry Smith {
31347c6ae99SBarry Smith   PetscErrorCode    ierr;
3140298fd71SBarry Smith   Vec               coords = NULL;
31547c6ae99SBarry Smith   PetscInt          dim,i,j;
31647c6ae99SBarry Smith   const PetscScalar *local_coords;
317ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
31847c6ae99SBarry Smith   PetscInt          N,Ni;
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith   PetscFunctionBegin;
321c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
322c73cfb54SMatthew G. Knepley   dim  = dm->dim;
323c73cfb54SMatthew G. Knepley   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
3247324c66bSJed Brown   if (coords) {
32547c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
32647c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
32747c6ae99SBarry Smith     Ni   = N/dim;
32847c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
3297324c66bSJed Brown       for (j=0; j<3; j++) {
3307324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
3312197688cSJed Brown         max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
33247c6ae99SBarry Smith       }
33347c6ae99SBarry Smith     }
33447c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
3357324c66bSJed Brown   } else {                      /* Just use grid indices */
3367324c66bSJed Brown     DMDALocalInfo info;
337c73cfb54SMatthew G. Knepley     ierr   = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
3387324c66bSJed Brown     min[0] = info.xs;
3397324c66bSJed Brown     min[1] = info.ys;
3407324c66bSJed Brown     min[2] = info.zs;
3417324c66bSJed Brown     max[0] = info.xs + info.xm-1;
3427324c66bSJed Brown     max[1] = info.ys + info.ym-1;
3437324c66bSJed Brown     max[2] = info.zs + info.zm-1;
3447324c66bSJed Brown   }
34547c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
34647c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
34747c6ae99SBarry Smith   PetscFunctionReturn(0);
34847c6ae99SBarry Smith }
34947c6ae99SBarry Smith 
35047c6ae99SBarry Smith /*@
351aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
35247c6ae99SBarry Smith 
353aa219208SBarry Smith    Collective on DMDA
35447c6ae99SBarry Smith 
35547c6ae99SBarry Smith    Input Parameter:
356c73cfb54SMatthew G. Knepley .  dm - the DM
35747c6ae99SBarry Smith 
35847c6ae99SBarry Smith    Output Parameters:
35947c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
36047c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
36147c6ae99SBarry Smith 
36247c6ae99SBarry Smith   Level: beginner
36347c6ae99SBarry Smith 
36447c6ae99SBarry Smith .keywords: distributed array, get, coordinates
36547c6ae99SBarry Smith 
3662150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
36747c6ae99SBarry Smith @*/
368c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetBoundingBox(DM dm,PetscReal gmin[],PetscReal gmax[])
36947c6ae99SBarry Smith {
37047c6ae99SBarry Smith   PetscErrorCode ierr;
37147c6ae99SBarry Smith   PetscMPIInt    count;
37247c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
37347c6ae99SBarry Smith 
37447c6ae99SBarry Smith   PetscFunctionBegin;
375c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
376c73cfb54SMatthew G. Knepley   ierr = PetscMPIIntCast(dm->dim,&count);CHKERRQ(ierr);
377c73cfb54SMatthew G. Knepley   ierr = DMDAGetLocalBoundingBox(dm,lmin,lmax);CHKERRQ(ierr);
378b2566f29SBarry Smith   if (gmin) {ierr = MPIU_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
379b2566f29SBarry Smith   if (gmax) {ierr = MPIU_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
38047c6ae99SBarry Smith   PetscFunctionReturn(0);
38147c6ae99SBarry Smith }
382bc2bf880SBarry Smith 
383bc2bf880SBarry Smith /*@
384db05f41bSBarry Smith    DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields
385bc2bf880SBarry Smith 
386bc2bf880SBarry Smith    Collective on DMDA
387bc2bf880SBarry Smith 
388907376e6SBarry Smith    Input Parameters:
389bc2bf880SBarry Smith +  da - the distributed array
390907376e6SBarry Smith -  nfields - number of fields in new DMDA
391bc2bf880SBarry Smith 
392bc2bf880SBarry Smith    Output Parameter:
393bc2bf880SBarry Smith .  nda - the new DMDA
394bc2bf880SBarry Smith 
395bc2bf880SBarry Smith   Level: intermediate
396bc2bf880SBarry Smith 
397bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
398bc2bf880SBarry Smith 
3992150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
400bc2bf880SBarry Smith @*/
401db05f41bSBarry Smith PetscErrorCode  DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
402bc2bf880SBarry Smith {
403bc2bf880SBarry Smith   PetscErrorCode   ierr;
404bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
40595c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
406320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
407bff4a2f0SMatthew G. Knepley   DMBoundaryType   bx,by,bz;
408320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
40995c13181SPeter Brune   PetscInt         ox,oy,oz;
41095c13181SPeter Brune   PetscInt         cl,rl;
411320964c4SBlaise Bourdin 
412320964c4SBlaise Bourdin   PetscFunctionBegin;
413c73cfb54SMatthew G. Knepley   dim = da->dim;
41495c13181SPeter Brune   M   = dd->M;
41595c13181SPeter Brune   N   = dd->N;
41695c13181SPeter Brune   P   = dd->P;
41795c13181SPeter Brune   m   = dd->m;
41895c13181SPeter Brune   n   = dd->n;
41995c13181SPeter Brune   p   = dd->p;
42095c13181SPeter Brune   s   = dd->s;
42195c13181SPeter Brune   bx  = dd->bx;
42295c13181SPeter Brune   by  = dd->by;
42395c13181SPeter Brune   bz  = dd->bz;
4248865f1eaSKarl Rupp 
42595c13181SPeter Brune   stencil_type = dd->stencil_type;
4268865f1eaSKarl Rupp 
427320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
428320964c4SBlaise Bourdin   if (dim == 1) {
429ce94432eSBarry Smith     ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
430320964c4SBlaise Bourdin   } else if (dim == 2) {
431ce94432eSBarry Smith     ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
432320964c4SBlaise Bourdin   } else if (dim == 3) {
433ce94432eSBarry Smith     ierr = DMDACreate3d(PetscObjectComm((PetscObject)da),bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);CHKERRQ(ierr);
434bc2bf880SBarry Smith   }
435897f7067SBarry Smith   ierr = DMSetUp(*nda);CHKERRQ(ierr);
4366636e97aSMatthew G Knepley   if (da->coordinates) {
4376636e97aSMatthew G Knepley     ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
4386636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
439bc2bf880SBarry Smith   }
44095c13181SPeter Brune 
44195c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
44295c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
44395c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
44495c13181SPeter Brune 
44595c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
44695c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
44795c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
4488865f1eaSKarl Rupp 
44995c13181SPeter Brune   (*nda)->levelup   = rl;
45095c13181SPeter Brune   (*nda)->leveldown = cl;
451bc2bf880SBarry Smith   PetscFunctionReturn(0);
452bc2bf880SBarry Smith }
453bc2bf880SBarry Smith 
454c593f006SBarry Smith /*@C
455c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
456c593f006SBarry Smith 
457c593f006SBarry Smith    Not Collective
458c593f006SBarry Smith 
459c593f006SBarry Smith    Input Parameter:
460c593f006SBarry Smith .  dm - the DM
461c593f006SBarry Smith 
462c593f006SBarry Smith    Output Parameter:
463c593f006SBarry Smith .  xc - the coordinates
464c593f006SBarry Smith 
465c593f006SBarry Smith   Level: intermediate
466c593f006SBarry Smith 
467f5f57ec0SBarry Smith   Not supported from Fortran
468f5f57ec0SBarry Smith 
469c593f006SBarry Smith .keywords: distributed array, get, component name
470c593f006SBarry Smith 
471c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
472c593f006SBarry Smith @*/
473c593f006SBarry Smith PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
474c593f006SBarry Smith {
475c593f006SBarry Smith   PetscErrorCode ierr;
476c593f006SBarry Smith   DM             cdm;
477c593f006SBarry Smith   Vec            x;
478c593f006SBarry Smith 
479c593f006SBarry Smith   PetscFunctionBegin;
480c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
481c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
482c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
483c593f006SBarry Smith   ierr = DMDAVecGetArray(cdm,x,xc);CHKERRQ(ierr);
484c593f006SBarry Smith   PetscFunctionReturn(0);
485c593f006SBarry Smith }
486c593f006SBarry Smith 
487c593f006SBarry Smith /*@C
488c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
489c593f006SBarry Smith 
490c593f006SBarry Smith    Not Collective
491c593f006SBarry Smith 
492c593f006SBarry Smith    Input Parameter:
493c593f006SBarry Smith +  dm - the DM
494c593f006SBarry Smith -  xc - the coordinates
495c593f006SBarry Smith 
496c593f006SBarry Smith   Level: intermediate
497c593f006SBarry Smith 
498f5f57ec0SBarry Smith   Not supported from Fortran
499f5f57ec0SBarry Smith 
500c593f006SBarry Smith .keywords: distributed array, get, component name
501c593f006SBarry Smith 
502c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
503c593f006SBarry Smith @*/
504c593f006SBarry Smith PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
505c593f006SBarry Smith {
506c593f006SBarry Smith   PetscErrorCode ierr;
507c593f006SBarry Smith   DM             cdm;
508c593f006SBarry Smith   Vec            x;
509c593f006SBarry Smith 
510c593f006SBarry Smith   PetscFunctionBegin;
511c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
512c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
513c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
514c593f006SBarry Smith   ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr);
515c593f006SBarry Smith   PetscFunctionReturn(0);
516c593f006SBarry Smith }
517