xref: /petsc/src/dm/impls/da/dacorn.c (revision b2566f29c2b6470df769aa9f7deb9e2726b0959e)
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
20847c6ae99SBarry Smith    corner 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;
244d886c4f4SPeter Brune   if (x) *x = dd->xs/w + dd->xo; if (m) *m = (dd->xe - dd->xs)/w;
24547c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
246d886c4f4SPeter Brune   if (y) *y = dd->ys + dd->yo; if (n) *n = (dd->ye - dd->ys);
247d886c4f4SPeter Brune   if (z) *z = dd->zs + dd->zo; if (p) *p = (dd->ze - dd->zs);
24847c6ae99SBarry Smith   PetscFunctionReturn(0);
24947c6ae99SBarry Smith }
25047c6ae99SBarry Smith 
25147c6ae99SBarry Smith #undef __FUNCT__
252aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox"
25347c6ae99SBarry Smith /*@
254aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
25547c6ae99SBarry Smith 
25647c6ae99SBarry Smith    Not Collective
25747c6ae99SBarry Smith 
25847c6ae99SBarry Smith    Input Parameter:
259c73cfb54SMatthew G. Knepley .  dm - the DM
26047c6ae99SBarry Smith 
26147c6ae99SBarry Smith    Output Parameters:
26247c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
26347c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
26447c6ae99SBarry Smith 
26547c6ae99SBarry Smith   Level: beginner
26647c6ae99SBarry Smith 
26747c6ae99SBarry Smith .keywords: distributed array, get, coordinates
26847c6ae99SBarry Smith 
2692150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
27047c6ae99SBarry Smith @*/
271c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[])
27247c6ae99SBarry Smith {
27347c6ae99SBarry Smith   PetscErrorCode    ierr;
2740298fd71SBarry Smith   Vec               coords = NULL;
27547c6ae99SBarry Smith   PetscInt          dim,i,j;
27647c6ae99SBarry Smith   const PetscScalar *local_coords;
277ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
27847c6ae99SBarry Smith   PetscInt          N,Ni;
27947c6ae99SBarry Smith 
28047c6ae99SBarry Smith   PetscFunctionBegin;
281c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
282c73cfb54SMatthew G. Knepley   dim  = dm->dim;
283c73cfb54SMatthew G. Knepley   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
2847324c66bSJed Brown   if (coords) {
28547c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
28647c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
28747c6ae99SBarry Smith     Ni   = N/dim;
28847c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
2897324c66bSJed Brown       for (j=0; j<3; j++) {
2907324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
2912197688cSJed Brown         max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
29247c6ae99SBarry Smith       }
29347c6ae99SBarry Smith     }
29447c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
2957324c66bSJed Brown   } else {                      /* Just use grid indices */
2967324c66bSJed Brown     DMDALocalInfo info;
297c73cfb54SMatthew G. Knepley     ierr   = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
2987324c66bSJed Brown     min[0] = info.xs;
2997324c66bSJed Brown     min[1] = info.ys;
3007324c66bSJed Brown     min[2] = info.zs;
3017324c66bSJed Brown     max[0] = info.xs + info.xm-1;
3027324c66bSJed Brown     max[1] = info.ys + info.ym-1;
3037324c66bSJed Brown     max[2] = info.zs + info.zm-1;
3047324c66bSJed Brown   }
30547c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
30647c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
30747c6ae99SBarry Smith   PetscFunctionReturn(0);
30847c6ae99SBarry Smith }
30947c6ae99SBarry Smith 
31047c6ae99SBarry Smith #undef __FUNCT__
311aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox"
31247c6ae99SBarry Smith /*@
313aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
31447c6ae99SBarry Smith 
315aa219208SBarry Smith    Collective on DMDA
31647c6ae99SBarry Smith 
31747c6ae99SBarry Smith    Input Parameter:
318c73cfb54SMatthew G. Knepley .  dm - the DM
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith    Output Parameters:
32147c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
32247c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
32347c6ae99SBarry Smith 
32447c6ae99SBarry Smith   Level: beginner
32547c6ae99SBarry Smith 
32647c6ae99SBarry Smith .keywords: distributed array, get, coordinates
32747c6ae99SBarry Smith 
3282150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
32947c6ae99SBarry Smith @*/
330c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetBoundingBox(DM dm,PetscReal gmin[],PetscReal gmax[])
33147c6ae99SBarry Smith {
33247c6ae99SBarry Smith   PetscErrorCode ierr;
33347c6ae99SBarry Smith   PetscMPIInt    count;
33447c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
33547c6ae99SBarry Smith 
33647c6ae99SBarry Smith   PetscFunctionBegin;
337c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
338c73cfb54SMatthew G. Knepley   ierr = PetscMPIIntCast(dm->dim,&count);CHKERRQ(ierr);
339c73cfb54SMatthew G. Knepley   ierr = DMDAGetLocalBoundingBox(dm,lmin,lmax);CHKERRQ(ierr);
340*b2566f29SBarry Smith   if (gmin) {ierr = MPIU_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
341*b2566f29SBarry Smith   if (gmax) {ierr = MPIU_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));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 
352907376e6SBarry Smith    Input Parameters:
353bc2bf880SBarry Smith +  da - the distributed array
354907376e6SBarry 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;
36995c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
370320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
371bff4a2f0SMatthew G. Knepley   DMBoundaryType   bx,by,bz;
372320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
37395c13181SPeter Brune   PetscInt         ox,oy,oz;
37495c13181SPeter Brune   PetscInt         cl,rl;
375320964c4SBlaise Bourdin 
376320964c4SBlaise Bourdin   PetscFunctionBegin;
377c73cfb54SMatthew G. Knepley   dim = da->dim;
37895c13181SPeter Brune   M   = dd->M;
37995c13181SPeter Brune   N   = dd->N;
38095c13181SPeter Brune   P   = dd->P;
38195c13181SPeter Brune   m   = dd->m;
38295c13181SPeter Brune   n   = dd->n;
38395c13181SPeter Brune   p   = dd->p;
38495c13181SPeter Brune   s   = dd->s;
38595c13181SPeter Brune   bx  = dd->bx;
38695c13181SPeter Brune   by  = dd->by;
38795c13181SPeter Brune   bz  = dd->bz;
3888865f1eaSKarl Rupp 
38995c13181SPeter Brune   stencil_type = dd->stencil_type;
3908865f1eaSKarl Rupp 
391320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
392320964c4SBlaise Bourdin   if (dim == 1) {
393ce94432eSBarry Smith     ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
394320964c4SBlaise Bourdin   } else if (dim == 2) {
395ce94432eSBarry Smith     ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
396320964c4SBlaise Bourdin   } else if (dim == 3) {
397ce94432eSBarry 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);
398bc2bf880SBarry Smith   }
3996636e97aSMatthew G Knepley   if (da->coordinates) {
4006636e97aSMatthew G Knepley     ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
4018865f1eaSKarl Rupp 
4026636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
403bc2bf880SBarry Smith   }
40495c13181SPeter Brune 
40595c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
40695c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
40795c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
40895c13181SPeter Brune 
40995c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
41095c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
41195c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
4128865f1eaSKarl Rupp 
41395c13181SPeter Brune   (*nda)->levelup   = rl;
41495c13181SPeter Brune   (*nda)->leveldown = cl;
415bc2bf880SBarry Smith   PetscFunctionReturn(0);
416bc2bf880SBarry Smith }
417bc2bf880SBarry Smith 
418c593f006SBarry Smith #undef __FUNCT__
419c593f006SBarry Smith #define __FUNCT__ "DMDAGetCoordinateArray"
420c593f006SBarry Smith /*@C
421c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
422c593f006SBarry Smith 
423c593f006SBarry Smith    Not Collective
424c593f006SBarry Smith 
425c593f006SBarry Smith    Input Parameter:
426c593f006SBarry Smith .  dm - the DM
427c593f006SBarry Smith 
428c593f006SBarry Smith    Output Parameter:
429c593f006SBarry Smith .  xc - the coordinates
430c593f006SBarry Smith 
431c593f006SBarry Smith   Level: intermediate
432c593f006SBarry Smith 
433c593f006SBarry Smith .keywords: distributed array, get, component name
434c593f006SBarry Smith 
435c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
436c593f006SBarry Smith @*/
437c593f006SBarry Smith PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
438c593f006SBarry Smith {
439c593f006SBarry Smith   PetscErrorCode ierr;
440c593f006SBarry Smith   DM             cdm;
441c593f006SBarry Smith   Vec            x;
442c593f006SBarry Smith 
443c593f006SBarry Smith   PetscFunctionBegin;
444c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
445c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
446c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
447c593f006SBarry Smith   ierr = DMDAVecGetArray(cdm,x,xc);CHKERRQ(ierr);
448c593f006SBarry Smith   PetscFunctionReturn(0);
449c593f006SBarry Smith }
450c593f006SBarry Smith 
451c593f006SBarry Smith #undef __FUNCT__
452c593f006SBarry Smith #define __FUNCT__ "DMDARestoreCoordinateArray"
453c593f006SBarry Smith /*@C
454c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
455c593f006SBarry Smith 
456c593f006SBarry Smith    Not Collective
457c593f006SBarry Smith 
458c593f006SBarry Smith    Input Parameter:
459c593f006SBarry Smith +  dm - the DM
460c593f006SBarry Smith -  xc - the coordinates
461c593f006SBarry Smith 
462c593f006SBarry Smith   Level: intermediate
463c593f006SBarry Smith 
464c593f006SBarry Smith .keywords: distributed array, get, component name
465c593f006SBarry Smith 
466c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
467c593f006SBarry Smith @*/
468c593f006SBarry Smith PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
469c593f006SBarry Smith {
470c593f006SBarry Smith   PetscErrorCode ierr;
471c593f006SBarry Smith   DM             cdm;
472c593f006SBarry Smith   Vec            x;
473c593f006SBarry Smith 
474c593f006SBarry Smith   PetscFunctionBegin;
475c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
476c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
477c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
478c593f006SBarry Smith   ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr);
479c593f006SBarry Smith   PetscFunctionReturn(0);
480c593f006SBarry Smith }
481