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