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: }