xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 811af0c4b09a35de4306c442f88bd09fdc09897d)
15c6c1daeSBarry Smith 
25ccc9f3cSMatthew G Knepley #include <petscviewer.h>
3999739cfSJacob Faibussowitsch #include <petsc/private/drawimpl.h> /*I   "petscdraw.h"  I*/
45c6c1daeSBarry Smith PetscClassId PETSC_DRAWLG_CLASSID = 0;
55c6c1daeSBarry Smith 
65c6c1daeSBarry Smith /*@
75c6c1daeSBarry Smith    PetscDrawLGGetAxis - Gets the axis context associated with a line graph.
85c6c1daeSBarry Smith    This is useful if one wants to change some axis property, such as
95c6c1daeSBarry Smith    labels, color, etc. The axis context should not be destroyed by the
105c6c1daeSBarry Smith    application code.
115c6c1daeSBarry Smith 
12*811af0c4SBarry Smith    Not Collective, if lg is parallel then axis is parallel
135c6c1daeSBarry Smith 
145c6c1daeSBarry Smith    Input Parameter:
155c6c1daeSBarry Smith .  lg - the line graph context
165c6c1daeSBarry Smith 
175c6c1daeSBarry Smith    Output Parameter:
185c6c1daeSBarry Smith .  axis - the axis context
195c6c1daeSBarry Smith 
205c6c1daeSBarry Smith    Level: advanced
215c6c1daeSBarry Smith 
22*811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawAxis`, `PetscDrawLG`
235c6c1daeSBarry Smith @*/
249371c9d4SSatish Balay PetscErrorCode PetscDrawLGGetAxis(PetscDrawLG lg, PetscDrawAxis *axis) {
255c6c1daeSBarry Smith   PetscFunctionBegin;
26e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2745f3bb6eSLisandro Dalcin   PetscValidPointer(axis, 2);
285c6c1daeSBarry Smith   *axis = lg->axis;
295c6c1daeSBarry Smith   PetscFunctionReturn(0);
305c6c1daeSBarry Smith }
315c6c1daeSBarry Smith 
325c6c1daeSBarry Smith /*@
335c6c1daeSBarry Smith    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
345c6c1daeSBarry Smith 
35*811af0c4SBarry Smith    Not Collective, if lg is parallel then draw is parallel
365c6c1daeSBarry Smith 
375c6c1daeSBarry Smith    Input Parameter:
385c6c1daeSBarry Smith .  lg - the line graph context
395c6c1daeSBarry Smith 
405c6c1daeSBarry Smith    Output Parameter:
415c6c1daeSBarry Smith .  draw - the draw context
425c6c1daeSBarry Smith 
435c6c1daeSBarry Smith    Level: intermediate
445c6c1daeSBarry Smith 
45*811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDraw`, `PetscDrawLG`
465c6c1daeSBarry Smith @*/
479371c9d4SSatish Balay PetscErrorCode PetscDrawLGGetDraw(PetscDrawLG lg, PetscDraw *draw) {
485c6c1daeSBarry Smith   PetscFunctionBegin;
495c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5045f3bb6eSLisandro Dalcin   PetscValidPointer(draw, 2);
515c6c1daeSBarry Smith   *draw = lg->win;
525c6c1daeSBarry Smith   PetscFunctionReturn(0);
535c6c1daeSBarry Smith }
545c6c1daeSBarry Smith 
555c6c1daeSBarry Smith /*@
56*811af0c4SBarry Smith   PetscDrawLGSPDraw - Redraws a line graph and a scatter plot on the same `PetscDraw` they must share
575c6c1daeSBarry Smith 
58*811af0c4SBarry Smith    Collective on lg
595c6c1daeSBarry Smith 
60*811af0c4SBarry Smith    Input Parameters:
61*811af0c4SBarry Smith +  lg - the line graph context
62*811af0c4SBarry Smith -  spin - the scatter plot
635c6c1daeSBarry Smith 
645c6c1daeSBarry Smith    Level: intermediate
655c6c1daeSBarry Smith 
66*811af0c4SBarry Smith    Developer Note:
67*811af0c4SBarry Smith     This code cheats and uses the fact that the `PetscDrawLG` and `PetscDrawSP` structs are the same
68*811af0c4SBarry Smith 
69db781477SPatrick Sanan .seealso: `PetscDrawLGDraw()`, `PetscDrawSPDraw()`
705c6c1daeSBarry Smith @*/
719371c9d4SSatish Balay PetscErrorCode PetscDrawLGSPDraw(PetscDrawLG lg, PetscDrawSP spin) {
725c6c1daeSBarry Smith   PetscDrawLG sp = (PetscDrawLG)spin;
735c6c1daeSBarry Smith   PetscReal   xmin, xmax, ymin, ymax;
74e118a51fSLisandro Dalcin   PetscBool   isnull;
75e118a51fSLisandro Dalcin   PetscMPIInt rank;
76e118a51fSLisandro Dalcin   PetscDraw   draw;
775c6c1daeSBarry Smith 
785c6c1daeSBarry Smith   PetscFunctionBegin;
795c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
80064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(sp, PETSC_DRAWLG_CLASSID, 2);
819566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
82e118a51fSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
839566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
845c6c1daeSBarry Smith 
855b399a63SLisandro Dalcin   draw = lg->win;
869566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
879566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
88e118a51fSLisandro Dalcin 
899371c9d4SSatish Balay   xmin = PetscMin(lg->xmin, sp->xmin);
909371c9d4SSatish Balay   ymin = PetscMin(lg->ymin, sp->ymin);
919371c9d4SSatish Balay   xmax = PetscMax(lg->xmax, sp->xmax);
929371c9d4SSatish Balay   ymax = PetscMax(lg->ymax, sp->ymax);
939566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
949566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
955c6c1daeSBarry Smith 
96d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
97dd400576SPatrick Sanan   if (rank == 0) {
98e118a51fSLisandro Dalcin     int i, j, dim, nopts;
995c6c1daeSBarry Smith     dim   = lg->dim;
1005c6c1daeSBarry Smith     nopts = lg->nopts;
1015c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
1025c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
1039566063dSJacob Faibussowitsch         PetscCall(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));
10448a46eb9SPierre Jolivet         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], PETSC_DRAW_RED));
1055c6c1daeSBarry Smith       }
1065c6c1daeSBarry Smith     }
1075c6c1daeSBarry Smith     dim   = sp->dim;
1085c6c1daeSBarry Smith     nopts = sp->nopts;
1095c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
11048a46eb9SPierre Jolivet       for (j = 0; j < nopts; j++) PetscCall(PetscDrawMarker(draw, sp->x[j * dim + i], sp->y[j * dim + i], PETSC_DRAW_RED));
1115c6c1daeSBarry Smith     }
1125c6c1daeSBarry Smith   }
113d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
1145b399a63SLisandro Dalcin 
1159566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
1169566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
1175c6c1daeSBarry Smith   PetscFunctionReturn(0);
1185c6c1daeSBarry Smith }
1195c6c1daeSBarry Smith 
1205c6c1daeSBarry Smith /*@
1215c6c1daeSBarry Smith     PetscDrawLGCreate - Creates a line graph data structure.
1225c6c1daeSBarry Smith 
123*811af0c4SBarry Smith     Collective on draw
1245c6c1daeSBarry Smith 
1255c6c1daeSBarry Smith     Input Parameters:
1265c6c1daeSBarry Smith +   draw - the window where the graph will be made.
1275c6c1daeSBarry Smith -   dim - the number of curves which will be drawn
1285c6c1daeSBarry Smith 
1295c6c1daeSBarry Smith     Output Parameters:
130e118a51fSLisandro Dalcin .   outlg - the line graph context
1315c6c1daeSBarry Smith 
1325c6c1daeSBarry Smith     Level: intermediate
1335c6c1daeSBarry Smith 
13495452b02SPatrick Sanan     Notes:
135*811af0c4SBarry Smith     The MPI communicator that owns the `PetscDraw` owns this `PetscDrawLG`, but the calls to set options and add points are ignored on all processes except the
136*811af0c4SBarry Smith            zeroth MPI process in the communicator.
1377e25d57eSBarry Smith 
138*811af0c4SBarry Smith     All MPI ranks in the communicator must call `PetscDrawLGDraw()` to display the updated graph.
139*811af0c4SBarry Smith 
140*811af0c4SBarry Smith .seealso: `PetscDrawLGCreate`, `PetscDrawLGDestroy()`, `PetscDrawLGAddPoint()`, `PetscDrawLGAddCommonPoint()`, `PetscDrawLGAddPoints()`, `PetscDrawLGDraw()`, `PetscDrawLGSave()`,
141db781477SPatrick Sanan           `PetscDrawLGView()`, `PetscDrawLGReset()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()`, `PetscDrawLGSetLegend()`, `PetscDrawLGGetAxis()`,
142db781477SPatrick Sanan           `PetscDrawLGGetDraw()`, `PetscDrawLGSetUseMarkers()`, `PetscDrawLGSetLimits()`, `PetscDrawLGSetColors()`, `PetscDrawLGSetOptionsPrefix()`, `PetscDrawLGSetFromOptions()`
1435c6c1daeSBarry Smith @*/
1449371c9d4SSatish Balay PetscErrorCode PetscDrawLGCreate(PetscDraw draw, PetscInt dim, PetscDrawLG *outlg) {
1455c6c1daeSBarry Smith   PetscDrawLG lg;
1465c6c1daeSBarry Smith 
1475c6c1daeSBarry Smith   PetscFunctionBegin;
1485c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
149e118a51fSLisandro Dalcin   PetscValidLogicalCollectiveInt(draw, dim, 2);
150e118a51fSLisandro Dalcin   PetscValidPointer(outlg, 3);
151e118a51fSLisandro Dalcin 
1529566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(lg, PETSC_DRAWLG_CLASSID, "DrawLG", "Line Graph", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawLGDestroy, NULL));
1539566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)draw, (PetscObject)lg));
1549566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetOptionsPrefix(lg, ((PetscObject)draw)->prefix));
155e118a51fSLisandro Dalcin 
1569566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)draw));
157e118a51fSLisandro Dalcin   lg->win = draw;
158a297a907SKarl Rupp 
15969c83917SLisandro Dalcin   lg->view    = NULL;
16069c83917SLisandro Dalcin   lg->destroy = NULL;
1615c6c1daeSBarry Smith   lg->nopts   = 0;
1625c6c1daeSBarry Smith   lg->dim     = dim;
1635c6c1daeSBarry Smith   lg->xmin    = 1.e20;
1645c6c1daeSBarry Smith   lg->ymin    = 1.e20;
1655c6c1daeSBarry Smith   lg->xmax    = -1.e20;
1665c6c1daeSBarry Smith   lg->ymax    = -1.e20;
167a297a907SKarl Rupp 
1689566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
1699566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)lg, 2 * dim * PETSC_DRAW_LG_CHUNK_SIZE * sizeof(PetscReal)));
170a297a907SKarl Rupp 
171999739cfSJacob Faibussowitsch   lg->len         = dim * PETSC_DRAW_LG_CHUNK_SIZE;
1725c6c1daeSBarry Smith   lg->loc         = 0;
173b6fe0379SLisandro Dalcin   lg->use_markers = PETSC_FALSE;
174a297a907SKarl Rupp 
1759566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &lg->axis));
1769566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)lg, (PetscObject)lg->axis));
177a297a907SKarl Rupp 
178e118a51fSLisandro Dalcin   *outlg = lg;
1795c6c1daeSBarry Smith   PetscFunctionReturn(0);
1805c6c1daeSBarry Smith }
1815c6c1daeSBarry Smith 
1825c6c1daeSBarry Smith /*@
1835c6c1daeSBarry Smith    PetscDrawLGSetColors - Sets the color of each line graph drawn
1845c6c1daeSBarry Smith 
185*811af0c4SBarry Smith    Logically Collective on lg
1865c6c1daeSBarry Smith 
187d8d19677SJose E. Roman    Input Parameters:
1885c6c1daeSBarry Smith +  lg - the line graph context.
1895c6c1daeSBarry Smith -  colors - the colors
1905c6c1daeSBarry Smith 
1915c6c1daeSBarry Smith    Level: intermediate
1925c6c1daeSBarry Smith 
193*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
1945c6c1daeSBarry Smith @*/
1959371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg, const int colors[]) {
1965c6c1daeSBarry Smith   PetscFunctionBegin;
1975c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
19845f3bb6eSLisandro Dalcin   if (lg->dim) PetscValidIntPointer(colors, 2);
199e118a51fSLisandro Dalcin 
2009566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
2019566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lg->dim, &lg->colors));
2029566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(lg->colors, colors, lg->dim));
2035c6c1daeSBarry Smith   PetscFunctionReturn(0);
2045c6c1daeSBarry Smith }
2055c6c1daeSBarry Smith 
2065c6c1daeSBarry Smith /*@C
2075c6c1daeSBarry Smith    PetscDrawLGSetLegend - sets the names of each curve plotted
2085c6c1daeSBarry Smith 
209*811af0c4SBarry Smith    Logically Collective on lg
2105c6c1daeSBarry Smith 
211d8d19677SJose E. Roman    Input Parameters:
2125c6c1daeSBarry Smith +  lg - the line graph context.
2135c6c1daeSBarry Smith -  names - the names for each curve
2145c6c1daeSBarry Smith 
2155c6c1daeSBarry Smith    Level: intermediate
2165c6c1daeSBarry Smith 
217*811af0c4SBarry Smith    Note:
218*811af0c4SBarry Smith     Call `PetscDrawLGGetAxis()` and then change properties of the `PetscDrawAxis` for detailed control of the plot
219ba1e01c4SBarry Smith 
220db781477SPatrick Sanan .seealso: `PetscDrawLGGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetHoldLimits()`
2215c6c1daeSBarry Smith @*/
2229371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg, const char *const *names) {
2235c6c1daeSBarry Smith   PetscInt i;
2245c6c1daeSBarry Smith 
2255c6c1daeSBarry Smith   PetscFunctionBegin;
2265c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
22745f3bb6eSLisandro Dalcin   if (names) PetscValidPointer(names, 2);
2285c6c1daeSBarry Smith 
2295c6c1daeSBarry Smith   if (lg->legend) {
23048a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2319566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2325c6c1daeSBarry Smith   }
2335c6c1daeSBarry Smith   if (names) {
2349566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(lg->dim, &lg->legend));
23548a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscStrallocpy(names[i], &lg->legend[i]));
2365c6c1daeSBarry Smith   }
2375c6c1daeSBarry Smith   PetscFunctionReturn(0);
2385c6c1daeSBarry Smith }
2395c6c1daeSBarry Smith 
2405c6c1daeSBarry Smith /*@
241*811af0c4SBarry Smith    PetscDrawLGGetDimension - Get the number of curves that are to be drawn.
2425c6c1daeSBarry Smith 
2435b399a63SLisandro Dalcin    Not Collective
2445c6c1daeSBarry Smith 
2455c6c1daeSBarry Smith    Input Parameter:
2465c6c1daeSBarry Smith .  lg - the line graph context.
2475c6c1daeSBarry Smith 
2485c6c1daeSBarry Smith    Output Parameter:
2495c6c1daeSBarry Smith .  dim - the number of curves.
2505c6c1daeSBarry Smith 
2515c6c1daeSBarry Smith    Level: intermediate
2525c6c1daeSBarry Smith 
253*811af0c4SBarry Smith .seealso: `PetscDrawLGC`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`
2545c6c1daeSBarry Smith @*/
2559371c9d4SSatish Balay PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg, PetscInt *dim) {
2565c6c1daeSBarry Smith   PetscFunctionBegin;
2575c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
25845f3bb6eSLisandro Dalcin   PetscValidIntPointer(dim, 2);
2595c6c1daeSBarry Smith   *dim = lg->dim;
2605c6c1daeSBarry Smith   PetscFunctionReturn(0);
2615c6c1daeSBarry Smith }
2625c6c1daeSBarry Smith 
2635c6c1daeSBarry Smith /*@
264*811af0c4SBarry Smith    PetscDrawLGSetDimension - Change the number of curves that are to be drawn.
2655c6c1daeSBarry Smith 
266*811af0c4SBarry Smith    Logically Collective on lg
2675c6c1daeSBarry Smith 
268d8d19677SJose E. Roman    Input Parameters:
2695c6c1daeSBarry Smith +  lg - the line graph context.
2705c6c1daeSBarry Smith -  dim - the number of curves.
2715c6c1daeSBarry Smith 
2725c6c1daeSBarry Smith    Level: intermediate
2735c6c1daeSBarry Smith 
274db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLGGetDimension()`
2755c6c1daeSBarry Smith @*/
2769371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg, PetscInt dim) {
2775c6c1daeSBarry Smith   PetscInt i;
2785c6c1daeSBarry Smith 
2795c6c1daeSBarry Smith   PetscFunctionBegin;
2805c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2815c6c1daeSBarry Smith   PetscValidLogicalCollectiveInt(lg, dim, 2);
2825c6c1daeSBarry Smith   if (lg->dim == dim) PetscFunctionReturn(0);
2835c6c1daeSBarry Smith 
2849566063dSJacob Faibussowitsch   PetscCall(PetscFree2(lg->x, lg->y));
2855c6c1daeSBarry Smith   if (lg->legend) {
28648a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2879566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2885c6c1daeSBarry Smith   }
2899566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
2905c6c1daeSBarry Smith   lg->dim = dim;
2919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
2929566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)lg, 2 * dim * PETSC_DRAW_LG_CHUNK_SIZE * sizeof(PetscReal)));
293999739cfSJacob Faibussowitsch   lg->len = dim * PETSC_DRAW_LG_CHUNK_SIZE;
2945c6c1daeSBarry Smith   PetscFunctionReturn(0);
2955c6c1daeSBarry Smith }
2965c6c1daeSBarry Smith 
29771917b75SLisandro Dalcin /*@
29871917b75SLisandro Dalcin    PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
29971917b75SLisandro Dalcin    points are added after this call, the limits will be adjusted to
30071917b75SLisandro Dalcin    include those additional points.
30171917b75SLisandro Dalcin 
302*811af0c4SBarry Smith    Logically Collective on lg
30371917b75SLisandro Dalcin 
30471917b75SLisandro Dalcin    Input Parameters:
30571917b75SLisandro Dalcin +  xlg - the line graph context
30671917b75SLisandro Dalcin -  x_min,x_max,y_min,y_max - the limits
30771917b75SLisandro Dalcin 
30871917b75SLisandro Dalcin    Level: intermediate
30971917b75SLisandro Dalcin 
310*811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis`
31171917b75SLisandro Dalcin @*/
3129371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max) {
31371917b75SLisandro Dalcin   PetscFunctionBegin;
31471917b75SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
31571917b75SLisandro Dalcin 
31671917b75SLisandro Dalcin   (lg)->xmin = x_min;
31771917b75SLisandro Dalcin   (lg)->xmax = x_max;
31871917b75SLisandro Dalcin   (lg)->ymin = y_min;
31971917b75SLisandro Dalcin   (lg)->ymax = y_max;
32071917b75SLisandro Dalcin   PetscFunctionReturn(0);
32171917b75SLisandro Dalcin }
32271917b75SLisandro Dalcin 
3235c6c1daeSBarry Smith /*@
3245c6c1daeSBarry Smith    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
3255c6c1daeSBarry Smith 
326*811af0c4SBarry Smith    Logically Collective on lg
3275c6c1daeSBarry Smith 
3285c6c1daeSBarry Smith    Input Parameter:
3295c6c1daeSBarry Smith .  lg - the line graph context.
3305c6c1daeSBarry Smith 
3315c6c1daeSBarry Smith    Level: intermediate
3325c6c1daeSBarry Smith 
333*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3345c6c1daeSBarry Smith @*/
3359371c9d4SSatish Balay PetscErrorCode PetscDrawLGReset(PetscDrawLG lg) {
3365c6c1daeSBarry Smith   PetscFunctionBegin;
3375c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
3385c6c1daeSBarry Smith   lg->xmin  = 1.e20;
3395c6c1daeSBarry Smith   lg->ymin  = 1.e20;
3405c6c1daeSBarry Smith   lg->xmax  = -1.e20;
3415c6c1daeSBarry Smith   lg->ymax  = -1.e20;
3425c6c1daeSBarry Smith   lg->loc   = 0;
3435c6c1daeSBarry Smith   lg->nopts = 0;
3445c6c1daeSBarry Smith   PetscFunctionReturn(0);
3455c6c1daeSBarry Smith }
3465c6c1daeSBarry Smith 
3475c6c1daeSBarry Smith /*@
3485c6c1daeSBarry Smith    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
3495c6c1daeSBarry Smith 
350*811af0c4SBarry Smith    Collective on lg
3515c6c1daeSBarry Smith 
3525c6c1daeSBarry Smith    Input Parameter:
3535c6c1daeSBarry Smith .  lg - the line graph context
3545c6c1daeSBarry Smith 
3555c6c1daeSBarry Smith    Level: intermediate
3565c6c1daeSBarry Smith 
357*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3585c6c1daeSBarry Smith @*/
3599371c9d4SSatish Balay PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg) {
3605c6c1daeSBarry Smith   PetscInt i;
3615c6c1daeSBarry Smith 
3625c6c1daeSBarry Smith   PetscFunctionBegin;
3635c6c1daeSBarry Smith   if (!*lg) PetscFunctionReturn(0);
364e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1);
3659371c9d4SSatish Balay   if (--((PetscObject)(*lg))->refct > 0) {
3669371c9d4SSatish Balay     *lg = NULL;
3679371c9d4SSatish Balay     PetscFunctionReturn(0);
3689371c9d4SSatish Balay   }
3695c6c1daeSBarry Smith 
3705c6c1daeSBarry Smith   if ((*lg)->legend) {
37148a46eb9SPierre Jolivet     for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i]));
3729566063dSJacob Faibussowitsch     PetscCall(PetscFree((*lg)->legend));
3735c6c1daeSBarry Smith   }
3749566063dSJacob Faibussowitsch   PetscCall(PetscFree((*lg)->colors));
3759566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*lg)->x, (*lg)->y));
3769566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*lg)->axis));
3779566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*lg)->win));
3789566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lg));
3795c6c1daeSBarry Smith   PetscFunctionReturn(0);
3805c6c1daeSBarry Smith }
3815c6c1daeSBarry Smith /*@
382*811af0c4SBarry Smith    PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point.
3835c6c1daeSBarry Smith 
384*811af0c4SBarry Smith    Logically Collective on lg
3855c6c1daeSBarry Smith 
3865c6c1daeSBarry Smith    Input Parameters:
387287de1a7SBarry Smith +  lg - the linegraph context
388287de1a7SBarry Smith -  flg - should mark each data point
389287de1a7SBarry Smith 
390*811af0c4SBarry Smith    Options Database Key:
391*811af0c4SBarry Smith .  -lg_use_markers  <true,false> - true means it draws a marker for each point
3925c6c1daeSBarry Smith 
3935c6c1daeSBarry Smith    Level: intermediate
3945c6c1daeSBarry Smith 
395*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3965c6c1daeSBarry Smith @*/
3979371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg) {
3985c6c1daeSBarry Smith   PetscFunctionBegin;
399e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
40045f3bb6eSLisandro Dalcin   PetscValidLogicalCollectiveBool(lg, flg, 2);
401b6fe0379SLisandro Dalcin   lg->use_markers = flg;
4025c6c1daeSBarry Smith   PetscFunctionReturn(0);
4035c6c1daeSBarry Smith }
4045c6c1daeSBarry Smith 
4055c6c1daeSBarry Smith /*@
4065c6c1daeSBarry Smith    PetscDrawLGDraw - Redraws a line graph.
4075c6c1daeSBarry Smith 
408*811af0c4SBarry Smith    Collective on lg
4095c6c1daeSBarry Smith 
4105c6c1daeSBarry Smith    Input Parameter:
4115c6c1daeSBarry Smith .  lg - the line graph context
4125c6c1daeSBarry Smith 
4135c6c1daeSBarry Smith    Level: intermediate
4145c6c1daeSBarry Smith 
415*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()`
4165c6c1daeSBarry Smith @*/
4179371c9d4SSatish Balay PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg) {
418e118a51fSLisandro Dalcin   PetscReal   xmin, xmax, ymin, ymax;
419e118a51fSLisandro Dalcin   PetscMPIInt rank;
420e118a51fSLisandro Dalcin   PetscDraw   draw;
4215c6c1daeSBarry Smith   PetscBool   isnull;
4225c6c1daeSBarry Smith 
4235c6c1daeSBarry Smith   PetscFunctionBegin;
4245c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
4259566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
4268f69470aSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
4279566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
4285c6c1daeSBarry Smith 
4295b399a63SLisandro Dalcin   draw = lg->win;
4309566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
4319566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
432e118a51fSLisandro Dalcin 
4339371c9d4SSatish Balay   xmin = lg->xmin;
4349371c9d4SSatish Balay   xmax = lg->xmax;
4359371c9d4SSatish Balay   ymin = lg->ymin;
4369371c9d4SSatish Balay   ymax = lg->ymax;
4379566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
4389566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
4395c6c1daeSBarry Smith 
440d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
441dd400576SPatrick Sanan   if (rank == 0) {
442e118a51fSLisandro Dalcin     int i, j, dim = lg->dim, nopts = lg->nopts, cl;
4435c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4445c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
4450ed3bfb6SBarry Smith         cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
4469566063dSJacob Faibussowitsch         PetscCall(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));
4479566063dSJacob Faibussowitsch         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl));
4485c6c1daeSBarry Smith       }
4495c6c1daeSBarry Smith     }
4505c6c1daeSBarry Smith   }
451dd400576SPatrick Sanan   if (rank == 0 && lg->legend) {
452088d793eSMatthew G. Knepley     PetscBool right = PETSC_FALSE;
453e118a51fSLisandro Dalcin     int       i, dim = lg->dim, cl;
4545c6c1daeSBarry Smith     PetscReal xl, yl, xr, yr, tw, th;
45571917b75SLisandro Dalcin     size_t    slen, len = 0;
4569566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr));
4579566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
4585c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4599566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(lg->legend[i], &slen));
46071917b75SLisandro Dalcin       len = PetscMax(len, slen);
4615c6c1daeSBarry Smith     }
462088d793eSMatthew G. Knepley     if (right) {
4639371c9d4SSatish Balay       xr = xr - 1.5 * tw;
4649371c9d4SSatish Balay       xl = xr - (len + 7) * tw;
465088d793eSMatthew G. Knepley     } else {
4669371c9d4SSatish Balay       xl = xl + 1.5 * tw;
4679371c9d4SSatish Balay       xr = xl + (len + 7) * tw;
468088d793eSMatthew G. Knepley     }
4699371c9d4SSatish Balay     yr = yr - 1.0 * th;
4709371c9d4SSatish Balay     yl = yr - (dim + 1) * th;
4719566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK));
4729566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK));
4739566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK));
4749566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK));
4755c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
47671917b75SLisandro Dalcin       cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
4779566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl));
4789566063dSJacob Faibussowitsch       PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i]));
4795c6c1daeSBarry Smith     }
4805c6c1daeSBarry Smith   }
481d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
4825b399a63SLisandro Dalcin 
4839566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
4849566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
4855c6c1daeSBarry Smith   PetscFunctionReturn(0);
4865c6c1daeSBarry Smith }
4875c6c1daeSBarry Smith 
48857fd6651SLisandro Dalcin /*@
48957fd6651SLisandro Dalcin   PetscDrawLGSave - Saves a drawn image
49057fd6651SLisandro Dalcin 
491*811af0c4SBarry Smith   Collective on lg
49257fd6651SLisandro Dalcin 
49357fd6651SLisandro Dalcin   Input Parameter:
49457fd6651SLisandro Dalcin . lg - The line graph context
49557fd6651SLisandro Dalcin 
49657fd6651SLisandro Dalcin   Level: intermediate
49757fd6651SLisandro Dalcin 
498*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`
49957fd6651SLisandro Dalcin @*/
5009371c9d4SSatish Balay PetscErrorCode PetscDrawLGSave(PetscDrawLG lg) {
50157fd6651SLisandro Dalcin   PetscFunctionBegin;
50257fd6651SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5039566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(lg->win));
50457fd6651SLisandro Dalcin   PetscFunctionReturn(0);
50557fd6651SLisandro Dalcin }
50657fd6651SLisandro Dalcin 
5075c6c1daeSBarry Smith /*@
50834a5a0e3SBarry Smith   PetscDrawLGView - Prints a line graph.
5095c6c1daeSBarry Smith 
510*811af0c4SBarry Smith   Collective on lg
5115c6c1daeSBarry Smith 
5125c6c1daeSBarry Smith   Input Parameter:
5135c6c1daeSBarry Smith . lg - the line graph context
5145c6c1daeSBarry Smith 
5155c6c1daeSBarry Smith   Level: beginner
5165c6c1daeSBarry Smith 
517*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
5185c6c1daeSBarry Smith @*/
5199371c9d4SSatish Balay PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer) {
5205c6c1daeSBarry Smith   PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax;
52134a5a0e3SBarry Smith   PetscInt  i, j, dim = lg->dim, nopts = lg->nopts;
5225c6c1daeSBarry Smith 
5235c6c1daeSBarry Smith   PetscFunctionBegin;
5245c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
525e118a51fSLisandro Dalcin 
5265c6c1daeSBarry Smith   if (nopts < 1) PetscFunctionReturn(0);
5275c6c1daeSBarry Smith   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
5285c6c1daeSBarry Smith 
52948a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer));
5309566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer));
5315c6c1daeSBarry Smith   for (i = 0; i < dim; i++) {
5329566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i));
53348a46eb9SPierre Jolivet     for (j = 0; j < nopts; j++) PetscCall(PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j * dim + i], (double)lg->y[j * dim + i]));
5345c6c1daeSBarry Smith   }
5355c6c1daeSBarry Smith   PetscFunctionReturn(0);
5365c6c1daeSBarry Smith }
537287de1a7SBarry Smith 
538c2bac407SLisandro Dalcin /*@C
539c2bac407SLisandro Dalcin    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
540*811af0c4SBarry Smith    `PetscDrawLG` options in the database.
541c2bac407SLisandro Dalcin 
542*811af0c4SBarry Smith    Logically Collective on lg
543c2bac407SLisandro Dalcin 
544d8d19677SJose E. Roman    Input Parameters:
545c2bac407SLisandro Dalcin +  lg - the line graph context
546c2bac407SLisandro Dalcin -  prefix - the prefix to prepend to all option names
547c2bac407SLisandro Dalcin 
548c2bac407SLisandro Dalcin    Level: advanced
549c2bac407SLisandro Dalcin 
550*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()`
551c2bac407SLisandro Dalcin @*/
5529371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[]) {
553c2bac407SLisandro Dalcin   PetscFunctionBegin;
554c2bac407SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5559566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix));
556c2bac407SLisandro Dalcin   PetscFunctionReturn(0);
557c2bac407SLisandro Dalcin }
558c2bac407SLisandro Dalcin 
559287de1a7SBarry Smith /*@
560*811af0c4SBarry Smith     PetscDrawLGSetFromOptions - Sets options related to the line graph object
561287de1a7SBarry Smith 
562*811af0c4SBarry Smith     Collective on lg
563287de1a7SBarry Smith 
564*811af0c4SBarry Smith     Input Parameters:
565*811af0c4SBarry Smith .   lg - the line graph context
566*811af0c4SBarry Smith 
567*811af0c4SBarry Smith     Options Database Key:
568*811af0c4SBarry Smith .  -lg_use_markers  <true,false> - true means it draws a marker for each point
569287de1a7SBarry Smith 
570287de1a7SBarry Smith     Level: intermediate
571287de1a7SBarry Smith 
572*811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()`
573287de1a7SBarry Smith @*/
5749371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg) {
57571917b75SLisandro Dalcin   PetscBool           usemarkers, set;
57671917b75SLisandro Dalcin   PetscDrawMarkerType markertype;
577287de1a7SBarry Smith 
578287de1a7SBarry Smith   PetscFunctionBegin;
579e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
580e118a51fSLisandro Dalcin 
5819566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetMarkerType(lg->win, &markertype));
5829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set));
58371917b75SLisandro Dalcin   if (set) {
5849566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE));
5859566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetMarkerType(lg->win, markertype));
58671917b75SLisandro Dalcin   }
58771917b75SLisandro Dalcin   usemarkers = lg->use_markers;
5889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set));
5899566063dSJacob Faibussowitsch   if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers));
590287de1a7SBarry Smith   PetscFunctionReturn(0);
591287de1a7SBarry Smith }
592