xref: /petsc/src/dm/impls/da/dacorn.c (revision 3eac1cee0d27a139bed83106d7747835ff0fe228)
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 
86636e97aSMatthew G Knepley PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
947c6ae99SBarry Smith {
1047c6ae99SBarry Smith   PetscErrorCode ierr;
113f2d3b52SPeter Brune   PetscFunctionBegin;
12c73cfb54SMatthew G. Knepley   ierr = DMDAGetReducedDMDA(dm,dm->dim,cdm);CHKERRQ(ierr);
1347c6ae99SBarry Smith   PetscFunctionReturn(0);
1447c6ae99SBarry Smith }
1547c6ae99SBarry Smith 
1647c6ae99SBarry Smith /*@C
17aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
18aa219208SBarry Smith    vectors associated with a DMDA.
1947c6ae99SBarry Smith 
2047c6ae99SBarry Smith    Not Collective
2147c6ae99SBarry Smith 
2247c6ae99SBarry Smith    Input Parameters:
2347c6ae99SBarry Smith +  da - the distributed array
24aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
25aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
2647c6ae99SBarry Smith -  names - the name of the field (component)
2747c6ae99SBarry Smith 
28*3eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
29*3eac1ceeSStefano Zampini 
3047c6ae99SBarry Smith   Level: intermediate
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith .keywords: distributed array, get, component name
3347c6ae99SBarry Smith 
34*3eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldNames(), DMSetUp()
3547c6ae99SBarry Smith @*/
367087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
3747c6ae99SBarry Smith {
3847c6ae99SBarry Smith   PetscErrorCode ierr;
3947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
4047c6ae99SBarry Smith 
4147c6ae99SBarry Smith   PetscFunctionBegin;
4247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
4347c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
44*3eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
45c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
4647c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
4747c6ae99SBarry Smith   PetscFunctionReturn(0);
4847c6ae99SBarry Smith }
4947c6ae99SBarry Smith 
50c629b14aSBarry Smith /*@C
51c629b14aSBarry Smith    DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
52c629b14aSBarry Smith 
53c629b14aSBarry Smith    Collective on TS
54c629b14aSBarry Smith 
55c629b14aSBarry Smith    Input Parameter:
56c629b14aSBarry Smith .  dm - the DMDA object
57c629b14aSBarry Smith 
58c629b14aSBarry Smith    Output Parameter:
59c629b14aSBarry 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
60c629b14aSBarry Smith 
61c629b14aSBarry Smith    Level: intermediate
62c629b14aSBarry Smith 
63c629b14aSBarry Smith .keywords: distributed array, get, component name
64c629b14aSBarry Smith 
65c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
66c629b14aSBarry Smith @*/
67c629b14aSBarry Smith PetscErrorCode  DMDAGetFieldNames(DM da,const char * const **names)
68c629b14aSBarry Smith {
69c629b14aSBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
70c629b14aSBarry Smith 
71c629b14aSBarry Smith   PetscFunctionBegin;
72c629b14aSBarry Smith   *names = (const char * const *) dd->fieldname;
73c629b14aSBarry Smith   PetscFunctionReturn(0);
74c629b14aSBarry Smith }
75c629b14aSBarry Smith 
76c629b14aSBarry Smith /*@C
77c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
78c629b14aSBarry Smith 
79c629b14aSBarry Smith    Collective on TS
80c629b14aSBarry Smith 
81c629b14aSBarry Smith    Input Parameters:
82c629b14aSBarry Smith +  dm - the DMDA object
83c629b14aSBarry 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
84c629b14aSBarry Smith 
85*3eac1ceeSStefano Zampini    Notes: It must be called after having called DMSetUp().
86*3eac1ceeSStefano Zampini 
87c629b14aSBarry Smith    Level: intermediate
88c629b14aSBarry Smith 
89c629b14aSBarry Smith .keywords: distributed array, get, component name
90c629b14aSBarry Smith 
91*3eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMSetUp()
92c629b14aSBarry Smith @*/
93c629b14aSBarry Smith PetscErrorCode  DMDASetFieldNames(DM da,const char * const *names)
94c629b14aSBarry Smith {
95c629b14aSBarry Smith   PetscErrorCode ierr;
96c629b14aSBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
97*3eac1ceeSStefano Zampini   char           **fieldname;
98*3eac1ceeSStefano Zampini   PetscInt       nf = 0;
99c629b14aSBarry Smith 
100c629b14aSBarry Smith   PetscFunctionBegin;
101*3eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
102*3eac1ceeSStefano Zampini   while (names[nf++]) {};
103*3eac1ceeSStefano Zampini   if (nf != dd->w+1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid number of fields %D",nf-1);
104*3eac1ceeSStefano Zampini   ierr = PetscStrArrayallocpy(names,&fieldname);CHKERRQ(ierr);
105c629b14aSBarry Smith   ierr = PetscStrArrayDestroy(&dd->fieldname);CHKERRQ(ierr);
106*3eac1ceeSStefano Zampini   dd->fieldname = fieldname;
107c629b14aSBarry Smith   PetscFunctionReturn(0);
108c629b14aSBarry Smith }
109c629b14aSBarry Smith 
11047c6ae99SBarry Smith /*@C
111aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
112aa219208SBarry Smith    vectors associated with a DMDA.
11347c6ae99SBarry Smith 
11447c6ae99SBarry Smith    Not Collective
11547c6ae99SBarry Smith 
11647c6ae99SBarry Smith    Input Parameter:
11747c6ae99SBarry Smith +  da - the distributed array
118aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
119aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
12047c6ae99SBarry Smith 
12147c6ae99SBarry Smith    Output Parameter:
12247c6ae99SBarry Smith .  names - the name of the field (component)
12347c6ae99SBarry Smith 
124*3eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
125*3eac1ceeSStefano Zampini 
12647c6ae99SBarry Smith   Level: intermediate
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith .keywords: distributed array, get, component name
12947c6ae99SBarry Smith 
130*3eac1ceeSStefano Zampini .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMSetUp()
13147c6ae99SBarry Smith @*/
1327087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
13347c6ae99SBarry Smith {
13447c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
13547c6ae99SBarry Smith 
13647c6ae99SBarry Smith   PetscFunctionBegin;
13747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
13847c6ae99SBarry Smith   PetscValidPointer(name,3);
13947c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
140*3eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
14147c6ae99SBarry Smith   *name = dd->fieldname[nf];
14247c6ae99SBarry Smith   PetscFunctionReturn(0);
14347c6ae99SBarry Smith }
14447c6ae99SBarry Smith 
145109c9344SBarry Smith /*@C
146109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
147109c9344SBarry Smith 
148109c9344SBarry Smith    Not Collective
149109c9344SBarry Smith 
150109c9344SBarry Smith    Input Parameters:
151c73cfb54SMatthew G. Knepley +  dm - the DM
152109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
153109c9344SBarry Smith -  name - the name of the coordinate
154109c9344SBarry Smith 
155*3eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
156*3eac1ceeSStefano Zampini 
157109c9344SBarry Smith   Level: intermediate
158109c9344SBarry Smith 
159109c9344SBarry Smith .keywords: distributed array, get, component name
160109c9344SBarry Smith 
161*3eac1ceeSStefano Zampini .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
162109c9344SBarry Smith @*/
163c73cfb54SMatthew G. Knepley PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
164109c9344SBarry Smith {
165109c9344SBarry Smith   PetscErrorCode ierr;
166c73cfb54SMatthew G. Knepley   DM_DA          *dd = (DM_DA*)dm->data;
167109c9344SBarry Smith 
168109c9344SBarry Smith   PetscFunctionBegin;
169c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
170c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
171*3eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
172109c9344SBarry Smith   ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr);
173109c9344SBarry Smith   ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr);
174109c9344SBarry Smith   PetscFunctionReturn(0);
175109c9344SBarry Smith }
176109c9344SBarry Smith 
177109c9344SBarry Smith /*@C
178109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
179109c9344SBarry Smith 
180109c9344SBarry Smith    Not Collective
181109c9344SBarry Smith 
182109c9344SBarry Smith    Input Parameter:
183c73cfb54SMatthew G. Knepley +  dm - the DM
184109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
185109c9344SBarry Smith 
186109c9344SBarry Smith    Output Parameter:
187109c9344SBarry Smith .  names - the name of the coordinate direction
188109c9344SBarry Smith 
189*3eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
190*3eac1ceeSStefano Zampini 
191109c9344SBarry Smith   Level: intermediate
192109c9344SBarry Smith 
193109c9344SBarry Smith .keywords: distributed array, get, component name
194109c9344SBarry Smith 
195*3eac1ceeSStefano Zampini .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
196109c9344SBarry Smith @*/
197c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
198109c9344SBarry Smith {
199c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA*)dm->data;
200109c9344SBarry Smith 
201109c9344SBarry Smith   PetscFunctionBegin;
202c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
203109c9344SBarry Smith   PetscValidPointer(name,3);
204c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
205*3eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
206109c9344SBarry Smith   *name = dd->coordinatename[nf];
207109c9344SBarry Smith   PetscFunctionReturn(0);
208109c9344SBarry Smith }
209109c9344SBarry Smith 
210a5d1443cSVincent Le Chenadec /*@C
211aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
21259f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
21347c6ae99SBarry Smith 
21447c6ae99SBarry Smith    Not Collective
21547c6ae99SBarry Smith 
21647c6ae99SBarry Smith    Input Parameter:
21747c6ae99SBarry Smith .  da - the distributed array
21847c6ae99SBarry Smith 
21947c6ae99SBarry Smith    Output Parameters:
22047c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
22147c6ae99SBarry Smith            for 2D and 3D problems)
22247c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
22347c6ae99SBarry Smith            these are used for 2D and 3D problems)
22447c6ae99SBarry Smith 
22547c6ae99SBarry Smith    Note:
22647c6ae99SBarry Smith    The corner information is independent of the number of degrees of
227aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
22847c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
22947c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2300298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
23147c6ae99SBarry Smith 
23247c6ae99SBarry Smith   Level: beginner
23347c6ae99SBarry Smith 
23447c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
23547c6ae99SBarry Smith 
236aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
23747c6ae99SBarry Smith @*/
2387087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
23947c6ae99SBarry Smith {
24047c6ae99SBarry Smith   PetscInt w;
24147c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
24247c6ae99SBarry Smith 
24347c6ae99SBarry Smith   PetscFunctionBegin;
24447c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
24547c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
24647c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
24747c6ae99SBarry Smith   w = dd->w;
24859bc5b24SSatish Balay   if (x) *x = dd->xs/w + dd->xo;
24947c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
25059bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
25159bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
25259bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs)/w;
25359bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
25459bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
25547c6ae99SBarry Smith   PetscFunctionReturn(0);
25647c6ae99SBarry Smith }
25747c6ae99SBarry Smith 
25847c6ae99SBarry Smith /*@
259aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
26047c6ae99SBarry Smith 
26147c6ae99SBarry Smith    Not Collective
26247c6ae99SBarry Smith 
26347c6ae99SBarry Smith    Input Parameter:
264c73cfb54SMatthew G. Knepley .  dm - the DM
26547c6ae99SBarry Smith 
26647c6ae99SBarry Smith    Output Parameters:
26747c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
26847c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
26947c6ae99SBarry Smith 
27047c6ae99SBarry Smith   Level: beginner
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith .keywords: distributed array, get, coordinates
27347c6ae99SBarry Smith 
2742150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
27547c6ae99SBarry Smith @*/
276c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[])
27747c6ae99SBarry Smith {
27847c6ae99SBarry Smith   PetscErrorCode    ierr;
2790298fd71SBarry Smith   Vec               coords = NULL;
28047c6ae99SBarry Smith   PetscInt          dim,i,j;
28147c6ae99SBarry Smith   const PetscScalar *local_coords;
282ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
28347c6ae99SBarry Smith   PetscInt          N,Ni;
28447c6ae99SBarry Smith 
28547c6ae99SBarry Smith   PetscFunctionBegin;
286c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
287c73cfb54SMatthew G. Knepley   dim  = dm->dim;
288c73cfb54SMatthew G. Knepley   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
2897324c66bSJed Brown   if (coords) {
29047c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
29147c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
29247c6ae99SBarry Smith     Ni   = N/dim;
29347c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
2947324c66bSJed Brown       for (j=0; j<3; j++) {
2957324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
2962197688cSJed Brown         max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
29747c6ae99SBarry Smith       }
29847c6ae99SBarry Smith     }
29947c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
3007324c66bSJed Brown   } else {                      /* Just use grid indices */
3017324c66bSJed Brown     DMDALocalInfo info;
302c73cfb54SMatthew G. Knepley     ierr   = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
3037324c66bSJed Brown     min[0] = info.xs;
3047324c66bSJed Brown     min[1] = info.ys;
3057324c66bSJed Brown     min[2] = info.zs;
3067324c66bSJed Brown     max[0] = info.xs + info.xm-1;
3077324c66bSJed Brown     max[1] = info.ys + info.ym-1;
3087324c66bSJed Brown     max[2] = info.zs + info.zm-1;
3097324c66bSJed Brown   }
31047c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
31147c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
31247c6ae99SBarry Smith   PetscFunctionReturn(0);
31347c6ae99SBarry Smith }
31447c6ae99SBarry Smith 
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 /*@
349db05f41bSBarry Smith    DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields
350bc2bf880SBarry Smith 
351bc2bf880SBarry Smith    Collective on DMDA
352bc2bf880SBarry Smith 
353907376e6SBarry Smith    Input Parameters:
354bc2bf880SBarry Smith +  da - the distributed array
355907376e6SBarry Smith -  nfields - number of fields in new DMDA
356bc2bf880SBarry Smith 
357bc2bf880SBarry Smith    Output Parameter:
358bc2bf880SBarry Smith .  nda - the new DMDA
359bc2bf880SBarry Smith 
360bc2bf880SBarry Smith   Level: intermediate
361bc2bf880SBarry Smith 
362bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
363bc2bf880SBarry Smith 
3642150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
365bc2bf880SBarry Smith @*/
366db05f41bSBarry Smith PetscErrorCode  DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
367bc2bf880SBarry Smith {
368bc2bf880SBarry Smith   PetscErrorCode   ierr;
369bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
37095c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
371320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
372bff4a2f0SMatthew G. Knepley   DMBoundaryType   bx,by,bz;
373320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
37495c13181SPeter Brune   PetscInt         ox,oy,oz;
37595c13181SPeter Brune   PetscInt         cl,rl;
376320964c4SBlaise Bourdin 
377320964c4SBlaise Bourdin   PetscFunctionBegin;
378c73cfb54SMatthew G. Knepley   dim = da->dim;
37995c13181SPeter Brune   M   = dd->M;
38095c13181SPeter Brune   N   = dd->N;
38195c13181SPeter Brune   P   = dd->P;
38295c13181SPeter Brune   m   = dd->m;
38395c13181SPeter Brune   n   = dd->n;
38495c13181SPeter Brune   p   = dd->p;
38595c13181SPeter Brune   s   = dd->s;
38695c13181SPeter Brune   bx  = dd->bx;
38795c13181SPeter Brune   by  = dd->by;
38895c13181SPeter Brune   bz  = dd->bz;
3898865f1eaSKarl Rupp 
39095c13181SPeter Brune   stencil_type = dd->stencil_type;
3918865f1eaSKarl Rupp 
392320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
393320964c4SBlaise Bourdin   if (dim == 1) {
394ce94432eSBarry Smith     ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
395320964c4SBlaise Bourdin   } else if (dim == 2) {
396ce94432eSBarry Smith     ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
397320964c4SBlaise Bourdin   } else if (dim == 3) {
398ce94432eSBarry 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);
399bc2bf880SBarry Smith   }
400897f7067SBarry Smith   ierr = DMSetUp(*nda);CHKERRQ(ierr);
4016636e97aSMatthew G Knepley   if (da->coordinates) {
4026636e97aSMatthew G Knepley     ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
4036636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
404bc2bf880SBarry Smith   }
40595c13181SPeter Brune 
40695c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
40795c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
40895c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
40995c13181SPeter Brune 
41095c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
41195c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
41295c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
4138865f1eaSKarl Rupp 
41495c13181SPeter Brune   (*nda)->levelup   = rl;
41595c13181SPeter Brune   (*nda)->leveldown = cl;
416bc2bf880SBarry Smith   PetscFunctionReturn(0);
417bc2bf880SBarry Smith }
418bc2bf880SBarry Smith 
419c593f006SBarry Smith /*@C
420c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
421c593f006SBarry Smith 
422c593f006SBarry Smith    Not Collective
423c593f006SBarry Smith 
424c593f006SBarry Smith    Input Parameter:
425c593f006SBarry Smith .  dm - the DM
426c593f006SBarry Smith 
427c593f006SBarry Smith    Output Parameter:
428c593f006SBarry Smith .  xc - the coordinates
429c593f006SBarry Smith 
430c593f006SBarry Smith   Level: intermediate
431c593f006SBarry Smith 
432c593f006SBarry Smith .keywords: distributed array, get, component name
433c593f006SBarry Smith 
434c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
435c593f006SBarry Smith @*/
436c593f006SBarry Smith PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
437c593f006SBarry Smith {
438c593f006SBarry Smith   PetscErrorCode ierr;
439c593f006SBarry Smith   DM             cdm;
440c593f006SBarry Smith   Vec            x;
441c593f006SBarry Smith 
442c593f006SBarry Smith   PetscFunctionBegin;
443c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
444c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
445c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
446c593f006SBarry Smith   ierr = DMDAVecGetArray(cdm,x,xc);CHKERRQ(ierr);
447c593f006SBarry Smith   PetscFunctionReturn(0);
448c593f006SBarry Smith }
449c593f006SBarry Smith 
450c593f006SBarry Smith /*@C
451c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
452c593f006SBarry Smith 
453c593f006SBarry Smith    Not Collective
454c593f006SBarry Smith 
455c593f006SBarry Smith    Input Parameter:
456c593f006SBarry Smith +  dm - the DM
457c593f006SBarry Smith -  xc - the coordinates
458c593f006SBarry Smith 
459c593f006SBarry Smith   Level: intermediate
460c593f006SBarry Smith 
461c593f006SBarry Smith .keywords: distributed array, get, component name
462c593f006SBarry Smith 
463c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
464c593f006SBarry Smith @*/
465c593f006SBarry Smith PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
466c593f006SBarry Smith {
467c593f006SBarry Smith   PetscErrorCode ierr;
468c593f006SBarry Smith   DM             cdm;
469c593f006SBarry Smith   Vec            x;
470c593f006SBarry Smith 
471c593f006SBarry Smith   PetscFunctionBegin;
472c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
473c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
474c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
475c593f006SBarry Smith   ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr);
476c593f006SBarry Smith   PetscFunctionReturn(0);
477c593f006SBarry Smith }
478