Actual source code: drawv.c

      1: #define PETSC_DLL

     3:  #include src/sys/src/viewer/impls/draw/vdraw.h

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

     14:   if (vdraw->singleton_made) {
     15:     SETERRQ(PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton");
     16:   }
     17:   for (i=0; i<vdraw->draw_max; i++) {
     18:     if (vdraw->drawaxis[i]) {PetscDrawAxisDestroy(vdraw->drawaxis[i]);}
     19:     if (vdraw->drawlg[i])   {PetscDrawLGDestroy(vdraw->drawlg[i]);}
     20:     if (vdraw->draw[i])     {PetscDrawDestroy(vdraw->draw[i]);}
     21:   }

     23:   PetscFree(vdraw->drawaxis);
     24:   PetscFree(vdraw->drawlg);
     25:   PetscFree(vdraw->draw);
     26:   PetscFree(vdraw);
     27:   return(0);
     28: }

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

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

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

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

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

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

     61:     Level: intermediate

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

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

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

     92:      vdraw->draw_max = 2*windownumber;
     93:      PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
     94:      PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
     95:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
     96:      PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
     97:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
     98:      PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));

    100:      PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
    101:      PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
    102:      PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));

    104:      PetscFree(tdraw);
    105:      PetscFree(drawlg);
    106:      PetscFree(drawaxis);
    107:   }

    109:   if (!vdraw->draw[windownumber]) {
    110:     if (vdraw->draw[0]) {
    111:       PetscDrawGetTitle(vdraw->draw[0],&title);
    112:     } else title = 0;
    113:     PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
    114:                      &vdraw->draw[windownumber]);
    115:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
    116:   }
    117:   *draw = vdraw->draw[windownumber];
    118:   return(0);
    119: }

    123: /*@C
    124:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
    125:     This PetscDrawLG object may then be used to perform graphics using
    126:     PetscDrawLGXXX() commands.

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

    130:     Input Parameter:
    131: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
    132: -   windownumber - indicates which subwindow (usually 0)

    134:     Ouput Parameter:
    135: .   draw - the draw line graph object

    137:     Level: intermediate

    139:   Concepts: line graph^accessing context

    141: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
    142: @*/
    143: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
    144: {
    145:   PetscErrorCode   ierr;
    146:   PetscTruth       isdraw;
    147:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

    152:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
    153:   if (!isdraw) {
    154:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
    155:   }
    156:   if (windownumber < 0) {
    157:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
    158:   }
    159:   if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
    160:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
    161:   }

    163:   if (!vdraw->drawlg[windownumber]) {
    164:     PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
    165:     PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
    166:   }
    167:   *drawlg = vdraw->drawlg[windownumber];
    168:   return(0);
    169: }

    173: /*@C
    174:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
    175:     This PetscDrawAxis object may then be used to perform graphics using
    176:     PetscDrawAxisXXX() commands.

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

    180:     Input Parameter:
    181: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
    182: -   windownumber - indicates which subwindow (usually 0)

    184:     Ouput Parameter:
    185: .   drawaxis - the draw axis object

    187:     Level: advanced

    189:   Concepts: line graph^accessing context

    191: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
    192: @*/
    193: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
    194: {
    195:   PetscErrorCode   ierr;
    196:   PetscTruth       isdraw;
    197:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;

    202:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
    203:   if (!isdraw) {
    204:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
    205:   }
    206:   if (windownumber < 0) {
    207:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
    208:   }
    209:   if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
    210:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
    211:   }

    213:   if (!vdraw->drawaxis[windownumber]) {
    214:     PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
    215:     PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
    216:   }
    217:   *drawaxis = vdraw->drawaxis[windownumber];
    218:   return(0);
    219: }

    223: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
    224: {
    225:   PetscErrorCode   ierr;
    226:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

    229:   vdraw->h  = h;
    230:   vdraw->w  = w;
    231:   PetscStrallocpy(display,&vdraw->display);
    232:   PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
    233:   PetscDrawSetFromOptions(vdraw->draw[0]);
    234:   PetscLogObjectParent(v,vdraw->draw[0]);
    235:   return(0);
    236: }

    240: /*@C
    241:    PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to
    242:    do graphics in this window, you must call PetscViewerDrawGetDraw() and
    243:    perform the graphics on the PetscDraw object.

    245:    Collective on MPI_Comm

    247:    Input Parameters:
    248: +  comm - communicator that will share window
    249: .  display - the X display on which to open, or null for the local machine
    250: .  title - the title to put in the title bar, or null for no title
    251: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
    252: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
    253:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

    255:    Output Parameters:
    256: . viewer - the PetscViewer

    258:    Format Options:
    259: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
    260: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

    262:    Options Database Keys:
    263:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
    264:    PetscDrawCreate() for runtime options, including
    265: +  -draw_type x or null
    266: .  -nox - Disables all x-windows output
    267: .  -display <name> - Specifies name of machine for the X display
    268: .  -geometry <x,y,w,h> - allows setting the window location and size
    269: -  -draw_pause <pause> - Sets time (in seconds) that the
    270:      program pauses after PetscDrawPause() has been called
    271:      (0 is default, -1 implies until user input).

    273:    Level: beginner

    275:    Note for Fortran Programmers:
    276:    Whenever indicating null character data in a Fortran code,
    277:    PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
    278:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
    279:    used for the display and title input parameters.

    281:   Concepts: graphics^opening PetscViewer
    282:   Concepts: drawing^opening PetscViewer

    285: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
    286:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
    287: @*/
    288: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
    289: {

    293:   PetscViewerCreate(comm,viewer);
    294:   PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
    295:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
    296:   return(0);
    297: }

    301: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
    302: {
    303:   PetscErrorCode   ierr;
    304:   PetscMPIInt      rank;
    305:   int              i;
    306:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

    309:   if (vdraw->singleton_made) {
    310:     SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
    311:   }

    313:   /* only processor zero can use the PetscViewer draw singleton */
    314:   MPI_Comm_rank(viewer->comm,&rank);
    315:   if (!rank) {
    316:     PetscViewerCreate(PETSC_COMM_SELF,sviewer);
    317:     PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
    318:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
    319:     for (i=0; i<vdraw->draw_max; i++) {
    320:       if (vdraw->draw[i]) {
    321:         PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
    322:       }
    323:     }
    324:   }
    325:   vdraw->singleton_made = PETSC_TRUE;
    326:   return(0);
    327: }

    331: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
    332: {
    333:   PetscErrorCode   ierr;
    334:   PetscMPIInt      rank;
    335:   int              i;
    336:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

    339:   if (!vdraw->singleton_made) {
    340:     SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
    341:   }
    342:   MPI_Comm_rank(viewer->comm,&rank);
    343:   if (!rank) {
    344:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
    345:     for (i=0; i<vdraw->draw_max; i++) {
    346:       if (vdraw->draw[i] && vsdraw->draw[i]) {
    347:          PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
    348:       }
    349:     }
    350:     PetscFree(vsdraw->drawaxis);
    351:     PetscFree(vsdraw->drawlg);
    352:     PetscFree(vsdraw->draw);
    353:     PetscFree((*sviewer)->data);
    354:     PetscHeaderDestroy(*sviewer);
    355:   }
    356:   vdraw->singleton_made = PETSC_FALSE;
    357:   return(0);
    358: }

    363: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_Draw(PetscViewer viewer)
    364: {
    365:   int              i;
    366:   PetscErrorCode   ierr;
    367:   PetscViewer_Draw *vdraw;

    370:   PetscNew(PetscViewer_Draw,&vdraw);
    371:   viewer->data = (void*)vdraw;

    373:   viewer->ops->flush            = PetscViewerFlush_Draw;
    374:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
    375:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
    376:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
    377:   viewer->format                = PETSC_VIEWER_NOFORMAT;

    379:   /* these are created on the fly if requested */
    380:   vdraw->draw_max = 5;
    381:   PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
    382:   PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
    383:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
    384:   PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
    385:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
    386:   PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
    387:   for (i=0; i<vdraw->draw_max; i++) {
    388:     vdraw->draw[i]     = 0;
    389:     vdraw->drawlg[i]   = 0;
    390:     vdraw->drawaxis[i] = 0;
    391:   }
    392:   vdraw->singleton_made = PETSC_FALSE;
    393:   return(0);
    394: }

    399: /*@
    400:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

    402:     Not Collective

    404:     Input Parameter:
    405: .  viewer - the PetscViewer

    407:     Level: intermediate

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

    411: @*/
    412: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawClear(PetscViewer viewer)
    413: {
    414:   PetscErrorCode   ierr;
    415:   int              i;
    416:   PetscTruth       isdraw;
    417:   PetscViewer_Draw *vdraw;

    420:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
    421:   if (isdraw) {
    422:     vdraw = (PetscViewer_Draw*)viewer->data;
    423:     for (i=0; i<vdraw->draw_max; i++) {
    424:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
    425:     }
    426:   }
    427:   return(0);
    428: }

    430: /* ---------------------------------------------------------------------*/
    431: /*
    432:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
    433:   is attached to a communicator, in this case the attribute is a PetscViewer.
    434: */
    435: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

    439: /*@C
    440:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors
    441:                      in a communicator.

    443:      Collective on MPI_Comm

    445:      Input Parameter:
    446: .    comm - the MPI communicator to share the window PetscViewer

    448:      Level: intermediate

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

    455: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(),
    456: @*/
    457: PetscViewer PETSC_DLLEXPORT PETSC_VIEWER_DRAW_(MPI_Comm comm)
    458: {
    460:   int            flag;
    461:   PetscViewer    viewer;

    464:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
    465:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
    466:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
    467:   }
    468:   MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
    469:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
    470:   if (!flag) { /* PetscViewer not yet created */
    471:     PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
    472:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
    473:     PetscObjectRegisterDestroy((PetscObject)viewer);
    474:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
    475:     MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
    476:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
    477:   }
    478:   PetscFunctionReturn(viewer);
    479: }