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