Actual source code: drawv.c

petsc-3.4.5 2014-06-29
  2: #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/
  3: #include <petscviewer.h>                                /*I "petscviewer.h" I*/

  7: PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
  8: {
  9:   PetscErrorCode   ierr;
 10:   PetscInt         i;
 11:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

 14:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton");
 15:   for (i=0; i<vdraw->draw_max; i++) {
 16:     PetscDrawAxisDestroy(&vdraw->drawaxis[i]);
 17:     PetscDrawLGDestroy(&vdraw->drawlg[i]);
 18:     PetscDrawDestroy(&vdraw->draw[i]);
 19:   }

 21:   PetscFree(vdraw->display);
 22:   PetscFree(vdraw->title);
 23:   PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
 24:   PetscFree(vdraw->bounds);
 25:   PetscFree(vdraw);
 26:   return(0);
 27: }

 31: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
 32: {
 33:   PetscErrorCode   ierr;
 34:   PetscInt         i;
 35:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

 38:   for (i=0; i<vdraw->draw_max; i++) {
 39:     if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
 40:   }
 41:   return(0);
 42: }

 46: /*@C
 47:     PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
 48:     This PetscDraw object may then be used to perform graphics using
 49:     PetscDrawXXX() commands.

 51:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

 53:     Input Parameters:
 54: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
 55: -   windownumber - indicates which subwindow (usually 0)

 57:     Ouput Parameter:
 58: .   draw - the draw object

 60:     Level: intermediate

 62:    Concepts: drawing^accessing PetscDraw context from PetscViewer
 63:    Concepts: graphics

 65: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
 66: @*/
 67: PetscErrorCode  PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
 68: {
 69:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
 70:   PetscErrorCode   ierr;
 71:   PetscBool        isdraw;
 72:   char             *title;

 77:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
 78:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
 79:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
 80:   windownumber += vdraw->draw_base;
 81:   if (windownumber >= vdraw->draw_max) {
 82:     /* allocate twice as many slots as needed */
 83:     PetscInt      draw_max  = vdraw->draw_max;
 84:     PetscDraw     *tdraw    = vdraw->draw;
 85:     PetscDrawLG   *drawlg   = vdraw->drawlg;
 86:     PetscDrawAxis *drawaxis = vdraw->drawaxis;

 88:     vdraw->draw_max = 2*windownumber;

 90:     PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
 91:     PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
 92:     PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
 93:     PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));

 95:     PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
 96:     PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
 97:     PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));

 99:     PetscFree3(tdraw,drawlg,drawaxis);
100:   }

102:   if (!vdraw->draw[windownumber]) {
103:     if (!windownumber) title = vdraw->title;
104:     else {
105:       char tmp_str[128];
106:       PetscSNPrintf(tmp_str, 128, "%s:%d", vdraw->title,windownumber);
107:       title = tmp_str;
108:     }
109:     PetscDrawCreate(PetscObjectComm((PetscObject)viewer),vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);
110:     PetscDrawSetPause(vdraw->draw[windownumber],vdraw->pause);
111:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
112:   }
113:   if (draw) *draw = vdraw->draw[windownumber];
115:   return(0);
116: }

120: /*@C
121:     PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()

123:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

125:     Input Parameters:
126: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
127: -   windownumber - how much to add to the base

129:     Level: developer

131:    Concepts: drawing^accessing PetscDraw context from PetscViewer
132:    Concepts: graphics

134: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
135: @*/
136: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
137: {
138:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
139:   PetscErrorCode   ierr;
140:   PetscBool        isdraw;

144:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
145:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
146:   if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
147:   vdraw->draw_base += windownumber;
148:   return(0);
149: }

153: /*@C
154:     PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()

156:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

158:     Input Parameters:
159: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
160: -   windownumber - value to set the base

162:     Level: developer

164:    Concepts: drawing^accessing PetscDraw context from PetscViewer
165:    Concepts: graphics

167: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
168: @*/
169: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
170: {
171:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
172:   PetscErrorCode   ierr;
173:   PetscBool        isdraw;

177:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
178:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
179:   if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
180:   vdraw->draw_base = windownumber;
181:   return(0);
182: }

186: /*@C
187:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
188:     This PetscDrawLG object may then be used to perform graphics using
189:     PetscDrawLGXXX() commands.

191:     Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)

193:     Input Parameter:
194: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
195: -   windownumber - indicates which subwindow (usually 0)

197:     Ouput Parameter:
198: .   draw - the draw line graph object

200:     Level: intermediate

202:   Concepts: line graph^accessing context

204: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
205: @*/
206: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
207: {
208:   PetscErrorCode   ierr;
209:   PetscBool        isdraw;
210:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

215:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
216:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
217:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");

219:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
220:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
221:   }
222:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
223:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
224:     PetscLogObjectParent(viewer,vdraw->drawlg[windownumber+vdraw->draw_base]);
225:   }
226:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
227:   return(0);
228: }

232: /*@C
233:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
234:     This PetscDrawAxis object may then be used to perform graphics using
235:     PetscDrawAxisXXX() commands.

237:     Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)

239:     Input Parameter:
240: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
241: -   windownumber - indicates which subwindow (usually 0)

243:     Ouput Parameter:
244: .   drawaxis - the draw axis object

246:     Level: advanced

248:   Concepts: line graph^accessing context

250: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
251: @*/
252: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
253: {
254:   PetscErrorCode   ierr;
255:   PetscBool        isdraw;
256:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;

261:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
262:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
263:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");

265:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
266:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
267:   }
268:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
269:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
270:     PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber+vdraw->draw_base]);
271:   }
272:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
273:   return(0);
274: }

278: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
279: {
280:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

283:   vdraw->h = h;
284:   vdraw->w = w;
285:   return(0);
286: }

290: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
291: {
292:   PetscErrorCode   ierr;
293:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

296:   vdraw->h = h;
297:   vdraw->w = w;
298:   PetscStrallocpy(display,&vdraw->display);
299:   PetscStrallocpy(title,&vdraw->title);
300:   return(0);
301: }

305: /*@C
306:    PetscViewerDrawOpen - Opens a window for use as a PetscViewer. If you want to
307:    do graphics in this window, you must call PetscViewerDrawGetDraw() and
308:    perform the graphics on the PetscDraw object.

310:    Collective on MPI_Comm

312:    Input Parameters:
313: +  comm - communicator that will share window
314: .  display - the X display on which to open, or null for the local machine
315: .  title - the title to put in the title bar, or null for no title
316: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
317: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
318:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

320:    Output Parameters:
321: . viewer - the PetscViewer

323:    Format Options:
324: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
325: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

327:    Options Database Keys:
328:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
329:    PetscDrawCreate() for runtime options, including
330: +  -draw_type x or null
331: .  -nox - Disables all x-windows output
332: .  -display <name> - Specifies name of machine for the X display
333: .  -geometry <x,y,w,h> - allows setting the window location and size
334: -  -draw_pause <pause> - Sets time (in seconds) that the
335:      program pauses after PetscDrawPause() has been called
336:      (0 is default, -1 implies until user input).

338:    Level: beginner

340:    Note for Fortran Programmers:
341:    Whenever indicating null character data in a Fortran code,
342:    NULL_CHARACTER must be employed; using NULL is not
343:    correct for character data!  Thus, NULL_CHARACTER can be
344:    used for the display and title input parameters.

346:   Concepts: graphics^opening PetscViewer
347:   Concepts: drawing^opening PetscViewer


350: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
351:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
352: @*/
353: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
354: {

358:   PetscViewerCreate(comm,viewer);
359:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
360:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
361:   return(0);
362: }

366: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
367: {
368:   PetscErrorCode   ierr;
369:   PetscMPIInt      rank;
370:   PetscInt         i;
371:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw;

374:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");

376:   /* only processor zero can use the PetscViewer draw singleton */
377:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
378:   if (!rank) {
379:     PetscViewerCreate(PETSC_COMM_SELF,sviewer);
380:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
381:     vsdraw = (PetscViewer_Draw*)(*sviewer)->data;
382:     for (i=0; i<vdraw->draw_max; i++) {
383:       if (vdraw->draw[i]) {
384:         PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
385:       }
386:     }
387:   }
388:   vdraw->singleton_made = PETSC_TRUE;
389:   return(0);
390: }

394: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
395: {
396:   PetscErrorCode   ierr;
397:   PetscMPIInt      rank;
398:   PetscInt         i;
399:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw;

402:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
403:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
404:   if (!rank) {
405:     vsdraw = (PetscViewer_Draw*)(*sviewer)->data;
406:     for (i=0; i<vdraw->draw_max; i++) {
407:       if (vdraw->draw[i] && vsdraw->draw[i]) {
408:         PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
409:       }
410:     }
411:     PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);
412:     PetscFree((*sviewer)->data);
413:     PetscHeaderDestroy(sviewer);
414:   }
415:   vdraw->singleton_made = PETSC_FALSE;
416:   return(0);
417: }

421: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v)
422: {
424:   PetscReal      bounds[16];
425:   PetscInt       nbounds = 16;
426:   PetscBool      flg;

429:   PetscOptionsHead("Draw PetscViewer Options");
430:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
431:   if (flg) {
432:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
433:   }

435:   PetscOptionsTail();
436:   return(0);
437: }

441: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
442: {
443:   PetscInt         i;
444:   PetscErrorCode   ierr;
445:   PetscViewer_Draw *vdraw;

448:   PetscNewLog(viewer,PetscViewer_Draw,&vdraw);
449:   viewer->data = (void*)vdraw;

451:   viewer->ops->flush            = PetscViewerFlush_Draw;
452:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
453:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
454:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
455:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;

457:   /* these are created on the fly if requested */
458:   vdraw->draw_max  = 5;
459:   vdraw->draw_base = 0;
460:   vdraw->w         = PETSC_DECIDE;
461:   vdraw->h         = PETSC_DECIDE;

463:   PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
464:   PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
465:   PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
466:   PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
467:   for (i=0; i<vdraw->draw_max; i++) {
468:     vdraw->draw[i]     = 0;
469:     vdraw->drawlg[i]   = 0;
470:     vdraw->drawaxis[i] = 0;
471:   }
472:   vdraw->singleton_made = PETSC_FALSE;
473:   return(0);
474: }

478: /*@
479:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

481:     Not Collective

483:     Input Parameter:
484: .  viewer - the PetscViewer

486:     Level: intermediate

488: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),

490: @*/
491: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
492: {
493:   PetscErrorCode   ierr;
494:   PetscInt         i;
495:   PetscBool        isdraw;
496:   PetscViewer_Draw *vdraw;

499:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
500:   if (isdraw) {
501:     vdraw = (PetscViewer_Draw*)viewer->data;
502:     for (i=0; i<vdraw->draw_max; i++) {
503:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
504:     }
505:   }
506:   return(0);
507: }

511: /*@
512:     PetscViewerDrawGetPause - Gets a pause for the first present draw

514:     Not Collective

516:     Input Parameter:
517: .  viewer - the PetscViewer

519:     Output Parameter:
520: .  pause - the pause value

522:     Level: intermediate

524: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),

526: @*/
527: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
528: {
529:   PetscErrorCode   ierr;
530:   PetscInt         i;
531:   PetscBool        isdraw;
532:   PetscViewer_Draw *vdraw;
533:   PetscDraw        draw;

536:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
537:   *pause = 0.0;
538:   if (isdraw) {
539:     vdraw = (PetscViewer_Draw*)viewer->data;
540:     for (i=0; i<vdraw->draw_max; i++) {
541:       if (vdraw->draw[i]) {
542:         PetscDrawGetPause(vdraw->draw[i],pause);
543:         return(0);
544:       }
545:     }
546:     /* none exist yet so create one and get its pause */
547:     PetscViewerDrawGetDraw(viewer,0,&draw);
548:     PetscDrawGetPause(vdraw->draw[0],pause);
549:   }
550:   return(0);
551: }

555: /*@
556:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

558:     Not Collective

560:     Input Parameters:
561: +  viewer - the PetscViewer
562: -  pause - the pause value

564:     Level: intermediate

566: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),

568: @*/
569: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
570: {
571:   PetscErrorCode   ierr;
572:   PetscInt         i;
573:   PetscBool        isdraw;

576:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
577:   if (isdraw) {
578:     PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

580:     vdraw->pause = pause;
581:     for (i=0; i<vdraw->draw_max; i++) {
582:       if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
583:     }
584:   }
585:   return(0);
586: }


591: /*@
592:     PetscViewerDrawSetHold - Holds previous image when drawing new image

594:     Not Collective

596:     Input Parameters:
597: +  viewer - the PetscViewer
598: -  hold - indicates to hold or not

600:     Level: intermediate

602: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),

604: @*/
605: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
606: {
607:   PetscErrorCode   ierr;
608:   PetscViewer_Draw *vdraw;
609:   PetscBool        isdraw;

612:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
613:   if (isdraw) {
614:     vdraw       = (PetscViewer_Draw*)viewer->data;
615:     vdraw->hold = hold;
616:   }
617:   return(0);
618: }

622: /*@
623:     PetscViewerDrawGetHold - Holds previous image when drawing new image

625:     Not Collective

627:     Input Parameter:
628: .  viewer - the PetscViewer

630:     Output Parameter:
631: .  hold - indicates to hold or not

633:     Level: intermediate

635: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(),

637: @*/
638: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
639: {
640:   PetscErrorCode   ierr;
641:   PetscViewer_Draw *vdraw;
642:   PetscBool        isdraw;

645:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
646:   if (isdraw) {
647:     vdraw = (PetscViewer_Draw*)viewer->data;
648:     *hold = vdraw->hold;
649:   }
650:   return(0);
651: }

653: /* ---------------------------------------------------------------------*/
654: /*
655:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
656:   is attached to a communicator, in this case the attribute is a PetscViewer.
657: */
658: static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

662: /*@C
663:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
664:                      in a communicator.

666:      Collective on MPI_Comm

668:      Input Parameter:
669: .    comm - the MPI communicator to share the window PetscViewer

671:      Level: intermediate

673:      Notes:
674:      Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return
675:      an error code.  The window is usually used in the form
676: $       XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));

678: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
679: @*/
680: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
681: {
683:   PetscMPIInt    flag;
684:   PetscViewer    viewer;
685:   MPI_Comm       ncomm;

688:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
689:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
690:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
691:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
692:   }
693:   MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
694:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
695:   if (!flag) { /* PetscViewer not yet created */
696:     PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
697:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
698:     PetscObjectRegisterDestroy((PetscObject)viewer);
699:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
700:     MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
701:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
702:   }
703:   PetscCommDestroy(&ncomm);
704:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
705:   PetscFunctionReturn(viewer);
706: }

710: /*@
711:     PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting

713:     Collective on PetscViewer

715:     Input Parameters:
716: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
717: .   nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
718: -   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, .....


721:     Options Database:
722: .   -draw_bounds  minF0,maxF0,minF1,maxF1

724:     Level: intermediate

726:     Notes: 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
727:       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
728:       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.

730:    Concepts: drawing^accessing PetscDraw context from PetscViewer
731:    Concepts: graphics

733: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
734: @*/
735: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
736: {
737:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
738:   PetscErrorCode   ierr;


743:   vdraw->nbounds = nbounds;

745:   PetscMalloc(2*nbounds*sizeof(PetscReal),&vdraw->bounds);
746:   PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));
747:   return(0);
748: }

752: /*@C
753:     PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds()

755:     Collective on PetscViewer

757:     Input Parameter:
758: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

760:     Output Paramters:
761: +   nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate()
762: -   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, .....

764:     Level: intermediate

766:    Concepts: drawing^accessing PetscDraw context from PetscViewer
767:    Concepts: graphics

769: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
770: @*/
771: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
772: {
773:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

777:   *nbounds = vdraw->nbounds;
778:   *bounds  = vdraw->bounds;
779:   return(0);
780: }