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