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

  9: /*
 10:         The data that is passed into the graphics callback
 11: */
 12: typedef struct {
 13:   int          m,n,step,k;
 14:   PetscReal    min,max,scale;
 15:   PetscScalar  *xy,*v;
 16:   PetscTruth   showgrid;
 17: } ZoomCtx;

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

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

 70: #undef __FUNCT__  
 72: int VecView_MPI_Draw_DA2d(Vec xin,PetscViewer viewer)
 73: {
 74:   DA                 da,dac,dag;
 75:   int                rank,ierr,igstart,N,s,M,istart,isize,jgstart,*lx,*ly,w;
 76:   PetscReal          coors[4],ymin,ymax,xmin,xmax;
 77:   PetscDraw          draw,popup;
 78:   PetscTruth         isnull,useports;
 79:   MPI_Comm           comm;
 80:   Vec                xlocal,xcoor,xcoorl;
 81:   DAPeriodicType     periodic;
 82:   DAStencilType      st;
 83:   ZoomCtx            zctx;
 84:   PetscDrawViewPorts *ports;
 85:   PetscViewerFormat  format;

 88:   PetscViewerDrawGetDraw(viewer,0,&draw);
 89:   PetscDrawIsNull(draw,&isnull); if (isnull) return(0);

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

 94:   PetscObjectGetComm((PetscObject)xin,&comm);
 95:   MPI_Comm_rank(comm,&rank);

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

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

139:   /*
140:       Get local (ghosted) values of vector
141:   */
142:   DAGlobalToLocalBegin(dac,xin,INSERT_VALUES,xlocal);
143:   DAGlobalToLocalEnd(dac,xin,INSERT_VALUES,xlocal);
144:   VecGetArray(xlocal,&zctx.v);

146:   /* get coordinates of nodes */
147:   DAGetCoordinates(da,&xcoor);
148:   if (!xcoor) {
149:     DASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0);
150:     DAGetCoordinates(da,&xcoor);
151:   }

153:   /*
154:       Determine the min and max  coordinates in plot 
155:   */
156:   VecStrideMin(xcoor,0,PETSC_NULL,&xmin);
157:   VecStrideMax(xcoor,0,PETSC_NULL,&xmax);
158:   VecStrideMin(xcoor,1,PETSC_NULL,&ymin);
159:   VecStrideMax(xcoor,1,PETSC_NULL,&ymax);
160:   coors[0] = xmin - .05*(xmax- xmin); coors[2] = xmax + .05*(xmax - xmin);
161:   coors[1] = ymin - .05*(ymax- ymin); coors[3] = ymax + .05*(ymax - ymin);
162:   PetscLogInfo(da,"VecView_MPI_Draw_DA2d:Preparing DA 2d contour plot coordinates %g %g %g %gn",coors[0],coors[1],coors[2],coors[3]);

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

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

192:   PetscViewerGetFormat(viewer,&format);
193:   PetscOptionsHasName(PETSC_NULL,"-draw_ports",&useports);
194:   if (useports || format == PETSC_VIEWER_DRAW_PORTS){
195:     PetscDrawSynchronizedClear(draw);
196:     PetscDrawViewPortsCreate(draw,zctx.step,&ports);
197:   }
198:   /*
199:      Loop over each field; drawing each in a different window
200:   */
201:   for (zctx.k=0; zctx.k<zctx.step; zctx.k++) {
202:     if (useports) {
203:       PetscDrawViewPortsSet(ports,zctx.k);
204:     } else {
205:       PetscViewerDrawGetDraw(viewer,zctx.k,&draw);
206:       PetscDrawSynchronizedClear(draw);
207:     }

209:     /*
210:         Determine the min and max color in plot 
211:     */
212:     VecStrideMin(xin,zctx.k,PETSC_NULL,&zctx.min);
213:     VecStrideMax(xin,zctx.k,PETSC_NULL,&zctx.max);
214:     if (zctx.min == zctx.max) {
215:       zctx.min -= 1.e-12;
216:       zctx.max += 1.e-12;
217:     }

219:     if (!rank) {
220:       char *title;

222:       DAGetFieldName(da,zctx.k,&title);
223:       if (title) {
224:         PetscDrawSetTitle(draw,title);
225:       }
226:     }
227:     PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);
228:     PetscLogInfo(da,"VecView_MPI_Draw_DA2d:DA 2d contour plot min %g max %gn",zctx.min,zctx.max);

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

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

235:     PetscDrawZoom(draw,VecView_MPI_Draw_DA2d_Zoom,&zctx);
236:   }
237:   if (useports){
238:     PetscDrawViewPortsDestroy(ports);
239:   }

241:   VecRestoreArray(xcoorl,&zctx.xy);
242:   VecRestoreArray(xlocal,&zctx.v);
243:   return(0);
244: }

246: EXTERN int VecView_MPI_Draw_DA1d(Vec,PetscViewer);

248: EXTERN_C_BEGIN
249: #undef __FUNCT__  
251: int VecView_MPI_DA(Vec xin,PetscViewer viewer)
252: {
253:   DA         da;
254:   int        ierr,dim;
255:   Vec        natural;
256:   PetscTruth isdraw;

259:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
260:   if (!da) SETERRQ(1,"Vector not generated from a DA");
261:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
262:   if (isdraw) {
263:     DAGetInfo(da,&dim,0,0,0,0,0,0,0,0,0,0);
264:     if (dim == 1) {
265:       VecView_MPI_Draw_DA1d(xin,viewer);
266:     } else if (dim == 2) {
267:       VecView_MPI_Draw_DA2d(xin,viewer);
268:     } else {
269:       SETERRQ1(1,"Cannot graphically view vector associated with this dimensional DA %d",dim);
270:     }
271:   } else {
272:     /* call viewer on natural ordering */
273:     DACreateNaturalVector(da,&natural);
274:     DAGlobalToNaturalBegin(da,xin,INSERT_VALUES,natural);
275:     DAGlobalToNaturalEnd(da,xin,INSERT_VALUES,natural);
276:     VecView(natural,viewer);
277:     VecDestroy(natural);
278:   }
279:   return(0);
280: }
281: EXTERN_C_END

283: EXTERN_C_BEGIN
284: #undef __FUNCT__  
286: int VecLoadIntoVector_Binary_DA(PetscViewer viewer,Vec xin)
287: {
288:   DA  da;
290:   Vec natural;

293:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
294:   if (!da) SETERRQ(1,"Vector not generated from a DA");
295:   DACreateNaturalVector(da,&natural);
296:   VecLoadIntoVector(viewer,natural);
297:   DANaturalToGlobalBegin(da,natural,INSERT_VALUES,xin);
298:   DANaturalToGlobalEnd(da,natural,INSERT_VALUES,xin);
299:   VecDestroy(natural);
300:   PetscLogInfo(xin,"VecLoadIntoVector_Binary_DA:Loading vector from natural ordering into DAn");
301:   return(0);
302: }
303: EXTERN_C_END