Actual source code: dacorn.c
2: /*
3: Code for manipulating distributed regular arrays in parallel.
4: */
6: #include <petsc/private/dmdaimpl.h>
7: #include <petscdmfield.h>
9: PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
10: {
11: DMDACreateCompatibleDMDA(dm, dm->dim, cdm);
12: return 0;
13: }
15: PetscErrorCode DMCreateCoordinateField_DA(DM dm, DMField *field)
16: {
17: PetscReal gmin[3], gmax[3];
18: PetscScalar corners[24];
19: PetscInt dim;
20: PetscInt i, j;
21: DM cdm;
23: DMGetDimension(dm, &dim);
24: /* TODO: this is wrong if coordinates are not rectilinear */
25: DMGetBoundingBox(dm, gmin, gmax);
26: for (i = 0; i < (1 << dim); i++) {
27: for (j = 0; j < dim; j++) corners[i * dim + j] = (i & (1 << j)) ? gmax[j] : gmin[j];
28: }
29: DMClone(dm, &cdm);
30: DMFieldCreateDA(cdm, dim, corners, field);
31: DMDestroy(&cdm);
32: return 0;
33: }
35: /*@C
36: DMDASetFieldName - Sets the names of individual field components in multicomponent
37: vectors associated with a DMDA.
39: Logically collective; name must contain a common value
41: Input Parameters:
42: + da - the distributed array
43: . nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
44: number of degrees of freedom per node within the DMDA
45: - names - the name of the field (component)
47: Notes:
48: It must be called after having called DMSetUp().
50: Level: intermediate
52: .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldNames()`, `DMSetUp()`
53: @*/
54: PetscErrorCode DMDASetFieldName(DM da, PetscInt nf, const char name[])
55: {
56: DM_DA *dd = (DM_DA *)da->data;
61: PetscFree(dd->fieldname[nf]);
62: PetscStrallocpy(name, &dd->fieldname[nf]);
63: return 0;
64: }
66: /*@C
67: DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
69: Not collective; names will contain a common value
71: Input Parameter:
72: . dm - the DMDA object
74: Output Parameter:
75: . 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
77: Level: intermediate
79: Not supported from Fortran, use DMDAGetFieldName()
81: .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDASetFieldNames()`
82: @*/
83: PetscErrorCode DMDAGetFieldNames(DM da, const char *const **names)
84: {
85: DM_DA *dd = (DM_DA *)da->data;
87: *names = (const char *const *)dd->fieldname;
88: return 0;
89: }
91: /*@C
92: DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
94: Logically collective; names must contain a common value
96: Input Parameters:
97: + dm - the DMDA object
98: - 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
100: Notes:
101: It must be called after having called DMSetUp().
103: Level: intermediate
105: Not supported from Fortran, use DMDASetFieldName()
107: .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMSetUp()`
108: @*/
109: PetscErrorCode DMDASetFieldNames(DM da, const char *const *names)
110: {
111: DM_DA *dd = (DM_DA *)da->data;
112: char **fieldname;
113: PetscInt nf = 0;
116: while (names[nf++]) { };
118: PetscStrArrayallocpy(names, &fieldname);
119: PetscStrArrayDestroy(&dd->fieldname);
120: dd->fieldname = fieldname;
121: return 0;
122: }
124: /*@C
125: DMDAGetFieldName - Gets the names of individual field components in multicomponent
126: vectors associated with a DMDA.
128: Not collective; name will contain a common value
130: Input Parameters:
131: + da - the distributed array
132: - nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
133: number of degrees of freedom per node within the DMDA
135: Output Parameter:
136: . names - the name of the field (component)
138: Notes:
139: It must be called after having called DMSetUp().
141: Level: intermediate
143: .seealso: `DMDASetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMSetUp()`
144: @*/
145: PetscErrorCode DMDAGetFieldName(DM da, PetscInt nf, const char **name)
146: {
147: DM_DA *dd = (DM_DA *)da->data;
153: *name = dd->fieldname[nf];
154: return 0;
155: }
157: /*@C
158: DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
160: Logically collective; name must contain a common value
162: Input Parameters:
163: + dm - the DM
164: . nf - coordinate number for the DMDA (0, 1, ... dim-1),
165: - name - the name of the coordinate
167: Notes:
168: It must be called after having called DMSetUp().
170: Level: intermediate
172: Not supported from Fortran
174: .seealso: `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
175: @*/
176: PetscErrorCode DMDASetCoordinateName(DM dm, PetscInt nf, const char name[])
177: {
178: DM_DA *dd = (DM_DA *)dm->data;
183: PetscFree(dd->coordinatename[nf]);
184: PetscStrallocpy(name, &dd->coordinatename[nf]);
185: return 0;
186: }
188: /*@C
189: DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
191: Not collective; name will contain a common value
193: Input Parameters:
194: + dm - the DM
195: - nf - number for the DMDA (0, 1, ... dim-1)
197: Output Parameter:
198: . names - the name of the coordinate direction
200: Notes:
201: It must be called after having called DMSetUp().
203: Level: intermediate
205: Not supported from Fortran
207: .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
208: @*/
209: PetscErrorCode DMDAGetCoordinateName(DM dm, PetscInt nf, const char **name)
210: {
211: DM_DA *dd = (DM_DA *)dm->data;
217: *name = dd->coordinatename[nf];
218: return 0;
219: }
221: /*@C
222: DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
223: corner and size of the local region, excluding ghost points.
225: Not collective
227: Input Parameter:
228: . da - the distributed array
230: Output Parameters:
231: + x - the corner index for the first dimension
232: . y - the corner index for the second dimension (only used in 2D and 3D problems)
233: . z - the corner index for the third dimension (only used in 3D problems)
234: . m - the width in the first dimension
235: . n - the width in the second dimension (only used in 2D and 3D problems)
236: - p - the width in the third dimension (only used in 3D problems)
238: Note:
239: The corner information is independent of the number of degrees of
240: freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
241: m, n, p can be thought of as coordinates on a logical grid, where each
242: grid point has (potentially) several degrees of freedom.
243: Any of y, z, n, and p can be passed in as NULL if not needed.
245: Level: beginner
247: .seealso: `DMDAGetGhostCorners()`, `DMDAGetOwnershipRanges()`, `DMStagGetCorners()`
248: @*/
249: PetscErrorCode DMDAGetCorners(DM da, PetscInt *x, PetscInt *y, PetscInt *z, PetscInt *m, PetscInt *n, PetscInt *p)
250: {
251: PetscInt w;
252: DM_DA *dd = (DM_DA *)da->data;
255: /* since the xs, xe ... have all been multiplied by the number of degrees
256: of freedom per cell, w = dd->w, we divide that out before returning.*/
257: w = dd->w;
258: if (x) *x = dd->xs / w + dd->xo;
259: /* the y and z have NOT been multiplied by w */
260: if (y) *y = dd->ys + dd->yo;
261: if (z) *z = dd->zs + dd->zo;
262: if (m) *m = (dd->xe - dd->xs) / w;
263: if (n) *n = (dd->ye - dd->ys);
264: if (p) *p = (dd->ze - dd->zs);
265: return 0;
266: }
268: PetscErrorCode DMGetLocalBoundingIndices_DMDA(DM dm, PetscReal lmin[], PetscReal lmax[])
269: {
270: DMDALocalInfo info;
272: DMDAGetLocalInfo(dm, &info);
273: lmin[0] = info.xs;
274: lmin[1] = info.ys;
275: lmin[2] = info.zs;
276: lmax[0] = info.xs + info.xm - 1;
277: lmax[1] = info.ys + info.ym - 1;
278: lmax[2] = info.zs + info.zm - 1;
279: return 0;
280: }
282: /*@
283: DMDAGetReducedDMDA - Deprecated; use DMDACreateCompatibleDMDA()
285: Level: deprecated
286: @*/
287: PetscErrorCode DMDAGetReducedDMDA(DM da, PetscInt nfields, DM *nda)
288: {
289: DMDACreateCompatibleDMDA(da, nfields, nda);
290: return 0;
291: }
293: /*@
294: DMDACreateCompatibleDMDA - Creates a DMDA with the same layout but with fewer or more fields
296: Collective
298: Input Parameters:
299: + da - the distributed array
300: - nfields - number of fields in new DMDA
302: Output Parameter:
303: . nda - the new DMDA
305: Level: intermediate
307: .seealso: `DMDAGetGhostCorners()`, `DMSetCoordinates()`, `DMDASetUniformCoordinates()`, `DMGetCoordinates()`, `DMDAGetGhostedCoordinates()`, `DMStagCreateCompatibleDMStag()`
308: @*/
309: PetscErrorCode DMDACreateCompatibleDMDA(DM da, PetscInt nfields, DM *nda)
310: {
311: DM_DA *dd = (DM_DA *)da->data;
312: PetscInt s, m, n, p, M, N, P, dim, Mo, No, Po;
313: const PetscInt *lx, *ly, *lz;
314: DMBoundaryType bx, by, bz;
315: DMDAStencilType stencil_type;
316: Vec coords;
317: PetscInt ox, oy, oz;
318: PetscInt cl, rl;
320: dim = da->dim;
321: M = dd->M;
322: N = dd->N;
323: P = dd->P;
324: m = dd->m;
325: n = dd->n;
326: p = dd->p;
327: s = dd->s;
328: bx = dd->bx;
329: by = dd->by;
330: bz = dd->bz;
332: stencil_type = dd->stencil_type;
334: DMDAGetOwnershipRanges(da, &lx, &ly, &lz);
335: if (dim == 1) {
336: DMDACreate1d(PetscObjectComm((PetscObject)da), bx, M, nfields, s, dd->lx, nda);
337: } else if (dim == 2) {
338: DMDACreate2d(PetscObjectComm((PetscObject)da), bx, by, stencil_type, M, N, m, n, nfields, s, lx, ly, nda);
339: } else if (dim == 3) {
340: DMDACreate3d(PetscObjectComm((PetscObject)da), bx, by, bz, stencil_type, M, N, P, m, n, p, nfields, s, lx, ly, lz, nda);
341: }
342: DMSetUp(*nda);
343: DMGetCoordinates(da, &coords);
344: DMSetCoordinates(*nda, coords);
346: /* allow for getting a reduced DA corresponding to a domain decomposition */
347: DMDAGetOffset(da, &ox, &oy, &oz, &Mo, &No, &Po);
348: DMDASetOffset(*nda, ox, oy, oz, Mo, No, Po);
350: /* allow for getting a reduced DA corresponding to a coarsened DA */
351: DMGetCoarsenLevel(da, &cl);
352: DMGetRefineLevel(da, &rl);
354: (*nda)->levelup = rl;
355: (*nda)->leveldown = cl;
356: return 0;
357: }
359: /*@C
360: DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
362: Not collective
364: Input Parameter:
365: . dm - the DM
367: Output Parameter:
368: . xc - the coordinates
370: Level: intermediate
372: Not supported from Fortran
374: .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDARestoreCoordinateArray()`
375: @*/
376: PetscErrorCode DMDAGetCoordinateArray(DM dm, void *xc)
377: {
378: DM cdm;
379: Vec x;
382: DMGetCoordinates(dm, &x);
383: DMGetCoordinateDM(dm, &cdm);
384: DMDAVecGetArray(cdm, x, xc);
385: return 0;
386: }
388: /*@C
389: DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
391: Not collective
393: Input Parameters:
394: + dm - the DM
395: - xc - the coordinates
397: Level: intermediate
399: Not supported from Fortran
401: .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDAGetCoordinateArray()`
402: @*/
403: PetscErrorCode DMDARestoreCoordinateArray(DM dm, void *xc)
404: {
405: DM cdm;
406: Vec x;
409: DMGetCoordinates(dm, &x);
410: DMGetCoordinateDM(dm, &cdm);
411: DMDAVecRestoreArray(cdm, x, xc);
412: return 0;
413: }