Actual source code: drawv.c

petsc-master 2020-12-02
Report Typos and Errors

  2: #include <../src/sys/classes/viewer/impls/draw/vdraw.h>
  3: #include <petscviewer.h>

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

 12:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton");
 13:   for (i=0; i<vdraw->draw_max; i++) {
 14:     PetscDrawAxisDestroy(&vdraw->drawaxis[i]);
 15:     PetscDrawLGDestroy(&vdraw->drawlg[i]);
 16:     PetscDrawDestroy(&vdraw->draw[i]);
 17:   }
 18:   PetscFree(vdraw->display);
 19:   PetscFree(vdraw->title);
 20:   PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
 21:   PetscFree(vdraw->bounds);
 22:   PetscFree(vdraw->drawtype);
 23:   PetscFree(v->data);
 24:   return(0);
 25: }

 27: static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
 28: {
 29:   PetscErrorCode   ierr;
 30:   PetscInt         i;
 31:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

 34:   for (i=0; i<vdraw->draw_max; i++) {
 35:     if (vdraw->draw[i]) {PetscDrawFlush(vdraw->draw[i]);}
 36:   }
 37:   return(0);
 38: }

 40: /*@C
 41:     PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
 42:     This PetscDraw object may then be used to perform graphics using
 43:     PetscDrawXXX() commands.

 45:     Collective on PetscViewer

 47:     Input Parameters:
 48: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
 49: -   windownumber - indicates which subwindow (usually 0)

 51:     Ouput Parameter:
 52: .   draw - the draw object

 54:     Level: intermediate


 57: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
 58: @*/
 59: PetscErrorCode  PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
 60: {
 61:   PetscViewer_Draw *vdraw;
 62:   PetscErrorCode   ierr;
 63:   PetscBool        isdraw;

 69:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
 70:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
 71:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
 72:   vdraw = (PetscViewer_Draw*)viewer->data;

 74:   windownumber += vdraw->draw_base;
 75:   if (windownumber >= vdraw->draw_max) {
 76:     /* allocate twice as many slots as needed */
 77:     PetscInt      draw_max  = vdraw->draw_max;
 78:     PetscDraw     *tdraw    = vdraw->draw;
 79:     PetscDrawLG   *drawlg   = vdraw->drawlg;
 80:     PetscDrawAxis *drawaxis = vdraw->drawaxis;

 82:     vdraw->draw_max = 2*windownumber;

 84:     PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
 85:     PetscArraycpy(vdraw->draw,tdraw,draw_max);
 86:     PetscArraycpy(vdraw->drawlg,drawlg,draw_max);
 87:     PetscArraycpy(vdraw->drawaxis,drawaxis,draw_max);
 88:     PetscFree3(tdraw,drawlg,drawaxis);
 89:   }

 91:   if (!vdraw->draw[windownumber]) {
 92:     char *title = vdraw->title, tmp_str[128];
 93:     if (windownumber) {
 94:       PetscSNPrintf(tmp_str,sizeof(tmp_str),"%s:%d",vdraw->title?vdraw->title:"",windownumber);
 95:       title = tmp_str;
 96:     }
 97:     PetscDrawCreate(PetscObjectComm((PetscObject)viewer),vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);
 98:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->draw[windownumber]);
 99:     if (vdraw->drawtype) {
100:       PetscDrawSetType(vdraw->draw[windownumber],vdraw->drawtype);
101:     }
102:     PetscDrawSetPause(vdraw->draw[windownumber],vdraw->pause);
103:     PetscDrawSetOptionsPrefix(vdraw->draw[windownumber],((PetscObject)viewer)->prefix);
104:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
105:   }
106:   if (draw) *draw = vdraw->draw[windownumber];
108:   return(0);
109: }

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

114:     Logically Collective on PetscViewer

116:     Input Parameters:
117: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
118: -   windownumber - how much to add to the base

120:     Level: developer


123: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
124: @*/
125: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
126: {
127:   PetscViewer_Draw *vdraw;
128:   PetscErrorCode   ierr;
129:   PetscBool        isdraw;

134:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
135:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
136:   vdraw = (PetscViewer_Draw*)viewer->data;

138:   if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
139:   vdraw->draw_base += windownumber;
140:   return(0);
141: }

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

146:     Logically Collective on PetscViewer

148:     Input Parameters:
149: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
150: -   windownumber - value to set the base

152:     Level: developer


155: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
156: @*/
157: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
158: {
159:   PetscViewer_Draw *vdraw;
160:   PetscErrorCode   ierr;
161:   PetscBool        isdraw;

166:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
167:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
168:   vdraw = (PetscViewer_Draw*)viewer->data;

170:   if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
171:   vdraw->draw_base = windownumber;
172:   return(0);
173: }

175: /*@C
176:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
177:     This PetscDrawLG object may then be used to perform graphics using
178:     PetscDrawLGXXX() commands.

180:     Collective on PetscViewer

182:     Input Parameter:
183: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
184: -   windownumber - indicates which subwindow (usually 0)

186:     Ouput Parameter:
187: .   draw - the draw line graph object

189:     Level: intermediate

191: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
192: @*/
193: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
194: {
195:   PetscErrorCode   ierr;
196:   PetscBool        isdraw;
197:   PetscViewer_Draw *vdraw;

203:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
204:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
205:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
206:   vdraw = (PetscViewer_Draw*)viewer->data;

208:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
209:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
210:   }
211:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
212:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
213:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawlg[windownumber+vdraw->draw_base]);
214:     PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber+vdraw->draw_base]);
215:   }
216:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
217:   return(0);
218: }

220: /*@C
221:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
222:     This PetscDrawAxis object may then be used to perform graphics using
223:     PetscDrawAxisXXX() commands.

225:     Collective on PetscViewer

227:     Input Parameter:
228: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
229: -   windownumber - indicates which subwindow (usually 0)

231:     Ouput Parameter:
232: .   drawaxis - the draw axis object

234:     Level: advanced

236: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
237: @*/
238: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
239: {
240:   PetscErrorCode   ierr;
241:   PetscBool        isdraw;
242:   PetscViewer_Draw *vdraw;

248:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
249:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
250:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
251:   vdraw = (PetscViewer_Draw*)viewer->data;

253:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
254:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
255:   }
256:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
257:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
258:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);
259:   }
260:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
261:   return(0);
262: }

264: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
265: {
266:   PetscErrorCode   ierr;
267:   PetscViewer_Draw *vdraw;
268:   PetscBool        isdraw;

272:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
273:   if (!isdraw) return(0);
274:   vdraw = (PetscViewer_Draw*)v->data;

276:   if (w >= 1) vdraw->w = w;
277:   if (h >= 1) vdraw->h = h;
278:   return(0);
279: }

281: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
282: {
283:   PetscErrorCode   ierr;
284:   PetscViewer_Draw *vdraw;
285:   PetscBool        isdraw;

289:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
290:   if (!isdraw) return(0);
291:   vdraw = (PetscViewer_Draw*)v->data;

293:   PetscStrallocpy(display,&vdraw->display);
294:   PetscStrallocpy(title,&vdraw->title);
295:   if (w >= 1) vdraw->w = w;
296:   if (h >= 1) vdraw->h = h;
297:   return(0);
298: }

300: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
301: {
302:   PetscErrorCode   ierr;
303:   PetscViewer_Draw *vdraw;
304:   PetscBool        isdraw;

308:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
309:   if (!isdraw) return(0);
310:   vdraw = (PetscViewer_Draw*)v->data;

312:   PetscFree(vdraw->drawtype);
313:   PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
314:   return(0);
315: }

317: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype)
318: {
319:   PetscErrorCode   ierr;
320:   PetscViewer_Draw *vdraw;
321:   PetscBool        isdraw;

325:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
326:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
327:   vdraw = (PetscViewer_Draw*)v->data;

329:   *drawtype = vdraw->drawtype;
330:   return(0);
331: }

333: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[])
334: {
335:   PetscErrorCode   ierr;
336:   PetscViewer_Draw *vdraw;
337:   PetscBool        isdraw;

341:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
342:   if (!isdraw) return(0);
343:   vdraw = (PetscViewer_Draw*)v->data;

345:   PetscFree(vdraw->title);
346:   PetscStrallocpy(title,&vdraw->title);
347:   return(0);
348: }

350: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[])
351: {
352:   PetscErrorCode   ierr;
353:   PetscViewer_Draw *vdraw;
354:   PetscBool        isdraw;

358:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
359:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
360:   vdraw = (PetscViewer_Draw*)v->data;

362:   *title = vdraw->title;
363:   return(0);
364: }

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

371:    Collective

373:    Input Parameters:
374: +  comm - communicator that will share window
375: .  display - the X display on which to open, or null for the local machine
376: .  title - the title to put in the title bar, or null for no title
377: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
378: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
379:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

381:    Output Parameters:
382: . viewer - the PetscViewer

384:    Format Options:
385: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
386: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

388:    Options Database Keys:
389:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
390:    PetscDrawCreate() for runtime options, including
391: +  -draw_type x or null
392: .  -nox - Disables all x-windows output
393: .  -display <name> - Specifies name of machine for the X display
394: .  -geometry <x,y,w,h> - allows setting the window location and size
395: -  -draw_pause <pause> - Sets time (in seconds) that the
396:      program pauses after PetscDrawPause() has been called
397:      (0 is default, -1 implies until user input).

399:    Level: beginner

401:    Note for Fortran Programmers:
402:    Whenever indicating null character data in a Fortran code,
403:    PETSC_NULL_CHARACTER must be employed; using NULL is not
404:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
405:    used for the display and title input parameters.



409: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
410:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
411: @*/
412: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
413: {

417:   PetscViewerCreate(comm,viewer);
418:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
419:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
420:   return(0);
421: }

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

425: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
426: {
427:   PetscErrorCode   ierr;
428:   PetscMPIInt      rank;
429:   PetscInt         i;
430:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

433:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous");
434:   /* only processor zero can use the PetscViewer draw singleton */
435:   if (sviewer) *sviewer = NULL;
436:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
437:   if (!rank) {
438:     PetscMPIInt flg;
439:     PetscDraw   draw,sdraw;

441:     MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
442:     if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
443:     PetscViewerCreate(comm,sviewer);
444:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
445:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
446:     (*sviewer)->format = viewer->format;
447:     for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
448:       if (vdraw->draw[i]) {PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);}
449:     }
450:     PetscViewerDrawGetDraw(viewer,0,&draw);
451:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
452:     if (draw->savefilename) {
453:       PetscDrawSetSave(sdraw,draw->savefilename);
454:       sdraw->savefilecount = draw->savefilecount;
455:       sdraw->savesinglefile = draw->savesinglefile;
456:       sdraw->savemoviefps = draw->savemoviefps;
457:       sdraw->saveonclear = draw->saveonclear;
458:       sdraw->saveonflush = draw->saveonflush;
459:     }
460:     if (draw->savefinalfilename) {PetscDrawSetSaveFinalImage(sdraw,draw->savefinalfilename);}
461:   } else {
462:     PetscDraw draw;
463:     PetscViewerDrawGetDraw(viewer,0,&draw);
464:   }
465:   vdraw->singleton_made = PETSC_TRUE;
466:   return(0);
467: }

469: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
470: {
471:   PetscErrorCode   ierr;
472:   PetscMPIInt      rank;
473:   PetscInt         i;
474:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

477:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
478:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
479:   if (!rank) {
480:     PetscDraw draw,sdraw;

482:     PetscViewerDrawGetDraw(viewer,0,&draw);
483:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
484:     if (draw->savefilename) {
485:       draw->savefilecount = sdraw->savefilecount;
486:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
487:     }
488:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
489:     for (i=0; i<vdraw->draw_max; i++) {
490:       if (vdraw->draw[i] && svdraw->draw[i]) {
491:         PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
492:       }
493:     }
494:     PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
495:     PetscFree((*sviewer)->data);
496:     PetscHeaderDestroy(sviewer);
497:   } else {
498:     PetscDraw draw;

500:     PetscViewerDrawGetDraw(viewer,0,&draw);
501:     if (draw->savefilename) {
502:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
503:     }
504:   }

506:   vdraw->singleton_made = PETSC_FALSE;
507:   return(0);
508: }

510: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
511: {
513:   PetscReal      bounds[16];
514:   PetscInt       nbounds = 16;
515:   PetscBool      flg;

518:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
519:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
520:   if (flg) {
521:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
522:   }
523:   PetscOptionsTail();
524:   return(0);
525: }

527: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
528: {
529:   PetscErrorCode   ierr;
530:   PetscDraw        draw;
531:   PetscInt         i;
532:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

535:   /*  If the PetscViewer has just been created then no vdraw->draw yet
536:       exists so this will not actually call the viewer on any draws. */
537:   for (i=0; i<vdraw->draw_base; i++) {
538:     if (vdraw->draw[i]) {
539:       PetscViewerDrawGetDraw(viewer,i,&draw);
540:       PetscDrawView(draw,v);
541:     }
542:   }
543:   return(0);
544: }

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


550: .seealso:  PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
551:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY,
552:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
553:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

555:   Level: beginner

557: M*/
558: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
559: {
560:   PetscErrorCode   ierr;
561:   PetscViewer_Draw *vdraw;

564:   PetscNewLog(viewer,&vdraw);
565:   viewer->data = (void*)vdraw;

567:   viewer->ops->flush            = PetscViewerFlush_Draw;
568:   viewer->ops->view             = PetscViewerView_Draw;
569:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
570:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
571:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
572:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

574:   /* these are created on the fly if requested */
575:   vdraw->draw_max  = 5;
576:   vdraw->draw_base = 0;
577:   vdraw->w         = PETSC_DECIDE;
578:   vdraw->h         = PETSC_DECIDE;

580:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
581:   vdraw->singleton_made = PETSC_FALSE;
582:   return(0);
583: }

585: /*@
586:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

588:     Not Collective

590:     Input Parameter:
591: .  viewer - the PetscViewer

593:     Level: intermediate

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

597: @*/
598: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
599: {
600:   PetscErrorCode   ierr;
601:   PetscViewer_Draw *vdraw;
602:   PetscBool        isdraw;
603:   PetscInt         i;

607:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
608:   if (!isdraw) return(0);
609:   vdraw = (PetscViewer_Draw*)viewer->data;

611:   for (i=0; i<vdraw->draw_max; i++) {
612:     if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
613:   }
614:   return(0);
615: }

617: /*@
618:     PetscViewerDrawGetPause - Gets a pause for the first present draw

620:     Not Collective

622:     Input Parameter:
623: .  viewer - the PetscViewer

625:     Output Parameter:
626: .  pause - the pause value

628:     Level: intermediate

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

632: @*/
633: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
634: {
635:   PetscErrorCode   ierr;
636:   PetscViewer_Draw *vdraw;
637:   PetscBool        isdraw;
638:   PetscInt         i;
639:   PetscDraw        draw;

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

647:   for (i=0; i<vdraw->draw_max; i++) {
648:     if (vdraw->draw[i]) {
649:       PetscDrawGetPause(vdraw->draw[i],pause);
650:       return(0);
651:     }
652:   }
653:   /* none exist yet so create one and get its pause */
654:   PetscViewerDrawGetDraw(viewer,0,&draw);
655:   PetscDrawGetPause(draw,pause);
656:   return(0);
657: }

659: /*@
660:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

662:     Not Collective

664:     Input Parameters:
665: +  viewer - the PetscViewer
666: -  pause - the pause value

668:     Level: intermediate

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

672: @*/
673: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
674: {
675:   PetscErrorCode   ierr;
676:   PetscViewer_Draw *vdraw;
677:   PetscBool        isdraw;
678:   PetscInt         i;

682:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
683:   if (!isdraw) return(0);
684:   vdraw = (PetscViewer_Draw*)viewer->data;

686:   vdraw->pause = pause;
687:   for (i=0; i<vdraw->draw_max; i++) {
688:     if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
689:   }
690:   return(0);
691: }


694: /*@
695:     PetscViewerDrawSetHold - Holds previous image when drawing new image

697:     Not Collective

699:     Input Parameters:
700: +  viewer - the PetscViewer
701: -  hold - indicates to hold or not

703:     Level: intermediate

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

707: @*/
708: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
709: {
710:   PetscErrorCode   ierr;
711:   PetscViewer_Draw *vdraw;
712:   PetscBool        isdraw;

716:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
717:   if (!isdraw) return(0);
718:   vdraw = (PetscViewer_Draw*)viewer->data;

720:   vdraw->hold = hold;
721:   return(0);
722: }

724: /*@
725:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

727:     Not Collective

729:     Input Parameter:
730: .  viewer - the PetscViewer

732:     Output Parameter:
733: .  hold - indicates to hold or not

735:     Level: intermediate

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

739: @*/
740: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
741: {
742:   PetscErrorCode   ierr;
743:   PetscViewer_Draw *vdraw;
744:   PetscBool        isdraw;

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

752:   *hold = vdraw->hold;
753:   return(0);
754: }

756: /* ---------------------------------------------------------------------*/
757: /*
758:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
759:   is attached to a communicator, in this case the attribute is a PetscViewer.
760: */
761: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

763: /*@C
764:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
765:                      in a communicator.

767:      Collective

769:      Input Parameter:
770: .    comm - the MPI communicator to share the window PetscViewer

772:      Level: intermediate

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

779: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
780: @*/
781: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
782: {
784:   PetscMPIInt    flag;
785:   PetscViewer    viewer;
786:   MPI_Comm       ncomm;

789:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
790:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
791:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,NULL);
792:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
793:   }
794:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
795:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
796:   if (!flag) { /* PetscViewer not yet created */
797:     PetscViewerDrawOpen(ncomm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
798:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
799:     PetscObjectRegisterDestroy((PetscObject)viewer);
800:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
801:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
802:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
803:   }
804:   PetscCommDestroy(&ncomm);
805:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
806:   PetscFunctionReturn(viewer);
807: }

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

812:     Collective on PetscViewer

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


820:     Options Database:
821: .   -draw_bounds  minF0,maxF0,minF1,maxF1

823:     Level: intermediate

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


831: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
832: @*/
833: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
834: {
835:   PetscViewer_Draw *vdraw;
836:   PetscBool        isdraw;
837:   PetscErrorCode   ierr;


842:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
843:   if (!isdraw) return(0);
844:   vdraw = (PetscViewer_Draw*)viewer->data;

846:   vdraw->nbounds = nbounds;
847:   PetscFree(vdraw->bounds);
848:   PetscMalloc1(2*nbounds,&vdraw->bounds);
849:   PetscArraycpy(vdraw->bounds,bounds,2*nbounds);
850:   return(0);
851: }

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

856:     Collective on PetscViewer

858:     Input Parameter:
859: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

865:     Level: intermediate


868: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
869: @*/
870: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
871: {
872:   PetscViewer_Draw *vdraw;
873:   PetscBool        isdraw;
874:   PetscErrorCode   ierr;

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

882:   if (nbounds) *nbounds = vdraw->nbounds;
883:   if (bounds)  *bounds  = vdraw->bounds;
884:   return(0);
885: }