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:     PetscDrawXXX() commands.

 41:     Collective on PetscViewer

 43:     Input Parameters:
 44: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
 45: -   windownumber - indicates which subwindow (usually 0)

 47:     Output Parameter:
 48: .   draw - the draw object

 50:     Level: intermediate

 52: .seealso: 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:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->draw[windownumber]);
 92:     if (vdraw->drawtype) {
 93:       PetscDrawSetType(vdraw->draw[windownumber],vdraw->drawtype);
 94:     }
 95:     PetscDrawSetPause(vdraw->draw[windownumber],vdraw->pause);
 96:     PetscDrawSetOptionsPrefix(vdraw->draw[windownumber],((PetscObject)viewer)->prefix);
 97:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
 98:   }
 99:   if (draw) *draw = vdraw->draw[windownumber];
101:   return 0;
102: }

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

107:     Logically Collective on PetscViewer

109:     Input Parameters:
110: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
111: -   windownumber - how much to add to the base

113:     Level: developer

115: .seealso: 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 on PetscViewer

138:     Input Parameters:
139: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
140: -   windownumber - value to set the base

142:     Level: developer

144: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
145: @*/
146: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
147: {
148:   PetscViewer_Draw *vdraw;
149:   PetscBool        isdraw;

153:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
155:   vdraw = (PetscViewer_Draw*)viewer->data;

158:   vdraw->draw_base = windownumber;
159:   return 0;
160: }

162: /*@C
163:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
164:     This PetscDrawLG object may then be used to perform graphics using
165:     PetscDrawLGXXX() commands.

167:     Collective on PetscViewer

169:     Input Parameters:
170: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
171: -   windownumber - indicates which subwindow (usually 0)

173:     Output Parameter:
174: .   draw - the draw line graph object

176:     Level: intermediate

178: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
179: @*/
180: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
181: {
182:   PetscBool        isdraw;
183:   PetscViewer_Draw *vdraw;

188:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
191:   vdraw = (PetscViewer_Draw*)viewer->data;

193:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
194:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
195:   }
196:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
197:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
198:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawlg[windownumber+vdraw->draw_base]);
199:     PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber+vdraw->draw_base]);
200:   }
201:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
202:   return 0;
203: }

205: /*@C
206:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
207:     This PetscDrawAxis object may then be used to perform graphics using
208:     PetscDrawAxisXXX() commands.

210:     Collective on PetscViewer

212:     Input Parameters:
213: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
214: -   windownumber - indicates which subwindow (usually 0)

216:     Output Parameter:
217: .   drawaxis - the draw axis object

219:     Level: advanced

221: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
222: @*/
223: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
224: {
225:   PetscBool        isdraw;
226:   PetscViewer_Draw *vdraw;

231:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
234:   vdraw = (PetscViewer_Draw*)viewer->data;

236:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
237:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
238:   }
239:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
240:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
241:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);
242:   }
243:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
244:   return 0;
245: }

247: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
248: {
249:   PetscViewer_Draw *vdraw;
250:   PetscBool        isdraw;

253:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
254:   if (!isdraw) return 0;
255:   vdraw = (PetscViewer_Draw*)v->data;

257:   if (w >= 1) vdraw->w = w;
258:   if (h >= 1) vdraw->h = h;
259:   return 0;
260: }

262: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
263: {
264:   PetscViewer_Draw *vdraw;
265:   PetscBool        isdraw;

268:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
269:   if (!isdraw) return 0;
270:   vdraw = (PetscViewer_Draw*)v->data;

272:   PetscStrallocpy(display,&vdraw->display);
273:   PetscStrallocpy(title,&vdraw->title);
274:   if (w >= 1) vdraw->w = w;
275:   if (h >= 1) vdraw->h = h;
276:   return 0;
277: }

279: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
280: {
281:   PetscViewer_Draw *vdraw;
282:   PetscBool        isdraw;

285:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
286:   if (!isdraw) return 0;
287:   vdraw = (PetscViewer_Draw*)v->data;

289:   PetscFree(vdraw->drawtype);
290:   PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
291:   return 0;
292: }

294: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype)
295: {
296:   PetscViewer_Draw *vdraw;
297:   PetscBool        isdraw;

300:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
302:   vdraw = (PetscViewer_Draw*)v->data;

304:   *drawtype = vdraw->drawtype;
305:   return 0;
306: }

308: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[])
309: {
310:   PetscViewer_Draw *vdraw;
311:   PetscBool        isdraw;

314:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
315:   if (!isdraw) return 0;
316:   vdraw = (PetscViewer_Draw*)v->data;

318:   PetscFree(vdraw->title);
319:   PetscStrallocpy(title,&vdraw->title);
320:   return 0;
321: }

323: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[])
324: {
325:   PetscViewer_Draw *vdraw;
326:   PetscBool        isdraw;

329:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
331:   vdraw = (PetscViewer_Draw*)v->data;

333:   *title = vdraw->title;
334:   return 0;
335: }

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

342:    Collective

344:    Input Parameters:
345: +  comm - communicator that will share window
346: .  display - the X display on which to open, or null for the local machine
347: .  title - the title to put in the title bar, or null for no title
348: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
349: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
350:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

352:    Output Parameter:
353: . viewer - the PetscViewer

355:    Format Options:
356: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
357: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

359:    Options Database Keys:
360: +  -draw_type - use x or null
361: .  -nox - Disables all x-windows output
362: .  -display <name> - Specifies name of machine for the X display
363: .  -geometry <x,y,w,h> - allows setting the window location and size
364: -  -draw_pause <pause> - Sets time (in seconds) that the
365:      program pauses after PetscDrawPause() has been called
366:      (0 is default, -1 implies until user input).

368:    Level: beginner

370:    Notes:
371:      PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual pages for PetscDrawCreate()

373:    Note for Fortran Programmers:
374:    Whenever indicating null character data in a Fortran code,
375:    PETSC_NULL_CHARACTER must be employed; using NULL is not
376:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
377:    used for the display and title input parameters.

379: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
380:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
381: @*/
382: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
383: {
384:   PetscViewerCreate(comm,viewer);
385:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
386:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
387:   return 0;
388: }

390: #include <petsc/private/drawimpl.h>

392: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
393: {
394:   PetscMPIInt      rank;
395:   PetscInt         i;
396:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

399:   /* only processor zero can use the PetscViewer draw singleton */
400:   if (sviewer) *sviewer = NULL;
401:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
402:   if (rank == 0) {
403:     PetscMPIInt flg;
404:     PetscDraw   draw,sdraw;

406:     MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
408:     PetscViewerCreate(comm,sviewer);
409:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
410:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
411:     (*sviewer)->format = viewer->format;
412:     for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
413:       if (vdraw->draw[i]) PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);
414:     }
415:     PetscViewerDrawGetDraw(viewer,0,&draw);
416:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
417:     if (draw->savefilename) {
418:       PetscDrawSetSave(sdraw,draw->savefilename);
419:       sdraw->savefilecount = draw->savefilecount;
420:       sdraw->savesinglefile = draw->savesinglefile;
421:       sdraw->savemoviefps = draw->savemoviefps;
422:       sdraw->saveonclear = draw->saveonclear;
423:       sdraw->saveonflush = draw->saveonflush;
424:     }
425:     if (draw->savefinalfilename) PetscDrawSetSaveFinalImage(sdraw,draw->savefinalfilename);
426:   } else {
427:     PetscDraw draw;
428:     PetscViewerDrawGetDraw(viewer,0,&draw);
429:   }
430:   vdraw->singleton_made = PETSC_TRUE;
431:   return 0;
432: }

434: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
435: {
436:   PetscMPIInt      rank;
437:   PetscInt         i;
438:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

441:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
442:   if (rank == 0) {
443:     PetscDraw draw,sdraw;

445:     PetscViewerDrawGetDraw(viewer,0,&draw);
446:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
447:     if (draw->savefilename) {
448:       draw->savefilecount = sdraw->savefilecount;
449:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
450:     }
451:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
452:     for (i=0; i<vdraw->draw_max; i++) {
453:       if (vdraw->draw[i] && svdraw->draw[i]) {
454:         PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
455:       }
456:     }
457:     PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
458:     PetscFree((*sviewer)->data);
459:     PetscHeaderDestroy(sviewer);
460:   } else {
461:     PetscDraw draw;

463:     PetscViewerDrawGetDraw(viewer,0,&draw);
464:     if (draw->savefilename) {
465:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
466:     }
467:   }

469:   vdraw->singleton_made = PETSC_FALSE;
470:   return 0;
471: }

473: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
474: {
475:   PetscReal      bounds[16];
476:   PetscInt       nbounds = 16;
477:   PetscBool      flg;

479:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
480:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
481:   if (flg) {
482:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
483:   }
484:   PetscOptionsTail();
485:   return 0;
486: }

488: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
489: {
490:   PetscDraw        draw;
491:   PetscInt         i;
492:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

494:   /*  If the PetscViewer has just been created then no vdraw->draw yet
495:       exists so this will not actually call the viewer on any draws. */
496:   for (i=0; i<vdraw->draw_base; i++) {
497:     if (vdraw->draw[i]) {
498:       PetscViewerDrawGetDraw(viewer,i,&draw);
499:       PetscDrawView(draw,v);
500:     }
501:   }
502:   return 0;
503: }

505: /*MC
506:    PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file

508: .seealso:  PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
509:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY,
510:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
511:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

513:   Level: beginner

515: M*/
516: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
517: {
518:   PetscViewer_Draw *vdraw;

520:   PetscNewLog(viewer,&vdraw);
521:   viewer->data = (void*)vdraw;

523:   viewer->ops->flush            = PetscViewerFlush_Draw;
524:   viewer->ops->view             = PetscViewerView_Draw;
525:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
526:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
527:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
528:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

530:   /* these are created on the fly if requested */
531:   vdraw->draw_max  = 5;
532:   vdraw->draw_base = 0;
533:   vdraw->w         = PETSC_DECIDE;
534:   vdraw->h         = PETSC_DECIDE;

536:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
537:   vdraw->singleton_made = PETSC_FALSE;
538:   return 0;
539: }

541: /*@
542:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

544:     Not Collective

546:     Input Parameter:
547: .  viewer - the PetscViewer

549:     Level: intermediate

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

553: @*/
554: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
555: {
556:   PetscViewer_Draw *vdraw;
557:   PetscBool        isdraw;
558:   PetscInt         i;

561:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
562:   if (!isdraw) return 0;
563:   vdraw = (PetscViewer_Draw*)viewer->data;

565:   for (i=0; i<vdraw->draw_max; i++) {
566:     if (vdraw->draw[i]) PetscDrawClear(vdraw->draw[i]);
567:   }
568:   return 0;
569: }

571: /*@
572:     PetscViewerDrawGetPause - Gets a pause for the first present draw

574:     Not Collective

576:     Input Parameter:
577: .  viewer - the PetscViewer

579:     Output Parameter:
580: .  pause - the pause value

582:     Level: intermediate

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

586: @*/
587: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
588: {
589:   PetscViewer_Draw *vdraw;
590:   PetscBool        isdraw;
591:   PetscInt         i;
592:   PetscDraw        draw;

595:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
596:   if (!isdraw) {*pause = 0.0; return 0;}
597:   vdraw = (PetscViewer_Draw*)viewer->data;

599:   for (i=0; i<vdraw->draw_max; i++) {
600:     if (vdraw->draw[i]) {
601:       PetscDrawGetPause(vdraw->draw[i],pause);
602:       return 0;
603:     }
604:   }
605:   /* none exist yet so create one and get its pause */
606:   PetscViewerDrawGetDraw(viewer,0,&draw);
607:   PetscDrawGetPause(draw,pause);
608:   return 0;
609: }

611: /*@
612:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

614:     Not Collective

616:     Input Parameters:
617: +  viewer - the PetscViewer
618: -  pause - the pause value

620:     Level: intermediate

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

624: @*/
625: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
626: {
627:   PetscViewer_Draw *vdraw;
628:   PetscBool        isdraw;
629:   PetscInt         i;

632:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
633:   if (!isdraw) return 0;
634:   vdraw = (PetscViewer_Draw*)viewer->data;

636:   vdraw->pause = pause;
637:   for (i=0; i<vdraw->draw_max; i++) {
638:     if (vdraw->draw[i]) PetscDrawSetPause(vdraw->draw[i],pause);
639:   }
640:   return 0;
641: }

643: /*@
644:     PetscViewerDrawSetHold - Holds previous image when drawing new image

646:     Not Collective

648:     Input Parameters:
649: +  viewer - the PetscViewer
650: -  hold - indicates to hold or not

652:     Level: intermediate

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

656: @*/
657: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
658: {
659:   PetscViewer_Draw *vdraw;
660:   PetscBool        isdraw;

663:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
664:   if (!isdraw) return 0;
665:   vdraw = (PetscViewer_Draw*)viewer->data;

667:   vdraw->hold = hold;
668:   return 0;
669: }

671: /*@
672:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

674:     Not Collective

676:     Input Parameter:
677: .  viewer - the PetscViewer

679:     Output Parameter:
680: .  hold - indicates to hold or not

682:     Level: intermediate

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

686: @*/
687: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
688: {
689:   PetscViewer_Draw *vdraw;
690:   PetscBool        isdraw;

693:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
694:   if (!isdraw) {*hold = PETSC_FALSE; return 0;}
695:   vdraw = (PetscViewer_Draw*)viewer->data;

697:   *hold = vdraw->hold;
698:   return 0;
699: }

701: /* ---------------------------------------------------------------------*/
702: /*
703:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
704:   is attached to a communicator, in this case the attribute is a PetscViewer.
705: */
706: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

708: /*@C
709:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
710:                      in a communicator.

712:      Collective

714:      Input Parameter:
715: .    comm - the MPI communicator to share the window PetscViewer

717:      Level: intermediate

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

724: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
725: @*/
726: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
727: {
729:   PetscMPIInt    flag;
730:   PetscViewer    viewer;
731:   MPI_Comm       ncomm;

733:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
734:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
735:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,NULL);
736:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
737:   }
738:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
739:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
740:   if (!flag) { /* PetscViewer not yet created */
741:     PetscViewerDrawOpen(ncomm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
742:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
743:     PetscObjectRegisterDestroy((PetscObject)viewer);
744:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
745:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
746:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
747:   }
748:   PetscCommDestroy(&ncomm);
749:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
750:   return viewer;
751: }

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

756:     Collective on PetscViewer

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

763:     Options Database:
764: .   -draw_bounds  minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds

766:     Level: intermediate

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

773: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
774: @*/
775: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
776: {
777:   PetscViewer_Draw *vdraw;
778:   PetscBool        isdraw;

781:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
782:   if (!isdraw) return 0;
783:   vdraw = (PetscViewer_Draw*)viewer->data;

785:   vdraw->nbounds = nbounds;
786:   PetscFree(vdraw->bounds);
787:   PetscMalloc1(2*nbounds,&vdraw->bounds);
788:   PetscArraycpy(vdraw->bounds,bounds,2*nbounds);
789:   return 0;
790: }

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

795:     Collective on PetscViewer

797:     Input Parameter:
798: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

804:     Level: intermediate

806: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
807: @*/
808: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
809: {
810:   PetscViewer_Draw *vdraw;
811:   PetscBool        isdraw;

814:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
815:   if (!isdraw) {if (nbounds) *nbounds = 0; if (bounds) *bounds = NULL; return 0;}
816:   vdraw = (PetscViewer_Draw*)viewer->data;

818:   if (nbounds) *nbounds = vdraw->nbounds;
819:   if (bounds)  *bounds  = vdraw->bounds;
820:   return 0;
821: }