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<PETSC_VIEWER_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);
20: return(0);
21: }
23: int PetscViewerFlush_Draw(PetscViewer v)
24: {
25: int ierr,i;
26: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
29: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
30: if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
31: }
32: return(0);
33: }
35: /*@C
36: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
37: This PetscDraw object may then be used to perform graphics using
38: PetscDrawXXX() commands.
40: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
42: Input Parameters:
43: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
44: - windownumber - indicates which subwindow (usually 0)
46: Ouput Parameter:
47: . draw - the draw object
49: Level: intermediate
51: Concepts: drawing^accessing PetscDraw context from PetscViewer
52: Concepts: graphics
54: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
55: @*/
56: int PetscViewerDrawGetDraw(PetscViewer viewer,int windownumber,PetscDraw *draw)
57: {
58: PetscViewer_Draw *vdraw;
59: int ierr;
60: PetscTruth isdraw;
61: char *title;
66: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
67: if (!isdraw) {
68: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
69: }
70: if (windownumber < 0 || windownumber >= PETSC_VIEWER_DRAW_MAX) {
71: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number out of range");
72: }
74: vdraw = (PetscViewer_Draw*)viewer->data;
75: if (!vdraw->draw[windownumber]) {
76: if (vdraw->draw[0]) {
77: PetscDrawGetTitle(vdraw->draw[0],&title);
78: } else title = 0;
79: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
80: &vdraw->draw[windownumber]);
81: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
82: }
83: *draw = vdraw->draw[windownumber];
84: return(0);
85: }
87: /*@C
88: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
89: This PetscDrawLG object may then be used to perform graphics using
90: PetscDrawLGXXX() commands.
92: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
94: Input Parameter:
95: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
96: - windownumber - indicates which subwindow (usually 0)
98: Ouput Parameter:
99: . draw - the draw line graph object
101: Level: intermediate
103: Concepts: line graph^accessing context
105: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
106: @*/
107: int PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
108: {
109: int ierr;
110: PetscTruth isdraw;
111: PetscViewer_Draw *vdraw;
116: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
117: if (!isdraw) {
118: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
119: }
120: if (windownumber < 0 || windownumber >= PETSC_VIEWER_DRAW_MAX) {
121: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number out of range");
122: }
123: vdraw = (PetscViewer_Draw*)viewer->data;
124: if (!vdraw->draw[windownumber]) {
125: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number");
126: }
128: if (!vdraw->drawlg[windownumber]) {
129: PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
130: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
131: }
132: *drawlg = vdraw->drawlg[windownumber];
133: return(0);
134: }
136: /*@C
137: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
138: This PetscDrawAxis object may then be used to perform graphics using
139: PetscDrawAxisXXX() commands.
141: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
143: Input Parameter:
144: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
145: - windownumber - indicates which subwindow (usually 0)
147: Ouput Parameter:
148: . drawaxis - the draw axis object
150: Level: advanced
152: Concepts: line graph^accessing context
154: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
155: @*/
156: int PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
157: {
158: int ierr;
159: PetscTruth isdraw;
160: PetscViewer_Draw *vdraw;
165: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
166: if (!isdraw) {
167: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
168: }
169: if (windownumber < 0 || windownumber >= PETSC_VIEWER_DRAW_MAX) {
170: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number out of range");
171: }
172: vdraw = (PetscViewer_Draw*)viewer->data;
173: if (!vdraw->draw[windownumber]) {
174: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number");
175: }
177: if (!vdraw->drawaxis[windownumber]) {
178: PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
179: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
180: }
181: *drawaxis = vdraw->drawaxis[windownumber];
182: return(0);
183: }
185: int PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
186: {
187: int ierr;
188: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
191: vdraw->h = h;
192: vdraw->w = w;
193: ierr = PetscStrallocpy(display,&vdraw->display);
194: ierr = PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
195: ierr = PetscDrawSetFromOptions(vdraw->draw[0]);
196: PetscLogObjectParent(v,vdraw->draw[0]);
197: return(0);
198: }
200: /*@C
201: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
202: do graphics in this window, you must call PetscViewerDrawGetDraw() and
203: perform the graphics on the PetscDraw object.
205: Collective on MPI_Comm
207: Input Parameters:
208: + comm - communicator that will share window
209: . display - the X display on which to open, or null for the local machine
210: . title - the title to put in the title bar, or null for no title
211: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
212: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
213: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
215: Output Parameters:
216: . viewer - the PetscViewer
218: Format Options:
219: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
220: - PETSC_VIEWER_DRAW_LG - displays using a line graph
222: Options Database Keys:
223: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
224: PetscDrawCreate() for runtime options, including
225: + -draw_type x or null
226: . -nox - Disables all x-windows output
227: . -display <name> - Specifies name of machine for the X display
228: - -draw_pause <pause> - Sets time (in seconds) that the
229: program pauses after PetscDrawPause() has been called
230: (0 is default, -1 implies until user input).
232: Level: beginner
234: Note for Fortran Programmers:
235: Whenever indicating null character data in a Fortran code,
236: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
237: correct for character data! Thus, PETSC_NULL_CHARACTER can be
238: used for the display and title input parameters.
240: Concepts: graphics^opening PetscViewer
241: Concepts: drawing^opening PetscViewer
244: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PetscViewer_DRAW_,
245: PetscViewer_DRAW_WORLD, PetscViewer_DRAW_SELF
246: @*/
247: int PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
248: {
252: PetscViewerCreate(comm,viewer);
253: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
254: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
255: return(0);
256: }
258: int PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
259: {
260: int ierr,rank,i;
261: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
264: if (vdraw->singleton_made) {
265: SETERRQ(1,"Trying to get singleton without first restoring previous");
266: }
268: /* only processor zero can use the PetscViewer draw singleton */
269: MPI_Comm_rank(viewer->comm,&rank);
270: if (!rank) {
271: ierr = PetscViewerCreate(PETSC_COMM_SELF,sviewer);
272: ierr = PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
273: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
274: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
275: if (vdraw->draw[i]) {
276: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
277: }
278: }
279: }
280: vdraw->singleton_made = PETSC_TRUE;
281: return(0);
282: }
284: int PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
285: {
286: int ierr,rank,i;
287: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
290: if (!vdraw->singleton_made) {
291: SETERRQ(1,"Trying to restore a singleton that was not gotten");
292: }
293: MPI_Comm_rank(viewer->comm,&rank);
294: if (!rank) {
295: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
296: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
297: if (vdraw->draw[i] && vsdraw->draw[i]) {
298: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
299: }
300: }
301: PetscFree((*sviewer)->data);
302: PetscLogObjectDestroy((PetscObject)*sviewer);
303: PetscHeaderDestroy((PetscObject)*sviewer);
304: }
305: vdraw->singleton_made = PETSC_FALSE;
306: return(0);
307: }
309: EXTERN_C_BEGIN
310: int PetscViewerCreate_Draw(PetscViewer viewer)
311: {
312: int i,ierr;
313: PetscViewer_Draw *vdraw;
316: ierr = PetscNew(PetscViewer_Draw,&vdraw);
317: viewer->data = (void*)vdraw;
319: viewer->ops->flush = PetscViewerFlush_Draw;
320: viewer->ops->destroy = PetscViewerDestroy_Draw;
321: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
322: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
323: viewer->format = PETSC_VIEWER_NOFORMAT;
325: /* these are created on the fly if requested */
326: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
327: vdraw->draw[i] = 0;
328: vdraw->drawlg[i] = 0;
329: vdraw->drawaxis[i] = 0;
330: }
331: vdraw->singleton_made = PETSC_FALSE;
332: return(0);
333: }
334: EXTERN_C_END
336: /*@
337: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
339: Not Collective
341: Input Parameter:
342: . viewer - the PetscViewer
344: Level: intermediate
346: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
348: @*/
349: int PetscViewerDrawClear(PetscViewer viewer)
350: {
351: int ierr,i;
352: PetscTruth isdraw;
353: PetscViewer_Draw *vdraw;
356: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
357: if (isdraw) {
358: vdraw = (PetscViewer_Draw*)viewer->data;
359: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
360: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
361: }
362: }
363: return(0);
364: }
366: /* ---------------------------------------------------------------------*/
367: /*
368: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
369: is attached to a communicator, in this case the attribute is a PetscViewer.
370: */
371: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
373: /*@C
374: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
375: in a communicator.
377: Collective on MPI_Comm
379: Input Parameter:
380: . comm - the MPI communicator to share the window PetscViewer
382: Level: intermediate
384: Notes:
385: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
386: an error code. The window is usually used in the form
387: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
389: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
390: @*/
391: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
392: {
393: int ierr,flag;
394: PetscViewer viewer;
397: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
398: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
399: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
400: }
401: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
402: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
403: if (!flag) { /* PetscViewer not yet created */
404: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
405: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
406: PetscObjectRegisterDestroy((PetscObject)viewer);
407: if (ierr) {PetscError(__LINE__,"VIEWER_STDOUT_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
408: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
409: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
410: }
411: PetscFunctionReturn(viewer);
412: }