Date: 2016-07-24T16:46:12+00:00

Actual source code: drawv.c
petsc-3.7.3 2016-07-24
Report Typos and Errors

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

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

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

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

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

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

     51:     Collective on PetscViewer

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

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

     60:     Level: intermediate

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

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

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

     82:   windownumber += vdraw->draw_base;
     83:   if (windownumber >= vdraw->draw_max) {
     84:     /* allocate twice as many slots as needed */
     85:     PetscInt      draw_max  = vdraw->draw_max;
     86:     PetscDraw     *tdraw    = vdraw->draw;
     87:     PetscDrawLG   *drawlg   = vdraw->drawlg;
     88:     PetscDrawAxis *drawaxis = vdraw->drawaxis;

     90:     vdraw->draw_max = 2*windownumber;

     92:     PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);

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

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

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

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

    126:     Logically Collective on PetscViewer

    128:     Input Parameters:
    129: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
    130: -   windownumber - how much to add to the base

    132:     Level: developer

    134:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    135:    Concepts: graphics

    137: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
    138: @*/
    139: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
    140: {
    141:   PetscViewer_Draw *vdraw;
    142:   PetscErrorCode   ierr;
    143:   PetscBool        isdraw;

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

    152:   if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
    153:   vdraw->draw_base += windownumber;
    154:   return(0);
    155: }

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

    162:     Logically Collective on PetscViewer

    164:     Input Parameters:
    165: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
    166: -   windownumber - value to set the base

    168:     Level: developer

    170:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    171:    Concepts: graphics

    173: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
    174: @*/
    175: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
    176: {
    177:   PetscViewer_Draw *vdraw;
    178:   PetscErrorCode   ierr;
    179:   PetscBool        isdraw;

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

    188:   if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
    189:   vdraw->draw_base = windownumber;
    190:   return(0);
    191: }

    195: /*@C
    196:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
    197:     This PetscDrawLG object may then be used to perform graphics using
    198:     PetscDrawLGXXX() commands.

    200:     Collective on PetscViewer

    202:     Input Parameter:
    203: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
    204: -   windownumber - indicates which subwindow (usually 0)

    206:     Ouput Parameter:
    207: .   draw - the draw line graph object

    209:     Level: intermediate

    211:   Concepts: line graph^accessing context

    213: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    214: @*/
    215: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
    216: {
    217:   PetscErrorCode   ierr;
    218:   PetscBool        isdraw;
    219:   PetscViewer_Draw *vdraw;

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

    230:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
    231:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
    232:   }
    233:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
    234:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
    235:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawlg[windownumber+vdraw->draw_base]);
    236:     PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber+vdraw->draw_base]);
    237:   }
    238:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
    239:   return(0);
    240: }

    244: /*@C
    245:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
    246:     This PetscDrawAxis object may then be used to perform graphics using
    247:     PetscDrawAxisXXX() commands.

    249:     Collective on PetscViewer

    251:     Input Parameter:
    252: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
    253: -   windownumber - indicates which subwindow (usually 0)

    255:     Ouput Parameter:
    256: .   drawaxis - the draw axis object

    258:     Level: advanced

    260:   Concepts: line graph^accessing context

    262: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
    263: @*/
    264: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
    265: {
    266:   PetscErrorCode   ierr;
    267:   PetscBool        isdraw;
    268:   PetscViewer_Draw *vdraw;

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

    279:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
    280:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
    281:   }
    282:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
    283:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
    284:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);
    285:   }
    286:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
    287:   return(0);
    288: }

    292: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
    293: {
    294:   PetscErrorCode   ierr;
    295:   PetscViewer_Draw *vdraw;
    296:   PetscBool        isdraw;

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

    304:   if (w >= 1) vdraw->w = w;
    305:   if (h >= 1) vdraw->h = h;
    306:   return(0);
    307: }

    311: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
    312: {
    313:   PetscErrorCode   ierr;
    314:   PetscViewer_Draw *vdraw;
    315:   PetscBool        isdraw;

    319:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
    320:   if (!isdraw) return(0);
    321:   vdraw = (PetscViewer_Draw*)v->data;

    323:   PetscStrallocpy(display,&vdraw->display);
    324:   PetscStrallocpy(title,&vdraw->title);
    325:   if (w >= 1) vdraw->w = w;
    326:   if (h >= 1) vdraw->h = h;
    327:   return(0);
    328: }

    332: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
    333: {
    334:   PetscErrorCode   ierr;
    335:   PetscViewer_Draw *vdraw;
    336:   PetscBool        isdraw;

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

    344:   PetscFree(vdraw->drawtype);
    345:   PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
    346:   return(0);
    347: }

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

    356:    Collective on MPI_Comm

    358:    Input Parameters:
    359: +  comm - communicator that will share window
    360: .  display - the X display on which to open, or null for the local machine
    361: .  title - the title to put in the title bar, or null for no title
    362: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
    363: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
    364:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

    366:    Output Parameters:
    367: . viewer - the PetscViewer

    369:    Format Options:
    370: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
    371: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

    373:    Options Database Keys:
    374:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
    375:    PetscDrawCreate() for runtime options, including
    376: +  -draw_type x or null
    377: .  -nox - Disables all x-windows output
    378: .  -display <name> - Specifies name of machine for the X display
    379: .  -geometry <x,y,w,h> - allows setting the window location and size
    380: -  -draw_pause <pause> - Sets time (in seconds) that the
    381:      program pauses after PetscDrawPause() has been called
    382:      (0 is default, -1 implies until user input).

    384:    Level: beginner

    386:    Note for Fortran Programmers:
    387:    Whenever indicating null character data in a Fortran code,
    388:    NULL_CHARACTER must be employed; using NULL is not
    389:    correct for character data!  Thus, NULL_CHARACTER can be
    390:    used for the display and title input parameters.

    392:   Concepts: graphics^opening PetscViewer
    393:   Concepts: drawing^opening PetscViewer

    396: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
    397:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
    398: @*/
    399: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
    400: {

    404:   PetscViewerCreate(comm,viewer);
    405:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
    406:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
    407:   return(0);
    408: }

    412: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
    413: {
    414:   PetscErrorCode   ierr;
    415:   PetscMPIInt      rank;
    416:   PetscInt         i;
    417:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

    420:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous");
    421:   /* only processor zero can use the PetscViewer draw singleton */
    422:   if (*sviewer) *sviewer = NULL;
    423:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    424:   if (!rank) {
    425:     PetscViewerCreate(PETSC_COMM_SELF,sviewer);
    426:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
    427:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    428:     (*sviewer)->format = viewer->format;
    429:     for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
    430:       if (vdraw->draw[i]) {PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);}
    431:     }
    432:   }
    433:   vdraw->singleton_made = PETSC_TRUE;
    434:   return(0);
    435: }

    439: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
    440: {
    441:   PetscErrorCode   ierr;
    442:   PetscMPIInt      rank;
    443:   PetscInt         i;
    444:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

    447:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
    448:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    449:   if (!rank) {
    450:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    451:     for (i=0; i<vdraw->draw_max; i++) {
    452:       if (vdraw->draw[i] && svdraw->draw[i]) {
    453:         PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
    454:       }
    455:     }
    456:     PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
    457:     PetscFree((*sviewer)->data);
    458:     PetscHeaderDestroy(sviewer);
    459:   }
    460:   vdraw->singleton_made = PETSC_FALSE;
    461:   return(0);
    462: }

    466: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
    467: {
    469:   PetscReal      bounds[16];
    470:   PetscInt       nbounds = 16;
    471:   PetscBool      flg;

    474:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
    475:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
    476:   if (flg) {
    477:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
    478:   }
    479:   PetscOptionsTail();
    480:   return(0);
    481: }

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

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

    506: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
    507: {
    508:   PetscErrorCode   ierr;
    509:   PetscViewer_Draw *vdraw;

    512:   PetscNewLog(viewer,&vdraw);
    513:   viewer->data = (void*)vdraw;

    515:   viewer->ops->flush            = PetscViewerFlush_Draw;
    516:   viewer->ops->view             = PetscViewerView_Draw;
    517:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
    518:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
    519:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
    520:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

    522:   /* these are created on the fly if requested */
    523:   vdraw->draw_max  = 5;
    524:   vdraw->draw_base = 0;
    525:   vdraw->w         = PETSC_DECIDE;
    526:   vdraw->h         = PETSC_DECIDE;

    528:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
    529:   vdraw->singleton_made = PETSC_FALSE;
    530:   return(0);
    531: }

    535: /*@
    536:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

    538:     Not Collective

    540:     Input Parameter:
    541: .  viewer - the PetscViewer

    543:     Level: intermediate

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

    547: @*/
    548: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
    549: {
    550:   PetscErrorCode   ierr;
    551:   PetscViewer_Draw *vdraw;
    552:   PetscBool        isdraw;
    553:   PetscInt         i;

    557:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    558:   if (!isdraw) return(0);
    559:   vdraw = (PetscViewer_Draw*)viewer->data;

    561:   for (i=0; i<vdraw->draw_max; i++) {
    562:     if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
    563:   }
    564:   return(0);
    565: }

    569: /*@
    570:     PetscViewerDrawGetPause - Gets a pause for the first present draw

    572:     Not Collective

    574:     Input Parameter:
    575: .  viewer - the PetscViewer

    577:     Output Parameter:
    578: .  pause - the pause value

    580:     Level: intermediate

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

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

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

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

    613: /*@
    614:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

    616:     Not Collective

    618:     Input Parameters:
    619: +  viewer - the PetscViewer
    620: -  pause - the pause value

    622:     Level: intermediate

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

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

    636:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    637:   if (!isdraw) return(0);
    638:   vdraw = (PetscViewer_Draw*)viewer->data;

    640:   vdraw->pause = pause;
    641:   for (i=0; i<vdraw->draw_max; i++) {
    642:     if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
    643:   }
    644:   return(0);
    645: }

    650: /*@
    651:     PetscViewerDrawSetHold - Holds previous image when drawing new image

    653:     Not Collective

    655:     Input Parameters:
    656: +  viewer - the PetscViewer
    657: -  hold - indicates to hold or not

    659:     Level: intermediate

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

    663: @*/
    664: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
    665: {
    666:   PetscErrorCode   ierr;
    667:   PetscViewer_Draw *vdraw;
    668:   PetscBool        isdraw;

    672:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    673:   if (!isdraw) return(0);
    674:   vdraw = (PetscViewer_Draw*)viewer->data;

    676:   vdraw->hold = hold;
    677:   return(0);
    678: }

    682: /*@
    683:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

    685:     Not Collective

    687:     Input Parameter:
    688: .  viewer - the PetscViewer

    690:     Output Parameter:
    691: .  hold - indicates to hold or not

    693:     Level: intermediate

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

    697: @*/
    698: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
    699: {
    700:   PetscErrorCode   ierr;
    701:   PetscViewer_Draw *vdraw;
    702:   PetscBool        isdraw;

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

    710:   *hold = vdraw->hold;
    711:   return(0);
    712: }

    714: /* ---------------------------------------------------------------------*/
    715: /*
    716:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
    717:   is attached to a communicator, in this case the attribute is a PetscViewer.
    718: */
    719: static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

    723: /*@C
    724:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
    725:                      in a communicator.

    727:      Collective on MPI_Comm

    729:      Input Parameter:
    730: .    comm - the MPI communicator to share the window PetscViewer

    732:      Level: intermediate

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

    739: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
    740: @*/
    741: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
    742: {
    744:   PetscMPIInt    flag;
    745:   PetscViewer    viewer;
    746:   MPI_Comm       ncomm;

    749:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    750:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
    751:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
    752:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    753:   }
    754:   MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
    755:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    756:   if (!flag) { /* PetscViewer not yet created */
    757:     PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
    758:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    759:     PetscObjectRegisterDestroy((PetscObject)viewer);
    760:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    761:     MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
    762:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    763:   }
    764:   PetscCommDestroy(&ncomm);
    765:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    766:   PetscFunctionReturn(viewer);
    767: }

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

    774:     Collective on PetscViewer

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

    782:     Options Database:
    783: .   -draw_bounds  minF0,maxF0,minF1,maxF1

    785:     Level: intermediate

    787:     Notes: this determines the colors used in 2d contour plots generated with VecView() for DMDA in 2d. Any values in the vector below or above the
    788:       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
    789:       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.

    791:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    792:    Concepts: graphics

    794: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    795: @*/
    796: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
    797: {
    798:   PetscViewer_Draw *vdraw;
    799:   PetscBool        isdraw;
    800:   PetscErrorCode   ierr;

    805:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    806:   if (!isdraw) return(0);
    807:   vdraw = (PetscViewer_Draw*)viewer->data;

    809:   vdraw->nbounds = nbounds;
    810:   PetscFree(vdraw->bounds);
    811:   PetscMalloc1(2*nbounds,&vdraw->bounds);
    812:   PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));
    813:   return(0);
    814: }

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

    821:     Collective on PetscViewer

    823:     Input Parameter:
    824: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

    830:     Level: intermediate

    832:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    833:    Concepts: graphics

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

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

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