Date: 2022-08-02T03:13:15+00:00

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:   PetscInt         i;
      8:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

     11:   for (i=0; i<vdraw->draw_max; i++) {
     12:     PetscDrawAxisDestroy(&vdraw->drawaxis[i]);
     13:     PetscDrawLGDestroy(&vdraw->drawlg[i]);
     14:     PetscDrawDestroy(&vdraw->draw[i]);
     15:   }
     16:   PetscFree(vdraw->display);
     17:   PetscFree(vdraw->title);
     18:   PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
     19:   PetscFree(vdraw->bounds);
     20:   PetscFree(vdraw->drawtype);
     21:   PetscFree(v->data);
     22:   return 0;
     23: }

     25: static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
     26: {
     27:   PetscInt         i;
     28:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

     30:   for (i=0; i<vdraw->draw_max; i++) {
     31:     if (vdraw->draw[i]) PetscDrawFlush(vdraw->draw[i]);
     32:   }
     33:   return 0;
     34: }

     36: /*@C
     37:     PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
     38:     This PetscDraw object may then be used to perform graphics using
     39:     PetscDrawXXX() commands.

     41:     Collective on PetscViewer

     43:     Input Parameters:
     44: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
     45: -   windownumber - indicates which subwindow (usually 0)

     47:     Output Parameter:
     48: .   draw - the draw object

     50:     Level: intermediate

     52: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
     53: @*/
     54: PetscErrorCode  PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw)
     55: {
     56:   PetscViewer_Draw *vdraw;
     57:   PetscBool        isdraw;

     62:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
     65:   vdraw = (PetscViewer_Draw*)viewer->data;

     67:   windownumber += vdraw->draw_base;
     68:   if (windownumber >= vdraw->draw_max) {
     69:     /* allocate twice as many slots as needed */
     70:     PetscInt      draw_max  = vdraw->draw_max;
     71:     PetscDraw     *tdraw    = vdraw->draw;
     72:     PetscDrawLG   *drawlg   = vdraw->drawlg;
     73:     PetscDrawAxis *drawaxis = vdraw->drawaxis;

     75:     vdraw->draw_max = 2*windownumber;

     77:     PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
     78:     PetscArraycpy(vdraw->draw,tdraw,draw_max);
     79:     PetscArraycpy(vdraw->drawlg,drawlg,draw_max);
     80:     PetscArraycpy(vdraw->drawaxis,drawaxis,draw_max);
     81:     PetscFree3(tdraw,drawlg,drawaxis);
     82:   }

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

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

    107:     Logically Collective on PetscViewer

    109:     Input Parameters:
    110: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
    111: -   windownumber - how much to add to the base

    113:     Level: developer

    115: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
    116: @*/
    117: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
    118: {
    119:   PetscViewer_Draw *vdraw;
    120:   PetscBool        isdraw;

    124:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    126:   vdraw = (PetscViewer_Draw*)viewer->data;

    129:   vdraw->draw_base += windownumber;
    130:   return 0;
    131: }

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

    136:     Logically Collective on PetscViewer

    138:     Input Parameters:
    139: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
    140: -   windownumber - value to set the base

    142:     Level: developer

    144: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
    145: @*/
    146: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
    147: {
    148:   PetscViewer_Draw *vdraw;
    149:   PetscBool        isdraw;

    153:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    155:   vdraw = (PetscViewer_Draw*)viewer->data;

    158:   vdraw->draw_base = windownumber;
    159:   return 0;
    160: }

    162: /*@C
    163:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
    164:     This PetscDrawLG object may then be used to perform graphics using
    165:     PetscDrawLGXXX() commands.

    167:     Collective on PetscViewer

    169:     Input Parameters:
    170: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
    171: -   windownumber - indicates which subwindow (usually 0)

    173:     Output Parameter:
    174: .   draw - the draw line graph object

    176:     Level: intermediate

    178: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    179: @*/
    180: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
    181: {
    182:   PetscBool        isdraw;
    183:   PetscViewer_Draw *vdraw;

    188:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    191:   vdraw = (PetscViewer_Draw*)viewer->data;

    193:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
    194:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
    195:   }
    196:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
    197:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
    198:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawlg[windownumber+vdraw->draw_base]);
    199:     PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber+vdraw->draw_base]);
    200:   }
    201:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
    202:   return 0;
    203: }

    205: /*@C
    206:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
    207:     This PetscDrawAxis object may then be used to perform graphics using
    208:     PetscDrawAxisXXX() commands.

    210:     Collective on PetscViewer

    212:     Input Parameters:
    213: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
    214: -   windownumber - indicates which subwindow (usually 0)

    216:     Output Parameter:
    217: .   drawaxis - the draw axis object

    219:     Level: advanced

    221: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
    222: @*/
    223: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
    224: {
    225:   PetscBool        isdraw;
    226:   PetscViewer_Draw *vdraw;

    231:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    234:   vdraw = (PetscViewer_Draw*)viewer->data;

    236:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
    237:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
    238:   }
    239:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
    240:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
    241:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);
    242:   }
    243:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
    244:   return 0;
    245: }

    247: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
    248: {
    249:   PetscViewer_Draw *vdraw;
    250:   PetscBool        isdraw;

    253:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
    254:   if (!isdraw) return 0;
    255:   vdraw = (PetscViewer_Draw*)v->data;

    257:   if (w >= 1) vdraw->w = w;
    258:   if (h >= 1) vdraw->h = h;
    259:   return 0;
    260: }

    262: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
    263: {
    264:   PetscViewer_Draw *vdraw;
    265:   PetscBool        isdraw;

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

    272:   PetscStrallocpy(display,&vdraw->display);
    273:   PetscStrallocpy(title,&vdraw->title);
    274:   if (w >= 1) vdraw->w = w;
    275:   if (h >= 1) vdraw->h = h;
    276:   return 0;
    277: }

    279: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
    280: {
    281:   PetscViewer_Draw *vdraw;
    282:   PetscBool        isdraw;

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

    289:   PetscFree(vdraw->drawtype);
    290:   PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
    291:   return 0;
    292: }

    294: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype)
    295: {
    296:   PetscViewer_Draw *vdraw;
    297:   PetscBool        isdraw;

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

    304:   *drawtype = vdraw->drawtype;
    305:   return 0;
    306: }

    308: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[])
    309: {
    310:   PetscViewer_Draw *vdraw;
    311:   PetscBool        isdraw;

    314:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
    315:   if (!isdraw) return 0;
    316:   vdraw = (PetscViewer_Draw*)v->data;

    318:   PetscFree(vdraw->title);
    319:   PetscStrallocpy(title,&vdraw->title);
    320:   return 0;
    321: }

    323: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[])
    324: {
    325:   PetscViewer_Draw *vdraw;
    326:   PetscBool        isdraw;

    329:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
    331:   vdraw = (PetscViewer_Draw*)v->data;

    333:   *title = vdraw->title;
    334:   return 0;
    335: }

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

    342:    Collective

    344:    Input Parameters:
    345: +  comm - communicator that will share window
    346: .  display - the X display on which to open, or null for the local machine
    347: .  title - the title to put in the title bar, or null for no title
    348: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
    349: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
    350:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

    352:    Output Parameter:
    353: . viewer - the PetscViewer

    355:    Format Options:
    356: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
    357: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

    359:    Options Database Keys:
    360: +  -draw_type - use x or null
    361: .  -nox - Disables all x-windows output
    362: .  -display <name> - Specifies name of machine for the X display
    363: .  -geometry <x,y,w,h> - allows setting the window location and size
    364: -  -draw_pause <pause> - Sets time (in seconds) that the
    365:      program pauses after PetscDrawPause() has been called
    366:      (0 is default, -1 implies until user input).

    368:    Level: beginner

    370:    Notes:
    371:      PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual pages for PetscDrawCreate()

    373:    Note for Fortran Programmers:
    374:    Whenever indicating null character data in a Fortran code,
    375:    PETSC_NULL_CHARACTER must be employed; using NULL is not
    376:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
    377:    used for the display and title input parameters.

    379: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
    380:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
    381: @*/
    382: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
    383: {
    384:   PetscViewerCreate(comm,viewer);
    385:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
    386:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
    387:   return 0;
    388: }

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

    392: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
    393: {
    394:   PetscMPIInt      rank;
    395:   PetscInt         i;
    396:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

    399:   /* only processor zero can use the PetscViewer draw singleton */
    400:   if (sviewer) *sviewer = NULL;
    401:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    402:   if (rank == 0) {
    403:     PetscMPIInt flg;
    404:     PetscDraw   draw,sdraw;

    406:     MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
    408:     PetscViewerCreate(comm,sviewer);
    409:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
    410:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    411:     (*sviewer)->format = viewer->format;
    412:     for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
    413:       if (vdraw->draw[i]) PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);
    414:     }
    415:     PetscViewerDrawGetDraw(viewer,0,&draw);
    416:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
    417:     if (draw->savefilename) {
    418:       PetscDrawSetSave(sdraw,draw->savefilename);
    419:       sdraw->savefilecount = draw->savefilecount;
    420:       sdraw->savesinglefile = draw->savesinglefile;
    421:       sdraw->savemoviefps = draw->savemoviefps;
    422:       sdraw->saveonclear = draw->saveonclear;
    423:       sdraw->saveonflush = draw->saveonflush;
    424:     }
    425:     if (draw->savefinalfilename) PetscDrawSetSaveFinalImage(sdraw,draw->savefinalfilename);
    426:   } else {
    427:     PetscDraw draw;
    428:     PetscViewerDrawGetDraw(viewer,0,&draw);
    429:   }
    430:   vdraw->singleton_made = PETSC_TRUE;
    431:   return 0;
    432: }

    434: PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
    435: {
    436:   PetscMPIInt      rank;
    437:   PetscInt         i;
    438:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

    441:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    442:   if (rank == 0) {
    443:     PetscDraw draw,sdraw;

    445:     PetscViewerDrawGetDraw(viewer,0,&draw);
    446:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
    447:     if (draw->savefilename) {
    448:       draw->savefilecount = sdraw->savefilecount;
    449:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
    450:     }
    451:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    452:     for (i=0; i<vdraw->draw_max; i++) {
    453:       if (vdraw->draw[i] && svdraw->draw[i]) {
    454:         PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
    455:       }
    456:     }
    457:     PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
    458:     PetscFree((*sviewer)->data);
    459:     PetscHeaderDestroy(sviewer);
    460:   } else {
    461:     PetscDraw draw;

    463:     PetscViewerDrawGetDraw(viewer,0,&draw);
    464:     if (draw->savefilename) {
    465:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
    466:     }
    467:   }

    469:   vdraw->singleton_made = PETSC_FALSE;
    470:   return 0;
    471: }

    473: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
    474: {
    475:   PetscReal      bounds[16];
    476:   PetscInt       nbounds = 16;
    477:   PetscBool      flg;

    479:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
    480:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
    481:   if (flg) {
    482:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
    483:   }
    484:   PetscOptionsTail();
    485:   return 0;
    486: }

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

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

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

    508: .seealso:  PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
    509:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY,
    510:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
    511:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

    513:   Level: beginner

    515: M*/
    516: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
    517: {
    518:   PetscViewer_Draw *vdraw;

    520:   PetscNewLog(viewer,&vdraw);
    521:   viewer->data = (void*)vdraw;

    523:   viewer->ops->flush            = PetscViewerFlush_Draw;
    524:   viewer->ops->view             = PetscViewerView_Draw;
    525:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
    526:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
    527:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
    528:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

    530:   /* these are created on the fly if requested */
    531:   vdraw->draw_max  = 5;
    532:   vdraw->draw_base = 0;
    533:   vdraw->w         = PETSC_DECIDE;
    534:   vdraw->h         = PETSC_DECIDE;

    536:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
    537:   vdraw->singleton_made = PETSC_FALSE;
    538:   return 0;
    539: }

    541: /*@
    542:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

    544:     Not Collective

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

    549:     Level: intermediate

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

    553: @*/
    554: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
    555: {
    556:   PetscViewer_Draw *vdraw;
    557:   PetscBool        isdraw;
    558:   PetscInt         i;

    561:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    562:   if (!isdraw) return 0;
    563:   vdraw = (PetscViewer_Draw*)viewer->data;

    565:   for (i=0; i<vdraw->draw_max; i++) {
    566:     if (vdraw->draw[i]) PetscDrawClear(vdraw->draw[i]);
    567:   }
    568:   return 0;
    569: }

    571: /*@
    572:     PetscViewerDrawGetPause - Gets a pause for the first present draw

    574:     Not Collective

    576:     Input Parameter:
    577: .  viewer - the PetscViewer

    579:     Output Parameter:
    580: .  pause - the pause value

    582:     Level: intermediate

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

    586: @*/
    587: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
    588: {
    589:   PetscViewer_Draw *vdraw;
    590:   PetscBool        isdraw;
    591:   PetscInt         i;
    592:   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: }

    611: /*@
    612:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

    614:     Not Collective

    616:     Input Parameters:
    617: +  viewer - the PetscViewer
    618: -  pause - the pause value

    620:     Level: intermediate

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

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

    632:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    633:   if (!isdraw) return 0;
    634:   vdraw = (PetscViewer_Draw*)viewer->data;

    636:   vdraw->pause = pause;
    637:   for (i=0; i<vdraw->draw_max; i++) {
    638:     if (vdraw->draw[i]) PetscDrawSetPause(vdraw->draw[i],pause);
    639:   }
    640:   return 0;
    641: }

    643: /*@
    644:     PetscViewerDrawSetHold - Holds previous image when drawing new image

    646:     Not Collective

    648:     Input Parameters:
    649: +  viewer - the PetscViewer
    650: -  hold - indicates to hold or not

    652:     Level: intermediate

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

    656: @*/
    657: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
    658: {
    659:   PetscViewer_Draw *vdraw;
    660:   PetscBool        isdraw;

    663:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    664:   if (!isdraw) return 0;
    665:   vdraw = (PetscViewer_Draw*)viewer->data;

    667:   vdraw->hold = hold;
    668:   return 0;
    669: }

    671: /*@
    672:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

    674:     Not Collective

    676:     Input Parameter:
    677: .  viewer - the PetscViewer

    679:     Output Parameter:
    680: .  hold - indicates to hold or not

    682:     Level: intermediate

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

    686: @*/
    687: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
    688: {
    689:   PetscViewer_Draw *vdraw;
    690:   PetscBool        isdraw;

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

    697:   *hold = vdraw->hold;
    698:   return 0;
    699: }

    701: /* ---------------------------------------------------------------------*/
    702: /*
    703:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
    704:   is attached to a communicator, in this case the attribute is a PetscViewer.
    705: */
    706: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

    708: /*@C
    709:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
    710:                      in a communicator.

    712:      Collective

    714:      Input Parameter:
    715: .    comm - the MPI communicator to share the window PetscViewer

    717:      Level: intermediate

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

    724: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
    725: @*/
    726: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
    727: {
    729:   PetscMPIInt    flag;
    730:   PetscViewer    viewer;
    731:   MPI_Comm       ncomm;

    733:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
    734:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
    735:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,NULL);
    736:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
    737:   }
    738:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
    739:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
    740:   if (!flag) { /* PetscViewer not yet created */
    741:     PetscViewerDrawOpen(ncomm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
    742:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
    743:     PetscObjectRegisterDestroy((PetscObject)viewer);
    744:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
    745:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
    746:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
    747:   }
    748:   PetscCommDestroy(&ncomm);
    749:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
    750:   return viewer;
    751: }

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

    756:     Collective on PetscViewer

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

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

    766:     Level: intermediate

    768:     Notes:
    769:     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
    770:       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
    771:       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.

    773: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    774: @*/
    775: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
    776: {
    777:   PetscViewer_Draw *vdraw;
    778:   PetscBool        isdraw;

    781:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    782:   if (!isdraw) return 0;
    783:   vdraw = (PetscViewer_Draw*)viewer->data;

    785:   vdraw->nbounds = nbounds;
    786:   PetscFree(vdraw->bounds);
    787:   PetscMalloc1(2*nbounds,&vdraw->bounds);
    788:   PetscArraycpy(vdraw->bounds,bounds,2*nbounds);
    789:   return 0;
    790: }

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

    795:     Collective on PetscViewer

    797:     Input Parameter:
    798: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

    804:     Level: intermediate

    806: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
    807: @*/
    808: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
    809: {
    810:   PetscViewer_Draw *vdraw;
    811:   PetscBool        isdraw;

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

    818:   if (nbounds) *nbounds = vdraw->nbounds;
    819:   if (bounds)  *bounds  = vdraw->bounds;
    820:   return 0;
    821: }