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