Actual source code: dacorn.c
1: /*
2: Code for manipulating distributed regular arrays in parallel.
3: */
5: #include src/dm/da/daimpl.h
9: /*@
10: DASetCoordinates - Sets into the DA a vector that indicates the
11: coordinates of the local nodes (NOT including ghost nodes).
13: Not Collective
15: Input Parameter:
16: + da - the distributed array
17: - c - coordinate vector
19: Note:
20: The coordinates should NOT include those for all ghost points
22: Does NOT increase the reference count of this vector, so caller should NOT
23: destroy the vector.
25: Level: intermediate
27: .keywords: distributed array, get, corners, nodes, local indices, coordinates
29: .seealso: DAGetGhostCorners(), DAGetCoordinates(), DASetUniformCoordinates(). DAGetGhostCoordinates(), DAGetCoordinateDA()
30: @*/
31: PetscErrorCode DASetCoordinates(DA da,Vec c)
32: {
38: da->coordinates = c;
39: VecSetBlockSize(c,da->dim);
40: return(0);
41: }
45: /*@
46: DAGetCoordinates - Gets the node coordinates associated with a DA.
48: Not Collective
50: Input Parameter:
51: . da - the distributed array
53: Output Parameter:
54: . c - coordinate vector
56: Note:
57: Each process has only the coordinates for its local nodes (does NOT have the
58: coordinates for the ghost nodes).
60: For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
61: and (x_0,y_0,z_0,x_1,y_1,z_1...)
63: You should not destroy or keep around this vector after the DA is destroyed.
65: Level: intermediate
67: .keywords: distributed array, get, corners, nodes, local indices, coordinates
69: .seealso: DAGetGhostCorners(), DASetCoordinates(), DASetUniformCoordinates(), DAGetCoordinates(), DAGetCoordinateDA()
70: @*/
71: PetscErrorCode DAGetCoordinates(DA da,Vec *c)
72: {
74:
77: *c = da->coordinates;
78: return(0);
79: }
83: /*@
84: DAGetCoordinateDA - Gets the DA that scatters between global and local DA coordinates
86: Collective on DA
88: Input Parameter:
89: . da - the distributed array
91: Output Parameter:
92: . dac - coordinate DA
94: Note: You should not destroy or keep around this vector after the DA is destroyed.
96: Level: intermediate
98: .keywords: distributed array, get, corners, nodes, local indices, coordinates
100: .seealso: DAGetGhostCorners(), DASetCoordinates(), DASetUniformCoordinates(), DAGetCoordinates(), DAGetGhostedCoordinates()
101: @*/
102: PetscErrorCode DAGetCoordinateDA(DA da,DA *cda)
103: {
104: DAStencilType st;
106: PetscMPIInt size;
109: if (da->da_coordinates) {
110: *cda = da->da_coordinates;
111: return(0);
112: }
113: MPI_Comm_size(da->comm,&size);
114: if (da->dim == 1) {
115: if (da->w == 1) {
116: da->da_coordinates = da;
117: } else {
118: PetscInt s,m,*lc,l;
119: DAPeriodicType pt;
120: DAGetInfo(da,0,&m,0,0,0,0,0,0,&s,&pt,0);
121: DAGetCorners(da,0,0,0,&l,0,0);
122: PetscMalloc(size*sizeof(PetscInt),&lc);
123: MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,da->comm);
124: DACreate1d(da->comm,pt,m,1,s,lc,&da->da_coordinates);
125: PetscFree(lc);
126: }
127: } else if (da->dim == 2) {
128: DAGetInfo(da,0,0,0,0,0,0,0,0,0,0,&st);
129: if (da->w == 2 && st == DA_STENCIL_BOX) {
130: da->da_coordinates = da;
131: } else {
132: PetscInt i,s,m,*lc,*ld,l,k,n,M,N;
133: DAPeriodicType pt;
134: DAGetInfo(da,0,&m,&n,0,&M,&N,0,0,&s,&pt,0);
135: DAGetCorners(da,0,0,0,&l,&k,0);
136: PetscMalloc(size*sizeof(PetscInt),&lc);
137: PetscMalloc(size*sizeof(PetscInt),&ld);
138: /* only first M values in lc matter */
139: MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,da->comm);
140: /* every Mth value in ld matters */
141: MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,da->comm);
142: for ( i=0; i<N; i++) {
143: ld[i] = ld[M*i];
144: }
145: DACreate2d(da->comm,pt,DA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,&da->da_coordinates);
146: PetscFree(lc);
147: PetscFree(ld);
148: }
149: } else if (da->dim == 3) {
150: DAGetInfo(da,0,0,0,0,0,0,0,0,0,0,&st);
151: if (da->w == 3 && st == DA_STENCIL_BOX) {
152: da->da_coordinates = da;
153: } else {
154: PetscInt i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p;
155: DAPeriodicType pt;
156: DAGetInfo(da,0,&m,&n,&p,&M,&N,&P,0,&s,&pt,0);
157: DAGetCorners(da,0,0,0,&l,&k,&q);
158: PetscMalloc(size*sizeof(PetscInt),&lc);
159: PetscMalloc(size*sizeof(PetscInt),&ld);
160: PetscMalloc(size*sizeof(PetscInt),&le);
161: /* only first M values in lc matter */
162: MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,da->comm);
163: /* every Mth value in ld matters */
164: MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,da->comm);
165: for ( i=0; i<N; i++) {
166: ld[i] = ld[M*i];
167: }
168: MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,da->comm);
169: for ( i=0; i<P; i++) {
170: le[i] = le[M*N*i];
171: }
172: DACreate3d(da->comm,pt,DA_STENCIL_BOX,m,n,p,M,N,P,3,s,lc,ld,le,&da->da_coordinates);
173: PetscFree(lc);
174: PetscFree(ld);
175: PetscFree(le);
176: }
177: }
178: *cda = da->da_coordinates;
179: return(0);
180: }
185: /*@
186: DAGetGhostedCoordinates - Gets the node coordinates associated with a DA.
188: Collective on DA the first time it is called
190: Input Parameter:
191: . da - the distributed array
193: Output Parameter:
194: . c - coordinate vector
196: Note:
197: Each process has only the coordinates for its local AND ghost nodes
199: For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
200: and (x_0,y_0,z_0,x_1,y_1,z_1...)
202: You should not destroy or keep around this vector after the DA is destroyed.
204: Level: intermediate
206: .keywords: distributed array, get, corners, nodes, local indices, coordinates
208: .seealso: DAGetGhostCorners(), DASetCoordinates(), DASetUniformCoordinates(), DAGetCoordinates(), DAGetCoordinateDA()
209: @*/
210: PetscErrorCode DAGetGhostedCoordinates(DA da,Vec *c)
211: {
213:
216: if (!da->coordinates) SETERRQ(PETSC_ERR_ORDER,"You must call DASetCoordinates() before this call");
217: if (!da->ghosted_coordinates) {
218: DA dac;
220: DAGetCoordinateDA(da,&dac);
221: DACreateLocalVector(dac,&da->ghosted_coordinates);
222: if (dac == da) {PetscObjectDereference((PetscObject)dac);}
223: DAGlobalToLocalBegin(dac,da->coordinates,INSERT_VALUES,da->ghosted_coordinates);
224: DAGlobalToLocalEnd(dac,da->coordinates,INSERT_VALUES,da->ghosted_coordinates);
225: }
226: *c = da->ghosted_coordinates;
227: return(0);
228: }
232: /*@C
233: DASetFieldName - Sets the names of individual field components in multicomponent
234: vectors associated with a DA.
236: Not Collective
238: Input Parameters:
239: + da - the distributed array
240: . nf - field number for the DA (0, 1, ... dof-1), where dof indicates the
241: number of degrees of freedom per node within the DA
242: - names - the name of the field (component)
244: Level: intermediate
246: .keywords: distributed array, get, component name
248: .seealso: DAGetFieldName()
249: @*/
250: PetscErrorCode DASetFieldName(DA da,PetscInt nf,const char name[])
251: {
255:
257: if (nf < 0 || nf >= da->w) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
258: if (da->fieldname[nf]) {PetscFree(da->fieldname[nf]);}
259:
260: PetscStrallocpy(name,&da->fieldname[nf]);
261: return(0);
262: }
266: /*@C
267: DAGetFieldName - Gets the names of individual field components in multicomponent
268: vectors associated with a DA.
270: Not Collective
272: Input Parameter:
273: + da - the distributed array
274: - nf - field number for the DA (0, 1, ... dof-1), where dof indicates the
275: number of degrees of freedom per node within the DA
277: Output Parameter:
278: . names - the name of the field (component)
280: Level: intermediate
282: .keywords: distributed array, get, component name
284: .seealso: DASetFieldName()
285: @*/
286: PetscErrorCode DAGetFieldName(DA da,PetscInt nf,char **name)
287: {
289:
292: if (nf < 0 || nf >= da->w) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
293: *name = da->fieldname[nf];
294: return(0);
295: }
299: /*@
300: DAGetCorners - Returns the global (x,y,z) indices of the lower left
301: corner of the local region, excluding ghost points.
303: Not Collective
305: Input Parameter:
306: . da - the distributed array
308: Output Parameters:
309: + x,y,z - the corner indices (where y and z are optional; these are used
310: for 2D and 3D problems)
311: - m,n,p - widths in the corresponding directions (where n and p are optional;
312: these are used for 2D and 3D problems)
314: Note:
315: The corner information is independent of the number of degrees of
316: freedom per node set with the DACreateXX() routine. Thus the x, y, z, and
317: m, n, p can be thought of as coordinates on a logical grid, where each
318: grid point has (potentially) several degrees of freedom.
319: Any of y, z, n, and p can be passed in as PETSC_NULL if not needed.
321: Level: beginner
323: .keywords: distributed array, get, corners, nodes, local indices
325: .seealso: DAGetGhostCorners()
326: @*/
327: PetscErrorCode DAGetCorners(DA da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
328: {
329: PetscInt w;
333: /* since the xs, xe ... have all been multiplied by the number of degrees
334: of freedom per cell, w = da->w, we divide that out before returning.*/
335: w = da->w;
336: if (x) *x = da->xs/w; if(m) *m = (da->xe - da->xs)/w;
337: /* the y and z have NOT been multiplied by w */
338: if (y) *y = da->ys; if (n) *n = (da->ye - da->ys);
339: if (z) *z = da->zs; if (p) *p = (da->ze - da->zs);
340: return(0);
341: }