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: int VecView_MPI_Draw_DA2d_Zoom(PetscDraw draw,void *ctx)
 25: {
 26:   ZoomCtx *zctx = (ZoomCtx*)ctx;
 27:   int     ierr,m,n,i,j,k,step,id,c1,c2,c3,c4;
 28:   PetscReal  s,min,x1,x2,x3,x4,y_1,y2,y3,y4;
 29:   PetscScalar  *v,*xy;

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

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

 84:   PetscViewerDrawGetDraw(viewer,0,&draw);
 85:   PetscDrawIsNull(draw,&isnull); if (isnull) return(0);

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

 90:   PetscObjectGetComm((PetscObject)xin,&comm);
 91:   MPI_Comm_rank(comm,&rank);

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

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

135:   /*
136:       Get local (ghosted) values of vector
137:   */
138:   DAGlobalToLocalBegin(dac,xin,INSERT_VALUES,xlocal);
139:   DAGlobalToLocalEnd(dac,xin,INSERT_VALUES,xlocal);
140:   VecGetArray(xlocal,&zctx.v);

142:   /* get coordinates of nodes */
143:   DAGetCoordinates(da,&xcoor);
144:   if (!xcoor) {
145:     DASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0);
146:     DAGetCoordinates(da,&xcoor);
147:   }

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

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

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

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

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

215:     if (!rank) {
216:       char *title;

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

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

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

231:     PetscDrawZoom(draw,VecView_MPI_Draw_DA2d_Zoom,&zctx);
232:   }
233:   if (useports){
234:     PetscDrawViewPortsDestroy(ports);
235:   }

237:   VecRestoreArray(xcoorl,&zctx.xy);
238:   VecRestoreArray(xlocal,&zctx.v);
239:   return(0);
240: }

242: EXTERN int VecView_MPI_Draw_DA1d(Vec,PetscViewer);

244: EXTERN_C_BEGIN
245: int VecView_MPI_DA(Vec xin,PetscViewer viewer)
246: {
247:   DA         da;
248:   int        ierr,dim;
249:   Vec        natural;
250:   PetscTruth isdraw;

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

277: EXTERN_C_BEGIN
278: int VecLoadIntoVector_Binary_DA(PetscViewer viewer,Vec xin)
279: {
280:   DA             da;
281:   int            ierr;
282:   Vec            natural;

285:   PetscObjectQuery((PetscObject)xin,"DA",(PetscObject*)&da);
286:   if (!da) SETERRQ(1,"Vector not generated from a DA");
287:   DACreateNaturalVector(da,&natural);
288:   VecLoadIntoVector(viewer,natural);
289:   DANaturalToGlobalBegin(da,natural,INSERT_VALUES,xin);
290:   DANaturalToGlobalEnd(da,natural,INSERT_VALUES,xin);
291:   VecDestroy(natural);
292:   PetscLogInfo(xin,"VecLoadIntoVector_Binary_DA:Loading vector from natural ordering into DAn");
293:   return(0);
294: }
295: EXTERN_C_END