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