Actual source code: drawv.c
2: #include src/sys/src/viewer/impls/draw/vdraw.h
6: PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
7: {
8: PetscErrorCode ierr;
9: int i;
10: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
13: if (vdraw->singleton_made) {
14: SETERRQ(PETSC_ERR_ORDER,"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: }
22: PetscFree(vdraw->drawaxis);
23: PetscFree(vdraw->drawlg);
24: PetscFree(vdraw->draw);
25: PetscFree(vdraw);
26: return(0);
27: }
31: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
32: {
33: PetscErrorCode ierr;
34: int 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,int 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: if (windownumber >= vdraw->draw_max) {
85: /* allocate twice as many slots as needed */
86: int draw_max = vdraw->draw_max;
87: PetscDraw *tdraw = vdraw->draw;
88: PetscDrawLG *drawlg = vdraw->drawlg;
89: PetscDrawAxis *drawaxis = vdraw->drawaxis;
91: vdraw->draw_max = 2*windownumber;
92: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
93: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
94: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
95: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
96: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
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: PetscFree(tdraw);
104: PetscFree(drawlg);
105: PetscFree(drawaxis);
106: }
108: if (!vdraw->draw[windownumber]) {
109: if (vdraw->draw[0]) {
110: PetscDrawGetTitle(vdraw->draw[0],&title);
111: } else title = 0;
112: PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
113: &vdraw->draw[windownumber]);
114: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
115: }
116: *draw = vdraw->draw[windownumber];
117: return(0);
118: }
122: /*@C
123: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
124: This PetscDrawLG object may then be used to perform graphics using
125: PetscDrawLGXXX() commands.
127: Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
129: Input Parameter:
130: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
131: - windownumber - indicates which subwindow (usually 0)
133: Ouput Parameter:
134: . draw - the draw line graph object
136: Level: intermediate
138: Concepts: line graph^accessing context
140: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
141: @*/
142: PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
143: {
144: PetscErrorCode ierr;
145: PetscTruth isdraw;
146: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
151: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
152: if (!isdraw) {
153: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
154: }
155: if (windownumber < 0) {
156: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
157: }
158: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
159: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
160: }
162: if (!vdraw->drawlg[windownumber]) {
163: PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
164: PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
165: }
166: *drawlg = vdraw->drawlg[windownumber];
167: return(0);
168: }
172: /*@C
173: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
174: This PetscDrawAxis object may then be used to perform graphics using
175: PetscDrawAxisXXX() commands.
177: Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
179: Input Parameter:
180: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
181: - windownumber - indicates which subwindow (usually 0)
183: Ouput Parameter:
184: . drawaxis - the draw axis object
186: Level: advanced
188: Concepts: line graph^accessing context
190: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
191: @*/
192: PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
193: {
194: PetscErrorCode ierr;
195: PetscTruth isdraw;
196: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
201: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
202: if (!isdraw) {
203: SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
204: }
205: if (windownumber < 0) {
206: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
207: }
208: if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
209: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
210: }
212: if (!vdraw->drawaxis[windownumber]) {
213: PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
214: PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
215: }
216: *drawaxis = vdraw->drawaxis[windownumber];
217: return(0);
218: }
222: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
223: {
224: PetscErrorCode ierr;
225: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
228: vdraw->h = h;
229: vdraw->w = w;
230: PetscStrallocpy(display,&vdraw->display);
231: PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
232: PetscDrawSetFromOptions(vdraw->draw[0]);
233: PetscLogObjectParent(v,vdraw->draw[0]);
234: return(0);
235: }
239: /*@C
240: PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
241: do graphics in this window, you must call PetscViewerDrawGetDraw() and
242: perform the graphics on the PetscDraw object.
244: Collective on MPI_Comm
246: Input Parameters:
247: + comm - communicator that will share window
248: . display - the X display on which to open, or null for the local machine
249: . title - the title to put in the title bar, or null for no title
250: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
251: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
252: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
254: Output Parameters:
255: . viewer - the PetscViewer
257: Format Options:
258: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
259: - PETSC_VIEWER_DRAW_LG - displays using a line graph
261: Options Database Keys:
262: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
263: PetscDrawCreate() for runtime options, including
264: + -draw_type x or null
265: . -nox - Disables all x-windows output
266: . -display <name> - Specifies name of machine for the X display
267: - -draw_pause <pause> - Sets time (in seconds) that the
268: program pauses after PetscDrawPause() has been called
269: (0 is default, -1 implies until user input).
271: Level: beginner
273: Note for Fortran Programmers:
274: Whenever indicating null character data in a Fortran code,
275: PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
276: correct for character data! Thus, PETSC_NULL_CHARACTER can be
277: used for the display and title input parameters.
279: Concepts: graphics^opening PetscViewer
280: Concepts: drawing^opening PetscViewer
283: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
284: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
285: @*/
286: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
287: {
291: PetscViewerCreate(comm,viewer);
292: PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
293: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
294: return(0);
295: }
299: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
300: {
301: PetscErrorCode ierr;
302: PetscMPIInt rank;
303: int i;
304: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
307: if (vdraw->singleton_made) {
308: SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
309: }
311: /* only processor zero can use the PetscViewer draw singleton */
312: MPI_Comm_rank(viewer->comm,&rank);
313: if (!rank) {
314: PetscViewerCreate(PETSC_COMM_SELF,sviewer);
315: PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
316: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
317: for (i=0; i<vdraw->draw_max; i++) {
318: if (vdraw->draw[i]) {
319: PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
320: }
321: }
322: }
323: vdraw->singleton_made = PETSC_TRUE;
324: return(0);
325: }
329: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
330: {
331: PetscErrorCode ierr;
332: PetscMPIInt rank;
333: int i;
334: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;
337: if (!vdraw->singleton_made) {
338: SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
339: }
340: MPI_Comm_rank(viewer->comm,&rank);
341: if (!rank) {
342: vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
343: for (i=0; i<vdraw->draw_max; i++) {
344: if (vdraw->draw[i] && vsdraw->draw[i]) {
345: PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
346: }
347: }
348: PetscFree(vsdraw->drawaxis);
349: PetscFree(vsdraw->drawlg);
350: PetscFree(vsdraw->draw);
351: PetscFree((*sviewer)->data);
352: PetscLogObjectDestroy((PetscObject)*sviewer);
353: PetscHeaderDestroy((PetscObject)*sviewer);
354: }
355: vdraw->singleton_made = PETSC_FALSE;
356: return(0);
357: }
362: PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
363: {
364: int i;
365: PetscErrorCode ierr;
366: PetscViewer_Draw *vdraw;
369: PetscNew(PetscViewer_Draw,&vdraw);
370: viewer->data = (void*)vdraw;
372: viewer->ops->flush = PetscViewerFlush_Draw;
373: viewer->ops->destroy = PetscViewerDestroy_Draw;
374: viewer->ops->getsingleton = PetscViewerGetSingleton_Draw;
375: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
376: viewer->format = PETSC_VIEWER_NOFORMAT;
378: /* these are created on the fly if requested */
379: vdraw->draw_max = 5;
380: PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
381: PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
382: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
383: PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
384: PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
385: PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
386: for (i=0; i<vdraw->draw_max; i++) {
387: vdraw->draw[i] = 0;
388: vdraw->drawlg[i] = 0;
389: vdraw->drawaxis[i] = 0;
390: }
391: vdraw->singleton_made = PETSC_FALSE;
392: return(0);
393: }
398: /*@
399: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
401: Not Collective
403: Input Parameter:
404: . viewer - the PetscViewer
406: Level: intermediate
408: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
410: @*/
411: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
412: {
413: PetscErrorCode ierr;
414: int i;
415: PetscTruth isdraw;
416: PetscViewer_Draw *vdraw;
419: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
420: if (isdraw) {
421: vdraw = (PetscViewer_Draw*)viewer->data;
422: for (i=0; i<vdraw->draw_max; i++) {
423: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
424: }
425: }
426: return(0);
427: }
429: /* ---------------------------------------------------------------------*/
430: /*
431: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
432: is attached to a communicator, in this case the attribute is a PetscViewer.
433: */
434: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
438: /*@C
439: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
440: in a communicator.
442: Collective on MPI_Comm
444: Input Parameter:
445: . comm - the MPI communicator to share the window PetscViewer
447: Level: intermediate
449: Notes:
450: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
451: an error code. The window is usually used in the form
452: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
454: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
455: @*/
456: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
457: {
459: int flag;
460: PetscViewer viewer;
463: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
464: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
465: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
466: }
467: MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
468: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
469: if (!flag) { /* PetscViewer not yet created */
470: PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
471: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
472: PetscObjectRegisterDestroy((PetscObject)viewer);
473: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
474: MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
475: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
476: }
477: PetscFunctionReturn(viewer);
478: }