1 
2 /*
3        Provides the registration process for PETSc PetscDraw routines
4 */
5 #include <petsc/private/drawimpl.h>  /*I "petscdraw.h" I*/
6 #include <petscviewer.h>             /*I "petscviewer.h" I*/
7 #if defined(PETSC_HAVE_SAWS)
8 #include <petscviewersaws.h>
9 #endif
10 
11 /*
12    Contains the list of registered PetscDraw routines
13 */
14 PetscFunctionList PetscDrawList = NULL;
15 
16 /*@C
17    PetscDrawView - Prints the PetscDraw data structure.
18 
19    Collective on PetscDraw
20 
21    Input Parameters:
22 +  indraw - the PetscDraw context
23 -  viewer - visualization context
24 
25    See PetscDrawSetFromOptions() for options database keys
26 
27    Note:
28    The available visualization contexts include
29 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
30 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
31          output where only the first processor opens
32          the file.  All other processors send their
33          data to the first processor to print.
34 
35    The user can open an alternative visualization context with
36    PetscViewerASCIIOpen() - output to a specified file.
37 
38    Level: beginner
39 
40 .seealso: PCView(), PetscViewerASCIIOpen()
41 @*/
PetscDrawView(PetscDraw indraw,PetscViewer viewer)42 PetscErrorCode  PetscDrawView(PetscDraw indraw,PetscViewer viewer)
43 {
44   PetscErrorCode ierr;
45   PetscBool      isdraw;
46 #if defined(PETSC_HAVE_SAWS)
47   PetscBool      issaws;
48 #endif
49 
50   PetscFunctionBegin;
51   PetscValidHeaderSpecific(indraw,PETSC_DRAW_CLASSID,1);
52   if (!viewer) {
53     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)indraw),&viewer);CHKERRQ(ierr);
54   }
55   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
56   PetscCheckSameComm(indraw,1,viewer,2);
57 
58   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)indraw,viewer);CHKERRQ(ierr);
59   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
60 #if defined(PETSC_HAVE_SAWS)
61   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
62 #endif
63   if (isdraw) {
64     PetscDraw draw;
65     char      str[36];
66     PetscReal x,y,bottom,h;
67 
68     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
69     ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
70     ierr   = PetscStrncpy(str,"PetscDraw: ",sizeof(str));CHKERRQ(ierr);
71     ierr   = PetscStrlcat(str,((PetscObject)indraw)->type_name,sizeof(str));CHKERRQ(ierr);
72     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_RED,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
73     bottom = y - h;
74     ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
75 #if defined(PETSC_HAVE_SAWS)
76   } else if (issaws) {
77     PetscMPIInt rank;
78 
79     ierr = PetscObjectName((PetscObject)indraw);CHKERRQ(ierr);
80     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
81     if (!((PetscObject)indraw)->amsmem && !rank) {
82       ierr = PetscObjectViewSAWs((PetscObject)indraw,viewer);CHKERRQ(ierr);
83     }
84 #endif
85   } else if (indraw->ops->view) {
86     ierr = (*indraw->ops->view)(indraw,viewer);CHKERRQ(ierr);
87   }
88   PetscFunctionReturn(0);
89 }
90 
91 /*@C
92    PetscDrawViewFromOptions - View from Options
93 
94    Collective on PetscDraw
95 
96    Input Parameters:
97 +  A - the PetscDraw context
98 .  obj - Optional object
99 -  name - command line option
100 
101    Level: intermediate
102 .seealso:  PetscDraw, PetscDrawView, PetscObjectViewFromOptions(), PetscDrawCreate()
103 @*/
PetscDrawViewFromOptions(PetscDraw A,PetscObject obj,const char name[])104 PetscErrorCode  PetscDrawViewFromOptions(PetscDraw A,PetscObject obj,const char name[])
105 {
106   PetscErrorCode ierr;
107 
108   PetscFunctionBegin;
109   PetscValidHeaderSpecific(A,PETSC_DRAW_CLASSID,1);
110   ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr);
111   PetscFunctionReturn(0);
112 }
113 
114 /*@C
115    PetscDrawCreate - Creates a graphics context.
116 
117    Collective
118 
119    Input Parameter:
120 +  comm - MPI communicator
121 .  display - X display when using X windows
122 .  title - optional title added to top of window
123 .  x,y - coordinates of lower left corner of window or PETSC_DECIDE
124 -  w, h - width and height of window or PETSC_DECIDE or PETSC_DRAW_HALF_SIZE, PETSC_DRAW_FULL_SIZE,
125           or PETSC_DRAW_THIRD_SIZE or PETSC_DRAW_QUARTER_SIZE
126 
127    Output Parameter:
128 .  draw - location to put the PetscDraw context
129 
130    Level: beginner
131 
132 
133 .seealso: PetscDrawSetType(), PetscDrawSetFromOptions(), PetscDrawDestroy(), PetscDrawSetType(), PetscDrawLGCreate(), PetscDrawSPCreate(),
134           PetscDrawViewPortsCreate(), PetscDrawViewPortsSet(), PetscDrawAxisCreate(), PetscDrawHGCreate(), PetscDrawBarCreate(),
135           PetscViewerDrawGetDraw(), PetscDrawSetFromOptions(), PetscDrawSetSave(), PetscDrawSetSaveMovie(), PetscDrawSetSaveFinalImage(),
136           PetscDrawOpenX(), PetscDrawOpenImage(), PetscDrawIsNull(), PetscDrawGetPopup(), PetscDrawCheckResizedWindow(), PetscDrawResizeWindow(),
137           PetscDrawGetWindowSize(), PetscDrawLine(), PetscDrawArrow(), PetscDrawLineSetWidth(), PetscDrawLineGetWidth(), PetscDrawMarker(),
138           PetscDrawPoint(), PetscDrawRectangle(), PetscDrawTriangle(), PetscDrawEllipse(), PetscDrawString(), PetscDrawStringCentered(),
139           PetscDrawStringBoxed(), PetscDrawStringBoxed(), PetscDrawStringVertical(), PetscDrawSetViewPort(), PetscDrawGetViewPort(),
140           PetscDrawSplitViewPort(), PetscDrawSetTitle(), PetscDrawAppendTitle(), PetscDrawGetTitle(), PetscDrawSetPause(), PetscDrawGetPause(),
141           PetscDrawPause(), PetscDrawSetDoubleBuffer(), PetscDrawClear(), PetscDrawFlush(), PetscDrawGetSingleton(), PetscDrawGetMouseButton(),
142           PetscDrawZoom(), PetscDrawGetBoundingBox()
143 
144 @*/
PetscDrawCreate(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw * indraw)145 PetscErrorCode  PetscDrawCreate(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *indraw)
146 {
147   PetscDraw      draw;
148   PetscErrorCode ierr;
149   PetscReal      dpause = 0.0;
150   PetscBool      flag;
151 
152   PetscFunctionBegin;
153   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
154   *indraw = NULL;
155   ierr = PetscHeaderCreate(draw,PETSC_DRAW_CLASSID,"Draw","Graphics","Draw",comm,PetscDrawDestroy,PetscDrawView);CHKERRQ(ierr);
156 
157   draw->data    = NULL;
158   ierr          = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
159   ierr          = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
160   draw->x       = x;
161   draw->y       = y;
162   draw->w       = w;
163   draw->h       = h;
164   draw->pause   = 0.0;
165   draw->coor_xl = 0.0;
166   draw->coor_xr = 1.0;
167   draw->coor_yl = 0.0;
168   draw->coor_yr = 1.0;
169   draw->port_xl = 0.0;
170   draw->port_xr = 1.0;
171   draw->port_yl = 0.0;
172   draw->port_yr = 1.0;
173   draw->popup   = NULL;
174 
175   ierr = PetscOptionsGetReal(NULL,NULL,"-draw_pause",&dpause,&flag);CHKERRQ(ierr);
176   if (flag) draw->pause = dpause;
177 
178   draw->savefilename   = NULL;
179   draw->saveimageext   = NULL;
180   draw->savemovieext   = NULL;
181   draw->savefilecount  = 0;
182   draw->savesinglefile = PETSC_FALSE;
183   draw->savemoviefps   = PETSC_DECIDE;
184 
185   ierr = PetscDrawSetCurrentPoint(draw,.5,.9);CHKERRQ(ierr);
186 
187   draw->boundbox_xl  = .5;
188   draw->boundbox_xr  = .5;
189   draw->boundbox_yl  = .9;
190   draw->boundbox_yr  = .9;
191 
192   *indraw = draw;
193   PetscFunctionReturn(0);
194 }
195 
196 /*@C
197    PetscDrawSetType - Builds graphics object for a particular implementation
198 
199    Collective on PetscDraw
200 
201    Input Parameter:
202 +  draw      - the graphics context
203 -  type      - for example, PETSC_DRAW_X
204 
205    Options Database Command:
206 .  -draw_type  <type> - Sets the type; use -help for a list of available methods (for instance, x)
207 
208    See PetscDrawSetFromOptions() for additional options database keys
209 
210    Level: intermediate
211 
212    Notes:
213    See "petsc/include/petscdraw.h" for available methods (for instance,
214    PETSC_DRAW_X, PETSC_DRAW_TIKZ or PETSC_DRAW_IMAGE)
215 
216 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawType
217 @*/
PetscDrawSetType(PetscDraw draw,PetscDrawType type)218 PetscErrorCode  PetscDrawSetType(PetscDraw draw,PetscDrawType type)
219 {
220   PetscErrorCode ierr,(*r)(PetscDraw);
221   PetscBool      match;
222   PetscBool      flg=PETSC_FALSE;
223 
224   PetscFunctionBegin;
225   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
226   PetscValidCharPointer(type,2);
227 
228   ierr = PetscObjectTypeCompare((PetscObject)draw,type,&match);CHKERRQ(ierr);
229   if (match) PetscFunctionReturn(0);
230 
231   /*  User requests no graphics */
232   ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&flg);CHKERRQ(ierr);
233 
234   /*
235      This is not ideal, but it allows codes to continue to run if X graphics
236    was requested but is not installed on this machine. Mostly this is for
237    testing.
238    */
239 #if !defined(PETSC_HAVE_X)
240   if (!flg) {
241     ierr = PetscStrcmp(type,PETSC_DRAW_X,&match);CHKERRQ(ierr);
242     if (match) {
243       PetscBool dontwarn = PETSC_TRUE;
244       flg  = PETSC_TRUE;
245       ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&dontwarn);CHKERRQ(ierr);
246       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X windows on this machine\nproceeding without graphics\n");
247     }
248   }
249 #endif
250   if (flg) {
251     ierr = PetscStrcmp(type,"tikz",&flg);CHKERRQ(ierr);
252     if (!flg) type = PETSC_DRAW_NULL;
253   }
254 
255   ierr = PetscStrcmp(type,PETSC_DRAW_NULL,&match);CHKERRQ(ierr);
256   if (match) {
257     ierr = PetscOptionsHasName(NULL,NULL,"-draw_double_buffer",NULL);CHKERRQ(ierr);
258     ierr = PetscOptionsHasName(NULL,NULL,"-draw_virtual",NULL);CHKERRQ(ierr);
259     ierr = PetscOptionsHasName(NULL,NULL,"-draw_fast",NULL);CHKERRQ(ierr);
260     ierr = PetscOptionsHasName(NULL,NULL,"-draw_ports",NULL);CHKERRQ(ierr);
261     ierr = PetscOptionsHasName(NULL,NULL,"-draw_coordinates",NULL);CHKERRQ(ierr);
262   }
263 
264   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
265   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
266   if (draw->ops->destroy) {ierr = (*draw->ops->destroy)(draw);CHKERRQ(ierr);}
267   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
268   ierr = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
269   ierr = (*r)(draw);CHKERRQ(ierr);
270   PetscFunctionReturn(0);
271 }
272 
273 /*@C
274    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
275 
276    Not Collective
277 
278    Input Parameter:
279 .  draw - Krylov context
280 
281    Output Parameters:
282 .  name - name of PetscDraw method
283 
284    Level: advanced
285 
286 .seealso: PetscDrawSetType(), PetscDrawType
287 
288 @*/
PetscDrawGetType(PetscDraw draw,PetscDrawType * type)289 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
290 {
291   PetscFunctionBegin;
292   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
293   PetscValidPointer(type,2);
294   *type = ((PetscObject)draw)->type_name;
295   PetscFunctionReturn(0);
296 }
297 
298 /*@C
299    PetscDrawRegister - Adds a method to the graphics package.
300 
301    Not Collective
302 
303    Input Parameters:
304 +  name_solver - name of a new user-defined graphics class
305 -  routine_create - routine to create method context
306 
307    Level: developer
308 
309    Notes:
310    PetscDrawRegister() may be called multiple times to add several user-defined graphics classes
311 
312    Sample usage:
313 .vb
314    PetscDrawRegister("my_draw_type", MyDrawCreate);
315 .ve
316 
317    Then, your specific graphics package can be chosen with the procedural interface via
318 $     PetscDrawSetType(ksp,"my_draw_type")
319    or at runtime via the option
320 $     -draw_type my_draw_type
321 
322 
323 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy(), PetscDrawType, PetscDrawSetType()
324 @*/
PetscDrawRegister(const char * sname,PetscErrorCode (* function)(PetscDraw))325 PetscErrorCode  PetscDrawRegister(const char *sname,PetscErrorCode (*function)(PetscDraw))
326 {
327   PetscErrorCode ierr;
328 
329   PetscFunctionBegin;
330   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
331   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
332   PetscFunctionReturn(0);
333 }
334 
335 /*@C
336    PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all
337    PetscDraw options in the database.
338 
339    Logically Collective on PetscDraw
340 
341    Input Parameter:
342 +  draw - the draw context
343 -  prefix - the prefix to prepend to all option names
344 
345    Level: advanced
346 
347 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate()
348 @*/
PetscDrawSetOptionsPrefix(PetscDraw draw,const char prefix[])349 PetscErrorCode  PetscDrawSetOptionsPrefix(PetscDraw draw,const char prefix[])
350 {
351   PetscErrorCode ierr;
352 
353   PetscFunctionBegin;
354   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
355   ierr = PetscObjectSetOptionsPrefix((PetscObject)draw,prefix);CHKERRQ(ierr);
356   PetscFunctionReturn(0);
357 }
358 
359 /*@
360    PetscDrawSetFromOptions - Sets the graphics type from the options database.
361       Defaults to a PETSc X windows graphics.
362 
363    Collective on PetscDraw
364 
365    Input Parameter:
366 .     draw - the graphics context
367 
368    Options Database Keys:
369 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
370 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
371 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
372 .   -draw_marker_type - <x,point>
373 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
374 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
375 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
376 .   -draw_save_single_file - saves each new image in the same file, normally each new image is saved in a new file with 'filename/filename_%d.ext'
377 .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
378 -   -draw_save_on_flush - saves an image on each flush, mainly for debugging
379 
380    Level: intermediate
381 
382    Notes:
383     Must be called after PetscDrawCreate() before the PetscDraw is used.
384 
385 
386 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage(), PetscDrawPause(), PetscDrawSetPause()
387 
388 @*/
PetscDrawSetFromOptions(PetscDraw draw)389 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
390 {
391   PetscErrorCode    ierr;
392   PetscBool         flg,nox;
393   char              vtype[256];
394   const char        *def;
395 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
396   PetscBool         warn;
397 #endif
398 
399   PetscFunctionBegin;
400   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
401 
402   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
403 
404   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
405   else {
406     ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox);CHKERRQ(ierr);
407     def  = PETSC_DRAW_NULL;
408 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
409     if (!nox) def = PETSC_DRAW_WIN32;
410 #elif defined(PETSC_HAVE_X)
411     if (!nox) def = PETSC_DRAW_X;
412 #else
413     ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn);CHKERRQ(ierr);
414     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows or Microsoft Graphics on this machine\nproceeding without graphics\n");
415 #endif
416   }
417   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
418   ierr = PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
419   if (flg) {
420     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
421   } else if (!((PetscObject)draw)->type_name) {
422     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
423   }
424   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
425   {
426     char      filename[PETSC_MAX_PATH_LEN];
427     char      movieext[32];
428     PetscBool image,movie;
429     ierr = PetscSNPrintf(filename,sizeof(filename),"%s%s",draw->savefilename?draw->savefilename:"",draw->saveimageext?draw->saveimageext:"");CHKERRQ(ierr);
430     ierr = PetscSNPrintf(movieext,sizeof(movieext),"%s",draw->savemovieext?draw->savemovieext:"");CHKERRQ(ierr);
431     ierr = PetscOptionsString("-draw_save","Save graphics to image file","PetscDrawSetSave",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
432     ierr = PetscOptionsString("-draw_save_movie","Make a movie from saved images","PetscDrawSetSaveMovie",movieext,movieext,sizeof(movieext),&movie);CHKERRQ(ierr);
433     ierr = PetscOptionsInt("-draw_save_movie_fps","Set frames per second in saved movie",PETSC_FUNCTION_NAME,draw->savemoviefps,&draw->savemoviefps,NULL);CHKERRQ(ierr);
434     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file",PETSC_FUNCTION_NAME,draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
435     if (image) {ierr = PetscDrawSetSave(draw,filename);CHKERRQ(ierr);}
436     if (movie) {ierr = PetscDrawSetSaveMovie(draw,movieext);CHKERRQ(ierr);}
437     ierr = PetscOptionsString("-draw_save_final_image","Save final graphics to image file","PetscDrawSetSaveFinalImage",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
438     if (image) {ierr = PetscDrawSetSaveFinalImage(draw,filename);CHKERRQ(ierr);}
439     ierr = PetscOptionsBool("-draw_save_on_clear","Save graphics to file on each clear",PETSC_FUNCTION_NAME,draw->saveonclear,&draw->saveonclear,NULL);CHKERRQ(ierr);
440     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file on each flush",PETSC_FUNCTION_NAME,draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
441   }
442   ierr = PetscOptionsReal("-draw_pause","Amount of time that program pauses after plots","PetscDrawSetPause",draw->pause,&draw->pause,NULL);CHKERRQ(ierr);
443   ierr = PetscOptionsEnum("-draw_marker_type","Type of marker to use on plots","PetscDrawSetMarkerType",PetscDrawMarkerTypes,(PetscEnum)draw->markertype,(PetscEnum *)&draw->markertype,NULL);CHKERRQ(ierr);
444 
445   /* process any options handlers added with PetscObjectAddOptionsHandler() */
446   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)draw);CHKERRQ(ierr);
447 
448   ierr = PetscDrawViewFromOptions(draw,NULL,"-draw_view");CHKERRQ(ierr);
449   ierr = PetscOptionsEnd();CHKERRQ(ierr);
450   PetscFunctionReturn(0);
451 }
452