Actual source code: drawv.c
1: #define PETSC_DLL
3: #include src/sys/src/viewer/impls/draw/vdraw.h
7: PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
8: {
9: PetscErrorCode ierr;
10: int 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->drawaxis);
24: PetscFree(vdraw->drawlg);
25: PetscFree(vdraw->draw);
26: PetscFree(vdraw);
27: return(0);
28: }
32: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
33: {
34: PetscErrorCode ierr;
35: int 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 PETSC_DLLEXPORT PetscViewerDrawGetDraw(PetscViewer viewer,int 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: if (windownumber >= vdraw->draw_max) {
86: /* allocate twice as many slots as needed */
87: int 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: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
94: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
95: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
96: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
97: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
98: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
100: PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
101: PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
102: PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));
104: PetscFree(tdraw);
105: PetscFree(drawlg);
106: PetscFree(drawaxis);
107: }
109: if (!vdraw->draw[windownumber]) {
110: if (vdraw->draw[0]) {
111: PetscDrawGetTitle(vdraw->draw[0],&title);
112: } else title = 0;
113: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
114: &vdraw->draw[windownumber]);
115: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
116: }
117: *draw = vdraw->draw[windownumber];
118: return(0);
119: }
123: /*@C
124: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
125: This PetscDrawLG object may then be used to perform graphics using
126: PetscDrawLGXXX() commands.
128: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
130: Input Parameter:
131: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
132: - windownumber - indicates which subwindow (usually 0)
134: Ouput Parameter:
135: . draw - the draw line graph object
137: Level: intermediate
139: Concepts: line graph^accessing context
141: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
142: @*/
143: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
144: {
145: PetscErrorCode ierr;
146: PetscTruth isdraw;
147: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
152: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
153: if (!isdraw) {
154: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
155: }
156: if (windownumber < 0) {
157: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
158: }
159: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
160: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
161: }
163: if (!vdraw->drawlg[windownumber]) {
164: PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
165: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
166: }
167: *drawlg = vdraw->drawlg[windownumber];
168: return(0);
169: }
173: /*@C
174: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
175: This PetscDrawAxis object may then be used to perform graphics using
176: PetscDrawAxisXXX() commands.
178: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
180: Input Parameter:
181: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
182: - windownumber - indicates which subwindow (usually 0)
184: Ouput Parameter:
185: . drawaxis - the draw axis object
187: Level: advanced
189: Concepts: line graph^accessing context
191: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
192: @*/
193: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
194: {
195: PetscErrorCode ierr;
196: PetscTruth isdraw;
197: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
202: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
203: if (!isdraw) {
204: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
205: }
206: if (windownumber < 0) {
207: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
208: }
209: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
210: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
211: }
213: if (!vdraw->drawaxis[windownumber]) {
214: PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
215: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
216: }
217: *drawaxis = vdraw->drawaxis[windownumber];
218: return(0);
219: }
223: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
224: {
225: PetscErrorCode ierr;
226: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
229: vdraw->h = h;
230: vdraw->w = w;
231: PetscStrallocpy(display,&vdraw->display);
232: PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
233: PetscDrawSetFromOptions(vdraw->draw[0]);
234: PetscLogObjectParent(v,vdraw->draw[0]);
235: return(0);
236: }
240: /*@C
241: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
242: do graphics in this window, you must call PetscViewerDrawGetDraw() and
243: perform the graphics on the PetscDraw object.
245: Collective on MPI_Comm
247: Input Parameters:
248: + comm - communicator that will share window
249: . display - the X display on which to open, or null for the local machine
250: . title - the title to put in the title bar, or null for no title
251: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
252: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
253: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
255: Output Parameters:
256: . viewer - the PetscViewer
258: Format Options:
259: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
260: - PETSC_VIEWER_DRAW_LG - displays using a line graph
262: Options Database Keys:
263: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
264: PetscDrawCreate() for runtime options, including
265: + -draw_type x or null
266: . -nox - Disables all x-windows output
267: . -display <name> - Specifies name of machine for the X display
268: . -geometry <x,y,w,h> - allows setting the window location and size
269: - -draw_pause <pause> - Sets time (in seconds) that the
270: program pauses after PetscDrawPause() has been called
271: (0 is default, -1 implies until user input).
273: Level: beginner
275: Note for Fortran Programmers:
276: Whenever indicating null character data in a Fortran code,
277: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
278: correct for character data! Thus, PETSC_NULL_CHARACTER can be
279: used for the display and title input parameters.
281: Concepts: graphics^opening PetscViewer
282: Concepts: drawing^opening PetscViewer
285: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
286: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
287: @*/
288: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
289: {
293: PetscViewerCreate(comm,viewer);
294: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
295: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
296: return(0);
297: }
301: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
302: {
303: PetscErrorCode ierr;
304: PetscMPIInt rank;
305: int i;
306: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
309: if (vdraw->singleton_made) {
310: SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
311: }
313: /* only processor zero can use the PetscViewer draw singleton */
314: MPI_Comm_rank(viewer->comm,&rank);
315: if (!rank) {
316: PetscViewerCreate(PETSC_COMM_SELF,sviewer);
317: PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
318: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
319: for (i=0; i<vdraw->draw_max; i++) {
320: if (vdraw->draw[i]) {
321: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
322: }
323: }
324: }
325: vdraw->singleton_made = PETSC_TRUE;
326: return(0);
327: }
331: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
332: {
333: PetscErrorCode ierr;
334: PetscMPIInt rank;
335: int i;
336: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
339: if (!vdraw->singleton_made) {
340: SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
341: }
342: MPI_Comm_rank(viewer->comm,&rank);
343: if (!rank) {
344: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
345: for (i=0; i<vdraw->draw_max; i++) {
346: if (vdraw->draw[i] && vsdraw->draw[i]) {
347: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
348: }
349: }
350: PetscFree(vsdraw->drawaxis);
351: PetscFree(vsdraw->drawlg);
352: PetscFree(vsdraw->draw);
353: PetscFree((*sviewer)->data);
354: PetscHeaderDestroy(*sviewer);
355: }
356: vdraw->singleton_made = PETSC_FALSE;
357: return(0);
358: }
363: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_Draw(PetscViewer viewer)
364: {
365: int i;
366: PetscErrorCode ierr;
367: PetscViewer_Draw *vdraw;
370: PetscNew(PetscViewer_Draw,&vdraw);
371: viewer->data = (void*)vdraw;
373: viewer->ops->flush = PetscViewerFlush_Draw;
374: viewer->ops->destroy = PetscViewerDestroy_Draw;
375: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
376: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
377: viewer->format = PETSC_VIEWER_NOFORMAT;
379: /* these are created on the fly if requested */
380: vdraw->draw_max = 5;
381: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
382: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
383: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
384: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
385: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
386: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
387: for (i=0; i<vdraw->draw_max; i++) {
388: vdraw->draw[i] = 0;
389: vdraw->drawlg[i] = 0;
390: vdraw->drawaxis[i] = 0;
391: }
392: vdraw->singleton_made = PETSC_FALSE;
393: return(0);
394: }
399: /*@
400: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
402: Not Collective
404: Input Parameter:
405: . viewer - the PetscViewer
407: Level: intermediate
409: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
411: @*/
412: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawClear(PetscViewer viewer)
413: {
414: PetscErrorCode ierr;
415: int i;
416: PetscTruth isdraw;
417: PetscViewer_Draw *vdraw;
420: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
421: if (isdraw) {
422: vdraw = (PetscViewer_Draw*)viewer->data;
423: for (i=0; i<vdraw->draw_max; i++) {
424: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
425: }
426: }
427: return(0);
428: }
430: /* ---------------------------------------------------------------------*/
431: /*
432: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
433: is attached to a communicator, in this case the attribute is a PetscViewer.
434: */
435: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
439: /*@C
440: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
441: in a communicator.
443: Collective on MPI_Comm
445: Input Parameter:
446: . comm - the MPI communicator to share the window PetscViewer
448: Level: intermediate
450: Notes:
451: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
452: an error code. The window is usually used in the form
453: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
455: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
456: @*/
457: PetscViewer PETSC_DLLEXPORT PETSC_VIEWER_DRAW_(MPI_Comm comm)
458: {
460: int flag;
461: PetscViewer viewer;
464: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
465: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
466: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
467: }
468: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
469: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
470: if (!flag) { /* PetscViewer not yet created */
471: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
472: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
473: PetscObjectRegisterDestroy((PetscObject)viewer);
474: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
475: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
476: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
477: }
478: PetscFunctionReturn(viewer);
479: }