xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision 5b6bfdb9644f185dbf5e5a09b808ec241507e1e7)
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 /*@C
17    PetscDrawView - Prints the PetscDraw data structure.
18 
19    Collective on PetscDraw
20 
21    Input Parameters:
22 +  indraw - the PetscDraw context
23 -  viewer - visualization context
24 
25    See PetscDrawSetFromOptions() for options database keys
26 
27    Note:
28    The available visualization contexts include
29 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
30 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
31          output where only the first processor opens
32          the file.  All other processors send their
33          data to the first processor to print.
34 
35    The user can open an alternative visualization context with
36    PetscViewerASCIIOpen() - output to a specified file.
37 
38    Level: beginner
39 
40 .keywords: PetscDraw, view
41 
42 .seealso: PCView(), PetscViewerASCIIOpen()
43 @*/
44 PetscErrorCode  PetscDrawView(PetscDraw indraw,PetscViewer viewer)
45 {
46   PetscErrorCode ierr;
47   PetscBool      isdraw;
48 #if defined(PETSC_HAVE_SAWS)
49   PetscBool      issaws;
50 #endif
51 
52   PetscFunctionBegin;
53   PetscValidHeaderSpecific(indraw,PETSC_DRAW_CLASSID,1);
54   if (!viewer) {
55     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)indraw),&viewer);CHKERRQ(ierr);
56   }
57   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
58   PetscCheckSameComm(indraw,1,viewer,2);
59 
60   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)indraw,viewer);CHKERRQ(ierr);
61   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
62 #if defined(PETSC_HAVE_SAWS)
63   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);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   = PetscStrncpy(str,"PetscDraw: ",sizeof(str));CHKERRQ(ierr);
73     ierr   = PetscStrlcat(str,((PetscObject)indraw)->type_name,sizeof(str));CHKERRQ(ierr);
74     ierr   = PetscDrawStringBoxed(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 (issaws) {
79     PetscMPIInt rank;
80 
81     ierr = PetscObjectName((PetscObject)indraw);CHKERRQ(ierr);
82     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
83     if (!((PetscObject)indraw)->amsmem && !rank) {
84       ierr = PetscObjectViewSAWs((PetscObject)indraw,viewer);CHKERRQ(ierr);
85     }
86 #endif
87   } else if (indraw->ops->view) {
88     ierr = (*indraw->ops->view)(indraw,viewer);CHKERRQ(ierr);
89   }
90   PetscFunctionReturn(0);
91 }
92 
93 /*@C
94    PetscDrawCreate - Creates a graphics context.
95 
96    Collective on MPI_Comm
97 
98    Input Parameter:
99 +  comm - MPI communicator
100 .  display - X display when using X windows
101 .  title - optional title added to top of window
102 .  x,y - coordinates of lower left corner of window or PETSC_DECIDE
103 -  w, h - width and height of window or PETSC_DECIDE or PETSC_DRAW_HALF_SIZE, PETSC_DRAW_FULL_SIZE,
104           or PETSC_DRAW_THIRD_SIZE or PETSC_DRAW_QUARTER_SIZE
105 
106    Output Parameter:
107 .  draw - location to put the PetscDraw context
108 
109    Level: beginner
110 
111    Concepts: graphics^creating context
112    Concepts: drawing^creating context
113 
114 .seealso: PetscDrawSetType(), PetscDrawSetFromOptions(), PetscDrawDestroy(), PetscDrawSetType(), PetscDrawLGCreate(), PetscDrawSPCreate(),
115           PetscDrawViewPortsCreate(), PetscDrawViewPortsSet(), PetscDrawAxisCreate(), PetscDrawHGCreate(), PetscDrawBarCreate(),
116           PetscViewerDrawGetDraw(), PetscDrawSetFromOptions(), PetscDrawSetSave(), PetscDrawSetSaveMovie(), PetscDrawSetSaveFinalImage(),
117           PetscDrawOpenX(), PetscDrawOpenImage(), PetscDrawIsNull(), PetscDrawGetPopup(), PetscDrawCheckResizedWindow(), PetscDrawResizeWindow(),
118           PetscDrawGetWindowSize(), PetscDrawLine(), PetscDrawArrow(), PetscDrawLineSetWidth(), PetscDrawLineGetWidth(), PetscDrawMarker(),
119           PetscDrawPoint(), PetscDrawRectangle(), PetscDrawTriangle(), PetscDrawEllipse(), PetscDrawString(), PetscDrawStringCentered(),
120           PetscDrawStringBoxed(), PetscDrawStringBoxed(), PetscDrawStringVertical(), PetscDrawSetViewPort(), PetscDrawGetViewPort(),
121           PetscDrawSplitViewPort(), PetscDrawSetTitle(), PetscDrawAppendTitle(), PetscDrawGetTitle(), PetscDrawSetPause(), PetscDrawGetPause(),
122           PetscDrawPause(), PetscDrawSetDoubleBuffer(), PetscDrawClear(), PetscDrawFlush(), PetscDrawGetSingleton(), PetscDrawGetMouseButton(),
123           PetscDrawZoom(), PetscDrawGetBoundingBox()
124 
125 @*/
126 PetscErrorCode  PetscDrawCreate(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *indraw)
127 {
128   PetscDraw      draw;
129   PetscErrorCode ierr;
130   PetscReal      dpause = 0.0;
131   PetscBool      flag;
132 
133   PetscFunctionBegin;
134   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
135   *indraw = 0;
136   ierr = PetscHeaderCreate(draw,PETSC_DRAW_CLASSID,"Draw","Graphics","Draw",comm,PetscDrawDestroy,PetscDrawView);CHKERRQ(ierr);
137 
138   draw->data    = NULL;
139   ierr          = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
140   ierr          = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
141   draw->x       = x;
142   draw->y       = y;
143   draw->w       = w;
144   draw->h       = h;
145   draw->pause   = 0.0;
146   draw->coor_xl = 0.0;
147   draw->coor_xr = 1.0;
148   draw->coor_yl = 0.0;
149   draw->coor_yr = 1.0;
150   draw->port_xl = 0.0;
151   draw->port_xr = 1.0;
152   draw->port_yl = 0.0;
153   draw->port_yr = 1.0;
154   draw->popup   = NULL;
155 
156   ierr = PetscOptionsGetReal(NULL,NULL,"-draw_pause",&dpause,&flag);CHKERRQ(ierr);
157   if (flag) draw->pause = dpause;
158 
159   draw->savefilename   = NULL;
160   draw->saveimageext   = NULL;
161   draw->savemovieext   = NULL;
162   draw->savefilecount  = 0;
163   draw->savesinglefile = PETSC_FALSE;
164   draw->savemoviefps   = PETSC_DECIDE;
165 
166   ierr = PetscDrawSetCurrentPoint(draw,.5,.9);CHKERRQ(ierr);
167 
168   draw->boundbox_xl  = .5;
169   draw->boundbox_xr  = .5;
170   draw->boundbox_yl  = .9;
171   draw->boundbox_yr  = .9;
172 
173   *indraw = draw;
174   PetscFunctionReturn(0);
175 }
176 
177 /*@C
178    PetscDrawSetType - Builds graphics object for a particular implementation
179 
180    Collective on PetscDraw
181 
182    Input Parameter:
183 +  draw      - the graphics context
184 -  type      - for example, PETSC_DRAW_X
185 
186    Options Database Command:
187 .  -draw_type  <type> - Sets the type; use -help for a list of available methods (for instance, x)
188 
189    See PetscDrawSetFromOptions() for additional options database keys
190 
191    Level: intermediate
192 
193    Notes:
194    See "petsc/include/petscdraw.h" for available methods (for instance,
195    PETSC_DRAW_X, PETSC_DRAW_TIKZ or PETSC_DRAW_IMAGE)
196 
197    Concepts: drawing^X windows
198    Concepts: X windows^graphics
199    Concepts: drawing^Microsoft Windows
200 
201 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawType
202 @*/
203 PetscErrorCode  PetscDrawSetType(PetscDraw draw,PetscDrawType type)
204 {
205   PetscErrorCode ierr,(*r)(PetscDraw);
206   PetscBool      match;
207   PetscBool      flg=PETSC_FALSE;
208 
209   PetscFunctionBegin;
210   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
211   PetscValidCharPointer(type,2);
212 
213   ierr = PetscObjectTypeCompare((PetscObject)draw,type,&match);CHKERRQ(ierr);
214   if (match) PetscFunctionReturn(0);
215 
216   /*  User requests no graphics */
217   ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&flg);CHKERRQ(ierr);
218 
219   /*
220      This is not ideal, but it allows codes to continue to run if X graphics
221    was requested but is not installed on this machine. Mostly this is for
222    testing.
223    */
224 #if !defined(PETSC_HAVE_X)
225   if (!flg) {
226     ierr = PetscStrcmp(type,PETSC_DRAW_X,&match);CHKERRQ(ierr);
227     if (match) {
228       PetscBool dontwarn = PETSC_TRUE;
229       flg  = PETSC_TRUE;
230       ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&dontwarn);CHKERRQ(ierr);
231       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X windows on this machine\nproceeding without graphics\n");
232     }
233   }
234 #endif
235   if (flg) {
236     ierr = PetscOptionsHasName(NULL,NULL,"-draw_double_buffer",NULL);CHKERRQ(ierr);
237     ierr = PetscOptionsHasName(NULL,NULL,"-draw_virtual",NULL);CHKERRQ(ierr);
238     ierr = PetscOptionsHasName(NULL,NULL,"-draw_fast",NULL);CHKERRQ(ierr);
239     ierr = PetscOptionsHasName(NULL,NULL,"-draw_ports",NULL);CHKERRQ(ierr);
240     ierr = PetscOptionsHasName(NULL,NULL,"-draw_coordinates",NULL);CHKERRQ(ierr);
241     ierr = PetscStrcmp(type,"tikz",&flg);CHKERRQ(ierr);
242     if (!flg) type = PETSC_DRAW_NULL;
243   }
244 
245   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
246   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
247   if (draw->ops->destroy) {ierr = (*draw->ops->destroy)(draw);CHKERRQ(ierr);}
248   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
249   ierr = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
250   ierr = (*r)(draw);CHKERRQ(ierr);
251   PetscFunctionReturn(0);
252 }
253 
254 /*@C
255    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
256 
257    Not Collective
258 
259    Input Parameter:
260 .  draw - Krylov context
261 
262    Output Parameters:
263 .  name - name of PetscDraw method
264 
265    Level: advanced
266 
267 .seealso: PetscDrawSetType(), PetscDrawType
268 
269 @*/
270 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
271 {
272   PetscFunctionBegin;
273   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
274   PetscValidPointer(type,2);
275   *type = ((PetscObject)draw)->type_name;
276   PetscFunctionReturn(0);
277 }
278 
279 /*@C
280    PetscDrawRegister - Adds a method to the graphics package.
281 
282    Not Collective
283 
284    Input Parameters:
285 +  name_solver - name of a new user-defined graphics class
286 -  routine_create - routine to create method context
287 
288    Level: developer
289 
290    Notes:
291    PetscDrawRegister() may be called multiple times to add several user-defined graphics classes
292 
293    Sample usage:
294 .vb
295    PetscDrawRegister("my_draw_type", MyDrawCreate);
296 .ve
297 
298    Then, your specific graphics package can be chosen with the procedural interface via
299 $     PetscDrawSetType(ksp,"my_draw_type")
300    or at runtime via the option
301 $     -draw_type my_draw_type
302 
303    Concepts: graphics^registering new draw classes
304    Concepts: PetscDraw^registering new draw classes
305 
306 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy(), PetscDrawType, PetscDrawSetType()
307 @*/
308 PetscErrorCode  PetscDrawRegister(const char *sname,PetscErrorCode (*function)(PetscDraw))
309 {
310   PetscErrorCode ierr;
311 
312   PetscFunctionBegin;
313   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
314   PetscFunctionReturn(0);
315 }
316 
317 /*@C
318    PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all
319    PetscDraw options in the database.
320 
321    Logically Collective on PetscDraw
322 
323    Input Parameter:
324 +  draw - the draw context
325 -  prefix - the prefix to prepend to all option names
326 
327    Level: advanced
328 
329 .keywords: PetscDraw, set, options, prefix, database
330 
331 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate()
332 @*/
333 PetscErrorCode  PetscDrawSetOptionsPrefix(PetscDraw draw,const char prefix[])
334 {
335   PetscErrorCode ierr;
336 
337   PetscFunctionBegin;
338   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
339   ierr = PetscObjectSetOptionsPrefix((PetscObject)draw,prefix);CHKERRQ(ierr);
340   PetscFunctionReturn(0);
341 }
342 
343 /*@
344    PetscDrawSetFromOptions - Sets the graphics type from the options database.
345       Defaults to a PETSc X windows graphics.
346 
347    Collective on PetscDraw
348 
349    Input Parameter:
350 .     draw - the graphics context
351 
352    Options Database Keys:
353 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
354 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
355 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
356 .   -draw_marker_type - <x,point>
357 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
358 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
359 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
360 .   -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'
361 .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
362 -   -draw_save_on_flush - saves an image on each flush, mainly for debugging
363 
364    Level: intermediate
365 
366    Notes: Must be called after PetscDrawCreate() before the PetscDraw is used.
367 
368    Concepts: drawing^setting options
369    Concepts: graphics^setting options
370 
371 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage(), PetscDrawPause(), PetscDrawSetPause()
372 
373 @*/
374 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
375 {
376   PetscErrorCode    ierr;
377   PetscBool         flg,nox;
378   char              vtype[256];
379   const char        *def;
380 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
381   PetscBool         warn;
382 #endif
383 
384   PetscFunctionBegin;
385   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
386 
387   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
388 
389   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
390   else {
391     ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox);CHKERRQ(ierr);
392     def  = PETSC_DRAW_NULL;
393 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
394     if (!nox) def = PETSC_DRAW_WIN32;
395 #elif defined(PETSC_HAVE_X)
396     if (!nox) def = PETSC_DRAW_X;
397 #elif defined(PETSC_HAVE_GLUT)
398     if (!nox) def = PETSC_DRAW_GLUT;
399 #elif defined(PETSC_HAVE_OPENGLES)
400     if (!nox) def = PETSC_DRAW_OPENGLES;
401 #else
402     ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn);CHKERRQ(ierr);
403     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
404 #endif
405   }
406   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
407   ierr = PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
408   if (flg) {
409     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
410   } else if (!((PetscObject)draw)->type_name) {
411     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
412   }
413   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
414   {
415     char      filename[PETSC_MAX_PATH_LEN];
416     char      movieext[32];
417     PetscBool image,movie;
418     ierr = PetscSNPrintf(filename,sizeof(filename),"%s%s",draw->savefilename?draw->savefilename:"",draw->saveimageext?draw->saveimageext:"");CHKERRQ(ierr);
419     ierr = PetscSNPrintf(movieext,sizeof(movieext),"%s",draw->savemovieext?draw->savemovieext:"");CHKERRQ(ierr);
420     ierr = PetscOptionsString("-draw_save","Save graphics to image file","PetscDrawSetSave",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
421     ierr = PetscOptionsString("-draw_save_movie","Make a movie from saved images","PetscDrawSetSaveMovie",movieext,movieext,sizeof(movieext),&movie);CHKERRQ(ierr);
422     ierr = PetscOptionsInt("-draw_save_movie_fps","Set frames per second in saved movie",PETSC_FUNCTION_NAME,draw->savemoviefps,&draw->savemoviefps,NULL);CHKERRQ(ierr);
423     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file",PETSC_FUNCTION_NAME,draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
424     if (image) {ierr = PetscDrawSetSave(draw,filename);CHKERRQ(ierr);}
425     if (movie) {ierr = PetscDrawSetSaveMovie(draw,movieext);CHKERRQ(ierr);}
426     ierr = PetscOptionsString("-draw_save_final_image","Save final graphics to image file","PetscDrawSetSaveFinalImage",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
427     if (image) {ierr = PetscDrawSetSaveFinalImage(draw,filename);CHKERRQ(ierr);}
428     ierr = PetscOptionsBool("-draw_save_on_clear","Save graphics to file on each clear",PETSC_FUNCTION_NAME,draw->saveonclear,&draw->saveonclear,NULL);CHKERRQ(ierr);
429     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file on each flush",PETSC_FUNCTION_NAME,draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
430   }
431   ierr = PetscOptionsReal("-draw_pause","Amount of time that program pauses after plots","PetscDrawSetPause",draw->pause,&draw->pause,NULL);CHKERRQ(ierr);
432   ierr = PetscOptionsEnum("-draw_marker_type","Type of marker to use on plots","PetscDrawSetMarkerType",PetscDrawMarkerTypes,(PetscEnum)draw->markertype,(PetscEnum *)&draw->markertype,NULL);CHKERRQ(ierr);
433 
434   /* process any options handlers added with PetscObjectAddOptionsHandler() */
435   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)draw);CHKERRQ(ierr);
436 
437   ierr = PetscDrawViewFromOptions(draw,NULL,"-draw_view");CHKERRQ(ierr);
438   ierr = PetscOptionsEnd();CHKERRQ(ierr);
439   PetscFunctionReturn(0);
440 }
441