Actual source code: drawv.c
1: #include <../src/sys/classes/viewer/impls/draw/vdraw.h>
2: #include <petscviewer.h>
4: static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
5: {
6: PetscInt i;
7: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
9: PetscFunctionBegin;
10: PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Destroying PetscViewer without first restoring singleton");
11: for (i = 0; i < vdraw->draw_max; i++) {
12: PetscCall(PetscDrawAxisDestroy(&vdraw->drawaxis[i]));
13: PetscCall(PetscDrawLGDestroy(&vdraw->drawlg[i]));
14: PetscCall(PetscDrawDestroy(&vdraw->draw[i]));
15: }
16: PetscCall(PetscFree(vdraw->display));
17: PetscCall(PetscFree(vdraw->title));
18: PetscCall(PetscFree3(vdraw->draw, vdraw->drawlg, vdraw->drawaxis));
19: PetscCall(PetscFree(vdraw->bounds));
20: PetscCall(PetscFree(vdraw->drawtype));
21: PetscCall(PetscFree(v->data));
22: PetscFunctionReturn(PETSC_SUCCESS);
23: }
25: static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
26: {
27: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
29: PetscFunctionBegin;
30: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
31: if (vdraw->draw[i]) PetscCall(PetscDrawFlush(vdraw->draw[i]));
32: }
33: PetscFunctionReturn(PETSC_SUCCESS);
34: }
36: /*@
37: PetscViewerDrawBaseAdd - add to the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
39: Logically Collective
41: Input Parameters:
42: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
43: - windownumber - how much to add to the base
45: Level: developer
47: Note:
48: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
50: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()`
51: @*/
52: PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber)
53: {
54: PetscViewer_Draw *vdraw;
55: PetscBool isdraw;
57: PetscFunctionBegin;
60: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
61: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
62: vdraw = (PetscViewer_Draw *)viewer->data;
64: PetscCheck(windownumber + vdraw->draw_base >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber + vdraw->draw_base);
65: vdraw->draw_base += windownumber;
66: PetscFunctionReturn(PETSC_SUCCESS);
67: }
69: /*@
70: PetscViewerDrawBaseSet - sets the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
72: Logically Collective
74: Input Parameters:
75: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
76: - windownumber - value to set the base
78: Level: developer
80: Note:
81: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
83: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()`
84: @*/
85: PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber)
86: {
87: PetscViewer_Draw *vdraw;
88: PetscBool isdraw;
90: PetscFunctionBegin;
93: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
94: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
95: vdraw = (PetscViewer_Draw *)viewer->data;
97: PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber);
98: vdraw->draw_base = windownumber;
99: PetscFunctionReturn(PETSC_SUCCESS);
100: }
102: /*@
103: PetscViewerDrawResize - Set the default width and height (in pixels) for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
105: Logically Collective
107: Input Parameters:
108: + v - the `PETSCVIEWERDRAW` viewer
109: . w - the new default window width in pixels; values less than 1 are ignored
110: - h - the new default window height in pixels; values less than 1 are ignored
112: Level: intermediate
114: Note:
115: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
117: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
118: @*/
119: PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h)
120: {
121: PetscViewer_Draw *vdraw;
122: PetscBool isdraw;
124: PetscFunctionBegin;
126: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
127: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
128: vdraw = (PetscViewer_Draw *)v->data;
130: if (w >= 1) vdraw->w = w;
131: if (h >= 1) vdraw->h = h;
132: PetscFunctionReturn(PETSC_SUCCESS);
133: }
135: /*@
136: PetscViewerDrawSetInfo - Record the default display, title, position, and size to use for `PetscDraw` windows
137: created by a `PETSCVIEWERDRAW` viewer.
139: Logically Collective
141: Input Parameters:
142: + v - the `PETSCVIEWERDRAW` viewer
143: . display - the X display name, or `NULL` for the local machine
144: . title - the window title, or `NULL`
145: . x - the horizontal screen coordinate of the upper left corner (unused; retained for API symmetry)
146: . y - the vertical screen coordinate of the upper left corner (unused; retained for API symmetry)
147: . w - the default window width in pixels; values less than 1 are ignored
148: - h - the default window height in pixels; values less than 1 are ignored
150: Level: intermediate
152: Note:
153: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
155: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetTitle()`, `PetscViewerDrawResize()`
156: @*/
157: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h)
158: {
159: PetscViewer_Draw *vdraw;
160: PetscBool isdraw;
162: PetscFunctionBegin;
164: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
165: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
166: vdraw = (PetscViewer_Draw *)v->data;
168: PetscCall(PetscStrallocpy(display, &vdraw->display));
169: PetscCall(PetscStrallocpy(title, &vdraw->title));
170: if (w >= 1) vdraw->w = w;
171: if (h >= 1) vdraw->h = h;
172: PetscFunctionReturn(PETSC_SUCCESS);
173: }
175: /*@
176: PetscViewerDrawSetTitle - Set the default title used for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
178: Logically Collective
180: Input Parameters:
181: + v - the `PETSCVIEWERDRAW` viewer
182: - title - the window title, or `NULL` for no title
184: Level: intermediate
186: Note:
187: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
189: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetTitle()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
190: @*/
191: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[])
192: {
193: PetscViewer_Draw *vdraw;
194: PetscBool isdraw;
196: PetscFunctionBegin;
198: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
199: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
200: vdraw = (PetscViewer_Draw *)v->data;
202: PetscCall(PetscFree(vdraw->title));
203: PetscCall(PetscStrallocpy(title, &vdraw->title));
204: PetscFunctionReturn(PETSC_SUCCESS);
205: }
207: /*@
208: PetscViewerDrawGetTitle - Get the default title used for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
210: Not Collective; No Fortran Support
212: Input Parameter:
213: . v - the `PETSCVIEWERDRAW` viewer
215: Output Parameter:
216: . title - the window title (owned by the viewer; do not free)
218: Level: intermediate
220: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawSetTitle()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
221: @*/
222: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[])
223: {
224: PetscViewer_Draw *vdraw;
225: PetscBool isdraw;
227: PetscFunctionBegin;
229: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
230: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
231: vdraw = (PetscViewer_Draw *)v->data;
233: *title = vdraw->title;
234: PetscFunctionReturn(PETSC_SUCCESS);
235: }
237: /*@
238: PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type
239: `PETSCVIEWERDRAW`.
241: Collective
243: Input Parameters:
244: + comm - communicator that will share window
245: . display - the X display on which to open, or `NULL` for the local machine
246: . title - the title to put in the title bar, or `NULL` for no title
247: . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
248: . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
249: . w - window width in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
250: - h - window height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
252: Output Parameter:
253: . viewer - the `PetscViewer`
255: Options Database Keys:
256: + -draw_type - use x or null
257: . -nox - Disables all x-windows output
258: . -display name - Specifies name of machine for the X display
259: . -geometry x,y,w,h - allows setting the window location and size
260: - -draw_pause pause - Sets time (in seconds) that the
261: program pauses after `PetscDrawPause()` has been called
262: (0 is default, -1 implies until user input).
264: Level: beginner
266: Notes:
267: If you want to do graphics in this window, you must call `PetscViewerDrawGetDraw()` and
268: perform the graphics on the `PetscDraw` object.
270: Format options include\:
271: + `PETSC_VIEWER_DRAW_BASIC` - displays with basic format
272: - `PETSC_VIEWER_DRAW_LG` - displays using a line graph
274: Fortran Note:
275: Whenever indicating null character data in a Fortran code,
276: `PETSC_NULL_CHARACTER` must be employed. Thus, `PETSC_NULL_CHARACTER` can be
277: used for the `display` and `title` input parameters.
279: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`,
280: `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`
281: @*/
282: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer)
283: {
284: PetscFunctionBegin;
285: PetscCall(PetscViewerCreate(comm, viewer));
286: PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW));
287: PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h));
288: PetscFunctionReturn(PETSC_SUCCESS);
289: }
291: #include <petsc/private/drawimpl.h>
293: static PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
294: {
295: PetscMPIInt rank;
296: PetscInt i;
297: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
299: PetscFunctionBegin;
300: PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous");
301: /* only processor zero can use the PetscViewer draw singleton */
302: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
303: if (rank == 0) {
304: PetscMPIInt flg;
305: PetscDraw draw, sdraw;
307: PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg));
308: PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
309: PetscCall(PetscViewerCreate(comm, sviewer));
310: PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW));
311: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
312: (*sviewer)->format = viewer->format;
313: for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
314: if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i]));
315: }
316: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
317: PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
318: if (draw->savefilename) {
319: PetscCall(PetscDrawSetSave(sdraw, draw->savefilename));
320: sdraw->savefilecount = draw->savefilecount;
321: sdraw->savesinglefile = draw->savesinglefile;
322: sdraw->savemoviefps = draw->savemoviefps;
323: sdraw->saveonclear = draw->saveonclear;
324: sdraw->saveonflush = draw->saveonflush;
325: }
326: if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename));
327: } else {
328: PetscDraw draw;
329: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
330: }
331: vdraw->singleton_made = PETSC_TRUE;
332: PetscFunctionReturn(PETSC_SUCCESS);
333: }
335: static PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
336: {
337: PetscMPIInt rank;
338: PetscInt i;
339: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
341: PetscFunctionBegin;
342: PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten");
343: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
344: if (rank == 0) {
345: PetscDraw draw, sdraw;
347: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
348: PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
349: if (draw->savefilename) {
350: draw->savefilecount = sdraw->savefilecount;
351: PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
352: }
353: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
354: for (i = 0; i < vdraw->draw_max; i++) {
355: if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i]));
356: }
357: PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis));
358: PetscCall(PetscFree((*sviewer)->data));
359: PetscCall(PetscHeaderDestroy(sviewer));
360: } else {
361: PetscDraw draw;
363: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
364: if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
365: }
367: vdraw->singleton_made = PETSC_FALSE;
368: PetscFunctionReturn(PETSC_SUCCESS);
369: }
371: static PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems PetscOptionsObject)
372: {
373: PetscReal bounds[16];
374: PetscInt nbounds = 16;
375: PetscBool flg;
377: PetscFunctionBegin;
378: PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options");
379: PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg));
380: if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds));
381: PetscOptionsHeadEnd();
382: PetscFunctionReturn(PETSC_SUCCESS);
383: }
385: static PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v)
386: {
387: PetscDraw draw;
388: PetscInt i;
389: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data;
390: PetscBool isascii;
392: PetscFunctionBegin;
393: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
394: if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Draw viewer is of type %s\n", vdraw->drawtype));
395: /* If the PetscViewer has just been created then no vdraw->draw yet
396: exists so this will not actually call the viewer on any draws. */
397: for (i = 0; i < vdraw->draw_base; i++) {
398: if (vdraw->draw[i]) {
399: PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw));
400: PetscCall(PetscDrawView(draw, v));
401: }
402: }
403: PetscFunctionReturn(PETSC_SUCCESS);
404: }
406: /*MC
407: PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
409: Level: beginner
411: .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`,
412: `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`,
413: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
414: `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
415: M*/
416: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
417: {
418: PetscViewer_Draw *vdraw;
420: PetscFunctionBegin;
421: PetscCall(PetscNew(&vdraw));
422: viewer->data = (void *)vdraw;
424: viewer->ops->flush = PetscViewerFlush_Draw;
425: viewer->ops->view = PetscViewerView_Draw;
426: viewer->ops->destroy = PetscViewerDestroy_Draw;
427: viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw;
428: viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw;
429: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
431: /* these are created on the fly if requested */
432: vdraw->draw_max = 5;
433: vdraw->draw_base = 0;
434: vdraw->w = PETSC_DECIDE;
435: vdraw->h = PETSC_DECIDE;
437: PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis));
438: vdraw->singleton_made = PETSC_FALSE;
439: PetscFunctionReturn(PETSC_SUCCESS);
440: }
442: /*@
443: PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`.
445: Not Collective
447: Input Parameter:
448: . viewer - the `PetscViewer`
450: Level: intermediate
452: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
453: @*/
454: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
455: {
456: PetscViewer_Draw *vdraw;
457: PetscBool isdraw;
459: PetscFunctionBegin;
461: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
462: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
463: vdraw = (PetscViewer_Draw *)viewer->data;
465: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
466: if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i]));
467: }
468: PetscFunctionReturn(PETSC_SUCCESS);
469: }
471: /*@
472: PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed) in the `PETSCVIEWERDRAW` `PetscViewer`
474: Not Collective
476: Input Parameter:
477: . viewer - the `PetscViewer`
479: Output Parameter:
480: . pause - the pause value
482: Level: intermediate
484: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
485: @*/
486: PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause)
487: {
488: PetscViewer_Draw *vdraw;
489: PetscBool isdraw;
490: PetscDraw draw;
492: PetscFunctionBegin;
494: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
495: if (!isdraw) {
496: *pause = 0.0;
497: PetscFunctionReturn(PETSC_SUCCESS);
498: }
499: vdraw = (PetscViewer_Draw *)viewer->data;
501: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
502: if (vdraw->draw[i]) {
503: PetscCall(PetscDrawGetPause(vdraw->draw[i], pause));
504: PetscFunctionReturn(PETSC_SUCCESS);
505: }
506: }
507: /* none exist yet so create one and get its pause */
508: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
509: PetscCall(PetscDrawGetPause(draw, pause));
510: PetscFunctionReturn(PETSC_SUCCESS);
511: }
513: /*@
514: PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer`
516: Not Collective
518: Input Parameters:
519: + viewer - the `PetscViewer`
520: - pause - the pause value
522: Level: intermediate
524: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
525: @*/
526: PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause)
527: {
528: PetscViewer_Draw *vdraw;
529: PetscBool isdraw;
531: PetscFunctionBegin;
533: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
534: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
535: vdraw = (PetscViewer_Draw *)viewer->data;
537: vdraw->pause = pause;
538: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
539: if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause));
540: }
541: PetscFunctionReturn(PETSC_SUCCESS);
542: }
544: /*@
545: PetscViewerDrawSetHold - Holds previous image when drawing new image in a `PETSCVIEWERDRAW`
547: Not Collective
549: Input Parameters:
550: + viewer - the `PetscViewer`
551: - hold - `PETSC_TRUE` indicates to hold the previous image
553: Level: intermediate
555: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
556: @*/
557: PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold)
558: {
559: PetscViewer_Draw *vdraw;
560: PetscBool isdraw;
562: PetscFunctionBegin;
564: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
565: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
566: vdraw = (PetscViewer_Draw *)viewer->data;
568: vdraw->hold = hold;
569: PetscFunctionReturn(PETSC_SUCCESS);
570: }
572: /*@
573: PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image
575: Not Collective
577: Input Parameter:
578: . viewer - the `PetscViewer`
580: Output Parameter:
581: . hold - indicates to hold or not
583: Level: intermediate
585: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
586: @*/
587: PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold)
588: {
589: PetscViewer_Draw *vdraw;
590: PetscBool isdraw;
592: PetscFunctionBegin;
594: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
595: if (!isdraw) {
596: *hold = PETSC_FALSE;
597: PetscFunctionReturn(PETSC_SUCCESS);
598: }
599: vdraw = (PetscViewer_Draw *)viewer->data;
601: *hold = vdraw->hold;
602: PetscFunctionReturn(PETSC_SUCCESS);
603: }
605: /*
606: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
607: is attached to a communicator, in this case the attribute is a PetscViewer.
608: */
609: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
611: /*@
612: PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors
613: in an MPI communicator.
615: Collective
617: Input Parameter:
618: . comm - the MPI communicator to share the window `PetscViewer`
620: Level: intermediate
622: Notes:
623: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
625: Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return
626: an error code. The window is usually used in the form
627: .vb
628: XXXView(XXX object, PETSC_VIEWER_DRAW_(comm));
629: .ve
631: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`,
632: @*/
633: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
634: {
635: PetscMPIInt iflg;
636: PetscViewer viewer;
637: MPI_Comm ncomm;
639: PetscFunctionBegin;
640: PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL));
641: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) PetscCallMPINull(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Draw_keyval, NULL));
642: PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &iflg));
643: if (!iflg) { /* PetscViewer not yet created */
644: PetscCallNull(PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer));
645: PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
646: PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer));
647: }
648: PetscCallNull(PetscCommDestroy(&ncomm));
649: PetscFunctionReturn(viewer);
650: }
652: /*@
653: PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting in a `PETSCVIEWERDRAW` `PetscViewer`
655: Collective
657: Input Parameters:
658: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
659: . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
660: - bounds - the actual bounds, the size of this is 2*`nbounds`, the values are stored in the order min F_0, max F_0, min F_1, max F_1, .....
662: Options Database Key:
663: . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds
665: Level: intermediate
667: Note:
668: this determines the colors used in 2d contour plots generated with VecView() for `DMDA` in 2d. Any values in the vector below or above the
669: bounds are moved to the bound value before plotting. In this way the color index from color to physical value remains the same for all plots generated with
670: this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
672: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
673: @*/
674: PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds)
675: {
676: PetscViewer_Draw *vdraw;
677: PetscBool isdraw;
679: PetscFunctionBegin;
681: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
682: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
683: vdraw = (PetscViewer_Draw *)viewer->data;
685: vdraw->nbounds = nbounds;
686: PetscCall(PetscFree(vdraw->bounds));
687: PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds));
688: PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds));
689: PetscFunctionReturn(PETSC_SUCCESS);
690: }
692: /*@
693: PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()`
695: Collective
697: Input Parameter:
698: . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
700: Output Parameters:
701: + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
702: - bounds - the actual bounds, the size of this is 2*`nbounds`, the values are stored in the order min F_0, max F_0, min F_1, max F_1, .....
704: Level: intermediate
706: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()`
707: @*/
708: PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal *bounds[])
709: {
710: PetscViewer_Draw *vdraw;
711: PetscBool isdraw;
713: PetscFunctionBegin;
715: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
716: if (!isdraw) {
717: if (nbounds) *nbounds = 0;
718: if (bounds) *bounds = NULL;
719: PetscFunctionReturn(PETSC_SUCCESS);
720: }
721: vdraw = (PetscViewer_Draw *)viewer->data;
723: if (nbounds) *nbounds = vdraw->nbounds;
724: if (bounds) *bounds = vdraw->bounds;
725: PetscFunctionReturn(PETSC_SUCCESS);
726: }
728: /*@
729: PetscViewerMonitorLGSetUp - sets up a viewer to be used by line graph monitoring routines such as `KSPMonitorResidualDrawLG()`
731: Collective
733: Input Parameters:
734: + viewer - the viewer in which to display the line graphs, it not a `PETSCVIEWERDRAW` it will set to that `PetscViewerType`
735: . host - the host to open the window on, `NULL` indicates the local host
736: . title - the title at the top of the window
737: . metric - the label above the graph
738: . l - the number of curves
739: . names - the names of each curve to be used in displaying the legend. May be `NULL`
740: . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
741: . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
742: . m - window width in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
743: - n - window height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
745: Level: developer
747: .seealso: `PetscViewer()`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetDrawLG()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
748: @*/
749: PetscErrorCode PetscViewerMonitorLGSetUp(PetscViewer viewer, const char host[], const char title[], const char metric[], PetscInt l, const char *names[], int x, int y, int m, int n) PeNS
750: {
751: PetscDrawAxis axis;
752: PetscDrawLG lg;
754: PetscFunctionBegin;
755: PetscCall(PetscViewerSetType(viewer, PETSCVIEWERDRAW));
756: PetscCall(PetscViewerDrawSetInfo(viewer, host, title, x, y, m, n));
757: PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
758: if (names) PetscCall(PetscDrawLGSetLegend(lg, names));
759: PetscCall(PetscDrawLGSetFromOptions(lg));
760: PetscCall(PetscDrawLGGetAxis(lg, &axis));
761: PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric));
762: PetscFunctionReturn(PETSC_SUCCESS);
763: }