Actual source code: gr2.c

  1: /*$Id: gr2.c,v 1.47 2001/08/07 03:04:39 balay Exp $*/

  3: /* 
  4:    Plots vectors obtained with DACreate2d()
  5: */

 7:  #include src/dm/da/daimpl.h
 8:  #include vecimpl.h

 10: #if defined(PETSC_HAVE_PNETCDF)
 11: EXTERN_C_BEGIN
 12: #include "pnetcdf.h"
 13: EXTERN_C_END
 14: #endif


 17: /*
 18:         The data that is passed into the graphics callback
 19: */
 20: typedef struct {
 21:   int          m,n,step,k;
 22:   PetscReal    min,max,scale;
 23:   PetscScalar  *xy,*v;
 24:   PetscTruth   showgrid;
 25: } ZoomCtx;

 27: /*
 28:        This does the drawing for one particular field 
 29:     in one particular set of coordinates. It is a callback
 30:     called from PetscDrawZoom()
 31: */
 34: int VecView_MPI_Draw_DA2d_Zoom(PetscDraw draw,void *ctx)
 35: {
 36:   ZoomCtx     *zctx = (ZoomCtx*)ctx;
 37:   int         ierr,m,n,i,j,k,step,id,c1,c2,c3,c4;
 38:   PetscReal   s,min,x1,x2,x3,x4,y_1,y2,y3,y4;
 39:   PetscScalar *v,*xy;

 42:   m    = zctx->m;
 43:   n    = zctx->n;
 44:   step = zctx->step;
 45:   k    = zctx->k;
 46:   v    = zctx->v;
 47:   xy   = zctx->xy;
 48:   s    = zctx->scale;
 49:   min  = zctx->min;
 50: 
 51:   /* PetscDraw the contour plot patch */
 52:   for (j=0; j<n-1; j++) {
 53:     for (i=0; i<m-1; i++) {
 54: #if !defined(PETSC_USE_COMPLEX)
 55:       id = i+j*m;    x1 = xy[2*id];y_1 = xy[2*id+1];c1 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
 56:       id = i+j*m+1;  x2 = xy[2*id];y2  = y_1;       c2 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
 57:       id = i+j*m+1+m;x3 = x2;      y3  = xy[2*id+1];c3 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
 58:       id = i+j*m+m;  x4 = x1;      y4  = y3;        c4 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
 59: #else
 60:       id = i+j*m;    x1 = PetscRealPart(xy[2*id]);y_1 = PetscRealPart(xy[2*id+1]);c1 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
 61:       id = i+j*m+1;  x2 = PetscRealPart(xy[2*id]);y2  = y_1;       c2 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
 62:       id = i+j*m+1+m;x3 = x2;      y3  = PetscRealPart(xy[2*id+1]);c3 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
 63:       id = i+j*m+m;  x4 = x1;      y4  = y3;        c4 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
 64: #endif
 65:       PetscDrawTriangle(draw,x1,y_1,x2,y2,x3,y3,c1,c2,c3);
 66:       PetscDrawTriangle(draw,x1,y_1,x3,y3,x4,y4,c1,c3,c4);
 67:       if (zctx->showgrid) {
 68:         PetscDrawLine(draw,x1,y_1,x2,y2,PETSC_DRAW_BLACK);
 69:         PetscDrawLine(draw,x2,y2,x3,y3,PETSC_DRAW_BLACK);
 70:         PetscDrawLine(draw,x3,y3,x4,y4,PETSC_DRAW_BLACK);
 71:         PetscDrawLine(draw,x4,y4,x1,y_1,PETSC_DRAW_BLACK);
 72:       }
 73:     }
 74:   }
 75:   return(0);
 76: }

 80: int VecView_MPI_Draw_DA2d(Vec xin,PetscViewer viewer)
 81: {
 82:   DA                 da,dac,dag;
 83:   int                rank,ierr,igstart,N,s,M,istart,isize,jgstart,*lx,*ly,w;
 84:   PetscReal          coors[4],ymin,ymax,xmin,xmax;
 85:   PetscDraw          draw,popup;
 86:   PetscTruth         isnull,useports;
 87:   MPI_Comm           comm;
 88:   Vec                xlocal,xcoor,xcoorl;
 89:   DAPeriodicType     periodic;
 90:   DAStencilType      st;
 91:   ZoomCtx            zctx;
 92:   PetscDrawViewPorts *ports;
 93:   PetscViewerFormat  format;

 96:   PetscViewerDrawGetDraw(viewer,0,&draw);
 97:   PetscDrawIsNull(draw,&isnull); if (isnull) return(0);

 99:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
100:   if (!da) SETERRQ(1,"Vector not generated from a DA");

102:   PetscObjectGetComm((PetscObject)xin,&comm);
103:   MPI_Comm_rank(comm,&rank);

105:   DAGetInfo(da,0,&M,&N,0,&zctx.m,&zctx.n,0,&w,&s,&periodic,&st);
106:   DAGetOwnershipRange(da,&lx,&ly,PETSC_NULL);

108:   /* 
109:         Obtain a sequential vector that is going to contain the local values plus ONE layer of 
110:      ghosted values to draw the graphics from. We also need its corresponding DA (dac) that will
111:      update the local values pluse ONE layer of ghost values. 
112:   */
113:   PetscObjectQuery((PetscObject)da,"GraphicsGhosted",(PetscObject*)&xlocal);
114:   if (!xlocal) {
115:     if (periodic != DA_NONPERIODIC || s != 1 || st != DA_STENCIL_BOX) {
116:       /* 
117:          if original da is not of stencil width one, or periodic or not a box stencil then
118:          create a special DA to handle one level of ghost points for graphics
119:       */
120:       DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,M,N,zctx.m,zctx.n,w,1,lx,ly,&dac);
121:       PetscLogInfo(da,"VecView_MPI_Draw_DA2d:Creating auxilary DA for managing graphics ghost points\n");
122:     } else {
123:       /* otherwise we can use the da we already have */
124:       dac = da;
125:     }
126:     /* create local vector for holding ghosted values used in graphics */
127:     DACreateLocalVector(dac,&xlocal);
128:     if (dac != da) {
129:       /* don't keep any public reference of this DA, is is only available through xlocal */
130:       DADestroy(dac);
131:     } else {
132:       /* remove association between xlocal and da, because below we compose in the opposite
133:          direction and if we left this connect we'd get a loop, so the objects could 
134:          never be destroyed */
135:       PetscObjectCompose((PetscObject)xlocal,"DA",0);
136:     }
137:     PetscObjectCompose((PetscObject)da,"GraphicsGhosted",(PetscObject)xlocal);
138:     PetscObjectDereference((PetscObject)xlocal);
139:   } else {
140:     if (periodic == DA_NONPERIODIC && s == 1 && st == DA_STENCIL_BOX) {
141:       dac = da;
142:     } else {
143:       PetscObjectQuery((PetscObject)xlocal,"DA",(PetscObject*)&dac);
144:     }
145:   }

147:   /*
148:       Get local (ghosted) values of vector
149:   */
150:   DAGlobalToLocalBegin(dac,xin,INSERT_VALUES,xlocal);
151:   DAGlobalToLocalEnd(dac,xin,INSERT_VALUES,xlocal);
152:   VecGetArray(xlocal,&zctx.v);

154:   /* get coordinates of nodes */
155:   DAGetCoordinates(da,&xcoor);
156:   if (!xcoor) {
157:     DASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0);
158:     DAGetCoordinates(da,&xcoor);
159:   }

161:   /*
162:       Determine the min and max  coordinates in plot 
163:   */
164:   VecStrideMin(xcoor,0,PETSC_NULL,&xmin);
165:   VecStrideMax(xcoor,0,PETSC_NULL,&xmax);
166:   VecStrideMin(xcoor,1,PETSC_NULL,&ymin);
167:   VecStrideMax(xcoor,1,PETSC_NULL,&ymax);
168:   coors[0] = xmin - .05*(xmax- xmin); coors[2] = xmax + .05*(xmax - xmin);
169:   coors[1] = ymin - .05*(ymax- ymin); coors[3] = ymax + .05*(ymax - ymin);
170:   PetscLogInfo(da,"VecView_MPI_Draw_DA2d:Preparing DA 2d contour plot coordinates %g %g %g %g\n",coors[0],coors[1],coors[2],coors[3]);

172:   /*
173:        get local ghosted version of coordinates 
174:   */
175:   PetscObjectQuery((PetscObject)da,"GraphicsCoordinateGhosted",(PetscObject*)&xcoorl);
176:   if (!xcoorl) {
177:     /* create DA to get local version of graphics */
178:     DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,M,N,zctx.m,zctx.n,2,1,lx,ly,&dag);
179:     PetscLogInfo(dag,"VecView_MPI_Draw_DA2d:Creating auxilary DA for managing graphics coordinates ghost points\n");
180:     DACreateLocalVector(dag,&xcoorl);
181:     PetscObjectCompose((PetscObject)da,"GraphicsCoordinateGhosted",(PetscObject)xcoorl);
182:     DADestroy(dag);/* dereference dag */
183:     PetscObjectDereference((PetscObject)xcoorl);
184:   } else {
185:     PetscObjectQuery((PetscObject)xcoorl,"DA",(PetscObject*)&dag);
186:   }
187:   DAGlobalToLocalBegin(dag,xcoor,INSERT_VALUES,xcoorl);
188:   DAGlobalToLocalEnd(dag,xcoor,INSERT_VALUES,xcoorl);
189:   VecGetArray(xcoorl,&zctx.xy);
190: 
191:   /*
192:         Get information about size of area each processor must do graphics for
193:   */
194:   DAGetInfo(dac,0,&M,&N,0,0,0,0,&zctx.step,0,&periodic,0);
195:   DAGetGhostCorners(dac,&igstart,&jgstart,0,&zctx.m,&zctx.n,0);
196:   DAGetCorners(dac,&istart,0,0,&isize,0,0);

198:   PetscOptionsHasName(PETSC_NULL,"-draw_contour_grid",&zctx.showgrid);

200:   PetscViewerGetFormat(viewer,&format);
201:   PetscOptionsHasName(PETSC_NULL,"-draw_ports",&useports);
202:   if (useports || format == PETSC_VIEWER_DRAW_PORTS){
203:     PetscDrawSynchronizedClear(draw);
204:     PetscDrawViewPortsCreate(draw,zctx.step,&ports);
205:   }
206:   /*
207:      Loop over each field; drawing each in a different window
208:   */
209:   for (zctx.k=0; zctx.k<zctx.step; zctx.k++) {
210:     if (useports) {
211:       PetscDrawViewPortsSet(ports,zctx.k);
212:     } else {
213:       PetscViewerDrawGetDraw(viewer,zctx.k,&draw);
214:       PetscDrawSynchronizedClear(draw);
215:     }

217:     /*
218:         Determine the min and max color in plot 
219:     */
220:     VecStrideMin(xin,zctx.k,PETSC_NULL,&zctx.min);
221:     VecStrideMax(xin,zctx.k,PETSC_NULL,&zctx.max);
222:     if (zctx.min == zctx.max) {
223:       zctx.min -= 1.e-12;
224:       zctx.max += 1.e-12;
225:     }

227:     if (!rank) {
228:       char *title;

230:       DAGetFieldName(da,zctx.k,&title);
231:       if (title) {
232:         PetscDrawSetTitle(draw,title);
233:       }
234:     }
235:     PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);
236:     PetscLogInfo(da,"VecView_MPI_Draw_DA2d:DA 2d contour plot min %g max %g\n",zctx.min,zctx.max);

238:     PetscDrawGetPopup(draw,&popup);
239:     if (popup) {PetscDrawScalePopup(popup,zctx.min,zctx.max);}

241:     zctx.scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/(zctx.max - zctx.min);

243:     PetscDrawZoom(draw,VecView_MPI_Draw_DA2d_Zoom,&zctx);
244:   }
245:   if (useports){
246:     PetscDrawViewPortsDestroy(ports);
247:   }

249:   VecRestoreArray(xcoorl,&zctx.xy);
250:   VecRestoreArray(xlocal,&zctx.v);
251:   return(0);
252: }

254: EXTERN int VecView_MPI_HDF4_Ex(Vec X, PetscViewer viewer, int d, int *dims);

258: int VecView_MPI_HDF4_DA2d(Vec xin,PetscViewer viewer)
259: {
260: #if defined(PETSC_HAVE_HDF4) && !defined(PETSC_USE_COMPLEX)
262:   int dims[2];
263:   DA  da;
264:   Vec natural;


268:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
269:   if (!da) SETERRQ(1,"Vector not generated from a DA");

271:   dims[0] = da->M;
272:   dims[1] = da->N;

274:   DACreateNaturalVector(da,&natural);
275:   DAGlobalToNaturalBegin(da,xin,INSERT_VALUES,natural);
276:   DAGlobalToNaturalEnd(da,xin,INSERT_VALUES,natural);
277:   VecView_MPI_HDF4_Ex(natural, viewer, 2, dims);
278:   VecDestroy(natural);

280:   return(0);
281: #else /* !defined(PETSC_HAVE_HDF4) */
283:   SETERRQ(1,"Build PETSc with HDF4 to use this viewer");
284: #endif    
285: }

289: int VecView_MPI_Netcdf_DA(Vec xin,PetscViewer viewer)
290: {
291: #if defined(PETSC_HAVE_PNETCDF)
292:   int            ierr,ncid,xstart,xdim_num=1;
293:   int            i,j,len,dim,m,n,p,dof,swidth,M,N,P;
294:   int            xin_dim,xin_id,xin_n,xin_N,xyz_dim,xyz_id,xyz_n,xyz_N;
295:   int            *lx,*ly,*lz;
296:   PetscScalar    *xarray;
297:   DA             da,dac;
298:   Vec            natural,xyz;
299:   DAStencilType  stencil;
300:   DAPeriodicType periodic;
301:   MPI_Comm       comm;

304:   PetscObjectGetComm((PetscObject)xin,&comm);
305:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
306:   if (!da) SETERRQ(1,"Vector not generated from a DA");
307:   DAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&dof,&swidth,&periodic,&stencil);

309:   /* create the appropriate DA to map the coordinates to natural ordering */
310:   DAGetOwnershipRange(da,&lx,&ly,&lz);
311:   if (dim == 1) {
312:     DACreate1d(comm,DA_NONPERIODIC,m,dim,0,lx,&dac);
313:   } else if (dim == 2) {
314:     DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,m,n,M,N,dim,0,lx,ly,&dac);
315:   } else if (dim == 3) {
316:     DACreate3d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,m,n,p,M,N,P,dim,0,lx,ly,lz,&dac);
317:   } else {
318:     SETERRQ1(1,"Dimension is not 1 2 or 3: %d\n",dim);
319:   }
320:   DACreateNaturalVector(dac,&xyz);
321:   PetscObjectSetOptionsPrefix((PetscObject)xyz,"coor_");
322:   DAGlobalToNaturalBegin(dac,da->coordinates,INSERT_VALUES,xyz);
323:   DAGlobalToNaturalEnd(dac,da->coordinates,INSERT_VALUES,xyz);
324:   /* Create the DA vector in natural ordering */
325:   DACreateNaturalVector(da,&natural);
326:   DAGlobalToNaturalBegin(da,xin,INSERT_VALUES,natural);
327:   DAGlobalToNaturalEnd(da,xin,INSERT_VALUES,natural);
328:   /* Write the netCDF dataset */
329:   PetscViewerNetcdfGetID(viewer,&ncid);
330:   if (ncid < 0) SETERRQ(1,"First call PetscViewerNetcdfOpen to create NetCDF dataset");
331:   /* define dimensions */
332:   VecGetSize(xin,&xin_N);
333:   VecGetLocalSize(xin,&xin_n);
334:   ncmpi_def_dim(ncid,"PETSc_DA_Vector_Global_Size",xin_N,&xin_dim);
335:   VecGetSize(xyz,&xyz_N);
336:   VecGetLocalSize(xyz,&xyz_n);
337:   ncmpi_def_dim(ncid,"PETSc_DA_Coordinate_Vector_Global_Size",xyz_N,&xyz_dim);
338:   /* define variables */
339:   ncmpi_def_var(ncid,"PETSc_DA_Vector",NC_DOUBLE,xdim_num,&xin_dim,&xin_id);
340:   ncmpi_def_var(ncid,"PETSc_DA_Coordinate_Vector",NC_DOUBLE,xdim_num,&xyz_dim,&xyz_id);
341:   /* leave define mode */
342:   ncmpi_enddef(ncid);
343:   /* store the vector */
344:   VecGetArray(xin,&xarray);
345:   VecGetOwnershipRange(xin,&xstart,PETSC_NULL);
346:   ncmpi_put_vara_double_all(ncid,xin_id,(const size_t*)&xstart,(const size_t*)&xin_n,xarray);
347:   VecRestoreArray(xin,&xarray);
348:   /* store the coordinate vector */
349:   VecGetArray(xyz,&xarray);
350:   VecGetOwnershipRange(xyz,&xstart,PETSC_NULL);
351:   ncmpi_put_vara_double_all(ncid,xyz_id,(const size_t*)&xstart,(const size_t*)&xyz_n,xarray);
352:   VecRestoreArray(xyz,&xarray);
353:   /* destroy the vectors and da */
354:   VecDestroy(natural);
355:   VecDestroy(xyz);
356:   DADestroy(dac);

358:   return(0);
359: #else /* !defined(PETSC_HAVE_PNETCDF) */
361:   SETERRQ(1,"Build PETSc with NETCDF to use this viewer");
362: #endif    
363: }

365: EXTERN int VecView_MPI_Draw_DA1d(Vec,PetscViewer);

367: EXTERN_C_BEGIN
370: int VecView_MPI_DA(Vec xin,PetscViewer viewer)
371: {
372:   DA         da;
373:   int        ierr,dim;
374:   Vec        natural;
375:   PetscTruth isdraw,ishdf4,isnetcdf;
376:   char       *prefix;

379:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
380:   if (!da) SETERRQ(1,"Vector not generated from a DA");
381:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
382:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_HDF4,&ishdf4);
383:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_NETCDF,&isnetcdf);
384:   if (isdraw) {
385:     DAGetInfo(da,&dim,0,0,0,0,0,0,0,0,0,0);
386:     if (dim == 1) {
387:       VecView_MPI_Draw_DA1d(xin,viewer);
388:     } else if (dim == 2) {
389:       VecView_MPI_Draw_DA2d(xin,viewer);
390:     } else {
391:       SETERRQ1(1,"Cannot graphically view vector associated with this dimensional DA %d",dim);
392:     }
393:   } else if (ishdf4) {
394:     DAGetInfo(da,&dim,0,0,0,0,0,0,0,0,0,0);
395:     switch (dim) {
396:     case 2:
397:       VecView_MPI_HDF4_DA2d(xin,viewer);
398:       break;
399:     default:
400:       SETERRQ1(1,"Cannot view HDF4 vector associated with this dimensional DA %d",dim);
401:     }
402:   } else if (isnetcdf) {
403:     VecView_MPI_Netcdf_DA(xin,viewer);
404:   } else {
405:     /* call viewer on natural ordering */
406:     PetscObjectGetOptionsPrefix((PetscObject)xin,&prefix);
407:     DACreateNaturalVector(da,&natural);
408:     PetscObjectSetOptionsPrefix((PetscObject)natural,prefix);
409:     DAGlobalToNaturalBegin(da,xin,INSERT_VALUES,natural);
410:     DAGlobalToNaturalEnd(da,xin,INSERT_VALUES,natural);
411:     PetscObjectName((PetscObject)xin);
412:     PetscObjectSetName((PetscObject)natural,xin->name);
413:     VecView(natural,viewer);
414:     VecDestroy(natural);
415:   }
416:   return(0);
417: }
418: EXTERN_C_END

420: EXTERN_C_BEGIN
423: int VecLoadIntoVector_Binary_DA(PetscViewer viewer,Vec xin)
424: {
425:   DA   da;
426:   int  ierr;
427:   Vec  natural;
428:   char *prefix;

431:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
432:   if (!da) SETERRQ(1,"Vector not generated from a DA");
433:   PetscObjectGetOptionsPrefix((PetscObject)xin,&prefix);
434:   DACreateNaturalVector(da,&natural);
435:   PetscObjectSetOptionsPrefix((PetscObject)natural,prefix);
436:   VecLoadIntoVector(viewer,natural);
437:   DANaturalToGlobalBegin(da,natural,INSERT_VALUES,xin);
438:   DANaturalToGlobalEnd(da,natural,INSERT_VALUES,xin);
439:   VecDestroy(natural);
440:   PetscLogInfo(xin,"VecLoadIntoVector_Binary_DA:Loading vector from natural ordering into DA\n");
441:   return(0);
442: }
443: EXTERN_C_END