xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision c3339decea92175325d9368fa13196bcd0e0e58b)
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 
12811af0c4SBarry 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 
22811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawAxis`, `PetscDrawLG`
235c6c1daeSBarry Smith @*/
24d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGGetAxis(PetscDrawLG lg, PetscDrawAxis *axis)
25d71ae5a4SJacob Faibussowitsch {
265c6c1daeSBarry Smith   PetscFunctionBegin;
27e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2845f3bb6eSLisandro Dalcin   PetscValidPointer(axis, 2);
295c6c1daeSBarry Smith   *axis = lg->axis;
305c6c1daeSBarry Smith   PetscFunctionReturn(0);
315c6c1daeSBarry Smith }
325c6c1daeSBarry Smith 
335c6c1daeSBarry Smith /*@
345c6c1daeSBarry Smith    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
355c6c1daeSBarry Smith 
36811af0c4SBarry Smith    Not Collective, if lg is parallel then draw is parallel
375c6c1daeSBarry Smith 
385c6c1daeSBarry Smith    Input Parameter:
395c6c1daeSBarry Smith .  lg - the line graph context
405c6c1daeSBarry Smith 
415c6c1daeSBarry Smith    Output Parameter:
425c6c1daeSBarry Smith .  draw - the draw context
435c6c1daeSBarry Smith 
445c6c1daeSBarry Smith    Level: intermediate
455c6c1daeSBarry Smith 
46811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDraw`, `PetscDrawLG`
475c6c1daeSBarry Smith @*/
48d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGGetDraw(PetscDrawLG lg, PetscDraw *draw)
49d71ae5a4SJacob Faibussowitsch {
505c6c1daeSBarry Smith   PetscFunctionBegin;
515c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5245f3bb6eSLisandro Dalcin   PetscValidPointer(draw, 2);
535c6c1daeSBarry Smith   *draw = lg->win;
545c6c1daeSBarry Smith   PetscFunctionReturn(0);
555c6c1daeSBarry Smith }
565c6c1daeSBarry Smith 
575c6c1daeSBarry Smith /*@
58811af0c4SBarry Smith   PetscDrawLGSPDraw - Redraws a line graph and a scatter plot on the same `PetscDraw` they must share
595c6c1daeSBarry Smith 
60*c3339decSBarry Smith    Collective
615c6c1daeSBarry Smith 
62811af0c4SBarry Smith    Input Parameters:
63811af0c4SBarry Smith +  lg - the line graph context
64811af0c4SBarry Smith -  spin - the scatter plot
655c6c1daeSBarry Smith 
665c6c1daeSBarry Smith    Level: intermediate
675c6c1daeSBarry Smith 
68811af0c4SBarry Smith    Developer Note:
69811af0c4SBarry Smith     This code cheats and uses the fact that the `PetscDrawLG` and `PetscDrawSP` structs are the same
70811af0c4SBarry Smith 
71db781477SPatrick Sanan .seealso: `PetscDrawLGDraw()`, `PetscDrawSPDraw()`
725c6c1daeSBarry Smith @*/
73d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSPDraw(PetscDrawLG lg, PetscDrawSP spin)
74d71ae5a4SJacob Faibussowitsch {
755c6c1daeSBarry Smith   PetscDrawLG sp = (PetscDrawLG)spin;
765c6c1daeSBarry Smith   PetscReal   xmin, xmax, ymin, ymax;
77e118a51fSLisandro Dalcin   PetscBool   isnull;
78e118a51fSLisandro Dalcin   PetscMPIInt rank;
79e118a51fSLisandro Dalcin   PetscDraw   draw;
805c6c1daeSBarry Smith 
815c6c1daeSBarry Smith   PetscFunctionBegin;
825c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
83064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(sp, PETSC_DRAWLG_CLASSID, 2);
849566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
85e118a51fSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
869566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
875c6c1daeSBarry Smith 
885b399a63SLisandro Dalcin   draw = lg->win;
899566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
909566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
91e118a51fSLisandro Dalcin 
929371c9d4SSatish Balay   xmin = PetscMin(lg->xmin, sp->xmin);
939371c9d4SSatish Balay   ymin = PetscMin(lg->ymin, sp->ymin);
949371c9d4SSatish Balay   xmax = PetscMax(lg->xmax, sp->xmax);
959371c9d4SSatish Balay   ymax = PetscMax(lg->ymax, sp->ymax);
969566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
979566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
985c6c1daeSBarry Smith 
99d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
100dd400576SPatrick Sanan   if (rank == 0) {
101e118a51fSLisandro Dalcin     int i, j, dim, nopts;
1025c6c1daeSBarry Smith     dim   = lg->dim;
1035c6c1daeSBarry Smith     nopts = lg->nopts;
1045c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
1055c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
1069566063dSJacob 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));
10748a46eb9SPierre Jolivet         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], PETSC_DRAW_RED));
1085c6c1daeSBarry Smith       }
1095c6c1daeSBarry Smith     }
1105c6c1daeSBarry Smith     dim   = sp->dim;
1115c6c1daeSBarry Smith     nopts = sp->nopts;
1125c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
11348a46eb9SPierre Jolivet       for (j = 0; j < nopts; j++) PetscCall(PetscDrawMarker(draw, sp->x[j * dim + i], sp->y[j * dim + i], PETSC_DRAW_RED));
1145c6c1daeSBarry Smith     }
1155c6c1daeSBarry Smith   }
116d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
1175b399a63SLisandro Dalcin 
1189566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
1199566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
1205c6c1daeSBarry Smith   PetscFunctionReturn(0);
1215c6c1daeSBarry Smith }
1225c6c1daeSBarry Smith 
1235c6c1daeSBarry Smith /*@
1245c6c1daeSBarry Smith     PetscDrawLGCreate - Creates a line graph data structure.
1255c6c1daeSBarry Smith 
126*c3339decSBarry Smith     Collective
1275c6c1daeSBarry Smith 
1285c6c1daeSBarry Smith     Input Parameters:
1295c6c1daeSBarry Smith +   draw - the window where the graph will be made.
1305c6c1daeSBarry Smith -   dim - the number of curves which will be drawn
1315c6c1daeSBarry Smith 
1325c6c1daeSBarry Smith     Output Parameters:
133e118a51fSLisandro Dalcin .   outlg - the line graph context
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith     Level: intermediate
1365c6c1daeSBarry Smith 
13795452b02SPatrick Sanan     Notes:
138811af0c4SBarry 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
139811af0c4SBarry Smith            zeroth MPI process in the communicator.
1407e25d57eSBarry Smith 
141811af0c4SBarry Smith     All MPI ranks in the communicator must call `PetscDrawLGDraw()` to display the updated graph.
142811af0c4SBarry Smith 
143811af0c4SBarry Smith .seealso: `PetscDrawLGCreate`, `PetscDrawLGDestroy()`, `PetscDrawLGAddPoint()`, `PetscDrawLGAddCommonPoint()`, `PetscDrawLGAddPoints()`, `PetscDrawLGDraw()`, `PetscDrawLGSave()`,
144db781477SPatrick Sanan           `PetscDrawLGView()`, `PetscDrawLGReset()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()`, `PetscDrawLGSetLegend()`, `PetscDrawLGGetAxis()`,
145db781477SPatrick Sanan           `PetscDrawLGGetDraw()`, `PetscDrawLGSetUseMarkers()`, `PetscDrawLGSetLimits()`, `PetscDrawLGSetColors()`, `PetscDrawLGSetOptionsPrefix()`, `PetscDrawLGSetFromOptions()`
1465c6c1daeSBarry Smith @*/
147d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGCreate(PetscDraw draw, PetscInt dim, PetscDrawLG *outlg)
148d71ae5a4SJacob Faibussowitsch {
1495c6c1daeSBarry Smith   PetscDrawLG lg;
1505c6c1daeSBarry Smith 
1515c6c1daeSBarry Smith   PetscFunctionBegin;
1525c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
153e118a51fSLisandro Dalcin   PetscValidLogicalCollectiveInt(draw, dim, 2);
154e118a51fSLisandro Dalcin   PetscValidPointer(outlg, 3);
155e118a51fSLisandro Dalcin 
1569566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(lg, PETSC_DRAWLG_CLASSID, "DrawLG", "Line Graph", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawLGDestroy, NULL));
1579566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetOptionsPrefix(lg, ((PetscObject)draw)->prefix));
158e118a51fSLisandro Dalcin 
1599566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)draw));
160e118a51fSLisandro Dalcin   lg->win = draw;
161a297a907SKarl Rupp 
16269c83917SLisandro Dalcin   lg->view    = NULL;
16369c83917SLisandro Dalcin   lg->destroy = NULL;
1645c6c1daeSBarry Smith   lg->nopts   = 0;
1655c6c1daeSBarry Smith   lg->dim     = dim;
1665c6c1daeSBarry Smith   lg->xmin    = 1.e20;
1675c6c1daeSBarry Smith   lg->ymin    = 1.e20;
1685c6c1daeSBarry Smith   lg->xmax    = -1.e20;
1695c6c1daeSBarry Smith   lg->ymax    = -1.e20;
170a297a907SKarl Rupp 
1719566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
172a297a907SKarl Rupp 
173999739cfSJacob Faibussowitsch   lg->len         = dim * PETSC_DRAW_LG_CHUNK_SIZE;
1745c6c1daeSBarry Smith   lg->loc         = 0;
175b6fe0379SLisandro Dalcin   lg->use_markers = PETSC_FALSE;
176a297a907SKarl Rupp 
1779566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &lg->axis));
178a297a907SKarl Rupp 
179e118a51fSLisandro Dalcin   *outlg = lg;
1805c6c1daeSBarry Smith   PetscFunctionReturn(0);
1815c6c1daeSBarry Smith }
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith /*@
1845c6c1daeSBarry Smith    PetscDrawLGSetColors - Sets the color of each line graph drawn
1855c6c1daeSBarry Smith 
186*c3339decSBarry Smith    Logically Collective
1875c6c1daeSBarry Smith 
188d8d19677SJose E. Roman    Input Parameters:
1895c6c1daeSBarry Smith +  lg - the line graph context.
1905c6c1daeSBarry Smith -  colors - the colors
1915c6c1daeSBarry Smith 
1925c6c1daeSBarry Smith    Level: intermediate
1935c6c1daeSBarry Smith 
194811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
1955c6c1daeSBarry Smith @*/
196d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg, const int colors[])
197d71ae5a4SJacob Faibussowitsch {
1985c6c1daeSBarry Smith   PetscFunctionBegin;
1995c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
20045f3bb6eSLisandro Dalcin   if (lg->dim) PetscValidIntPointer(colors, 2);
201e118a51fSLisandro Dalcin 
2029566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
2039566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lg->dim, &lg->colors));
2049566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(lg->colors, colors, lg->dim));
2055c6c1daeSBarry Smith   PetscFunctionReturn(0);
2065c6c1daeSBarry Smith }
2075c6c1daeSBarry Smith 
2085c6c1daeSBarry Smith /*@C
2095c6c1daeSBarry Smith    PetscDrawLGSetLegend - sets the names of each curve plotted
2105c6c1daeSBarry Smith 
211*c3339decSBarry Smith    Logically Collective
2125c6c1daeSBarry Smith 
213d8d19677SJose E. Roman    Input Parameters:
2145c6c1daeSBarry Smith +  lg - the line graph context.
2155c6c1daeSBarry Smith -  names - the names for each curve
2165c6c1daeSBarry Smith 
2175c6c1daeSBarry Smith    Level: intermediate
2185c6c1daeSBarry Smith 
219811af0c4SBarry Smith    Note:
220811af0c4SBarry Smith     Call `PetscDrawLGGetAxis()` and then change properties of the `PetscDrawAxis` for detailed control of the plot
221ba1e01c4SBarry Smith 
222db781477SPatrick Sanan .seealso: `PetscDrawLGGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetHoldLimits()`
2235c6c1daeSBarry Smith @*/
224d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg, const char *const *names)
225d71ae5a4SJacob Faibussowitsch {
2265c6c1daeSBarry Smith   PetscInt i;
2275c6c1daeSBarry Smith 
2285c6c1daeSBarry Smith   PetscFunctionBegin;
2295c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
23045f3bb6eSLisandro Dalcin   if (names) PetscValidPointer(names, 2);
2315c6c1daeSBarry Smith 
2325c6c1daeSBarry Smith   if (lg->legend) {
23348a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2349566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2355c6c1daeSBarry Smith   }
2365c6c1daeSBarry Smith   if (names) {
2379566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(lg->dim, &lg->legend));
23848a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscStrallocpy(names[i], &lg->legend[i]));
2395c6c1daeSBarry Smith   }
2405c6c1daeSBarry Smith   PetscFunctionReturn(0);
2415c6c1daeSBarry Smith }
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith /*@
244811af0c4SBarry Smith    PetscDrawLGGetDimension - Get the number of curves that are to be drawn.
2455c6c1daeSBarry Smith 
2465b399a63SLisandro Dalcin    Not Collective
2475c6c1daeSBarry Smith 
2485c6c1daeSBarry Smith    Input Parameter:
2495c6c1daeSBarry Smith .  lg - the line graph context.
2505c6c1daeSBarry Smith 
2515c6c1daeSBarry Smith    Output Parameter:
2525c6c1daeSBarry Smith .  dim - the number of curves.
2535c6c1daeSBarry Smith 
2545c6c1daeSBarry Smith    Level: intermediate
2555c6c1daeSBarry Smith 
256811af0c4SBarry Smith .seealso: `PetscDrawLGC`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`
2575c6c1daeSBarry Smith @*/
258d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg, PetscInt *dim)
259d71ae5a4SJacob Faibussowitsch {
2605c6c1daeSBarry Smith   PetscFunctionBegin;
2615c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
26245f3bb6eSLisandro Dalcin   PetscValidIntPointer(dim, 2);
2635c6c1daeSBarry Smith   *dim = lg->dim;
2645c6c1daeSBarry Smith   PetscFunctionReturn(0);
2655c6c1daeSBarry Smith }
2665c6c1daeSBarry Smith 
2675c6c1daeSBarry Smith /*@
268811af0c4SBarry Smith    PetscDrawLGSetDimension - Change the number of curves that are to be drawn.
2695c6c1daeSBarry Smith 
270*c3339decSBarry Smith    Logically Collective
2715c6c1daeSBarry Smith 
272d8d19677SJose E. Roman    Input Parameters:
2735c6c1daeSBarry Smith +  lg - the line graph context.
2745c6c1daeSBarry Smith -  dim - the number of curves.
2755c6c1daeSBarry Smith 
2765c6c1daeSBarry Smith    Level: intermediate
2775c6c1daeSBarry Smith 
278db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLGGetDimension()`
2795c6c1daeSBarry Smith @*/
280d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg, PetscInt dim)
281d71ae5a4SJacob Faibussowitsch {
2825c6c1daeSBarry Smith   PetscInt i;
2835c6c1daeSBarry Smith 
2845c6c1daeSBarry Smith   PetscFunctionBegin;
2855c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2865c6c1daeSBarry Smith   PetscValidLogicalCollectiveInt(lg, dim, 2);
2875c6c1daeSBarry Smith   if (lg->dim == dim) PetscFunctionReturn(0);
2885c6c1daeSBarry Smith 
2899566063dSJacob Faibussowitsch   PetscCall(PetscFree2(lg->x, lg->y));
2905c6c1daeSBarry Smith   if (lg->legend) {
29148a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2929566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2935c6c1daeSBarry Smith   }
2949566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
2955c6c1daeSBarry Smith   lg->dim = dim;
2969566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
297999739cfSJacob Faibussowitsch   lg->len = dim * PETSC_DRAW_LG_CHUNK_SIZE;
2985c6c1daeSBarry Smith   PetscFunctionReturn(0);
2995c6c1daeSBarry Smith }
3005c6c1daeSBarry Smith 
30171917b75SLisandro Dalcin /*@
30271917b75SLisandro Dalcin    PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
30371917b75SLisandro Dalcin    points are added after this call, the limits will be adjusted to
30471917b75SLisandro Dalcin    include those additional points.
30571917b75SLisandro Dalcin 
306*c3339decSBarry Smith    Logically Collective
30771917b75SLisandro Dalcin 
30871917b75SLisandro Dalcin    Input Parameters:
30971917b75SLisandro Dalcin +  xlg - the line graph context
31071917b75SLisandro Dalcin -  x_min,x_max,y_min,y_max - the limits
31171917b75SLisandro Dalcin 
31271917b75SLisandro Dalcin    Level: intermediate
31371917b75SLisandro Dalcin 
314811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis`
31571917b75SLisandro Dalcin @*/
316d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max)
317d71ae5a4SJacob Faibussowitsch {
31871917b75SLisandro Dalcin   PetscFunctionBegin;
31971917b75SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
32071917b75SLisandro Dalcin 
32171917b75SLisandro Dalcin   (lg)->xmin = x_min;
32271917b75SLisandro Dalcin   (lg)->xmax = x_max;
32371917b75SLisandro Dalcin   (lg)->ymin = y_min;
32471917b75SLisandro Dalcin   (lg)->ymax = y_max;
32571917b75SLisandro Dalcin   PetscFunctionReturn(0);
32671917b75SLisandro Dalcin }
32771917b75SLisandro Dalcin 
3285c6c1daeSBarry Smith /*@
3295c6c1daeSBarry Smith    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
3305c6c1daeSBarry Smith 
331*c3339decSBarry Smith    Logically Collective
3325c6c1daeSBarry Smith 
3335c6c1daeSBarry Smith    Input Parameter:
3345c6c1daeSBarry Smith .  lg - the line graph context.
3355c6c1daeSBarry Smith 
3365c6c1daeSBarry Smith    Level: intermediate
3375c6c1daeSBarry Smith 
338811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3395c6c1daeSBarry Smith @*/
340d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGReset(PetscDrawLG lg)
341d71ae5a4SJacob Faibussowitsch {
3425c6c1daeSBarry Smith   PetscFunctionBegin;
3435c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
3445c6c1daeSBarry Smith   lg->xmin  = 1.e20;
3455c6c1daeSBarry Smith   lg->ymin  = 1.e20;
3465c6c1daeSBarry Smith   lg->xmax  = -1.e20;
3475c6c1daeSBarry Smith   lg->ymax  = -1.e20;
3485c6c1daeSBarry Smith   lg->loc   = 0;
3495c6c1daeSBarry Smith   lg->nopts = 0;
3505c6c1daeSBarry Smith   PetscFunctionReturn(0);
3515c6c1daeSBarry Smith }
3525c6c1daeSBarry Smith 
3535c6c1daeSBarry Smith /*@
3545c6c1daeSBarry Smith    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
3555c6c1daeSBarry Smith 
356*c3339decSBarry Smith    Collective
3575c6c1daeSBarry Smith 
3585c6c1daeSBarry Smith    Input Parameter:
3595c6c1daeSBarry Smith .  lg - the line graph context
3605c6c1daeSBarry Smith 
3615c6c1daeSBarry Smith    Level: intermediate
3625c6c1daeSBarry Smith 
363811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3645c6c1daeSBarry Smith @*/
365d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg)
366d71ae5a4SJacob Faibussowitsch {
3675c6c1daeSBarry Smith   PetscInt i;
3685c6c1daeSBarry Smith 
3695c6c1daeSBarry Smith   PetscFunctionBegin;
3705c6c1daeSBarry Smith   if (!*lg) PetscFunctionReturn(0);
371e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1);
3729371c9d4SSatish Balay   if (--((PetscObject)(*lg))->refct > 0) {
3739371c9d4SSatish Balay     *lg = NULL;
3749371c9d4SSatish Balay     PetscFunctionReturn(0);
3759371c9d4SSatish Balay   }
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith   if ((*lg)->legend) {
37848a46eb9SPierre Jolivet     for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i]));
3799566063dSJacob Faibussowitsch     PetscCall(PetscFree((*lg)->legend));
3805c6c1daeSBarry Smith   }
3819566063dSJacob Faibussowitsch   PetscCall(PetscFree((*lg)->colors));
3829566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*lg)->x, (*lg)->y));
3839566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*lg)->axis));
3849566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*lg)->win));
3859566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lg));
3865c6c1daeSBarry Smith   PetscFunctionReturn(0);
3875c6c1daeSBarry Smith }
3885c6c1daeSBarry Smith /*@
389811af0c4SBarry Smith    PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point.
3905c6c1daeSBarry Smith 
391*c3339decSBarry Smith    Logically Collective
3925c6c1daeSBarry Smith 
3935c6c1daeSBarry Smith    Input Parameters:
394287de1a7SBarry Smith +  lg - the linegraph context
395287de1a7SBarry Smith -  flg - should mark each data point
396287de1a7SBarry Smith 
397811af0c4SBarry Smith    Options Database Key:
398811af0c4SBarry Smith .  -lg_use_markers  <true,false> - true means it draws a marker for each point
3995c6c1daeSBarry Smith 
4005c6c1daeSBarry Smith    Level: intermediate
4015c6c1daeSBarry Smith 
402811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
4035c6c1daeSBarry Smith @*/
404d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg)
405d71ae5a4SJacob Faibussowitsch {
4065c6c1daeSBarry Smith   PetscFunctionBegin;
407e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
40845f3bb6eSLisandro Dalcin   PetscValidLogicalCollectiveBool(lg, flg, 2);
409b6fe0379SLisandro Dalcin   lg->use_markers = flg;
4105c6c1daeSBarry Smith   PetscFunctionReturn(0);
4115c6c1daeSBarry Smith }
4125c6c1daeSBarry Smith 
4135c6c1daeSBarry Smith /*@
4145c6c1daeSBarry Smith    PetscDrawLGDraw - Redraws a line graph.
4155c6c1daeSBarry Smith 
416*c3339decSBarry Smith    Collective
4175c6c1daeSBarry Smith 
4185c6c1daeSBarry Smith    Input Parameter:
4195c6c1daeSBarry Smith .  lg - the line graph context
4205c6c1daeSBarry Smith 
4215c6c1daeSBarry Smith    Level: intermediate
4225c6c1daeSBarry Smith 
423811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()`
4245c6c1daeSBarry Smith @*/
425d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg)
426d71ae5a4SJacob Faibussowitsch {
427e118a51fSLisandro Dalcin   PetscReal   xmin, xmax, ymin, ymax;
428e118a51fSLisandro Dalcin   PetscMPIInt rank;
429e118a51fSLisandro Dalcin   PetscDraw   draw;
4305c6c1daeSBarry Smith   PetscBool   isnull;
4315c6c1daeSBarry Smith 
4325c6c1daeSBarry Smith   PetscFunctionBegin;
4335c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
4349566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
4358f69470aSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
4369566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
4375c6c1daeSBarry Smith 
4385b399a63SLisandro Dalcin   draw = lg->win;
4399566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
4409566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
441e118a51fSLisandro Dalcin 
4429371c9d4SSatish Balay   xmin = lg->xmin;
4439371c9d4SSatish Balay   xmax = lg->xmax;
4449371c9d4SSatish Balay   ymin = lg->ymin;
4459371c9d4SSatish Balay   ymax = lg->ymax;
4469566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
4479566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
4485c6c1daeSBarry Smith 
449d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
450dd400576SPatrick Sanan   if (rank == 0) {
451e118a51fSLisandro Dalcin     int i, j, dim = lg->dim, nopts = lg->nopts, cl;
4525c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4535c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
4540ed3bfb6SBarry Smith         cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
4559566063dSJacob 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));
4569566063dSJacob Faibussowitsch         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl));
4575c6c1daeSBarry Smith       }
4585c6c1daeSBarry Smith     }
4595c6c1daeSBarry Smith   }
460dd400576SPatrick Sanan   if (rank == 0 && lg->legend) {
461088d793eSMatthew G. Knepley     PetscBool right = PETSC_FALSE;
462e118a51fSLisandro Dalcin     int       i, dim = lg->dim, cl;
4635c6c1daeSBarry Smith     PetscReal xl, yl, xr, yr, tw, th;
46471917b75SLisandro Dalcin     size_t    slen, len = 0;
4659566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr));
4669566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
4675c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4689566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(lg->legend[i], &slen));
46971917b75SLisandro Dalcin       len = PetscMax(len, slen);
4705c6c1daeSBarry Smith     }
471088d793eSMatthew G. Knepley     if (right) {
4729371c9d4SSatish Balay       xr = xr - 1.5 * tw;
4739371c9d4SSatish Balay       xl = xr - (len + 7) * tw;
474088d793eSMatthew G. Knepley     } else {
4759371c9d4SSatish Balay       xl = xl + 1.5 * tw;
4769371c9d4SSatish Balay       xr = xl + (len + 7) * tw;
477088d793eSMatthew G. Knepley     }
4789371c9d4SSatish Balay     yr = yr - 1.0 * th;
4799371c9d4SSatish Balay     yl = yr - (dim + 1) * th;
4809566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK));
4819566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK));
4829566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK));
4839566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK));
4845c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
48571917b75SLisandro Dalcin       cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
4869566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl));
4879566063dSJacob Faibussowitsch       PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i]));
4885c6c1daeSBarry Smith     }
4895c6c1daeSBarry Smith   }
490d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
4915b399a63SLisandro Dalcin 
4929566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
4939566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
4945c6c1daeSBarry Smith   PetscFunctionReturn(0);
4955c6c1daeSBarry Smith }
4965c6c1daeSBarry Smith 
49757fd6651SLisandro Dalcin /*@
49857fd6651SLisandro Dalcin   PetscDrawLGSave - Saves a drawn image
49957fd6651SLisandro Dalcin 
500*c3339decSBarry Smith   Collective
50157fd6651SLisandro Dalcin 
50257fd6651SLisandro Dalcin   Input Parameter:
50357fd6651SLisandro Dalcin . lg - The line graph context
50457fd6651SLisandro Dalcin 
50557fd6651SLisandro Dalcin   Level: intermediate
50657fd6651SLisandro Dalcin 
507811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`
50857fd6651SLisandro Dalcin @*/
509d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSave(PetscDrawLG lg)
510d71ae5a4SJacob Faibussowitsch {
51157fd6651SLisandro Dalcin   PetscFunctionBegin;
51257fd6651SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5139566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(lg->win));
51457fd6651SLisandro Dalcin   PetscFunctionReturn(0);
51557fd6651SLisandro Dalcin }
51657fd6651SLisandro Dalcin 
5175c6c1daeSBarry Smith /*@
51834a5a0e3SBarry Smith   PetscDrawLGView - Prints a line graph.
5195c6c1daeSBarry Smith 
520*c3339decSBarry Smith   Collective
5215c6c1daeSBarry Smith 
5225c6c1daeSBarry Smith   Input Parameter:
5235c6c1daeSBarry Smith . lg - the line graph context
5245c6c1daeSBarry Smith 
5255c6c1daeSBarry Smith   Level: beginner
5265c6c1daeSBarry Smith 
527811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
5285c6c1daeSBarry Smith @*/
529d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer)
530d71ae5a4SJacob Faibussowitsch {
5315c6c1daeSBarry Smith   PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax;
53234a5a0e3SBarry Smith   PetscInt  i, j, dim = lg->dim, nopts = lg->nopts;
5335c6c1daeSBarry Smith 
5345c6c1daeSBarry Smith   PetscFunctionBegin;
5355c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
536e118a51fSLisandro Dalcin 
5375c6c1daeSBarry Smith   if (nopts < 1) PetscFunctionReturn(0);
5385c6c1daeSBarry Smith   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
5395c6c1daeSBarry Smith 
54048a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer));
5419566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer));
5425c6c1daeSBarry Smith   for (i = 0; i < dim; i++) {
5439566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i));
54448a46eb9SPierre 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]));
5455c6c1daeSBarry Smith   }
5465c6c1daeSBarry Smith   PetscFunctionReturn(0);
5475c6c1daeSBarry Smith }
548287de1a7SBarry Smith 
549c2bac407SLisandro Dalcin /*@C
550c2bac407SLisandro Dalcin    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
551811af0c4SBarry Smith    `PetscDrawLG` options in the database.
552c2bac407SLisandro Dalcin 
553*c3339decSBarry Smith    Logically Collective
554c2bac407SLisandro Dalcin 
555d8d19677SJose E. Roman    Input Parameters:
556c2bac407SLisandro Dalcin +  lg - the line graph context
557c2bac407SLisandro Dalcin -  prefix - the prefix to prepend to all option names
558c2bac407SLisandro Dalcin 
559c2bac407SLisandro Dalcin    Level: advanced
560c2bac407SLisandro Dalcin 
561811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()`
562c2bac407SLisandro Dalcin @*/
563d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[])
564d71ae5a4SJacob Faibussowitsch {
565c2bac407SLisandro Dalcin   PetscFunctionBegin;
566c2bac407SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5679566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix));
568c2bac407SLisandro Dalcin   PetscFunctionReturn(0);
569c2bac407SLisandro Dalcin }
570c2bac407SLisandro Dalcin 
571287de1a7SBarry Smith /*@
572811af0c4SBarry Smith     PetscDrawLGSetFromOptions - Sets options related to the line graph object
573287de1a7SBarry Smith 
574*c3339decSBarry Smith     Collective
575287de1a7SBarry Smith 
576811af0c4SBarry Smith     Input Parameters:
577811af0c4SBarry Smith .   lg - the line graph context
578811af0c4SBarry Smith 
579811af0c4SBarry Smith     Options Database Key:
580811af0c4SBarry Smith .  -lg_use_markers  <true,false> - true means it draws a marker for each point
581287de1a7SBarry Smith 
582287de1a7SBarry Smith     Level: intermediate
583287de1a7SBarry Smith 
584811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()`
585287de1a7SBarry Smith @*/
586d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg)
587d71ae5a4SJacob Faibussowitsch {
58871917b75SLisandro Dalcin   PetscBool           usemarkers, set;
58971917b75SLisandro Dalcin   PetscDrawMarkerType markertype;
590287de1a7SBarry Smith 
591287de1a7SBarry Smith   PetscFunctionBegin;
592e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
593e118a51fSLisandro Dalcin 
5949566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetMarkerType(lg->win, &markertype));
5959566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set));
59671917b75SLisandro Dalcin   if (set) {
5979566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE));
5989566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetMarkerType(lg->win, markertype));
59971917b75SLisandro Dalcin   }
60071917b75SLisandro Dalcin   usemarkers = lg->use_markers;
6019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set));
6029566063dSJacob Faibussowitsch   if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers));
603287de1a7SBarry Smith   PetscFunctionReturn(0);
604287de1a7SBarry Smith }
605