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:   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:     Output Parameter:
 52: .   draw - the draw object

 54:     Level: intermediate

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

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

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

 81:     vdraw->draw_max = 2*windownumber;

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

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

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

113:     Logically Collective on PetscViewer

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

119:     Level: developer

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

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

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

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

144:     Logically Collective on PetscViewer

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

150:     Level: developer

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

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

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

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

177:     Collective on PetscViewer

179:     Input Parameters:
180: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
181: -   windownumber - indicates which subwindow (usually 0)

183:     Output Parameter:
184: .   draw - the draw line graph object

186:     Level: intermediate

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

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

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

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

222:     Collective on PetscViewer

224:     Input Parameters:
225: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
226: -   windownumber - indicates which subwindow (usually 0)

228:     Output Parameter:
229: .   drawaxis - the draw axis object

231:     Level: advanced

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

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

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

261: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
262: {
263:   PetscErrorCode   ierr;
264:   PetscViewer_Draw *vdraw;
265:   PetscBool        isdraw;

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

273:   if (w >= 1) vdraw->w = w;
274:   if (h >= 1) vdraw->h = h;
275:   return(0);
276: }

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

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

290:   PetscStrallocpy(display,&vdraw->display);
291:   PetscStrallocpy(title,&vdraw->title);
292:   if (w >= 1) vdraw->w = w;
293:   if (h >= 1) vdraw->h = h;
294:   return(0);
295: }

297: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
298: {
299:   PetscErrorCode   ierr;
300:   PetscViewer_Draw *vdraw;
301:   PetscBool        isdraw;

305:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
306:   if (!isdraw) return(0);
307:   vdraw = (PetscViewer_Draw*)v->data;

309:   PetscFree(vdraw->drawtype);
310:   PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
311:   return(0);
312: }

314: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype)
315: {
316:   PetscErrorCode   ierr;
317:   PetscViewer_Draw *vdraw;
318:   PetscBool        isdraw;

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

326:   *drawtype = vdraw->drawtype;
327:   return(0);
328: }

330: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[])
331: {
332:   PetscErrorCode   ierr;
333:   PetscViewer_Draw *vdraw;
334:   PetscBool        isdraw;

338:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
339:   if (!isdraw) return(0);
340:   vdraw = (PetscViewer_Draw*)v->data;

342:   PetscFree(vdraw->title);
343:   PetscStrallocpy(title,&vdraw->title);
344:   return(0);
345: }

347: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[])
348: {
349:   PetscErrorCode   ierr;
350:   PetscViewer_Draw *vdraw;
351:   PetscBool        isdraw;

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

359:   *title = vdraw->title;
360:   return(0);
361: }

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

368:    Collective

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

378:    Output Parameter:
379: . viewer - the PetscViewer

381:    Format Options:
382: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
383: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

385:    Options Database Keys:
386: +  -draw_type - use x or null
387: .  -nox - Disables all x-windows output
388: .  -display <name> - Specifies name of machine for the X display
389: .  -geometry <x,y,w,h> - allows setting the window location and size
390: -  -draw_pause <pause> - Sets time (in seconds) that the
391:      program pauses after PetscDrawPause() has been called
392:      (0 is default, -1 implies until user input).

394:    Level: beginner

396:    Notes:
397:      PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual pages for PetscDrawCreate()

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

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

413:   PetscViewerCreate(comm,viewer);
414:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
415:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
416:   return(0);
417: }

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

421: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
422: {
423:   PetscErrorCode   ierr;
424:   PetscMPIInt      rank;
425:   PetscInt         i;
426:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

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

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

465: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
466: {
467:   PetscErrorCode   ierr;
468:   PetscMPIInt      rank;
469:   PetscInt         i;
470:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

473:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
474:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
475:   if (rank == 0) {
476:     PetscDraw draw,sdraw;

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

496:     PetscViewerDrawGetDraw(viewer,0,&draw);
497:     if (draw->savefilename) {
498:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
499:     }
500:   }

502:   vdraw->singleton_made = PETSC_FALSE;
503:   return(0);
504: }

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

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

523: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
524: {
525:   PetscErrorCode   ierr;
526:   PetscDraw        draw;
527:   PetscInt         i;
528:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

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

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

545: .seealso:  PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
546:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY,
547:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
548:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

550:   Level: beginner

552: M*/
553: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
554: {
555:   PetscErrorCode   ierr;
556:   PetscViewer_Draw *vdraw;

559:   PetscNewLog(viewer,&vdraw);
560:   viewer->data = (void*)vdraw;

562:   viewer->ops->flush            = PetscViewerFlush_Draw;
563:   viewer->ops->view             = PetscViewerView_Draw;
564:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
565:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
566:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
567:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

569:   /* these are created on the fly if requested */
570:   vdraw->draw_max  = 5;
571:   vdraw->draw_base = 0;
572:   vdraw->w         = PETSC_DECIDE;
573:   vdraw->h         = PETSC_DECIDE;

575:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
576:   vdraw->singleton_made = PETSC_FALSE;
577:   return(0);
578: }

580: /*@
581:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

583:     Not Collective

585:     Input Parameter:
586: .  viewer - the PetscViewer

588:     Level: intermediate

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

592: @*/
593: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
594: {
595:   PetscErrorCode   ierr;
596:   PetscViewer_Draw *vdraw;
597:   PetscBool        isdraw;
598:   PetscInt         i;

602:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
603:   if (!isdraw) return(0);
604:   vdraw = (PetscViewer_Draw*)viewer->data;

606:   for (i=0; i<vdraw->draw_max; i++) {
607:     if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
608:   }
609:   return(0);
610: }

612: /*@
613:     PetscViewerDrawGetPause - Gets a pause for the first present draw

615:     Not Collective

617:     Input Parameter:
618: .  viewer - the PetscViewer

620:     Output Parameter:
621: .  pause - the pause value

623:     Level: intermediate

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

627: @*/
628: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
629: {
630:   PetscErrorCode   ierr;
631:   PetscViewer_Draw *vdraw;
632:   PetscBool        isdraw;
633:   PetscInt         i;
634:   PetscDraw        draw;

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

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

654: /*@
655:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

657:     Not Collective

659:     Input Parameters:
660: +  viewer - the PetscViewer
661: -  pause - the pause value

663:     Level: intermediate

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

667: @*/
668: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
669: {
670:   PetscErrorCode   ierr;
671:   PetscViewer_Draw *vdraw;
672:   PetscBool        isdraw;
673:   PetscInt         i;

677:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
678:   if (!isdraw) return(0);
679:   vdraw = (PetscViewer_Draw*)viewer->data;

681:   vdraw->pause = pause;
682:   for (i=0; i<vdraw->draw_max; i++) {
683:     if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
684:   }
685:   return(0);
686: }

688: /*@
689:     PetscViewerDrawSetHold - Holds previous image when drawing new image

691:     Not Collective

693:     Input Parameters:
694: +  viewer - the PetscViewer
695: -  hold - indicates to hold or not

697:     Level: intermediate

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

701: @*/
702: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
703: {
704:   PetscErrorCode   ierr;
705:   PetscViewer_Draw *vdraw;
706:   PetscBool        isdraw;

710:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
711:   if (!isdraw) return(0);
712:   vdraw = (PetscViewer_Draw*)viewer->data;

714:   vdraw->hold = hold;
715:   return(0);
716: }

718: /*@
719:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

721:     Not Collective

723:     Input Parameter:
724: .  viewer - the PetscViewer

726:     Output Parameter:
727: .  hold - indicates to hold or not

729:     Level: intermediate

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

733: @*/
734: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
735: {
736:   PetscErrorCode   ierr;
737:   PetscViewer_Draw *vdraw;
738:   PetscBool        isdraw;

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

746:   *hold = vdraw->hold;
747:   return(0);
748: }

750: /* ---------------------------------------------------------------------*/
751: /*
752:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
753:   is attached to a communicator, in this case the attribute is a PetscViewer.
754: */
755: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

757: /*@C
758:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
759:                      in a communicator.

761:      Collective

763:      Input Parameter:
764: .    comm - the MPI communicator to share the window PetscViewer

766:      Level: intermediate

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

773: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
774: @*/
775: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
776: {
778:   PetscMPIInt    flag;
779:   PetscViewer    viewer;
780:   MPI_Comm       ncomm;

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

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

806:     Collective on PetscViewer

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

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

816:     Level: intermediate

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

823: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
824: @*/
825: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
826: {
827:   PetscViewer_Draw *vdraw;
828:   PetscBool        isdraw;
829:   PetscErrorCode   ierr;

833:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
834:   if (!isdraw) return(0);
835:   vdraw = (PetscViewer_Draw*)viewer->data;

837:   vdraw->nbounds = nbounds;
838:   PetscFree(vdraw->bounds);
839:   PetscMalloc1(2*nbounds,&vdraw->bounds);
840:   PetscArraycpy(vdraw->bounds,bounds,2*nbounds);
841:   return(0);
842: }

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

847:     Collective on PetscViewer

849:     Input Parameter:
850: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

856:     Level: intermediate

858: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
859: @*/
860: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
861: {
862:   PetscViewer_Draw *vdraw;
863:   PetscBool        isdraw;
864:   PetscErrorCode   ierr;

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

872:   if (nbounds) *nbounds = vdraw->nbounds;
873:   if (bounds)  *bounds  = vdraw->bounds;
874:   return(0);
875: }