Actual source code: lgc.c
 
   petsc-3.7.7 2017-09-25
   
  2: #include <petscviewer.h>
  3: #include <../src/sys/classes/draw/utils/lgimpl.h>  /*I   "petscdraw.h"  I*/
  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: {
 30:   *axis = lg->axis;
 31:   return(0);
 32: }
 36: /*@
 37:    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
 39:    Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel
 41:    Input Parameter:
 42: .  lg - the line graph context
 44:    Output Parameter:
 45: .  draw - the draw context
 47:    Level: intermediate
 49: @*/
 50: PetscErrorCode  PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw)
 51: {
 55:   *draw = lg->win;
 56:   return(0);
 57: }
 62: /*@
 63:    PetscDrawLGSPDraw - Redraws a line graph.
 65:    Collective on PetscDrawLG
 67:    Input Parameter:
 68: .  lg - the line graph context
 70:    Level: intermediate
 72: .seealso: PetscDrawLGDraw(), PetscDrawSPDraw()
 74:    Developer Notes: This code cheats and uses the fact that the LG and SP structs are the same
 76: @*/
 77: PetscErrorCode  PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)
 78: {
 79:   PetscDrawLG    sp = (PetscDrawLG)spin;
 80:   PetscReal      xmin,xmax,ymin,ymax;
 82:   PetscBool      isnull;
 83:   PetscMPIInt    rank;
 84:   PetscDraw      draw;
 89:   PetscDrawIsNull(lg->win,&isnull);
 90:   if (isnull) return(0);
 91:   MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);
 93:   draw = lg->win;
 94:   PetscDrawCheckResizedWindow(draw);
 95:   PetscDrawClear(draw);
 97:   xmin = PetscMin(lg->xmin,sp->xmin); ymin = PetscMin(lg->ymin,sp->ymin);
 98:   xmax = PetscMax(lg->xmax,sp->xmax); ymax = PetscMax(lg->ymax,sp->ymax);
 99:   PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);
100:   PetscDrawAxisDraw(lg->axis);
102:   PetscDrawCollectiveBegin(draw);
103:   if (!rank) {
104:     int i,j,dim,nopts;
105:     dim   = lg->dim;
106:     nopts = lg->nopts;
107:     for (i=0; i<dim; i++) {
108:       for (j=1; j<nopts; j++) {
109:         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);
110:         if (lg->use_markers) {
111:           PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED);
112:         }
113:       }
114:     }
115:     dim   = sp->dim;
116:     nopts = sp->nopts;
117:     for (i=0; i<dim; i++) {
118:       for (j=0; j<nopts; j++) {
119:         PetscDrawMarker(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);
120:       }
121:     }
122:   }
123:   PetscDrawCollectiveEnd(draw);
125:   PetscDrawFlush(draw);
126:   PetscDrawPause(draw);
127:   return(0);
128: }
133: /*@
134:     PetscDrawLGCreate - Creates a line graph data structure.
136:     Collective on PetscDraw
138:     Input Parameters:
139: +   draw - the window where the graph will be made.
140: -   dim - the number of curves which will be drawn
142:     Output Parameters:
143: .   outlg - the line graph context
145:     Level: intermediate
147:     Concepts: line graph^creating
149: .seealso:  PetscDrawLGDestroy()
150: @*/
151: PetscErrorCode  PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG *outlg)
152: {
153:   PetscDrawLG    lg;
161:   PetscHeaderCreate(lg,PETSC_DRAWLG_CLASSID,"DrawLG","Line Graph","Draw",PetscObjectComm((PetscObject)draw),PetscDrawLGDestroy,NULL);
162:   PetscLogObjectParent((PetscObject)draw,(PetscObject)lg);
163:   PetscDrawLGSetOptionsPrefix(lg,((PetscObject)draw)->prefix);
165:   PetscObjectReference((PetscObject)draw);
166:   lg->win = draw;
168:   lg->view    = NULL;
169:   lg->destroy = NULL;
170:   lg->nopts   = 0;
171:   lg->dim     = dim;
172:   lg->xmin    = 1.e20;
173:   lg->ymin    = 1.e20;
174:   lg->xmax    = -1.e20;
175:   lg->ymax    = -1.e20;
177:   PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);
178:   PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));
180:   lg->len         = dim*CHUNCKSIZE;
181:   lg->loc         = 0;
182:   lg->use_markers = PETSC_FALSE;
184:   PetscDrawAxisCreate(draw,&lg->axis);
185:   PetscLogObjectParent((PetscObject)lg,(PetscObject)lg->axis);
187:   *outlg = lg;
188:   return(0);
189: }
193: /*@
194:    PetscDrawLGSetColors - Sets the color of each line graph drawn
196:    Logically Collective on PetscDrawLG
198:    Input Parameter:
199: +  lg - the line graph context.
200: -  colors - the colors
202:    Level: intermediate
204:    Concepts: line graph^setting number of lines
206: @*/
207: PetscErrorCode  PetscDrawLGSetColors(PetscDrawLG lg,const int colors[])
208: {
215:   PetscFree(lg->colors);
216:   PetscMalloc1(lg->dim,&lg->colors);
217:   PetscMemcpy(lg->colors,colors,lg->dim*sizeof(int));
218:   return(0);
219: }
224: /*@C
225:    PetscDrawLGSetLegend - sets the names of each curve plotted
227:    Logically Collective on PetscDrawLG
229:    Input Parameter:
230: +  lg - the line graph context.
231: -  names - the names for each curve
233:    Level: intermediate
235:    Concepts: line graph^setting number of lines
237: @*/
238: PetscErrorCode  PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names)
239: {
241:   PetscInt       i;
247:   if (lg->legend) {
248:     for (i=0; i<lg->dim; i++) {
249:       PetscFree(lg->legend[i]);
250:     }
251:     PetscFree(lg->legend);
252:   }
253:   if (names) {
254:     PetscMalloc1(lg->dim,&lg->legend);
255:     for (i=0; i<lg->dim; i++) {
256:       PetscStrallocpy(names[i],&lg->legend[i]);
257:     }
258:   }
259:   return(0);
260: }
264: /*@
265:    PetscDrawLGGetDimension - Change the number of lines that are to be drawn.
267:    Not Collective
269:    Input Parameter:
270: .  lg - the line graph context.
272:    Output Parameter:
273: .  dim - the number of curves.
275:    Level: intermediate
277:    Concepts: line graph^setting number of lines
279: @*/
280: PetscErrorCode  PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim)
281: {
285:   *dim = lg->dim;
286:   return(0);
287: }
291: /*@
292:    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.
294:    Logically Collective on PetscDrawLG
296:    Input Parameter:
297: +  lg - the line graph context.
298: -  dim - the number of curves.
300:    Level: intermediate
302:    Concepts: line graph^setting number of lines
304: @*/
305: PetscErrorCode  PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim)
306: {
308:   PetscInt       i;
313:   if (lg->dim == dim) return(0);
315:   PetscFree2(lg->x,lg->y);
316:   if (lg->legend) {
317:     for (i=0; i<lg->dim; i++) {
318:       PetscFree(lg->legend[i]);
319:     }
320:     PetscFree(lg->legend);
321:   }
322:   PetscFree(lg->colors);
323:   lg->dim = dim;
324:   PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);
325:   PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));
326:   lg->len = dim*CHUNCKSIZE;
327:   return(0);
328: }
333: /*@
334:    PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
335:    points are added after this call, the limits will be adjusted to
336:    include those additional points.
338:    Logically Collective on PetscDrawLG
340:    Input Parameters:
341: +  xlg - the line graph context
342: -  x_min,x_max,y_min,y_max - the limits
344:    Level: intermediate
346:    Concepts: line graph^setting axis
348: @*/
349: PetscErrorCode  PetscDrawLGSetLimits(PetscDrawLG lg,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
350: {
354:   (lg)->xmin = x_min;
355:   (lg)->xmax = x_max;
356:   (lg)->ymin = y_min;
357:   (lg)->ymax = y_max;
358:   return(0);
359: }
363: /*@
364:    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
366:    Logically Collective on PetscDrawLG
368:    Input Parameter:
369: .  lg - the line graph context.
371:    Level: intermediate
373:    Concepts: line graph^restarting
375: @*/
376: PetscErrorCode  PetscDrawLGReset(PetscDrawLG lg)
377: {
380:   lg->xmin  = 1.e20;
381:   lg->ymin  = 1.e20;
382:   lg->xmax  = -1.e20;
383:   lg->ymax  = -1.e20;
384:   lg->loc   = 0;
385:   lg->nopts = 0;
386:   return(0);
387: }
391: /*@
392:    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
394:    Collective on PetscDrawLG
396:    Input Parameter:
397: .  lg - the line graph context
399:    Level: intermediate
401: .seealso:  PetscDrawLGCreate()
402: @*/
403: PetscErrorCode  PetscDrawLGDestroy(PetscDrawLG *lg)
404: {
406:   PetscInt       i;
409:   if (!*lg) return(0);
411:   if (--((PetscObject)(*lg))->refct > 0) {*lg = NULL; return(0);}
413:   if ((*lg)->legend) {
414:     for (i=0; i<(*lg)->dim; i++) {
415:       PetscFree((*lg)->legend[i]);
416:     }
417:     PetscFree((*lg)->legend);
418:   }
419:   PetscFree((*lg)->colors);
420:   PetscFree2((*lg)->x,(*lg)->y);
421:   PetscDrawAxisDestroy(&(*lg)->axis);
422:   PetscDrawDestroy(&(*lg)->win);
423:   PetscHeaderDestroy(lg);
424:   return(0);
425: }
428: /*@
429:    PetscDrawLGSetUseMarkers - Causes LG to draw a marker for each data-point.
431:    Logically Collective on PetscDrawLG
433:    Input Parameters:
434: +  lg - the linegraph context
435: -  flg - should mark each data point
437:    Options Database:
438: .  -lg_use_markers  <true,false>
440:    Level: intermediate
442:    Concepts: line graph^showing points
444: @*/
445: PetscErrorCode  PetscDrawLGSetUseMarkers(PetscDrawLG lg,PetscBool flg)
446: {
450:   lg->use_markers = flg;
451:   return(0);
452: }
456: /*@
457:    PetscDrawLGDraw - Redraws a line graph.
459:    Collective on PetscDrawLG
461:    Input Parameter:
462: .  lg - the line graph context
464:    Level: intermediate
466: .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw()
468: @*/
469: PetscErrorCode  PetscDrawLGDraw(PetscDrawLG lg)
470: {
471:   PetscReal      xmin,xmax,ymin,ymax;
473:   PetscMPIInt    rank;
474:   PetscDraw      draw;
475:   PetscBool      isnull;
479:   PetscDrawIsNull(lg->win,&isnull);
480:   if (isnull) return(0);
481:   MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);
483:   draw = lg->win;
484:   PetscDrawCheckResizedWindow(draw);
485:   PetscDrawClear(draw);
487:   xmin = lg->xmin; xmax = lg->xmax; ymin = lg->ymin; ymax = lg->ymax;
488:   PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);
489:   PetscDrawAxisDraw(lg->axis);
491:   PetscDrawCollectiveBegin(draw);
492:   if (!rank) {
493:     int i,j,dim=lg->dim,nopts=lg->nopts,cl;
494:     for (i=0; i<dim; i++) {
495:       for (j=1; j<nopts; j++) {
496:         cl   = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
497:         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);
498:         if (lg->use_markers) {PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl);}
499:       }
500:     }
501:   }
502:   if (!rank && lg->legend) {
503:     int       i,dim=lg->dim,cl;
504:     PetscReal xl,yl,xr,yr,tw,th;
505:     size_t    slen,len=0;
506:     PetscDrawAxisGetLimits(lg->axis,&xl,&xr,&yl,&yr);
507:     PetscDrawStringGetSize(draw,&tw,&th);
508:     for (i=0; i<dim; i++) {
509:       PetscStrlen(lg->legend[i],&slen);
510:       len = PetscMax(len,slen);
511:     }
512:     xr = xr - 1.5*tw; xl = xr - (len + 7)*tw;
513:     yr = yr - 1.0*th; yl = yr - (dim + 1)*th;
514:     PetscDrawLine(draw,xl,yl,xr,yl,PETSC_DRAW_BLACK);
515:     PetscDrawLine(draw,xr,yl,xr,yr,PETSC_DRAW_BLACK);
516:     PetscDrawLine(draw,xr,yr,xl,yr,PETSC_DRAW_BLACK);
517:     PetscDrawLine(draw,xl,yr,xl,yl,PETSC_DRAW_BLACK);
518:     for  (i=0; i<dim; i++) {
519:       cl   = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
520:       PetscDrawLine(draw,xl + 1*tw,yr - (i + 1)*th,xl + 5*tw,yr - (i + 1)*th,cl);
521:       PetscDrawString(draw,xl + 6*tw,yr - (i + 1.5)*th,PETSC_DRAW_BLACK,lg->legend[i]);
522:     }
523:   }
524:   PetscDrawCollectiveEnd(draw);
526:   PetscDrawFlush(draw);
527:   PetscDrawPause(draw);
528:   return(0);
529: }
533: /*@
534:   PetscDrawLGSave - Saves a drawn image
536:   Collective on PetscDrawLG
538:   Input Parameter:
539: . lg - The line graph context
541:   Level: intermediate
543:   Concepts: line graph^saving
545: .seealso:  PetscDrawLGCreate(), PetscDrawLGGetDraw(), PetscDrawSetSave(), PetscDrawSave()
546: @*/
547: PetscErrorCode  PetscDrawLGSave(PetscDrawLG lg)
548: {
553:   PetscDrawSave(lg->win);
554:   return(0);
555: }
559: /*@
560:   PetscDrawLGView - Prints a line graph.
562:   Collective on PetscDrawLG
564:   Input Parameter:
565: . lg - the line graph context
567:   Level: beginner
569: .keywords:  draw, line, graph
570: @*/
571: PetscErrorCode  PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)
572: {
573:   PetscReal      xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax;
574:   PetscInt       i, j, dim = lg->dim, nopts = lg->nopts;
580:   if (nopts < 1)                  return(0);
581:   if (xmin > xmax || ymin > ymax) return(0);
583:   if (!viewer){
584:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);
585:   }
586:   PetscObjectPrintClassNamePrefixType((PetscObject)lg,viewer);
587:   for (i = 0; i < dim; i++) {
588:     PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);
589:     for (j = 0; j < nopts; j++) {
590:       PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);
591:     }
592:   }
593:   return(0);
594: }
598: /*@C
599:    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
600:    PetscDrawLG options in the database.
602:    Logically Collective on PetscDrawLG
604:    Input Parameter:
605: +  lg - the line graph context
606: -  prefix - the prefix to prepend to all option names
608:    Level: advanced
610: .keywords: PetscDrawLG, set, options, prefix, database
612: .seealso: PetscDrawLGSetFromOptions()
613: @*/
614: PetscErrorCode  PetscDrawLGSetOptionsPrefix(PetscDrawLG lg,const char prefix[])
615: {
620:   PetscObjectSetOptionsPrefix((PetscObject)lg,prefix);
621:   return(0);
622: }
626: /*@
627:     PetscDrawLGSetFromOptions - Sets options related to the PetscDrawLG
629:     Collective on PetscDrawLG
631:     Options Database:
633:     Level: intermediate
635:     Concepts: line graph^creating
637: .seealso:  PetscDrawLGDestroy(), PetscDrawLGCreate()
638: @*/
639: PetscErrorCode  PetscDrawLGSetFromOptions(PetscDrawLG lg)
640: {
641:   PetscErrorCode      ierr;
642:   PetscBool           usemarkers,set;
643:   PetscDrawMarkerType markertype;
648:   PetscDrawGetMarkerType(lg->win,&markertype);
649:   PetscOptionsGetEnum(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_marker_type",PetscDrawMarkerTypes,(PetscEnum*)&markertype,&set);
650:   if (set) {
651:     PetscDrawLGSetUseMarkers(lg,PETSC_TRUE);
652:     PetscDrawSetMarkerType(lg->win,markertype);
653:   }
654:   usemarkers = lg->use_markers;
655:   PetscOptionsGetBool(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_use_markers",&usemarkers,&set);
656:   if (set) {PetscDrawLGSetUseMarkers(lg,usemarkers);}
657:   return(0);
658: }