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