Actual source code: drawv.c

petsc-master 2019-06-15
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);

 86:     PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
 87:     PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
 88:     PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));

 90:     PetscFree3(tdraw,drawlg,drawaxis);
 91:   }

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

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

116:     Logically Collective on PetscViewer

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

122:     Level: developer


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

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

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

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

148:     Logically Collective on PetscViewer

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

154:     Level: developer


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

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

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

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

182:     Collective on PetscViewer

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

188:     Ouput Parameter:
189: .   draw - the draw line graph object

191:     Level: intermediate

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

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

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

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

227:     Collective on PetscViewer

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

233:     Ouput Parameter:
234: .   drawaxis - the draw axis object

236:     Level: advanced

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

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

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

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

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

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

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

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

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

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

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

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

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

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

331:   *drawtype = vdraw->drawtype;
332:   return(0);
333: }

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

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

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

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

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

364:   *title = vdraw->title;
365:   return(0);
366: }

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

373:    Collective

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

383:    Output Parameters:
384: . viewer - the PetscViewer

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

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

401:    Level: beginner

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



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

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

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;

440:     MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
441:     if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
442:     PetscViewerCreate(comm,sviewer);
443:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
444:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
445:     (*sviewer)->format = viewer->format;
446:     for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
447:       if (vdraw->draw[i]) {PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);}
448:     }
449:   }
450:   vdraw->singleton_made = PETSC_TRUE;
451:   return(0);
452: }

454: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
455: {
456:   PetscErrorCode   ierr;
457:   PetscMPIInt      rank;
458:   PetscInt         i;
459:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

462:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
463:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
464:   if (!rank) {
465:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
466:     for (i=0; i<vdraw->draw_max; i++) {
467:       if (vdraw->draw[i] && svdraw->draw[i]) {
468:         PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
469:       }
470:     }
471:     PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
472:     PetscFree((*sviewer)->data);
473:     PetscHeaderDestroy(sviewer);
474:   }
475:   vdraw->singleton_made = PETSC_FALSE;
476:   return(0);
477: }

479: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
480: {
482:   PetscReal      bounds[16];
483:   PetscInt       nbounds = 16;
484:   PetscBool      flg;

487:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
488:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
489:   if (flg) {
490:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
491:   }
492:   PetscOptionsTail();
493:   return(0);
494: }

496: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
497: {
498:   PetscErrorCode   ierr;
499:   PetscDraw        draw;
500:   PetscInt         i;
501:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

504:   /*  If the PetscViewer has just been created then no vdraw->draw yet
505:       exists so this will not actually call the viewer on any draws. */
506:   for (i=0; i<vdraw->draw_base; i++) {
507:     if (vdraw->draw[i]) {
508:       PetscViewerDrawGetDraw(viewer,i,&draw);
509:       PetscDrawView(draw,v);
510:     }
511:   }
512:   return(0);
513: }

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


519: .seealso:  PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
520:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, 
521:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
522:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

524:   Level: beginner

526: M*/
527: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
528: {
529:   PetscErrorCode   ierr;
530:   PetscViewer_Draw *vdraw;

533:   PetscNewLog(viewer,&vdraw);
534:   viewer->data = (void*)vdraw;

536:   viewer->ops->flush            = PetscViewerFlush_Draw;
537:   viewer->ops->view             = PetscViewerView_Draw;
538:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
539:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
540:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
541:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

543:   /* these are created on the fly if requested */
544:   vdraw->draw_max  = 5;
545:   vdraw->draw_base = 0;
546:   vdraw->w         = PETSC_DECIDE;
547:   vdraw->h         = PETSC_DECIDE;

549:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
550:   vdraw->singleton_made = PETSC_FALSE;
551:   return(0);
552: }

554: /*@
555:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

557:     Not Collective

559:     Input Parameter:
560: .  viewer - the PetscViewer

562:     Level: intermediate

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

566: @*/
567: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
568: {
569:   PetscErrorCode   ierr;
570:   PetscViewer_Draw *vdraw;
571:   PetscBool        isdraw;
572:   PetscInt         i;

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

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

586: /*@
587:     PetscViewerDrawGetPause - Gets a pause for the first present draw

589:     Not Collective

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

594:     Output Parameter:
595: .  pause - the pause value

597:     Level: intermediate

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

601: @*/
602: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
603: {
604:   PetscErrorCode   ierr;
605:   PetscViewer_Draw *vdraw;
606:   PetscBool        isdraw;
607:   PetscInt         i;
608:   PetscDraw        draw;

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

616:   for (i=0; i<vdraw->draw_max; i++) {
617:     if (vdraw->draw[i]) {
618:       PetscDrawGetPause(vdraw->draw[i],pause);
619:       return(0);
620:     }
621:   }
622:   /* none exist yet so create one and get its pause */
623:   PetscViewerDrawGetDraw(viewer,0,&draw);
624:   PetscDrawGetPause(draw,pause);
625:   return(0);
626: }

628: /*@
629:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

631:     Not Collective

633:     Input Parameters:
634: +  viewer - the PetscViewer
635: -  pause - the pause value

637:     Level: intermediate

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

641: @*/
642: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
643: {
644:   PetscErrorCode   ierr;
645:   PetscViewer_Draw *vdraw;
646:   PetscBool        isdraw;
647:   PetscInt         i;

651:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
652:   if (!isdraw) return(0);
653:   vdraw = (PetscViewer_Draw*)viewer->data;

655:   vdraw->pause = pause;
656:   for (i=0; i<vdraw->draw_max; i++) {
657:     if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
658:   }
659:   return(0);
660: }


663: /*@
664:     PetscViewerDrawSetHold - Holds previous image when drawing new image

666:     Not Collective

668:     Input Parameters:
669: +  viewer - the PetscViewer
670: -  hold - indicates to hold or not

672:     Level: intermediate

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

676: @*/
677: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
678: {
679:   PetscErrorCode   ierr;
680:   PetscViewer_Draw *vdraw;
681:   PetscBool        isdraw;

685:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
686:   if (!isdraw) return(0);
687:   vdraw = (PetscViewer_Draw*)viewer->data;

689:   vdraw->hold = hold;
690:   return(0);
691: }

693: /*@
694:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

696:     Not Collective

698:     Input Parameter:
699: .  viewer - the PetscViewer

701:     Output Parameter:
702: .  hold - indicates to hold or not

704:     Level: intermediate

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

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

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

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

725: /* ---------------------------------------------------------------------*/
726: /*
727:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
728:   is attached to a communicator, in this case the attribute is a PetscViewer.
729: */
730: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

732: /*@C
733:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
734:                      in a communicator.

736:      Collective

738:      Input Parameter:
739: .    comm - the MPI communicator to share the window PetscViewer

741:      Level: intermediate

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

748: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
749: @*/
750: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
751: {
753:   PetscMPIInt    flag;
754:   PetscViewer    viewer;
755:   MPI_Comm       ncomm;

758:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
759:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
760:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
761:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
762:   }
763:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
764:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
765:   if (!flag) { /* PetscViewer not yet created */
766:     PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
767:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
768:     PetscObjectRegisterDestroy((PetscObject)viewer);
769:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
770:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
771:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
772:   }
773:   PetscCommDestroy(&ncomm);
774:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
775:   PetscFunctionReturn(viewer);
776: }

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

781:     Collective on PetscViewer

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


789:     Options Database:
790: .   -draw_bounds  minF0,maxF0,minF1,maxF1

792:     Level: intermediate

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


800: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
801: @*/
802: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
803: {
804:   PetscViewer_Draw *vdraw;
805:   PetscBool        isdraw;
806:   PetscErrorCode   ierr;


811:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
812:   if (!isdraw) return(0);
813:   vdraw = (PetscViewer_Draw*)viewer->data;

815:   vdraw->nbounds = nbounds;
816:   PetscFree(vdraw->bounds);
817:   PetscMalloc1(2*nbounds,&vdraw->bounds);
818:   PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));
819:   return(0);
820: }

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

825:     Collective on PetscViewer

827:     Input Parameter:
828: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

834:     Level: intermediate


837: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
838: @*/
839: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
840: {
841:   PetscViewer_Draw *vdraw;
842:   PetscBool        isdraw;
843:   PetscErrorCode   ierr;

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

851:   if (nbounds) *nbounds = vdraw->nbounds;
852:   if (bounds)  *bounds  = vdraw->bounds;
853:   return(0);
854: }