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: PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
25: PetscFree(vdraw);
26: return(0);
27: }
31: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
32: {
33: PetscErrorCode ierr;
34: PetscInt i;
35: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
38: for (i=0; i<vdraw->draw_max; i++) {
39: if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
40: }
41: return(0);
42: }
46: /*@C
47: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
48: This PetscDraw object may then be used to perform graphics using
49: PetscDrawXXX() commands.
51: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
53: Input Parameters:
54: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
55: - windownumber - indicates which subwindow (usually 0)
57: Ouput Parameter:
58: . draw - the draw object
60: Level: intermediate
62: Concepts: drawing^accessing PetscDraw context from PetscViewer
63: Concepts: graphics
65: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
66: @*/
67: PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
68: {
69: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
70: PetscErrorCode ierr;
71: PetscTruth isdraw;
72: char *title;
77: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
78: if (!isdraw) {
79: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
80: }
81: if (windownumber < 0) {
82: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
83: }
84: windownumber += vdraw->draw_base;
85: if (windownumber >= vdraw->draw_max) {
86: /* allocate twice as many slots as needed */
87: PetscInt draw_max = vdraw->draw_max;
88: PetscDraw *tdraw = vdraw->draw;
89: PetscDrawLG *drawlg = vdraw->drawlg;
90: PetscDrawAxis *drawaxis = vdraw->drawaxis;
92: vdraw->draw_max = 2*windownumber;
93: PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
94: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
95: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
96: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
98: PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
99: PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
100: PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));
102: PetscFree3(tdraw,drawlg,drawaxis);
103: }
105: if (!vdraw->draw[windownumber]) {
106: if (vdraw->draw[0]) {
107: PetscDrawGetTitle(vdraw->draw[0],&title);
108: } else title = 0;
109: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);
110: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
111: }
112: if (draw) *draw = vdraw->draw[windownumber];
113: return(0);
114: }
118: /*@C
119: PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
121: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
123: Input Parameters:
124: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
125: - windownumber - how much to add to the base
127: Level: developer
129: Concepts: drawing^accessing PetscDraw context from PetscViewer
130: Concepts: graphics
132: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
133: @*/
134: PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
135: {
136: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
137: PetscErrorCode ierr;
138: PetscTruth isdraw;
142: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
143: if (!isdraw) {
144: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
145: }
146: if (windownumber + vdraw->draw_base < 0) {
147: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
148: }
149: vdraw->draw_base += windownumber;
150: return(0);
151: }
155: /*@C
156: PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
158: Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
160: Input Parameters:
161: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
162: - windownumber - value to set the base
164: Level: developer
166: Concepts: drawing^accessing PetscDraw context from PetscViewer
167: Concepts: graphics
169: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
170: @*/
171: PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
172: {
173: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
174: PetscErrorCode ierr;
175: PetscTruth isdraw;
179: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
180: if (!isdraw) {
181: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
182: }
183: if (windownumber < 0) {
184: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
185: }
186: vdraw->draw_base = windownumber;
187: return(0);
188: }
192: /*@C
193: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
194: This PetscDrawLG object may then be used to perform graphics using
195: PetscDrawLGXXX() commands.
197: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
199: Input Parameter:
200: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
201: - windownumber - indicates which subwindow (usually 0)
203: Ouput Parameter:
204: . draw - the draw line graph object
206: Level: intermediate
208: Concepts: line graph^accessing context
210: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
211: @*/
212: PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
213: {
214: PetscErrorCode ierr;
215: PetscTruth isdraw;
216: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
221: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
222: if (!isdraw) {
223: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
224: }
225: if (windownumber < 0) {
226: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
227: }
229: if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
230: PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
231: }
232: if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
233: PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
234: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber+vdraw->draw_base]);
235: }
236: *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
237: return(0);
238: }
242: /*@C
243: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
244: This PetscDrawAxis object may then be used to perform graphics using
245: PetscDrawAxisXXX() commands.
247: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
249: Input Parameter:
250: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
251: - windownumber - indicates which subwindow (usually 0)
253: Ouput Parameter:
254: . drawaxis - the draw axis object
256: Level: advanced
258: Concepts: line graph^accessing context
260: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
261: @*/
262: PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
263: {
264: PetscErrorCode ierr;
265: PetscTruth isdraw;
266: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
271: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
272: if (!isdraw) {
273: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
274: }
275: if (windownumber < 0) {
276: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
277: }
279: if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
280: PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
281: }
282: if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
283: PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
284: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber+vdraw->draw_base]);
285: }
286: *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
287: return(0);
288: }
292: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
293: {
294: PetscErrorCode ierr;
295: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
298: vdraw->h = h;
299: vdraw->w = w;
300: PetscStrallocpy(display,&vdraw->display);
301: /* PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
302: PetscDrawSetFromOptions(vdraw->draw[0]);*/
303: return(0);
304: }
308: /*@C
309: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
310: do graphics in this window, you must call PetscViewerDrawGetDraw() and
311: perform the graphics on the PetscDraw object.
313: Collective on MPI_Comm
315: Input Parameters:
316: + comm - communicator that will share window
317: . display - the X display on which to open, or null for the local machine
318: . title - the title to put in the title bar, or null for no title
319: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
320: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
321: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
323: Output Parameters:
324: . viewer - the PetscViewer
326: Format Options:
327: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
328: - PETSC_VIEWER_DRAW_LG - displays using a line graph
330: Options Database Keys:
331: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
332: PetscDrawCreate() for runtime options, including
333: + -draw_type x or null
334: . -nox - Disables all x-windows output
335: . -display <name> - Specifies name of machine for the X display
336: . -geometry <x,y,w,h> - allows setting the window location and size
337: - -draw_pause <pause> - Sets time (in seconds) that the
338: program pauses after PetscDrawPause() has been called
339: (0 is default, -1 implies until user input).
341: Level: beginner
343: Note for Fortran Programmers:
344: Whenever indicating null character data in a Fortran code,
345: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
346: correct for character data! Thus, PETSC_NULL_CHARACTER can be
347: used for the display and title input parameters.
349: Concepts: graphics^opening PetscViewer
350: Concepts: drawing^opening PetscViewer
353: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
354: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
355: @*/
356: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
357: {
361: PetscViewerCreate(comm,viewer);
362: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
363: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
364: return(0);
365: }
369: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
370: {
371: PetscErrorCode ierr;
372: PetscMPIInt rank;
373: PetscInt i;
374: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
377: if (vdraw->singleton_made) {
378: SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
379: }
381: /* only processor zero can use the PetscViewer draw singleton */
382: MPI_Comm_rank(viewer->comm,&rank);
383: if (!rank) {
384: PetscViewerCreate(PETSC_COMM_SELF,sviewer);
385: PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
386: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
387: for (i=0; i<vdraw->draw_max; i++) {
388: if (vdraw->draw[i]) {
389: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
390: }
391: }
392: }
393: vdraw->singleton_made = PETSC_TRUE;
394: return(0);
395: }
399: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
400: {
401: PetscErrorCode ierr;
402: PetscMPIInt rank;
403: PetscInt i;
404: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
407: if (!vdraw->singleton_made) {
408: SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
409: }
410: MPI_Comm_rank(viewer->comm,&rank);
411: if (!rank) {
412: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
413: for (i=0; i<vdraw->draw_max; i++) {
414: if (vdraw->draw[i] && vsdraw->draw[i]) {
415: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
416: }
417: }
418: PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);
419: PetscFree((*sviewer)->data);
420: PetscHeaderDestroy(*sviewer);
421: }
422: vdraw->singleton_made = PETSC_FALSE;
423: return(0);
424: }
429: PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
430: {
431: PetscInt i;
432: PetscErrorCode ierr;
433: PetscViewer_Draw *vdraw;
436: PetscNew(PetscViewer_Draw,&vdraw);
437: viewer->data = (void*)vdraw;
439: viewer->ops->flush = PetscViewerFlush_Draw;
440: viewer->ops->destroy = PetscViewerDestroy_Draw;
441: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
442: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
443: viewer->format = PETSC_VIEWER_NOFORMAT;
445: /* these are created on the fly if requested */
446: vdraw->draw_max = 5;
447: vdraw->draw_base = 0;
448: PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
449: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
450: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
451: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
452: for (i=0; i<vdraw->draw_max; i++) {
453: vdraw->draw[i] = 0;
454: vdraw->drawlg[i] = 0;
455: vdraw->drawaxis[i] = 0;
456: }
457: vdraw->singleton_made = PETSC_FALSE;
458: return(0);
459: }
464: /*@
465: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
467: Not Collective
469: Input Parameter:
470: . viewer - the PetscViewer
472: Level: intermediate
474: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
476: @*/
477: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
478: {
479: PetscErrorCode ierr;
480: PetscInt i;
481: PetscTruth isdraw;
482: PetscViewer_Draw *vdraw;
485: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
486: if (isdraw) {
487: vdraw = (PetscViewer_Draw*)viewer->data;
488: for (i=0; i<vdraw->draw_max; i++) {
489: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
490: }
491: }
492: return(0);
493: }
495: /* ---------------------------------------------------------------------*/
496: /*
497: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
498: is attached to a communicator, in this case the attribute is a PetscViewer.
499: */
500: static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
504: /*@C
505: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
506: in a communicator.
508: Collective on MPI_Comm
510: Input Parameter:
511: . comm - the MPI communicator to share the window PetscViewer
513: Level: intermediate
515: Notes:
516: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
517: an error code. The window is usually used in the form
518: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
520: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
521: @*/
522: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
523: {
525: PetscMPIInt flag;
526: PetscViewer viewer;
529: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
530: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
531: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
532: }
533: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
534: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
535: if (!flag) { /* PetscViewer not yet created */
536: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
537: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
538: PetscObjectRegisterDestroy((PetscObject)viewer);
539: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
540: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
541: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
542: }
543: PetscFunctionReturn(viewer);
544: }