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