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