xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision c09129f1575ca10e91085867db66f4d9c9ac2b6c)
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 = PetscDrawInitializePackage();CHKERRQ(ierr);
314   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
315   PetscFunctionReturn(0);
316 }
317 
318 /*@C
319    PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all
320    PetscDraw options in the database.
321 
322    Logically Collective on PetscDraw
323 
324    Input Parameter:
325 +  draw - the draw context
326 -  prefix - the prefix to prepend to all option names
327 
328    Level: advanced
329 
330 .keywords: PetscDraw, set, options, prefix, database
331 
332 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate()
333 @*/
334 PetscErrorCode  PetscDrawSetOptionsPrefix(PetscDraw draw,const char prefix[])
335 {
336   PetscErrorCode ierr;
337 
338   PetscFunctionBegin;
339   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
340   ierr = PetscObjectSetOptionsPrefix((PetscObject)draw,prefix);CHKERRQ(ierr);
341   PetscFunctionReturn(0);
342 }
343 
344 /*@
345    PetscDrawSetFromOptions - Sets the graphics type from the options database.
346       Defaults to a PETSc X windows graphics.
347 
348    Collective on PetscDraw
349 
350    Input Parameter:
351 .     draw - the graphics context
352 
353    Options Database Keys:
354 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
355 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
356 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
357 .   -draw_marker_type - <x,point>
358 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
359 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
360 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
361 .   -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'
362 .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
363 -   -draw_save_on_flush - saves an image on each flush, mainly for debugging
364 
365    Level: intermediate
366 
367    Notes:
368     Must be called after PetscDrawCreate() before the PetscDraw is used.
369 
370    Concepts: drawing^setting options
371    Concepts: graphics^setting options
372 
373 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage(), PetscDrawPause(), PetscDrawSetPause()
374 
375 @*/
376 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
377 {
378   PetscErrorCode    ierr;
379   PetscBool         flg,nox;
380   char              vtype[256];
381   const char        *def;
382 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
383   PetscBool         warn;
384 #endif
385 
386   PetscFunctionBegin;
387   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
388 
389   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
390 
391   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
392   else {
393     ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox);CHKERRQ(ierr);
394     def  = PETSC_DRAW_NULL;
395 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
396     if (!nox) def = PETSC_DRAW_WIN32;
397 #elif defined(PETSC_HAVE_X)
398     if (!nox) def = PETSC_DRAW_X;
399 #else
400     ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn);CHKERRQ(ierr);
401     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows or Microsoft Graphics on this machine\nproceeding without graphics\n");
402 #endif
403   }
404   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
405   ierr = PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
406   if (flg) {
407     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
408   } else if (!((PetscObject)draw)->type_name) {
409     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
410   }
411   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
412   {
413     char      filename[PETSC_MAX_PATH_LEN];
414     char      movieext[32];
415     PetscBool image,movie;
416     ierr = PetscSNPrintf(filename,sizeof(filename),"%s%s",draw->savefilename?draw->savefilename:"",draw->saveimageext?draw->saveimageext:"");CHKERRQ(ierr);
417     ierr = PetscSNPrintf(movieext,sizeof(movieext),"%s",draw->savemovieext?draw->savemovieext:"");CHKERRQ(ierr);
418     ierr = PetscOptionsString("-draw_save","Save graphics to image file","PetscDrawSetSave",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
419     ierr = PetscOptionsString("-draw_save_movie","Make a movie from saved images","PetscDrawSetSaveMovie",movieext,movieext,sizeof(movieext),&movie);CHKERRQ(ierr);
420     ierr = PetscOptionsInt("-draw_save_movie_fps","Set frames per second in saved movie",PETSC_FUNCTION_NAME,draw->savemoviefps,&draw->savemoviefps,NULL);CHKERRQ(ierr);
421     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file",PETSC_FUNCTION_NAME,draw->savesinglefile,&draw->savesinglefile,NULL);CHKERRQ(ierr);
422     if (image) {ierr = PetscDrawSetSave(draw,filename);CHKERRQ(ierr);}
423     if (movie) {ierr = PetscDrawSetSaveMovie(draw,movieext);CHKERRQ(ierr);}
424     ierr = PetscOptionsString("-draw_save_final_image","Save final graphics to image file","PetscDrawSetSaveFinalImage",filename,filename,sizeof(filename),&image);CHKERRQ(ierr);
425     if (image) {ierr = PetscDrawSetSaveFinalImage(draw,filename);CHKERRQ(ierr);}
426     ierr = PetscOptionsBool("-draw_save_on_clear","Save graphics to file on each clear",PETSC_FUNCTION_NAME,draw->saveonclear,&draw->saveonclear,NULL);CHKERRQ(ierr);
427     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file on each flush",PETSC_FUNCTION_NAME,draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
428   }
429   ierr = PetscOptionsReal("-draw_pause","Amount of time that program pauses after plots","PetscDrawSetPause",draw->pause,&draw->pause,NULL);CHKERRQ(ierr);
430   ierr = PetscOptionsEnum("-draw_marker_type","Type of marker to use on plots","PetscDrawSetMarkerType",PetscDrawMarkerTypes,(PetscEnum)draw->markertype,(PetscEnum *)&draw->markertype,NULL);CHKERRQ(ierr);
431 
432   /* process any options handlers added with PetscObjectAddOptionsHandler() */
433   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)draw);CHKERRQ(ierr);
434 
435   ierr = PetscDrawViewFromOptions(draw,NULL,"-draw_view");CHKERRQ(ierr);
436   ierr = PetscOptionsEnd();CHKERRQ(ierr);
437   PetscFunctionReturn(0);
438 }
439