xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision 8067a7d5d1c29607366ed2aff819d529007817c0)
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    See PetscDrawSetFromOptions() for options database keys
28 
29    Note:
30    The available visualization contexts include
31 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
32 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
33          output where only the first processor opens
34          the file.  All other processors send their
35          data to the first processor to print.
36 
37    The user can open an alternative visualization context with
38    PetscViewerASCIIOpen() - output to a specified file.
39 
40    Level: beginner
41 
42 .keywords: PetscDraw, view
43 
44 .seealso: PCView(), PetscViewerASCIIOpen()
45 @*/
46 PetscErrorCode  PetscDrawView(PetscDraw indraw,PetscViewer viewer)
47 {
48   PetscErrorCode ierr;
49   PetscBool      isdraw;
50 #if defined(PETSC_HAVE_SAWS)
51   PetscBool      issaws;
52 #endif
53 
54   PetscFunctionBegin;
55   PetscValidHeaderSpecific(indraw,PETSC_DRAW_CLASSID,1);
56   if (!viewer) {
57     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)indraw),&viewer);CHKERRQ(ierr);
58   }
59   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
60   PetscCheckSameComm(indraw,1,viewer,2);
61 
62   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)indraw,viewer);CHKERRQ(ierr);
63   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
64 #if defined(PETSC_HAVE_SAWS)
65   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
66 #endif
67   if (isdraw) {
68     PetscDraw draw;
69     char      str[36];
70     PetscReal x,y,bottom,h;
71 
72     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
73     ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
74     ierr   = PetscStrcpy(str,"PetscDraw: ");CHKERRQ(ierr);
75     ierr   = PetscStrcat(str,((PetscObject)indraw)->type_name);CHKERRQ(ierr);
76     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_RED,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
77     bottom = y - h;
78     ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
79 #if defined(PETSC_HAVE_SAWS)
80   } else if (issaws) {
81     PetscMPIInt rank;
82 
83     ierr = PetscObjectName((PetscObject)indraw);CHKERRQ(ierr);
84     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
85     if (!((PetscObject)indraw)->amsmem && !rank) {
86       ierr = PetscObjectViewSAWs((PetscObject)indraw,viewer);CHKERRQ(ierr);
87     }
88 #endif
89   } else if (indraw->ops->view) {
90     ierr = (*indraw->ops->view)(indraw,viewer);CHKERRQ(ierr);
91   }
92   PetscFunctionReturn(0);
93 }
94 
95 #undef __FUNCT__
96 #define __FUNCT__ "PetscDrawCreate"
97 /*@C
98    PetscDrawCreate - Creates a graphics context.
99 
100    Collective on MPI_Comm
101 
102    Input Parameter:
103 +  comm - MPI communicator
104 .  display - X display when using X windows
105 .  title - optional title added to top of window
106 .  x,y - coordinates of lower left corner of window or PETSC_DECIDE
107 -  w, h - width and height of window or PETSC_DECIDE or PETSC_DRAW_HALF_SIZE, PETSC_DRAW_FULL_SIZE,
108           or PETSC_DRAW_THIRD_SIZE or PETSC_DRAW_QUARTER_SIZE
109 
110    Output Parameter:
111 .  draw - location to put the PetscDraw context
112 
113    Level: beginner
114 
115    Concepts: graphics^creating context
116    Concepts: drawing^creating context
117 
118 .seealso: PetscDrawSetFromOptions(), PetscDrawDestroy(), PetscDrawSetType()
119 @*/
120 PetscErrorCode  PetscDrawCreate(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *indraw)
121 {
122   PetscDraw      draw;
123   PetscErrorCode ierr;
124   PetscReal      dpause = 0.0;
125   PetscBool      flag;
126 
127   PetscFunctionBegin;
128   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
129   *indraw = 0;
130   ierr = PetscHeaderCreate(draw,PETSC_DRAW_CLASSID,"Draw","Graphics","Draw",comm,PetscDrawDestroy,PetscDrawView);CHKERRQ(ierr);
131 
132   draw->data    = NULL;
133   ierr          = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
134   ierr          = PetscStrallocpy(title,&draw->title);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   = NULL;
149 
150   ierr = PetscOptionsGetReal(NULL,NULL,"-draw_pause",&dpause,&flag);CHKERRQ(ierr);
151   if (flag) draw->pause = dpause;
152 
153   draw->savefilename   = NULL;
154   draw->saveimageext   = NULL;
155   draw->savemovieext   = NULL;
156   draw->savefilecount  = 0;
157   draw->savesinglefile = PETSC_FALSE;
158 
159   ierr = PetscDrawSetCurrentPoint(draw,.5,.9);CHKERRQ(ierr);
160 
161   draw->boundbox_xl  = .5;
162   draw->boundbox_xr  = .5;
163   draw->boundbox_yl  = .9;
164   draw->boundbox_yr  = .9;
165 
166   *indraw = draw;
167   PetscFunctionReturn(0);
168 }
169 
170 #undef __FUNCT__
171 #define __FUNCT__ "PetscDrawSetType"
172 /*@C
173    PetscDrawSetType - Builds graphics object for a particular implementation
174 
175    Collective on PetscDraw
176 
177    Input Parameter:
178 +  draw      - the graphics context
179 -  type      - for example, PETSC_DRAW_X
180 
181    Options Database Command:
182 .  -draw_type  <type> - Sets the type; use -help for a list of available methods (for instance, x)
183 
184    See PetscDrawSetFromOptions for additional options database keys
185 
186    Level: intermediate
187 
188    Notes:
189    See "petsc/include/petscdraw.h" for available methods (for instance,
190    PETSC_DRAW_X)
191 
192    Concepts: drawing^X windows
193    Concepts: X windows^graphics
194    Concepts: drawing^Microsoft Windows
195 
196 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
197 @*/
198 PetscErrorCode  PetscDrawSetType(PetscDraw draw,PetscDrawType type)
199 {
200   PetscErrorCode ierr,(*r)(PetscDraw);
201   PetscBool      match;
202   PetscBool      flg=PETSC_FALSE;
203 
204   PetscFunctionBegin;
205   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
206   PetscValidCharPointer(type,2);
207 
208   ierr = PetscObjectTypeCompare((PetscObject)draw,type,&match);CHKERRQ(ierr);
209   if (match) PetscFunctionReturn(0);
210 
211   /*  User requests no graphics */
212   ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&flg);CHKERRQ(ierr);
213 
214   /*
215      This is not ideal, but it allows codes to continue to run if X graphics
216    was requested but is not installed on this machine. Mostly this is for
217    testing.
218    */
219 #if !defined(PETSC_HAVE_X)
220   if (!flg) {
221     ierr = PetscStrcmp(type,PETSC_DRAW_X,&match);CHKERRQ(ierr);
222     if (match) {
223       PetscBool dontwarn = PETSC_TRUE;
224       flg  = PETSC_TRUE;
225       ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&dontwarn);CHKERRQ(ierr);
226       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X windows on this machine\nproceeding without graphics\n");
227     }
228   }
229 #endif
230   if (flg) type = PETSC_DRAW_NULL;
231 
232   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
233   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
234   if (draw->ops->destroy) {ierr = (*draw->ops->destroy)(draw);CHKERRQ(ierr);}
235   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
236   ierr = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
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__ "PetscDrawSetOptionsPrefix"
308 /*@C
309    PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all
310    PetscDraw options in the database.
311 
312    Logically Collective on PetscDraw
313 
314    Input Parameter:
315 +  draw - the draw context
316 -  prefix - the prefix to prepend to all option names
317 
318    Level: advanced
319 
320 .keywords: PetscDraw, set, options, prefix, database
321 
322 .seealso: PetscDrawSetFromOptions()
323 @*/
324 PetscErrorCode  PetscDrawSetOptionsPrefix(PetscDraw draw,const char prefix[])
325 {
326   PetscErrorCode ierr;
327 
328   PetscFunctionBegin;
329   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
330   ierr = PetscObjectSetOptionsPrefix((PetscObject)draw,prefix);CHKERRQ(ierr);
331   PetscFunctionReturn(0);
332 }
333 
334 #undef __FUNCT__
335 #define __FUNCT__ "PetscDrawSetFromOptions"
336 /*@
337    PetscDrawSetFromOptions - Sets the graphics type from the options database.
338       Defaults to a PETSc X windows graphics.
339 
340    Collective on PetscDraw
341 
342    Input Parameter:
343 .     draw - the graphics context
344 
345    Options Database Keys:
346 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
347 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
348 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
349 .   -draw_marker_type - <x,point>
350 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
351 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
352 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
353 .   -draw_save_single_file - saves each new image in the same file, normally each new image is saved in a new file with 'filename/filename_%d.ext'
354 .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
355 -   -draw_save_on_flush - saves an image on each flush, mainly for debugging
356 
357    Level: intermediate
358 
359    Notes: Must be called after PetscDrawCreate() before the PetscDraw is used.
360 
361    Concepts: drawing^setting options
362    Concepts: graphics^setting options
363 
364 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage()
365 
366 @*/
367 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
368 {
369   PetscErrorCode    ierr;
370   PetscBool         flg,nox;
371   char              vtype[256];
372   const char        *def;
373 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
374   PetscBool         warn;
375 #endif
376 
377   PetscFunctionBegin;
378   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
379 
380   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
381 
382   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
383   else {
384     ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox);CHKERRQ(ierr);
385     def  = PETSC_DRAW_NULL;
386 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
387     if (!nox) def = PETSC_DRAW_WIN32;
388 #elif defined(PETSC_HAVE_X)
389     if (!nox) def = PETSC_DRAW_X;
390 #elif defined(PETSC_HAVE_GLUT)
391     if (!nox) def = PETSC_DRAW_GLUT;
392 #elif defined(PETSC_HAVE_OPENGLES)
393     if (!nox) def = PETSC_DRAW_OPENGLES;
394 #else
395     ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn);CHKERRQ(ierr);
396     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
397 #endif
398   }
399   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
400   ierr = PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
401   if (flg) {
402     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
403   } else if (!((PetscObject)draw)->type_name) {
404     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
405   }
406   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
407 #if defined(PETSC_HAVE_X)
408   {
409     char      filename[PETSC_MAX_PATH_LEN] = "";
410     char      movieext[PETSC_MAX_PATH_LEN] = ".m4v";
411     PetscBool save,movie;
412     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file","PetscDrawSetSave",draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
413     ierr = PetscOptionsString("-draw_save","Save graphics to image file (X Windows only)","PetscDrawSetSave",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr);
414     ierr = PetscOptionsString("-draw_save_movie","Make a movie from the images saved (X Windows only)","PetscDrawSetSave",movieext,movieext,PETSC_MAX_PATH_LEN,&movie);CHKERRQ(ierr);
415     if (save || movie) {ierr = PetscDrawSetSave(draw,save?filename:NULL,movie?movieext:NULL);CHKERRQ(ierr);}
416     ierr = PetscOptionsString("-draw_save_final_image","Save graphics to file (X Windows only)","PetscDrawSetSaveFinalImage",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr);
417     if (save) {ierr = PetscDrawSetSaveFinalImage(draw,filename);CHKERRQ(ierr);}
418     ierr = PetscOptionsBool("-draw_save_on_clear","Save graphics to file (X Windows only) on each clear","PetscDrawSetSave",draw->saveonclear,&draw->saveonclear,NULL);CHKERRQ(ierr);
419     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file (X Windows only) on each flush","PetscDrawSetSave",draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
420   }
421 #endif
422   ierr = PetscOptionsReal("-draw_pause","Amount of time that program pauses after plots","PetscDrawSetPause",draw->pause,&draw->pause,NULL);CHKERRQ(ierr);
423   ierr = PetscOptionsEnum("-draw_marker_type","Type of marker to use on plots","PetscDrawSetMarkerType",PetscDrawMarkerTypes,(PetscEnum)draw->markertype,(PetscEnum *)&draw->markertype,NULL);CHKERRQ(ierr);
424 
425   /* process any options handlers added with PetscObjectAddOptionsHandler() */
426   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)draw);CHKERRQ(ierr);
427 
428   ierr = PetscDrawViewFromOptions(draw,NULL,"-draw_view");CHKERRQ(ierr);
429   ierr = PetscOptionsEnd();CHKERRQ(ierr);
430   PetscFunctionReturn(0);
431 }
432