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: PetscInt i;
28: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
30: PetscFunctionBegin;
31: for (i = 0; i < vdraw->draw_max; i++) {
32: if (vdraw->draw[i]) PetscCall(PetscDrawFlush(vdraw->draw[i]));
33: }
34: PetscFunctionReturn(PETSC_SUCCESS);
35: }
37: /*@
38: PetscViewerDrawBaseAdd - add to the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
40: Logically Collective
42: Input Parameters:
43: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
44: - windownumber - how much to add to the base
46: Level: developer
48: Note:
49: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
51: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()`
52: @*/
53: PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber)
54: {
55: PetscViewer_Draw *vdraw;
56: PetscBool isdraw;
58: PetscFunctionBegin;
61: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
62: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
63: vdraw = (PetscViewer_Draw *)viewer->data;
65: PetscCheck(windownumber + vdraw->draw_base >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber + vdraw->draw_base);
66: vdraw->draw_base += windownumber;
67: PetscFunctionReturn(PETSC_SUCCESS);
68: }
70: /*@
71: PetscViewerDrawBaseSet - sets the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
73: Logically Collective
75: Input Parameters:
76: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
77: - windownumber - value to set the base
79: Level: developer
81: Note:
82: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
84: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()`
85: @*/
86: PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber)
87: {
88: PetscViewer_Draw *vdraw;
89: PetscBool isdraw;
91: PetscFunctionBegin;
94: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
95: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
96: vdraw = (PetscViewer_Draw *)viewer->data;
98: PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber);
99: vdraw->draw_base = windownumber;
100: PetscFunctionReturn(PETSC_SUCCESS);
101: }
103: /*@
104: PetscViewerDrawResize - Set the default width and height (in pixels) for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
106: Logically Collective
108: Input Parameters:
109: + v - the `PETSCVIEWERDRAW` viewer
110: . w - the new default window width in pixels; values less than 1 are ignored
111: - h - the new default window height in pixels; values less than 1 are ignored
113: Level: intermediate
115: Note:
116: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
118: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
119: @*/
120: PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h)
121: {
122: PetscViewer_Draw *vdraw;
123: PetscBool isdraw;
125: PetscFunctionBegin;
127: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
128: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
129: vdraw = (PetscViewer_Draw *)v->data;
131: if (w >= 1) vdraw->w = w;
132: if (h >= 1) vdraw->h = h;
133: PetscFunctionReturn(PETSC_SUCCESS);
134: }
136: /*@C
137: PetscViewerDrawSetInfo - Record the default display, title, position, and size to use for `PetscDraw` windows
138: created by a `PETSCVIEWERDRAW` viewer.
140: Logically Collective
142: Input Parameters:
143: + v - the `PETSCVIEWERDRAW` viewer
144: . display - the X display name, or `NULL` for the local machine
145: . title - the window title, or `NULL`
146: . x - the horizontal screen coordinate of the upper left corner (unused; retained for API symmetry)
147: . y - the vertical screen coordinate of the upper left corner (unused; retained for API symmetry)
148: . w - the default window width in pixels; values less than 1 are ignored
149: - h - the default window height in pixels; values less than 1 are ignored
151: Level: intermediate
153: Note:
154: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
156: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetTitle()`, `PetscViewerDrawResize()`
157: @*/
158: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h)
159: {
160: PetscViewer_Draw *vdraw;
161: PetscBool isdraw;
163: PetscFunctionBegin;
165: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
166: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
167: vdraw = (PetscViewer_Draw *)v->data;
169: PetscCall(PetscStrallocpy(display, &vdraw->display));
170: PetscCall(PetscStrallocpy(title, &vdraw->title));
171: if (w >= 1) vdraw->w = w;
172: if (h >= 1) vdraw->h = h;
173: PetscFunctionReturn(PETSC_SUCCESS);
174: }
176: /*@C
177: PetscViewerDrawSetTitle - Set the default title used for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
179: Logically Collective
181: Input Parameters:
182: + v - the `PETSCVIEWERDRAW` viewer
183: - title - the window title, or `NULL` for no title
185: Level: intermediate
187: Note:
188: If `v` is not a `PETSCVIEWERDRAW` viewer, the call is a no-op.
190: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetTitle()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
191: @*/
192: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[])
193: {
194: PetscViewer_Draw *vdraw;
195: PetscBool isdraw;
197: PetscFunctionBegin;
199: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
200: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
201: vdraw = (PetscViewer_Draw *)v->data;
203: PetscCall(PetscFree(vdraw->title));
204: PetscCall(PetscStrallocpy(title, &vdraw->title));
205: PetscFunctionReturn(PETSC_SUCCESS);
206: }
208: /*@C
209: PetscViewerDrawGetTitle - Get the default title used for `PetscDraw` windows created by a `PETSCVIEWERDRAW` viewer.
211: Not Collective; No Fortran Support
213: Input Parameter:
214: . v - the `PETSCVIEWERDRAW` viewer
216: Output Parameter:
217: . title - the window title (owned by the viewer; do not free)
219: Level: intermediate
221: .seealso: `PetscViewer`, `PETSCVIEWERDRAW`, `PetscViewerDrawSetTitle()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
222: @*/
223: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[])
224: {
225: PetscViewer_Draw *vdraw;
226: PetscBool isdraw;
228: PetscFunctionBegin;
230: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
231: PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
232: vdraw = (PetscViewer_Draw *)v->data;
234: *title = vdraw->title;
235: PetscFunctionReturn(PETSC_SUCCESS);
236: }
238: /*@
239: PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type
240: `PETSCVIEWERDRAW`.
242: Collective
244: Input Parameters:
245: + comm - communicator that will share window
246: . display - the X display on which to open, or `NULL` for the local machine
247: . title - the title to put in the title bar, or `NULL` for no title
248: . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
249: . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
250: . 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`
251: - 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`
253: Output Parameter:
254: . viewer - the `PetscViewer`
256: Options Database Keys:
257: + -draw_type - use x or null
258: . -nox - Disables all x-windows output
259: . -display name - Specifies name of machine for the X display
260: . -geometry x,y,w,h - allows setting the window location and size
261: - -draw_pause pause - Sets time (in seconds) that the
262: program pauses after `PetscDrawPause()` has been called
263: (0 is default, -1 implies until user input).
265: Level: beginner
267: Notes:
268: If you want to do graphics in this window, you must call `PetscViewerDrawGetDraw()` and
269: perform the graphics on the `PetscDraw` object.
271: Format options include\:
272: + `PETSC_VIEWER_DRAW_BASIC` - displays with basic format
273: - `PETSC_VIEWER_DRAW_LG` - displays using a line graph
275: Fortran Note:
276: Whenever indicating null character data in a Fortran code,
277: `PETSC_NULL_CHARACTER` must be employed. Thus, `PETSC_NULL_CHARACTER` can be
278: used for the `display` and `title` input parameters.
280: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`,
281: `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`
282: @*/
283: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer)
284: {
285: PetscFunctionBegin;
286: PetscCall(PetscViewerCreate(comm, viewer));
287: PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW));
288: PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h));
289: PetscFunctionReturn(PETSC_SUCCESS);
290: }
292: #include <petsc/private/drawimpl.h>
294: static PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
295: {
296: PetscMPIInt rank;
297: PetscInt i;
298: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
300: PetscFunctionBegin;
301: PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous");
302: /* only processor zero can use the PetscViewer draw singleton */
303: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
304: if (rank == 0) {
305: PetscMPIInt flg;
306: PetscDraw draw, sdraw;
308: PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg));
309: PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
310: PetscCall(PetscViewerCreate(comm, sviewer));
311: PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW));
312: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
313: (*sviewer)->format = viewer->format;
314: for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
315: if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i]));
316: }
317: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
318: PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
319: if (draw->savefilename) {
320: PetscCall(PetscDrawSetSave(sdraw, draw->savefilename));
321: sdraw->savefilecount = draw->savefilecount;
322: sdraw->savesinglefile = draw->savesinglefile;
323: sdraw->savemoviefps = draw->savemoviefps;
324: sdraw->saveonclear = draw->saveonclear;
325: sdraw->saveonflush = draw->saveonflush;
326: }
327: if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename));
328: } else {
329: PetscDraw draw;
330: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
331: }
332: vdraw->singleton_made = PETSC_TRUE;
333: PetscFunctionReturn(PETSC_SUCCESS);
334: }
336: static PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
337: {
338: PetscMPIInt rank;
339: PetscInt i;
340: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
342: PetscFunctionBegin;
343: PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten");
344: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
345: if (rank == 0) {
346: PetscDraw draw, sdraw;
348: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
349: PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
350: if (draw->savefilename) {
351: draw->savefilecount = sdraw->savefilecount;
352: PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
353: }
354: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
355: for (i = 0; i < vdraw->draw_max; i++) {
356: if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i]));
357: }
358: PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis));
359: PetscCall(PetscFree((*sviewer)->data));
360: PetscCall(PetscHeaderDestroy(sviewer));
361: } else {
362: PetscDraw draw;
364: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
365: if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
366: }
368: vdraw->singleton_made = PETSC_FALSE;
369: PetscFunctionReturn(PETSC_SUCCESS);
370: }
372: static PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems PetscOptionsObject)
373: {
374: PetscReal bounds[16];
375: PetscInt nbounds = 16;
376: PetscBool flg;
378: PetscFunctionBegin;
379: PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options");
380: PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg));
381: if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds));
382: PetscOptionsHeadEnd();
383: PetscFunctionReturn(PETSC_SUCCESS);
384: }
386: static PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v)
387: {
388: PetscDraw draw;
389: PetscInt i;
390: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data;
391: PetscBool isascii;
393: PetscFunctionBegin;
394: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
395: if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Draw viewer is of type %s\n", vdraw->drawtype));
396: /* If the PetscViewer has just been created then no vdraw->draw yet
397: exists so this will not actually call the viewer on any draws. */
398: for (i = 0; i < vdraw->draw_base; i++) {
399: if (vdraw->draw[i]) {
400: PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw));
401: PetscCall(PetscDrawView(draw, v));
402: }
403: }
404: PetscFunctionReturn(PETSC_SUCCESS);
405: }
407: /*MC
408: PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
410: Level: beginner
412: .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`,
413: `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`,
414: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
415: `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
416: M*/
417: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
418: {
419: PetscViewer_Draw *vdraw;
421: PetscFunctionBegin;
422: PetscCall(PetscNew(&vdraw));
423: viewer->data = (void *)vdraw;
425: viewer->ops->flush = PetscViewerFlush_Draw;
426: viewer->ops->view = PetscViewerView_Draw;
427: viewer->ops->destroy = PetscViewerDestroy_Draw;
428: viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw;
429: viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw;
430: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
432: /* these are created on the fly if requested */
433: vdraw->draw_max = 5;
434: vdraw->draw_base = 0;
435: vdraw->w = PETSC_DECIDE;
436: vdraw->h = PETSC_DECIDE;
438: PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis));
439: vdraw->singleton_made = PETSC_FALSE;
440: PetscFunctionReturn(PETSC_SUCCESS);
441: }
443: /*@
444: PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`.
446: Not Collective
448: Input Parameter:
449: . viewer - the `PetscViewer`
451: Level: intermediate
453: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
454: @*/
455: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
456: {
457: PetscViewer_Draw *vdraw;
458: PetscBool isdraw;
459: PetscInt i;
461: PetscFunctionBegin;
463: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
464: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
465: vdraw = (PetscViewer_Draw *)viewer->data;
467: for (i = 0; i < vdraw->draw_max; i++) {
468: if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i]));
469: }
470: PetscFunctionReturn(PETSC_SUCCESS);
471: }
473: /*@
474: PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed) in the `PETSCVIEWERDRAW` `PetscViewer`
476: Not Collective
478: Input Parameter:
479: . viewer - the `PetscViewer`
481: Output Parameter:
482: . pause - the pause value
484: Level: intermediate
486: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
487: @*/
488: PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause)
489: {
490: PetscViewer_Draw *vdraw;
491: PetscBool isdraw;
492: PetscInt i;
493: PetscDraw draw;
495: PetscFunctionBegin;
497: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
498: if (!isdraw) {
499: *pause = 0.0;
500: PetscFunctionReturn(PETSC_SUCCESS);
501: }
502: vdraw = (PetscViewer_Draw *)viewer->data;
504: for (i = 0; i < vdraw->draw_max; i++) {
505: if (vdraw->draw[i]) {
506: PetscCall(PetscDrawGetPause(vdraw->draw[i], pause));
507: PetscFunctionReturn(PETSC_SUCCESS);
508: }
509: }
510: /* none exist yet so create one and get its pause */
511: PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
512: PetscCall(PetscDrawGetPause(draw, pause));
513: PetscFunctionReturn(PETSC_SUCCESS);
514: }
516: /*@
517: PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer`
519: Not Collective
521: Input Parameters:
522: + viewer - the `PetscViewer`
523: - pause - the pause value
525: Level: intermediate
527: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
528: @*/
529: PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause)
530: {
531: PetscViewer_Draw *vdraw;
532: PetscBool isdraw;
533: PetscInt i;
535: PetscFunctionBegin;
537: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
538: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
539: vdraw = (PetscViewer_Draw *)viewer->data;
541: vdraw->pause = pause;
542: for (i = 0; i < vdraw->draw_max; i++) {
543: if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause));
544: }
545: PetscFunctionReturn(PETSC_SUCCESS);
546: }
548: /*@
549: PetscViewerDrawSetHold - Holds previous image when drawing new image in a `PETSCVIEWERDRAW`
551: Not Collective
553: Input Parameters:
554: + viewer - the `PetscViewer`
555: - hold - `PETSC_TRUE` indicates to hold the previous image
557: Level: intermediate
559: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
560: @*/
561: PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold)
562: {
563: PetscViewer_Draw *vdraw;
564: PetscBool isdraw;
566: PetscFunctionBegin;
568: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
569: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
570: vdraw = (PetscViewer_Draw *)viewer->data;
572: vdraw->hold = hold;
573: PetscFunctionReturn(PETSC_SUCCESS);
574: }
576: /*@
577: PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image
579: Not Collective
581: Input Parameter:
582: . viewer - the `PetscViewer`
584: Output Parameter:
585: . hold - indicates to hold or not
587: Level: intermediate
589: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`
590: @*/
591: PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold)
592: {
593: PetscViewer_Draw *vdraw;
594: PetscBool isdraw;
596: PetscFunctionBegin;
598: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
599: if (!isdraw) {
600: *hold = PETSC_FALSE;
601: PetscFunctionReturn(PETSC_SUCCESS);
602: }
603: vdraw = (PetscViewer_Draw *)viewer->data;
605: *hold = vdraw->hold;
606: PetscFunctionReturn(PETSC_SUCCESS);
607: }
609: /*
610: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
611: is attached to a communicator, in this case the attribute is a PetscViewer.
612: */
613: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
615: /*@C
616: PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors
617: in an MPI communicator.
619: Collective
621: Input Parameter:
622: . comm - the MPI communicator to share the window `PetscViewer`
624: Level: intermediate
626: Notes:
627: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
629: Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return
630: an error code. The window is usually used in the form
631: .vb
632: XXXView(XXX object, PETSC_VIEWER_DRAW_(comm));
633: .ve
635: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`,
636: @*/
637: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
638: {
639: PetscMPIInt iflg;
640: PetscViewer viewer;
641: MPI_Comm ncomm;
643: PetscFunctionBegin;
644: PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL));
645: 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));
646: PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &iflg));
647: if (!iflg) { /* PetscViewer not yet created */
648: PetscCallNull(PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer));
649: PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
650: PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer));
651: }
652: PetscCallNull(PetscCommDestroy(&ncomm));
653: PetscFunctionReturn(viewer);
654: }
656: /*@
657: PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting in a `PETSCVIEWERDRAW` `PetscViewer`
659: Collective
661: Input Parameters:
662: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
663: . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
664: - 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, .....
666: Options Database Key:
667: . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds
669: Level: intermediate
671: Note:
672: 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
673: 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
674: this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
676: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
677: @*/
678: PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds)
679: {
680: PetscViewer_Draw *vdraw;
681: PetscBool isdraw;
683: PetscFunctionBegin;
685: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
686: if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
687: vdraw = (PetscViewer_Draw *)viewer->data;
689: vdraw->nbounds = nbounds;
690: PetscCall(PetscFree(vdraw->bounds));
691: PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds));
692: PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds));
693: PetscFunctionReturn(PETSC_SUCCESS);
694: }
696: /*@C
697: PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()`
699: Collective
701: Input Parameter:
702: . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
704: Output Parameters:
705: + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
706: - 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, .....
708: Level: intermediate
710: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()`
711: @*/
712: PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal *bounds[])
713: {
714: PetscViewer_Draw *vdraw;
715: PetscBool isdraw;
717: PetscFunctionBegin;
719: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
720: if (!isdraw) {
721: if (nbounds) *nbounds = 0;
722: if (bounds) *bounds = NULL;
723: PetscFunctionReturn(PETSC_SUCCESS);
724: }
725: vdraw = (PetscViewer_Draw *)viewer->data;
727: if (nbounds) *nbounds = vdraw->nbounds;
728: if (bounds) *bounds = vdraw->bounds;
729: PetscFunctionReturn(PETSC_SUCCESS);
730: }
732: /*@C
733: PetscViewerMonitorLGSetUp - sets up a viewer to be used by line graph monitoring routines such as `KSPMonitorResidualDrawLG()`
735: Collective
737: Input Parameters:
738: + viewer - the viewer in which to display the line graphs, it not a `PETSCVIEWERDRAW` it will set to that `PetscViewerType`
739: . host - the host to open the window on, `NULL` indicates the local host
740: . title - the title at the top of the window
741: . metric - the label above the graph
742: . l - the number of curves
743: . names - the names of each curve to be used in displaying the legend. May be `NULL`
744: . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
745: . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
746: . 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`
747: - 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`
749: Level: developer
751: .seealso: `PetscViewer()`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetDrawLG()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
752: @*/
753: 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
754: {
755: PetscDrawAxis axis;
756: PetscDrawLG lg;
758: PetscFunctionBegin;
759: PetscCall(PetscViewerSetType(viewer, PETSCVIEWERDRAW));
760: PetscCall(PetscViewerDrawSetInfo(viewer, host, title, x, y, m, n));
761: PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
762: if (names) PetscCall(PetscDrawLGSetLegend(lg, names));
763: PetscCall(PetscDrawLGSetFromOptions(lg));
764: PetscCall(PetscDrawLGGetAxis(lg, &axis));
765: PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric));
766: PetscFunctionReturn(PETSC_SUCCESS);
767: }