Actual source code: daview.c

  1: /*$Id: daview.c,v 1.50 2001/06/21 21:19:09 bsmith Exp $*/
  2: 
  3: /*
  4:   Code for manipulating distributed regular arrays in parallel.
  5: */

 7:  #include src/dm/da/daimpl.h
  8: #if defined(PETSC_HAVE_PNETCDF)
  9: EXTERN_C_BEGIN
 10: #include "pnetcdf.h"
 11: EXTERN_C_END
 12: #endif


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

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

 30:   MPI_Comm_rank(da->comm,&rank);
 31:   if (rank) return(0);

 33:   DAGetInfo(da,&dim,&m,&n,&p,0,0,0,&dof,&swidth,&periodic,&stencil);

 35:   mx = mxCreateStructMatrix(1,1,8,(const char **)fnames);
 36:   if (!mx) SETERRQ(1,"Unable to generate Matlab struct array to hold DA informations");
 37:   mxSetFieldByNumber(mx,0,0,mxCreateDoubleScalar((double)dim));
 38:   mxSetFieldByNumber(mx,0,1,mxCreateDoubleScalar((double)m));
 39:   mxSetFieldByNumber(mx,0,2,mxCreateDoubleScalar((double)n));
 40:   mxSetFieldByNumber(mx,0,3,mxCreateDoubleScalar((double)p));
 41:   mxSetFieldByNumber(mx,0,4,mxCreateDoubleScalar((double)dof));
 42:   mxSetFieldByNumber(mx,0,5,mxCreateDoubleScalar((double)swidth));
 43:   mxSetFieldByNumber(mx,0,6,mxCreateDoubleScalar((double)periodic));
 44:   mxSetFieldByNumber(mx,0,7,mxCreateDoubleScalar((double)stencil));

 46:   PetscObjectName((PetscObject)da);
 47:   PetscViewerMatlabPutVariable(viewer,da->name,mx);
 48:   return(0);
 49: }
 50: #endif

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

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

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

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

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

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

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

118:   return(0);
119: }

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

126:    Collective on DA

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

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

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

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

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

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

167:    Level: beginner

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

173: .keywords: distributed array, view, visualize

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

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

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

229: /*@C
230:    DAGetInfo - Gets information about a given distributed array.

232:    Not Collective

234:    Input Parameter:
235: .  da - the distributed array

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

247:    Level: beginner
248:   
249:    Note:
250:    Use PETSC_NULL (PETSC_NULL_INTEGER in Fortran) in place of any output parameter that is not of interest.

252: .keywords: distributed array, get, information

254: .seealso: DAView(), DAGetCorners(), DAGetLocalInfo()
255: @*/
256: int DAGetInfo(DA da,int *dim,int *M,int *N,int *P,int *m,int *n,int *p,int *dof,int *s,DAPeriodicType *wrap,DAStencilType *st)
257: {
260:   if (dim)  *dim  = da->dim;
261:   if (M)    *M    = da->M;
262:   if (N)    *N    = da->N;
263:   if (P)    *P    = da->P;
264:   if (m)    *m    = da->m;
265:   if (n)    *n    = da->n;
266:   if (p)    *p    = da->p;
267:   if (dof)  *dof  = da->w;
268:   if (s)    *s    = da->s;
269:   if (wrap) *wrap = da->wrap;
270:   if (st)   *st   = da->stencil_type;
271:   return(0);
272: }

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

279:    Not Collective

281:    Input Parameter:
282: .  da - the distributed array

284:    Output Parameters:
285: .  dainfo - structure containing the information

287:    Level: beginner
288:   
289: .keywords: distributed array, get, information

291: .seealso: DAGetInfo(), DAGetCorners()
292: @*/
293: int DAGetLocalInfo(DA da,DALocalInfo *info)
294: {
295:   int w;

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

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

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