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++) {
28: corners[i*dim + j] = (i & (1 << j)) ? gmax[j] : gmin[j];
29: }
30: }
31: DMClone(dm,&cdm);
32: DMFieldCreateDA(cdm,dim,corners,field);
33: DMDestroy(&cdm);
34: return 0;
35: }
37: /*@C
38: DMDASetFieldName - Sets the names of individual field components in multicomponent
39: vectors associated with a DMDA.
41: Logically collective; name must contain a common value
43: Input Parameters:
44: + da - the distributed array
45: . nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
46: number of degrees of freedom per node within the DMDA
47: - names - the name of the field (component)
49: Notes:
50: It must be called after having called DMSetUp().
52: Level: intermediate
54: .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldNames(), DMSetUp()
55: @*/
56: PetscErrorCode DMDASetFieldName(DM da,PetscInt nf,const char name[])
57: {
58: DM_DA *dd = (DM_DA*)da->data;
63: PetscFree(dd->fieldname[nf]);
64: PetscStrallocpy(name,&dd->fieldname[nf]);
65: return 0;
66: }
68: /*@C
69: DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
71: Not collective; names will contain a common value
73: Input Parameter:
74: . dm - the DMDA object
76: Output Parameter:
77: . 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
79: Level: intermediate
81: Not supported from Fortran, use DMDAGetFieldName()
83: .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
84: @*/
85: PetscErrorCode DMDAGetFieldNames(DM da,const char * const **names)
86: {
87: DM_DA *dd = (DM_DA*)da->data;
89: *names = (const char * const *) dd->fieldname;
90: return 0;
91: }
93: /*@C
94: DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
96: Logically collective; names must contain a common value
98: Input Parameters:
99: + dm - the DMDA object
100: - 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
102: Notes:
103: It must be called after having called DMSetUp().
105: Level: intermediate
107: Not supported from Fortran, use DMDASetFieldName()
109: .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMSetUp()
110: @*/
111: PetscErrorCode DMDASetFieldNames(DM da,const char * const *names)
112: {
113: DM_DA *dd = (DM_DA*)da->data;
114: char **fieldname;
115: PetscInt nf = 0;
118: while (names[nf++]) {};
120: PetscStrArrayallocpy(names,&fieldname);
121: PetscStrArrayDestroy(&dd->fieldname);
122: dd->fieldname = fieldname;
123: return 0;
124: }
126: /*@C
127: DMDAGetFieldName - Gets the names of individual field components in multicomponent
128: vectors associated with a DMDA.
130: Not collective; name will contain a common value
132: Input Parameters:
133: + da - the distributed array
134: - nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
135: number of degrees of freedom per node within the DMDA
137: Output Parameter:
138: . names - the name of the field (component)
140: Notes:
141: It must be called after having called DMSetUp().
143: Level: intermediate
145: .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMSetUp()
146: @*/
147: PetscErrorCode DMDAGetFieldName(DM da,PetscInt nf,const char **name)
148: {
149: DM_DA *dd = (DM_DA*)da->data;
155: *name = dd->fieldname[nf];
156: return 0;
157: }
159: /*@C
160: DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
162: Logically collective; name must contain a common value
164: Input Parameters:
165: + dm - the DM
166: . nf - coordinate number for the DMDA (0, 1, ... dim-1),
167: - name - the name of the coordinate
169: Notes:
170: It must be called after having called DMSetUp().
172: Level: intermediate
174: Not supported from Fortran
176: .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
177: @*/
178: PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
179: {
180: DM_DA *dd = (DM_DA*)dm->data;
185: PetscFree(dd->coordinatename[nf]);
186: PetscStrallocpy(name,&dd->coordinatename[nf]);
187: return 0;
188: }
190: /*@C
191: DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
193: Not collective; name will contain a common value
195: Input Parameters:
196: + dm - the DM
197: - nf - number for the DMDA (0, 1, ... dim-1)
199: Output Parameter:
200: . names - the name of the coordinate direction
202: Notes:
203: It must be called after having called DMSetUp().
205: Level: intermediate
207: Not supported from Fortran
209: .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
210: @*/
211: PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
212: {
213: DM_DA *dd = (DM_DA*)dm->data;
219: *name = dd->coordinatename[nf];
220: return 0;
221: }
223: /*@C
224: DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
225: corner and size of the local region, excluding ghost points.
227: Not collective
229: Input Parameter:
230: . da - the distributed array
232: Output Parameters:
233: + x - the corner index for the first dimension
234: . y - the corner index for the second dimension (only used in 2D and 3D problems)
235: . z - the corner index for the third dimension (only used in 3D problems)
236: . m - the width in the first dimension
237: . n - the width in the second dimension (only used in 2D and 3D problems)
238: - p - the width in the third dimension (only used in 3D problems)
240: Note:
241: The corner information is independent of the number of degrees of
242: freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
243: m, n, p can be thought of as coordinates on a logical grid, where each
244: grid point has (potentially) several degrees of freedom.
245: Any of y, z, n, and p can be passed in as NULL if not needed.
247: Level: beginner
249: .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges(), DMStagGetCorners()
250: @*/
251: PetscErrorCode DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
252: {
253: PetscInt w;
254: DM_DA *dd = (DM_DA*)da->data;
257: /* since the xs, xe ... have all been multiplied by the number of degrees
258: of freedom per cell, w = dd->w, we divide that out before returning.*/
259: w = dd->w;
260: if (x) *x = dd->xs/w + dd->xo;
261: /* the y and z have NOT been multiplied by w */
262: if (y) *y = dd->ys + dd->yo;
263: if (z) *z = dd->zs + dd->zo;
264: if (m) *m = (dd->xe - dd->xs)/w;
265: if (n) *n = (dd->ye - dd->ys);
266: if (p) *p = (dd->ze - dd->zs);
267: return 0;
268: }
270: PetscErrorCode DMGetLocalBoundingIndices_DMDA(DM dm, PetscReal lmin[], PetscReal lmax[])
271: {
272: DMDALocalInfo info;
274: DMDAGetLocalInfo(dm, &info);
275: lmin[0] = info.xs;
276: lmin[1] = info.ys;
277: lmin[2] = info.zs;
278: lmax[0] = info.xs + info.xm-1;
279: lmax[1] = info.ys + info.ym-1;
280: lmax[2] = info.zs + info.zm-1;
281: return 0;
282: }
284: /*@
285: DMDAGetReducedDMDA - Deprecated; use DMDACreateCompatibleDMDA()
287: Level: deprecated
288: @*/
289: PetscErrorCode DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
290: {
291: DMDACreateCompatibleDMDA(da,nfields,nda);
292: return 0;
293: }
295: /*@
296: DMDACreateCompatibleDMDA - Creates a DMDA with the same layout but with fewer or more fields
298: Collective
300: Input Parameters:
301: + da - the distributed array
302: - nfields - number of fields in new DMDA
304: Output Parameter:
305: . nda - the new DMDA
307: Level: intermediate
309: .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates(), DMStagCreateCompatibleDMStag()
310: @*/
311: PetscErrorCode DMDACreateCompatibleDMDA(DM da,PetscInt nfields,DM *nda)
312: {
313: DM_DA *dd = (DM_DA*)da->data;
314: PetscInt s,m,n,p,M,N,P,dim,Mo,No,Po;
315: const PetscInt *lx,*ly,*lz;
316: DMBoundaryType bx,by,bz;
317: DMDAStencilType stencil_type;
318: PetscInt ox,oy,oz;
319: PetscInt cl,rl;
321: dim = da->dim;
322: M = dd->M;
323: N = dd->N;
324: P = dd->P;
325: m = dd->m;
326: n = dd->n;
327: p = dd->p;
328: s = dd->s;
329: bx = dd->bx;
330: by = dd->by;
331: bz = dd->bz;
333: stencil_type = dd->stencil_type;
335: DMDAGetOwnershipRanges(da,&lx,&ly,&lz);
336: if (dim == 1) {
337: DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);
338: } else if (dim == 2) {
339: DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);
340: } else if (dim == 3) {
341: DMDACreate3d(PetscObjectComm((PetscObject)da),bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);
342: }
343: DMSetUp(*nda);
344: if (da->coordinates) {
345: PetscObjectReference((PetscObject)da->coordinates);
346: (*nda)->coordinates = da->coordinates;
347: }
349: /* allow for getting a reduced DA corresponding to a domain decomposition */
350: DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);
351: DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);
353: /* allow for getting a reduced DA corresponding to a coarsened DA */
354: DMGetCoarsenLevel(da,&cl);
355: DMGetRefineLevel(da,&rl);
357: (*nda)->levelup = rl;
358: (*nda)->leveldown = cl;
359: return 0;
360: }
362: /*@C
363: DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
365: Not collective
367: Input Parameter:
368: . dm - the DM
370: Output Parameter:
371: . xc - the coordinates
373: Level: intermediate
375: Not supported from Fortran
377: .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
378: @*/
379: PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
380: {
381: DM cdm;
382: Vec x;
385: DMGetCoordinates(dm,&x);
386: DMGetCoordinateDM(dm,&cdm);
387: DMDAVecGetArray(cdm,x,xc);
388: return 0;
389: }
391: /*@C
392: DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
394: Not collective
396: Input Parameters:
397: + dm - the DM
398: - xc - the coordinates
400: Level: intermediate
402: Not supported from Fortran
404: .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
405: @*/
406: PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
407: {
408: DM cdm;
409: Vec x;
412: DMGetCoordinates(dm,&x);
413: DMGetCoordinateDM(dm,&cdm);
414: DMDAVecRestoreArray(cdm,x,xc);
415: return 0;
416: }