xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision b2bbaf76f4dd33c9042d329b49dbc66b9ef10f10)
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   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
228   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
229   if (draw->data) {ierr = (*draw->ops->destroy)(draw);CHKERRQ(ierr);}
230   draw->ops->destroy = NULL;
231   draw->data         = NULL;
232   ierr       = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
233   ierr       = (*r)(draw);CHKERRQ(ierr);
234   PetscFunctionReturn(0);
235 }
236 
237 #undef __FUNCT__
238 #define __FUNCT__ "PetscDrawGetType"
239 /*@C
240    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
241 
242    Not Collective
243 
244    Input Parameter:
245 .  draw - Krylov context
246 
247    Output Parameters:
248 .  name - name of PetscDraw method
249 
250    Level: advanced
251 
252 @*/
253 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
254 {
255   PetscFunctionBegin;
256   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
257   PetscValidPointer(type,2);
258   *type = ((PetscObject)draw)->type_name;
259   PetscFunctionReturn(0);
260 }
261 
262 #undef __FUNCT__
263 #define __FUNCT__ "PetscDrawRegister"
264 /*@C
265    PetscDrawRegister - Adds a method to the graphics package.
266 
267    Not Collective
268 
269    Input Parameters:
270 +  name_solver - name of a new user-defined graphics class
271 -  routine_create - routine to create method context
272 
273    Level: developer
274 
275    Notes:
276    PetscDrawRegister() may be called multiple times to add several user-defined graphics classes
277 
278    Sample usage:
279 .vb
280    PetscDrawRegister("my_draw_type", MyDrawCreate);
281 .ve
282 
283    Then, your specific graphics package can be chosen with the procedural interface via
284 $     PetscDrawSetType(ksp,"my_draw_type")
285    or at runtime via the option
286 $     -draw_type my_draw_type
287 
288    Concepts: graphics^registering new draw classes
289    Concepts: PetscDraw^registering new draw classes
290 
291 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy()
292 @*/
293 PetscErrorCode  PetscDrawRegister(const char *sname,PetscErrorCode (*function)(PetscDraw))
294 {
295   PetscErrorCode ierr;
296 
297   PetscFunctionBegin;
298   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
299   PetscFunctionReturn(0);
300 }
301 
302 #undef __FUNCT__
303 #define __FUNCT__ "PetscDrawSetFromOptions"
304 /*@
305    PetscDrawSetFromOptions - Sets the graphics type from the options database.
306       Defaults to a PETSc X windows graphics.
307 
308    Collective on PetscDraw
309 
310    Input Parameter:
311 .     draw - the graphics context
312 
313    Options Database Keys:
314 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
315 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
316 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
317 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
318 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
319 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
320 .   -draw_save_on_flush - saves an image on each flush in addition to each clear
321 -   -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
322 
323    Level: intermediate
324 
325    Notes:
326     Must be called after PetscDrawCreate() before the PetscDraw is used.
327 
328     Concepts: drawing^setting options
329     Concepts: graphics^setting options
330 
331 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage()
332 
333 @*/
334 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
335 {
336   PetscErrorCode    ierr;
337   PetscBool         flg,nox;
338   char              vtype[256];
339   const char        *def;
340   PetscReal         dpause;
341 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
342   PetscBool         warn;
343 #endif
344 
345   PetscFunctionBegin;
346   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
347 
348   if (!PetscDrawList) {
349     ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
350   }
351 
352   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
353   else {
354     ierr = PetscOptionsHasName(NULL,"-nox",&nox);CHKERRQ(ierr);
355     def  = PETSC_DRAW_NULL;
356 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
357     if (!nox) def = PETSC_DRAW_WIN32;
358 #elif defined(PETSC_HAVE_X)
359     if (!nox) def = PETSC_DRAW_X;
360 #elif defined(PETSC_HAVE_GLUT)
361     if (!nox) def = PETSC_DRAW_GLUT;
362 #elif defined(PETSC_HAVE_OPENGLES)
363     if (!nox) def = PETSC_DRAW_OPENGLES;
364 #else
365     ierr = PetscOptionsHasName(NULL,"-nox_warning",&warn);CHKERRQ(ierr);
366     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
367 #endif
368   }
369   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
370   ierr = PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
371   if (flg) {
372     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
373   } else if (!((PetscObject)draw)->type_name) {
374     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
375   }
376   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
377 #if defined(PETSC_HAVE_X)
378   {
379     char      filename[PETSC_MAX_PATH_LEN];
380     PetscBool save,movie = PETSC_FALSE;
381     ierr = PetscOptionsBool("-draw_save_movie","Make a movie from the images saved (X Windows only)","PetscDrawSetSave",movie,&movie,NULL);CHKERRQ(ierr);
382     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file","PetscDrawSetSave",draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
383     ierr = PetscOptionsString("-draw_save","Save graphics to file (X Windows only)","PetscDrawSetSave",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr);
384     if (save) {
385       ierr = PetscDrawSetSave(draw,filename,movie);CHKERRQ(ierr);
386     }
387     ierr = PetscOptionsString("-draw_save_final_image","Save graphics to file (X Windows only)","PetscDrawSetSaveFinalImage",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr);
388     if (save) {
389       ierr = PetscDrawSetSaveFinalImage(draw,filename);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 
400   ierr = PetscDrawViewFromOptions(draw,NULL,"-draw_view");CHKERRQ(ierr);
401   ierr = PetscOptionsEnd();CHKERRQ(ierr);
402   PetscFunctionReturn(0);
403 }
404 
405 #undef __FUNCT__
406 #define __FUNCT__ "PetscDrawSetSave"
407 /*@C
408    PetscDrawSetSave - Saves images produced in a PetscDraw into a file as a Gif file using AfterImage
409 
410    Collective on PetscDraw
411 
412    Input Parameter:
413 +  draw      - the graphics context
414 .  filename  - name of the file, if NULL uses name of draw object
415 -  movie - produce a movie of all the images
416 
417    Options Database Command:
418 +  -draw_save  <filename>
419 -  -draw_save_movie
420 
421    Level: intermediate
422 
423    Concepts: X windows^graphics
424 
425    Notes: You should call this BEFORE calling PetscDrawClear() and creating your image.
426 
427    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
428 
429    If X windows generates an error message about X_CreateWindow() failing then Afterimage was installed without X windows. Reinstall Afterimage using the
430    ./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
431 
432 
433 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawSetSaveFinalImage()
434 @*/
435 PetscErrorCode  PetscDrawSetSave(PetscDraw draw,const char *filename,PetscBool movie)
436 {
437   PetscErrorCode ierr;
438 
439   PetscFunctionBegin;
440   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
441   ierr = PetscFree(draw->savefilename);CHKERRQ(ierr);
442 
443   draw->savefilemovie = movie;
444   if (filename && filename[0]) {
445     ierr = PetscStrallocpy(filename,&draw->savefilename);CHKERRQ(ierr);
446   } else {
447     const char *name;
448     ierr = PetscObjectGetName((PetscObject)draw,&name);CHKERRQ(ierr);
449     ierr = PetscStrallocpy(name,&draw->savefilename);CHKERRQ(ierr);
450   }
451   if (draw->ops->setsave) {
452     ierr = (*draw->ops->setsave)(draw,draw->savefilename);CHKERRQ(ierr);
453   }
454   PetscFunctionReturn(0);
455 }
456 
457 #undef __FUNCT__
458 #define __FUNCT__ "PetscDrawSetSaveFinalImage"
459 /*@C
460    PetscDrawSetSaveFinalImage - Saves the finale image produced in a PetscDraw into a file as a Gif file using AfterImage
461 
462    Collective on PetscDraw
463 
464    Input Parameter:
465 +  draw      - the graphics context
466 -  filename  - name of the file, if NULL uses name of draw object
467 
468    Options Database Command:
469 .  -draw_save_final_image  <filename>
470 
471    Level: intermediate
472 
473    Concepts: X windows^graphics
474 
475    Notes: You should call this BEFORE calling PetscDrawClear() and creating your image.
476 
477    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
478 
479    If X windows generates an error message about X_CreateWindow() failing then Afterimage was installed without X windows. Reinstall Afterimage using the
480    ./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
481 
482 
483 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawSetSave()
484 @*/
485 PetscErrorCode  PetscDrawSetSaveFinalImage(PetscDraw draw,const char *filename)
486 {
487   PetscErrorCode ierr;
488 
489   PetscFunctionBegin;
490   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
491   ierr = PetscFree(draw->savefinalfilename);CHKERRQ(ierr);
492 
493   if (filename && filename[0]) {
494     ierr = PetscStrallocpy(filename,&draw->savefinalfilename);CHKERRQ(ierr);
495   } else {
496     const char *name;
497     ierr = PetscObjectGetName((PetscObject)draw,&name);CHKERRQ(ierr);
498     ierr = PetscStrallocpy(name,&draw->savefinalfilename);CHKERRQ(ierr);
499   }
500   PetscFunctionReturn(0);
501 }
502