Date: 2013-07-02T14:38:31+00:00

Actual source code: lgc.c
petsc-3.4.2 2013-07-02

      2: #include <../src/sys/classes/draw/utils/lgimpl.h>  /*I   "petscdraw.h"  I*/
      3: #include <petscviewer.h>
      4: PetscClassId PETSC_DRAWLG_CLASSID = 0;

      8: /*@
      9:    PetscDrawLGGetAxis - Gets the axis context associated with a line graph.
     10:    This is useful if one wants to change some axis property, such as
     11:    labels, color, etc. The axis context should not be destroyed by the
     12:    application code.

     14:    Not Collective, if PetscDrawLG is parallel then PetscDrawAxis is parallel

     16:    Input Parameter:
     17: .  lg - the line graph context

     19:    Output Parameter:
     20: .  axis - the axis context

     22:    Level: advanced

     24: @*/
     25: PetscErrorCode  PetscDrawLGGetAxis(PetscDrawLG lg,PetscDrawAxis *axis)
     26: {
     28:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) {
     29:     *axis = 0;
     30:     return(0);
     31:   }
     34:   *axis = lg->axis;
     35:   return(0);
     36: }

     40: /*@
     41:    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.

     43:    Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel

     45:    Input Parameter:
     46: .  lg - the line graph context

     48:    Output Parameter:
     49: .  draw - the draw context

     51:    Level: intermediate

     53: @*/
     54: PetscErrorCode  PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw)
     55: {
     59:   if (((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) *draw = (PetscDraw)lg;
     60:   else {
     62:     *draw = lg->win;
     63:   }
     64:   return(0);
     65: }

     70: /*@
     71:    PetscDrawLGSPDraw - Redraws a line graph.

     73:    Not Collective,but ignored by all processors except processor 0 in PetscDrawLG

     75:    Input Parameter:
     76: .  lg - the line graph context

     78:    Level: intermediate

     80: .seealso: PetscDrawLGDraw(), PetscDrawSPDraw()

     82:    Developer Notes: This code cheats and uses the fact that the LG and SP structs are the same

     84: @*/
     85: PetscErrorCode  PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)
     86: {
     87:   PetscDrawLG    sp = (PetscDrawLG)spin;
     88:   PetscReal      xmin,xmax,ymin,ymax;
     90:   int            i,j,dim,nopts,rank;
     91:   PetscDraw      draw = lg->win;

     94:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);

     98:   xmin = PetscMin(lg->xmin,sp->xmin);
     99:   ymin = PetscMin(lg->ymin,sp->ymin);
    100:   xmax = PetscMax(lg->xmax,sp->xmax);
    101:   ymax = PetscMax(lg->ymax,sp->ymax);

    103:   PetscDrawClear(draw);
    104:   PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);
    105:   PetscDrawAxisDraw(lg->axis);

    107:   MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);
    108:   if (!rank) {

    110:     dim   = lg->dim;
    111:     nopts = lg->nopts;
    112:     for (i=0; i<dim; i++) {
    113:       for (j=1; j<nopts; j++) {
    114:         PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_BLACK+i);
    115:         if (lg->use_dots) {
    116:           PetscDrawString(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED,"x");
    117:         }
    118:       }
    119:     }

    121:     dim   = sp->dim;
    122:     nopts = sp->nopts;
    123:     for (i=0; i<dim; i++) {
    124:       for (j=0; j<nopts; j++) {
    125:         PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");
    126:       }
    127:     }
    128:   }
    129:   PetscDrawFlush(lg->win);
    130:   PetscDrawPause(lg->win);
    131:   return(0);
    132: }

    137: /*@
    138:     PetscDrawLGCreate - Creates a line graph data structure.

    140:     Collective over PetscDraw

    142:     Input Parameters:
    143: +   draw - the window where the graph will be made.
    144: -   dim - the number of curves which will be drawn

    146:     Output Parameters:
    147: .   outctx - the line graph context

    149:     Level: intermediate

    151:     Concepts: line graph^creating

    153: .seealso:  PetscDrawLGDestroy()
    154: @*/
    155: PetscErrorCode  PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG *outctx)
    156: {
    158:   PetscBool      isnull;
    159:   PetscObject    obj = (PetscObject)draw;
    160:   PetscDrawLG    lg;

    165:   PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
    166:   if (isnull) {
    167:     PetscDrawOpenNull(PetscObjectComm((PetscObject)obj),(PetscDraw*)outctx);
    168:     return(0);
    169:   }
    170:   PetscHeaderCreate(lg,_p_PetscDrawLG,int,PETSC_DRAWLG_CLASSID,"PetscDrawLG","Line graph","Draw",PetscObjectComm((PetscObject)obj),PetscDrawLGDestroy,0);

    172:   lg->view    = 0;
    173:   lg->destroy = 0;
    174:   lg->nopts   = 0;
    175:   lg->win     = draw;
    176:   lg->dim     = dim;
    177:   lg->xmin    = 1.e20;
    178:   lg->ymin    = 1.e20;
    179:   lg->xmax    = -1.e20;
    180:   lg->ymax    = -1.e20;

    182:   PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&lg->x,dim*CHUNCKSIZE,PetscReal,&lg->y);
    183:   PetscLogObjectMemory(lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));

    185:   lg->len     = dim*CHUNCKSIZE;
    186:   lg->loc     = 0;
    187:   lg->use_dots= PETSC_FALSE;

    189:   PetscDrawAxisCreate(draw,&lg->axis);
    190:   PetscLogObjectParent(lg,lg->axis);

    192:   *outctx = lg;
    193:   return(0);
    194: }

    198: /*@
    199:    PetscDrawLGSetColors - Sets the color of each line graph drawn

    201:    Logically Collective over PetscDrawLG

    203:    Input Parameter:
    204: +  lg - the line graph context.
    205: -  colors - the colors

    207:    Level: intermediate

    209:    Concepts: line graph^setting number of lines

    211: @*/
    212: PetscErrorCode  PetscDrawLGSetColors(PetscDrawLG lg,const int *colors)
    213: {

    217:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);
    219:   PetscFree(lg->colors);
    220:   PetscMalloc(lg->dim*sizeof(int),&lg->colors);
    221:   PetscMemcpy(lg->colors,colors,lg->dim*sizeof(int));
    222:   return(0);
    223: }

    228: /*@C
    229:    PetscDrawLGSetLegend - sets the names of each curve plotted

    231:    Logically Collective over PetscDrawLG

    233:    Input Parameter:
    234: +  lg - the line graph context.
    235: -  names - the names for each curve

    237:    Level: intermediate

    239:    Concepts: line graph^setting number of lines

    241: @*/
    242: PetscErrorCode  PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names)
    243: {
    245:   PetscInt       i;

    248:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);

    251:   if (lg->legend) {
    252:     for (i=0; i<lg->dim; i++) {
    253:       PetscFree(lg->legend[i]);
    254:     }
    255:     PetscFree(lg->legend);
    256:   }
    257:   if (names) {
    258:     PetscMalloc(lg->dim*sizeof(char**),&lg->legend);
    259:     for (i=0; i<lg->dim; i++) {
    260:       PetscStrallocpy(names[i],&lg->legend[i]);
    261:     }
    262:   }
    263:   return(0);
    264: }

    268: /*@
    269:    PetscDrawLGGetDimension - Change the number of lines that are to be drawn.

    271:    Logically Collective over PetscDrawLG

    273:    Input Parameter:
    274: .  lg - the line graph context.

    276:    Output Parameter:
    277: .  dim - the number of curves.

    279:    Level: intermediate

    281:    Concepts: line graph^setting number of lines

    283: @*/
    284: PetscErrorCode  PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim)
    285: {
    287:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);
    289:   *dim = lg->dim;
    290:   return(0);
    291: }

    295: /*@
    296:    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.

    298:    Logically Collective over PetscDrawLG

    300:    Input Parameter:
    301: +  lg - the line graph context.
    302: -  dim - the number of curves.

    304:    Level: intermediate

    306:    Concepts: line graph^setting number of lines

    308: @*/
    309: PetscErrorCode  PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim)
    310: {
    312:   PetscInt       i;

    315:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);
    318:   if (lg->dim == dim) return(0);

    320:   PetscFree2(lg->x,lg->y);
    321:   if (lg->legend) {
    322:     for (i=0; i<lg->dim; i++) {
    323:       PetscFree(lg->legend[i]);
    324:     }
    325:     PetscFree(lg->legend);
    326:   }
    327:   PetscFree(lg->colors);
    328:   lg->dim = dim;
    329:   PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&lg->x,dim*CHUNCKSIZE,PetscReal,&lg->y);
    330:   PetscLogObjectMemory(lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));
    331:   lg->len = dim*CHUNCKSIZE;
    332:   return(0);
    333: }

    337: /*@
    338:    PetscDrawLGReset - Clears line graph to allow for reuse with new data.

    340:    Logically Collective over PetscDrawLG

    342:    Input Parameter:
    343: .  lg - the line graph context.

    345:    Level: intermediate

    347:    Concepts: line graph^restarting

    349: @*/
    350: PetscErrorCode  PetscDrawLGReset(PetscDrawLG lg)
    351: {
    353:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);
    355:   lg->xmin  = 1.e20;
    356:   lg->ymin  = 1.e20;
    357:   lg->xmax  = -1.e20;
    358:   lg->ymax  = -1.e20;
    359:   lg->loc   = 0;
    360:   lg->nopts = 0;
    361:   return(0);
    362: }

    366: /*@
    367:    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.

    369:    Collective over PetscDrawLG

    371:    Input Parameter:
    372: .  lg - the line graph context

    374:    Level: intermediate

    376: .seealso:  PetscDrawLGCreate()
    377: @*/
    378: PetscErrorCode  PetscDrawLGDestroy(PetscDrawLG *lg)
    379: {
    381:   PetscInt       i;

    384:   if (!*lg) return(0);

    387:   if (--((PetscObject)(*lg))->refct > 0) {*lg = 0; return(0);}
    388:   if (((PetscObject)(*lg))->classid == PETSC_DRAW_CLASSID) {
    389:     PetscObjectDestroy((PetscObject*)lg);
    390:     return(0);
    391:   }
    392:   if ((*lg)->legend) {
    393:     for (i=0; i<(*lg)->dim; i++) {
    394:       PetscFree((*lg)->legend[i]);
    395:     }
    396:     PetscFree((*lg)->legend);
    397:   }
    398:   PetscFree((*lg)->colors);
    399:   PetscDrawAxisDestroy(&(*lg)->axis);
    400:   PetscFree2((*lg)->x,(*lg)->y);
    401:   PetscHeaderDestroy(lg);
    402:   return(0);
    403: }
    406: /*@
    407:    PetscDrawLGIndicateDataPoints - Causes LG to draw a big dot for each data-point.

    409:    Not Collective, but ignored by all processors except processor 0 in PetscDrawLG

    411:    Input Parameters:
    412: .  lg - the linegraph context

    414:    Level: intermediate

    416:    Concepts: line graph^showing points

    418: @*/
    419: PetscErrorCode  PetscDrawLGIndicateDataPoints(PetscDrawLG lg)
    420: {
    422:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);

    424:   lg->use_dots = PETSC_TRUE;
    425:   return(0);
    426: }

    428: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
    429: #include <X11/Xlib.h>
    430: #include <X11/Xutil.h>
    431: #include <setjmp.h>
    432: static jmp_buf PetscXIOErrorJumpBuf;
    433: static void PetscXIOHandler(Display *dpy)
    434: {
    435:   longjmp(PetscXIOErrorJumpBuf, 1);
    436: }
    437: #endif

    441: /*@
    442:    PetscDrawLGDraw - Redraws a line graph.

    444:    Not Collective,but ignored by all processors except processor 0 in PetscDrawLG

    446:    Input Parameter:
    447: .  lg - the line graph context

    449:    Level: intermediate

    451: .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw()

    453: @*/
    454: PetscErrorCode  PetscDrawLGDraw(PetscDrawLG lg)
    455: {
    456:   PetscReal      xmin=lg->xmin,xmax=lg->xmax,ymin=lg->ymin,ymax=lg->ymax;
    458:   int            i,j,dim = lg->dim,nopts = lg->nopts,rank,cl;
    459:   PetscDraw      draw = lg->win;
    460:   PetscBool      isnull;

    463:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);
    465:   PetscDrawIsNull(lg->win,&isnull);
    466:   if (isnull) return(0);

    468: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
    469:   if (!setjmp(PetscXIOErrorJumpBuf)) XSetIOErrorHandler((XIOErrorHandler)PetscXIOHandler);
    470:   else {
    471:     XSetIOErrorHandler(NULL);
    472:     PetscDrawSetType(draw,PETSC_DRAW_NULL);
    473:     return(0);
    474:   }
    475: #endif

    477:   PetscDrawCheckResizedWindow(draw);
    478:   PetscDrawClear(draw);
    479:   PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);
    480:   PetscDrawAxisDraw(lg->axis);

    482:   MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);
    483:   if (!rank) {

    485:     for (i=0; i<dim; i++) {
    486:       for (j=1; j<nopts; j++) {
    487:         if (lg->colors) cl = lg->colors[i];
    488:         else cl = PETSC_DRAW_BLACK+i;
    489:         PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],cl);
    490:         if (lg->use_dots) {
    491:           PetscDrawString(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl,"x");
    492:         }
    493:       }
    494:     }
    495:   }
    496:   if (lg->legend) {
    497:     PetscReal xl,yl,xr,yr,tw,th;
    498:     size_t    len,mlen = 0;
    499:     int       cl;
    500:     PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);
    501:     PetscDrawStringGetSize(draw,&tw,&th);
    502:     for (i=0; i<dim; i++) {
    503:       PetscStrlen(lg->legend[i],&len);
    504:       mlen = PetscMax(mlen,len);
    505:     }
    506:     PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - 2*tw,yr - 3*th,PETSC_DRAW_BLACK);
    507:     PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);
    508:     for  (i=0; i<dim; i++) {
    509:       cl   = (lg->colors ? lg->colors[i] : i + 1);
    510:       PetscDrawLine(draw,xr - (mlen + 6.7)*tw,yr - (4 + i)*th,xr - (mlen + 3.2)*tw,yr - (4 + i)*th,cl);
    511:       PetscDrawString(draw,xr - (mlen + 3)*tw,yr - (4.5 + i)*th,PETSC_DRAW_BLACK,lg->legend[i]);
    512:     }
    513:     PetscDrawLine(draw,xr - 2*tw,yr - 3*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);
    514:     PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);
    515:   }
    516:   PetscDrawFlush(lg->win);
    517:   PetscDrawPause(lg->win);
    518: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
    519:   XSetIOErrorHandler(NULL);
    520: #endif
    521:   return(0);
    522: }

    526: /*@
    527:   PetscDrawLGView - Prints a line graph.

    529:   Not collective

    531:   Input Parameter:
    532: . lg - the line graph context

    534:   Level: beginner

    536: .keywords:  draw, line, graph
    537: @*/
    538: PetscErrorCode  PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)
    539: {
    540:   PetscReal      xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax;
    541:   PetscInt       i, j, dim = lg->dim, nopts = lg->nopts;

    545:   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) return(0);
    547:   if (nopts < 1)                  return(0);
    548:   if (xmin > xmax || ymin > ymax) return(0);

    550:   if (!viewer){
    551:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);
    552:   }
    553:   for (i = 0; i < dim; i++) {
    554:     PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);
    555:     for (j = 0; j < nopts; j++) {
    556:       PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);
    557:     }
    558:   }
    559:   return(0);
    560: }