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