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: PetscInt 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->title);
25: PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
26: PetscFree(vdraw);
27: return(0);
28: }
32: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
33: {
34: PetscErrorCode ierr;
35: PetscInt i;
36: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
39: for (i=0; i<vdraw->draw_max; i++) {
40: if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
41: }
42: return(0);
43: }
47: /*@C
48: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
49: This PetscDraw object may then be used to perform graphics using
50: PetscDrawXXX() commands.
52: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
54: Input Parameters:
55: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
56: - windownumber - indicates which subwindow (usually 0)
58: Ouput Parameter:
59: . draw - the draw object
61: Level: intermediate
63: Concepts: drawing^accessing PetscDraw context from PetscViewer
64: Concepts: graphics
66: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
67: @*/
68: PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
69: {
70: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
71: PetscErrorCode ierr;
72: PetscTruth isdraw;
73: char *title;
78: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
79: if (!isdraw) {
80: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
81: }
82: if (windownumber < 0) {
83: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
84: }
85: windownumber += vdraw->draw_base;
86: if (windownumber >= vdraw->draw_max) {
87: /* allocate twice as many slots as needed */
88: PetscInt 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: PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
95: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
96: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
97: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
99: PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
100: PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
101: PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));
103: PetscFree3(tdraw,drawlg,drawaxis);
104: }
106: if (!vdraw->draw[windownumber]) {
107: if (!windownumber) {
108: title = vdraw->title;
109: } else {
110: char tmp_str[128];
111: PetscSNPrintf(tmp_str, 128, "%s:%d", vdraw->title,windownumber);
112: title = tmp_str;
113: }
114: PetscDrawCreate(((PetscObject)viewer)->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);
115: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
116: }
117: if (draw) *draw = vdraw->draw[windownumber];
118: return(0);
119: }
123: /*@C
124: PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
126: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
128: Input Parameters:
129: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
130: - windownumber - how much to add to the base
132: Level: developer
134: Concepts: drawing^accessing PetscDraw context from PetscViewer
135: Concepts: graphics
137: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
138: @*/
139: PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
140: {
141: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
142: PetscErrorCode ierr;
143: PetscTruth isdraw;
147: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
148: if (!isdraw) {
149: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
150: }
151: if (windownumber + vdraw->draw_base < 0) {
152: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
153: }
154: vdraw->draw_base += windownumber;
155: return(0);
156: }
160: /*@C
161: PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
163: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
165: Input Parameters:
166: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
167: - windownumber - value to set the base
169: Level: developer
171: Concepts: drawing^accessing PetscDraw context from PetscViewer
172: Concepts: graphics
174: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
175: @*/
176: PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
177: {
178: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
179: PetscErrorCode ierr;
180: PetscTruth isdraw;
184: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
185: if (!isdraw) {
186: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
187: }
188: if (windownumber < 0) {
189: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
190: }
191: vdraw->draw_base = windownumber;
192: return(0);
193: }
197: /*@C
198: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
199: This PetscDrawLG object may then be used to perform graphics using
200: PetscDrawLGXXX() commands.
202: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
204: Input Parameter:
205: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
206: - windownumber - indicates which subwindow (usually 0)
208: Ouput Parameter:
209: . draw - the draw line graph object
211: Level: intermediate
213: Concepts: line graph^accessing context
215: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
216: @*/
217: PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
218: {
219: PetscErrorCode ierr;
220: PetscTruth isdraw;
221: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
226: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
227: if (!isdraw) {
228: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
229: }
230: if (windownumber < 0) {
231: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
232: }
234: if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
235: PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
236: }
237: if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
238: PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
239: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber+vdraw->draw_base]);
240: }
241: *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
242: return(0);
243: }
247: /*@C
248: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
249: This PetscDrawAxis object may then be used to perform graphics using
250: PetscDrawAxisXXX() commands.
252: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
254: Input Parameter:
255: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
256: - windownumber - indicates which subwindow (usually 0)
258: Ouput Parameter:
259: . drawaxis - the draw axis object
261: Level: advanced
263: Concepts: line graph^accessing context
265: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
266: @*/
267: PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
268: {
269: PetscErrorCode ierr;
270: PetscTruth isdraw;
271: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
276: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
277: if (!isdraw) {
278: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
279: }
280: if (windownumber < 0) {
281: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
282: }
284: if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
285: PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
286: }
287: if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
288: PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
289: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber+vdraw->draw_base]);
290: }
291: *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
292: return(0);
293: }
297: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
298: {
299: PetscErrorCode ierr;
300: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
303: vdraw->h = h;
304: vdraw->w = w;
305: PetscStrallocpy(display,&vdraw->display);
306: PetscStrallocpy(title,&vdraw->title);
307: return(0);
308: }
312: /*@C
313: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
314: do graphics in this window, you must call PetscViewerDrawGetDraw() and
315: perform the graphics on the PetscDraw object.
317: Collective on MPI_Comm
319: Input Parameters:
320: + comm - communicator that will share window
321: . display - the X display on which to open, or null for the local machine
322: . title - the title to put in the title bar, or null for no title
323: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
324: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
325: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
327: Output Parameters:
328: . viewer - the PetscViewer
330: Format Options:
331: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
332: - PETSC_VIEWER_DRAW_LG - displays using a line graph
334: Options Database Keys:
335: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
336: PetscDrawCreate() for runtime options, including
337: + -draw_type x or null
338: . -nox - Disables all x-windows output
339: . -display <name> - Specifies name of machine for the X display
340: . -geometry <x,y,w,h> - allows setting the window location and size
341: - -draw_pause <pause> - Sets time (in seconds) that the
342: program pauses after PetscDrawPause() has been called
343: (0 is default, -1 implies until user input).
345: Level: beginner
347: Note for Fortran Programmers:
348: Whenever indicating null character data in a Fortran code,
349: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
350: correct for character data! Thus, PETSC_NULL_CHARACTER can be
351: used for the display and title input parameters.
353: Concepts: graphics^opening PetscViewer
354: Concepts: drawing^opening PetscViewer
357: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
358: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
359: @*/
360: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
361: {
365: PetscViewerCreate(comm,viewer);
366: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
367: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
368: return(0);
369: }
373: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
374: {
375: PetscErrorCode ierr;
376: PetscMPIInt rank;
377: PetscInt i;
378: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
381: if (vdraw->singleton_made) {
382: SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
383: }
385: /* only processor zero can use the PetscViewer draw singleton */
386: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
387: if (!rank) {
388: PetscViewerCreate(PETSC_COMM_SELF,sviewer);
389: PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
390: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
391: for (i=0; i<vdraw->draw_max; i++) {
392: if (vdraw->draw[i]) {
393: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
394: }
395: }
396: }
397: vdraw->singleton_made = PETSC_TRUE;
398: return(0);
399: }
403: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
404: {
405: PetscErrorCode ierr;
406: PetscMPIInt rank;
407: PetscInt i;
408: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
411: if (!vdraw->singleton_made) {
412: SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
413: }
414: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
415: if (!rank) {
416: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
417: for (i=0; i<vdraw->draw_max; i++) {
418: if (vdraw->draw[i] && vsdraw->draw[i]) {
419: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
420: }
421: }
422: PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);
423: PetscFree((*sviewer)->data);
424: PetscHeaderDestroy(*sviewer);
425: }
426: vdraw->singleton_made = PETSC_FALSE;
427: return(0);
428: }
433: PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
434: {
435: PetscInt i;
436: PetscErrorCode ierr;
437: PetscViewer_Draw *vdraw;
440: PetscNewLog(viewer,PetscViewer_Draw,&vdraw);
441: viewer->data = (void*)vdraw;
443: viewer->ops->flush = PetscViewerFlush_Draw;
444: viewer->ops->destroy = PetscViewerDestroy_Draw;
445: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
446: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
447: viewer->format = PETSC_VIEWER_NOFORMAT;
449: /* these are created on the fly if requested */
450: vdraw->draw_max = 5;
451: vdraw->draw_base = 0;
452: PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
453: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
454: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
455: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
456: for (i=0; i<vdraw->draw_max; i++) {
457: vdraw->draw[i] = 0;
458: vdraw->drawlg[i] = 0;
459: vdraw->drawaxis[i] = 0;
460: }
461: vdraw->singleton_made = PETSC_FALSE;
462: return(0);
463: }
468: /*@
469: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
471: Not Collective
473: Input Parameter:
474: . viewer - the PetscViewer
476: Level: intermediate
478: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
480: @*/
481: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
482: {
483: PetscErrorCode ierr;
484: PetscInt i;
485: PetscTruth isdraw;
486: PetscViewer_Draw *vdraw;
489: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
490: if (isdraw) {
491: vdraw = (PetscViewer_Draw*)viewer->data;
492: for (i=0; i<vdraw->draw_max; i++) {
493: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
494: }
495: }
496: return(0);
497: }
499: /* ---------------------------------------------------------------------*/
500: /*
501: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
502: is attached to a communicator, in this case the attribute is a PetscViewer.
503: */
504: static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
508: /*@C
509: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
510: in a communicator.
512: Collective on MPI_Comm
514: Input Parameter:
515: . comm - the MPI communicator to share the window PetscViewer
517: Level: intermediate
519: Notes:
520: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
521: an error code. The window is usually used in the form
522: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
524: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
525: @*/
526: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
527: {
529: PetscMPIInt flag;
530: PetscViewer viewer;
533: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
534: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
535: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
536: }
537: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
538: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
539: if (!flag) { /* PetscViewer not yet created */
540: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
541: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
542: PetscObjectRegisterDestroy((PetscObject)viewer);
543: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
544: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
545: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
546: }
547: PetscFunctionReturn(viewer);
548: }