xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision aaa8cc7d2a5c3913edcbb923e20f154fe9c4aa65)
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;
303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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;
543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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 
60c3339decSBarry 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));
853ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
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));
1203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1215c6c1daeSBarry Smith }
1225c6c1daeSBarry Smith 
1235c6c1daeSBarry Smith /*@
1245c6c1daeSBarry Smith     PetscDrawLGCreate - Creates a line graph data structure.
1255c6c1daeSBarry Smith 
126c3339decSBarry 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 
1322fe279fdSBarry Smith     Output Parameter:
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;
1803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1815c6c1daeSBarry Smith }
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith /*@
1845c6c1daeSBarry Smith    PetscDrawLGSetColors - Sets the color of each line graph drawn
1855c6c1daeSBarry Smith 
186c3339decSBarry 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));
2053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2065c6c1daeSBarry Smith }
2075c6c1daeSBarry Smith 
2085c6c1daeSBarry Smith /*@C
2095c6c1daeSBarry Smith    PetscDrawLGSetLegend - sets the names of each curve plotted
2105c6c1daeSBarry Smith 
211c3339decSBarry 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   }
2403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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;
2643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2655c6c1daeSBarry Smith }
2665c6c1daeSBarry Smith 
2675c6c1daeSBarry Smith /*@
268811af0c4SBarry Smith    PetscDrawLGSetDimension - Change the number of curves that are to be drawn.
2695c6c1daeSBarry Smith 
270c3339decSBarry 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);
2873ba16761SJacob Faibussowitsch   if (lg->dim == dim) PetscFunctionReturn(PETSC_SUCCESS);
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;
2983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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 
306c3339decSBarry Smith    Logically Collective
30771917b75SLisandro Dalcin 
30871917b75SLisandro Dalcin    Input Parameters:
30971917b75SLisandro Dalcin +  xlg - the line graph context
3102fe279fdSBarry Smith .  x_min - the horizontal lower limit
311*aaa8cc7dSPierre Jolivet .  x_max - the horizontal upper limit
3122fe279fdSBarry Smith .  y_min - the vertical lower limit
3132fe279fdSBarry Smith -  y_max - the vertical upper limit
31471917b75SLisandro Dalcin 
31571917b75SLisandro Dalcin    Level: intermediate
31671917b75SLisandro Dalcin 
317811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis`
31871917b75SLisandro Dalcin @*/
319d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max)
320d71ae5a4SJacob Faibussowitsch {
32171917b75SLisandro Dalcin   PetscFunctionBegin;
32271917b75SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
32371917b75SLisandro Dalcin 
32471917b75SLisandro Dalcin   (lg)->xmin = x_min;
32571917b75SLisandro Dalcin   (lg)->xmax = x_max;
32671917b75SLisandro Dalcin   (lg)->ymin = y_min;
32771917b75SLisandro Dalcin   (lg)->ymax = y_max;
3283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32971917b75SLisandro Dalcin }
33071917b75SLisandro Dalcin 
3315c6c1daeSBarry Smith /*@
3325c6c1daeSBarry Smith    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
3335c6c1daeSBarry Smith 
334c3339decSBarry Smith    Logically Collective
3355c6c1daeSBarry Smith 
3365c6c1daeSBarry Smith    Input Parameter:
3375c6c1daeSBarry Smith .  lg - the line graph context.
3385c6c1daeSBarry Smith 
3395c6c1daeSBarry Smith    Level: intermediate
3405c6c1daeSBarry Smith 
341811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3425c6c1daeSBarry Smith @*/
343d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGReset(PetscDrawLG lg)
344d71ae5a4SJacob Faibussowitsch {
3455c6c1daeSBarry Smith   PetscFunctionBegin;
3465c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
3475c6c1daeSBarry Smith   lg->xmin  = 1.e20;
3485c6c1daeSBarry Smith   lg->ymin  = 1.e20;
3495c6c1daeSBarry Smith   lg->xmax  = -1.e20;
3505c6c1daeSBarry Smith   lg->ymax  = -1.e20;
3515c6c1daeSBarry Smith   lg->loc   = 0;
3525c6c1daeSBarry Smith   lg->nopts = 0;
3533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3545c6c1daeSBarry Smith }
3555c6c1daeSBarry Smith 
3565c6c1daeSBarry Smith /*@
3575c6c1daeSBarry Smith    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
3585c6c1daeSBarry Smith 
359c3339decSBarry Smith    Collective
3605c6c1daeSBarry Smith 
3615c6c1daeSBarry Smith    Input Parameter:
3625c6c1daeSBarry Smith .  lg - the line graph context
3635c6c1daeSBarry Smith 
3645c6c1daeSBarry Smith    Level: intermediate
3655c6c1daeSBarry Smith 
366811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3675c6c1daeSBarry Smith @*/
368d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg)
369d71ae5a4SJacob Faibussowitsch {
3705c6c1daeSBarry Smith   PetscInt i;
3715c6c1daeSBarry Smith 
3725c6c1daeSBarry Smith   PetscFunctionBegin;
3733ba16761SJacob Faibussowitsch   if (!*lg) PetscFunctionReturn(PETSC_SUCCESS);
374e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1);
3759371c9d4SSatish Balay   if (--((PetscObject)(*lg))->refct > 0) {
3769371c9d4SSatish Balay     *lg = NULL;
3773ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
3789371c9d4SSatish Balay   }
3795c6c1daeSBarry Smith 
3805c6c1daeSBarry Smith   if ((*lg)->legend) {
38148a46eb9SPierre Jolivet     for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i]));
3829566063dSJacob Faibussowitsch     PetscCall(PetscFree((*lg)->legend));
3835c6c1daeSBarry Smith   }
3849566063dSJacob Faibussowitsch   PetscCall(PetscFree((*lg)->colors));
3859566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*lg)->x, (*lg)->y));
3869566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*lg)->axis));
3879566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*lg)->win));
3889566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lg));
3893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3905c6c1daeSBarry Smith }
3915c6c1daeSBarry Smith /*@
392811af0c4SBarry Smith    PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point.
3935c6c1daeSBarry Smith 
394c3339decSBarry Smith    Logically Collective
3955c6c1daeSBarry Smith 
3965c6c1daeSBarry Smith    Input Parameters:
397287de1a7SBarry Smith +  lg - the linegraph context
398287de1a7SBarry Smith -  flg - should mark each data point
399287de1a7SBarry Smith 
400811af0c4SBarry Smith    Options Database Key:
401811af0c4SBarry Smith .  -lg_use_markers  <true,false> - true means it draws a marker for each point
4025c6c1daeSBarry Smith 
4035c6c1daeSBarry Smith    Level: intermediate
4045c6c1daeSBarry Smith 
405811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
4065c6c1daeSBarry Smith @*/
407d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg)
408d71ae5a4SJacob Faibussowitsch {
4095c6c1daeSBarry Smith   PetscFunctionBegin;
410e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
41145f3bb6eSLisandro Dalcin   PetscValidLogicalCollectiveBool(lg, flg, 2);
412b6fe0379SLisandro Dalcin   lg->use_markers = flg;
4133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4145c6c1daeSBarry Smith }
4155c6c1daeSBarry Smith 
4165c6c1daeSBarry Smith /*@
4175c6c1daeSBarry Smith    PetscDrawLGDraw - Redraws a line graph.
4185c6c1daeSBarry Smith 
419c3339decSBarry Smith    Collective
4205c6c1daeSBarry Smith 
4215c6c1daeSBarry Smith    Input Parameter:
4225c6c1daeSBarry Smith .  lg - the line graph context
4235c6c1daeSBarry Smith 
4245c6c1daeSBarry Smith    Level: intermediate
4255c6c1daeSBarry Smith 
426811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()`
4275c6c1daeSBarry Smith @*/
428d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg)
429d71ae5a4SJacob Faibussowitsch {
430e118a51fSLisandro Dalcin   PetscReal   xmin, xmax, ymin, ymax;
431e118a51fSLisandro Dalcin   PetscMPIInt rank;
432e118a51fSLisandro Dalcin   PetscDraw   draw;
4335c6c1daeSBarry Smith   PetscBool   isnull;
4345c6c1daeSBarry Smith 
4355c6c1daeSBarry Smith   PetscFunctionBegin;
4365c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
4379566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
4383ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
4399566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
4405c6c1daeSBarry Smith 
4415b399a63SLisandro Dalcin   draw = lg->win;
4429566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
4439566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
444e118a51fSLisandro Dalcin 
4459371c9d4SSatish Balay   xmin = lg->xmin;
4469371c9d4SSatish Balay   xmax = lg->xmax;
4479371c9d4SSatish Balay   ymin = lg->ymin;
4489371c9d4SSatish Balay   ymax = lg->ymax;
4499566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
4509566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
4515c6c1daeSBarry Smith 
452d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
453dd400576SPatrick Sanan   if (rank == 0) {
454e118a51fSLisandro Dalcin     int i, j, dim = lg->dim, nopts = lg->nopts, cl;
4555c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4565c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
4570ed3bfb6SBarry Smith         cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
4589566063dSJacob 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));
4599566063dSJacob Faibussowitsch         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl));
4605c6c1daeSBarry Smith       }
4615c6c1daeSBarry Smith     }
4625c6c1daeSBarry Smith   }
463dd400576SPatrick Sanan   if (rank == 0 && lg->legend) {
464088d793eSMatthew G. Knepley     PetscBool right = PETSC_FALSE;
465e118a51fSLisandro Dalcin     int       i, dim = lg->dim, cl;
4665c6c1daeSBarry Smith     PetscReal xl, yl, xr, yr, tw, th;
46771917b75SLisandro Dalcin     size_t    slen, len = 0;
4689566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr));
4699566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
4705c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4719566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(lg->legend[i], &slen));
47271917b75SLisandro Dalcin       len = PetscMax(len, slen);
4735c6c1daeSBarry Smith     }
474088d793eSMatthew G. Knepley     if (right) {
4759371c9d4SSatish Balay       xr = xr - 1.5 * tw;
4769371c9d4SSatish Balay       xl = xr - (len + 7) * tw;
477088d793eSMatthew G. Knepley     } else {
4789371c9d4SSatish Balay       xl = xl + 1.5 * tw;
4799371c9d4SSatish Balay       xr = xl + (len + 7) * tw;
480088d793eSMatthew G. Knepley     }
4819371c9d4SSatish Balay     yr = yr - 1.0 * th;
4829371c9d4SSatish Balay     yl = yr - (dim + 1) * th;
4839566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK));
4849566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK));
4859566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK));
4869566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK));
4875c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
48871917b75SLisandro Dalcin       cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
4899566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl));
4909566063dSJacob Faibussowitsch       PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i]));
4915c6c1daeSBarry Smith     }
4925c6c1daeSBarry Smith   }
493d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
4945b399a63SLisandro Dalcin 
4959566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
4969566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
4973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4985c6c1daeSBarry Smith }
4995c6c1daeSBarry Smith 
50057fd6651SLisandro Dalcin /*@
50157fd6651SLisandro Dalcin   PetscDrawLGSave - Saves a drawn image
50257fd6651SLisandro Dalcin 
503c3339decSBarry Smith   Collective
50457fd6651SLisandro Dalcin 
50557fd6651SLisandro Dalcin   Input Parameter:
50657fd6651SLisandro Dalcin . lg - The line graph context
50757fd6651SLisandro Dalcin 
50857fd6651SLisandro Dalcin   Level: intermediate
50957fd6651SLisandro Dalcin 
510811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`
51157fd6651SLisandro Dalcin @*/
512d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSave(PetscDrawLG lg)
513d71ae5a4SJacob Faibussowitsch {
51457fd6651SLisandro Dalcin   PetscFunctionBegin;
51557fd6651SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5169566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(lg->win));
5173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
51857fd6651SLisandro Dalcin }
51957fd6651SLisandro Dalcin 
5205c6c1daeSBarry Smith /*@
52134a5a0e3SBarry Smith   PetscDrawLGView - Prints a line graph.
5225c6c1daeSBarry Smith 
523c3339decSBarry Smith   Collective
5245c6c1daeSBarry Smith 
5255c6c1daeSBarry Smith   Input Parameter:
5265c6c1daeSBarry Smith . lg - the line graph context
5275c6c1daeSBarry Smith 
5285c6c1daeSBarry Smith   Level: beginner
5295c6c1daeSBarry Smith 
530811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
5315c6c1daeSBarry Smith @*/
532d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer)
533d71ae5a4SJacob Faibussowitsch {
5345c6c1daeSBarry Smith   PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax;
53534a5a0e3SBarry Smith   PetscInt  i, j, dim = lg->dim, nopts = lg->nopts;
5365c6c1daeSBarry Smith 
5375c6c1daeSBarry Smith   PetscFunctionBegin;
5385c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
539e118a51fSLisandro Dalcin 
5403ba16761SJacob Faibussowitsch   if (nopts < 1) PetscFunctionReturn(PETSC_SUCCESS);
5413ba16761SJacob Faibussowitsch   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(PETSC_SUCCESS);
5425c6c1daeSBarry Smith 
54348a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer));
5449566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer));
5455c6c1daeSBarry Smith   for (i = 0; i < dim; i++) {
5469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i));
54748a46eb9SPierre 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]));
5485c6c1daeSBarry Smith   }
5493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5505c6c1daeSBarry Smith }
551287de1a7SBarry Smith 
552c2bac407SLisandro Dalcin /*@C
553c2bac407SLisandro Dalcin    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
554811af0c4SBarry Smith    `PetscDrawLG` options in the database.
555c2bac407SLisandro Dalcin 
556c3339decSBarry Smith    Logically Collective
557c2bac407SLisandro Dalcin 
558d8d19677SJose E. Roman    Input Parameters:
559c2bac407SLisandro Dalcin +  lg - the line graph context
560c2bac407SLisandro Dalcin -  prefix - the prefix to prepend to all option names
561c2bac407SLisandro Dalcin 
562c2bac407SLisandro Dalcin    Level: advanced
563c2bac407SLisandro Dalcin 
564811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()`
565c2bac407SLisandro Dalcin @*/
566d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[])
567d71ae5a4SJacob Faibussowitsch {
568c2bac407SLisandro Dalcin   PetscFunctionBegin;
569c2bac407SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5709566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix));
5713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
572c2bac407SLisandro Dalcin }
573c2bac407SLisandro Dalcin 
574287de1a7SBarry Smith /*@
575811af0c4SBarry Smith     PetscDrawLGSetFromOptions - Sets options related to the line graph object
576287de1a7SBarry Smith 
577c3339decSBarry Smith     Collective
578287de1a7SBarry Smith 
579811af0c4SBarry Smith     Input Parameters:
580811af0c4SBarry Smith .   lg - the line graph context
581811af0c4SBarry Smith 
582811af0c4SBarry Smith     Options Database Key:
583811af0c4SBarry Smith .  -lg_use_markers  <true,false> - true means it draws a marker for each point
584287de1a7SBarry Smith 
585287de1a7SBarry Smith     Level: intermediate
586287de1a7SBarry Smith 
587811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()`
588287de1a7SBarry Smith @*/
589d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg)
590d71ae5a4SJacob Faibussowitsch {
59171917b75SLisandro Dalcin   PetscBool           usemarkers, set;
59271917b75SLisandro Dalcin   PetscDrawMarkerType markertype;
593287de1a7SBarry Smith 
594287de1a7SBarry Smith   PetscFunctionBegin;
595e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
596e118a51fSLisandro Dalcin 
5979566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetMarkerType(lg->win, &markertype));
5989566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set));
59971917b75SLisandro Dalcin   if (set) {
6009566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE));
6019566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetMarkerType(lg->win, markertype));
60271917b75SLisandro Dalcin   }
60371917b75SLisandro Dalcin   usemarkers = lg->use_markers;
6049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set));
6059566063dSJacob Faibussowitsch   if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers));
6063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
607287de1a7SBarry Smith }
608