Date: 2022-03-04T17:36:58+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:   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:     Output Parameter:
     52: .   draw - the draw object

     54:     Level: intermediate

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

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

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

     81:     vdraw->draw_max = 2*windownumber;

     83:     PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
     84:     PetscArraycpy(vdraw->draw,tdraw,draw_max);
     85:     PetscArraycpy(vdraw->drawlg,drawlg,draw_max);
     86:     PetscArraycpy(vdraw->drawaxis,drawaxis,draw_max);
     87:     PetscFree3(tdraw,drawlg,drawaxis);
     88:   }

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

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

    113:     Logically Collective on PetscViewer

    115:     Input Parameters:
    116: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
    117: -   windownumber - how much to add to the base

    119:     Level: developer

    121: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
    122: @*/
    123: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)
    124: {
    125:   PetscViewer_Draw *vdraw;
    126:   PetscErrorCode   ierr;
    127:   PetscBool        isdraw;

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

    136:   if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
    137:   vdraw->draw_base += windownumber;
    138:   return(0);
    139: }

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

    144:     Logically Collective on PetscViewer

    146:     Input Parameters:
    147: +   viewer - the PetscViewer (created with PetscViewerDrawOpen())
    148: -   windownumber - value to set the base

    150:     Level: developer

    152: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
    153: @*/
    154: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)
    155: {
    156:   PetscViewer_Draw *vdraw;
    157:   PetscErrorCode   ierr;
    158:   PetscBool        isdraw;

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

    167:   if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
    168:   vdraw->draw_base = windownumber;
    169:   return(0);
    170: }

    172: /*@C
    173:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
    174:     This PetscDrawLG object may then be used to perform graphics using
    175:     PetscDrawLGXXX() commands.

    177:     Collective on PetscViewer

    179:     Input Parameters:
    180: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
    181: -   windownumber - indicates which subwindow (usually 0)

    183:     Output Parameter:
    184: .   draw - the draw line graph object

    186:     Level: intermediate

    188: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    189: @*/
    190: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg)
    191: {
    192:   PetscErrorCode   ierr;
    193:   PetscBool        isdraw;
    194:   PetscViewer_Draw *vdraw;

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

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

    217: /*@C
    218:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
    219:     This PetscDrawAxis object may then be used to perform graphics using
    220:     PetscDrawAxisXXX() commands.

    222:     Collective on PetscViewer

    224:     Input Parameters:
    225: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
    226: -   windownumber - indicates which subwindow (usually 0)

    228:     Output Parameter:
    229: .   drawaxis - the draw axis object

    231:     Level: advanced

    233: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
    234: @*/
    235: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis)
    236: {
    237:   PetscErrorCode   ierr;
    238:   PetscBool        isdraw;
    239:   PetscViewer_Draw *vdraw;

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

    250:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
    251:     PetscViewerDrawGetDraw(viewer,windownumber,NULL);
    252:   }
    253:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
    254:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
    255:     PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);
    256:   }
    257:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
    258:   return(0);
    259: }

    261: PetscErrorCode  PetscViewerDrawResize(PetscViewer v,int w,int h)
    262: {
    263:   PetscErrorCode   ierr;
    264:   PetscViewer_Draw *vdraw;
    265:   PetscBool        isdraw;

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

    273:   if (w >= 1) vdraw->w = w;
    274:   if (h >= 1) vdraw->h = h;
    275:   return(0);
    276: }

    278: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
    279: {
    280:   PetscErrorCode   ierr;
    281:   PetscViewer_Draw *vdraw;
    282:   PetscBool        isdraw;

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

    290:   PetscStrallocpy(display,&vdraw->display);
    291:   PetscStrallocpy(title,&vdraw->title);
    292:   if (w >= 1) vdraw->w = w;
    293:   if (h >= 1) vdraw->h = h;
    294:   return(0);
    295: }

    297: PetscErrorCode  PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype)
    298: {
    299:   PetscErrorCode   ierr;
    300:   PetscViewer_Draw *vdraw;
    301:   PetscBool        isdraw;

    305:   PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);
    306:   if (!isdraw) return(0);
    307:   vdraw = (PetscViewer_Draw*)v->data;

    309:   PetscFree(vdraw->drawtype);
    310:   PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);
    311:   return(0);
    312: }

    314: PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype)
    315: {
    316:   PetscErrorCode   ierr;
    317:   PetscViewer_Draw *vdraw;
    318:   PetscBool        isdraw;

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

    326:   *drawtype = vdraw->drawtype;
    327:   return(0);
    328: }

    330: PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[])
    331: {
    332:   PetscErrorCode   ierr;
    333:   PetscViewer_Draw *vdraw;
    334:   PetscBool        isdraw;

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

    342:   PetscFree(vdraw->title);
    343:   PetscStrallocpy(title,&vdraw->title);
    344:   return(0);
    345: }

    347: PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[])
    348: {
    349:   PetscErrorCode   ierr;
    350:   PetscViewer_Draw *vdraw;
    351:   PetscBool        isdraw;

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

    359:   *title = vdraw->title;
    360:   return(0);
    361: }

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

    368:    Collective

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

    378:    Output Parameter:
    379: . viewer - the PetscViewer

    381:    Format Options:
    382: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
    383: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

    385:    Options Database Keys:
    386: +  -draw_type - use x or null
    387: .  -nox - Disables all x-windows output
    388: .  -display <name> - Specifies name of machine for the X display
    389: .  -geometry <x,y,w,h> - allows setting the window location and size
    390: -  -draw_pause <pause> - Sets time (in seconds) that the
    391:      program pauses after PetscDrawPause() has been called
    392:      (0 is default, -1 implies until user input).

    394:    Level: beginner

    396:    Notes:
    397:      PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual pages for PetscDrawCreate()

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

    405: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
    406:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
    407: @*/
    408: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
    409: {

    413:   PetscViewerCreate(comm,viewer);
    414:   PetscViewerSetType(*viewer,PETSCVIEWERDRAW);
    415:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
    416:   return(0);
    417: }

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

    421: PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
    422: {
    423:   PetscErrorCode   ierr;
    424:   PetscMPIInt      rank;
    425:   PetscInt         i;
    426:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw;

    429:   if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous");
    430:   /* only processor zero can use the PetscViewer draw singleton */
    431:   if (sviewer) *sviewer = NULL;
    432:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    433:   if (rank == 0) {
    434:     PetscMPIInt flg;
    435:     PetscDraw   draw,sdraw;

    437:     MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
    438:     if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
    439:     PetscViewerCreate(comm,sviewer);
    440:     PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);
    441:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    442:     (*sviewer)->format = viewer->format;
    443:     for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
    444:       if (vdraw->draw[i]) {PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);}
    445:     }
    446:     PetscViewerDrawGetDraw(viewer,0,&draw);
    447:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
    448:     if (draw->savefilename) {
    449:       PetscDrawSetSave(sdraw,draw->savefilename);
    450:       sdraw->savefilecount = draw->savefilecount;
    451:       sdraw->savesinglefile = draw->savesinglefile;
    452:       sdraw->savemoviefps = draw->savemoviefps;
    453:       sdraw->saveonclear = draw->saveonclear;
    454:       sdraw->saveonflush = draw->saveonflush;
    455:     }
    456:     if (draw->savefinalfilename) {PetscDrawSetSaveFinalImage(sdraw,draw->savefinalfilename);}
    457:   } else {
    458:     PetscDraw draw;
    459:     PetscViewerDrawGetDraw(viewer,0,&draw);
    460:   }
    461:   vdraw->singleton_made = PETSC_TRUE;
    462:   return(0);
    463: }

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

    473:   if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
    474:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    475:   if (rank == 0) {
    476:     PetscDraw draw,sdraw;

    478:     PetscViewerDrawGetDraw(viewer,0,&draw);
    479:     PetscViewerDrawGetDraw(*sviewer,0,&sdraw);
    480:     if (draw->savefilename) {
    481:       draw->savefilecount = sdraw->savefilecount;
    482:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
    483:     }
    484:     svdraw = (PetscViewer_Draw*)(*sviewer)->data;
    485:     for (i=0; i<vdraw->draw_max; i++) {
    486:       if (vdraw->draw[i] && svdraw->draw[i]) {
    487:         PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);
    488:       }
    489:     }
    490:     PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);
    491:     PetscFree((*sviewer)->data);
    492:     PetscHeaderDestroy(sviewer);
    493:   } else {
    494:     PetscDraw draw;

    496:     PetscViewerDrawGetDraw(viewer,0,&draw);
    497:     if (draw->savefilename) {
    498:       MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));
    499:     }
    500:   }

    502:   vdraw->singleton_made = PETSC_FALSE;
    503:   return(0);
    504: }

    506: PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v)
    507: {
    509:   PetscReal      bounds[16];
    510:   PetscInt       nbounds = 16;
    511:   PetscBool      flg;

    514:   PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");
    515:   PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);
    516:   if (flg) {
    517:     PetscViewerDrawSetBounds(v,nbounds/2,bounds);
    518:   }
    519:   PetscOptionsTail();
    520:   return(0);
    521: }

    523: PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)
    524: {
    525:   PetscErrorCode   ierr;
    526:   PetscDraw        draw;
    527:   PetscInt         i;
    528:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

    531:   /*  If the PetscViewer has just been created then no vdraw->draw yet
    532:       exists so this will not actually call the viewer on any draws. */
    533:   for (i=0; i<vdraw->draw_base; i++) {
    534:     if (vdraw->draw[i]) {
    535:       PetscViewerDrawGetDraw(viewer,i,&draw);
    536:       PetscDrawView(draw,v);
    537:     }
    538:   }
    539:   return(0);
    540: }

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

    545: .seealso:  PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD,
    546:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY,
    547:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
    548:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

    550:   Level: beginner

    552: M*/
    553: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
    554: {
    555:   PetscErrorCode   ierr;
    556:   PetscViewer_Draw *vdraw;

    559:   PetscNewLog(viewer,&vdraw);
    560:   viewer->data = (void*)vdraw;

    562:   viewer->ops->flush            = PetscViewerFlush_Draw;
    563:   viewer->ops->view             = PetscViewerView_Draw;
    564:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
    565:   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
    566:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
    567:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;

    569:   /* these are created on the fly if requested */
    570:   vdraw->draw_max  = 5;
    571:   vdraw->draw_base = 0;
    572:   vdraw->w         = PETSC_DECIDE;
    573:   vdraw->h         = PETSC_DECIDE;

    575:   PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);
    576:   vdraw->singleton_made = PETSC_FALSE;
    577:   return(0);
    578: }

    580: /*@
    581:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

    583:     Not Collective

    585:     Input Parameter:
    586: .  viewer - the PetscViewer

    588:     Level: intermediate

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

    592: @*/
    593: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
    594: {
    595:   PetscErrorCode   ierr;
    596:   PetscViewer_Draw *vdraw;
    597:   PetscBool        isdraw;
    598:   PetscInt         i;

    602:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    603:   if (!isdraw) return(0);
    604:   vdraw = (PetscViewer_Draw*)viewer->data;

    606:   for (i=0; i<vdraw->draw_max; i++) {
    607:     if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
    608:   }
    609:   return(0);
    610: }

    612: /*@
    613:     PetscViewerDrawGetPause - Gets a pause for the first present draw

    615:     Not Collective

    617:     Input Parameter:
    618: .  viewer - the PetscViewer

    620:     Output Parameter:
    621: .  pause - the pause value

    623:     Level: intermediate

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

    627: @*/
    628: PetscErrorCode  PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause)
    629: {
    630:   PetscErrorCode   ierr;
    631:   PetscViewer_Draw *vdraw;
    632:   PetscBool        isdraw;
    633:   PetscInt         i;
    634:   PetscDraw        draw;

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

    642:   for (i=0; i<vdraw->draw_max; i++) {
    643:     if (vdraw->draw[i]) {
    644:       PetscDrawGetPause(vdraw->draw[i],pause);
    645:       return(0);
    646:     }
    647:   }
    648:   /* none exist yet so create one and get its pause */
    649:   PetscViewerDrawGetDraw(viewer,0,&draw);
    650:   PetscDrawGetPause(draw,pause);
    651:   return(0);
    652: }

    654: /*@
    655:     PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer

    657:     Not Collective

    659:     Input Parameters:
    660: +  viewer - the PetscViewer
    661: -  pause - the pause value

    663:     Level: intermediate

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

    667: @*/
    668: PetscErrorCode  PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)
    669: {
    670:   PetscErrorCode   ierr;
    671:   PetscViewer_Draw *vdraw;
    672:   PetscBool        isdraw;
    673:   PetscInt         i;

    677:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    678:   if (!isdraw) return(0);
    679:   vdraw = (PetscViewer_Draw*)viewer->data;

    681:   vdraw->pause = pause;
    682:   for (i=0; i<vdraw->draw_max; i++) {
    683:     if (vdraw->draw[i]) {PetscDrawSetPause(vdraw->draw[i],pause);}
    684:   }
    685:   return(0);
    686: }

    688: /*@
    689:     PetscViewerDrawSetHold - Holds previous image when drawing new image

    691:     Not Collective

    693:     Input Parameters:
    694: +  viewer - the PetscViewer
    695: -  hold - indicates to hold or not

    697:     Level: intermediate

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

    701: @*/
    702: PetscErrorCode  PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)
    703: {
    704:   PetscErrorCode   ierr;
    705:   PetscViewer_Draw *vdraw;
    706:   PetscBool        isdraw;

    710:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    711:   if (!isdraw) return(0);
    712:   vdraw = (PetscViewer_Draw*)viewer->data;

    714:   vdraw->hold = hold;
    715:   return(0);
    716: }

    718: /*@
    719:     PetscViewerDrawGetHold - Checks if holds previous image when drawing new image

    721:     Not Collective

    723:     Input Parameter:
    724: .  viewer - the PetscViewer

    726:     Output Parameter:
    727: .  hold - indicates to hold or not

    729:     Level: intermediate

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

    733: @*/
    734: PetscErrorCode  PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold)
    735: {
    736:   PetscErrorCode   ierr;
    737:   PetscViewer_Draw *vdraw;
    738:   PetscBool        isdraw;

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

    746:   *hold = vdraw->hold;
    747:   return(0);
    748: }

    750: /* ---------------------------------------------------------------------*/
    751: /*
    752:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
    753:   is attached to a communicator, in this case the attribute is a PetscViewer.
    754: */
    755: PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

    757: /*@C
    758:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
    759:                      in a communicator.

    761:      Collective

    763:      Input Parameter:
    764: .    comm - the MPI communicator to share the window PetscViewer

    766:      Level: intermediate

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

    773: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
    774: @*/
    775: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
    776: {
    778:   PetscMPIInt    flag;
    779:   PetscViewer    viewer;
    780:   MPI_Comm       ncomm;

    783:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
    784:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
    785:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,NULL);
    786:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
    787:   }
    788:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag);
    789:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
    790:   if (!flag) { /* PetscViewer not yet created */
    791:     PetscViewerDrawOpen(ncomm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
    792:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
    793:     PetscObjectRegisterDestroy((PetscObject)viewer);
    794:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
    795:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer);
    796:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
    797:   }
    798:   PetscCommDestroy(&ncomm);
    799:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
    800:   PetscFunctionReturn(viewer);
    801: }

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

    806:     Collective on PetscViewer

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

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

    816:     Level: intermediate

    818:     Notes:
    819:     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
    820:       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
    821:       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.

    823: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    824: @*/
    825: PetscErrorCode  PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds)
    826: {
    827:   PetscViewer_Draw *vdraw;
    828:   PetscBool        isdraw;
    829:   PetscErrorCode   ierr;

    833:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    834:   if (!isdraw) return(0);
    835:   vdraw = (PetscViewer_Draw*)viewer->data;

    837:   vdraw->nbounds = nbounds;
    838:   PetscFree(vdraw->bounds);
    839:   PetscMalloc1(2*nbounds,&vdraw->bounds);
    840:   PetscArraycpy(vdraw->bounds,bounds,2*nbounds);
    841:   return(0);
    842: }

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

    847:     Collective on PetscViewer

    849:     Input Parameter:
    850: .   viewer - the PetscViewer (created with PetscViewerDrawOpen())

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

    856:     Level: intermediate

    858: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds()
    859: @*/
    860: PetscErrorCode  PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds)
    861: {
    862:   PetscViewer_Draw *vdraw;
    863:   PetscBool        isdraw;
    864:   PetscErrorCode   ierr;

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

    872:   if (nbounds) *nbounds = vdraw->nbounds;
    873:   if (bounds)  *bounds  = vdraw->bounds;
    874:   return(0);
    875: }