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