xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision bfcb38ea38335faa6e7f8d97f6bc6ce9aa2a1dd1)
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 on MPI_Comm
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    Concepts: graphics^creating context
110    Concepts: drawing^creating context
111 
112 .seealso: PetscDrawSetType(), PetscDrawSetFromOptions(), PetscDrawDestroy(), PetscDrawSetType(), PetscDrawLGCreate(), PetscDrawSPCreate(),
113           PetscDrawViewPortsCreate(), PetscDrawViewPortsSet(), PetscDrawAxisCreate(), PetscDrawHGCreate(), PetscDrawBarCreate(),
114           PetscViewerDrawGetDraw(), PetscDrawSetFromOptions(), PetscDrawSetSave(), PetscDrawSetSaveMovie(), PetscDrawSetSaveFinalImage(),
115           PetscDrawOpenX(), PetscDrawOpenImage(), PetscDrawIsNull(), PetscDrawGetPopup(), PetscDrawCheckResizedWindow(), PetscDrawResizeWindow(),
116           PetscDrawGetWindowSize(), PetscDrawLine(), PetscDrawArrow(), PetscDrawLineSetWidth(), PetscDrawLineGetWidth(), PetscDrawMarker(),
117           PetscDrawPoint(), PetscDrawRectangle(), PetscDrawTriangle(), PetscDrawEllipse(), PetscDrawString(), PetscDrawStringCentered(),
118           PetscDrawStringBoxed(), PetscDrawStringBoxed(), PetscDrawStringVertical(), PetscDrawSetViewPort(), PetscDrawGetViewPort(),
119           PetscDrawSplitViewPort(), PetscDrawSetTitle(), PetscDrawAppendTitle(), PetscDrawGetTitle(), PetscDrawSetPause(), PetscDrawGetPause(),
120           PetscDrawPause(), PetscDrawSetDoubleBuffer(), PetscDrawClear(), PetscDrawFlush(), PetscDrawGetSingleton(), PetscDrawGetMouseButton(),
121           PetscDrawZoom(), PetscDrawGetBoundingBox()
122 
123 @*/
124 PetscErrorCode  PetscDrawCreate(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *indraw)
125 {
126   PetscDraw      draw;
127   PetscErrorCode ierr;
128   PetscReal      dpause = 0.0;
129   PetscBool      flag;
130 
131   PetscFunctionBegin;
132   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
133   *indraw = 0;
134   ierr = PetscHeaderCreate(draw,PETSC_DRAW_CLASSID,"Draw","Graphics","Draw",comm,PetscDrawDestroy,PetscDrawView);CHKERRQ(ierr);
135 
136   draw->data    = NULL;
137   ierr          = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
138   ierr          = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
139   draw->x       = x;
140   draw->y       = y;
141   draw->w       = w;
142   draw->h       = h;
143   draw->pause   = 0.0;
144   draw->coor_xl = 0.0;
145   draw->coor_xr = 1.0;
146   draw->coor_yl = 0.0;
147   draw->coor_yr = 1.0;
148   draw->port_xl = 0.0;
149   draw->port_xr = 1.0;
150   draw->port_yl = 0.0;
151   draw->port_yr = 1.0;
152   draw->popup   = NULL;
153 
154   ierr = PetscOptionsGetReal(NULL,NULL,"-draw_pause",&dpause,&flag);CHKERRQ(ierr);
155   if (flag) draw->pause = dpause;
156 
157   draw->savefilename   = NULL;
158   draw->saveimageext   = NULL;
159   draw->savemovieext   = NULL;
160   draw->savefilecount  = 0;
161   draw->savesinglefile = PETSC_FALSE;
162   draw->savemoviefps   = PETSC_DECIDE;
163 
164   ierr = PetscDrawSetCurrentPoint(draw,.5,.9);CHKERRQ(ierr);
165 
166   draw->boundbox_xl  = .5;
167   draw->boundbox_xr  = .5;
168   draw->boundbox_yl  = .9;
169   draw->boundbox_yr  = .9;
170 
171   *indraw = draw;
172   PetscFunctionReturn(0);
173 }
174 
175 /*@C
176    PetscDrawSetType - Builds graphics object for a particular implementation
177 
178    Collective on PetscDraw
179 
180    Input Parameter:
181 +  draw      - the graphics context
182 -  type      - for example, PETSC_DRAW_X
183 
184    Options Database Command:
185 .  -draw_type  <type> - Sets the type; use -help for a list of available methods (for instance, x)
186 
187    See PetscDrawSetFromOptions() for additional options database keys
188 
189    Level: intermediate
190 
191    Notes:
192    See "petsc/include/petscdraw.h" for available methods (for instance,
193    PETSC_DRAW_X, PETSC_DRAW_TIKZ or PETSC_DRAW_IMAGE)
194 
195    Concepts: drawing^X windows
196    Concepts: X windows^graphics
197    Concepts: drawing^Microsoft Windows
198 
199 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawType
200 @*/
201 PetscErrorCode  PetscDrawSetType(PetscDraw draw,PetscDrawType type)
202 {
203   PetscErrorCode ierr,(*r)(PetscDraw);
204   PetscBool      match;
205   PetscBool      flg=PETSC_FALSE;
206 
207   PetscFunctionBegin;
208   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
209   PetscValidCharPointer(type,2);
210 
211   ierr = PetscObjectTypeCompare((PetscObject)draw,type,&match);CHKERRQ(ierr);
212   if (match) PetscFunctionReturn(0);
213 
214   /*  User requests no graphics */
215   ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&flg);CHKERRQ(ierr);
216 
217   /*
218      This is not ideal, but it allows codes to continue to run if X graphics
219    was requested but is not installed on this machine. Mostly this is for
220    testing.
221    */
222 #if !defined(PETSC_HAVE_X)
223   if (!flg) {
224     ierr = PetscStrcmp(type,PETSC_DRAW_X,&match);CHKERRQ(ierr);
225     if (match) {
226       PetscBool dontwarn = PETSC_TRUE;
227       flg  = PETSC_TRUE;
228       ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&dontwarn);CHKERRQ(ierr);
229       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X windows on this machine\nproceeding without graphics\n");
230     }
231   }
232 #endif
233   if (flg) {
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     ierr = PetscStrcmp(type,"tikz",&flg);CHKERRQ(ierr);
240     if (!flg) type = PETSC_DRAW_NULL;
241   }
242 
243   ierr =  PetscFunctionListFind(PetscDrawList,type,&r);CHKERRQ(ierr);
244   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
245   if (draw->ops->destroy) {ierr = (*draw->ops->destroy)(draw);CHKERRQ(ierr);}
246   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
247   ierr = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
248   ierr = (*r)(draw);CHKERRQ(ierr);
249   PetscFunctionReturn(0);
250 }
251 
252 /*@C
253    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
254 
255    Not Collective
256 
257    Input Parameter:
258 .  draw - Krylov context
259 
260    Output Parameters:
261 .  name - name of PetscDraw method
262 
263    Level: advanced
264 
265 .seealso: PetscDrawSetType(), PetscDrawType
266 
267 @*/
268 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
269 {
270   PetscFunctionBegin;
271   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
272   PetscValidPointer(type,2);
273   *type = ((PetscObject)draw)->type_name;
274   PetscFunctionReturn(0);
275 }
276 
277 /*@C
278    PetscDrawRegister - Adds a method to the graphics package.
279 
280    Not Collective
281 
282    Input Parameters:
283 +  name_solver - name of a new user-defined graphics class
284 -  routine_create - routine to create method context
285 
286    Level: developer
287 
288    Notes:
289    PetscDrawRegister() may be called multiple times to add several user-defined graphics classes
290 
291    Sample usage:
292 .vb
293    PetscDrawRegister("my_draw_type", MyDrawCreate);
294 .ve
295 
296    Then, your specific graphics package can be chosen with the procedural interface via
297 $     PetscDrawSetType(ksp,"my_draw_type")
298    or at runtime via the option
299 $     -draw_type my_draw_type
300 
301    Concepts: graphics^registering new draw classes
302    Concepts: PetscDraw^registering new draw classes
303 
304 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy(), PetscDrawType, PetscDrawSetType()
305 @*/
306 PetscErrorCode  PetscDrawRegister(const char *sname,PetscErrorCode (*function)(PetscDraw))
307 {
308   PetscErrorCode ierr;
309 
310   PetscFunctionBegin;
311   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
312   ierr = PetscFunctionListAdd(&PetscDrawList,sname,function);CHKERRQ(ierr);
313   PetscFunctionReturn(0);
314 }
315 
316 /*@C
317    PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all
318    PetscDraw options in the database.
319 
320    Logically Collective on PetscDraw
321 
322    Input Parameter:
323 +  draw - the draw context
324 -  prefix - the prefix to prepend to all option names
325 
326    Level: advanced
327 
328 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate()
329 @*/
330 PetscErrorCode  PetscDrawSetOptionsPrefix(PetscDraw draw,const char prefix[])
331 {
332   PetscErrorCode ierr;
333 
334   PetscFunctionBegin;
335   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
336   ierr = PetscObjectSetOptionsPrefix((PetscObject)draw,prefix);CHKERRQ(ierr);
337   PetscFunctionReturn(0);
338 }
339 
340 /*@
341    PetscDrawSetFromOptions - Sets the graphics type from the options database.
342       Defaults to a PETSc X windows graphics.
343 
344    Collective on PetscDraw
345 
346    Input Parameter:
347 .     draw - the graphics context
348 
349    Options Database Keys:
350 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
351 .   -nox_warning - when X windows support is not installed this prevents the warning message from being printed
352 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
353 .   -draw_marker_type - <x,point>
354 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
355 .   -draw_save_final_image [optional filename] - (X windows only) saves the final image displayed in a window
356 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
357 .   -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'
358 .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
359 -   -draw_save_on_flush - saves an image on each flush, mainly for debugging
360 
361    Level: intermediate
362 
363    Notes:
364     Must be called after PetscDrawCreate() before the PetscDraw is used.
365 
366    Concepts: drawing^setting options
367    Concepts: graphics^setting options
368 
369 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave(), PetscDrawSetSaveFinalImage(), PetscDrawPause(), PetscDrawSetPause()
370 
371 @*/
372 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
373 {
374   PetscErrorCode    ierr;
375   PetscBool         flg,nox;
376   char              vtype[256];
377   const char        *def;
378 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
379   PetscBool         warn;
380 #endif
381 
382   PetscFunctionBegin;
383   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
384 
385   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
386 
387   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
388   else {
389     ierr = PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox);CHKERRQ(ierr);
390     def  = PETSC_DRAW_NULL;
391 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
392     if (!nox) def = PETSC_DRAW_WIN32;
393 #elif defined(PETSC_HAVE_X)
394     if (!nox) def = PETSC_DRAW_X;
395 #else
396     ierr = PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn);CHKERRQ(ierr);
397     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows or Microsoft Graphics 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",PETSC_FUNCTION_NAME,draw->savemoviefps,&draw->savemoviefps,NULL);CHKERRQ(ierr);
417     ierr = PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file",PETSC_FUNCTION_NAME,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",PETSC_FUNCTION_NAME,draw->saveonclear,&draw->saveonclear,NULL);CHKERRQ(ierr);
423     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file on each flush",PETSC_FUNCTION_NAME,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