Actual source code: dacorn.c
petsc-3.7.3 2016-08-01
2: /*
3: Code for manipulating distributed regular arrays in parallel.
4: */
6: #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/
10: PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
11: {
14: DMDAGetReducedDMDA(dm,dm->dim,cdm);
15: return(0);
16: }
20: /*@C
21: DMDASetFieldName - Sets the names of individual field components in multicomponent
22: vectors associated with a DMDA.
24: Not Collective
26: Input Parameters:
27: + da - the distributed array
28: . nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
29: number of degrees of freedom per node within the DMDA
30: - names - the name of the field (component)
32: Level: intermediate
34: .keywords: distributed array, get, component name
36: .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldNames()
37: @*/
38: PetscErrorCode DMDASetFieldName(DM da,PetscInt nf,const char name[])
39: {
41: DM_DA *dd = (DM_DA*)da->data;
45: if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
46: PetscFree(dd->fieldname[nf]);
47: PetscStrallocpy(name,&dd->fieldname[nf]);
48: return(0);
49: }
53: /*@C
54: DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
56: Collective on TS
58: Input Parameter:
59: . dm - the DMDA object
61: Output Parameter:
62: . 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
64: Level: intermediate
66: .keywords: distributed array, get, component name
68: .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
69: @*/
70: PetscErrorCode DMDAGetFieldNames(DM da,const char * const **names)
71: {
72: DM_DA *dd = (DM_DA*)da->data;
75: *names = (const char * const *) dd->fieldname;
76: return(0);
77: }
81: /*@C
82: DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
84: Collective on TS
86: Input Parameters:
87: + dm - the DMDA object
88: - 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
90: Level: intermediate
92: .keywords: distributed array, get, component name
94: .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName()
95: @*/
96: PetscErrorCode DMDASetFieldNames(DM da,const char * const *names)
97: {
98: PetscErrorCode ierr;
99: DM_DA *dd = (DM_DA*)da->data;
102: PetscStrArrayDestroy(&dd->fieldname);
103: PetscStrArrayallocpy(names,&dd->fieldname);
104: return(0);
105: }
109: /*@C
110: DMDAGetFieldName - Gets the names of individual field components in multicomponent
111: vectors associated with a DMDA.
113: Not Collective
115: Input Parameter:
116: + da - the distributed array
117: - nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
118: number of degrees of freedom per node within the DMDA
120: Output Parameter:
121: . names - the name of the field (component)
123: Level: intermediate
125: .keywords: distributed array, get, component name
127: .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName()
128: @*/
129: PetscErrorCode DMDAGetFieldName(DM da,PetscInt nf,const char **name)
130: {
131: DM_DA *dd = (DM_DA*)da->data;
136: if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
137: *name = dd->fieldname[nf];
138: return(0);
139: }
143: /*@C
144: DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
146: Not Collective
148: Input Parameters:
149: + dm - the DM
150: . nf - coordinate number for the DMDA (0, 1, ... dim-1),
151: - name - the name of the coordinate
153: Level: intermediate
155: .keywords: distributed array, get, component name
157: .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName()
158: @*/
159: PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
160: {
162: DM_DA *dd = (DM_DA*)dm->data;
166: if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
167: PetscFree(dd->coordinatename[nf]);
168: PetscStrallocpy(name,&dd->coordinatename[nf]);
169: return(0);
170: }
174: /*@C
175: DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
177: Not Collective
179: Input Parameter:
180: + dm - the DM
181: - nf - number for the DMDA (0, 1, ... dim-1)
183: Output Parameter:
184: . names - the name of the coordinate direction
186: Level: intermediate
188: .keywords: distributed array, get, component name
190: .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName()
191: @*/
192: PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
193: {
194: DM_DA *dd = (DM_DA*)dm->data;
199: if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
200: *name = dd->coordinatename[nf];
201: return(0);
202: }
206: /*@
207: DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
208: corner and size of the local region, excluding ghost points.
210: Not Collective
212: Input Parameter:
213: . da - the distributed array
215: Output Parameters:
216: + x,y,z - the corner indices (where y and z are optional; these are used
217: for 2D and 3D problems)
218: - m,n,p - widths in the corresponding directions (where n and p are optional;
219: these are used for 2D and 3D problems)
221: Note:
222: The corner information is independent of the number of degrees of
223: freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
224: m, n, p can be thought of as coordinates on a logical grid, where each
225: grid point has (potentially) several degrees of freedom.
226: Any of y, z, n, and p can be passed in as NULL if not needed.
228: Level: beginner
230: .keywords: distributed array, get, corners, nodes, local indices
232: .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
233: @*/
234: PetscErrorCode DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
235: {
236: PetscInt w;
237: DM_DA *dd = (DM_DA*)da->data;
241: /* since the xs, xe ... have all been multiplied by the number of degrees
242: of freedom per cell, w = dd->w, we divide that out before returning.*/
243: w = dd->w;
244: if (x) *x = dd->xs/w + dd->xo;
245: /* the y and z have NOT been multiplied by w */
246: if (y) *y = dd->ys + dd->yo;
247: if (z) *z = dd->zs + dd->zo;
248: if (m) *m = (dd->xe - dd->xs)/w;
249: if (n) *n = (dd->ye - dd->ys);
250: if (p) *p = (dd->ze - dd->zs);
251: return(0);
252: }
256: /*@
257: DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA.
259: Not Collective
261: Input Parameter:
262: . dm - the DM
264: Output Parameters:
265: + lmin - local minimum coordinates (length dim, optional)
266: - lmax - local maximim coordinates (length dim, optional)
268: Level: beginner
270: .keywords: distributed array, get, coordinates
272: .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox()
273: @*/
274: PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[])
275: {
276: PetscErrorCode ierr;
277: Vec coords = NULL;
278: PetscInt dim,i,j;
279: const PetscScalar *local_coords;
280: PetscReal min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL};
281: PetscInt N,Ni;
285: dim = dm->dim;
286: DMGetCoordinates(dm,&coords);
287: if (coords) {
288: VecGetArrayRead(coords,&local_coords);
289: VecGetLocalSize(coords,&N);
290: Ni = N/dim;
291: for (i=0; i<Ni; i++) {
292: for (j=0; j<3; j++) {
293: min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0;
294: max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0;
295: }
296: }
297: VecRestoreArrayRead(coords,&local_coords);
298: } else { /* Just use grid indices */
299: DMDALocalInfo info;
300: DMDAGetLocalInfo(dm,&info);
301: min[0] = info.xs;
302: min[1] = info.ys;
303: min[2] = info.zs;
304: max[0] = info.xs + info.xm-1;
305: max[1] = info.ys + info.ym-1;
306: max[2] = info.zs + info.zm-1;
307: }
308: if (lmin) {PetscMemcpy(lmin,min,dim*sizeof(PetscReal));}
309: if (lmax) {PetscMemcpy(lmax,max,dim*sizeof(PetscReal));}
310: return(0);
311: }
315: /*@
316: DMDAGetBoundingBox - Returns the global bounding box for the DMDA.
318: Collective on DMDA
320: Input Parameter:
321: . dm - the DM
323: Output Parameters:
324: + gmin - global minimum coordinates (length dim, optional)
325: - gmax - global maximim coordinates (length dim, optional)
327: Level: beginner
329: .keywords: distributed array, get, coordinates
331: .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox()
332: @*/
333: PetscErrorCode DMDAGetBoundingBox(DM dm,PetscReal gmin[],PetscReal gmax[])
334: {
336: PetscMPIInt count;
337: PetscReal lmin[3],lmax[3];
341: PetscMPIIntCast(dm->dim,&count);
342: DMDAGetLocalBoundingBox(dm,lmin,lmax);
343: if (gmin) {MPIU_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));}
344: if (gmax) {MPIU_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));}
345: return(0);
346: }
350: /*@
351: DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields
353: Collective on DMDA
355: Input Parameters:
356: + da - the distributed array
357: - nfields - number of fields in new DMDA
359: Output Parameter:
360: . nda - the new DMDA
362: Level: intermediate
364: .keywords: distributed array, get, corners, nodes, local indices, coordinates
366: .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
367: @*/
368: PetscErrorCode DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
369: {
370: PetscErrorCode ierr;
371: DM_DA *dd = (DM_DA*)da->data;
372: PetscInt s,m,n,p,M,N,P,dim,Mo,No,Po;
373: const PetscInt *lx,*ly,*lz;
374: DMBoundaryType bx,by,bz;
375: DMDAStencilType stencil_type;
376: PetscInt ox,oy,oz;
377: PetscInt cl,rl;
380: dim = da->dim;
381: M = dd->M;
382: N = dd->N;
383: P = dd->P;
384: m = dd->m;
385: n = dd->n;
386: p = dd->p;
387: s = dd->s;
388: bx = dd->bx;
389: by = dd->by;
390: bz = dd->bz;
392: stencil_type = dd->stencil_type;
394: DMDAGetOwnershipRanges(da,&lx,&ly,&lz);
395: if (dim == 1) {
396: DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);
397: } else if (dim == 2) {
398: DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);
399: } else if (dim == 3) {
400: DMDACreate3d(PetscObjectComm((PetscObject)da),bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);
401: }
402: if (da->coordinates) {
403: PetscObjectReference((PetscObject)da->coordinates);
405: (*nda)->coordinates = da->coordinates;
406: }
408: /* allow for getting a reduced DA corresponding to a domain decomposition */
409: DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);
410: DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);
412: /* allow for getting a reduced DA corresponding to a coarsened DA */
413: DMGetCoarsenLevel(da,&cl);
414: DMGetRefineLevel(da,&rl);
416: (*nda)->levelup = rl;
417: (*nda)->leveldown = cl;
418: return(0);
419: }
423: /*@C
424: DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
426: Not Collective
428: Input Parameter:
429: . dm - the DM
431: Output Parameter:
432: . xc - the coordinates
434: Level: intermediate
436: .keywords: distributed array, get, component name
438: .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
439: @*/
440: PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
441: {
443: DM cdm;
444: Vec x;
448: DMGetCoordinates(dm,&x);
449: DMGetCoordinateDM(dm,&cdm);
450: DMDAVecGetArray(cdm,x,xc);
451: return(0);
452: }
456: /*@C
457: DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
459: Not Collective
461: Input Parameter:
462: + dm - the DM
463: - xc - the coordinates
465: Level: intermediate
467: .keywords: distributed array, get, component name
469: .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
470: @*/
471: PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
472: {
474: DM cdm;
475: Vec x;
479: DMGetCoordinates(dm,&x);
480: DMGetCoordinateDM(dm,&cdm);
481: DMDAVecRestoreArray(cdm,x,xc);
482: return(0);
483: }