Actual source code: drawv.c
1: /*$Id: drawv.c,v 1.59 2001/04/10 19:34:07 bsmith Exp $*/
3: #include "petsc.h"
4: #include "src/sys/src/viewer/impls/draw/vdraw.h" /*I "petscdraw.h" I*/
6: int PetscViewerDestroy_Draw(PetscViewer v)
7: {
8: int ierr,i;
9: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
12: if (vdraw->singleton_made) {
13: SETERRQ(1,"Destroying PetscViewer without first restoring singleton");
14: }
15: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
16: if (vdraw->drawaxis[i]) {PetscDrawAxisDestroy(vdraw->drawaxis[i]);}
17: if (vdraw->drawlg[i]) {PetscDrawLGDestroy(vdraw->drawlg[i]);}
18: if (vdraw->draw[i]) {PetscDrawDestroy(vdraw->draw[i]);}
19: }
20: PetscFree(vdraw);
21: return(0);
22: }
24: int PetscViewerFlush_Draw(PetscViewer v)
25: {
26: int ierr,i;
27: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
30: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
31: if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
32: }
33: return(0);
34: }
36: /*@C
37: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
38: This PetscDraw object may then be used to perform graphics using
39: PetscDrawXXX() commands.
41: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
43: Input Parameter:
44: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
45: - windownumber - indicates which subwindow (usually 0)
47: Ouput Parameter:
48: . draw - the draw object
50: Level: intermediate
52: Concepts: drawing^accessing PetscDraw context from PetscViewer
53: Concepts: graphics
55: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
56: @*/
57: int PetscViewerDrawGetDraw(PetscViewer viewer,int windownumber,PetscDraw *draw)
58: {
59: PetscViewer_Draw *vdraw;
60: int ierr;
61: PetscTruth isdraw;
62: char *title;
67: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
68: if (!isdraw) {
69: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
70: }
71: if (windownumber < 0 || windownumber >= PETSC_VIEWER_DRAW_MAX) {
72: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number out of range");
73: }
75: vdraw = (PetscViewer_Draw*)viewer->data;
76: if (!vdraw->draw[windownumber]) {
77: if (vdraw->draw[0]) {
78: PetscDrawGetTitle(vdraw->draw[0],&title);
79: } else title = 0;
80: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
81: &vdraw->draw[windownumber]);
82: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
83: }
84: *draw = vdraw->draw[windownumber];
85: return(0);
86: }
88: /*@C
89: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
90: This PetscDrawLG object may then be used to perform graphics using
91: PetscDrawLGXXX() commands.
93: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
95: Input Parameter:
96: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
97: - windownumber - indicates which subwindow (usually 0)
99: Ouput Parameter:
100: . draw - the draw line graph object
102: Level: intermediate
104: Concepts: line graph^accessing context
106: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
107: @*/
108: int PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
109: {
110: int ierr;
111: PetscTruth isdraw;
112: PetscViewer_Draw *vdraw;
117: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
118: if (!isdraw) {
119: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
120: }
121: if (windownumber < 0 || windownumber >= PETSC_VIEWER_DRAW_MAX) {
122: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number out of range");
123: }
124: vdraw = (PetscViewer_Draw*)viewer->data;
125: if (!vdraw->draw[windownumber]) {
126: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number");
127: }
129: if (!vdraw->drawlg[windownumber]) {
130: PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
131: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
132: }
133: *drawlg = vdraw->drawlg[windownumber];
134: return(0);
135: }
137: /*@C
138: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
139: This PetscDrawAxis object may then be used to perform graphics using
140: PetscDrawAxisXXX() commands.
142: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
144: Input Parameter:
145: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
146: - windownumber - indicates which subwindow (usually 0)
148: Ouput Parameter:
149: . drawaxis - the draw axis object
151: Level: advanced
153: Concepts: line graph^accessing context
155: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
156: @*/
157: int PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
158: {
159: int ierr;
160: PetscTruth isdraw;
161: PetscViewer_Draw *vdraw;
166: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
167: if (!isdraw) {
168: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
169: }
170: if (windownumber < 0 || windownumber >= PETSC_VIEWER_DRAW_MAX) {
171: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number out of range");
172: }
173: vdraw = (PetscViewer_Draw*)viewer->data;
174: if (!vdraw->draw[windownumber]) {
175: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number");
176: }
178: if (!vdraw->drawaxis[windownumber]) {
179: PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
180: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
181: }
182: *drawaxis = vdraw->drawaxis[windownumber];
183: return(0);
184: }
186: int PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
187: {
188: int ierr;
189: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
192: vdraw->h = h;
193: vdraw->w = w;
194: ierr = PetscStrallocpy(display,&vdraw->display);
195: ierr = PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
196: ierr = PetscDrawSetFromOptions(vdraw->draw[0]);
197: PetscLogObjectParent(v,vdraw->draw[0]);
198: return(0);
199: }
201: /*@C
202: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
203: do graphics in this window, you must call PetscViewerDrawGetDraw() and
204: perform the graphics on the PetscDraw object.
206: Collective on MPI_Comm
208: Input Parameters:
209: + comm - communicator that will share window
210: . display - the X display on which to open, or null for the local machine
211: . title - the title to put in the title bar, or null for no title
212: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
213: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
214: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
216: Output Parameters:
217: . viewer - the PetscViewer
219: Format Options:
220: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
221: - PETSC_VIEWER_DRAW_LG - displays using a line graph
223: Options Database Keys:
224: PetscViewerDrawOpen() calls PetscDrawOpen(), so see the manual page for
225: PetscDrawOpen() for runtime options, including
226: + -draw_type x or null
227: . -nox - Disables all x-windows output
228: . -display <name> - Specifies name of machine for the X display
229: - -draw_pause <pause> - Sets time (in seconds) that the
230: program pauses after PetscDrawPause() has been called
231: (0 is default, -1 implies until user input).
233: Level: beginner
235: Note for Fortran Programmers:
236: Whenever indicating null character data in a Fortran code,
237: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
238: correct for character data! Thus, PETSC_NULL_CHARACTER can be
239: used for the display and title input parameters.
241: Concepts: graphics^opening PetscViewer
242: Concepts: drawing^opening PetscViewer
245: .seealso: PetscDrawOpen(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PetscViewer_DRAW_,
246: PetscViewer_DRAW_WORLD, PetscViewer_DRAW_SELF
247: @*/
248: int PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
249: {
253: PetscViewerCreate(comm,viewer);
254: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
255: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
256: return(0);
257: }
259: int PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
260: {
261: int ierr,rank,i;
262: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
265: if (vdraw->singleton_made) {
266: SETERRQ(1,"Trying to get singleton without first restoring previous");
267: }
269: /* only processor zero can use the PetscViewer draw singleton */
270: MPI_Comm_rank(viewer->comm,&rank);
271: if (!rank) {
272: ierr = PetscViewerCreate(PETSC_COMM_SELF,sviewer);
273: ierr = PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
274: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
275: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
276: if (vdraw->draw[i]) {
277: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
278: }
279: }
280: }
281: vdraw->singleton_made = PETSC_TRUE;
282: return(0);
283: }
285: int PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
286: {
287: int ierr,rank,i;
288: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
291: if (!vdraw->singleton_made) {
292: SETERRQ(1,"Trying to restore a singleton that was not gotten");
293: }
294: MPI_Comm_rank(viewer->comm,&rank);
295: if (!rank) {
296: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
297: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
298: if (vdraw->draw[i] && vsdraw->draw[i]) {
299: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
300: }
301: }
302: PetscFree((*sviewer)->data);
303: PetscLogObjectDestroy((PetscObject)*sviewer);
304: PetscHeaderDestroy((PetscObject)*sviewer);
305: }
306: vdraw->singleton_made = PETSC_FALSE;
307: return(0);
308: }
310: EXTERN_C_BEGIN
311: int PetscViewerCreate_Draw(PetscViewer viewer)
312: {
313: int i,ierr;
314: PetscViewer_Draw *vdraw;
317: ierr = PetscNew(PetscViewer_Draw,&vdraw);
318: viewer->data = (void*)vdraw;
320: viewer->ops->flush = PetscViewerFlush_Draw;
321: viewer->ops->destroy = PetscViewerDestroy_Draw;
322: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
323: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
324: viewer->format = PETSC_VIEWER_NOFORMAT;
326: /* these are created on the fly if requested */
327: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
328: vdraw->draw[i] = 0;
329: vdraw->drawlg[i] = 0;
330: vdraw->drawaxis[i] = 0;
331: }
332: vdraw->singleton_made = PETSC_FALSE;
333: return(0);
334: }
335: EXTERN_C_END
337: /*@
338: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
340: Not Collective
342: Input Parameter:
343: . viewer - the PetscViewer
345: Level: intermediate
347: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
349: @*/
350: int PetscViewerDrawClear(PetscViewer viewer)
351: {
352: int ierr,i;
353: PetscTruth isdraw;
354: PetscViewer_Draw *vdraw;
357: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
358: if (isdraw) {
359: vdraw = (PetscViewer_Draw*)viewer->data;
360: for (i=0; i<PETSC_VIEWER_DRAW_MAX; i++) {
361: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
362: }
363: }
364: return(0);
365: }
367: /* ---------------------------------------------------------------------*/
368: /*
369: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
370: is attached to a communicator, in this case the attribute is a PetscViewer.
371: */
372: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
374: /*@C
375: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
376: in a communicator.
378: Collective on MPI_Comm
380: Input Parameter:
381: . comm - the MPI communicator to share the window PetscViewer
383: Level: intermediate
385: Notes:
386: Unlike almost all other PETSc routines, PETSC)VIEWER_DRAW_ does not return
387: an error code. The window is usually used in the form
388: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
390: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
391: @*/
392: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
393: {
394: int ierr,flag;
395: PetscViewer viewer;
398: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
399: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
400: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1,0); viewer = 0;}
401: }
402: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
403: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1,0); viewer = 0;}
404: if (!flag) { /* PetscViewer not yet created */
405: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
406: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1,0); viewer = 0;}
407: PetscObjectRegisterDestroy((PetscObject)viewer);
408: if (ierr) {PetscError(__LINE__,"VIEWER_STDOUT_",__FILE__,__SDIR__,1,1,0); viewer = 0;}
409: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
410: if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1,0); viewer = 0;}
411: }
412: PetscFunctionReturn(viewer);
413: }