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