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