xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision 16ad03002c971217bb7d68d241ce25e1b2bc6bef)
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     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 from being printed
318 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
319 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
320 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
321 .   -draw_save_on_flush - saves an image on each flush in addition to each clear
322 -   -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
323 
324    Level: intermediate
325 
326    Notes:
327     Must be called after PetscDrawCreate() before the PetscDrawtor is used.
328 
329     Concepts: drawing^setting options
330     Concepts: graphics^setting options
331 
332 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave()
333 
334 @*/
335 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
336 {
337   PetscErrorCode    ierr;
338   PetscBool         flg,nox;
339   char              vtype[256];
340   const char        *def;
341   PetscReal         dpause;
342 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
343   PetscBool         warn;
344 #endif
345   PetscViewer       v2;
346   PetscViewerFormat format;
347 
348   PetscFunctionBegin;
349   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
350 
351   if (!PetscDrawList) {
352     ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
353   }
354 
355   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
356   else {
357     ierr = PetscOptionsHasName(NULL,"-nox",&nox);CHKERRQ(ierr);
358     def  = PETSC_DRAW_NULL;
359 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
360     if (!nox) def = PETSC_DRAW_WIN32;
361 #elif defined(PETSC_HAVE_X)
362     if (!nox) def = PETSC_DRAW_X;
363 #elif defined(PETSC_HAVE_GLUT)
364     if (!nox) def = PETSC_DRAW_GLUT;
365 #elif defined(PETSC_HAVE_OPENGLES)
366     if (!nox) def = PETSC_DRAW_OPENGLES;
367 #else
368     ierr = PetscOptionsHasName(NULL,"-nox_warning",&warn);CHKERRQ(ierr);
369     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
370 #endif
371   }
372   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
373   ierr = PetscOptionsList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
374   if (flg) {
375     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
376   } else if (!((PetscObject)draw)->type_name) {
377     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
378   }
379   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
380 #if defined(PETSC_HAVE_X)
381   {
382     char      filename[PETSC_MAX_PATH_LEN];
383     PetscBool save,movie = PETSC_FALSE;
384     ierr = PetscOptionsBool("-draw_save_movie","Make a movie from the images saved (X Windows only)","PetscDrawSetSave",movie,&movie,NULL);CHKERRQ(ierr);
385     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file","PetscDrawSetSave",draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
386     ierr = PetscOptionsString("-draw_save","Save graphics to file (X Windows only)","PetscDrawSetSave",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr);
387     if (save) {
388       ierr = PetscDrawSetSave(draw,filename,movie);CHKERRQ(ierr);
389     }
390     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file (X Windows only) on each flush","PetscDrawSetSave",draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
391   }
392 #endif
393   ierr = PetscOptionsGetReal(NULL,"-draw_pause",&dpause,&flg);CHKERRQ(ierr);
394   if (flg) draw->pause = dpause;
395 
396   /* process any options handlers added with PetscObjectAddOptionsHandler() */
397   ierr = PetscObjectProcessOptionsHandlers((PetscObject)draw);CHKERRQ(ierr);
398   ierr = PetscOptionsViewer("-draw_view","Display Draw with the viewer","PetscDrawView",&v2,&format,&flg);CHKERRQ(ierr);
399   if (flg) {
400     ierr = PetscViewerPushFormat(v2,format);CHKERRQ(ierr);
401     ierr = PetscDrawView(draw,v2);CHKERRQ(ierr);
402     ierr = PetscViewerPopFormat(v2);CHKERRQ(ierr);
403   }
404   ierr = PetscOptionsEnd();CHKERRQ(ierr);
405   PetscFunctionReturn(0);
406 }
407 
408 #undef __FUNCT__
409 #define __FUNCT__ "PetscDrawSetSave"
410 /*@C
411    PetscDrawSetSave - Saves images produced in a PetscDraw into a file as a Gif file using AfterImage
412 
413    Collective on PetscDraw
414 
415    Input Parameter:
416 +  draw      - the graphics context
417 .  filename  - name of the file, if NULL uses name of draw object
418 -  movie - produce a movie of all the images
419 
420    Options Database Command:
421 +  -draw_save  <filename>
422 -  -draw_save_movie
423 
424    Level: intermediate
425 
426    Concepts: X windows^graphics
427 
428    Notes: You should call this BEFORE calling PetscDrawClear() and creating your image.
429 
430    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
431 
432    If X windows generates an error message about X_CreateWindow() failing then Afterimage was installed without X windows. Reinstall Afterimage using the
433    ./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
434 
435 
436 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
437 @*/
438 PetscErrorCode  PetscDrawSetSave(PetscDraw draw,const char *filename,PetscBool movie)
439 {
440   PetscErrorCode ierr;
441 
442   PetscFunctionBegin;
443   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
444   ierr = PetscFree(draw->savefilename);CHKERRQ(ierr);
445 
446   draw->savefilemovie = movie;
447   if (filename && filename[0]) {
448     ierr = PetscStrallocpy(filename,&draw->savefilename);CHKERRQ(ierr);
449   } else {
450     const char *name;
451     ierr = PetscObjectGetName((PetscObject)draw,&name);CHKERRQ(ierr);
452     ierr = PetscStrallocpy(name,&draw->savefilename);CHKERRQ(ierr);
453   }
454   if (draw->ops->setsave) {
455     ierr = (*draw->ops->setsave)(draw,filename);CHKERRQ(ierr);
456   }
457   PetscFunctionReturn(0);
458 }
459