Actual source code: drawv.c
2: #include <../src/sys/classes/viewer/impls/draw/vdraw.h>
3: #include <petscviewer.h>
5: static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
6: {
7: PetscInt i;
8: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
11: for (i = 0; i < vdraw->draw_max; i++) {
12: PetscDrawAxisDestroy(&vdraw->drawaxis[i]);
13: PetscDrawLGDestroy(&vdraw->drawlg[i]);
14: PetscDrawDestroy(&vdraw->draw[i]);
15: }
16: PetscFree(vdraw->display);
17: PetscFree(vdraw->title);
18: PetscFree3(vdraw->draw, vdraw->drawlg, vdraw->drawaxis);
19: PetscFree(vdraw->bounds);
20: PetscFree(vdraw->drawtype);
21: PetscFree(v->data);
22: return 0;
23: }
25: static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
26: {
27: PetscInt i;
28: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
30: for (i = 0; i < vdraw->draw_max; i++) {
31: if (vdraw->draw[i]) PetscDrawFlush(vdraw->draw[i]);
32: }
33: return 0;
34: }
36: /*@C
37: PetscViewerDrawGetDraw - Returns `PetscDraw` object from `PetscViewer` object.
38: This `PetscDraw` object may then be used to perform graphics using
39: `PetscDraw` commands.
41: Collective
43: Input Parameters:
44: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()` of type `PETSCVIEWERDRAW`)
45: - windownumber - indicates which subwindow (usually 0)
47: Output Parameter:
48: . draw - the draw object
50: Level: intermediate
52: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
53: @*/
54: PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer, PetscInt windownumber, PetscDraw *draw)
55: {
56: PetscViewer_Draw *vdraw;
57: PetscBool isdraw;
62: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
65: vdraw = (PetscViewer_Draw *)viewer->data;
67: windownumber += vdraw->draw_base;
68: if (windownumber >= vdraw->draw_max) {
69: /* allocate twice as many slots as needed */
70: PetscInt draw_max = vdraw->draw_max;
71: PetscDraw *tdraw = vdraw->draw;
72: PetscDrawLG *drawlg = vdraw->drawlg;
73: PetscDrawAxis *drawaxis = vdraw->drawaxis;
75: vdraw->draw_max = 2 * windownumber;
77: PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis);
78: PetscArraycpy(vdraw->draw, tdraw, draw_max);
79: PetscArraycpy(vdraw->drawlg, drawlg, draw_max);
80: PetscArraycpy(vdraw->drawaxis, drawaxis, draw_max);
81: PetscFree3(tdraw, drawlg, drawaxis);
82: }
84: if (!vdraw->draw[windownumber]) {
85: char *title = vdraw->title, tmp_str[128];
86: if (windownumber) {
87: PetscSNPrintf(tmp_str, sizeof(tmp_str), "%s:%" PetscInt_FMT, vdraw->title ? vdraw->title : "", windownumber);
88: title = tmp_str;
89: }
90: PetscDrawCreate(PetscObjectComm((PetscObject)viewer), vdraw->display, title, PETSC_DECIDE, PETSC_DECIDE, vdraw->w, vdraw->h, &vdraw->draw[windownumber]);
91: if (vdraw->drawtype) PetscDrawSetType(vdraw->draw[windownumber], vdraw->drawtype);
92: PetscDrawSetPause(vdraw->draw[windownumber], vdraw->pause);
93: PetscDrawSetOptionsPrefix(vdraw->draw[windownumber], ((PetscObject)viewer)->prefix);
94: PetscDrawSetFromOptions(vdraw->draw[windownumber]);
95: }
96: if (draw) *draw = vdraw->draw[windownumber];
98: return 0;
99: }
101: /*@C
102: PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to `PetscViewerDrawGetDraw()`
104: Logically Collective
106: Input Parameters:
107: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
108: - windownumber - how much to add to the base
110: Level: developer
112: Note:
113: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
115: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()`
116: @*/
117: PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber)
118: {
119: PetscViewer_Draw *vdraw;
120: PetscBool isdraw;
124: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
126: vdraw = (PetscViewer_Draw *)viewer->data;
129: vdraw->draw_base += windownumber;
130: return 0;
131: }
133: /*@C
134: PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to `PetscViewerDrawGetDraw()`
136: Logically Collective
138: Input Parameters:
139: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
140: - windownumber - value to set the base
142: Level: developer
144: Note:
145: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
147: .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()`
148: @*/
149: PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber)
150: {
151: PetscViewer_Draw *vdraw;
152: PetscBool isdraw;
156: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
158: vdraw = (PetscViewer_Draw *)viewer->data;
161: vdraw->draw_base = windownumber;
162: return 0;
163: }
165: /*@C
166: PetscViewerDrawGetDrawLG - Returns a `PetscDrawLG` object from `PetscViewer` object of type `PETSCVIEWERDRAW`.
167: This `PetscDrawLG` object may then be used to perform graphics using `PetscDrawLG` commands.
169: Collective
171: Input Parameters:
172: + PetscViewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
173: - windownumber - indicates which subwindow (usually 0)
175: Output Parameter:
176: . draw - the draw line graph object
178: Level: intermediate
180: Note:
181: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows
183: .seealso: [](sec_viewers), `PetscDrawLG`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
184: @*/
185: PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer, PetscInt windownumber, PetscDrawLG *drawlg)
186: {
187: PetscBool isdraw;
188: PetscViewer_Draw *vdraw;
193: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
196: vdraw = (PetscViewer_Draw *)viewer->data;
198: if (windownumber + vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber + vdraw->draw_base]) PetscViewerDrawGetDraw(viewer, windownumber, NULL);
199: if (!vdraw->drawlg[windownumber + vdraw->draw_base]) {
200: PetscDrawLGCreate(vdraw->draw[windownumber + vdraw->draw_base], 1, &vdraw->drawlg[windownumber + vdraw->draw_base]);
201: PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber + vdraw->draw_base]);
202: }
203: *drawlg = vdraw->drawlg[windownumber + vdraw->draw_base];
204: return 0;
205: }
207: /*@C
208: PetscViewerDrawGetDrawAxis - Returns a `PetscDrawAxis` object from a `PetscViewer` object of type `PETSCVIEWERDRAW`.
209: This `PetscDrawAxis` object may then be used to perform graphics using `PetscDrawAxis` commands.
211: Collective
213: Input Parameters:
214: + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
215: - windownumber - indicates which subwindow (usually 0)
217: Output Parameter:
218: . drawaxis - the draw axis object
220: Level: advanced
222: Note:
223: A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows
225: .seealso: [](sec_viewers), `PetscViewerDrawGetDraw()`, `PetscViewerDrawGetLG()`, `PetscViewerDrawOpen()`
226: @*/
227: PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer, PetscInt windownumber, PetscDrawAxis *drawaxis)
228: {
229: PetscBool isdraw;
230: PetscViewer_Draw *vdraw;
235: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
238: vdraw = (PetscViewer_Draw *)viewer->data;
240: if (windownumber + vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber + vdraw->draw_base]) PetscViewerDrawGetDraw(viewer, windownumber, NULL);
241: if (!vdraw->drawaxis[windownumber + vdraw->draw_base]) PetscDrawAxisCreate(vdraw->draw[windownumber + vdraw->draw_base], &vdraw->drawaxis[windownumber + vdraw->draw_base]);
242: *drawaxis = vdraw->drawaxis[windownumber + vdraw->draw_base];
243: return 0;
244: }
246: PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h)
247: {
248: PetscViewer_Draw *vdraw;
249: PetscBool isdraw;
252: PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw);
253: if (!isdraw) return 0;
254: vdraw = (PetscViewer_Draw *)v->data;
256: if (w >= 1) vdraw->w = w;
257: if (h >= 1) vdraw->h = h;
258: return 0;
259: }
261: PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h)
262: {
263: PetscViewer_Draw *vdraw;
264: PetscBool isdraw;
267: PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw);
268: if (!isdraw) return 0;
269: vdraw = (PetscViewer_Draw *)v->data;
271: PetscStrallocpy(display, &vdraw->display);
272: PetscStrallocpy(title, &vdraw->title);
273: if (w >= 1) vdraw->w = w;
274: if (h >= 1) vdraw->h = h;
275: return 0;
276: }
278: PetscErrorCode PetscViewerDrawSetDrawType(PetscViewer v, PetscDrawType drawtype)
279: {
280: PetscViewer_Draw *vdraw;
281: PetscBool isdraw;
284: PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw);
285: if (!isdraw) return 0;
286: vdraw = (PetscViewer_Draw *)v->data;
288: PetscFree(vdraw->drawtype);
289: PetscStrallocpy(drawtype, (char **)&vdraw->drawtype);
290: return 0;
291: }
293: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v, PetscDrawType *drawtype)
294: {
295: PetscViewer_Draw *vdraw;
296: PetscBool isdraw;
299: PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw);
301: vdraw = (PetscViewer_Draw *)v->data;
303: *drawtype = vdraw->drawtype;
304: return 0;
305: }
307: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[])
308: {
309: PetscViewer_Draw *vdraw;
310: PetscBool isdraw;
313: PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw);
314: if (!isdraw) return 0;
315: vdraw = (PetscViewer_Draw *)v->data;
317: PetscFree(vdraw->title);
318: PetscStrallocpy(title, &vdraw->title);
319: return 0;
320: }
322: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[])
323: {
324: PetscViewer_Draw *vdraw;
325: PetscBool isdraw;
328: PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw);
330: vdraw = (PetscViewer_Draw *)v->data;
332: *title = vdraw->title;
333: return 0;
334: }
336: /*@C
337: PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type `PETSCVIEWERDRAW`. If you want to
338: do graphics in this window, you must call `PetscViewerDrawGetDraw()` and
339: perform the graphics on the `PetscDraw` object.
341: Collective
343: Input Parameters:
344: + comm - communicator that will share window
345: . display - the X display on which to open, or null for the local machine
346: . title - the title to put in the title bar, or null for no title
347: . x, y - the screen coordinates of the upper left corner of window, or use `PETSC_DECIDE`
348: - w, h - window width and height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,
349: `PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
351: Output Parameter:
352: . viewer - the `PetscViewer`
354: Format Options:
355: + `PETSC_VIEWER_DRAW_BASIC` - displays with basic format
356: - `PETSC_VIEWER_DRAW_LG` - displays using a line graph
358: Options Database Keys:
359: + -draw_type - use x or null
360: . -nox - Disables all x-windows output
361: . -display <name> - Specifies name of machine for the X display
362: . -geometry <x,y,w,h> - allows setting the window location and size
363: - -draw_pause <pause> - Sets time (in seconds) that the
364: program pauses after PetscDrawPause() has been called
365: (0 is default, -1 implies until user input).
367: Level: beginner
369: Note for Fortran Programmers:
370: Whenever indicating null character data in a Fortran code,
371: `PETSC_NULL_CHARACTER` must be employed; using NULL is not
372: correct for character data! Thus, `PETSC_NULL_CHARACTER` can be
373: used for the display and title input parameters.
375: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`,
376: `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`
377: @*/
378: PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer)
379: {
380: PetscViewerCreate(comm, viewer);
381: PetscViewerSetType(*viewer, PETSCVIEWERDRAW);
382: PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h);
383: return 0;
384: }
386: #include <petsc/private/drawimpl.h>
388: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
389: {
390: PetscMPIInt rank;
391: PetscInt i;
392: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
395: /* only processor zero can use the PetscViewer draw singleton */
396: if (sviewer) *sviewer = NULL;
397: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
398: if (rank == 0) {
399: PetscMPIInt flg;
400: PetscDraw draw, sdraw;
402: MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg);
404: PetscViewerCreate(comm, sviewer);
405: PetscViewerSetType(*sviewer, PETSCVIEWERDRAW);
406: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
407: (*sviewer)->format = viewer->format;
408: for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
409: if (vdraw->draw[i]) PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i]);
410: }
411: PetscViewerDrawGetDraw(viewer, 0, &draw);
412: PetscViewerDrawGetDraw(*sviewer, 0, &sdraw);
413: if (draw->savefilename) {
414: PetscDrawSetSave(sdraw, draw->savefilename);
415: sdraw->savefilecount = draw->savefilecount;
416: sdraw->savesinglefile = draw->savesinglefile;
417: sdraw->savemoviefps = draw->savemoviefps;
418: sdraw->saveonclear = draw->saveonclear;
419: sdraw->saveonflush = draw->saveonflush;
420: }
421: if (draw->savefinalfilename) PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename);
422: } else {
423: PetscDraw draw;
424: PetscViewerDrawGetDraw(viewer, 0, &draw);
425: }
426: vdraw->singleton_made = PETSC_TRUE;
427: return 0;
428: }
430: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
431: {
432: PetscMPIInt rank;
433: PetscInt i;
434: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
437: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
438: if (rank == 0) {
439: PetscDraw draw, sdraw;
441: PetscViewerDrawGetDraw(viewer, 0, &draw);
442: PetscViewerDrawGetDraw(*sviewer, 0, &sdraw);
443: if (draw->savefilename) {
444: draw->savefilecount = sdraw->savefilecount;
445: MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw));
446: }
447: svdraw = (PetscViewer_Draw *)(*sviewer)->data;
448: for (i = 0; i < vdraw->draw_max; i++) {
449: if (vdraw->draw[i] && svdraw->draw[i]) PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i]);
450: }
451: PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis);
452: PetscFree((*sviewer)->data);
453: PetscHeaderDestroy(sviewer);
454: } else {
455: PetscDraw draw;
457: PetscViewerDrawGetDraw(viewer, 0, &draw);
458: if (draw->savefilename) MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw));
459: }
461: vdraw->singleton_made = PETSC_FALSE;
462: return 0;
463: }
465: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems *PetscOptionsObject)
466: {
467: PetscReal bounds[16];
468: PetscInt nbounds = 16;
469: PetscBool flg;
471: PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options");
472: PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg);
473: if (flg) PetscViewerDrawSetBounds(v, nbounds / 2, bounds);
474: PetscOptionsHeadEnd();
475: return 0;
476: }
478: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v)
479: {
480: PetscDraw draw;
481: PetscInt i;
482: PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data;
484: /* If the PetscViewer has just been created then no vdraw->draw yet
485: exists so this will not actually call the viewer on any draws. */
486: for (i = 0; i < vdraw->draw_base; i++) {
487: if (vdraw->draw[i]) {
488: PetscViewerDrawGetDraw(viewer, i, &draw);
489: PetscDrawView(draw, v);
490: }
491: }
492: return 0;
493: }
495: /*MC
496: PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
498: Level: beginner
500: .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`,
501: `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`,
502: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
503: `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
504: M*/
505: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
506: {
507: PetscViewer_Draw *vdraw;
509: PetscNew(&vdraw);
510: viewer->data = (void *)vdraw;
512: viewer->ops->flush = PetscViewerFlush_Draw;
513: viewer->ops->view = PetscViewerView_Draw;
514: viewer->ops->destroy = PetscViewerDestroy_Draw;
515: viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw;
516: viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw;
517: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
519: /* these are created on the fly if requested */
520: vdraw->draw_max = 5;
521: vdraw->draw_base = 0;
522: vdraw->w = PETSC_DECIDE;
523: vdraw->h = PETSC_DECIDE;
525: PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis);
526: vdraw->singleton_made = PETSC_FALSE;
527: return 0;
528: }
530: /*@
531: PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`.
533: Not Collective
535: Input Parameter:
536: . viewer - the `PetscViewer`
538: Level: intermediate
540: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
541: @*/
542: PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
543: {
544: PetscViewer_Draw *vdraw;
545: PetscBool isdraw;
546: PetscInt i;
549: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
550: if (!isdraw) return 0;
551: vdraw = (PetscViewer_Draw *)viewer->data;
553: for (i = 0; i < vdraw->draw_max; i++) {
554: if (vdraw->draw[i]) PetscDrawClear(vdraw->draw[i]);
555: }
556: return 0;
557: }
559: /*@
560: PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed) in the `PETSCVIEWERDRAW` `PetscViewer`
562: Not Collective
564: Input Parameter:
565: . viewer - the `PetscViewer`
567: Output Parameter:
568: . pause - the pause value
570: Level: intermediate
572: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
573: @*/
574: PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause)
575: {
576: PetscViewer_Draw *vdraw;
577: PetscBool isdraw;
578: PetscInt i;
579: PetscDraw draw;
582: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
583: if (!isdraw) {
584: *pause = 0.0;
585: return 0;
586: }
587: vdraw = (PetscViewer_Draw *)viewer->data;
589: for (i = 0; i < vdraw->draw_max; i++) {
590: if (vdraw->draw[i]) {
591: PetscDrawGetPause(vdraw->draw[i], pause);
592: return 0;
593: }
594: }
595: /* none exist yet so create one and get its pause */
596: PetscViewerDrawGetDraw(viewer, 0, &draw);
597: PetscDrawGetPause(draw, pause);
598: return 0;
599: }
601: /*@
602: PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer`
604: Not Collective
606: Input Parameters:
607: + viewer - the `PetscViewer`
608: - pause - the pause value
610: Level: intermediate
612: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
613: @*/
614: PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause)
615: {
616: PetscViewer_Draw *vdraw;
617: PetscBool isdraw;
618: PetscInt i;
621: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
622: if (!isdraw) return 0;
623: vdraw = (PetscViewer_Draw *)viewer->data;
625: vdraw->pause = pause;
626: for (i = 0; i < vdraw->draw_max; i++) {
627: if (vdraw->draw[i]) PetscDrawSetPause(vdraw->draw[i], pause);
628: }
629: return 0;
630: }
632: /*@
633: PetscViewerDrawSetHold - Holds previous image when drawing new image
635: Not Collective
637: Input Parameters:
638: + viewer - the `PetscViewer`
639: - hold - `PETSC_TRUE` indicates to hold the previous image
641: Level: intermediate
643: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
644: @*/
645: PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold)
646: {
647: PetscViewer_Draw *vdraw;
648: PetscBool isdraw;
651: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
652: if (!isdraw) return 0;
653: vdraw = (PetscViewer_Draw *)viewer->data;
655: vdraw->hold = hold;
656: return 0;
657: }
659: /*@
660: PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image
662: Not Collective
664: Input Parameter:
665: . viewer - the `PetscViewer`
667: Output Parameter:
668: . hold - indicates to hold or not
670: Level: intermediate
672: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
673: @*/
674: PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold)
675: {
676: PetscViewer_Draw *vdraw;
677: PetscBool isdraw;
680: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
681: if (!isdraw) {
682: *hold = PETSC_FALSE;
683: return 0;
684: }
685: vdraw = (PetscViewer_Draw *)viewer->data;
687: *hold = vdraw->hold;
688: return 0;
689: }
691: /* ---------------------------------------------------------------------*/
692: /*
693: The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
694: is attached to a communicator, in this case the attribute is a PetscViewer.
695: */
696: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
698: /*@C
699: PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors
700: in a communicator.
702: Collective
704: Input Parameter:
705: . comm - the MPI communicator to share the window `PetscViewer`
707: Level: intermediate
709: Note:
710: Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return
711: an error code. The window is usually used in the form
712: $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
714: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`,
715: @*/
716: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
717: {
719: PetscMPIInt flag;
720: PetscViewer viewer;
721: MPI_Comm ncomm;
723: PetscCommDuplicate(comm, &ncomm, NULL);
724: if (ierr) {
725: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
726: return NULL;
727: }
728: if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
729: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Draw_keyval, NULL);
730: if (ierr) {
731: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
732: return NULL;
733: }
734: }
735: MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &flag);
736: if (ierr) {
737: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
738: return NULL;
739: }
740: if (!flag) { /* PetscViewer not yet created */
741: PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer);
742: if (ierr) {
743: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
744: return NULL;
745: }
746: PetscObjectRegisterDestroy((PetscObject)viewer);
747: if (ierr) {
748: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
749: return NULL;
750: }
751: MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer);
752: if (ierr) {
753: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
754: return NULL;
755: }
756: }
757: PetscCommDestroy(&ncomm);
758: if (ierr) {
759: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
760: return NULL;
761: }
762: return viewer;
763: }
765: /*@
766: PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting
768: Collective
770: Input Parameters:
771: + viewer - the Petsc`Viewer` (created with `PetscViewerDrawOpen()`)
772: . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
773: - 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, .....
775: Options Database Key:
776: . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds
778: Level: intermediate
780: Note:
781: 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
782: 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
783: this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
785: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
786: @*/
787: PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds)
788: {
789: PetscViewer_Draw *vdraw;
790: PetscBool isdraw;
793: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
794: if (!isdraw) return 0;
795: vdraw = (PetscViewer_Draw *)viewer->data;
797: vdraw->nbounds = nbounds;
798: PetscFree(vdraw->bounds);
799: PetscMalloc1(2 * nbounds, &vdraw->bounds);
800: PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds);
801: return 0;
802: }
804: /*@C
805: PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()`
807: Collective
809: Input Parameter:
810: . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
812: Output Parameters:
813: + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
814: - 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, .....
816: Level: intermediate
818: .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()`
819: @*/
820: PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal **bounds)
821: {
822: PetscViewer_Draw *vdraw;
823: PetscBool isdraw;
826: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
827: if (!isdraw) {
828: if (nbounds) *nbounds = 0;
829: if (bounds) *bounds = NULL;
830: return 0;
831: }
832: vdraw = (PetscViewer_Draw *)viewer->data;
834: if (nbounds) *nbounds = vdraw->nbounds;
835: if (bounds) *bounds = vdraw->bounds;
836: return 0;
837: }