xref: /petsc/src/sys/classes/viewer/impls/draw/drawv.c (revision 7453f77509fc006cbcc7de2dd772f60dc49feac5)
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 M*/
514 #undef __FUNCT__
515 #define __FUNCT__ "PetscViewerCreate_Draw"
516 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
517 {
518   PetscErrorCode   ierr;
519   PetscViewer_Draw *vdraw;
520 
521   PetscFunctionBegin;
522   ierr = PetscNewLog(viewer,&vdraw);CHKERRQ(ierr);
523   viewer->data = (void*)vdraw;
524 
525   viewer->ops->flush            = PetscViewerFlush_Draw;
526   viewer->ops->view             = PetscViewerView_Draw;
527   viewer->ops->destroy          = PetscViewerDestroy_Draw;
528   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
529   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
530   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
531 
532   /* these are created on the fly if requested */
533   vdraw->draw_max  = 5;
534   vdraw->draw_base = 0;
535   vdraw->w         = PETSC_DECIDE;
536   vdraw->h         = PETSC_DECIDE;
537 
538   ierr = PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);CHKERRQ(ierr);
539   vdraw->singleton_made = PETSC_FALSE;
540   PetscFunctionReturn(0);
541 }
542 
543 #undef __FUNCT__
544 #define __FUNCT__ "PetscViewerDrawClear"
545 /*@
546     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.
547 
548     Not Collective
549 
550     Input Parameter:
551 .  viewer - the PetscViewer
552 
553     Level: intermediate
554 
555 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
556 
557 @*/
558 PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
559 {
560   PetscErrorCode   ierr;
561   PetscViewer_Draw *vdraw;
562   PetscBool        isdraw;
563   PetscInt         i;
564 
565   PetscFunctionBegin;
566   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
567   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
568   if (!isdraw) PetscFunctionReturn(0);
569   vdraw = (PetscViewer_Draw*)viewer->data;
570 
571   for (i=0; i<vdraw->draw_max; i++) {
572     if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);}
573   }
574   PetscFunctionReturn(0);
575 }
576 
577 #undef __FUNCT__
578 #define __FUNCT__ "PetscViewerDrawGetPause"
579 /*@
580     PetscViewerDrawGetPause - Gets a pause for the first present draw
581 
582     Not Collective
583 
584     Input Parameter:
585 .  viewer - the PetscViewer
586 
587     Output Parameter:
588 .  pause - the pause value
589 
590     Level: intermediate
591 
592 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
593 
594 @*/
595 PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
596 {
597   PetscErrorCode   ierr;
598   PetscViewer_Draw *vdraw;
599   PetscBool        isdraw;
600   PetscInt         i;
601   PetscDraw        draw;
602 
603   PetscFunctionBegin;
604   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
605   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
606   if (!isdraw) {*pause = 0.0; PetscFunctionReturn(0);}
607   vdraw = (PetscViewer_Draw*)viewer->data;
608 
609   for (i=0; i<vdraw->draw_max; i++) {
610     if (vdraw->draw[i]) {
611       ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr);
612       PetscFunctionReturn(0);
613     }
614   }
615   /* none exist yet so create one and get its pause */
616   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
617   ierr = PetscDrawGetPause(draw,pause);CHKERRQ(ierr);
618   PetscFunctionReturn(0);
619 }
620 
621 #undef __FUNCT__
622 #define __FUNCT__ "PetscViewerDrawSetPause"
623 /*@
624     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer
625 
626     Not Collective
627 
628     Input Parameters:
629 +  viewer - the PetscViewer
630 -  pause - the pause value
631 
632     Level: intermediate
633 
634 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
635 
636 @*/
637 PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
638 {
639   PetscErrorCode   ierr;
640   PetscViewer_Draw *vdraw;
641   PetscBool        isdraw;
642   PetscInt         i;
643 
644   PetscFunctionBegin;
645   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
646   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
647   if (!isdraw) PetscFunctionReturn(0);
648   vdraw = (PetscViewer_Draw*)viewer->data;
649 
650   vdraw->pause = pause;
651   for (i=0; i<vdraw->draw_max; i++) {
652     if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);}
653   }
654   PetscFunctionReturn(0);
655 }
656 
657 
658 #undef __FUNCT__
659 #define __FUNCT__ "PetscViewerDrawSetHold"
660 /*@
661     PetscViewerDrawSetHold - Holds previous image when drawing new image
662 
663     Not Collective
664 
665     Input Parameters:
666 +  viewer - the PetscViewer
667 -  hold - indicates to hold or not
668 
669     Level: intermediate
670 
671 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
672 
673 @*/
674 PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
675 {
676   PetscErrorCode   ierr;
677   PetscViewer_Draw *vdraw;
678   PetscBool        isdraw;
679 
680   PetscFunctionBegin;
681   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
682   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
683   if (!isdraw) PetscFunctionReturn(0);
684   vdraw = (PetscViewer_Draw*)viewer->data;
685 
686   vdraw->hold = hold;
687   PetscFunctionReturn(0);
688 }
689 
690 #undef __FUNCT__
691 #define __FUNCT__ "PetscViewerDrawGetHold"
692 /*@
693     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image
694 
695     Not Collective
696 
697     Input Parameter:
698 .  viewer - the PetscViewer
699 
700     Output Parameter:
701 .  hold - indicates to hold or not
702 
703     Level: intermediate
704 
705 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),
706 
707 @*/
708 PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
709 {
710   PetscErrorCode   ierr;
711   PetscViewer_Draw *vdraw;
712   PetscBool        isdraw;
713 
714   PetscFunctionBegin;
715   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
716   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
717   if (!isdraw) {*hold = PETSC_FALSE; PetscFunctionReturn(0);}
718   vdraw = (PetscViewer_Draw*)viewer->data;
719 
720   *hold = vdraw->hold;
721   PetscFunctionReturn(0);
722 }
723 
724 /* ---------------------------------------------------------------------*/
725 /*
726     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
727   is attached to a communicator, in this case the attribute is a PetscViewer.
728 */
729 static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
730 
731 #undef __FUNCT__
732 #define __FUNCT__ "PETSC_VIEWER_DRAW_"
733 /*@C
734     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
735                      in a communicator.
736 
737      Collective on MPI_Comm
738 
739      Input Parameter:
740 .    comm - the MPI communicator to share the window PetscViewer
741 
742      Level: intermediate
743 
744      Notes:
745      Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
746      an error code.  The window is usually used in the form
747 $       XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
748 
749 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
750 @*/
751 PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
752 {
753   PetscErrorCode ierr;
754   PetscMPIInt    flag;
755   PetscViewer    viewer;
756   MPI_Comm       ncomm;
757 
758   PetscFunctionBegin;
759   ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
760   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
761     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
762     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
763   }
764   ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
765   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
766   if (!flag) { /* PetscViewer not yet created */
767     ierr = PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
768     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
769     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
770     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
771     ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
772     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
773   }
774   ierr = PetscCommDestroy(&ncomm);
775   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
776   PetscFunctionReturn(viewer);
777 }
778 
779 #undef __FUNCT__
780 #define __FUNCT__ "PetscViewerDrawSetBounds"
781 /*@
782     PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting
783 
784     Collective on PetscViewer
785 
786     Input Parameters:
787 +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
788 .   nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
789 -   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, .....
790 
791 
792     Options Database:
793 .   -draw_bounds  minF0,maxF0,minF1,maxF1
794 
795     Level: intermediate
796 
797     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
798       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
799       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
800 
801    Concepts: drawing^accessing PetscDraw context from PetscViewer
802    Concepts: graphics
803 
804 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
805 @*/
806 PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
807 {
808   PetscViewer_Draw *vdraw;
809   PetscBool        isdraw;
810   PetscErrorCode   ierr;
811 
812 
813   PetscFunctionBegin;
814   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
815   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
816   if (!isdraw) PetscFunctionReturn(0);
817   vdraw = (PetscViewer_Draw*)viewer->data;
818 
819   vdraw->nbounds = nbounds;
820   ierr = PetscFree(vdraw->bounds);CHKERRQ(ierr);
821   ierr = PetscMalloc1(2*nbounds,&vdraw->bounds);CHKERRQ(ierr);
822   ierr = PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));CHKERRQ(ierr);
823   PetscFunctionReturn(0);
824 }
825 
826 #undef __FUNCT__
827 #define __FUNCT__ "PetscViewerDrawGetBounds"
828 /*@C
829     PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds()
830 
831     Collective on PetscViewer
832 
833     Input Parameter:
834 .   viewer - the PetscViewer (created with PetscViewerDrawOpen())
835 
836     Output Paramters:
837 +   nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
838 -   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, .....
839 
840     Level: intermediate
841 
842    Concepts: drawing^accessing PetscDraw context from PetscViewer
843    Concepts: graphics
844 
845 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
846 @*/
847 PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
848 {
849   PetscViewer_Draw *vdraw;
850   PetscBool        isdraw;
851   PetscErrorCode   ierr;
852 
853   PetscFunctionBegin;
854   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
855   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
856   if (!isdraw) {if (nbounds) *nbounds = 0; if (bounds) *bounds = NULL; PetscFunctionReturn(0);}
857   vdraw = (PetscViewer_Draw*)viewer->data;
858 
859   if (nbounds) *nbounds = vdraw->nbounds;
860   if (bounds)  *bounds  = vdraw->bounds;
861   PetscFunctionReturn(0);
862 }
863