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: }