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