Actual source code: drawv.c
1: #include <../src/sys/classes/viewer/impls/draw/vdraw.h>
3: static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
4: {
5: PetscInt i;
6: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
8: PetscFunctionBegin;
9: PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Destroying PetscViewer without first restoring singleton");
10: for (i = 0; i < vdraw->draw_max; i++) {
11: PetscCall(PetscDrawAxisDestroy(&vdraw->drawaxis[i]));
12: PetscCall(PetscDrawLGDestroy(&vdraw->drawlg[i]));
13: PetscCall(PetscDrawDestroy(&vdraw->draw[i]));
14: }
15: PetscCall(PetscFree(vdraw->display));
16: PetscCall(PetscFree(vdraw->title));
17: PetscCall(PetscFree3(vdraw->draw, vdraw->drawlg, vdraw->drawaxis));
18: PetscCall(PetscFree(vdraw->bounds));
19: PetscCall(PetscFree(vdraw->drawtype));
20: PetscCall(PetscFree(v->data));
21: PetscFunctionReturn(PETSC_SUCCESS);
22: }
24: static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
25: {
26: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
28: PetscFunctionBegin;
29: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
30: if (vdraw->draw[i]) PetscCall(PetscDrawFlush(vdraw->draw[i]));
31: }
32: PetscFunctionReturn(PETSC_SUCCESS);
33: }
35: /*@
36: PetscViewerDrawBaseAdd - add to the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
38: Logically Collective
40: Input Parameters:
41: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
42: - windownumber - how much to add to the base
44: Level: developer
46: Note:
47: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
49: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()`
50: @*/
51: PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber)
52: {
53: PetscViewer_Draw *vdraw;
54: PetscBool isdraw;
56: PetscFunctionBegin;
59: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
60: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
61: vdraw = (PetscViewer_Draw *)viewer->data;
63: PetscCheck(windownumber + vdraw->draw_base >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber + vdraw->draw_base);
64: vdraw->draw_base += windownumber;
65: PetscFunctionReturn(PETSC_SUCCESS);
66: }
68: /*@
69: PetscViewerDrawBaseSet - sets the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
71: Logically Collective
73: Input Parameters:
74: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
75: - windownumber - value to set the base
77: Level: developer
79: Note:
80: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
82: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()`
83: @*/
84: PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber)
85: {
86: PetscViewer_Draw *vdraw;
87: PetscBool isdraw;
89: PetscFunctionBegin;
92: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
93: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
94: vdraw = (PetscViewer_Draw *)viewer->data;
96: PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber);
97: vdraw->draw_base = windownumber;
98: PetscFunctionReturn(PETSC_SUCCESS);
99: }
101: /*@
102: PetscViewerDrawResize - Set the default width and height (in pixels) for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
104: Logically Collective
106: Input Parameters:
107: + v - the `PETSCVIEWERDRAW` viewer
108: . w - the new default window width in pixels; values less than 1 are ignored
109: - h - the new default window height in pixels; values less than 1 are ignored
111: Level: intermediate
113: Note:
114: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
116: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
117: @*/
118: PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h)
119: {
120: PetscViewer_Draw *vdraw;
121: PetscBool isdraw;
123: PetscFunctionBegin;
125: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
126: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
127: vdraw = (PetscViewer_Draw *)v->data;
129: if (w >= 1) vdraw->w = w;
130: if (h >= 1) vdraw->h = h;
131: PetscFunctionReturn(PETSC_SUCCESS);
132: }
134: /*@
135: PetscViewerDrawSetInfo - Record the default display, title, position, and size to use for `PetscDraw` windows
136: created by a `PETSCVIEWERDRAW` viewer.
138: Logically Collective
140: Input Parameters:
141: + v - the `PETSCVIEWERDRAW` viewer
142: . display - the X display name, or `NULL` for the local machine
143: . title - the window title, or `NULL`
144: . x - the horizontal screen coordinate of the upper left corner (unused; retained for API symmetry)
145: . y - the vertical screen coordinate of the upper left corner (unused; retained for API symmetry)
146: . w - the default window width in pixels; values less than 1 are ignored
147: - h - the default window height in pixels; values less than 1 are ignored
149: Level: intermediate
151: Note:
152: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
154: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetTitle()`, `PetscViewerDrawResize()`
155: @*/
156: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h)
157: {
158: PetscViewer_Draw *vdraw;
159: PetscBool isdraw;
161: PetscFunctionBegin;
163: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
164: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
165: vdraw = (PetscViewer_Draw *)v->data;
167: PetscCall(PetscStrallocpy(display, &vdraw->display));
168: PetscCall(PetscStrallocpy(title, &vdraw->title));
169: if (w >= 1) vdraw->w = w;
170: if (h >= 1) vdraw->h = h;
171: PetscFunctionReturn(PETSC_SUCCESS);
172: }
174: /*@
175: PetscViewerDrawSetTitle - Set the default title used for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
177: Logically Collective
179: Input Parameters:
180: + v - the `PETSCVIEWERDRAW` viewer
181: - title - the window title, or `NULL` for no title
183: Level: intermediate
185: Note:
186: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
188: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetTitle()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
189: @*/
190: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[])
191: {
192: PetscViewer_Draw *vdraw;
193: PetscBool isdraw;
195: PetscFunctionBegin;
197: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
198: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
199: vdraw = (PetscViewer_Draw *)v->data;
201: PetscCall(PetscFree(vdraw->title));
202: PetscCall(PetscStrallocpy(title, &vdraw->title));
203: PetscFunctionReturn(PETSC_SUCCESS);
204: }
206: /*@
207: PetscViewerDrawGetTitle - Get the default title used for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
209: Not Collective; No Fortran Support
211: Input Parameter:
212: . v - the `PETSCVIEWERDRAW` viewer
214: Output Parameter:
215: . title - the window title (owned by the viewer; do not free)
217: Level: intermediate
219: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawSetTitle()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
220: @*/
221: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[])
222: {
223: PetscViewer_Draw *vdraw;
224: PetscBool isdraw;
226: PetscFunctionBegin;
228: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
229: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
230: vdraw = (PetscViewer_Draw *)v->data;
232: *title = vdraw->title;
233: PetscFunctionReturn(PETSC_SUCCESS);
234: }
236: /*@
237: PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type
238: `PETSCVIEWERDRAW`.
240: Collective
242: Input Parameters:
243: + comm - communicator that will share window
244: . display - the X display on which to open, or `NULL` for the local machine
245: . title - the title to put in the title bar, or `NULL` for no title
246: . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
247: . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
248: . 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`
249: - 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`
251: Output Parameter:
252: . viewer - the `PetscViewer`
254: Options Database Keys:
255: + -draw_type - use x or null
256: . -nox - Disables all x-windows output
257: . -display name - Specifies name of machine for the X display
258: . -geometry x,y,w,h - allows setting the window location and size
259: - -draw_pause pause - Sets time (in seconds) that the
260: program pauses after `PetscDrawPause()` has been called
261: (0 is default, -1 implies until user input).
263: Level: beginner
265: Notes:
266: If you want to do graphics in this window, you must call `PetscViewerDrawGetDraw()` and
267: perform the graphics on the `PetscDraw` object.
269: Format options include\:
270: + `PETSC_VIEWER_DRAW_BASIC` - displays with basic format
271: - `PETSC_VIEWER_DRAW_LG` - displays using a line graph
273: Fortran Note:
274: Whenever indicating null character data in a Fortran code,
275: `PETSC_NULL_CHARACTER` must be employed. Thus, `PETSC_NULL_CHARACTER` can be
276: used for the `display` and `title` input parameters.
278: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`,
279: `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`
280: @*/
281: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer)
282: {
283: PetscFunctionBegin;
284: PetscCall(PetscViewerCreate(comm, viewer));
285: PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW));
286: PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h));
287: PetscFunctionReturn(PETSC_SUCCESS);
288: }
290: #include <petsc/private/drawimpl.h>
292: static PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
293: {
294: PetscMPIInt rank;
295: PetscInt i;
296: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
298: PetscFunctionBegin;
299: PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous");
300: /* only processor zero can use the PetscViewer draw singleton */
301: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
302: if (rank == 0) {
303: PetscMPIInt flg;
304: PetscDraw draw, sdraw;
306: PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg));
307: PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
308: PetscCall(PetscViewerCreate(comm, sviewer));
309: PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW));
310: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
311: (*sviewer)->format = viewer->format;
312: for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
313: if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i]));
314: }
315: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
316: PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
317: if (draw->savefilename) {
318: PetscCall(PetscDrawSetSave(sdraw, draw->savefilename));
319: sdraw->savefilecount = draw->savefilecount;
320: sdraw->savesinglefile = draw->savesinglefile;
321: sdraw->savemoviefps = draw->savemoviefps;
322: sdraw->saveonclear = draw->saveonclear;
323: sdraw->saveonflush = draw->saveonflush;
324: }
325: if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename));
326: } else {
327: PetscDraw draw;
328: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
329: }
330: vdraw->singleton_made = PETSC_TRUE;
331: PetscFunctionReturn(PETSC_SUCCESS);
332: }
334: static PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
335: {
336: PetscMPIInt rank;
337: PetscInt i;
338: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
340: PetscFunctionBegin;
341: PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten");
342: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
343: if (rank == 0) {
344: PetscDraw draw, sdraw;
346: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
347: PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
348: if (draw->savefilename) {
349: draw->savefilecount = sdraw->savefilecount;
350: PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
351: }
352: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
353: for (i = 0; i < vdraw->draw_max; i++) {
354: if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i]));
355: }
356: PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis));
357: PetscCall(PetscFree((*sviewer)->data));
358: PetscCall(PetscHeaderDestroy(sviewer));
359: } else {
360: PetscDraw draw;
362: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
363: if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
364: }
366: vdraw->singleton_made = PETSC_FALSE;
367: PetscFunctionReturn(PETSC_SUCCESS);
368: }
370: static PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems PetscOptionsObject)
371: {
372: PetscReal bounds[16];
373: PetscInt nbounds = 16;
374: PetscBool flg;
376: PetscFunctionBegin;
377: PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options");
378: PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg));
379: if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds));
380: PetscOptionsHeadEnd();
381: PetscFunctionReturn(PETSC_SUCCESS);
382: }
384: static PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v)
385: {
386: PetscDraw draw;
387: PetscInt i;
388: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data;
389: PetscBool isascii;
391: PetscFunctionBegin;
392: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
393: if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Draw viewer is of type %s\n", vdraw->drawtype));
394: /* If the PetscViewer has just been created then no vdraw->draw yet
395: exists so this will not actually call the viewer on any draws. */
396: for (i = 0; i < vdraw->draw_base; i++) {
397: if (vdraw->draw[i]) {
398: PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw));
399: PetscCall(PetscDrawView(draw, v));
400: }
401: }
402: PetscFunctionReturn(PETSC_SUCCESS);
403: }
405: /*MC
406: PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
408: Level: beginner
410: .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`,
411: `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`,
412: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
413: `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
414: M*/
415: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
416: {
417: PetscViewer_Draw *vdraw;
419: PetscFunctionBegin;
420: PetscCall(PetscNew(&vdraw));
421: viewer->data = (void *)vdraw;
423: viewer->ops->flush = PetscViewerFlush_Draw;
424: viewer->ops->view = PetscViewerView_Draw;
425: viewer->ops->destroy = PetscViewerDestroy_Draw;
426: viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw;
427: viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw;
428: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
430: /* these are created on the fly if requested */
431: vdraw->draw_max = 5;
432: vdraw->draw_base = 0;
433: vdraw->w = PETSC_DECIDE;
434: vdraw->h = PETSC_DECIDE;
436: PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis));
437: vdraw->singleton_made = PETSC_FALSE;
438: PetscFunctionReturn(PETSC_SUCCESS);
439: }
441: /*@
442: PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`.
444: Not Collective
446: Input Parameter:
447: . viewer - the `PetscViewer`
449: Level: intermediate
451: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
452: @*/
453: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
454: {
455: PetscViewer_Draw *vdraw;
456: PetscBool isdraw;
458: PetscFunctionBegin;
460: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
461: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
462: vdraw = (PetscViewer_Draw *)viewer->data;
464: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
465: if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i]));
466: }
467: PetscFunctionReturn(PETSC_SUCCESS);
468: }
470: /*@
471: PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed) in the `PETSCVIEWERDRAW` `PetscViewer`
473: Not Collective
475: Input Parameter:
476: . viewer - the `PetscViewer`
478: Output Parameter:
479: . pause - the pause value
481: Level: intermediate
483: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
484: @*/
485: PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause)
486: {
487: PetscViewer_Draw *vdraw;
488: PetscBool isdraw;
489: PetscDraw draw;
491: PetscFunctionBegin;
493: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
494: if (!isdraw) {
495: *pause = 0.0;
496: PetscFunctionReturn(PETSC_SUCCESS);
497: }
498: vdraw = (PetscViewer_Draw *)viewer->data;
500: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
501: if (vdraw->draw[i]) {
502: PetscCall(PetscDrawGetPause(vdraw->draw[i], pause));
503: PetscFunctionReturn(PETSC_SUCCESS);
504: }
505: }
506: /* none exist yet so create one and get its pause */
507: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
508: PetscCall(PetscDrawGetPause(draw, pause));
509: PetscFunctionReturn(PETSC_SUCCESS);
510: }
512: /*@
513: PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer`
515: Not Collective
517: Input Parameters:
518: + viewer - the `PetscViewer`
519: - pause - the pause value
521: Level: intermediate
523: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
524: @*/
525: PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause)
526: {
527: PetscViewer_Draw *vdraw;
528: PetscBool isdraw;
530: PetscFunctionBegin;
532: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
533: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
534: vdraw = (PetscViewer_Draw *)viewer->data;
536: vdraw->pause = pause;
537: for (PetscInt i = 0; i < vdraw->draw_max; i++) {
538: if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause));
539: }
540: PetscFunctionReturn(PETSC_SUCCESS);
541: }
543: /*@
544: PetscViewerDrawSetHold - Holds previous image when drawing new image in a `PETSCVIEWERDRAW`
546: Not Collective
548: Input Parameters:
549: + viewer - the `PetscViewer`
550: - hold - `PETSC_TRUE` indicates to hold the previous image
552: Level: intermediate
554: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
555: @*/
556: PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold)
557: {
558: PetscViewer_Draw *vdraw;
559: PetscBool isdraw;
561: PetscFunctionBegin;
563: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
564: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
565: vdraw = (PetscViewer_Draw *)viewer->data;
567: vdraw->hold = hold;
568: PetscFunctionReturn(PETSC_SUCCESS);
569: }
571: /*@
572: PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image
574: Not Collective
576: Input Parameter:
577: . viewer - the `PetscViewer`
579: Output Parameter:
580: . hold - indicates to hold or not
582: Level: intermediate
584: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
585: @*/
586: PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold)
587: {
588: PetscViewer_Draw *vdraw;
589: PetscBool isdraw;
591: PetscFunctionBegin;
593: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
594: if (!isdraw) {
595: *hold = PETSC_FALSE;
596: PetscFunctionReturn(PETSC_SUCCESS);
597: }
598: vdraw = (PetscViewer_Draw *)viewer->data;
600: *hold = vdraw->hold;
601: PetscFunctionReturn(PETSC_SUCCESS);
602: }
604: /*
605: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
606: is attached to a communicator, in this case the attribute is a PetscViewer.
607: */
608: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
610: /*@
611: PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors
612: in an MPI communicator.
614: Collective
616: Input Parameter:
617: . comm - the MPI communicator to share the window `PetscViewer`
619: Level: intermediate
621: Notes:
622: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
624: Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return
625: an error code. The window is usually used in the form
626: .vb
627: XXXView(XXX object, PETSC_VIEWER_DRAW_(comm));
628: .ve
630: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`,
631: @*/
632: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
633: {
634: PetscMPIInt iflg;
635: PetscViewer viewer;
636: MPI_Comm ncomm;
638: PetscFunctionBegin;
639: PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL));
640: 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));
641: PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &iflg));
642: if (!iflg) { /* PetscViewer not yet created */
643: PetscCallNull(PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer));
644: PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
645: PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer));
646: }
647: PetscCallNull(PetscCommDestroy(&ncomm));
648: PetscFunctionReturn(viewer);
649: }
651: /*@
652: PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting in a `PETSCVIEWERDRAW` `PetscViewer`
654: Collective
656: Input Parameters:
657: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
658: . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
659: - 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, .....
661: Options Database Key:
662: . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds
664: Level: intermediate
666: Note:
667: 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
668: 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
669: this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
671: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
672: @*/
673: PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds)
674: {
675: PetscViewer_Draw *vdraw;
676: PetscBool isdraw;
678: PetscFunctionBegin;
680: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
681: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
682: vdraw = (PetscViewer_Draw *)viewer->data;
684: vdraw->nbounds = nbounds;
685: PetscCall(PetscFree(vdraw->bounds));
686: PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds));
687: PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds));
688: PetscFunctionReturn(PETSC_SUCCESS);
689: }
691: /*@
692: PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()`
694: Collective
696: Input Parameter:
697: . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
699: Output Parameters:
700: + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
701: - 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, .....
703: Level: intermediate
705: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()`
706: @*/
707: PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal *bounds[])
708: {
709: PetscViewer_Draw *vdraw;
710: PetscBool isdraw;
712: PetscFunctionBegin;
714: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
715: if (!isdraw) {
716: if (nbounds) *nbounds = 0;
717: if (bounds) *bounds = NULL;
718: PetscFunctionReturn(PETSC_SUCCESS);
719: }
720: vdraw = (PetscViewer_Draw *)viewer->data;
722: if (nbounds) *nbounds = vdraw->nbounds;
723: if (bounds) *bounds = vdraw->bounds;
724: PetscFunctionReturn(PETSC_SUCCESS);
725: }
727: /*@
728: PetscViewerMonitorLGSetUp - sets up a viewer to be used by line graph monitoring routines such as `KSPMonitorResidualDrawLG()`
730: Collective
732: Input Parameters:
733: + viewer - the viewer in which to display the line graphs, it not a `PETSCVIEWERDRAW` it will set to that `PetscViewerType`
734: . host - the host to open the window on, `NULL` indicates the local host
735: . title - the title at the top of the window
736: . metric - the label above the graph
737: . l - the number of curves
738: . names - the names of each curve to be used in displaying the legend. May be `NULL`
739: . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
740: . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
741: . 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`
742: - 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`
744: Level: developer
746: .seealso: `PetscViewer()`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetDrawLG()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
747: @*/
748: 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
749: {
750: PetscDrawAxis axis;
751: PetscDrawLG lg;
753: PetscFunctionBegin;
754: PetscCall(PetscViewerSetType(viewer, PETSCVIEWERDRAW));
755: PetscCall(PetscViewerDrawSetInfo(viewer, host, title, x, y, m, n));
756: PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
757: if (names) PetscCall(PetscDrawLGSetLegend(lg, names));
758: PetscCall(PetscDrawLGSetFromOptions(lg));
759: PetscCall(PetscDrawLGGetAxis(lg, &axis));
760: PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric));
761: PetscFunctionReturn(PETSC_SUCCESS);
762: }