xref: /petsc/src/dm/impls/da/dacorn.c (revision 211d3afb70a2c85c8ea35e22f0c64a5e0dd01503)
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*/
7f19dbd58SToby 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;
13*211d3afbSPatrick Sanan   ierr = DMDACreateCompatibleDMDA(dm,dm->dim,cdm);CHKERRQ(ierr);
1447c6ae99SBarry Smith   PetscFunctionReturn(0);
1547c6ae99SBarry Smith }
1647c6ae99SBarry Smith 
17f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_DA(DM dm, DMField *field)
18f19dbd58SToby Isaac {
19f19dbd58SToby Isaac   PetscReal      gmin[3], gmax[3];
204d1a973fSToby Isaac   PetscScalar    corners[24];
21f19dbd58SToby Isaac   PetscInt       dim;
22f19dbd58SToby Isaac   PetscInt       i, j;
23f19dbd58SToby Isaac   DM             cdm;
24f19dbd58SToby Isaac   PetscErrorCode ierr;
25f19dbd58SToby Isaac 
26f19dbd58SToby Isaac   PetscFunctionBegin;
27f19dbd58SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
28f19dbd58SToby Isaac   /* TODO: this is wrong if coordinates are not rectilinear */
29f19dbd58SToby Isaac   ierr = DMDAGetBoundingBox(dm,gmin,gmax);CHKERRQ(ierr);
30f19dbd58SToby Isaac   for (i = 0; i < (1 << dim); i++) {
31f19dbd58SToby Isaac     for (j = 0; j < dim; j++) {
32f19dbd58SToby Isaac       corners[i*dim + j] = (i & (1 << j)) ? gmax[j] : gmin[j];
33f19dbd58SToby Isaac     }
34f19dbd58SToby Isaac   }
35f19dbd58SToby Isaac   ierr = DMClone(dm,&cdm);CHKERRQ(ierr);
36f19dbd58SToby Isaac   ierr = DMFieldCreateDA(cdm,dim,corners,field);CHKERRQ(ierr);
37f19dbd58SToby Isaac   ierr = DMDestroy(&cdm);CHKERRQ(ierr);
38f19dbd58SToby Isaac   PetscFunctionReturn(0);
39f19dbd58SToby Isaac }
40f19dbd58SToby 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 
5395452b02SPatrick Sanan   Notes:
5495452b02SPatrick Sanan     It must be called after having called DMSetUp().
553eac1ceeSStefano Zampini 
5647c6ae99SBarry Smith   Level: intermediate
5747c6ae99SBarry Smith 
5847c6ae99SBarry Smith .keywords: distributed array, get, component name
5947c6ae99SBarry Smith 
603eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldNames(), DMSetUp()
6147c6ae99SBarry Smith @*/
627087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
6347c6ae99SBarry Smith {
6447c6ae99SBarry Smith   PetscErrorCode ierr;
6547c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
6647c6ae99SBarry Smith 
6747c6ae99SBarry Smith   PetscFunctionBegin;
6847c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
6947c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
703eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
71c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
7247c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
7347c6ae99SBarry Smith   PetscFunctionReturn(0);
7447c6ae99SBarry Smith }
7547c6ae99SBarry Smith 
76c629b14aSBarry Smith /*@C
77c629b14aSBarry Smith    DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
78c629b14aSBarry Smith 
79c629b14aSBarry Smith    Collective on TS
80c629b14aSBarry Smith 
81c629b14aSBarry Smith    Input Parameter:
82c629b14aSBarry Smith .  dm - the DMDA object
83c629b14aSBarry Smith 
84c629b14aSBarry Smith    Output Parameter:
85c629b14aSBarry 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
86c629b14aSBarry Smith 
87c629b14aSBarry Smith    Level: intermediate
88c629b14aSBarry Smith 
89f5f57ec0SBarry Smith    Not supported from Fortran, use DMDAGetFieldName()
90f5f57ec0SBarry Smith 
91c629b14aSBarry Smith .keywords: distributed array, get, component name
92c629b14aSBarry Smith 
93c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
94c629b14aSBarry Smith @*/
95c629b14aSBarry Smith PetscErrorCode  DMDAGetFieldNames(DM da,const char * const **names)
96c629b14aSBarry Smith {
97c629b14aSBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
98c629b14aSBarry Smith 
99c629b14aSBarry Smith   PetscFunctionBegin;
100c629b14aSBarry Smith   *names = (const char * const *) dd->fieldname;
101c629b14aSBarry Smith   PetscFunctionReturn(0);
102c629b14aSBarry Smith }
103c629b14aSBarry Smith 
104c629b14aSBarry Smith /*@C
105c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
106c629b14aSBarry Smith 
107c629b14aSBarry Smith    Collective on TS
108c629b14aSBarry Smith 
109c629b14aSBarry Smith    Input Parameters:
110c629b14aSBarry Smith +  dm - the DMDA object
111c629b14aSBarry 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
112c629b14aSBarry Smith 
11395452b02SPatrick Sanan    Notes:
11495452b02SPatrick Sanan     It must be called after having called DMSetUp().
1153eac1ceeSStefano Zampini 
116c629b14aSBarry Smith    Level: intermediate
117c629b14aSBarry Smith 
118f5f57ec0SBarry Smith    Not supported from Fortran, use DMDASetFieldName()
119f5f57ec0SBarry Smith 
120c629b14aSBarry Smith .keywords: distributed array, get, component name
121c629b14aSBarry Smith 
1223eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMSetUp()
123c629b14aSBarry Smith @*/
124c629b14aSBarry Smith PetscErrorCode  DMDASetFieldNames(DM da,const char * const *names)
125c629b14aSBarry Smith {
126c629b14aSBarry Smith   PetscErrorCode ierr;
127c629b14aSBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
1283eac1ceeSStefano Zampini   char           **fieldname;
1293eac1ceeSStefano Zampini   PetscInt       nf = 0;
130c629b14aSBarry Smith 
131c629b14aSBarry Smith   PetscFunctionBegin;
1323eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
1333eac1ceeSStefano Zampini   while (names[nf++]) {};
1343eac1ceeSStefano Zampini   if (nf != dd->w+1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid number of fields %D",nf-1);
1353eac1ceeSStefano Zampini   ierr = PetscStrArrayallocpy(names,&fieldname);CHKERRQ(ierr);
136c629b14aSBarry Smith   ierr = PetscStrArrayDestroy(&dd->fieldname);CHKERRQ(ierr);
1373eac1ceeSStefano Zampini   dd->fieldname = fieldname;
138c629b14aSBarry Smith   PetscFunctionReturn(0);
139c629b14aSBarry Smith }
140c629b14aSBarry Smith 
14147c6ae99SBarry Smith /*@C
142aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
143aa219208SBarry Smith    vectors associated with a DMDA.
14447c6ae99SBarry Smith 
14547c6ae99SBarry Smith    Not Collective
14647c6ae99SBarry Smith 
14747c6ae99SBarry Smith    Input Parameter:
14847c6ae99SBarry Smith +  da - the distributed array
149aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
150aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
15147c6ae99SBarry Smith 
15247c6ae99SBarry Smith    Output Parameter:
15347c6ae99SBarry Smith .  names - the name of the field (component)
15447c6ae99SBarry Smith 
15595452b02SPatrick Sanan   Notes:
15695452b02SPatrick Sanan     It must be called after having called DMSetUp().
1573eac1ceeSStefano Zampini 
15847c6ae99SBarry Smith   Level: intermediate
15947c6ae99SBarry Smith 
16047c6ae99SBarry Smith .keywords: distributed array, get, component name
16147c6ae99SBarry Smith 
1623eac1ceeSStefano Zampini .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMSetUp()
16347c6ae99SBarry Smith @*/
1647087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
16547c6ae99SBarry Smith {
16647c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
16747c6ae99SBarry Smith 
16847c6ae99SBarry Smith   PetscFunctionBegin;
16947c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
17047c6ae99SBarry Smith   PetscValidPointer(name,3);
17147c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
1723eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
17347c6ae99SBarry Smith   *name = dd->fieldname[nf];
17447c6ae99SBarry Smith   PetscFunctionReturn(0);
17547c6ae99SBarry Smith }
17647c6ae99SBarry Smith 
177109c9344SBarry Smith /*@C
178109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
179109c9344SBarry Smith 
180109c9344SBarry Smith    Not Collective
181109c9344SBarry Smith 
182109c9344SBarry Smith    Input Parameters:
183c73cfb54SMatthew G. Knepley +  dm - the DM
184109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
185109c9344SBarry Smith -  name - the name of the coordinate
186109c9344SBarry Smith 
18795452b02SPatrick Sanan   Notes:
18895452b02SPatrick Sanan     It must be called after having called DMSetUp().
1893eac1ceeSStefano Zampini 
190109c9344SBarry Smith   Level: intermediate
191109c9344SBarry Smith 
192f5f57ec0SBarry Smith   Not supported from Fortran
193f5f57ec0SBarry Smith 
194109c9344SBarry Smith .keywords: distributed array, get, component name
195109c9344SBarry Smith 
1963eac1ceeSStefano Zampini .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
197109c9344SBarry Smith @*/
198c73cfb54SMatthew G. Knepley PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
199109c9344SBarry Smith {
200109c9344SBarry Smith   PetscErrorCode ierr;
201c73cfb54SMatthew G. Knepley   DM_DA          *dd = (DM_DA*)dm->data;
202109c9344SBarry Smith 
203109c9344SBarry Smith   PetscFunctionBegin;
204c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
205c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
2063eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
207109c9344SBarry Smith   ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr);
208109c9344SBarry Smith   ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr);
209109c9344SBarry Smith   PetscFunctionReturn(0);
210109c9344SBarry Smith }
211109c9344SBarry Smith 
212109c9344SBarry Smith /*@C
213109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
214109c9344SBarry Smith 
215109c9344SBarry Smith    Not Collective
216109c9344SBarry Smith 
217109c9344SBarry Smith    Input Parameter:
218c73cfb54SMatthew G. Knepley +  dm - the DM
219109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
220109c9344SBarry Smith 
221109c9344SBarry Smith    Output Parameter:
222109c9344SBarry Smith .  names - the name of the coordinate direction
223109c9344SBarry Smith 
22495452b02SPatrick Sanan   Notes:
22595452b02SPatrick Sanan     It must be called after having called DMSetUp().
2263eac1ceeSStefano Zampini 
227109c9344SBarry Smith   Level: intermediate
228109c9344SBarry Smith 
229f5f57ec0SBarry Smith   Not supported from Fortran
230f5f57ec0SBarry Smith 
231109c9344SBarry Smith .keywords: distributed array, get, component name
232109c9344SBarry Smith 
2333eac1ceeSStefano Zampini .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
234109c9344SBarry Smith @*/
235c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
236109c9344SBarry Smith {
237c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA*)dm->data;
238109c9344SBarry Smith 
239109c9344SBarry Smith   PetscFunctionBegin;
240c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
241109c9344SBarry Smith   PetscValidPointer(name,3);
242c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
2433eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
244109c9344SBarry Smith   *name = dd->coordinatename[nf];
245109c9344SBarry Smith   PetscFunctionReturn(0);
246109c9344SBarry Smith }
247109c9344SBarry Smith 
248a5d1443cSVincent Le Chenadec /*@C
249aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
25059f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
25147c6ae99SBarry Smith 
25247c6ae99SBarry Smith    Not Collective
25347c6ae99SBarry Smith 
25447c6ae99SBarry Smith    Input Parameter:
25547c6ae99SBarry Smith .  da - the distributed array
25647c6ae99SBarry Smith 
25747c6ae99SBarry Smith    Output Parameters:
25847c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
25947c6ae99SBarry Smith            for 2D and 3D problems)
26047c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
26147c6ae99SBarry Smith            these are used for 2D and 3D problems)
26247c6ae99SBarry Smith 
26347c6ae99SBarry Smith    Note:
26447c6ae99SBarry Smith    The corner information is independent of the number of degrees of
265aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
26647c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
26747c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2680298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
26947c6ae99SBarry Smith 
27047c6ae99SBarry Smith   Level: beginner
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
27347c6ae99SBarry Smith 
274aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
27547c6ae99SBarry Smith @*/
2767087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
27747c6ae99SBarry Smith {
27847c6ae99SBarry Smith   PetscInt w;
27947c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
28047c6ae99SBarry Smith 
28147c6ae99SBarry Smith   PetscFunctionBegin;
28247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
28347c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
28447c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
28547c6ae99SBarry Smith   w = dd->w;
28659bc5b24SSatish Balay   if (x) *x = dd->xs/w + dd->xo;
28747c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
28859bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
28959bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
29059bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs)/w;
29159bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
29259bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
29347c6ae99SBarry Smith   PetscFunctionReturn(0);
29447c6ae99SBarry Smith }
29547c6ae99SBarry Smith 
29647c6ae99SBarry Smith /*@
297aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
29847c6ae99SBarry Smith 
29947c6ae99SBarry Smith    Not Collective
30047c6ae99SBarry Smith 
30147c6ae99SBarry Smith    Input Parameter:
302c73cfb54SMatthew G. Knepley .  dm - the DM
30347c6ae99SBarry Smith 
30447c6ae99SBarry Smith    Output Parameters:
30547c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
30647c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
30747c6ae99SBarry Smith 
30847c6ae99SBarry Smith   Level: beginner
30947c6ae99SBarry Smith 
310f5f57ec0SBarry Smith   Not supported from Fortran
311f5f57ec0SBarry Smith 
31247c6ae99SBarry Smith .keywords: distributed array, get, coordinates
31347c6ae99SBarry Smith 
3142150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
31547c6ae99SBarry Smith @*/
316c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[])
31747c6ae99SBarry Smith {
31847c6ae99SBarry Smith   PetscErrorCode    ierr;
3190298fd71SBarry Smith   Vec               coords = NULL;
32047c6ae99SBarry Smith   PetscInt          dim,i,j;
32147c6ae99SBarry Smith   const PetscScalar *local_coords;
322ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
32347c6ae99SBarry Smith   PetscInt          N,Ni;
32447c6ae99SBarry Smith 
32547c6ae99SBarry Smith   PetscFunctionBegin;
326c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
327c73cfb54SMatthew G. Knepley   dim  = dm->dim;
328c73cfb54SMatthew G. Knepley   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
3297324c66bSJed Brown   if (coords) {
33047c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
33147c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
33247c6ae99SBarry Smith     Ni   = N/dim;
33347c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
3347324c66bSJed Brown       for (j=0; j<3; j++) {
3357324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
3362197688cSJed Brown         max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
33747c6ae99SBarry Smith       }
33847c6ae99SBarry Smith     }
33947c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
3407324c66bSJed Brown   } else {                      /* Just use grid indices */
3417324c66bSJed Brown     DMDALocalInfo info;
342c73cfb54SMatthew G. Knepley     ierr   = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
3437324c66bSJed Brown     min[0] = info.xs;
3447324c66bSJed Brown     min[1] = info.ys;
3457324c66bSJed Brown     min[2] = info.zs;
3467324c66bSJed Brown     max[0] = info.xs + info.xm-1;
3477324c66bSJed Brown     max[1] = info.ys + info.ym-1;
3487324c66bSJed Brown     max[2] = info.zs + info.zm-1;
3497324c66bSJed Brown   }
35047c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
35147c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
35247c6ae99SBarry Smith   PetscFunctionReturn(0);
35347c6ae99SBarry Smith }
35447c6ae99SBarry Smith 
35547c6ae99SBarry Smith /*@
356aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
35747c6ae99SBarry Smith 
358aa219208SBarry Smith    Collective on DMDA
35947c6ae99SBarry Smith 
36047c6ae99SBarry Smith    Input Parameter:
361c73cfb54SMatthew G. Knepley .  dm - the DM
36247c6ae99SBarry Smith 
36347c6ae99SBarry Smith    Output Parameters:
36447c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
36547c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
36647c6ae99SBarry Smith 
36747c6ae99SBarry Smith   Level: beginner
36847c6ae99SBarry Smith 
36947c6ae99SBarry Smith .keywords: distributed array, get, coordinates
37047c6ae99SBarry Smith 
3712150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
37247c6ae99SBarry Smith @*/
373c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetBoundingBox(DM dm,PetscReal gmin[],PetscReal gmax[])
37447c6ae99SBarry Smith {
37547c6ae99SBarry Smith   PetscErrorCode ierr;
37647c6ae99SBarry Smith   PetscMPIInt    count;
37747c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
37847c6ae99SBarry Smith 
37947c6ae99SBarry Smith   PetscFunctionBegin;
380c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
381c73cfb54SMatthew G. Knepley   ierr = PetscMPIIntCast(dm->dim,&count);CHKERRQ(ierr);
382c73cfb54SMatthew G. Knepley   ierr = DMDAGetLocalBoundingBox(dm,lmin,lmax);CHKERRQ(ierr);
383b2566f29SBarry Smith   if (gmin) {ierr = MPIU_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
384b2566f29SBarry Smith   if (gmax) {ierr = MPIU_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
38547c6ae99SBarry Smith   PetscFunctionReturn(0);
38647c6ae99SBarry Smith }
387bc2bf880SBarry Smith 
388bc2bf880SBarry Smith /*@
389*211d3afbSPatrick Sanan    DMDACreateCompatibleDMDA - Creates a DMDA with the same layout but with fewer or more fields
390bc2bf880SBarry Smith 
391bc2bf880SBarry Smith    Collective on DMDA
392bc2bf880SBarry Smith 
393907376e6SBarry Smith    Input Parameters:
394bc2bf880SBarry Smith +  da - the distributed array
395907376e6SBarry Smith -  nfields - number of fields in new DMDA
396bc2bf880SBarry Smith 
397bc2bf880SBarry Smith    Output Parameter:
398bc2bf880SBarry Smith .  nda - the new DMDA
399bc2bf880SBarry Smith 
400bc2bf880SBarry Smith   Level: intermediate
401bc2bf880SBarry Smith 
402bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
403bc2bf880SBarry Smith 
4042150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
405bc2bf880SBarry Smith @*/
406*211d3afbSPatrick Sanan PetscErrorCode  DMDACreateCompatibleDMDA(DM da,PetscInt nfields,DM *nda)
407bc2bf880SBarry Smith {
408bc2bf880SBarry Smith   PetscErrorCode   ierr;
409bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
41095c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
411320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
412bff4a2f0SMatthew G. Knepley   DMBoundaryType   bx,by,bz;
413320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
41495c13181SPeter Brune   PetscInt         ox,oy,oz;
41595c13181SPeter Brune   PetscInt         cl,rl;
416320964c4SBlaise Bourdin 
417320964c4SBlaise Bourdin   PetscFunctionBegin;
418c73cfb54SMatthew G. Knepley   dim = da->dim;
41995c13181SPeter Brune   M   = dd->M;
42095c13181SPeter Brune   N   = dd->N;
42195c13181SPeter Brune   P   = dd->P;
42295c13181SPeter Brune   m   = dd->m;
42395c13181SPeter Brune   n   = dd->n;
42495c13181SPeter Brune   p   = dd->p;
42595c13181SPeter Brune   s   = dd->s;
42695c13181SPeter Brune   bx  = dd->bx;
42795c13181SPeter Brune   by  = dd->by;
42895c13181SPeter Brune   bz  = dd->bz;
4298865f1eaSKarl Rupp 
43095c13181SPeter Brune   stencil_type = dd->stencil_type;
4318865f1eaSKarl Rupp 
432320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
433320964c4SBlaise Bourdin   if (dim == 1) {
434ce94432eSBarry Smith     ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
435320964c4SBlaise Bourdin   } else if (dim == 2) {
436ce94432eSBarry Smith     ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
437320964c4SBlaise Bourdin   } else if (dim == 3) {
438ce94432eSBarry 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);
439bc2bf880SBarry Smith   }
440897f7067SBarry Smith   ierr = DMSetUp(*nda);CHKERRQ(ierr);
4416636e97aSMatthew G Knepley   if (da->coordinates) {
4426636e97aSMatthew G Knepley     ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
4436636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
444bc2bf880SBarry Smith   }
44595c13181SPeter Brune 
44695c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
44795c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
44895c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
44995c13181SPeter Brune 
45095c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
45195c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
45295c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
4538865f1eaSKarl Rupp 
45495c13181SPeter Brune   (*nda)->levelup   = rl;
45595c13181SPeter Brune   (*nda)->leveldown = cl;
456bc2bf880SBarry Smith   PetscFunctionReturn(0);
457bc2bf880SBarry Smith }
458bc2bf880SBarry Smith 
459c593f006SBarry Smith /*@C
460c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
461c593f006SBarry Smith 
462c593f006SBarry Smith    Not Collective
463c593f006SBarry Smith 
464c593f006SBarry Smith    Input Parameter:
465c593f006SBarry Smith .  dm - the DM
466c593f006SBarry Smith 
467c593f006SBarry Smith    Output Parameter:
468c593f006SBarry Smith .  xc - the coordinates
469c593f006SBarry Smith 
470c593f006SBarry Smith   Level: intermediate
471c593f006SBarry Smith 
472f5f57ec0SBarry Smith   Not supported from Fortran
473f5f57ec0SBarry Smith 
474c593f006SBarry Smith .keywords: distributed array, get, component name
475c593f006SBarry Smith 
476c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
477c593f006SBarry Smith @*/
478c593f006SBarry Smith PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
479c593f006SBarry Smith {
480c593f006SBarry Smith   PetscErrorCode ierr;
481c593f006SBarry Smith   DM             cdm;
482c593f006SBarry Smith   Vec            x;
483c593f006SBarry Smith 
484c593f006SBarry Smith   PetscFunctionBegin;
485c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
486c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
487c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
488c593f006SBarry Smith   ierr = DMDAVecGetArray(cdm,x,xc);CHKERRQ(ierr);
489c593f006SBarry Smith   PetscFunctionReturn(0);
490c593f006SBarry Smith }
491c593f006SBarry Smith 
492c593f006SBarry Smith /*@C
493c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
494c593f006SBarry Smith 
495c593f006SBarry Smith    Not Collective
496c593f006SBarry Smith 
497c593f006SBarry Smith    Input Parameter:
498c593f006SBarry Smith +  dm - the DM
499c593f006SBarry Smith -  xc - the coordinates
500c593f006SBarry Smith 
501c593f006SBarry Smith   Level: intermediate
502c593f006SBarry Smith 
503f5f57ec0SBarry Smith   Not supported from Fortran
504f5f57ec0SBarry Smith 
505c593f006SBarry Smith .keywords: distributed array, get, component name
506c593f006SBarry Smith 
507c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
508c593f006SBarry Smith @*/
509c593f006SBarry Smith PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
510c593f006SBarry Smith {
511c593f006SBarry Smith   PetscErrorCode ierr;
512c593f006SBarry Smith   DM             cdm;
513c593f006SBarry Smith   Vec            x;
514c593f006SBarry Smith 
515c593f006SBarry Smith   PetscFunctionBegin;
516c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
517c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
518c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
519c593f006SBarry Smith   ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr);
520c593f006SBarry Smith   PetscFunctionReturn(0);
521c593f006SBarry Smith }
522