Actual source code: drawv.c
1: /*$Id: drawv.c,v 1.61 2001/04/22 17:22:00 buschelm Exp $*/
3: #include src/sys/src/viewer/impls/draw/vdraw.h
5: int PetscViewerDestroy_Draw(PetscViewer v)
6: {
7: int ierr,i;
8: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
11: if (vdraw->singleton_made) {
12: SETERRQ(1,"Destroying PetscViewer without first restoring singleton");
13: }
14: for (i=0; i<vdraw->draw_max; i++) {
15: if (vdraw->drawaxis[i]) {PetscDrawAxisDestroy(vdraw->drawaxis[i]);}
16: if (vdraw->drawlg[i]) {PetscDrawLGDestroy(vdraw->drawlg[i]);}
17: if (vdraw->draw[i]) {PetscDrawDestroy(vdraw->draw[i]);}
18: }
19: PetscFree(vdraw->drawaxis);
20: PetscFree(vdraw->drawlg);
21: PetscFree(vdraw->draw);
22: PetscFree(vdraw);
23: return(0);
24: }
26: int PetscViewerFlush_Draw(PetscViewer v)
27: {
28: int ierr,i;
29: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
32: for (i=0; i<vdraw->draw_max; i++) {
33: if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
34: }
35: return(0);
36: }
38: /*@C
39: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
40: This PetscDraw object may then be used to perform graphics using
41: PetscDrawXXX() commands.
43: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
45: Input Parameters:
46: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
47: - windownumber - indicates which subwindow (usually 0)
49: Ouput Parameter:
50: . draw - the draw object
52: Level: intermediate
54: Concepts: drawing^accessing PetscDraw context from PetscViewer
55: Concepts: graphics
57: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
58: @*/
59: int PetscViewerDrawGetDraw(PetscViewer viewer,int windownumber,PetscDraw *draw)
60: {
61: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
62: int ierr;
63: PetscTruth isdraw;
64: char *title;
69: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
70: if (!isdraw) {
71: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
72: }
73: if (windownumber < 0) {
74: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
75: }
76: if (windownumber >= vdraw->draw_max) {
77: /* allocate twice as many slots as needed */
78: int draw_max = vdraw->draw_max;
79: PetscDraw *tdraw = vdraw->draw;
80: PetscDrawLG *drawlg = vdraw->drawlg;
81: PetscDrawAxis *drawaxis = vdraw->drawaxis;
83: vdraw->draw_max = 2*windownumber;
84: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
85: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
86: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
87: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
88: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
89: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
91: PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
92: PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
93: PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));
95: PetscFree(tdraw);
96: PetscFree(drawlg);
97: PetscFree(drawaxis);
98: }
100: if (!vdraw->draw[windownumber]) {
101: if (vdraw->draw[0]) {
102: PetscDrawGetTitle(vdraw->draw[0],&title);
103: } else title = 0;
104: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
105: &vdraw->draw[windownumber]);
106: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
107: }
108: *draw = vdraw->draw[windownumber];
109: return(0);
110: }
112: /*@C
113: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
114: This PetscDrawLG object may then be used to perform graphics using
115: PetscDrawLGXXX() commands.
117: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
119: Input Parameter:
120: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
121: - windownumber - indicates which subwindow (usually 0)
123: Ouput Parameter:
124: . draw - the draw line graph object
126: Level: intermediate
128: Concepts: line graph^accessing context
130: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
131: @*/
132: int PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
133: {
134: int ierr;
135: PetscTruth isdraw;
136: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
141: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
142: if (!isdraw) {
143: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
144: }
145: if (windownumber < 0) {
146: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
147: }
148: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
149: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
150: }
152: if (!vdraw->drawlg[windownumber]) {
153: PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
154: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
155: }
156: *drawlg = vdraw->drawlg[windownumber];
157: return(0);
158: }
160: /*@C
161: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
162: This PetscDrawAxis object may then be used to perform graphics using
163: PetscDrawAxisXXX() commands.
165: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
167: Input Parameter:
168: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
169: - windownumber - indicates which subwindow (usually 0)
171: Ouput Parameter:
172: . drawaxis - the draw axis object
174: Level: advanced
176: Concepts: line graph^accessing context
178: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
179: @*/
180: int PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
181: {
182: int ierr;
183: PetscTruth isdraw;
184: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
189: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
190: if (!isdraw) {
191: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
192: }
193: if (windownumber < 0) {
194: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
195: }
196: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
197: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
198: }
200: if (!vdraw->drawaxis[windownumber]) {
201: PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
202: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
203: }
204: *drawaxis = vdraw->drawaxis[windownumber];
205: return(0);
206: }
208: int PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
209: {
210: int ierr;
211: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
214: vdraw->h = h;
215: vdraw->w = w;
216: ierr = PetscStrallocpy(display,&vdraw->display);
217: ierr = PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
218: ierr = PetscDrawSetFromOptions(vdraw->draw[0]);
219: PetscLogObjectParent(v,vdraw->draw[0]);
220: return(0);
221: }
223: /*@C
224: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
225: do graphics in this window, you must call PetscViewerDrawGetDraw() and
226: perform the graphics on the PetscDraw object.
228: Collective on MPI_Comm
230: Input Parameters:
231: + comm - communicator that will share window
232: . display - the X display on which to open, or null for the local machine
233: . title - the title to put in the title bar, or null for no title
234: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
235: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
236: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
238: Output Parameters:
239: . viewer - the PetscViewer
241: Format Options:
242: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
243: - PETSC_VIEWER_DRAW_LG - displays using a line graph
245: Options Database Keys:
246: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
247: PetscDrawCreate() for runtime options, including
248: + -draw_type x or null
249: . -nox - Disables all x-windows output
250: . -display <name> - Specifies name of machine for the X display
251: - -draw_pause <pause> - Sets time (in seconds) that the
252: program pauses after PetscDrawPause() has been called
253: (0 is default, -1 implies until user input).
255: Level: beginner
257: Note for Fortran Programmers:
258: Whenever indicating null character data in a Fortran code,
259: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
260: correct for character data! Thus, PETSC_NULL_CHARACTER can be
261: used for the display and title input parameters.
263: Concepts: graphics^opening PetscViewer
264: Concepts: drawing^opening PetscViewer
267: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
268: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
269: @*/
270: int PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
271: {
275: PetscViewerCreate(comm,viewer);
276: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
277: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
278: return(0);
279: }
281: int PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
282: {
283: int ierr,rank,i;
284: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
287: if (vdraw->singleton_made) {
288: SETERRQ(1,"Trying to get singleton without first restoring previous");
289: }
291: /* only processor zero can use the PetscViewer draw singleton */
292: MPI_Comm_rank(viewer->comm,&rank);
293: if (!rank) {
294: ierr = PetscViewerCreate(PETSC_COMM_SELF,sviewer);
295: ierr = PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
296: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
297: for (i=0; i<vdraw->draw_max; i++) {
298: if (vdraw->draw[i]) {
299: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
300: }
301: }
302: }
303: vdraw->singleton_made = PETSC_TRUE;
304: return(0);
305: }
307: int PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
308: {
309: int ierr,rank,i;
310: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
313: if (!vdraw->singleton_made) {
314: SETERRQ(1,"Trying to restore a singleton that was not gotten");
315: }
316: MPI_Comm_rank(viewer->comm,&rank);
317: if (!rank) {
318: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
319: for (i=0; i<vdraw->draw_max; i++) {
320: if (vdraw->draw[i] && vsdraw->draw[i]) {
321: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
322: }
323: }
324: PetscFree(vsdraw->drawaxis);
325: PetscFree(vsdraw->drawlg);
326: PetscFree(vsdraw->draw);
327: PetscFree((*sviewer)->data);
328: PetscLogObjectDestroy((PetscObject)*sviewer);
329: PetscHeaderDestroy((PetscObject)*sviewer);
330: }
331: vdraw->singleton_made = PETSC_FALSE;
332: return(0);
333: }
335: EXTERN_C_BEGIN
336: int PetscViewerCreate_Draw(PetscViewer viewer)
337: {
338: int i,ierr;
339: PetscViewer_Draw *vdraw;
342: ierr = PetscNew(PetscViewer_Draw,&vdraw);
343: viewer->data = (void*)vdraw;
345: viewer->ops->flush = PetscViewerFlush_Draw;
346: viewer->ops->destroy = PetscViewerDestroy_Draw;
347: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
348: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
349: viewer->format = PETSC_VIEWER_NOFORMAT;
351: /* these are created on the fly if requested */
352: vdraw->draw_max = 5;
353: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
354: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
355: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
356: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
357: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
358: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
359: for (i=0; i<vdraw->draw_max; i++) {
360: vdraw->draw[i] = 0;
361: vdraw->drawlg[i] = 0;
362: vdraw->drawaxis[i] = 0;
363: }
364: vdraw->singleton_made = PETSC_FALSE;
365: return(0);
366: }
367: EXTERN_C_END
369: /*@
370: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
372: Not Collective
374: Input Parameter:
375: . viewer - the PetscViewer
377: Level: intermediate
379: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
381: @*/
382: int PetscViewerDrawClear(PetscViewer viewer)
383: {
384: int ierr,i;
385: PetscTruth isdraw;
386: PetscViewer_Draw *vdraw;
389: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
390: if (isdraw) {
391: vdraw = (PetscViewer_Draw*)viewer->data;
392: for (i=0; i<vdraw->draw_max; i++) {
393: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
394: }
395: }
396: return(0);
397: }
399: /* ---------------------------------------------------------------------*/
400: /*
401: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
402: is attached to a communicator, in this case the attribute is a PetscViewer.
403: */
404: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
406: /*@C
407: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
408: in a communicator.
410: Collective on MPI_Comm
412: Input Parameter:
413: . comm - the MPI communicator to share the window PetscViewer
415: Level: intermediate
417: Notes:
418: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
419: an error code. The window is usually used in the form
420: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
422: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
423: @*/
424: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
425: {
426: int ierr,flag;
427: PetscViewer viewer;
430: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
431: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
432: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
433: }
434: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
435: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
436: if (!flag) { /* PetscViewer not yet created */
437: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
438: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
439: PetscObjectRegisterDestroy((PetscObject)viewer);
440: if (ierr) {PetscError(__LINE__,"VIEWER_STDOUT_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
441: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
442: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
443: }
444: PetscFunctionReturn(viewer);
445: }