Actual source code: drawv.c
petsc-3.10.5 2019-03-28
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

     56:    Concepts: drawing^accessing PetscDraw context from PetscViewer
     57:    Concepts: graphics

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

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

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

     84:     vdraw->draw_max = 2*windownumber;

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

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

     92:     PetscFree3(tdraw,drawlg,drawaxis);
     93:   }

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

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

    118:     Logically Collective on PetscViewer

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

    124:     Level: developer

    126:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    127:    Concepts: graphics

    129: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
    130: @*/
    131: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
    132: {
    133:   PetscViewer_Draw *vdraw;
    134:   PetscErrorCode   ierr;
    135:   PetscBool        isdraw;

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

    144:   if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
    145:   vdraw->draw_base += windownumber;
    146:   return(0);
    147: }

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

    152:     Logically Collective on PetscViewer

    154:     Input Parameters:
    155: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
    156: -   windownumber - value to set the base

    158:     Level: developer

    160:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    161:    Concepts: graphics

    163: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
    164: @*/
    165: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
    166: {
    167:   PetscViewer_Draw *vdraw;
    168:   PetscErrorCode   ierr;
    169:   PetscBool        isdraw;

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

    178:   if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
    179:   vdraw->draw_base = windownumber;
    180:   return(0);
    181: }

    183: /*@C
    184:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
    185:     This PetscDrawLG object may then be used to perform graphics using
    186:     PetscDrawLGXXX() commands.

    188:     Collective on PetscViewer

    190:     Input Parameter:
    191: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
    192: -   windownumber - indicates which subwindow (usually 0)

    194:     Ouput Parameter:
    195: .   draw - the draw line graph object

    197:     Level: intermediate

    199:   Concepts: line graph^accessing context

    201: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    202: @*/
    203: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
    204: {
    205:   PetscErrorCode   ierr;
    206:   PetscBool        isdraw;
    207:   PetscViewer_Draw *vdraw;

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

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

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

    235:     Collective on PetscViewer

    237:     Input Parameter:
    238: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
    239: -   windownumber - indicates which subwindow (usually 0)

    241:     Ouput Parameter:
    242: .   drawaxis - the draw axis object

    244:     Level: advanced

    246:   Concepts: line graph^accessing context

    248: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
    249: @*/
    250: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
    251: {
    252:   PetscErrorCode   ierr;
    253:   PetscBool        isdraw;
    254:   PetscViewer_Draw *vdraw;

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

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

    276: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
    277: {
    278:   PetscErrorCode   ierr;
    279:   PetscViewer_Draw *vdraw;
    280:   PetscBool        isdraw;

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

    288:   if (w >= 1) vdraw->w = w;
    289:   if (h >= 1) vdraw->h = h;
    290:   return(0);
    291: }

    293: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
    294: {
    295:   PetscErrorCode   ierr;
    296:   PetscViewer_Draw *vdraw;
    297:   PetscBool        isdraw;

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

    305:   PetscStrallocpy(display,&vdraw->display);
    306:   PetscStrallocpy(title,&vdraw->title);
    307:   if (w >= 1) vdraw->w = w;
    308:   if (h >= 1) vdraw->h = h;
    309:   return(0);
    310: }

    312: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
    313: {
    314:   PetscErrorCode   ierr;
    315:   PetscViewer_Draw *vdraw;
    316:   PetscBool        isdraw;

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

    324:   PetscFree(vdraw->drawtype);
    325:   PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
    326:   return(0);
    327: }

    329: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype)
    330: {
    331:   PetscErrorCode   ierr;
    332:   PetscViewer_Draw *vdraw;
    333:   PetscBool        isdraw;

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

    341:   *drawtype = vdraw->drawtype;
    342:   return(0);
    343: }

    345: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[])
    346: {
    347:   PetscErrorCode   ierr;
    348:   PetscViewer_Draw *vdraw;
    349:   PetscBool        isdraw;

    353:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
    354:   if (!isdraw) return(0);
    355:   vdraw = (PetscViewer_Draw*)v->data;

    357:   PetscFree(vdraw->title);
    358:   PetscStrallocpy(title,&vdraw->title);
    359:   return(0);
    360: }

    362: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[])
    363: {
    364:   PetscErrorCode   ierr;
    365:   PetscViewer_Draw *vdraw;
    366:   PetscBool        isdraw;

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

    374:   *title = vdraw->title;
    375:   return(0);
    376: }

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

    383:    Collective on MPI_Comm

    385:    Input Parameters:
    386: +  comm - communicator that will share window
    387: .  display - the X display on which to open, or null for the local machine
    388: .  title - the title to put in the title bar, or null for no title
    389: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
    390: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
    391:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

    393:    Output Parameters:
    394: . viewer - the PetscViewer

    396:    Format Options:
    397: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
    398: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

    400:    Options Database Keys:
    401:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
    402:    PetscDrawCreate() for runtime options, including
    403: +  -draw_type x or null
    404: .  -nox - Disables all x-windows output
    405: .  -display <name> - Specifies name of machine for the X display
    406: .  -geometry <x,y,w,h> - allows setting the window location and size
    407: -  -draw_pause <pause> - Sets time (in seconds) that the
    408:      program pauses after PetscDrawPause() has been called
    409:      (0 is default, -1 implies until user input).

    411:    Level: beginner

    413:    Note for Fortran Programmers:
    414:    Whenever indicating null character data in a Fortran code,
    415:    NULL_CHARACTER must be employed; using NULL is not
    416:    correct for character data!  Thus, NULL_CHARACTER can be
    417:    used for the display and title input parameters.

    419:   Concepts: graphics^opening PetscViewer
    420:   Concepts: drawing^opening PetscViewer

    423: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
    424:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
    425: @*/
    426: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
    427: {

    431:   PetscViewerCreate(comm,viewer);
    432:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
    433:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
    434:   return(0);
    435: }

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

    445:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous");
    446:   /* only processor zero can use the PetscViewer draw singleton */
    447:   if (sviewer) *sviewer = NULL;
    448:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    449:   if (!rank) {
    450:     PetscViewerCreate(PETSC_COMM_SELF,sviewer);
    451:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
    452:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    453:     (*sviewer)->format = viewer->format;
    454:     for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
    455:       if (vdraw->draw[i]) {PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);}
    456:     }
    457:   }
    458:   vdraw->singleton_made = PETSC_TRUE;
    459:   return(0);
    460: }

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

    470:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
    471:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    472:   if (!rank) {
    473:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    474:     for (i=0; i<vdraw->draw_max; i++) {
    475:       if (vdraw->draw[i] && svdraw->draw[i]) {
    476:         PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
    477:       }
    478:     }
    479:     PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
    480:     PetscFree((*sviewer)->data);
    481:     PetscHeaderDestroy(sviewer);
    482:   }
    483:   vdraw->singleton_made = PETSC_FALSE;
    484:   return(0);
    485: }

    487: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
    488: {
    490:   PetscReal      bounds[16];
    491:   PetscInt       nbounds = 16;
    492:   PetscBool      flg;

    495:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
    496:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
    497:   if (flg) {
    498:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
    499:   }
    500:   PetscOptionsTail();
    501:   return(0);
    502: }

    504: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
    505: {
    506:   PetscErrorCode   ierr;
    507:   PetscDraw        draw;
    508:   PetscInt         i;
    509:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

    512:   /*  If the PetscViewer has just been created then no vdraw->draw yet
    513:       exists so this will not actually call the viewer on any draws. */
    514:   for (i=0; i<vdraw->draw_base; i++) {
    515:     if (vdraw->draw[i]) {
    516:       PetscViewerDrawGetDraw(viewer,i,&draw);
    517:       PetscDrawView(draw,v);
    518:     }
    519:   }
    520:   return(0);
    521: }

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

    527: .seealso:  PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
    528:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY,
    529:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
    530:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

    532:   Level: beginner

    534: M*/
    535: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
    536: {
    537:   PetscErrorCode   ierr;
    538:   PetscViewer_Draw *vdraw;

    541:   PetscNewLog(viewer,&vdraw);
    542:   viewer->data = (void*)vdraw;

    544:   viewer->ops->flush            = PetscViewerFlush_Draw;
    545:   viewer->ops->view             = PetscViewerView_Draw;
    546:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
    547:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
    548:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
    549:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

    551:   /* these are created on the fly if requested */
    552:   vdraw->draw_max  = 5;
    553:   vdraw->draw_base = 0;
    554:   vdraw->w         = PETSC_DECIDE;
    555:   vdraw->h         = PETSC_DECIDE;

    557:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
    558:   vdraw->singleton_made = PETSC_FALSE;
    559:   return(0);
    560: }

    562: /*@
    563:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

    565:     Not Collective

    567:     Input Parameter:
    568: .  viewer - the PetscViewer

    570:     Level: intermediate

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

    574: @*/
    575: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
    576: {
    577:   PetscErrorCode   ierr;
    578:   PetscViewer_Draw *vdraw;
    579:   PetscBool        isdraw;
    580:   PetscInt         i;

    584:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    585:   if (!isdraw) return(0);
    586:   vdraw = (PetscViewer_Draw*)viewer->data;

    588:   for (i=0; i<vdraw->draw_max; i++) {
    589:     if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
    590:   }
    591:   return(0);
    592: }

    594: /*@
    595:     PetscViewerDrawGetPause - Gets a pause for the first present draw

    597:     Not Collective

    599:     Input Parameter:
    600: .  viewer - the PetscViewer

    602:     Output Parameter:
    603: .  pause - the pause value

    605:     Level: intermediate

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

    609: @*/
    610: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
    611: {
    612:   PetscErrorCode   ierr;
    613:   PetscViewer_Draw *vdraw;
    614:   PetscBool        isdraw;
    615:   PetscInt         i;
    616:   PetscDraw        draw;

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

    624:   for (i=0; i<vdraw->draw_max; i++) {
    625:     if (vdraw->draw[i]) {
    626:       PetscDrawGetPause(vdraw->draw[i],pause);
    627:       return(0);
    628:     }
    629:   }
    630:   /* none exist yet so create one and get its pause */
    631:   PetscViewerDrawGetDraw(viewer,0,&draw);
    632:   PetscDrawGetPause(draw,pause);
    633:   return(0);
    634: }

    636: /*@
    637:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

    639:     Not Collective

    641:     Input Parameters:
    642: +  viewer - the PetscViewer
    643: -  pause - the pause value

    645:     Level: intermediate

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

    649: @*/
    650: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
    651: {
    652:   PetscErrorCode   ierr;
    653:   PetscViewer_Draw *vdraw;
    654:   PetscBool        isdraw;
    655:   PetscInt         i;

    659:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    660:   if (!isdraw) return(0);
    661:   vdraw = (PetscViewer_Draw*)viewer->data;

    663:   vdraw->pause = pause;
    664:   for (i=0; i<vdraw->draw_max; i++) {
    665:     if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
    666:   }
    667:   return(0);
    668: }

    671: /*@
    672:     PetscViewerDrawSetHold - Holds previous image when drawing new image

    674:     Not Collective

    676:     Input Parameters:
    677: +  viewer - the PetscViewer
    678: -  hold - indicates to hold or not

    680:     Level: intermediate

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

    684: @*/
    685: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
    686: {
    687:   PetscErrorCode   ierr;
    688:   PetscViewer_Draw *vdraw;
    689:   PetscBool        isdraw;

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

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

    701: /*@
    702:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

    704:     Not Collective

    706:     Input Parameter:
    707: .  viewer - the PetscViewer

    709:     Output Parameter:
    710: .  hold - indicates to hold or not

    712:     Level: intermediate

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

    716: @*/
    717: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
    718: {
    719:   PetscErrorCode   ierr;
    720:   PetscViewer_Draw *vdraw;
    721:   PetscBool        isdraw;

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

    729:   *hold = vdraw->hold;
    730:   return(0);
    731: }

    733: /* ---------------------------------------------------------------------*/
    734: /*
    735:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
    736:   is attached to a communicator, in this case the attribute is a PetscViewer.
    737: */
    738: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

    740: /*@C
    741:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
    742:                      in a communicator.

    744:      Collective on MPI_Comm

    746:      Input Parameter:
    747: .    comm - the MPI communicator to share the window PetscViewer

    749:      Level: intermediate

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

    756: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
    757: @*/
    758: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
    759: {
    761:   PetscMPIInt    flag;
    762:   PetscViewer    viewer;
    763:   MPI_Comm       ncomm;

    766:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    767:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
    768:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
    769:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    770:   }
    771:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
    772:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    773:   if (!flag) { /* PetscViewer not yet created */
    774:     PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
    775:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    776:     PetscObjectRegisterDestroy((PetscObject)viewer);
    777:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    778:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
    779:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    780:   }
    781:   PetscCommDestroy(&ncomm);
    782:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    783:   PetscFunctionReturn(viewer);
    784: }

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

    789:     Collective on PetscViewer

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

    797:     Options Database:
    798: .   -draw_bounds  minF0,maxF0,minF1,maxF1

    800:     Level: intermediate

    802:     Notes:
    803:     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
    804:       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
    805:       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.

    807:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    808:    Concepts: graphics

    810: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    811: @*/
    812: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
    813: {
    814:   PetscViewer_Draw *vdraw;
    815:   PetscBool        isdraw;
    816:   PetscErrorCode   ierr;

    821:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    822:   if (!isdraw) return(0);
    823:   vdraw = (PetscViewer_Draw*)viewer->data;

    825:   vdraw->nbounds = nbounds;
    826:   PetscFree(vdraw->bounds);
    827:   PetscMalloc1(2*nbounds,&vdraw->bounds);
    828:   PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));
    829:   return(0);
    830: }

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

    835:     Collective on PetscViewer

    837:     Input Parameter:
    838: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

    844:     Level: intermediate

    846:    Concepts: drawing^accessing PetscDraw context from PetscViewer
    847:    Concepts: graphics

    849: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
    850: @*/
    851: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
    852: {
    853:   PetscViewer_Draw *vdraw;
    854:   PetscBool        isdraw;
    855:   PetscErrorCode   ierr;

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

    863:   if (nbounds) *nbounds = vdraw->nbounds;
    864:   if (bounds)  *bounds  = vdraw->bounds;
    865:   return(0);
    866: }