xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision 0fc8abbb0d2c66d68d698915e846a5e6ada4b530)
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   draw->savemoviefps   = PETSC_DECIDE;
159 
160   ierr = PetscDrawSetCurrentPoint(draw,.5,.9);CHKERRQ(ierr);
161 
162   draw->boundbox_xl  = .5;
163   draw->boundbox_xr  = .5;
164   draw->boundbox_yl  = .9;
165   draw->boundbox_yr  = .9;
166 
167   *indraw = draw;
168   PetscFunctionReturn(0);
169 }
170 
171 #undef __FUNCT__
172 #define __FUNCT__ "PetscDrawSetType"
173 /*@C
174    PetscDrawSetType - Builds graphics object for a particular implementation
175 
176    Collective on PetscDraw
177 
178    Input Parameter:
179 +  draw      - the graphics context
180 -  type      - for example, PETSC_DRAW_X
181 
182    Options Database Command:
183 .  -draw_type  <type> - Sets the type; use -help for a list of available methods (for instance, x)
184 
185    See PetscDrawSetFromOptions for additional options database keys
186 
187    Level: intermediate
188 
189    Notes:
190    See "petsc/include/petscdraw.h" for available methods (for instance,
191    PETSC_DRAW_X)
192 
193    Concepts: drawing^X windows
194    Concepts: X windows^graphics
195    Concepts: drawing^Microsoft Windows
196 
197 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
198 @*/
199 PetscErrorCode  PetscDrawSetType(PetscDraw draw,PetscDrawType type)
200 {
201   PetscErrorCode ierr,(*r)(PetscDraw);
202   PetscBool      match;
203   PetscBool      flg=PETSC_FALSE;
204 
205   PetscFunctionBegin;
206   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
207   PetscValidCharPointer(type,2);
208 
209   ierr = PetscObjectTypeCompare((PetscObject)draw,type,&match);CHKERRQ(ierr);
210   if (match) PetscFunctionReturn(0);
211 
212   /*  User requests no graphics */
213   ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&flg);CHKERRQ(ierr);
214 
215   /*
216      This is not ideal, but it allows codes to continue to run if X graphics
217    was requested but is not installed on this machine. Mostly this is for
218    testing.
219    */
220 #if !defined(PETSC_HAVE_X)
221   if (!flg) {
222     ierr = PetscStrcmp(type,PETSC_DRAW_X,&match);CHKERRQ(ierr);
223     if (match) {
224       PetscBool dontwarn = PETSC_TRUE;
225       flg  = PETSC_TRUE;
226       ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&dontwarn);CHKERRQ(ierr);
227       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X windows on this machine\nproceeding without graphics\n");
228     }
229   }
230 #endif
231   if (flg) {
232     ierr = PetscStrcmp(type,"tikz",&flg);CHKERRQ(ierr);
233     if (!flg) type = PETSC_DRAW_NULL;
234   }
235 
236   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
237   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
238   if (draw->ops->destroy) {ierr = (*draw->ops->destroy)(draw);CHKERRQ(ierr);}
239   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
240   ierr = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
241   ierr = (*r)(draw);CHKERRQ(ierr);
242   PetscFunctionReturn(0);
243 }
244 
245 #undef __FUNCT__
246 #define __FUNCT__ "PetscDrawGetType"
247 /*@C
248    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
249 
250    Not Collective
251 
252    Input Parameter:
253 .  draw - Krylov context
254 
255    Output Parameters:
256 .  name - name of PetscDraw method
257 
258    Level: advanced
259 
260 @*/
261 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
262 {
263   PetscFunctionBegin;
264   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
265   PetscValidPointer(type,2);
266   *type = ((PetscObject)draw)->type_name;
267   PetscFunctionReturn(0);
268 }
269 
270 #undef __FUNCT__
271 #define __FUNCT__ "PetscDrawRegister"
272 /*@C
273    PetscDrawRegister - Adds a method to the graphics package.
274 
275    Not Collective
276 
277    Input Parameters:
278 +  name_solver - name of a new user-defined graphics class
279 -  routine_create - routine to create method context
280 
281    Level: developer
282 
283    Notes:
284    PetscDrawRegister() may be called multiple times to add several user-defined graphics classes
285 
286    Sample usage:
287 .vb
288    PetscDrawRegister("my_draw_type", MyDrawCreate);
289 .ve
290 
291    Then, your specific graphics package can be chosen with the procedural interface via
292 $     PetscDrawSetType(ksp,"my_draw_type")
293    or at runtime via the option
294 $     -draw_type my_draw_type
295 
296    Concepts: graphics^registering new draw classes
297    Concepts: PetscDraw^registering new draw classes
298 
299 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy()
300 @*/
301 PetscErrorCode  PetscDrawRegister(const char *sname,PetscErrorCode (*function)(PetscDraw))
302 {
303   PetscErrorCode ierr;
304 
305   PetscFunctionBegin;
306   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
307   PetscFunctionReturn(0);
308 }
309 
310 #undef __FUNCT__
311 #define __FUNCT__ "PetscDrawSetOptionsPrefix"
312 /*@C
313    PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all
314    PetscDraw options in the database.
315 
316    Logically Collective on PetscDraw
317 
318    Input Parameter:
319 +  draw - the draw context
320 -  prefix - the prefix to prepend to all option names
321 
322    Level: advanced
323 
324 .keywords: PetscDraw, set, options, prefix, database
325 
326 .seealso: PetscDrawSetFromOptions()
327 @*/
328 PetscErrorCode  PetscDrawSetOptionsPrefix(PetscDraw draw,const char prefix[])
329 {
330   PetscErrorCode ierr;
331 
332   PetscFunctionBegin;
333   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
334   ierr = PetscObjectSetOptionsPrefix((PetscObject)draw,prefix);CHKERRQ(ierr);
335   PetscFunctionReturn(0);
336 }
337 
338 #undef __FUNCT__
339 #define __FUNCT__ "PetscDrawSetFromOptions"
340 /*@
341    PetscDrawSetFromOptions - Sets the graphics type from the options database.
342       Defaults to a PETSc X windows graphics.
343 
344    Collective on PetscDraw
345 
346    Input Parameter:
347 .     draw - the graphics context
348 
349    Options Database Keys:
350 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
351 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
352 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
353 .   -draw_marker_type - <x,point>
354 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
355 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
356 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
357 .   -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'
358 .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
359 -   -draw_save_on_flush - saves an image on each flush, mainly for debugging
360 
361    Level: intermediate
362 
363    Notes: Must be called after PetscDrawCreate() before the PetscDraw is used.
364 
365    Concepts: drawing^setting options
366    Concepts: graphics^setting options
367 
368 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage()
369 
370 @*/
371 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
372 {
373   PetscErrorCode    ierr;
374   PetscBool         flg,nox;
375   char              vtype[256];
376   const char        *def;
377 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
378   PetscBool         warn;
379 #endif
380 
381   PetscFunctionBegin;
382   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
383 
384   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
385 
386   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
387   else {
388     ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox);CHKERRQ(ierr);
389     def  = PETSC_DRAW_NULL;
390 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
391     if (!nox) def = PETSC_DRAW_WIN32;
392 #elif defined(PETSC_HAVE_X)
393     if (!nox) def = PETSC_DRAW_X;
394 #elif defined(PETSC_HAVE_GLUT)
395     if (!nox) def = PETSC_DRAW_GLUT;
396 #elif defined(PETSC_HAVE_OPENGLES)
397     if (!nox) def = PETSC_DRAW_OPENGLES;
398 #else
399     ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn);CHKERRQ(ierr);
400     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
401 #endif
402   }
403   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
404   ierr = PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
405   if (flg) {
406     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
407   } else if (!((PetscObject)draw)->type_name) {
408     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
409   }
410   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
411   {
412     char      filename[PETSC_MAX_PATH_LEN];
413     char      movieext[32];
414     PetscBool image,movie;
415     ierr = PetscSNPrintf(filename,sizeof(filename),"%s%s",draw->savefilename?draw->savefilename:"",draw->saveimageext?draw->saveimageext:"");CHKERRQ(ierr);
416     ierr = PetscSNPrintf(movieext,sizeof(movieext),"%s",draw->savemovieext?draw->savemovieext:"");CHKERRQ(ierr);
417     ierr = PetscOptionsString("-draw_save","Save graphics to image file","PetscDrawSetSave",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
418     ierr = PetscOptionsString("-draw_save_movie","Make a movie from saved images","PetscDrawSetSaveMovie",movieext,movieext,sizeof(movieext),&movie);CHKERRQ(ierr);
419     ierr = PetscOptionsInt("-draw_save_movie_fps","Set frames per second in saved movie",__FUNCT__,draw->savemoviefps,&draw->savemoviefps,NULL);CHKERRQ(ierr);
420     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file",__FUNCT__,draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
421     if (image) {ierr = PetscDrawSetSave(draw,filename);CHKERRQ(ierr);}
422     if (movie) {ierr = PetscDrawSetSaveMovie(draw,movieext);CHKERRQ(ierr);}
423     ierr = PetscOptionsString("-draw_save_final_image","Save final graphics to image file","PetscDrawSetSaveFinalImage",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
424     if (image) {ierr = PetscDrawSetSaveFinalImage(draw,filename);CHKERRQ(ierr);}
425     ierr = PetscOptionsBool("-draw_save_on_clear","Save graphics to file on each clear",__FUNCT__,draw->saveonclear,&draw->saveonclear,NULL);CHKERRQ(ierr);
426     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file on each flush",__FUNCT__,draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
427   }
428   ierr = PetscOptionsReal("-draw_pause","Amount of time that program pauses after plots","PetscDrawSetPause",draw->pause,&draw->pause,NULL);CHKERRQ(ierr);
429   ierr = PetscOptionsEnum("-draw_marker_type","Type of marker to use on plots","PetscDrawSetMarkerType",PetscDrawMarkerTypes,(PetscEnum)draw->markertype,(PetscEnum *)&draw->markertype,NULL);CHKERRQ(ierr);
430 
431   /* process any options handlers added with PetscObjectAddOptionsHandler() */
432   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)draw);CHKERRQ(ierr);
433 
434   ierr = PetscDrawViewFromOptions(draw,NULL,"-draw_view");CHKERRQ(ierr);
435   ierr = PetscOptionsEnd();CHKERRQ(ierr);
436   PetscFunctionReturn(0);
437 }
438