Actual source code: daview.c

  1: #define PETSCDM_DLL

  3: /*
  4:   Code for manipulating distributed regular arrays in parallel.
  5: */

 7:  #include private/daimpl.h
  8: #if defined(PETSC_HAVE_PNETCDF)
 10: #include "pnetcdf.h"
 12: #endif


 15: #if defined(PETSC_HAVE_MATLAB_ENGINE)
 16: #include "mat.h"   /* Matlab include file */

 20: PetscErrorCode DAView_Matlab(DA da,PetscViewer viewer)
 21: {
 23:   PetscMPIInt    rank;
 24:   PetscInt       dim,m,n,p,dof,swidth;
 25:   DAStencilType  stencil;
 26:   DAPeriodicType periodic;
 27:   mxArray        *mx;
 28:   const char     *fnames[] = {"dimension","m","n","p","dof","stencil_width","periodicity","stencil_type"};

 31:   MPI_Comm_rank(((PetscObject)da)->comm,&rank);
 32:   if (!rank) {
 33:     DAGetInfo(da,&dim,&m,&n,&p,0,0,0,&dof,&swidth,&periodic,&stencil);
 34:     mx = mxCreateStructMatrix(1,1,8,(const char **)fnames);
 35:     if (!mx) SETERRQ(PETSC_ERR_LIB,"Unable to generate Matlab struct array to hold DA informations");
 36:     mxSetFieldByNumber(mx,0,0,mxCreateDoubleScalar((double)dim));
 37:     mxSetFieldByNumber(mx,0,1,mxCreateDoubleScalar((double)m));
 38:     mxSetFieldByNumber(mx,0,2,mxCreateDoubleScalar((double)n));
 39:     mxSetFieldByNumber(mx,0,3,mxCreateDoubleScalar((double)p));
 40:     mxSetFieldByNumber(mx,0,4,mxCreateDoubleScalar((double)dof));
 41:     mxSetFieldByNumber(mx,0,5,mxCreateDoubleScalar((double)swidth));
 42:     mxSetFieldByNumber(mx,0,6,mxCreateDoubleScalar((double)periodic));
 43:     mxSetFieldByNumber(mx,0,7,mxCreateDoubleScalar((double)stencil));
 44:     PetscObjectName((PetscObject)da);
 45:     PetscViewerMatlabPutVariable(viewer,((PetscObject)da)->name,mx);
 46:   }
 47:   return(0);
 48: }
 49: #endif

 53: PetscErrorCode DAView_Binary(DA da,PetscViewer viewer)
 54: {
 56:   PetscMPIInt    rank;
 57:   PetscInt       i,dim,m,n,p,dof,swidth,M,N,P;
 58:   size_t         j,len;
 59:   DAStencilType  stencil;
 60:   DAPeriodicType periodic;
 61:   MPI_Comm       comm;

 64:   PetscObjectGetComm((PetscObject)da,&comm);

 66:   DAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&dof,&swidth,&periodic,&stencil);
 67:   MPI_Comm_rank(comm,&rank);
 68:   if (!rank) {
 69:     FILE *file;

 71:     PetscViewerBinaryGetInfoPointer(viewer,&file);
 72:     if (file) {
 73:       char fieldname[PETSC_MAX_PATH_LEN];

 75:       PetscFPrintf(PETSC_COMM_SELF,file,"-daload_info %D,%D,%D,%D,%D,%D,%D,%D\n",dim,m,n,p,dof,swidth,stencil,periodic);
 76:       for (i=0; i<dof; i++) {
 77:         if (da->fieldname[i]) {
 78:           PetscStrncpy(fieldname,da->fieldname[i],PETSC_MAX_PATH_LEN);
 79:           PetscStrlen(fieldname,&len);
 80:           len  = PetscMin(PETSC_MAX_PATH_LEN,len);
 81:           for (j=0; j<len; j++) {
 82:             if (fieldname[j] == ' ') fieldname[j] = '_';
 83:           }
 84:           PetscFPrintf(PETSC_COMM_SELF,file,"-daload_fieldname_%D %s\n",i,fieldname);
 85:         }
 86:       }
 87:       if (da->coordinates) { /* save the DA's coordinates */
 88:         PetscFPrintf(PETSC_COMM_SELF,file,"-daload_coordinates\n");
 89:       }
 90:     }
 91:   }

 93:   /* save the coordinates if they exist to disk (in the natural ordering) */
 94:   if (da->coordinates) {
 95:     DA             dac;
 96:     const PetscInt *lx,*ly,*lz;
 97:     Vec            natural;

 99:     /* create the appropriate DA to map to natural ordering */
100:     DAGetOwnershipRanges(da,&lx,&ly,&lz);
101:     if (dim == 1) {
102:       DACreate1d(comm,DA_NONPERIODIC,m,dim,0,lx,&dac);
103:     } else if (dim == 2) {
104:       DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,m,n,M,N,dim,0,lx,ly,&dac);
105:     } else if (dim == 3) {
106:       DACreate3d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,m,n,p,M,N,P,dim,0,lx,ly,lz,&dac);
107:     } else {
108:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Dimension is not 1 2 or 3: %D\n",dim);
109:     }
110:     DACreateNaturalVector(dac,&natural);
111:     PetscObjectSetOptionsPrefix((PetscObject)natural,"coor_");
112:     DAGlobalToNaturalBegin(dac,da->coordinates,INSERT_VALUES,natural);
113:     DAGlobalToNaturalEnd(dac,da->coordinates,INSERT_VALUES,natural);
114:     VecView(natural,viewer);
115:     VecDestroy(natural);
116:     DADestroy(dac);
117:   }

119:   return(0);
120: }

124: PetscErrorCode DAView_VTK(DA da, PetscViewer viewer)
125: {
126:   PetscInt       dim, dof, M = 0, N = 0, P = 0;

130:   DAGetInfo(da, &dim, &M, &N, &P, PETSC_NULL, PETSC_NULL, PETSC_NULL, &dof, PETSC_NULL, PETSC_NULL, PETSC_NULL);
131:   /* if (dim != 3) {SETERRQ(PETSC_ERR_SUP, "VTK output only works for three dimensional DAs.");} */
132:   if (!da->coordinates) {SETERRQ(PETSC_ERR_SUP, "VTK output requires DA coordinates.");}
133:   /* Write Header */
134:   PetscViewerASCIIPrintf(viewer,"# vtk DataFile Version 2.0\n");
135:   PetscViewerASCIIPrintf(viewer,"Structured Mesh Example\n");
136:   PetscViewerASCIIPrintf(viewer,"ASCII\n");
137:   PetscViewerASCIIPrintf(viewer,"DATASET STRUCTURED_GRID\n");
138:   PetscViewerASCIIPrintf(viewer,"DIMENSIONS %d %d %d\n", M, N, P);
139:   PetscViewerASCIIPrintf(viewer,"POINTS %d double\n", M*N*P);
140:   if (da->coordinates) {
141:     DA  dac;
142:     Vec natural;

144:     DAGetCoordinateDA(da, &dac);
145:     DACreateNaturalVector(dac, &natural);
146:     PetscObjectSetOptionsPrefix((PetscObject) natural, "coor_");
147:     DAGlobalToNaturalBegin(dac, da->coordinates, INSERT_VALUES, natural);
148:     DAGlobalToNaturalEnd(dac, da->coordinates, INSERT_VALUES, natural);
149:     PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_VTK_COORDS);
150:     VecView(natural, viewer);
151:     PetscViewerPopFormat(viewer);
152:     VecDestroy(natural);
153:     DADestroy(dac);
154:   }
155:   return(0);
156: }

160: /*@C
161:    DAView - Visualizes a distributed array object.

163:    Collective on DA

165:    Input Parameters:
166: +  da - the distributed array
167: -  ptr - an optional visualization context

169:    Notes:
170:    The available visualization contexts include
171: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
172: .     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
173:          output where only the first processor opens
174:          the file.  All other processors send their 
175:          data to the first processor to print. 
176: -     PETSC_VIEWER_DRAW_WORLD - to default window

178:    The user can open alternative visualization contexts with
179: +    PetscViewerASCIIOpen() - Outputs vector to a specified file
180: -    PetscViewerDrawOpen() - Outputs vector to an X window display

182:    Default Output Format:
183:   (for 3d arrays)
184: .vb
185:    Processor [proc] M  N  P  m  n  p  w  s
186:    X range: xs xe, Y range: ys, ye, Z range: zs, ze

188:    where
189:       M,N,P - global dimension in each direction of the array
190:       m,n,p - corresponding number of procs in each dimension 
191:       w - number of degrees of freedom per node
192:       s - stencil width
193:       xs, xe - internal local starting/ending grid points
194:                in x-direction, (augmented to handle multiple 
195:                degrees of freedom per node)
196:       ys, ye - local starting/ending grid points in y-direction
197:       zs, ze - local starting/ending grid points in z-direction
198: .ve

200:    Options Database Key:
201: .  -da_view - Calls DAView() at the conclusion of DACreate1d(),
202:               DACreate2d(), and DACreate3d()

204:    Level: beginner

206:    Notes:
207:    Use DAGetCorners() and DAGetGhostCorners() to get the starting
208:    and ending grid points (ghost points) in each direction.

210:    When drawing the DA grid it only draws the logical grid and does not
211:    respect the grid coordinates set with DASetCoordinates()

213: .keywords: distributed array, view, visualize

215: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), DAGetInfo(), DAGetCorners(),
216:           DAGetGhostCorners(), DAGetOwnershipRanges(), DACreate(), DACreate1d(), DACreate2d(), DACreate3d()
217: @*/
218: PetscErrorCode  DAView(DA da,PetscViewer viewer)
219: {
221:   PetscInt       i,dof = da->w;
222:   PetscTruth     iascii,fieldsnamed = PETSC_FALSE,isbinary;
223: #if defined(PETSC_HAVE_MATLAB_ENGINE)
224:   PetscTruth     ismatlab;
225: #endif

229:   if (!viewer) {
230:     PetscViewerASCIIGetStdout(((PetscObject)da)->comm,&viewer);
231:   }

234:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
235:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);
236: #if defined(PETSC_HAVE_MATLAB_ENGINE)
237:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_MATLAB,&ismatlab);
238: #endif
239:   if (iascii) {
240:     PetscViewerFormat format;

242:     PetscViewerGetFormat(viewer, &format);
243:     if (format == PETSC_VIEWER_ASCII_VTK || format == PETSC_VIEWER_ASCII_VTK_CELL) {
244:       DAView_VTK(da, viewer);
245:     } else {
246:       for (i=0; i<dof; i++) {
247:         if (da->fieldname[i]) {
248:           fieldsnamed = PETSC_TRUE;
249:           break;
250:         }
251:       }
252:       if (fieldsnamed) {
253:         PetscViewerASCIIPrintf(viewer,"FieldNames: ");
254:         for (i=0; i<dof; i++) {
255:           if (da->fieldname[i]) {
256:             PetscViewerASCIIPrintf(viewer,"%s ",da->fieldname[i]);
257:           } else {
258:             PetscViewerASCIIPrintf(viewer,"(not named) ");
259:           }
260:         }
261:         PetscViewerASCIIPrintf(viewer,"\n");
262:       }
263:     }
264:   }
265:   if (isbinary){
266:     DAView_Binary(da,viewer);
267: #if defined(PETSC_HAVE_MATLAB_ENGINE)
268:   } else if (ismatlab) {
269:     DAView_Matlab(da,viewer);
270: #endif
271:   } else {
272:     (*da->ops->view)(da,viewer);
273:   }
274:   return(0);
275: }

279: /*@C
280:    DAGetInfo - Gets information about a given distributed array.

282:    Not Collective

284:    Input Parameter:
285: .  da - the distributed array

287:    Output Parameters:
288: +  dim     - dimension of the distributed array (1, 2, or 3)
289: .  M, N, P - global dimension in each direction of the array
290: .  m, n, p - corresponding number of procs in each dimension
291: .  dof     - number of degrees of freedom per node
292: .  s       - stencil width
293: .  wrap    - type of periodicity, one of DA_NONPERIODIC, DA_XPERIODIC, DA_YPERIODIC, 
294:              DA_XYPERIODIC, DA_XYZPERIODIC, DA_XZPERIODIC, DA_YZPERIODIC,DA_ZPERIODIC
295: -  st      - stencil type, either DA_STENCIL_STAR or DA_STENCIL_BOX

297:    Level: beginner
298:   
299:    Note:
300:    Use PETSC_NULL (PETSC_NULL_INTEGER in Fortran) in place of any output parameter that is not of interest.

302: .keywords: distributed array, get, information

304: .seealso: DAView(), DAGetCorners(), DAGetLocalInfo()
305: @*/
306: PetscErrorCode  DAGetInfo(DA da,PetscInt *dim,PetscInt *M,PetscInt *N,PetscInt *P,PetscInt *m,PetscInt *n,PetscInt *p,PetscInt *dof,PetscInt *s,DAPeriodicType *wrap,DAStencilType *st)
307: {
310:   if (dim)  *dim  = da->dim;
311:   if (M)    *M    = da->M;
312:   if (N)    *N    = da->N;
313:   if (P)    *P    = da->P;
314:   if (m)    *m    = da->m;
315:   if (n)    *n    = da->n;
316:   if (p)    *p    = da->p;
317:   if (dof)  *dof  = da->w;
318:   if (s)    *s    = da->s;
319:   if (wrap) *wrap = da->wrap;
320:   if (st)   *st   = da->stencil_type;
321:   return(0);
322: }

326: /*@C
327:    DAGetLocalInfo - Gets information about a given distributed array and this processors location in it

329:    Not Collective

331:    Input Parameter:
332: .  da - the distributed array

334:    Output Parameters:
335: .  dainfo - structure containing the information

337:    Level: beginner
338:   
339: .keywords: distributed array, get, information

341: .seealso: DAGetInfo(), DAGetCorners()
342: @*/
343: PetscErrorCode  DAGetLocalInfo(DA da,DALocalInfo *info)
344: {
345:   PetscInt w;

350:   info->da   = da;
351:   info->dim  = da->dim;
352:   info->mx   = da->M;
353:   info->my   = da->N;
354:   info->mz   = da->P;
355:   info->dof  = da->w;
356:   info->sw   = da->s;
357:   info->pt   = da->wrap;
358:   info->st   = da->stencil_type;

360:   /* since the xs, xe ... have all been multiplied by the number of degrees 
361:      of freedom per cell, w = da->w, we divide that out before returning.*/
362:   w = da->w;
363:   info->xs = da->xs/w;
364:   info->xm = (da->xe - da->xs)/w;
365:   /* the y and z have NOT been multiplied by w */
366:   info->ys = da->ys;
367:   info->ym = (da->ye - da->ys);
368:   info->zs = da->zs;
369:   info->zm = (da->ze - da->zs);

371:   info->gxs = da->Xs/w;
372:   info->gxm = (da->Xe - da->Xs)/w;
373:   /* the y and z have NOT been multiplied by w */
374:   info->gys = da->Ys;
375:   info->gym = (da->Ye - da->Ys);
376:   info->gzs = da->Zs;
377:   info->gzm = (da->Ze - da->Zs);
378:   return(0);
379: }