Date: 2015-10-02T21:58:21+00:00

Actual source code: drawv.c
petsc-3.6.2 2015-10-02
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: 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:   }

     21:   PetscFree(vdraw->display);
     22:   PetscFree(vdraw->title);
     23:   PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
     24:   PetscFree(vdraw->bounds);
     25:   PetscFree(vdraw->drawtype);
     26:   PetscFree(vdraw);
     27:   return(0);
     28: }

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

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

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

     52:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

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

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

     61:     Level: intermediate

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

     66: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
     67: @*/
     68: PetscErrorCode  PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
     69: {
     70:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
     71:   PetscErrorCode   ierr;
     72:   PetscBool        isdraw;
     73:   char             *title;

     78:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
     79:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
     80:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
     81:   windownumber += vdraw->draw_base;
     82:   if (windownumber >= vdraw->draw_max) {
     83:     /* allocate twice as many slots as needed */
     84:     PetscInt      draw_max  = vdraw->draw_max;
     85:     PetscDraw     *tdraw    = vdraw->draw;
     86:     PetscDrawLG   *drawlg   = vdraw->drawlg;
     87:     PetscDrawAxis *drawaxis = vdraw->drawaxis;

     89:     vdraw->draw_max = 2*windownumber;

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

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

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

    100:   if (!vdraw->draw[windownumber]) {
    101:     if (!windownumber) title = vdraw->title;
    102:     else {
    103:       char tmp_str[128];
    104:       PetscSNPrintf(tmp_str, 128, "%s:%d", 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:     if (vdraw->drawtype) {
    109:       PetscDrawSetType(vdraw->draw[windownumber],vdraw->drawtype);
    110:     }
    111:     PetscDrawSetPause(vdraw->draw[windownumber],vdraw->pause);
    112:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
    113:   }
    114:   if (draw) *draw = vdraw->draw[windownumber];
    116:   return(0);
    117: }

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

    124:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

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

    130:     Level: developer

    132:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    133:    Concepts: graphics

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

    145:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    146:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
    147:   if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
    148:   vdraw->draw_base += windownumber;
    149:   return(0);
    150: }

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

    157:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

    159:     Input Parameters:
    160: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
    161: -   windownumber - value to set the base

    163:     Level: developer

    165:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    166:    Concepts: graphics

    168: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
    169: @*/
    170: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
    171: {
    172:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
    173:   PetscErrorCode   ierr;
    174:   PetscBool        isdraw;

    178:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    179:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
    180:   if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
    181:   vdraw->draw_base = windownumber;
    182:   return(0);
    183: }

    187: /*@C
    188:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
    189:     This PetscDrawLG object may then be used to perform graphics using
    190:     PetscDrawLGXXX() commands.

    192:     Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)

    194:     Input Parameter:
    195: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
    196: -   windownumber - indicates which subwindow (usually 0)

    198:     Ouput Parameter:
    199: .   draw - the draw line graph object

    201:     Level: intermediate

    203:   Concepts: line graph^accessing context

    205: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    206: @*/
    207: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
    208: {
    209:   PetscErrorCode   ierr;
    210:   PetscBool        isdraw;
    211:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

    216:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    217:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
    218:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");

    220:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
    221:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
    222:   }
    223:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
    224:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
    225:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawlg[windownumber+vdraw->draw_base]);
    226:   }
    227:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
    228:   return(0);
    229: }

    233: /*@C
    234:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
    235:     This PetscDrawAxis object may then be used to perform graphics using
    236:     PetscDrawAxisXXX() commands.

    238:     Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)

    240:     Input Parameter:
    241: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
    242: -   windownumber - indicates which subwindow (usually 0)

    244:     Ouput Parameter:
    245: .   drawaxis - the draw axis object

    247:     Level: advanced

    249:   Concepts: line graph^accessing context

    251: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
    252: @*/
    253: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
    254: {
    255:   PetscErrorCode   ierr;
    256:   PetscBool        isdraw;
    257:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;

    262:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    263:   if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
    264:   if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");

    266:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
    267:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
    268:   }
    269:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
    270:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
    271:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);
    272:   }
    273:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
    274:   return(0);
    275: }

    279: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
    280: {
    281:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

    284:   vdraw->h = h;
    285:   vdraw->w = w;
    286:   return(0);
    287: }

    291: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
    292: {
    293:   PetscErrorCode   ierr;
    294:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

    297:   vdraw->h = h;
    298:   vdraw->w = w;
    299:   PetscStrallocpy(display,&vdraw->display);
    300:   PetscStrallocpy(title,&vdraw->title);
    301:   return(0);
    302: }

    306: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
    307: {
    308:   PetscErrorCode   ierr;
    309:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;
    310:   PetscBool        flg;

    313:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&flg);
    314:   if (flg) {
    315:     PetscFree(vdraw->drawtype);
    316:     PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
    317:   }
    318:   return(0);
    319: }

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

    328:    Collective on MPI_Comm

    330:    Input Parameters:
    331: +  comm - communicator that will share window
    332: .  display - the X display on which to open, or null for the local machine
    333: .  title - the title to put in the title bar, or null for no title
    334: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
    335: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
    336:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

    338:    Output Parameters:
    339: . viewer - the PetscViewer

    341:    Format Options:
    342: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
    343: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

    345:    Options Database Keys:
    346:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
    347:    PetscDrawCreate() for runtime options, including
    348: +  -draw_type x or null
    349: .  -nox - Disables all x-windows output
    350: .  -display <name> - Specifies name of machine for the X display
    351: .  -geometry <x,y,w,h> - allows setting the window location and size
    352: -  -draw_pause <pause> - Sets time (in seconds) that the
    353:      program pauses after PetscDrawPause() has been called
    354:      (0 is default, -1 implies until user input).

    356:    Level: beginner

    358:    Note for Fortran Programmers:
    359:    Whenever indicating null character data in a Fortran code,
    360:    NULL_CHARACTER must be employed; using NULL is not
    361:    correct for character data!  Thus, NULL_CHARACTER can be
    362:    used for the display and title input parameters.

    364:   Concepts: graphics^opening PetscViewer
    365:   Concepts: drawing^opening PetscViewer

    368: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
    369:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
    370: @*/
    371: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
    372: {

    376:   PetscViewerCreate(comm,viewer);
    377:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
    378:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
    379:   return(0);
    380: }

    384: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
    385: {
    386:   PetscErrorCode   ierr;
    387:   PetscMPIInt      rank;
    388:   PetscInt         i;
    389:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw;

    392:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");

    394:   /* only processor zero can use the PetscViewer draw singleton */
    395:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    396:   if (!rank) {
    397:     PetscViewerCreate(PETSC_COMM_SELF,sviewer);
    398:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
    399:     vsdraw = (PetscViewer_Draw*)(*sviewer)->data;
    400:     for (i=0; i<vdraw->draw_max; i++) {
    401:       if (vdraw->draw[i]) {
    402:         PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
    403:       }
    404:     }
    405:   }
    406:   vdraw->singleton_made = PETSC_TRUE;
    407:   return(0);
    408: }

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

    420:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
    421:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    422:   if (!rank) {
    423:     vsdraw = (PetscViewer_Draw*)(*sviewer)->data;
    424:     for (i=0; i<vdraw->draw_max; i++) {
    425:       if (vdraw->draw[i] && vsdraw->draw[i]) {
    426:         PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
    427:       }
    428:     }
    429:     PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);
    430:     PetscFree((*sviewer)->data);
    431:     PetscHeaderDestroy(sviewer);
    432:   }
    433:   vdraw->singleton_made = PETSC_FALSE;
    434:   return(0);
    435: }

    439: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptions *PetscOptionsObject,PetscViewer v)
    440: {
    442:   PetscReal      bounds[16];
    443:   PetscInt       nbounds = 16;
    444:   PetscBool      flg;

    447:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
    448:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
    449:   if (flg) {
    450:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
    451:   }

    453:   PetscOptionsTail();
    454:   return(0);
    455: }

    459: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
    460: {
    461:   PetscErrorCode   ierr;
    462:   PetscDraw        draw;
    463:   PetscInt         i;
    464:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

    467:   /*  If the PetscViewer has just been created then no vdraw->draw yet
    468:       exists so this will not actually call the viewer on any draws. */
    469:   for (i=0; i<vdraw->draw_base; i++) {
    470:     if (vdraw->draw[i]) {
    471:       PetscViewerDrawGetDraw(viewer,i,&draw);
    472:       PetscDrawView(draw,v);
    473:     }
    474:   }
    475:   return(0);
    476: }

    480: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
    481: {
    482:   PetscErrorCode   ierr;
    483:   PetscViewer_Draw *vdraw;

    486:   PetscNewLog(viewer,&vdraw);
    487:   viewer->data = (void*)vdraw;

    489:   viewer->ops->flush            = PetscViewerFlush_Draw;
    490:   viewer->ops->view             = PetscViewerView_Draw;
    491:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
    492:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
    493:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
    494:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;

    496:   /* these are created on the fly if requested */
    497:   vdraw->draw_max  = 5;
    498:   vdraw->draw_base = 0;
    499:   vdraw->w         = PETSC_DECIDE;
    500:   vdraw->h         = PETSC_DECIDE;

    502:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
    503:   vdraw->singleton_made = PETSC_FALSE;
    504:   return(0);
    505: }

    509: /*@
    510:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

    512:     Not Collective

    514:     Input Parameter:
    515: .  viewer - the PetscViewer

    517:     Level: intermediate

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

    521: @*/
    522: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
    523: {
    524:   PetscErrorCode   ierr;
    525:   PetscInt         i;
    526:   PetscBool        isdraw;
    527:   PetscViewer_Draw *vdraw;

    530:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    531:   if (isdraw) {
    532:     vdraw = (PetscViewer_Draw*)viewer->data;
    533:     for (i=0; i<vdraw->draw_max; i++) {
    534:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
    535:     }
    536:   }
    537:   return(0);
    538: }

    542: /*@
    543:     PetscViewerDrawGetPause - Gets a pause for the first present draw

    545:     Not Collective

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

    550:     Output Parameter:
    551: .  pause - the pause value

    553:     Level: intermediate

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

    557: @*/
    558: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
    559: {
    560:   PetscErrorCode   ierr;
    561:   PetscInt         i;
    562:   PetscBool        isdraw;
    563:   PetscViewer_Draw *vdraw;
    564:   PetscDraw        draw;

    567:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    568:   *pause = 0.0;
    569:   if (isdraw) {
    570:     vdraw = (PetscViewer_Draw*)viewer->data;
    571:     for (i=0; i<vdraw->draw_max; i++) {
    572:       if (vdraw->draw[i]) {
    573:         PetscDrawGetPause(vdraw->draw[i],pause);
    574:         return(0);
    575:       }
    576:     }
    577:     /* none exist yet so create one and get its pause */
    578:     PetscViewerDrawGetDraw(viewer,0,&draw);
    579:     PetscDrawGetPause(vdraw->draw[0],pause);
    580:   }
    581:   return(0);
    582: }

    586: /*@
    587:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

    589:     Not Collective

    591:     Input Parameters:
    592: +  viewer - the PetscViewer
    593: -  pause - the pause value

    595:     Level: intermediate

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

    599: @*/
    600: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
    601: {
    602:   PetscErrorCode   ierr;
    603:   PetscInt         i;
    604:   PetscBool        isdraw;

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

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

    622: /*@
    623:     PetscViewerDrawSetHold - Holds previous image when drawing new image

    625:     Not Collective

    627:     Input Parameters:
    628: +  viewer - the PetscViewer
    629: -  hold - indicates to hold or not

    631:     Level: intermediate

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

    635: @*/
    636: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
    637: {
    638:   PetscErrorCode   ierr;
    639:   PetscViewer_Draw *vdraw;
    640:   PetscBool        isdraw;

    643:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    644:   if (isdraw) {
    645:     vdraw       = (PetscViewer_Draw*)viewer->data;
    646:     vdraw->hold = hold;
    647:   }
    648:   return(0);
    649: }

    653: /*@
    654:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

    656:     Not Collective

    658:     Input Parameter:
    659: .  viewer - the PetscViewer

    661:     Output Parameter:
    662: .  hold - indicates to hold or not

    664:     Level: intermediate

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

    668: @*/
    669: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
    670: {
    671:   PetscErrorCode   ierr;
    672:   PetscViewer_Draw *vdraw;
    673:   PetscBool        isdraw;

    676:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    677:   if (isdraw) {
    678:     vdraw = (PetscViewer_Draw*)viewer->data;
    679:     *hold = vdraw->hold;
    680:   }
    681:   return(0);
    682: }

    684: /* ---------------------------------------------------------------------*/
    685: /*
    686:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
    687:   is attached to a communicator, in this case the attribute is a PetscViewer.
    688: */
    689: static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

    693: /*@C
    694:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
    695:                      in a communicator.

    697:      Collective on MPI_Comm

    699:      Input Parameter:
    700: .    comm - the MPI communicator to share the window PetscViewer

    702:      Level: intermediate

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

    709: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
    710: @*/
    711: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
    712: {
    714:   PetscMPIInt    flag;
    715:   PetscViewer    viewer;
    716:   MPI_Comm       ncomm;

    719:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    720:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
    721:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
    722:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    723:   }
    724:   MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
    725:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    726:   if (!flag) { /* PetscViewer not yet created */
    727:     PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
    728:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    729:     PetscObjectRegisterDestroy((PetscObject)viewer);
    730:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    731:     MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
    732:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    733:   }
    734:   PetscCommDestroy(&ncomm);
    735:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    736:   PetscFunctionReturn(viewer);
    737: }

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

    744:     Collective on PetscViewer

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

    752:     Options Database:
    753: .   -draw_bounds  minF0,maxF0,minF1,maxF1

    755:     Level: intermediate

    757:     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
    758:       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
    759:       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.

    761:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    762:    Concepts: graphics

    764: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    765: @*/
    766: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
    767: {
    768:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
    769:   PetscErrorCode   ierr;

    774:   vdraw->nbounds = nbounds;

    776:   PetscMalloc1(2*nbounds,&vdraw->bounds);
    777:   PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));
    778:   return(0);
    779: }

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

    786:     Collective on PetscViewer

    788:     Input Parameter:
    789: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

    795:     Level: intermediate

    797:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    798:    Concepts: graphics

    800: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
    801: @*/
    802: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
    803: {
    804:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

    808:   *nbounds = vdraw->nbounds;
    809:   *bounds  = vdraw->bounds;
    810:   return(0);
    811: }