xref: /petsc/src/dm/impls/da/dacorn.c (revision f5f57ec0aaa1e5be6a6f3c2ef714a1a38ff0b64a)
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 
283eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
293eac1ceeSStefano Zampini 
3047c6ae99SBarry Smith   Level: intermediate
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith .keywords: distributed array, get, component name
3347c6ae99SBarry Smith 
343eac1ceeSStefano 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);
443eac1ceeSStefano 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 
63*f5f57ec0SBarry Smith    Not supported from Fortran, use DMDAGetFieldName()
64*f5f57ec0SBarry Smith 
65c629b14aSBarry Smith .keywords: distributed array, get, component name
66c629b14aSBarry Smith 
67c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
68c629b14aSBarry Smith @*/
69c629b14aSBarry Smith PetscErrorCode  DMDAGetFieldNames(DM da,const char * const **names)
70c629b14aSBarry Smith {
71c629b14aSBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
72c629b14aSBarry Smith 
73c629b14aSBarry Smith   PetscFunctionBegin;
74c629b14aSBarry Smith   *names = (const char * const *) dd->fieldname;
75c629b14aSBarry Smith   PetscFunctionReturn(0);
76c629b14aSBarry Smith }
77c629b14aSBarry Smith 
78c629b14aSBarry Smith /*@C
79c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
80c629b14aSBarry Smith 
81c629b14aSBarry Smith    Collective on TS
82c629b14aSBarry Smith 
83c629b14aSBarry Smith    Input Parameters:
84c629b14aSBarry Smith +  dm - the DMDA object
85c629b14aSBarry 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
86c629b14aSBarry Smith 
873eac1ceeSStefano Zampini    Notes: It must be called after having called DMSetUp().
883eac1ceeSStefano Zampini 
89c629b14aSBarry Smith    Level: intermediate
90c629b14aSBarry Smith 
91*f5f57ec0SBarry Smith    Not supported from Fortran, use DMDASetFieldName()
92*f5f57ec0SBarry Smith 
93c629b14aSBarry Smith .keywords: distributed array, get, component name
94c629b14aSBarry Smith 
953eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMSetUp()
96c629b14aSBarry Smith @*/
97c629b14aSBarry Smith PetscErrorCode  DMDASetFieldNames(DM da,const char * const *names)
98c629b14aSBarry Smith {
99c629b14aSBarry Smith   PetscErrorCode ierr;
100c629b14aSBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
1013eac1ceeSStefano Zampini   char           **fieldname;
1023eac1ceeSStefano Zampini   PetscInt       nf = 0;
103c629b14aSBarry Smith 
104c629b14aSBarry Smith   PetscFunctionBegin;
1053eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
1063eac1ceeSStefano Zampini   while (names[nf++]) {};
1073eac1ceeSStefano Zampini   if (nf != dd->w+1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid number of fields %D",nf-1);
1083eac1ceeSStefano Zampini   ierr = PetscStrArrayallocpy(names,&fieldname);CHKERRQ(ierr);
109c629b14aSBarry Smith   ierr = PetscStrArrayDestroy(&dd->fieldname);CHKERRQ(ierr);
1103eac1ceeSStefano Zampini   dd->fieldname = fieldname;
111c629b14aSBarry Smith   PetscFunctionReturn(0);
112c629b14aSBarry Smith }
113c629b14aSBarry Smith 
11447c6ae99SBarry Smith /*@C
115aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
116aa219208SBarry Smith    vectors associated with a DMDA.
11747c6ae99SBarry Smith 
11847c6ae99SBarry Smith    Not Collective
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith    Input Parameter:
12147c6ae99SBarry Smith +  da - the distributed array
122aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
123aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
12447c6ae99SBarry Smith 
12547c6ae99SBarry Smith    Output Parameter:
12647c6ae99SBarry Smith .  names - the name of the field (component)
12747c6ae99SBarry Smith 
1283eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
1293eac1ceeSStefano Zampini 
13047c6ae99SBarry Smith   Level: intermediate
13147c6ae99SBarry Smith 
13247c6ae99SBarry Smith .keywords: distributed array, get, component name
13347c6ae99SBarry Smith 
1343eac1ceeSStefano Zampini .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMSetUp()
13547c6ae99SBarry Smith @*/
1367087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
13747c6ae99SBarry Smith {
13847c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
13947c6ae99SBarry Smith 
14047c6ae99SBarry Smith   PetscFunctionBegin;
14147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
14247c6ae99SBarry Smith   PetscValidPointer(name,3);
14347c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
1443eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
14547c6ae99SBarry Smith   *name = dd->fieldname[nf];
14647c6ae99SBarry Smith   PetscFunctionReturn(0);
14747c6ae99SBarry Smith }
14847c6ae99SBarry Smith 
149109c9344SBarry Smith /*@C
150109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
151109c9344SBarry Smith 
152109c9344SBarry Smith    Not Collective
153109c9344SBarry Smith 
154109c9344SBarry Smith    Input Parameters:
155c73cfb54SMatthew G. Knepley +  dm - the DM
156109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
157109c9344SBarry Smith -  name - the name of the coordinate
158109c9344SBarry Smith 
1593eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
1603eac1ceeSStefano Zampini 
161109c9344SBarry Smith   Level: intermediate
162109c9344SBarry Smith 
163*f5f57ec0SBarry Smith   Not supported from Fortran
164*f5f57ec0SBarry Smith 
165109c9344SBarry Smith .keywords: distributed array, get, component name
166109c9344SBarry Smith 
1673eac1ceeSStefano Zampini .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
168109c9344SBarry Smith @*/
169c73cfb54SMatthew G. Knepley PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
170109c9344SBarry Smith {
171109c9344SBarry Smith   PetscErrorCode ierr;
172c73cfb54SMatthew G. Knepley   DM_DA          *dd = (DM_DA*)dm->data;
173109c9344SBarry Smith 
174109c9344SBarry Smith   PetscFunctionBegin;
175c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
176c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
1773eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
178109c9344SBarry Smith   ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr);
179109c9344SBarry Smith   ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr);
180109c9344SBarry Smith   PetscFunctionReturn(0);
181109c9344SBarry Smith }
182109c9344SBarry Smith 
183109c9344SBarry Smith /*@C
184109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
185109c9344SBarry Smith 
186109c9344SBarry Smith    Not Collective
187109c9344SBarry Smith 
188109c9344SBarry Smith    Input Parameter:
189c73cfb54SMatthew G. Knepley +  dm - the DM
190109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
191109c9344SBarry Smith 
192109c9344SBarry Smith    Output Parameter:
193109c9344SBarry Smith .  names - the name of the coordinate direction
194109c9344SBarry Smith 
1953eac1ceeSStefano Zampini   Notes: It must be called after having called DMSetUp().
1963eac1ceeSStefano Zampini 
197109c9344SBarry Smith   Level: intermediate
198109c9344SBarry Smith 
199*f5f57ec0SBarry Smith   Not supported from Fortran
200*f5f57ec0SBarry Smith 
201109c9344SBarry Smith .keywords: distributed array, get, component name
202109c9344SBarry Smith 
2033eac1ceeSStefano Zampini .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
204109c9344SBarry Smith @*/
205c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
206109c9344SBarry Smith {
207c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA*)dm->data;
208109c9344SBarry Smith 
209109c9344SBarry Smith   PetscFunctionBegin;
210c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
211109c9344SBarry Smith   PetscValidPointer(name,3);
212c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
2133eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
214109c9344SBarry Smith   *name = dd->coordinatename[nf];
215109c9344SBarry Smith   PetscFunctionReturn(0);
216109c9344SBarry Smith }
217109c9344SBarry Smith 
218a5d1443cSVincent Le Chenadec /*@C
219aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
22059f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
22147c6ae99SBarry Smith 
22247c6ae99SBarry Smith    Not Collective
22347c6ae99SBarry Smith 
22447c6ae99SBarry Smith    Input Parameter:
22547c6ae99SBarry Smith .  da - the distributed array
22647c6ae99SBarry Smith 
22747c6ae99SBarry Smith    Output Parameters:
22847c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
22947c6ae99SBarry Smith            for 2D and 3D problems)
23047c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
23147c6ae99SBarry Smith            these are used for 2D and 3D problems)
23247c6ae99SBarry Smith 
23347c6ae99SBarry Smith    Note:
23447c6ae99SBarry Smith    The corner information is independent of the number of degrees of
235aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
23647c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
23747c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2380298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
23947c6ae99SBarry Smith 
24047c6ae99SBarry Smith   Level: beginner
24147c6ae99SBarry Smith 
24247c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices
24347c6ae99SBarry Smith 
244aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
24547c6ae99SBarry Smith @*/
2467087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
24747c6ae99SBarry Smith {
24847c6ae99SBarry Smith   PetscInt w;
24947c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
25047c6ae99SBarry Smith 
25147c6ae99SBarry Smith   PetscFunctionBegin;
25247c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
25347c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
25447c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
25547c6ae99SBarry Smith   w = dd->w;
25659bc5b24SSatish Balay   if (x) *x = dd->xs/w + dd->xo;
25747c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
25859bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
25959bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
26059bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs)/w;
26159bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
26259bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
26347c6ae99SBarry Smith   PetscFunctionReturn(0);
26447c6ae99SBarry Smith }
26547c6ae99SBarry Smith 
26647c6ae99SBarry Smith /*@
267aa219208SBarry Smith    DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
26847c6ae99SBarry Smith 
26947c6ae99SBarry Smith    Not Collective
27047c6ae99SBarry Smith 
27147c6ae99SBarry Smith    Input Parameter:
272c73cfb54SMatthew G. Knepley .  dm - the DM
27347c6ae99SBarry Smith 
27447c6ae99SBarry Smith    Output Parameters:
27547c6ae99SBarry Smith +  lmin - local minimum coordinates (length dim, optional)
27647c6ae99SBarry Smith -  lmax - local maximim coordinates (length dim, optional)
27747c6ae99SBarry Smith 
27847c6ae99SBarry Smith   Level: beginner
27947c6ae99SBarry Smith 
280*f5f57ec0SBarry Smith   Not supported from Fortran
281*f5f57ec0SBarry Smith 
28247c6ae99SBarry Smith .keywords: distributed array, get, coordinates
28347c6ae99SBarry Smith 
2842150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
28547c6ae99SBarry Smith @*/
286c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[])
28747c6ae99SBarry Smith {
28847c6ae99SBarry Smith   PetscErrorCode    ierr;
2890298fd71SBarry Smith   Vec               coords = NULL;
29047c6ae99SBarry Smith   PetscInt          dim,i,j;
29147c6ae99SBarry Smith   const PetscScalar *local_coords;
292ea345e14SBarry Smith   PetscReal         min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
29347c6ae99SBarry Smith   PetscInt          N,Ni;
29447c6ae99SBarry Smith 
29547c6ae99SBarry Smith   PetscFunctionBegin;
296c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
297c73cfb54SMatthew G. Knepley   dim  = dm->dim;
298c73cfb54SMatthew G. Knepley   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
2997324c66bSJed Brown   if (coords) {
30047c6ae99SBarry Smith     ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr);
30147c6ae99SBarry Smith     ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr);
30247c6ae99SBarry Smith     Ni   = N/dim;
30347c6ae99SBarry Smith     for (i=0; i<Ni; i++) {
3047324c66bSJed Brown       for (j=0; j<3; j++) {
3057324c66bSJed Brown         min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
3062197688cSJed Brown         max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
30747c6ae99SBarry Smith       }
30847c6ae99SBarry Smith     }
30947c6ae99SBarry Smith     ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr);
3107324c66bSJed Brown   } else {                      /* Just use grid indices */
3117324c66bSJed Brown     DMDALocalInfo info;
312c73cfb54SMatthew G. Knepley     ierr   = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
3137324c66bSJed Brown     min[0] = info.xs;
3147324c66bSJed Brown     min[1] = info.ys;
3157324c66bSJed Brown     min[2] = info.zs;
3167324c66bSJed Brown     max[0] = info.xs + info.xm-1;
3177324c66bSJed Brown     max[1] = info.ys + info.ym-1;
3187324c66bSJed Brown     max[2] = info.zs + info.zm-1;
3197324c66bSJed Brown   }
32047c6ae99SBarry Smith   if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);}
32147c6ae99SBarry Smith   if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);}
32247c6ae99SBarry Smith   PetscFunctionReturn(0);
32347c6ae99SBarry Smith }
32447c6ae99SBarry Smith 
32547c6ae99SBarry Smith /*@
326aa219208SBarry Smith    DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
32747c6ae99SBarry Smith 
328aa219208SBarry Smith    Collective on DMDA
32947c6ae99SBarry Smith 
33047c6ae99SBarry Smith    Input Parameter:
331c73cfb54SMatthew G. Knepley .  dm - the DM
33247c6ae99SBarry Smith 
33347c6ae99SBarry Smith    Output Parameters:
33447c6ae99SBarry Smith +  gmin - global minimum coordinates (length dim, optional)
33547c6ae99SBarry Smith -  gmax - global maximim coordinates (length dim, optional)
33647c6ae99SBarry Smith 
33747c6ae99SBarry Smith   Level: beginner
33847c6ae99SBarry Smith 
33947c6ae99SBarry Smith .keywords: distributed array, get, coordinates
34047c6ae99SBarry Smith 
3412150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
34247c6ae99SBarry Smith @*/
343c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetBoundingBox(DM dm,PetscReal gmin[],PetscReal gmax[])
34447c6ae99SBarry Smith {
34547c6ae99SBarry Smith   PetscErrorCode ierr;
34647c6ae99SBarry Smith   PetscMPIInt    count;
34747c6ae99SBarry Smith   PetscReal      lmin[3],lmax[3];
34847c6ae99SBarry Smith 
34947c6ae99SBarry Smith   PetscFunctionBegin;
350c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
351c73cfb54SMatthew G. Knepley   ierr = PetscMPIIntCast(dm->dim,&count);CHKERRQ(ierr);
352c73cfb54SMatthew G. Knepley   ierr = DMDAGetLocalBoundingBox(dm,lmin,lmax);CHKERRQ(ierr);
353b2566f29SBarry Smith   if (gmin) {ierr = MPIU_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
354b2566f29SBarry Smith   if (gmax) {ierr = MPIU_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);}
35547c6ae99SBarry Smith   PetscFunctionReturn(0);
35647c6ae99SBarry Smith }
357bc2bf880SBarry Smith 
358bc2bf880SBarry Smith /*@
359db05f41bSBarry Smith    DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields
360bc2bf880SBarry Smith 
361bc2bf880SBarry Smith    Collective on DMDA
362bc2bf880SBarry Smith 
363907376e6SBarry Smith    Input Parameters:
364bc2bf880SBarry Smith +  da - the distributed array
365907376e6SBarry Smith -  nfields - number of fields in new DMDA
366bc2bf880SBarry Smith 
367bc2bf880SBarry Smith    Output Parameter:
368bc2bf880SBarry Smith .  nda - the new DMDA
369bc2bf880SBarry Smith 
370bc2bf880SBarry Smith   Level: intermediate
371bc2bf880SBarry Smith 
372bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates
373bc2bf880SBarry Smith 
3742150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
375bc2bf880SBarry Smith @*/
376db05f41bSBarry Smith PetscErrorCode  DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
377bc2bf880SBarry Smith {
378bc2bf880SBarry Smith   PetscErrorCode   ierr;
379bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
38095c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
381320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
382bff4a2f0SMatthew G. Knepley   DMBoundaryType   bx,by,bz;
383320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
38495c13181SPeter Brune   PetscInt         ox,oy,oz;
38595c13181SPeter Brune   PetscInt         cl,rl;
386320964c4SBlaise Bourdin 
387320964c4SBlaise Bourdin   PetscFunctionBegin;
388c73cfb54SMatthew G. Knepley   dim = da->dim;
38995c13181SPeter Brune   M   = dd->M;
39095c13181SPeter Brune   N   = dd->N;
39195c13181SPeter Brune   P   = dd->P;
39295c13181SPeter Brune   m   = dd->m;
39395c13181SPeter Brune   n   = dd->n;
39495c13181SPeter Brune   p   = dd->p;
39595c13181SPeter Brune   s   = dd->s;
39695c13181SPeter Brune   bx  = dd->bx;
39795c13181SPeter Brune   by  = dd->by;
39895c13181SPeter Brune   bz  = dd->bz;
3998865f1eaSKarl Rupp 
40095c13181SPeter Brune   stencil_type = dd->stencil_type;
4018865f1eaSKarl Rupp 
402320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
403320964c4SBlaise Bourdin   if (dim == 1) {
404ce94432eSBarry Smith     ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
405320964c4SBlaise Bourdin   } else if (dim == 2) {
406ce94432eSBarry Smith     ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
407320964c4SBlaise Bourdin   } else if (dim == 3) {
408ce94432eSBarry 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);
409bc2bf880SBarry Smith   }
410897f7067SBarry Smith   ierr = DMSetUp(*nda);CHKERRQ(ierr);
4116636e97aSMatthew G Knepley   if (da->coordinates) {
4126636e97aSMatthew G Knepley     ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
4136636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
414bc2bf880SBarry Smith   }
41595c13181SPeter Brune 
41695c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
41795c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
41895c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
41995c13181SPeter Brune 
42095c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
42195c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
42295c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
4238865f1eaSKarl Rupp 
42495c13181SPeter Brune   (*nda)->levelup   = rl;
42595c13181SPeter Brune   (*nda)->leveldown = cl;
426bc2bf880SBarry Smith   PetscFunctionReturn(0);
427bc2bf880SBarry Smith }
428bc2bf880SBarry Smith 
429c593f006SBarry Smith /*@C
430c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
431c593f006SBarry Smith 
432c593f006SBarry Smith    Not Collective
433c593f006SBarry Smith 
434c593f006SBarry Smith    Input Parameter:
435c593f006SBarry Smith .  dm - the DM
436c593f006SBarry Smith 
437c593f006SBarry Smith    Output Parameter:
438c593f006SBarry Smith .  xc - the coordinates
439c593f006SBarry Smith 
440c593f006SBarry Smith   Level: intermediate
441c593f006SBarry Smith 
442*f5f57ec0SBarry Smith   Not supported from Fortran
443*f5f57ec0SBarry Smith 
444c593f006SBarry Smith .keywords: distributed array, get, component name
445c593f006SBarry Smith 
446c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
447c593f006SBarry Smith @*/
448c593f006SBarry Smith PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
449c593f006SBarry Smith {
450c593f006SBarry Smith   PetscErrorCode ierr;
451c593f006SBarry Smith   DM             cdm;
452c593f006SBarry Smith   Vec            x;
453c593f006SBarry Smith 
454c593f006SBarry Smith   PetscFunctionBegin;
455c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
456c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
457c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
458c593f006SBarry Smith   ierr = DMDAVecGetArray(cdm,x,xc);CHKERRQ(ierr);
459c593f006SBarry Smith   PetscFunctionReturn(0);
460c593f006SBarry Smith }
461c593f006SBarry Smith 
462c593f006SBarry Smith /*@C
463c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
464c593f006SBarry Smith 
465c593f006SBarry Smith    Not Collective
466c593f006SBarry Smith 
467c593f006SBarry Smith    Input Parameter:
468c593f006SBarry Smith +  dm - the DM
469c593f006SBarry Smith -  xc - the coordinates
470c593f006SBarry Smith 
471c593f006SBarry Smith   Level: intermediate
472c593f006SBarry Smith 
473*f5f57ec0SBarry Smith   Not supported from Fortran
474*f5f57ec0SBarry Smith 
475c593f006SBarry Smith .keywords: distributed array, get, component name
476c593f006SBarry Smith 
477c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
478c593f006SBarry Smith @*/
479c593f006SBarry Smith PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
480c593f006SBarry Smith {
481c593f006SBarry Smith   PetscErrorCode ierr;
482c593f006SBarry Smith   DM             cdm;
483c593f006SBarry Smith   Vec            x;
484c593f006SBarry Smith 
485c593f006SBarry Smith   PetscFunctionBegin;
486c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
487c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
488c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
489c593f006SBarry Smith   ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr);
490c593f006SBarry Smith   PetscFunctionReturn(0);
491c593f006SBarry Smith }
492