xref: /petsc/src/dm/impls/da/dacorn.c (revision 59bc5b247cf7f730c8613f20507b11845af040ae)
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*/
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 {
1247c6ae99SBarry Smith   PetscErrorCode ierr;
133f2d3b52SPeter Brune   PetscFunctionBegin;
14c73cfb54SMatthew G. Knepley   ierr = DMDAGetReducedDMDA(dm,dm->dim,cdm);CHKERRQ(ierr);
1547c6ae99SBarry Smith   PetscFunctionReturn(0);
1647c6ae99SBarry Smith }
1747c6ae99SBarry Smith 
1847c6ae99SBarry Smith #undef __FUNCT__
19aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName"
2047c6ae99SBarry Smith /*@C
21aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
22aa219208SBarry Smith    vectors associated with a DMDA.
2347c6ae99SBarry Smith 
2447c6ae99SBarry Smith    Not Collective
2547c6ae99SBarry Smith 
2647c6ae99SBarry Smith    Input Parameters:
2747c6ae99SBarry Smith +  da - the distributed array
28aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
29aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
3047c6ae99SBarry Smith -  names - the name of the field (component)
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith   Level: intermediate
3347c6ae99SBarry Smith 
3447c6ae99SBarry Smith .keywords: distributed array, get, component name
3547c6ae99SBarry Smith 
36c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldNames()
3747c6ae99SBarry Smith @*/
387087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
3947c6ae99SBarry Smith {
4047c6ae99SBarry Smith   PetscErrorCode ierr;
4147c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
4247c6ae99SBarry Smith 
4347c6ae99SBarry Smith   PetscFunctionBegin;
4447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
4547c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
46c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
4747c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
4847c6ae99SBarry Smith   PetscFunctionReturn(0);
4947c6ae99SBarry Smith }
5047c6ae99SBarry Smith 
5147c6ae99SBarry Smith #undef __FUNCT__
52c629b14aSBarry Smith #define __FUNCT__ "DMDAGetFieldNames"
53c629b14aSBarry Smith /*@C
54c629b14aSBarry Smith    DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
55c629b14aSBarry Smith 
56c629b14aSBarry Smith    Collective on TS
57c629b14aSBarry Smith 
58c629b14aSBarry Smith    Input Parameter:
59c629b14aSBarry Smith .  dm - the DMDA object
60c629b14aSBarry Smith 
61c629b14aSBarry Smith    Output Parameter:
62c629b14aSBarry 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
63c629b14aSBarry Smith 
64c629b14aSBarry Smith    Level: intermediate
65c629b14aSBarry Smith 
66c629b14aSBarry Smith .keywords: distributed array, get, component name
67c629b14aSBarry Smith 
68c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
69c629b14aSBarry Smith @*/
70c629b14aSBarry Smith PetscErrorCode  DMDAGetFieldNames(DM da,const char * const **names)
71c629b14aSBarry Smith {
72c629b14aSBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
73c629b14aSBarry Smith 
74c629b14aSBarry Smith   PetscFunctionBegin;
75c629b14aSBarry Smith   *names = (const char * const *) dd->fieldname;
76c629b14aSBarry Smith   PetscFunctionReturn(0);
77c629b14aSBarry Smith }
78c629b14aSBarry Smith 
79c629b14aSBarry Smith #undef __FUNCT__
80c629b14aSBarry Smith #define __FUNCT__ "DMDASetFieldNames"
81c629b14aSBarry Smith /*@C
82c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
83c629b14aSBarry Smith 
84c629b14aSBarry Smith    Collective on TS
85c629b14aSBarry Smith 
86c629b14aSBarry Smith    Input Parameters:
87c629b14aSBarry Smith +  dm - the DMDA object
88c629b14aSBarry 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
89c629b14aSBarry Smith 
90c629b14aSBarry Smith    Level: intermediate
91c629b14aSBarry Smith 
92c629b14aSBarry Smith .keywords: distributed array, get, component name
93c629b14aSBarry Smith 
94c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName()
95c629b14aSBarry Smith @*/
96c629b14aSBarry Smith PetscErrorCode  DMDASetFieldNames(DM da,const char * const *names)
97c629b14aSBarry Smith {
98c629b14aSBarry Smith   PetscErrorCode    ierr;
99c629b14aSBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
100c629b14aSBarry Smith 
101c629b14aSBarry Smith   PetscFunctionBegin;
102c629b14aSBarry Smith   ierr = PetscStrArrayDestroy(&dd->fieldname);CHKERRQ(ierr);
103c629b14aSBarry Smith   ierr = PetscStrArrayallocpy(names,&dd->fieldname);CHKERRQ(ierr);
104c629b14aSBarry Smith   PetscFunctionReturn(0);
105c629b14aSBarry Smith }
106c629b14aSBarry Smith 
107c629b14aSBarry Smith #undef __FUNCT__
108aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName"
10947c6ae99SBarry Smith /*@C
110aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
111aa219208SBarry Smith    vectors associated with a DMDA.
11247c6ae99SBarry Smith 
11347c6ae99SBarry Smith    Not Collective
11447c6ae99SBarry Smith 
11547c6ae99SBarry Smith    Input Parameter:
11647c6ae99SBarry Smith +  da - the distributed array
117aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
118aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith    Output Parameter:
12147c6ae99SBarry Smith .  names - the name of the field (component)
12247c6ae99SBarry Smith 
12347c6ae99SBarry Smith   Level: intermediate
12447c6ae99SBarry Smith 
12547c6ae99SBarry Smith .keywords: distributed array, get, component name
12647c6ae99SBarry Smith 
127109c9344SBarry Smith .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName()
12847c6ae99SBarry Smith @*/
1297087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
13047c6ae99SBarry Smith {
13147c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
13247c6ae99SBarry Smith 
13347c6ae99SBarry Smith   PetscFunctionBegin;
13447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
13547c6ae99SBarry Smith   PetscValidPointer(name,3);
13647c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
13747c6ae99SBarry Smith   *name = dd->fieldname[nf];
13847c6ae99SBarry Smith   PetscFunctionReturn(0);
13947c6ae99SBarry Smith }
14047c6ae99SBarry Smith 
14147c6ae99SBarry Smith #undef __FUNCT__
142109c9344SBarry Smith #define __FUNCT__ "DMDASetCoordinateName"
143109c9344SBarry Smith /*@C
144109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
145109c9344SBarry Smith 
146109c9344SBarry Smith    Not Collective
147109c9344SBarry Smith 
148109c9344SBarry Smith    Input Parameters:
149c73cfb54SMatthew G. Knepley +  dm - the DM
150109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
151109c9344SBarry Smith -  name - the name of the coordinate
152109c9344SBarry Smith 
153109c9344SBarry Smith   Level: intermediate
154109c9344SBarry Smith 
155109c9344SBarry Smith .keywords: distributed array, get, component name
156109c9344SBarry Smith 
157109c9344SBarry Smith .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName()
158109c9344SBarry Smith @*/
159c73cfb54SMatthew G. Knepley PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
160109c9344SBarry Smith {
161109c9344SBarry Smith   PetscErrorCode ierr;
162c73cfb54SMatthew G. Knepley   DM_DA          *dd = (DM_DA*)dm->data;
163109c9344SBarry Smith 
164109c9344SBarry Smith   PetscFunctionBegin;
165c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
166c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
167109c9344SBarry Smith   ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr);
168109c9344SBarry Smith   ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr);
169109c9344SBarry Smith   PetscFunctionReturn(0);
170109c9344SBarry Smith }
171109c9344SBarry Smith 
172109c9344SBarry Smith #undef __FUNCT__
173109c9344SBarry Smith #define __FUNCT__ "DMDAGetCoordinateName"
174109c9344SBarry Smith /*@C
175109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
176109c9344SBarry Smith 
177109c9344SBarry Smith    Not Collective
178109c9344SBarry Smith 
179109c9344SBarry Smith    Input Parameter:
180c73cfb54SMatthew G. Knepley +  dm - the DM
181109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
182109c9344SBarry Smith 
183109c9344SBarry Smith    Output Parameter:
184109c9344SBarry Smith .  names - the name of the coordinate direction
185109c9344SBarry Smith 
186109c9344SBarry Smith   Level: intermediate
187109c9344SBarry Smith 
188109c9344SBarry Smith .keywords: distributed array, get, component name
189109c9344SBarry Smith 
190109c9344SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName()
191109c9344SBarry Smith @*/
192c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
193109c9344SBarry Smith {
194c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA*)dm->data;
195109c9344SBarry Smith 
196109c9344SBarry Smith   PetscFunctionBegin;
197c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
198109c9344SBarry Smith   PetscValidPointer(name,3);
199c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
200109c9344SBarry Smith   *name = dd->coordinatename[nf];
201109c9344SBarry Smith   PetscFunctionReturn(0);
202109c9344SBarry Smith }
203109c9344SBarry Smith 
204109c9344SBarry Smith #undef __FUNCT__
205aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners"
20647c6ae99SBarry Smith /*@
207aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
20859f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
20947c6ae99SBarry Smith 
21047c6ae99SBarry Smith    Not Collective
21147c6ae99SBarry Smith 
21247c6ae99SBarry Smith    Input Parameter:
21347c6ae99SBarry Smith .  da - the distributed array
21447c6ae99SBarry Smith 
21547c6ae99SBarry Smith    Output Parameters:
21647c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
21747c6ae99SBarry Smith            for 2D and 3D problems)
21847c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
21947c6ae99SBarry Smith            these are used for 2D and 3D problems)
22047c6ae99SBarry Smith 
22147c6ae99SBarry Smith    Note:
22247c6ae99SBarry Smith    The corner information is independent of the number of degrees of
223aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
22447c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
22547c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2260298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
22747c6ae99SBarry Smith 
22847c6ae99SBarry Smith   Level: beginner
22947c6ae99SBarry Smith 
23047c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
23147c6ae99SBarry Smith 
232aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
23347c6ae99SBarry Smith @*/
2347087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
23547c6ae99SBarry Smith {
23647c6ae99SBarry Smith   PetscInt w;
23747c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
23847c6ae99SBarry Smith 
23947c6ae99SBarry Smith   PetscFunctionBegin;
24047c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
24147c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
24247c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
24347c6ae99SBarry Smith   w = dd->w;
244*59bc5b24SSatish Balay   if (x) *x = dd->xs/w + dd->xo;
24547c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
246*59bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
247*59bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
248*59bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs)/w;
249*59bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
250*59bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
25147c6ae99SBarry Smith   PetscFunctionReturn(0);
25247c6ae99SBarry Smith }
25347c6ae99SBarry Smith 
25447c6ae99SBarry Smith #undef __FUNCT__
255aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox"
25647c6ae99SBarry Smith /*@
257aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
25847c6ae99SBarry Smith 
25947c6ae99SBarry Smith    Not Collective
26047c6ae99SBarry Smith 
26147c6ae99SBarry Smith    Input Parameter:
262c73cfb54SMatthew G. Knepley .  dm - the DM
26347c6ae99SBarry Smith 
26447c6ae99SBarry Smith    Output Parameters:
26547c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
26647c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
26747c6ae99SBarry Smith 
26847c6ae99SBarry Smith   Level: beginner
26947c6ae99SBarry Smith 
27047c6ae99SBarry Smith .keywords: distributed array, get, coordinates
27147c6ae99SBarry Smith 
2722150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
27347c6ae99SBarry Smith @*/
274c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[])
27547c6ae99SBarry Smith {
27647c6ae99SBarry Smith   PetscErrorCode    ierr;
2770298fd71SBarry Smith   Vec               coords = NULL;
27847c6ae99SBarry Smith   PetscInt          dim,i,j;
27947c6ae99SBarry Smith   const PetscScalar *local_coords;
280ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
28147c6ae99SBarry Smith   PetscInt          N,Ni;
28247c6ae99SBarry Smith 
28347c6ae99SBarry Smith   PetscFunctionBegin;
284c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
285c73cfb54SMatthew G. Knepley   dim  = dm->dim;
286c73cfb54SMatthew G. Knepley   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
2877324c66bSJed Brown   if (coords) {
28847c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
28947c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
29047c6ae99SBarry Smith     Ni   = N/dim;
29147c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
2927324c66bSJed Brown       for (j=0; j<3; j++) {
2937324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
2942197688cSJed Brown         max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
29547c6ae99SBarry Smith       }
29647c6ae99SBarry Smith     }
29747c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
2987324c66bSJed Brown   } else {                      /* Just use grid indices */
2997324c66bSJed Brown     DMDALocalInfo info;
300c73cfb54SMatthew G. Knepley     ierr   = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
3017324c66bSJed Brown     min[0] = info.xs;
3027324c66bSJed Brown     min[1] = info.ys;
3037324c66bSJed Brown     min[2] = info.zs;
3047324c66bSJed Brown     max[0] = info.xs + info.xm-1;
3057324c66bSJed Brown     max[1] = info.ys + info.ym-1;
3067324c66bSJed Brown     max[2] = info.zs + info.zm-1;
3077324c66bSJed Brown   }
30847c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
30947c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
31047c6ae99SBarry Smith   PetscFunctionReturn(0);
31147c6ae99SBarry Smith }
31247c6ae99SBarry Smith 
31347c6ae99SBarry Smith #undef __FUNCT__
314aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox"
31547c6ae99SBarry Smith /*@
316aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
31747c6ae99SBarry Smith 
318aa219208SBarry Smith    Collective on DMDA
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith    Input Parameter:
321c73cfb54SMatthew G. Knepley .  dm - the DM
32247c6ae99SBarry Smith 
32347c6ae99SBarry Smith    Output Parameters:
32447c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
32547c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
32647c6ae99SBarry Smith 
32747c6ae99SBarry Smith   Level: beginner
32847c6ae99SBarry Smith 
32947c6ae99SBarry Smith .keywords: distributed array, get, coordinates
33047c6ae99SBarry Smith 
3312150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
33247c6ae99SBarry Smith @*/
333c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetBoundingBox(DM dm,PetscReal gmin[],PetscReal gmax[])
33447c6ae99SBarry Smith {
33547c6ae99SBarry Smith   PetscErrorCode ierr;
33647c6ae99SBarry Smith   PetscMPIInt    count;
33747c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
33847c6ae99SBarry Smith 
33947c6ae99SBarry Smith   PetscFunctionBegin;
340c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
341c73cfb54SMatthew G. Knepley   ierr = PetscMPIIntCast(dm->dim,&count);CHKERRQ(ierr);
342c73cfb54SMatthew G. Knepley   ierr = DMDAGetLocalBoundingBox(dm,lmin,lmax);CHKERRQ(ierr);
343b2566f29SBarry Smith   if (gmin) {ierr = MPIU_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
344b2566f29SBarry Smith   if (gmax) {ierr = MPIU_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
34547c6ae99SBarry Smith   PetscFunctionReturn(0);
34647c6ae99SBarry Smith }
347bc2bf880SBarry Smith 
348bc2bf880SBarry Smith #undef __FUNCT__
349db05f41bSBarry Smith #define __FUNCT__ "DMDAGetReducedDMDA"
350bc2bf880SBarry Smith /*@
351db05f41bSBarry Smith    DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields
352bc2bf880SBarry Smith 
353bc2bf880SBarry Smith    Collective on DMDA
354bc2bf880SBarry Smith 
355907376e6SBarry Smith    Input Parameters:
356bc2bf880SBarry Smith +  da - the distributed array
357907376e6SBarry Smith -  nfields - number of fields in new DMDA
358bc2bf880SBarry Smith 
359bc2bf880SBarry Smith    Output Parameter:
360bc2bf880SBarry Smith .  nda - the new DMDA
361bc2bf880SBarry Smith 
362bc2bf880SBarry Smith   Level: intermediate
363bc2bf880SBarry Smith 
364bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
365bc2bf880SBarry Smith 
3662150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
367bc2bf880SBarry Smith @*/
368db05f41bSBarry Smith PetscErrorCode  DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
369bc2bf880SBarry Smith {
370bc2bf880SBarry Smith   PetscErrorCode   ierr;
371bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
37295c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
373320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
374bff4a2f0SMatthew G. Knepley   DMBoundaryType   bx,by,bz;
375320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
37695c13181SPeter Brune   PetscInt         ox,oy,oz;
37795c13181SPeter Brune   PetscInt         cl,rl;
378320964c4SBlaise Bourdin 
379320964c4SBlaise Bourdin   PetscFunctionBegin;
380c73cfb54SMatthew G. Knepley   dim = da->dim;
38195c13181SPeter Brune   M   = dd->M;
38295c13181SPeter Brune   N   = dd->N;
38395c13181SPeter Brune   P   = dd->P;
38495c13181SPeter Brune   m   = dd->m;
38595c13181SPeter Brune   n   = dd->n;
38695c13181SPeter Brune   p   = dd->p;
38795c13181SPeter Brune   s   = dd->s;
38895c13181SPeter Brune   bx  = dd->bx;
38995c13181SPeter Brune   by  = dd->by;
39095c13181SPeter Brune   bz  = dd->bz;
3918865f1eaSKarl Rupp 
39295c13181SPeter Brune   stencil_type = dd->stencil_type;
3938865f1eaSKarl Rupp 
394320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
395320964c4SBlaise Bourdin   if (dim == 1) {
396ce94432eSBarry Smith     ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
397320964c4SBlaise Bourdin   } else if (dim == 2) {
398ce94432eSBarry Smith     ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
399320964c4SBlaise Bourdin   } else if (dim == 3) {
400ce94432eSBarry 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);
401bc2bf880SBarry Smith   }
4026636e97aSMatthew G Knepley   if (da->coordinates) {
4036636e97aSMatthew G Knepley     ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
4048865f1eaSKarl Rupp 
4056636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
406bc2bf880SBarry Smith   }
40795c13181SPeter Brune 
40895c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
40995c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
41095c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
41195c13181SPeter Brune 
41295c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
41395c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
41495c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
4158865f1eaSKarl Rupp 
41695c13181SPeter Brune   (*nda)->levelup   = rl;
41795c13181SPeter Brune   (*nda)->leveldown = cl;
418bc2bf880SBarry Smith   PetscFunctionReturn(0);
419bc2bf880SBarry Smith }
420bc2bf880SBarry Smith 
421c593f006SBarry Smith #undef __FUNCT__
422c593f006SBarry Smith #define __FUNCT__ "DMDAGetCoordinateArray"
423c593f006SBarry Smith /*@C
424c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
425c593f006SBarry Smith 
426c593f006SBarry Smith    Not Collective
427c593f006SBarry Smith 
428c593f006SBarry Smith    Input Parameter:
429c593f006SBarry Smith .  dm - the DM
430c593f006SBarry Smith 
431c593f006SBarry Smith    Output Parameter:
432c593f006SBarry Smith .  xc - the coordinates
433c593f006SBarry Smith 
434c593f006SBarry Smith   Level: intermediate
435c593f006SBarry Smith 
436c593f006SBarry Smith .keywords: distributed array, get, component name
437c593f006SBarry Smith 
438c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
439c593f006SBarry Smith @*/
440c593f006SBarry Smith PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
441c593f006SBarry Smith {
442c593f006SBarry Smith   PetscErrorCode ierr;
443c593f006SBarry Smith   DM             cdm;
444c593f006SBarry Smith   Vec            x;
445c593f006SBarry Smith 
446c593f006SBarry Smith   PetscFunctionBegin;
447c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
448c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
449c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
450c593f006SBarry Smith   ierr = DMDAVecGetArray(cdm,x,xc);CHKERRQ(ierr);
451c593f006SBarry Smith   PetscFunctionReturn(0);
452c593f006SBarry Smith }
453c593f006SBarry Smith 
454c593f006SBarry Smith #undef __FUNCT__
455c593f006SBarry Smith #define __FUNCT__ "DMDARestoreCoordinateArray"
456c593f006SBarry Smith /*@C
457c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
458c593f006SBarry Smith 
459c593f006SBarry Smith    Not Collective
460c593f006SBarry Smith 
461c593f006SBarry Smith    Input Parameter:
462c593f006SBarry Smith +  dm - the DM
463c593f006SBarry Smith -  xc - the coordinates
464c593f006SBarry Smith 
465c593f006SBarry Smith   Level: intermediate
466c593f006SBarry Smith 
467c593f006SBarry Smith .keywords: distributed array, get, component name
468c593f006SBarry Smith 
469c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
470c593f006SBarry Smith @*/
471c593f006SBarry Smith PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
472c593f006SBarry Smith {
473c593f006SBarry Smith   PetscErrorCode ierr;
474c593f006SBarry Smith   DM             cdm;
475c593f006SBarry Smith   Vec            x;
476c593f006SBarry Smith 
477c593f006SBarry Smith   PetscFunctionBegin;
478c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
479c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
480c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
481c593f006SBarry Smith   ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr);
482c593f006SBarry Smith   PetscFunctionReturn(0);
483c593f006SBarry Smith }
484