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