Actual source code: daview.c

  1: /*
  2:   Code for manipulating distributed regular arrays in parallel.
  3: */

 5:  #include src/dm/da/daimpl.h
  6: #if defined(PETSC_HAVE_PNETCDF)
  8: #include "pnetcdf.h"
 10: #endif


 13: #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
 14: #include "mat.h"   /* Matlab include file */

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

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

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

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

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

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

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

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

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

117:   return(0);
118: }

122: /*@C
123:    DAView - Visualizes a distributed array object.

125:    Collective on DA

127:    Input Parameters:
128: +  da - the distributed array
129: -  ptr - an optional visualization context

131:    Notes:
132:    The available visualization contexts include
133: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
134: .     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
135:          output where only the first processor opens
136:          the file.  All other processors send their 
137:          data to the first processor to print. 
138: -     PETSC_VIEWER_DRAW_WORLD - to default window

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

144:    Default Output Format:
145:   (for 3d arrays)
146: .vb
147:    Processor [proc] M  N  P  m  n  p  w  s
148:    X range: xs xe, Y range: ys, ye, Z range: zs, ze

150:    where
151:       M,N,P - global dimension in each direction of the array
152:       m,n,p - corresponding number of procs in each dimension 
153:       w - number of degrees of freedom per node
154:       s - stencil width
155:       xs, xe - internal local starting/ending grid points
156:                in x-direction, (augmented to handle multiple 
157:                degrees of freedom per node)
158:       ys, ye - local starting/ending grid points in y-direction
159:       zs, ze - local starting/ending grid points in z-direction
160: .ve

162:    Options Database Key:
163: .  -da_view - Calls DAView() at the conclusion of DACreate1d(),
164:               DACreate2d(), and DACreate3d()

166:    Level: beginner

168:    Notes:
169:    Use DAGetCorners() and DAGetGhostCorners() to get the starting
170:    and ending grid points (ghost points) in each direction.

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

175: .keywords: distributed array, view, visualize

177: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), DAGetInfo(), DAGetCorners(),
178:           DAGetGhostCorners()
179: @*/
180: PetscErrorCode DAView(DA da,PetscViewer viewer)
181: {
183:   PetscInt i,dof = da->w;
184:   PetscTruth iascii,fieldsnamed = PETSC_FALSE,isbinary;
185: #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
186:   PetscTruth ismatlab;
187: #endif

191:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(da->comm);

194:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
195:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);
196: #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
197:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_MATLAB,&ismatlab);
198: #endif
199:   if (iascii) {
200:     for (i=0; i<dof; i++) {
201:       if (da->fieldname[i]) {
202:         fieldsnamed = PETSC_TRUE;
203:         break;
204:       }
205:     }
206:     if (fieldsnamed) {
207:       PetscViewerASCIIPrintf(viewer,"FieldNames: ");
208:       for (i=0; i<dof; i++) {
209:         if (da->fieldname[i]) {
210:           PetscViewerASCIIPrintf(viewer,"%s ",da->fieldname[i]);
211:         } else {
212:           PetscViewerASCIIPrintf(viewer,"(not named) ");
213:         }
214:       }
215:       PetscViewerASCIIPrintf(viewer,"\n");
216:     }
217:   }
218:   if (isbinary){
219:     DAView_Binary(da,viewer);
220: #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
221:   } else if (ismatlab) {
222:     DAView_Matlab(da,viewer);
223: #endif
224:   } else {
225:     (*da->ops->view)(da,viewer);
226:   }
227:   return(0);
228: }

232: /*@C
233:    DAGetInfo - Gets information about a given distributed array.

235:    Not Collective

237:    Input Parameter:
238: .  da - the distributed array

240:    Output Parameters:
241: +  dim     - dimension of the distributed array (1, 2, or 3)
242: .  M, N, P - global dimension in each direction of the array
243: .  m, n, p - corresponding number of procs in each dimension
244: .  dof     - number of degrees of freedom per node
245: .  s       - stencil width
246: .  wrap    - type of periodicity, on of DA_NONPERIODIC, DA_XPERIODIC, DA_YPERIODIC, 
247:              DA_XYPERIODIC, DA_XYZPERIODIC, DA_XZPERIODIC, DA_YZPERIODIC,DA_ZPERIODIC
248: -  st      - stencil type, either DA_STENCIL_STAR or DA_STENCIL_BOX

250:    Level: beginner
251:   
252:    Note:
253:    Use PETSC_NULL (PETSC_NULL_INTEGER in Fortran) in place of any output parameter that is not of interest.

255: .keywords: distributed array, get, information

257: .seealso: DAView(), DAGetCorners(), DAGetLocalInfo()
258: @*/
259: 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)
260: {
263:   if (dim)  *dim  = da->dim;
264:   if (M)    *M    = da->M;
265:   if (N)    *N    = da->N;
266:   if (P)    *P    = da->P;
267:   if (m)    *m    = da->m;
268:   if (n)    *n    = da->n;
269:   if (p)    *p    = da->p;
270:   if (dof)  *dof  = da->w;
271:   if (s)    *s    = da->s;
272:   if (wrap) *wrap = da->wrap;
273:   if (st)   *st   = da->stencil_type;
274:   return(0);
275: }

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

282:    Not Collective

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

287:    Output Parameters:
288: .  dainfo - structure containing the information

290:    Level: beginner
291:   
292: .keywords: distributed array, get, information

294: .seealso: DAGetInfo(), DAGetCorners()
295: @*/
296: PetscErrorCode DAGetLocalInfo(DA da,DALocalInfo *info)
297: {
298:   PetscInt w;

303:   info->da   = da;
304:   info->dim  = da->dim;
305:   info->mx   = da->M;
306:   info->my   = da->N;
307:   info->mz   = da->P;
308:   info->dof  = da->w;
309:   info->sw   = da->s;
310:   info->pt   = da->wrap;
311:   info->st   = da->stencil_type;

313:   /* since the xs, xe ... have all been multiplied by the number of degrees 
314:      of freedom per cell, w = da->w, we divide that out before returning.*/
315:   w = da->w;
316:   info->xs = da->xs/w;
317:   info->xm = (da->xe - da->xs)/w;
318:   /* the y and z have NOT been multiplied by w */
319:   info->ys = da->ys;
320:   info->ym = (da->ye - da->ys);
321:   info->zs = da->zs;
322:   info->zm = (da->ze - da->zs);

324:   info->gxs = da->Xs/w;
325:   info->gxm = (da->Xe - da->Xs)/w;
326:   /* the y and z have NOT been multiplied by w */
327:   info->gys = da->Ys;
328:   info->gym = (da->Ye - da->Ys);
329:   info->gzs = da->Zs;
330:   info->gzm = (da->Ze - da->Zs);
331:   return(0);
332: }