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