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