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