Actual source code: drawv.c
petsc-3.10.5 2019-03-28
2: #include <../src/sys/classes/viewer/impls/draw/vdraw.h>
3: #include <petscviewer.h>
5: static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
6: {
7: PetscErrorCode ierr;
8: PetscInt i;
9: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
12: if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton");
13: for (i=0; i<vdraw->draw_max; i++) {
14: PetscDrawAxisDestroy(&vdraw->drawaxis[i]);
15: PetscDrawLGDestroy(&vdraw->drawlg[i]);
16: PetscDrawDestroy(&vdraw->draw[i]);
17: }
18: PetscFree(vdraw->display);
19: PetscFree(vdraw->title);
20: PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
21: PetscFree(vdraw->bounds);
22: PetscFree(vdraw->drawtype);
23: PetscFree(v->data);
24: return(0);
25: }
27: static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
28: {
29: PetscErrorCode ierr;
30: PetscInt i;
31: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
34: for (i=0; i<vdraw->draw_max; i++) {
35: if (vdraw->draw[i]) {PetscDrawFlush(vdraw->draw[i]);}
36: }
37: return(0);
38: }
40: /*@C
41: PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
42: This PetscDraw object may then be used to perform graphics using
43: PetscDrawXXX() commands.
45: Collective on PetscViewer
47: Input Parameters:
48: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
49: - windownumber - indicates which subwindow (usually 0)
51: Ouput Parameter:
52: . draw - the draw object
54: Level: intermediate
56: Concepts: drawing^accessing PetscDraw context from PetscViewer
57: Concepts: graphics
59: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
60: @*/
61: PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
62: {
63: PetscViewer_Draw *vdraw;
64: PetscErrorCode ierr;
65: PetscBool isdraw;
71: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
72: if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
73: if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
74: vdraw = (PetscViewer_Draw*)viewer->data;
76: windownumber += vdraw->draw_base;
77: if (windownumber >= vdraw->draw_max) {
78: /* allocate twice as many slots as needed */
79: PetscInt draw_max = vdraw->draw_max;
80: PetscDraw *tdraw = vdraw->draw;
81: PetscDrawLG *drawlg = vdraw->drawlg;
82: PetscDrawAxis *drawaxis = vdraw->drawaxis;
84: vdraw->draw_max = 2*windownumber;
86: PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
88: PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
89: PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
90: PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));
92: PetscFree3(tdraw,drawlg,drawaxis);
93: }
95: if (!vdraw->draw[windownumber]) {
96: char *title = vdraw->title, tmp_str[128];
97: if (windownumber) {
98: PetscSNPrintf(tmp_str,sizeof(tmp_str),"%s:%d",vdraw->title?vdraw->title:"",windownumber);
99: title = tmp_str;
100: }
101: PetscDrawCreate(PetscObjectComm((PetscObject)viewer),vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);
102: PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->draw[windownumber]);
103: if (vdraw->drawtype) {
104: PetscDrawSetType(vdraw->draw[windownumber],vdraw->drawtype);
105: }
106: PetscDrawSetPause(vdraw->draw[windownumber],vdraw->pause);
107: PetscDrawSetOptionsPrefix(vdraw->draw[windownumber],((PetscObject)viewer)->prefix);
108: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
109: }
110: if (draw) *draw = vdraw->draw[windownumber];
112: return(0);
113: }
115: /*@C
116: PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
118: Logically Collective on PetscViewer
120: Input Parameters:
121: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
122: - windownumber - how much to add to the base
124: Level: developer
126: Concepts: drawing^accessing PetscDraw context from PetscViewer
127: Concepts: graphics
129: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
130: @*/
131: PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
132: {
133: PetscViewer_Draw *vdraw;
134: PetscErrorCode ierr;
135: PetscBool isdraw;
140: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
141: if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
142: vdraw = (PetscViewer_Draw*)viewer->data;
144: if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
145: vdraw->draw_base += windownumber;
146: return(0);
147: }
149: /*@C
150: PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
152: Logically Collective on PetscViewer
154: Input Parameters:
155: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
156: - windownumber - value to set the base
158: Level: developer
160: Concepts: drawing^accessing PetscDraw context from PetscViewer
161: Concepts: graphics
163: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
164: @*/
165: PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
166: {
167: PetscViewer_Draw *vdraw;
168: PetscErrorCode ierr;
169: PetscBool isdraw;
174: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
175: if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
176: vdraw = (PetscViewer_Draw*)viewer->data;
178: if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
179: vdraw->draw_base = windownumber;
180: return(0);
181: }
183: /*@C
184: PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
185: This PetscDrawLG object may then be used to perform graphics using
186: PetscDrawLGXXX() commands.
188: Collective on PetscViewer
190: Input Parameter:
191: + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
192: - windownumber - indicates which subwindow (usually 0)
194: Ouput Parameter:
195: . draw - the draw line graph object
197: Level: intermediate
199: Concepts: line graph^accessing context
201: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
202: @*/
203: PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
204: {
205: PetscErrorCode ierr;
206: PetscBool isdraw;
207: PetscViewer_Draw *vdraw;
213: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
214: if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
215: if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
216: vdraw = (PetscViewer_Draw*)viewer->data;
218: if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
219: PetscViewerDrawGetDraw(viewer,windownumber,NULL);
220: }
221: if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
222: PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
223: PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawlg[windownumber+vdraw->draw_base]);
224: PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber+vdraw->draw_base]);
225: }
226: *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
227: return(0);
228: }
230: /*@C
231: PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
232: This PetscDrawAxis object may then be used to perform graphics using
233: PetscDrawAxisXXX() commands.
235: Collective on PetscViewer
237: Input Parameter:
238: + viewer - the PetscViewer (created with PetscViewerDrawOpen()
239: - windownumber - indicates which subwindow (usually 0)
241: Ouput Parameter:
242: . drawaxis - the draw axis object
244: Level: advanced
246: Concepts: line graph^accessing context
248: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
249: @*/
250: PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
251: {
252: PetscErrorCode ierr;
253: PetscBool isdraw;
254: PetscViewer_Draw *vdraw;
260: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
261: if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
262: if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
263: vdraw = (PetscViewer_Draw*)viewer->data;
265: if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
266: PetscViewerDrawGetDraw(viewer,windownumber,NULL);
267: }
268: if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
269: PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
270: PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);
271: }
272: *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
273: return(0);
274: }
276: PetscErrorCode PetscViewerDrawResize(PetscViewer v,int w,int h)
277: {
278: PetscErrorCode ierr;
279: PetscViewer_Draw *vdraw;
280: PetscBool isdraw;
284: PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
285: if (!isdraw) return(0);
286: vdraw = (PetscViewer_Draw*)v->data;
288: if (w >= 1) vdraw->w = w;
289: if (h >= 1) vdraw->h = h;
290: return(0);
291: }
293: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
294: {
295: PetscErrorCode ierr;
296: PetscViewer_Draw *vdraw;
297: PetscBool isdraw;
301: PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
302: if (!isdraw) return(0);
303: vdraw = (PetscViewer_Draw*)v->data;
305: PetscStrallocpy(display,&vdraw->display);
306: PetscStrallocpy(title,&vdraw->title);
307: if (w >= 1) vdraw->w = w;
308: if (h >= 1) vdraw->h = h;
309: return(0);
310: }
312: PetscErrorCode PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
313: {
314: PetscErrorCode ierr;
315: PetscViewer_Draw *vdraw;
316: PetscBool isdraw;
320: PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
321: if (!isdraw) return(0);
322: vdraw = (PetscViewer_Draw*)v->data;
324: PetscFree(vdraw->drawtype);
325: PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
326: return(0);
327: }
329: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype)
330: {
331: PetscErrorCode ierr;
332: PetscViewer_Draw *vdraw;
333: PetscBool isdraw;
337: PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
338: if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
339: vdraw = (PetscViewer_Draw*)v->data;
341: *drawtype = vdraw->drawtype;
342: return(0);
343: }
345: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[])
346: {
347: PetscErrorCode ierr;
348: PetscViewer_Draw *vdraw;
349: PetscBool isdraw;
353: PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
354: if (!isdraw) return(0);
355: vdraw = (PetscViewer_Draw*)v->data;
357: PetscFree(vdraw->title);
358: PetscStrallocpy(title,&vdraw->title);
359: return(0);
360: }
362: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[])
363: {
364: PetscErrorCode ierr;
365: PetscViewer_Draw *vdraw;
366: PetscBool isdraw;
370: PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
371: if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
372: vdraw = (PetscViewer_Draw*)v->data;
374: *title = vdraw->title;
375: return(0);
376: }
378: /*@C
379: PetscViewerDrawOpen - Opens a window for use as a PetscViewer. If you want to
380: do graphics in this window, you must call PetscViewerDrawGetDraw() and
381: perform the graphics on the PetscDraw object.
383: Collective on MPI_Comm
385: Input Parameters:
386: + comm - communicator that will share window
387: . display - the X display on which to open, or null for the local machine
388: . title - the title to put in the title bar, or null for no title
389: . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
390: - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
391: PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
393: Output Parameters:
394: . viewer - the PetscViewer
396: Format Options:
397: + PETSC_VIEWER_DRAW_BASIC - displays with basic format
398: - PETSC_VIEWER_DRAW_LG - displays using a line graph
400: Options Database Keys:
401: PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
402: PetscDrawCreate() for runtime options, including
403: + -draw_type x or null
404: . -nox - Disables all x-windows output
405: . -display <name> - Specifies name of machine for the X display
406: . -geometry <x,y,w,h> - allows setting the window location and size
407: - -draw_pause <pause> - Sets time (in seconds) that the
408: program pauses after PetscDrawPause() has been called
409: (0 is default, -1 implies until user input).
411: Level: beginner
413: Note for Fortran Programmers:
414: Whenever indicating null character data in a Fortran code,
415: NULL_CHARACTER must be employed; using NULL is not
416: correct for character data! Thus, NULL_CHARACTER can be
417: used for the display and title input parameters.
419: Concepts: graphics^opening PetscViewer
420: Concepts: drawing^opening PetscViewer
423: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
424: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
425: @*/
426: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
427: {
431: PetscViewerCreate(comm,viewer);
432: PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
433: PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
434: return(0);
435: }
437: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
438: {
439: PetscErrorCode ierr;
440: PetscMPIInt rank;
441: PetscInt i;
442: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;
445: if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous");
446: /* only processor zero can use the PetscViewer draw singleton */
447: if (sviewer) *sviewer = NULL;
448: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
449: if (!rank) {
450: PetscViewerCreate(PETSC_COMM_SELF,sviewer);
451: PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
452: svdraw = (PetscViewer_Draw*)(*sviewer)->data;
453: (*sviewer)->format = viewer->format;
454: for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
455: if (vdraw->draw[i]) {PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);}
456: }
457: }
458: vdraw->singleton_made = PETSC_TRUE;
459: return(0);
460: }
462: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
463: {
464: PetscErrorCode ierr;
465: PetscMPIInt rank;
466: PetscInt i;
467: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;
470: if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
471: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
472: if (!rank) {
473: svdraw = (PetscViewer_Draw*)(*sviewer)->data;
474: for (i=0; i<vdraw->draw_max; i++) {
475: if (vdraw->draw[i] && svdraw->draw[i]) {
476: PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
477: }
478: }
479: PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
480: PetscFree((*sviewer)->data);
481: PetscHeaderDestroy(sviewer);
482: }
483: vdraw->singleton_made = PETSC_FALSE;
484: return(0);
485: }
487: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
488: {
490: PetscReal bounds[16];
491: PetscInt nbounds = 16;
492: PetscBool flg;
495: PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
496: PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
497: if (flg) {
498: PetscViewerDrawSetBounds(v,nbounds/2,bounds);
499: }
500: PetscOptionsTail();
501: return(0);
502: }
504: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
505: {
506: PetscErrorCode ierr;
507: PetscDraw draw;
508: PetscInt i;
509: PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
512: /* If the PetscViewer has just been created then no vdraw->draw yet
513: exists so this will not actually call the viewer on any draws. */
514: for (i=0; i<vdraw->draw_base; i++) {
515: if (vdraw->draw[i]) {
516: PetscViewerDrawGetDraw(viewer,i,&draw);
517: PetscDrawView(draw,v);
518: }
519: }
520: return(0);
521: }
523: /*MC
524: PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
527: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
528: PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY,
529: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
530: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
532: Level: beginner
534: M*/
535: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
536: {
537: PetscErrorCode ierr;
538: PetscViewer_Draw *vdraw;
541: PetscNewLog(viewer,&vdraw);
542: viewer->data = (void*)vdraw;
544: viewer->ops->flush = PetscViewerFlush_Draw;
545: viewer->ops->view = PetscViewerView_Draw;
546: viewer->ops->destroy = PetscViewerDestroy_Draw;
547: viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw;
548: viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw;
549: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
551: /* these are created on the fly if requested */
552: vdraw->draw_max = 5;
553: vdraw->draw_base = 0;
554: vdraw->w = PETSC_DECIDE;
555: vdraw->h = PETSC_DECIDE;
557: PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
558: vdraw->singleton_made = PETSC_FALSE;
559: return(0);
560: }
562: /*@
563: PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
565: Not Collective
567: Input Parameter:
568: . viewer - the PetscViewer
570: Level: intermediate
572: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
574: @*/
575: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
576: {
577: PetscErrorCode ierr;
578: PetscViewer_Draw *vdraw;
579: PetscBool isdraw;
580: PetscInt i;
584: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
585: if (!isdraw) return(0);
586: vdraw = (PetscViewer_Draw*)viewer->data;
588: for (i=0; i<vdraw->draw_max; i++) {
589: if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
590: }
591: return(0);
592: }
594: /*@
595: PetscViewerDrawGetPause - Gets a pause for the first present draw
597: Not Collective
599: Input Parameter:
600: . viewer - the PetscViewer
602: Output Parameter:
603: . pause - the pause value
605: Level: intermediate
607: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
609: @*/
610: PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
611: {
612: PetscErrorCode ierr;
613: PetscViewer_Draw *vdraw;
614: PetscBool isdraw;
615: PetscInt i;
616: PetscDraw draw;
620: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
621: if (!isdraw) {*pause = 0.0; return(0);}
622: vdraw = (PetscViewer_Draw*)viewer->data;
624: for (i=0; i<vdraw->draw_max; i++) {
625: if (vdraw->draw[i]) {
626: PetscDrawGetPause(vdraw->draw[i],pause);
627: return(0);
628: }
629: }
630: /* none exist yet so create one and get its pause */
631: PetscViewerDrawGetDraw(viewer,0,&draw);
632: PetscDrawGetPause(draw,pause);
633: return(0);
634: }
636: /*@
637: PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer
639: Not Collective
641: Input Parameters:
642: + viewer - the PetscViewer
643: - pause - the pause value
645: Level: intermediate
647: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
649: @*/
650: PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
651: {
652: PetscErrorCode ierr;
653: PetscViewer_Draw *vdraw;
654: PetscBool isdraw;
655: PetscInt i;
659: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
660: if (!isdraw) return(0);
661: vdraw = (PetscViewer_Draw*)viewer->data;
663: vdraw->pause = pause;
664: for (i=0; i<vdraw->draw_max; i++) {
665: if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
666: }
667: return(0);
668: }
671: /*@
672: PetscViewerDrawSetHold - Holds previous image when drawing new image
674: Not Collective
676: Input Parameters:
677: + viewer - the PetscViewer
678: - hold - indicates to hold or not
680: Level: intermediate
682: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
684: @*/
685: PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
686: {
687: PetscErrorCode ierr;
688: PetscViewer_Draw *vdraw;
689: PetscBool isdraw;
693: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
694: if (!isdraw) return(0);
695: vdraw = (PetscViewer_Draw*)viewer->data;
697: vdraw->hold = hold;
698: return(0);
699: }
701: /*@
702: PetscViewerDrawGetHold - Checks if holds previous image when drawing new image
704: Not Collective
706: Input Parameter:
707: . viewer - the PetscViewer
709: Output Parameter:
710: . hold - indicates to hold or not
712: Level: intermediate
714: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
716: @*/
717: PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
718: {
719: PetscErrorCode ierr;
720: PetscViewer_Draw *vdraw;
721: PetscBool isdraw;
725: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
726: if (!isdraw) {*hold = PETSC_FALSE; return(0);}
727: vdraw = (PetscViewer_Draw*)viewer->data;
729: *hold = vdraw->hold;
730: return(0);
731: }
733: /* ---------------------------------------------------------------------*/
734: /*
735: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
736: is attached to a communicator, in this case the attribute is a PetscViewer.
737: */
738: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
740: /*@C
741: PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
742: in a communicator.
744: Collective on MPI_Comm
746: Input Parameter:
747: . comm - the MPI communicator to share the window PetscViewer
749: Level: intermediate
751: Notes:
752: Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
753: an error code. The window is usually used in the form
754: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
756: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
757: @*/
758: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
759: {
761: PetscMPIInt flag;
762: PetscViewer viewer;
763: MPI_Comm ncomm;
766: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
767: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
768: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
769: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
770: }
771: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
772: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
773: if (!flag) { /* PetscViewer not yet created */
774: PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
775: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
776: PetscObjectRegisterDestroy((PetscObject)viewer);
777: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
778: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
779: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
780: }
781: PetscCommDestroy(&ncomm);
782: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
783: PetscFunctionReturn(viewer);
784: }
786: /*@
787: PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting
789: Collective on PetscViewer
791: Input Parameters:
792: + viewer - the PetscViewer (created with PetscViewerDrawOpen())
793: . nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
794: - bounds - the actual bounds, the size of this is 2*nbounds, the values are stored in the order min F_0, max F_0, min F_1, max F_1, .....
797: Options Database:
798: . -draw_bounds minF0,maxF0,minF1,maxF1
800: Level: intermediate
802: Notes:
803: this determines the colors used in 2d contour plots generated with VecView() for DMDA in 2d. Any values in the vector below or above the
804: bounds are moved to the bound value before plotting. In this way the color index from color to physical value remains the same for all plots generated with
805: this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
807: Concepts: drawing^accessing PetscDraw context from PetscViewer
808: Concepts: graphics
810: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
811: @*/
812: PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
813: {
814: PetscViewer_Draw *vdraw;
815: PetscBool isdraw;
816: PetscErrorCode ierr;
821: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
822: if (!isdraw) return(0);
823: vdraw = (PetscViewer_Draw*)viewer->data;
825: vdraw->nbounds = nbounds;
826: PetscFree(vdraw->bounds);
827: PetscMalloc1(2*nbounds,&vdraw->bounds);
828: PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));
829: return(0);
830: }
832: /*@C
833: PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds()
835: Collective on PetscViewer
837: Input Parameter:
838: . viewer - the PetscViewer (created with PetscViewerDrawOpen())
840: Output Paramters:
841: + nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
842: - bounds - the actual bounds, the size of this is 2*nbounds, the values are stored in the order min F_0, max F_0, min F_1, max F_1, .....
844: Level: intermediate
846: Concepts: drawing^accessing PetscDraw context from PetscViewer
847: Concepts: graphics
849: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
850: @*/
851: PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
852: {
853: PetscViewer_Draw *vdraw;
854: PetscBool isdraw;
855: PetscErrorCode ierr;
859: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
860: if (!isdraw) {if (nbounds) *nbounds = 0; if (bounds) *bounds = NULL; return(0);}
861: vdraw = (PetscViewer_Draw*)viewer->data;
863: if (nbounds) *nbounds = vdraw->nbounds;
864: if (bounds) *bounds = vdraw->bounds;
865: return(0);
866: }