xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision 2f6eced2a19e978d64f27de66fbc6c26cc5c7934)
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   = PetscStrcpy(str,"PetscDraw: ");CHKERRQ(ierr);
73     ierr   = PetscStrcat(str,((PetscObject)indraw)->type_name);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(), PetscDrawStringBoxedSize(), 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 = PetscStrcmp(type,"tikz",&flg);CHKERRQ(ierr);
237     if (!flg) type = PETSC_DRAW_NULL;
238   }
239 
240   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
241   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
242   if (draw->ops->destroy) {ierr = (*draw->ops->destroy)(draw);CHKERRQ(ierr);}
243   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
244   ierr = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
245   ierr = (*r)(draw);CHKERRQ(ierr);
246   PetscFunctionReturn(0);
247 }
248 
249 /*@C
250    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
251 
252    Not Collective
253 
254    Input Parameter:
255 .  draw - Krylov context
256 
257    Output Parameters:
258 .  name - name of PetscDraw method
259 
260    Level: advanced
261 
262 .seealso: PetscDrawSetType(), PetscDrawType
263 
264 @*/
265 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
266 {
267   PetscFunctionBegin;
268   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
269   PetscValidPointer(type,2);
270   *type = ((PetscObject)draw)->type_name;
271   PetscFunctionReturn(0);
272 }
273 
274 /*@C
275    PetscDrawRegister - Adds a method to the graphics package.
276 
277    Not Collective
278 
279    Input Parameters:
280 +  name_solver - name of a new user-defined graphics class
281 -  routine_create - routine to create method context
282 
283    Level: developer
284 
285    Notes:
286    PetscDrawRegister() may be called multiple times to add several user-defined graphics classes
287 
288    Sample usage:
289 .vb
290    PetscDrawRegister("my_draw_type", MyDrawCreate);
291 .ve
292 
293    Then, your specific graphics package can be chosen with the procedural interface via
294 $     PetscDrawSetType(ksp,"my_draw_type")
295    or at runtime via the option
296 $     -draw_type my_draw_type
297 
298    Concepts: graphics^registering new draw classes
299    Concepts: PetscDraw^registering new draw classes
300 
301 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy(), PetscDrawType, PetscDrawSetType()
302 @*/
303 PetscErrorCode  PetscDrawRegister(const char *sname,PetscErrorCode (*function)(PetscDraw))
304 {
305   PetscErrorCode ierr;
306 
307   PetscFunctionBegin;
308   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
309   PetscFunctionReturn(0);
310 }
311 
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(), PetscDrawCreate()
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 /*@
339    PetscDrawSetFromOptions - Sets the graphics type from the options database.
340       Defaults to a PETSc X windows graphics.
341 
342    Collective on PetscDraw
343 
344    Input Parameter:
345 .     draw - the graphics context
346 
347    Options Database Keys:
348 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
349 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
350 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
351 .   -draw_marker_type - <x,point>
352 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
353 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
354 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
355 .   -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'
356 .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
357 -   -draw_save_on_flush - saves an image on each flush, mainly for debugging
358 
359    Level: intermediate
360 
361    Notes: Must be called after PetscDrawCreate() before the PetscDraw is used.
362 
363    Concepts: drawing^setting options
364    Concepts: graphics^setting options
365 
366 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage(), PetscDrawPause(), PetscDrawSetPause()
367 
368 @*/
369 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
370 {
371   PetscErrorCode    ierr;
372   PetscBool         flg,nox;
373   char              vtype[256];
374   const char        *def;
375 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
376   PetscBool         warn;
377 #endif
378 
379   PetscFunctionBegin;
380   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
381 
382   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
383 
384   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
385   else {
386     ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox);CHKERRQ(ierr);
387     def  = PETSC_DRAW_NULL;
388 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
389     if (!nox) def = PETSC_DRAW_WIN32;
390 #elif defined(PETSC_HAVE_X)
391     if (!nox) def = PETSC_DRAW_X;
392 #elif defined(PETSC_HAVE_GLUT)
393     if (!nox) def = PETSC_DRAW_GLUT;
394 #elif defined(PETSC_HAVE_OPENGLES)
395     if (!nox) def = PETSC_DRAW_OPENGLES;
396 #else
397     ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn);CHKERRQ(ierr);
398     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
399 #endif
400   }
401   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
402   ierr = PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
403   if (flg) {
404     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
405   } else if (!((PetscObject)draw)->type_name) {
406     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
407   }
408   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
409   {
410     char      filename[PETSC_MAX_PATH_LEN];
411     char      movieext[32];
412     PetscBool image,movie;
413     ierr = PetscSNPrintf(filename,sizeof(filename),"%s%s",draw->savefilename?draw->savefilename:"",draw->saveimageext?draw->saveimageext:"");CHKERRQ(ierr);
414     ierr = PetscSNPrintf(movieext,sizeof(movieext),"%s",draw->savemovieext?draw->savemovieext:"");CHKERRQ(ierr);
415     ierr = PetscOptionsString("-draw_save","Save graphics to image file","PetscDrawSetSave",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
416     ierr = PetscOptionsString("-draw_save_movie","Make a movie from saved images","PetscDrawSetSaveMovie",movieext,movieext,sizeof(movieext),&movie);CHKERRQ(ierr);
417     ierr = PetscOptionsInt("-draw_save_movie_fps","Set frames per second in saved movie",PETSC_FUNCTION_NAME,draw->savemoviefps,&draw->savemoviefps,NULL);CHKERRQ(ierr);
418     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file",PETSC_FUNCTION_NAME,draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
419     if (image) {ierr = PetscDrawSetSave(draw,filename);CHKERRQ(ierr);}
420     if (movie) {ierr = PetscDrawSetSaveMovie(draw,movieext);CHKERRQ(ierr);}
421     ierr = PetscOptionsString("-draw_save_final_image","Save final graphics to image file","PetscDrawSetSaveFinalImage",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
422     if (image) {ierr = PetscDrawSetSaveFinalImage(draw,filename);CHKERRQ(ierr);}
423     ierr = PetscOptionsBool("-draw_save_on_clear","Save graphics to file on each clear",PETSC_FUNCTION_NAME,draw->saveonclear,&draw->saveonclear,NULL);CHKERRQ(ierr);
424     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file on each flush",PETSC_FUNCTION_NAME,draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
425   }
426   ierr = PetscOptionsReal("-draw_pause","Amount of time that program pauses after plots","PetscDrawSetPause",draw->pause,&draw->pause,NULL);CHKERRQ(ierr);
427   ierr = PetscOptionsEnum("-draw_marker_type","Type of marker to use on plots","PetscDrawSetMarkerType",PetscDrawMarkerTypes,(PetscEnum)draw->markertype,(PetscEnum *)&draw->markertype,NULL);CHKERRQ(ierr);
428 
429   /* process any options handlers added with PetscObjectAddOptionsHandler() */
430   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)draw);CHKERRQ(ierr);
431 
432   ierr = PetscDrawViewFromOptions(draw,NULL,"-draw_view");CHKERRQ(ierr);
433   ierr = PetscOptionsEnd();CHKERRQ(ierr);
434   PetscFunctionReturn(0);
435 }
436