Actual source code: drawv.c
1: #define PETSC_DLL
3: #include src/sys/viewer/impls/draw/vdraw.h
7: PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
8: {
9: PetscErrorCode ierr;
10: int i;
11: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
14: if (vdraw->singleton_made) {
15: SETERRQ(PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton");
16: }
17: for (i=0; i<vdraw->draw_max; i++) {
18: if (vdraw->drawaxis[i]) {PetscDrawAxisDestroy(vdraw->drawaxis[i]);}
19: if (vdraw->drawlg[i]) {PetscDrawLGDestroy(vdraw->drawlg[i]);}
20: if (vdraw->draw[i]) {PetscDrawDestroy(vdraw->draw[i]);}
21: }
23: PetscFree(vdraw->display);
24: PetscFree(vdraw->drawaxis);
25: PetscFree(vdraw->drawlg);
26: PetscFree(vdraw->draw);
27: PetscFree(vdraw);
28: return(0);
29: }
33: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
34: {
35: PetscErrorCode ierr;
36: int i;
37: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
40: for (i=0; i<vdraw->draw_max; i++) {
41: if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
42: }
43: return(0);
44: }
48: /*@C
49: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
50: This PetscDraw object may then be used to perform graphics using
51: PetscDrawXXX() commands.
53: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
55: Input Parameters:
56: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
57: - windownumber - indicates which subwindow (usually 0)
59: Ouput Parameter:
60: . draw - the draw object
62: Level: intermediate
64: Concepts: drawing^accessing PetscDraw context from PetscViewer
65: Concepts: graphics
67: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
68: @*/
69: PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer,int windownumber,PetscDraw *draw)
70: {
71: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
72: PetscErrorCode ierr;
73: PetscTruth isdraw;
74: char *title;
79: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
80: if (!isdraw) {
81: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
82: }
83: if (windownumber < 0) {
84: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
85: }
86: if (windownumber >= vdraw->draw_max) {
87: /* allocate twice as many slots as needed */
88: int draw_max = vdraw->draw_max;
89: PetscDraw *tdraw = vdraw->draw;
90: PetscDrawLG *drawlg = vdraw->drawlg;
91: PetscDrawAxis *drawaxis = vdraw->drawaxis;
93: vdraw->draw_max = 2*windownumber;
94: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
95: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
96: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
97: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
98: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
99: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
101: PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
102: PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
103: PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));
105: PetscFree(tdraw);
106: PetscFree(drawlg);
107: PetscFree(drawaxis);
108: }
110: if (!vdraw->draw[windownumber]) {
111: if (vdraw->draw[0]) {
112: PetscDrawGetTitle(vdraw->draw[0],&title);
113: } else title = 0;
114: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
115: &vdraw->draw[windownumber]);
116: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
117: }
118: *draw = vdraw->draw[windownumber];
119: return(0);
120: }
124: /*@C
125: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
126: This PetscDrawLG object may then be used to perform graphics using
127: PetscDrawLGXXX() commands.
129: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
131: Input Parameter:
132: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
133: - windownumber - indicates which subwindow (usually 0)
135: Ouput Parameter:
136: . draw - the draw line graph object
138: Level: intermediate
140: Concepts: line graph^accessing context
142: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
143: @*/
144: PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
145: {
146: PetscErrorCode ierr;
147: PetscTruth isdraw;
148: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
153: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
154: if (!isdraw) {
155: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
156: }
157: if (windownumber < 0) {
158: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
159: }
160: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
161: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
162: }
164: if (!vdraw->drawlg[windownumber]) {
165: PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
166: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
167: }
168: *drawlg = vdraw->drawlg[windownumber];
169: return(0);
170: }
174: /*@C
175: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
176: This PetscDrawAxis object may then be used to perform graphics using
177: PetscDrawAxisXXX() commands.
179: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
181: Input Parameter:
182: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
183: - windownumber - indicates which subwindow (usually 0)
185: Ouput Parameter:
186: . drawaxis - the draw axis object
188: Level: advanced
190: Concepts: line graph^accessing context
192: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
193: @*/
194: PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
195: {
196: PetscErrorCode ierr;
197: PetscTruth isdraw;
198: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
203: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
204: if (!isdraw) {
205: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
206: }
207: if (windownumber < 0) {
208: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
209: }
210: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
211: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
212: }
214: if (!vdraw->drawaxis[windownumber]) {
215: PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
216: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
217: }
218: *drawaxis = vdraw->drawaxis[windownumber];
219: return(0);
220: }
224: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
225: {
226: PetscErrorCode ierr;
227: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
230: vdraw->h = h;
231: vdraw->w = w;
232: PetscStrallocpy(display,&vdraw->display);
233: PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
234: PetscDrawSetFromOptions(vdraw->draw[0]);
235: PetscLogObjectParent(v,vdraw->draw[0]);
236: return(0);
237: }
241: /*@C
242: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
243: do graphics in this window, you must call PetscViewerDrawGetDraw() and
244: perform the graphics on the PetscDraw object.
246: Collective on MPI_Comm
248: Input Parameters:
249: + comm - communicator that will share window
250: . display - the X display on which to open, or null for the local machine
251: . title - the title to put in the title bar, or null for no title
252: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
253: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
254: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
256: Output Parameters:
257: . viewer - the PetscViewer
259: Format Options:
260: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
261: - PETSC_VIEWER_DRAW_LG - displays using a line graph
263: Options Database Keys:
264: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
265: PetscDrawCreate() for runtime options, including
266: + -draw_type x or null
267: . -nox - Disables all x-windows output
268: . -display <name> - Specifies name of machine for the X display
269: . -geometry <x,y,w,h> - allows setting the window location and size
270: - -draw_pause <pause> - Sets time (in seconds) that the
271: program pauses after PetscDrawPause() has been called
272: (0 is default, -1 implies until user input).
274: Level: beginner
276: Note for Fortran Programmers:
277: Whenever indicating null character data in a Fortran code,
278: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
279: correct for character data! Thus, PETSC_NULL_CHARACTER can be
280: used for the display and title input parameters.
282: Concepts: graphics^opening PetscViewer
283: Concepts: drawing^opening PetscViewer
286: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
287: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
288: @*/
289: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
290: {
294: PetscViewerCreate(comm,viewer);
295: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
296: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
297: return(0);
298: }
302: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
303: {
304: PetscErrorCode ierr;
305: PetscMPIInt rank;
306: int i;
307: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
310: if (vdraw->singleton_made) {
311: SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
312: }
314: /* only processor zero can use the PetscViewer draw singleton */
315: MPI_Comm_rank(viewer->comm,&rank);
316: if (!rank) {
317: PetscViewerCreate(PETSC_COMM_SELF,sviewer);
318: PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
319: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
320: for (i=0; i<vdraw->draw_max; i++) {
321: if (vdraw->draw[i]) {
322: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
323: }
324: }
325: }
326: vdraw->singleton_made = PETSC_TRUE;
327: return(0);
328: }
332: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
333: {
334: PetscErrorCode ierr;
335: PetscMPIInt rank;
336: int i;
337: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
340: if (!vdraw->singleton_made) {
341: SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
342: }
343: MPI_Comm_rank(viewer->comm,&rank);
344: if (!rank) {
345: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
346: for (i=0; i<vdraw->draw_max; i++) {
347: if (vdraw->draw[i] && vsdraw->draw[i]) {
348: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
349: }
350: }
351: PetscFree(vsdraw->drawaxis);
352: PetscFree(vsdraw->drawlg);
353: PetscFree(vsdraw->draw);
354: PetscFree((*sviewer)->data);
355: PetscHeaderDestroy(*sviewer);
356: }
357: vdraw->singleton_made = PETSC_FALSE;
358: return(0);
359: }
364: PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
365: {
366: int i;
367: PetscErrorCode ierr;
368: PetscViewer_Draw *vdraw;
371: PetscNew(PetscViewer_Draw,&vdraw);
372: viewer->data = (void*)vdraw;
374: viewer->ops->flush = PetscViewerFlush_Draw;
375: viewer->ops->destroy = PetscViewerDestroy_Draw;
376: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
377: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
378: viewer->format = PETSC_VIEWER_NOFORMAT;
380: /* these are created on the fly if requested */
381: vdraw->draw_max = 5;
382: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
383: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
384: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
385: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
386: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
387: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
388: for (i=0; i<vdraw->draw_max; i++) {
389: vdraw->draw[i] = 0;
390: vdraw->drawlg[i] = 0;
391: vdraw->drawaxis[i] = 0;
392: }
393: vdraw->singleton_made = PETSC_FALSE;
394: return(0);
395: }
400: /*@
401: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
403: Not Collective
405: Input Parameter:
406: . viewer - the PetscViewer
408: Level: intermediate
410: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
412: @*/
413: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
414: {
415: PetscErrorCode ierr;
416: int i;
417: PetscTruth isdraw;
418: PetscViewer_Draw *vdraw;
421: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
422: if (isdraw) {
423: vdraw = (PetscViewer_Draw*)viewer->data;
424: for (i=0; i<vdraw->draw_max; i++) {
425: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
426: }
427: }
428: return(0);
429: }
431: /* ---------------------------------------------------------------------*/
432: /*
433: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
434: is attached to a communicator, in this case the attribute is a PetscViewer.
435: */
436: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
440: /*@C
441: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
442: in a communicator.
444: Collective on MPI_Comm
446: Input Parameter:
447: . comm - the MPI communicator to share the window PetscViewer
449: Level: intermediate
451: Notes:
452: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
453: an error code. The window is usually used in the form
454: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
456: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
457: @*/
458: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
459: {
461: int flag;
462: PetscViewer viewer;
465: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
466: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
467: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
468: }
469: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
470: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
471: if (!flag) { /* PetscViewer not yet created */
472: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
473: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
474: PetscObjectRegisterDestroy((PetscObject)viewer);
475: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
476: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
477: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
478: }
479: PetscFunctionReturn(viewer);
480: }