xref: /petsc/src/sys/classes/viewer/impls/draw/drawv.c (revision ce94432eddcd14845bc7e8083b7f8ea723b9bf7d)
1 
2 #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/
3 
4 #undef __FUNCT__
5 #define __FUNCT__ "PetscViewerDestroy_Draw"
6 PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
7 {
8   PetscErrorCode   ierr;
9   PetscInt         i;
10   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
11 
12   PetscFunctionBegin;
13   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton");
14   for (i=0; i<vdraw->draw_max; i++) {
15     ierr = PetscDrawAxisDestroy(&vdraw->drawaxis[i]);CHKERRQ(ierr);
16     ierr = PetscDrawLGDestroy(&vdraw->drawlg[i]);CHKERRQ(ierr);
17     ierr = PetscDrawDestroy(&vdraw->draw[i]);CHKERRQ(ierr);
18   }
19 
20   ierr = PetscFree(vdraw->display);CHKERRQ(ierr);
21   ierr = PetscFree(vdraw->title);CHKERRQ(ierr);
22   ierr = PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);CHKERRQ(ierr);
23   ierr = PetscFree(vdraw->bounds);CHKERRQ(ierr);
24   ierr = PetscFree(vdraw);CHKERRQ(ierr);
25   PetscFunctionReturn(0);
26 }
27 
28 #undef __FUNCT__
29 #define __FUNCT__ "PetscViewerFlush_Draw"
30 PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
31 {
32   PetscErrorCode   ierr;
33   PetscInt         i;
34   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
35 
36   PetscFunctionBegin;
37   for (i=0; i<vdraw->draw_max; i++) {
38     if (vdraw->draw[i]) {ierr = PetscDrawSynchronizedFlush(vdraw->draw[i]);CHKERRQ(ierr);}
39   }
40   PetscFunctionReturn(0);
41 }
42 
43 #undef __FUNCT__
44 #define __FUNCT__ "PetscViewerDrawGetDraw"
45 /*@C
46     PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
47     This PetscDraw object may then be used to perform graphics using
48     PetscDrawXXX() commands.
49 
50     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
51 
52     Input Parameters:
53 +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
54 -   windownumber - indicates which subwindow (usually 0)
55 
56     Ouput Parameter:
57 .   draw - the draw object
58 
59     Level: intermediate
60 
61    Concepts: drawing^accessing PetscDraw context from PetscViewer
62    Concepts: graphics
63 
64 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
65 @*/
66 PetscErrorCode  PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
67 {
68   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
69   PetscErrorCode   ierr;
70   PetscBool        isdraw;
71   char             *title;
72 
73   PetscFunctionBegin;
74   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
75   if (draw) PetscValidPointer(draw,3);
76   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
77   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
78   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
79   windownumber += vdraw->draw_base;
80   if (windownumber >= vdraw->draw_max) {
81     /* allocate twice as many slots as needed */
82     PetscInt      draw_max  = vdraw->draw_max;
83     PetscDraw     *tdraw    = vdraw->draw;
84     PetscDrawLG   *drawlg   = vdraw->drawlg;
85     PetscDrawAxis *drawaxis = vdraw->drawaxis;
86 
87     vdraw->draw_max = 2*windownumber;
88 
89     ierr = PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);CHKERRQ(ierr);
90     ierr = PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));CHKERRQ(ierr);
91     ierr = PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr);
92     ierr = PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr);
93 
94     ierr = PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));CHKERRQ(ierr);
95     ierr = PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr);
96     ierr = PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr);
97 
98     ierr = PetscFree3(tdraw,drawlg,drawaxis);CHKERRQ(ierr);
99   }
100 
101   if (!vdraw->draw[windownumber]) {
102     if (!windownumber) title = vdraw->title;
103     else {
104       char tmp_str[128];
105       ierr  = PetscSNPrintf(tmp_str, 128, "%s:%d", vdraw->title,windownumber);CHKERRQ(ierr);
106       title = tmp_str;
107     }
108     ierr = PetscDrawCreate(PetscObjectComm((PetscObject)viewer),vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);CHKERRQ(ierr);
109     ierr = PetscDrawSetPause(vdraw->draw[windownumber],vdraw->pause);CHKERRQ(ierr);
110     ierr = PetscDrawSetFromOptions(vdraw->draw[windownumber]);CHKERRQ(ierr);
111   }
112   if (draw) *draw = vdraw->draw[windownumber];
113   if (draw) PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,-1);
114   PetscFunctionReturn(0);
115 }
116 
117 #undef __FUNCT__
118 #define __FUNCT__ "PetscViewerDrawBaseAdd"
119 /*@C
120     PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
121 
122     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
123 
124     Input Parameters:
125 +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
126 -   windownumber - how much to add to the base
127 
128     Level: developer
129 
130    Concepts: drawing^accessing PetscDraw context from PetscViewer
131    Concepts: graphics
132 
133 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
134 @*/
135 PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
136 {
137   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
138   PetscErrorCode   ierr;
139   PetscBool        isdraw;
140 
141   PetscFunctionBegin;
142   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
143   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
144   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
145   if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
146   vdraw->draw_base += windownumber;
147   PetscFunctionReturn(0);
148 }
149 
150 #undef __FUNCT__
151 #define __FUNCT__ "PetscViewerDrawBaseSet"
152 /*@C
153     PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()
154 
155     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)
156 
157     Input Parameters:
158 +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
159 -   windownumber - value to set the base
160 
161     Level: developer
162 
163    Concepts: drawing^accessing PetscDraw context from PetscViewer
164    Concepts: graphics
165 
166 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
167 @*/
168 PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
169 {
170   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
171   PetscErrorCode   ierr;
172   PetscBool        isdraw;
173 
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
176   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
177   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
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   PetscFunctionReturn(0);
181 }
182 
183 #undef __FUNCT__
184 #define __FUNCT__ "PetscViewerDrawGetDrawLG"
185 /*@C
186     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
187     This PetscDrawLG object may then be used to perform graphics using
188     PetscDrawLGXXX() commands.
189 
190     Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)
191 
192     Input Parameter:
193 +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
194 -   windownumber - indicates which subwindow (usually 0)
195 
196     Ouput Parameter:
197 .   draw - the draw line graph object
198 
199     Level: intermediate
200 
201   Concepts: line graph^accessing context
202 
203 .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
204 @*/
205 PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
206 {
207   PetscErrorCode   ierr;
208   PetscBool        isdraw;
209   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
210 
211   PetscFunctionBegin;
212   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
213   PetscValidPointer(drawlg,3);
214   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
215   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
216   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
217 
218   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
219     ierr = PetscViewerDrawGetDraw(viewer,windownumber,NULL);CHKERRQ(ierr);
220   }
221   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
222     ierr = PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr);
223     ierr = PetscLogObjectParent(viewer,vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr);
224   }
225   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
226   PetscFunctionReturn(0);
227 }
228 
229 #undef __FUNCT__
230 #define __FUNCT__ "PetscViewerDrawGetDrawAxis"
231 /*@C
232     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
233     This PetscDrawAxis object may then be used to perform graphics using
234     PetscDrawAxisXXX() commands.
235 
236     Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)
237 
238     Input Parameter:
239 +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
240 -   windownumber - indicates which subwindow (usually 0)
241 
242     Ouput Parameter:
243 .   drawaxis - the draw axis object
244 
245     Level: advanced
246 
247   Concepts: line graph^accessing context
248 
249 .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
250 @*/
251 PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
252 {
253   PetscErrorCode   ierr;
254   PetscBool        isdraw;
255   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;
256 
257   PetscFunctionBegin;
258   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
259   PetscValidPointer(drawaxis,3);
260   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
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 
264   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
265     ierr = PetscViewerDrawGetDraw(viewer,windownumber,NULL);CHKERRQ(ierr);
266   }
267   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
268     ierr = PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr);
269     ierr = PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr);
270   }
271   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
272   PetscFunctionReturn(0);
273 }
274 
275 #undef __FUNCT__
276 #define __FUNCT__ "PetscViewerDrawResize"
277 PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
278 {
279   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
280 
281   PetscFunctionBegin;
282   vdraw->h = h;
283   vdraw->w = w;
284   PetscFunctionReturn(0);
285 }
286 
287 #undef __FUNCT__
288 #define __FUNCT__ "PetscViewerDrawSetInfo"
289 PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
290 {
291   PetscErrorCode   ierr;
292   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
293 
294   PetscFunctionBegin;
295   vdraw->h = h;
296   vdraw->w = w;
297   ierr     = PetscStrallocpy(display,&vdraw->display);CHKERRQ(ierr);
298   ierr     = PetscStrallocpy(title,&vdraw->title);CHKERRQ(ierr);
299   PetscFunctionReturn(0);
300 }
301 
302 #undef __FUNCT__
303 #define __FUNCT__ "PetscViewerDrawOpen"
304 /*@C
305    PetscViewerDrawOpen - Opens a window for use as a PetscViewer. If you want to
306    do graphics in this window, you must call PetscViewerDrawGetDraw() and
307    perform the graphics on the PetscDraw object.
308 
309    Collective on MPI_Comm
310 
311    Input Parameters:
312 +  comm - communicator that will share window
313 .  display - the X display on which to open, or null for the local machine
314 .  title - the title to put in the title bar, or null for no title
315 .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
316 -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
317           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE
318 
319    Output Parameters:
320 . viewer - the PetscViewer
321 
322    Format Options:
323 +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
324 -  PETSC_VIEWER_DRAW_LG    - displays using a line graph
325 
326    Options Database Keys:
327    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
328    PetscDrawCreate() for runtime options, including
329 +  -draw_type x or null
330 .  -nox - Disables all x-windows output
331 .  -display <name> - Specifies name of machine for the X display
332 .  -geometry <x,y,w,h> - allows setting the window location and size
333 -  -draw_pause <pause> - Sets time (in seconds) that the
334      program pauses after PetscDrawPause() has been called
335      (0 is default, -1 implies until user input).
336 
337    Level: beginner
338 
339    Note for Fortran Programmers:
340    Whenever indicating null character data in a Fortran code,
341    NULL_CHARACTER must be employed; using NULL is not
342    correct for character data!  Thus, NULL_CHARACTER can be
343    used for the display and title input parameters.
344 
345   Concepts: graphics^opening PetscViewer
346   Concepts: drawing^opening PetscViewer
347 
348 
349 .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
350           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
351 @*/
352 PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
353 {
354   PetscErrorCode ierr;
355 
356   PetscFunctionBegin;
357   ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr);
358   ierr = PetscViewerSetType(*viewer,PETSCVIEWERDRAW);CHKERRQ(ierr);
359   ierr = PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);CHKERRQ(ierr);
360   PetscFunctionReturn(0);
361 }
362 
363 #undef __FUNCT__
364 #define __FUNCT__ "PetscViewerGetSingleton_Draw"
365 PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
366 {
367   PetscErrorCode   ierr;
368   PetscMPIInt      rank;
369   PetscInt         i;
370   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw;
371 
372   PetscFunctionBegin;
373   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
374 
375   /* only processor zero can use the PetscViewer draw singleton */
376   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
377   if (!rank) {
378     ierr   = PetscViewerCreate(PETSC_COMM_SELF,sviewer);CHKERRQ(ierr);
379     ierr   = PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);CHKERRQ(ierr);
380     vsdraw = (PetscViewer_Draw*)(*sviewer)->data;
381     for (i=0; i<vdraw->draw_max; i++) {
382       if (vdraw->draw[i]) {
383         ierr = PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);CHKERRQ(ierr);
384       }
385     }
386   }
387   vdraw->singleton_made = PETSC_TRUE;
388   PetscFunctionReturn(0);
389 }
390 
391 #undef __FUNCT__
392 #define __FUNCT__ "PetscViewerRestoreSingleton_Draw"
393 PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
394 {
395   PetscErrorCode   ierr;
396   PetscMPIInt      rank;
397   PetscInt         i;
398   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw;
399 
400   PetscFunctionBegin;
401   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
402   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
403   if (!rank) {
404     vsdraw = (PetscViewer_Draw*)(*sviewer)->data;
405     for (i=0; i<vdraw->draw_max; i++) {
406       if (vdraw->draw[i] && vsdraw->draw[i]) {
407         ierr = PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);CHKERRQ(ierr);
408       }
409     }
410     ierr = PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);CHKERRQ(ierr);
411     ierr = PetscFree((*sviewer)->data);CHKERRQ(ierr);
412     ierr = PetscHeaderDestroy(sviewer);CHKERRQ(ierr);
413   }
414   vdraw->singleton_made = PETSC_FALSE;
415   PetscFunctionReturn(0);
416 }
417 
418 #undef __FUNCT__
419 #define __FUNCT__ "PetscViewerSetFromOptions_Draw"
420 PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v)
421 {
422   PetscErrorCode ierr;
423   PetscReal      bounds[16];
424   PetscInt       nbounds = 16;
425   PetscBool      flg;
426 
427   PetscFunctionBegin;
428   ierr = PetscOptionsHead("Draw PetscViewer Options");CHKERRQ(ierr);
429   ierr = PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);CHKERRQ(ierr);
430   if (flg) {
431     ierr = PetscViewerDrawSetBounds(v,nbounds/2,bounds);CHKERRQ(ierr);
432   }
433 
434   ierr = PetscOptionsTail();CHKERRQ(ierr);
435   PetscFunctionReturn(0);
436 }
437 
438 EXTERN_C_BEGIN
439 #undef __FUNCT__
440 #define __FUNCT__ "PetscViewerCreate_Draw"
441 PetscErrorCode  PetscViewerCreate_Draw(PetscViewer viewer)
442 {
443   PetscInt         i;
444   PetscErrorCode   ierr;
445   PetscViewer_Draw *vdraw;
446 
447   PetscFunctionBegin;
448   ierr         = PetscNewLog(viewer,PetscViewer_Draw,&vdraw);CHKERRQ(ierr);
449   viewer->data = (void*)vdraw;
450 
451   viewer->ops->flush            = PetscViewerFlush_Draw;
452   viewer->ops->destroy          = PetscViewerDestroy_Draw;
453   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
454   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
455   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
456   viewer->format                = PETSC_VIEWER_NOFORMAT;
457 
458   /* these are created on the fly if requested */
459   vdraw->draw_max  = 5;
460   vdraw->draw_base = 0;
461   vdraw->w         = PETSC_DECIDE;
462   vdraw->h         = PETSC_DECIDE;
463 
464   ierr = PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);CHKERRQ(ierr);
465   ierr = PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));CHKERRQ(ierr);
466   ierr = PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr);
467   ierr = PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr);
468   for (i=0; i<vdraw->draw_max; i++) {
469     vdraw->draw[i]     = 0;
470     vdraw->drawlg[i]   = 0;
471     vdraw->drawaxis[i] = 0;
472   }
473   vdraw->singleton_made = PETSC_FALSE;
474   PetscFunctionReturn(0);
475 }
476 EXTERN_C_END
477 
478 #undef __FUNCT__
479 #define __FUNCT__ "PetscViewerDrawClear"
480 /*@
481     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
482 
483     Not Collective
484 
485     Input Parameter:
486 .  viewer - the PetscViewer
487 
488     Level: intermediate
489 
490 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
491 
492 @*/
493 PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
494 {
495   PetscErrorCode   ierr;
496   PetscInt         i;
497   PetscBool        isdraw;
498   PetscViewer_Draw *vdraw;
499 
500   PetscFunctionBegin;
501   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
502   if (isdraw) {
503     vdraw = (PetscViewer_Draw*)viewer->data;
504     for (i=0; i<vdraw->draw_max; i++) {
505       if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);}
506     }
507   }
508   PetscFunctionReturn(0);
509 }
510 
511 #undef __FUNCT__
512 #define __FUNCT__ "PetscViewerDrawGetPause"
513 /*@
514     PetscViewerDrawGetPause - Gets a pause for the first present draw
515 
516     Not Collective
517 
518     Input Parameter:
519 .  viewer - the PetscViewer
520 
521     Output Parameter:
522 .  pause - the pause value
523 
524     Level: intermediate
525 
526 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
527 
528 @*/
529 PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
530 {
531   PetscErrorCode   ierr;
532   PetscInt         i;
533   PetscBool        isdraw;
534   PetscViewer_Draw *vdraw;
535   PetscDraw        draw;
536 
537   PetscFunctionBegin;
538   ierr   = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
539   *pause = 0.0;
540   if (isdraw) {
541     vdraw = (PetscViewer_Draw*)viewer->data;
542     for (i=0; i<vdraw->draw_max; i++) {
543       if (vdraw->draw[i]) {
544         ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr);
545         PetscFunctionReturn(0);
546       }
547     }
548     /* none exist yet so create one and get its pause */
549     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
550     ierr = PetscDrawGetPause(vdraw->draw[0],pause);CHKERRQ(ierr);
551   }
552   PetscFunctionReturn(0);
553 }
554 
555 #undef __FUNCT__
556 #define __FUNCT__ "PetscViewerDrawSetPause"
557 /*@
558     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer
559 
560     Not Collective
561 
562     Input Parameters:
563 +  viewer - the PetscViewer
564 -  pause - the pause value
565 
566     Level: intermediate
567 
568 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
569 
570 @*/
571 PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
572 {
573   PetscErrorCode   ierr;
574   PetscInt         i;
575   PetscBool        isdraw;
576 
577   PetscFunctionBegin;
578   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
579   if (isdraw) {
580     PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
581 
582     vdraw->pause = pause;
583     for (i=0; i<vdraw->draw_max; i++) {
584       if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);}
585     }
586   }
587   PetscFunctionReturn(0);
588 }
589 
590 
591 #undef __FUNCT__
592 #define __FUNCT__ "PetscViewerDrawSetHold"
593 /*@
594     PetscViewerDrawSetHold - Holds previous image when drawing new image
595 
596     Not Collective
597 
598     Input Parameters:
599 +  viewer - the PetscViewer
600 -  hold - indicates to hold or not
601 
602     Level: intermediate
603 
604 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
605 
606 @*/
607 PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
608 {
609   PetscErrorCode   ierr;
610   PetscViewer_Draw *vdraw;
611   PetscBool        isdraw;
612 
613   PetscFunctionBegin;
614   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
615   if (isdraw) {
616     vdraw       = (PetscViewer_Draw*)viewer->data;
617     vdraw->hold = hold;
618   }
619   PetscFunctionReturn(0);
620 }
621 
622 #undef __FUNCT__
623 #define __FUNCT__ "PetscViewerDrawGetHold"
624 /*@
625     PetscViewerDrawGetHold - Holds previous image when drawing new image
626 
627     Not Collective
628 
629     Input Parameter:
630 .  viewer - the PetscViewer
631 
632     Output Parameter:
633 .  hold - indicates to hold or not
634 
635     Level: intermediate
636 
637 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
638 
639 @*/
640 PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
641 {
642   PetscErrorCode   ierr;
643   PetscViewer_Draw *vdraw;
644   PetscBool        isdraw;
645 
646   PetscFunctionBegin;
647   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
648   if (isdraw) {
649     vdraw = (PetscViewer_Draw*)viewer->data;
650     *hold = vdraw->hold;
651   }
652   PetscFunctionReturn(0);
653 }
654 
655 /* ---------------------------------------------------------------------*/
656 /*
657     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
658   is attached to a communicator, in this case the attribute is a PetscViewer.
659 */
660 static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
661 
662 #undef __FUNCT__
663 #define __FUNCT__ "PETSC_VIEWER_DRAW_"
664 /*@C
665     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
666                      in a communicator.
667 
668      Collective on MPI_Comm
669 
670      Input Parameter:
671 .    comm - the MPI communicator to share the window PetscViewer
672 
673      Level: intermediate
674 
675      Notes:
676      Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
677      an error code.  The window is usually used in the form
678 $       XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
679 
680 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
681 @*/
682 PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
683 {
684   PetscErrorCode ierr;
685   PetscMPIInt    flag;
686   PetscViewer    viewer;
687   MPI_Comm       ncomm;
688 
689   PetscFunctionBegin;
690   ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
691   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
692     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
693     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
694   }
695   ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
696   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
697   if (!flag) { /* PetscViewer not yet created */
698     ierr = PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
699     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
700     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
701     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
702     ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
703     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
704   }
705   ierr = PetscCommDestroy(&ncomm);
706   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
707   PetscFunctionReturn(viewer);
708 }
709 
710 #undef __FUNCT__
711 #define __FUNCT__ "PetscViewerDrawSetBounds"
712 /*@
713     PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting
714 
715     Collective on PetscViewer
716 
717     Input Parameters:
718 +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
719 .   nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
720 -   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, .....
721 
722 
723     Options Database:
724 .   -draw_bounds  minF0,maxF0,minF1,maxF1
725 
726     Level: intermediate
727 
728     Notes: 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
729       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
730       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
731 
732    Concepts: drawing^accessing PetscDraw context from PetscViewer
733    Concepts: graphics
734 
735 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
736 @*/
737 PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
738 {
739   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
740   PetscErrorCode   ierr;
741 
742 
743   PetscFunctionBegin;
744   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
745   vdraw->nbounds = nbounds;
746 
747   ierr = PetscMalloc(2*nbounds*sizeof(PetscReal),&vdraw->bounds);CHKERRQ(ierr);
748   ierr = PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));CHKERRQ(ierr);
749   PetscFunctionReturn(0);
750 }
751 
752 #undef __FUNCT__
753 #define __FUNCT__ "PetscViewerDrawGetBounds"
754 /*@C
755     PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds()
756 
757     Collective on PetscViewer
758 
759     Input Parameter:
760 .   viewer - the PetscViewer (created with PetscViewerDrawOpen())
761 
762     Output Paramters:
763 +   nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
764 -   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, .....
765 
766     Level: intermediate
767 
768    Concepts: drawing^accessing PetscDraw context from PetscViewer
769    Concepts: graphics
770 
771 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
772 @*/
773 PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
774 {
775   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
776 
777   PetscFunctionBegin;
778   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
779   *nbounds = vdraw->nbounds;
780   *bounds  = vdraw->bounds;
781   PetscFunctionReturn(0);
782 }
783