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