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: #undef __FUNCT__
7: int PetscViewerDestroy_Draw(PetscViewer v)
8: {
9: int ierr,i;
10: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
13: if (vdraw->singleton_made) {
14: SETERRQ(1,"Destroying PetscViewer without first restoring singleton");
15: }
16: for (i=0; i<vdraw->draw_max; i++) {
17: if (vdraw->drawaxis[i]) {PetscDrawAxisDestroy(vdraw->drawaxis[i]);}
18: if (vdraw->drawlg[i]) {PetscDrawLGDestroy(vdraw->drawlg[i]);}
19: if (vdraw->draw[i]) {PetscDrawDestroy(vdraw->draw[i]);}
20: }
21: PetscFree(vdraw->drawaxis);
22: PetscFree(vdraw->drawlg);
23: PetscFree(vdraw->draw);
24: PetscFree(vdraw);
25: return(0);
26: }
28: #undef __FUNCT__
30: int PetscViewerFlush_Draw(PetscViewer v)
31: {
32: int ierr,i;
33: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
36: for (i=0; i<vdraw->draw_max; i++) {
37: if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
38: }
39: return(0);
40: }
42: #undef __FUNCT__
44: /*@C
45: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
46: This PetscDraw object may then be used to perform graphics using
47: PetscDrawXXX() commands.
49: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
51: Input Parameters:
52: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
53: - windownumber - indicates which subwindow (usually 0)
55: Ouput Parameter:
56: . draw - the draw object
58: Level: intermediate
60: Concepts: drawing^accessing PetscDraw context from PetscViewer
61: Concepts: graphics
63: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
64: @*/
65: int PetscViewerDrawGetDraw(PetscViewer viewer,int windownumber,PetscDraw *draw)
66: {
67: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
68: int ierr;
69: PetscTruth isdraw;
70: char *title;
75: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
76: if (!isdraw) {
77: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
78: }
79: if (windownumber < 0) {
80: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
81: }
82: if (windownumber >= vdraw->draw_max) {
83: /* allocate twice as many slots as needed */
84: int draw_max = vdraw->draw_max;
85: PetscDraw *tdraw = vdraw->draw;
86: PetscDrawLG *drawlg = vdraw->drawlg;
87: PetscDrawAxis *drawaxis = vdraw->drawaxis;
89: vdraw->draw_max = 2*windownumber;
90: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
91: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
92: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
93: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
94: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
95: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
97: PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
98: PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
99: PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));
101: PetscFree(tdraw);
102: PetscFree(drawlg);
103: PetscFree(drawaxis);
104: }
106: if (!vdraw->draw[windownumber]) {
107: if (vdraw->draw[0]) {
108: PetscDrawGetTitle(vdraw->draw[0],&title);
109: } else title = 0;
110: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
111: &vdraw->draw[windownumber]);
112: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
113: }
114: *draw = vdraw->draw[windownumber];
115: return(0);
116: }
118: #undef __FUNCT__
120: /*@C
121: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
122: This PetscDrawLG object may then be used to perform graphics using
123: PetscDrawLGXXX() commands.
125: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
127: Input Parameter:
128: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
129: - windownumber - indicates which subwindow (usually 0)
131: Ouput Parameter:
132: . draw - the draw line graph object
134: Level: intermediate
136: Concepts: line graph^accessing context
138: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
139: @*/
140: int PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
141: {
142: int ierr;
143: PetscTruth isdraw;
144: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
149: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
150: if (!isdraw) {
151: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
152: }
153: if (windownumber < 0) {
154: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
155: }
156: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
157: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
158: }
160: if (!vdraw->drawlg[windownumber]) {
161: PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
162: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
163: }
164: *drawlg = vdraw->drawlg[windownumber];
165: return(0);
166: }
168: #undef __FUNCT__
170: /*@C
171: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
172: This PetscDrawAxis object may then be used to perform graphics using
173: PetscDrawAxisXXX() commands.
175: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
177: Input Parameter:
178: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
179: - windownumber - indicates which subwindow (usually 0)
181: Ouput Parameter:
182: . drawaxis - the draw axis object
184: Level: advanced
186: Concepts: line graph^accessing context
188: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
189: @*/
190: int PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
191: {
192: int ierr;
193: PetscTruth isdraw;
194: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
199: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
200: if (!isdraw) {
201: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
202: }
203: if (windownumber < 0) {
204: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
205: }
206: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
207: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
208: }
210: if (!vdraw->drawaxis[windownumber]) {
211: PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
212: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
213: }
214: *drawaxis = vdraw->drawaxis[windownumber];
215: return(0);
216: }
218: #undef __FUNCT__
220: int PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
221: {
222: int ierr;
223: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
226: vdraw->h = h;
227: vdraw->w = w;
228: ierr = PetscStrallocpy(display,&vdraw->display);
229: ierr = PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
230: ierr = PetscDrawSetFromOptions(vdraw->draw[0]);
231: PetscLogObjectParent(v,vdraw->draw[0]);
232: return(0);
233: }
235: #undef __FUNCT__
237: /*@C
238: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
239: do graphics in this window, you must call PetscViewerDrawGetDraw() and
240: perform the graphics on the PetscDraw object.
242: Collective on MPI_Comm
244: Input Parameters:
245: + comm - communicator that will share window
246: . display - the X display on which to open, or null for the local machine
247: . title - the title to put in the title bar, or null for no title
248: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
249: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
250: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
252: Output Parameters:
253: . viewer - the PetscViewer
255: Format Options:
256: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
257: - PETSC_VIEWER_DRAW_LG - displays using a line graph
259: Options Database Keys:
260: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
261: PetscDrawCreate() for runtime options, including
262: + -draw_type x or null
263: . -nox - Disables all x-windows output
264: . -display <name> - Specifies name of machine for the X display
265: - -draw_pause <pause> - Sets time (in seconds) that the
266: program pauses after PetscDrawPause() has been called
267: (0 is default, -1 implies until user input).
269: Level: beginner
271: Note for Fortran Programmers:
272: Whenever indicating null character data in a Fortran code,
273: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
274: correct for character data! Thus, PETSC_NULL_CHARACTER can be
275: used for the display and title input parameters.
277: Concepts: graphics^opening PetscViewer
278: Concepts: drawing^opening PetscViewer
281: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
282: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
283: @*/
284: int PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
285: {
289: PetscViewerCreate(comm,viewer);
290: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
291: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
292: return(0);
293: }
295: #undef __FUNCT__
297: int PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
298: {
299: int ierr,rank,i;
300: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
303: if (vdraw->singleton_made) {
304: SETERRQ(1,"Trying to get singleton without first restoring previous");
305: }
307: /* only processor zero can use the PetscViewer draw singleton */
308: MPI_Comm_rank(viewer->comm,&rank);
309: if (!rank) {
310: ierr = PetscViewerCreate(PETSC_COMM_SELF,sviewer);
311: ierr = PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
312: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
313: for (i=0; i<vdraw->draw_max; i++) {
314: if (vdraw->draw[i]) {
315: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
316: }
317: }
318: }
319: vdraw->singleton_made = PETSC_TRUE;
320: return(0);
321: }
323: #undef __FUNCT__
325: int PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
326: {
327: int ierr,rank,i;
328: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
331: if (!vdraw->singleton_made) {
332: SETERRQ(1,"Trying to restore a singleton that was not gotten");
333: }
334: MPI_Comm_rank(viewer->comm,&rank);
335: if (!rank) {
336: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
337: for (i=0; i<vdraw->draw_max; i++) {
338: if (vdraw->draw[i] && vsdraw->draw[i]) {
339: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
340: }
341: }
342: PetscFree(vsdraw->drawaxis);
343: PetscFree(vsdraw->drawlg);
344: PetscFree(vsdraw->draw);
345: PetscFree((*sviewer)->data);
346: PetscLogObjectDestroy((PetscObject)*sviewer);
347: PetscHeaderDestroy((PetscObject)*sviewer);
348: }
349: vdraw->singleton_made = PETSC_FALSE;
350: return(0);
351: }
353: EXTERN_C_BEGIN
354: #undef __FUNCT__
356: int PetscViewerCreate_Draw(PetscViewer viewer)
357: {
358: int i,ierr;
359: PetscViewer_Draw *vdraw;
362: ierr = PetscNew(PetscViewer_Draw,&vdraw);
363: viewer->data = (void*)vdraw;
365: viewer->ops->flush = PetscViewerFlush_Draw;
366: viewer->ops->destroy = PetscViewerDestroy_Draw;
367: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
368: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
369: viewer->format = PETSC_VIEWER_NOFORMAT;
371: /* these are created on the fly if requested */
372: vdraw->draw_max = 5;
373: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
374: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
375: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
376: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
377: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
378: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
379: for (i=0; i<vdraw->draw_max; i++) {
380: vdraw->draw[i] = 0;
381: vdraw->drawlg[i] = 0;
382: vdraw->drawaxis[i] = 0;
383: }
384: vdraw->singleton_made = PETSC_FALSE;
385: return(0);
386: }
387: EXTERN_C_END
389: #undef __FUNCT__
391: /*@
392: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
394: Not Collective
396: Input Parameter:
397: . viewer - the PetscViewer
399: Level: intermediate
401: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
403: @*/
404: int PetscViewerDrawClear(PetscViewer viewer)
405: {
406: int ierr,i;
407: PetscTruth isdraw;
408: PetscViewer_Draw *vdraw;
411: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
412: if (isdraw) {
413: vdraw = (PetscViewer_Draw*)viewer->data;
414: for (i=0; i<vdraw->draw_max; i++) {
415: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
416: }
417: }
418: return(0);
419: }
421: /* ---------------------------------------------------------------------*/
422: /*
423: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
424: is attached to a communicator, in this case the attribute is a PetscViewer.
425: */
426: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
428: /*MC
429: PETSC_VIEWER_DRAW_WORLD - same as PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD)
431: Level: intermediate
432: M*/
434: /*MC
435: PETSC_VIEWER_DRAW_SELF - same as PETSC_VIEWER_DRAW_(PETSC_COMM_SELF)
437: Level: intermediate
438: M*/
440: #undef __FUNCT__
442: /*@C
443: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
444: in a communicator.
446: Collective on MPI_Comm
448: Input Parameter:
449: . comm - the MPI communicator to share the window PetscViewer
451: Level: intermediate
453: Notes:
454: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
455: an error code. The window is usually used in the form
456: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
458: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
459: @*/
460: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
461: {
462: int ierr,flag;
463: PetscViewer viewer;
466: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
467: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
468: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
469: }
470: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
471: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
472: if (!flag) { /* PetscViewer not yet created */
473: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
474: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
475: PetscObjectRegisterDestroy((PetscObject)viewer);
476: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
477: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
478: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
479: }
480: PetscFunctionReturn(viewer);
481: }