xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision ca93e9546dc92e90e21611678f80a2cde2568e43)
1 
2 /*
3        Provides the registration process for PETSc PetscDraw routines
4 */
5 #include <petsc-private/drawimpl.h>  /*I "petscdraw.h" I*/
6 
7 /*
8    Contains the list of registered PetscDraw routines
9 */
10 PetscFunctionList PetscDrawList = 0;
11 
12 #if defined(PETSC_HAVE_SAWS)
13 #include <petscviewersaws.h>
14 #endif
15 
16 #undef __FUNCT__
17 #define __FUNCT__ "PetscDrawView"
18 /*@C
19    PetscDrawView - Prints the PetscDraw data structure.
20 
21    Collective on PetscDraw
22 
23    Input Parameters:
24 +  indraw - the PetscDraw context
25 -  viewer - visualization context
26 
27    Options Database Keys:
28 .  -draw_view - print the ksp data structure at the end of a PetscDrawSetFromOptions() call
29 
30    Note:
31    The available visualization contexts include
32 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
33 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
34          output where only the first processor opens
35          the file.  All other processors send their
36          data to the first processor to print.
37 
38    The user can open an alternative visualization context with
39    PetscViewerASCIIOpen() - output to a specified file.
40 
41    Level: beginner
42 
43 .keywords: PetscDraw, view
44 
45 .seealso: PCView(), PetscViewerASCIIOpen()
46 @*/
47 PetscErrorCode  PetscDrawView(PetscDraw indraw,PetscViewer viewer)
48 {
49   PetscErrorCode ierr;
50   PetscBool      isdraw;
51 #if defined(PETSC_HAVE_SAWS)
52   PetscBool      isams;
53 #endif
54 
55   PetscFunctionBegin;
56   PetscValidHeaderSpecific(indraw,PETSC_DRAW_CLASSID,1);
57   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)indraw));
58   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
59   PetscCheckSameComm(indraw,1,viewer,2);
60 
61   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
62 #if defined(PETSC_HAVE_SAWS)
63   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&isams);CHKERRQ(ierr);
64 #endif
65   if (isdraw) {
66     PetscDraw draw;
67     char      str[36];
68     PetscReal x,y,bottom,h;
69 
70     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
71     ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
72     ierr   = PetscStrcpy(str,"PetscDraw: ");CHKERRQ(ierr);
73     ierr   = PetscStrcat(str,((PetscObject)indraw)->type_name);CHKERRQ(ierr);
74     ierr   = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_RED,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
75     bottom = y - h;
76     ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
77 #if defined(PETSC_HAVE_SAWS)
78   } else if (isams) {
79     if (!((PetscObject)indraw)->amsmem) {
80       ierr = PetscObjectViewSAWs((PetscObject)indraw,viewer);CHKERRQ(ierr);
81     }
82 #endif
83   } else if (indraw->ops->view) {
84     ierr = (*indraw->ops->view)(indraw,viewer);CHKERRQ(ierr);
85   }
86   PetscFunctionReturn(0);
87 }
88 
89 #undef __FUNCT__
90 #define __FUNCT__ "PetscDrawCreate"
91 /*@C
92    PetscDrawCreate - Creates a graphics context.
93 
94    Collective on MPI_Comm
95 
96    Input Parameter:
97 +  comm - MPI communicator
98 .  display - X display when using X windows
99 .  title - optional title added to top of window
100 .  x,y - coordinates of lower left corner of window or PETSC_DECIDE
101 -  w, h - width and height of window or PETSC_DECIDE or PETSC_DRAW_HALF_SIZE, PETSC_DRAW_FULL_SIZE,
102           or PETSC_DRAW_THIRD_SIZE or PETSC_DRAW_QUARTER_SIZE
103 
104    Output Parameter:
105 .  draw - location to put the PetscDraw context
106 
107    Level: beginner
108 
109    Concepts: graphics^creating context
110    Concepts: drawing^creating context
111 
112 .seealso: PetscDrawSetFromOptions(), PetscDrawDestroy(), PetscDrawSetType()
113 @*/
114 PetscErrorCode  PetscDrawCreate(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *indraw)
115 {
116   PetscDraw      draw;
117   PetscErrorCode ierr;
118   PetscReal      dpause;
119   PetscBool      flag;
120 
121   PetscFunctionBegin;
122 #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
123   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
124 #endif
125   *indraw = 0;
126   ierr = PetscHeaderCreate(draw,_p_PetscDraw,struct _PetscDrawOps,PETSC_DRAW_CLASSID,"Draw","Graphics","Draw",comm,PetscDrawDestroy,PetscDrawView);CHKERRQ(ierr);
127 
128   draw->data    = 0;
129   ierr          = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
130   ierr          = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
131   draw->x       = x;
132   draw->y       = y;
133   draw->w       = w;
134   draw->h       = h;
135   draw->pause   = 0.0;
136   draw->coor_xl = 0.0;
137   draw->coor_xr = 1.0;
138   draw->coor_yl = 0.0;
139   draw->coor_yr = 1.0;
140   draw->port_xl = 0.0;
141   draw->port_xr = 1.0;
142   draw->port_yl = 0.0;
143   draw->port_yr = 1.0;
144   draw->popup   = 0;
145 
146   ierr = PetscOptionsGetReal(NULL,"-draw_pause",&dpause,&flag);CHKERRQ(ierr);
147   if (flag) draw->pause = dpause;
148   draw->savefilename  = NULL;
149   draw->savefilemovie = PETSC_FALSE;
150   draw->savefilecount = -1;
151 
152   ierr = PetscDrawSetCurrentPoint(draw,.5,.9);CHKERRQ(ierr);
153 
154   draw->boundbox_xl  = .5;
155   draw->boundbox_xr  = .5;
156   draw->boundbox_yl  = .9;
157   draw->boundbox_yr  = .9;
158 
159   *indraw = draw;
160   PetscFunctionReturn(0);
161 }
162 
163 #undef __FUNCT__
164 #define __FUNCT__ "PetscDrawSetType"
165 /*@C
166    PetscDrawSetType - Builds graphics object for a particular implementation
167 
168    Collective on PetscDraw
169 
170    Input Parameter:
171 +  draw      - the graphics context
172 -  type      - for example, PETSC_DRAW_X
173 
174    Options Database Command:
175 .  -draw_type  <type> - Sets the type; use -help for a list
176     of available methods (for instance, x)
177 
178    Level: intermediate
179 
180    Notes:
181    See "petsc/include/petscdraw.h" for available methods (for instance,
182    PETSC_DRAW_X)
183 
184    Concepts: drawing^X windows
185    Concepts: X windows^graphics
186    Concepts: drawing^Microsoft Windows
187 
188 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
189 @*/
190 PetscErrorCode  PetscDrawSetType(PetscDraw draw,PetscDrawType type)
191 {
192   PetscErrorCode ierr,(*r)(PetscDraw);
193   PetscBool      match;
194   PetscBool      flg=PETSC_FALSE;
195 
196   PetscFunctionBegin;
197   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
198   PetscValidCharPointer(type,2);
199 
200   ierr = PetscObjectTypeCompare((PetscObject)draw,type,&match);CHKERRQ(ierr);
201   if (match) PetscFunctionReturn(0);
202 
203   /*  User requests no graphics */
204   ierr = PetscOptionsHasName(NULL,"-nox",&flg);CHKERRQ(ierr);
205 
206   /*
207      This is not ideal, but it allows codes to continue to run if X graphics
208    was requested but is not installed on this machine. Mostly this is for
209    testing.
210    */
211 #if !defined(PETSC_HAVE_X)
212   if (!flg) {
213     ierr = PetscStrcmp(type,PETSC_DRAW_X,&match);CHKERRQ(ierr);
214     if (match) {
215       PetscBool dontwarn = PETSC_TRUE;
216       flg  = PETSC_TRUE;
217       ierr = PetscOptionsHasName(NULL,"-nox_warning",&dontwarn);CHKERRQ(ierr);
218       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X windows on this machine\nproceeding without graphics\n");
219     }
220   }
221 #endif
222   if (flg) type = PETSC_DRAW_NULL;
223 
224   if (draw->data) {
225     /* destroy the old private PetscDraw context */
226     ierr               = (*draw->ops->destroy)(draw);CHKERRQ(ierr);
227     draw->ops->destroy = NULL;
228     draw->data         = 0;
229   }
230 
231   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
232   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
233   ierr       = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
234   draw->data = 0;
235   ierr       = (*r)(draw);CHKERRQ(ierr);
236   PetscFunctionReturn(0);
237 }
238 
239 #undef __FUNCT__
240 #define __FUNCT__ "PetscDrawGetType"
241 /*@C
242    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
243 
244    Not Collective
245 
246    Input Parameter:
247 .  draw - Krylov context
248 
249    Output Parameters:
250 .  name - name of PetscDraw method
251 
252    Level: advanced
253 
254 @*/
255 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
256 {
257   PetscFunctionBegin;
258   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
259   PetscValidPointer(type,2);
260   *type = ((PetscObject)draw)->type_name;
261   PetscFunctionReturn(0);
262 }
263 
264 #undef __FUNCT__
265 #define __FUNCT__ "PetscDrawRegister"
266 /*@C
267    PetscDrawRegister - Adds a method to the graphics package.
268 
269    Not Collective
270 
271    Input Parameters:
272 +  name_solver - name of a new user-defined graphics class
273 -  routine_create - routine to create method context
274 
275    Level: developer
276 
277    Notes:
278    PetscDrawRegister() may be called multiple times to add several user-defined graphics classes
279 
280    Sample usage:
281 .vb
282    PetscDrawRegister("my_draw_type", MyDrawCreate);
283 .ve
284 
285    Then, your specific graphics package can be chosen with the procedural interface via
286 $     PetscDrawSetType(ksp,"my_draw_type")
287    or at runtime via the option
288 $     -draw_type my_draw_type
289 
290    Concepts: graphics^registering new draw classes
291    Concepts: PetscDraw^registering new draw classes
292 
293 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy()
294 @*/
295 PetscErrorCode  PetscDrawRegister(const char *sname,PetscErrorCode (*function)(PetscDraw))
296 {
297   PetscErrorCode ierr;
298 
299   PetscFunctionBegin;
300   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
301   PetscFunctionReturn(0);
302 }
303 
304 #undef __FUNCT__
305 #define __FUNCT__ "PetscDrawSetFromOptions"
306 /*@
307    PetscDrawSetFromOptions - Sets the graphics type from the options database.
308       Defaults to a PETSc X windows graphics.
309 
310    Collective on PetscDraw
311 
312    Input Parameter:
313 .     draw - the graphics context
314 
315    Options Database Keys:
316 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
317 .   -nox_warning - when X windows support is not installed this prevents the warning message
318                    from being printed
319 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
320 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
321 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
322 .   -draw_save_on_flush - saves an image on each flush in addition to each clear
323 -   -draw_save_single_file - saves each new image in the same file, normally each new image is saved in a new file with filename_%d
324 
325    Level: intermediate
326 
327    Notes:
328     Must be called after PetscDrawCreate() before the PetscDrawtor is used.
329 
330     Concepts: drawing^setting options
331     Concepts: graphics^setting options
332 
333 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave()
334 
335 @*/
336 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
337 {
338   PetscErrorCode    ierr;
339   PetscBool         flg,nox;
340   char              vtype[256];
341   const char        *def;
342   PetscReal         dpause;
343 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
344   PetscBool         warn;
345 #endif
346   PetscViewer       v2;
347   PetscViewerFormat format;
348 
349   PetscFunctionBegin;
350   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
351 
352   if (!PetscDrawList) {
353     ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
354   }
355 
356   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
357   else {
358     ierr = PetscOptionsHasName(NULL,"-nox",&nox);CHKERRQ(ierr);
359     def  = PETSC_DRAW_NULL;
360 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
361     if (!nox) def = PETSC_DRAW_WIN32;
362 #elif defined(PETSC_HAVE_X)
363     if (!nox) def = PETSC_DRAW_X;
364 #elif defined(PETSC_HAVE_GLUT)
365     if (!nox) def = PETSC_DRAW_GLUT;
366 #elif defined(PETSC_HAVE_OPENGLES)
367     if (!nox) def = PETSC_DRAW_OPENGLES;
368 #else
369     ierr = PetscOptionsHasName(NULL,"-nox_warning",&warn);CHKERRQ(ierr);
370     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
371 #endif
372   }
373   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
374   ierr = PetscOptionsList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
375   if (flg) {
376     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
377   } else if (!((PetscObject)draw)->type_name) {
378     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
379   }
380   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
381 #if defined(PETSC_HAVE_X)
382   {
383     char      filename[PETSC_MAX_PATH_LEN];
384     PetscBool save,movie = PETSC_FALSE;
385     ierr = PetscOptionsBool("-draw_save_movie","Make a movie from the images saved (X Windows only)","PetscDrawSetSave",movie,&movie,NULL);CHKERRQ(ierr);
386     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file","PetscDrawSetSave",draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
387     ierr = PetscOptionsString("-draw_save","Save graphics to file (X Windows only)","PetscDrawSetSave",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr);
388     if (save) {
389       ierr = PetscDrawSetSave(draw,filename,movie);CHKERRQ(ierr);
390     }
391     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file (X Windows only) on each flush","PetscDrawSetSave",draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
392   }
393 #endif
394   ierr = PetscOptionsGetReal(NULL,"-draw_pause",&dpause,&flg);CHKERRQ(ierr);
395   if (flg) draw->pause = dpause;
396 
397   /* process any options handlers added with PetscObjectAddOptionsHandler() */
398   ierr = PetscObjectProcessOptionsHandlers((PetscObject)draw);CHKERRQ(ierr);
399   ierr = PetscOptionsViewer("-draw_view","Display Draw with the viewer","PetscDrawView",&v2,&format,&flg);CHKERRQ(ierr);
400   if (flg) {
401     ierr = PetscViewerPushFormat(v2,format);CHKERRQ(ierr);
402     ierr = PetscDrawView(draw,v2);CHKERRQ(ierr);
403     ierr = PetscViewerPopFormat(v2);CHKERRQ(ierr);
404   }
405   ierr = PetscOptionsEnd();CHKERRQ(ierr);
406   PetscFunctionReturn(0);
407 }
408 
409 #undef __FUNCT__
410 #define __FUNCT__ "PetscDrawSetSave"
411 /*@C
412    PetscDrawSetSave - Saves images produced in a PetscDraw into a file as a Gif file using AfterImage
413 
414    Collective on PetscDraw
415 
416    Input Parameter:
417 +  draw      - the graphics context
418 .  filename  - name of the file, if NULL uses name of draw object
419 -  movie - produce a movie of all the images
420 
421    Options Database Command:
422 +  -draw_save  <filename>
423 -  -draw_save_movie
424 
425    Level: intermediate
426 
427    Concepts: X windows^graphics
428 
429    Notes: You should call this BEFORE calling PetscDrawClear() and creating your image.
430 
431    Requires that PETSc be configured with the option --with-afterimage to save the images and ffmpeg must be in your path to make the movie
432 
433    If X windows generates an error message about X_CreateWindow() failing then Afterimage was installed without X windows. Reinstall Afterimage using the
434    ./configure flags --x-includes=/pathtoXincludes --x-libraries=/pathtoXlibraries   For example under Mac OS X Mountain Lion --x-includes=/opt/X11/include -x-libraries=/opt/X11/lib
435 
436 
437 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
438 @*/
439 PetscErrorCode  PetscDrawSetSave(PetscDraw draw,const char *filename,PetscBool movie)
440 {
441   PetscErrorCode ierr;
442 
443   PetscFunctionBegin;
444   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
445   ierr = PetscFree(draw->savefilename);CHKERRQ(ierr);
446 
447   draw->savefilemovie = movie;
448   if (filename && filename[0]) {
449     ierr = PetscStrallocpy(filename,&draw->savefilename);CHKERRQ(ierr);
450   } else {
451     const char *name;
452     ierr = PetscObjectGetName((PetscObject)draw,&name);CHKERRQ(ierr);
453     ierr = PetscStrallocpy(name,&draw->savefilename);CHKERRQ(ierr);
454   }
455   if (draw->ops->setsave) {
456     ierr = (*draw->ops->setsave)(draw,filename);CHKERRQ(ierr);
457   }
458   PetscFunctionReturn(0);
459 }
460