xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 10450e9e44b354a0a3da7bbd573407bdf051df10)
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 
68aec76313SJacob Faibussowitsch   Developer Notes:
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:
309aec76313SJacob Faibussowitsch + lg    - the line graph context
3102fe279fdSBarry Smith . x_min - the horizontal lower limit
311aaa8cc7dSPierre 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 
510aec76313SJacob Faibussowitsch .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()`
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 
525*10450e9eSJacob Faibussowitsch   Input Parameters:
526*10450e9eSJacob Faibussowitsch + lg     - the line graph context
527*10450e9eSJacob Faibussowitsch - viewer - the viewer to view it with
5285c6c1daeSBarry Smith 
5295c6c1daeSBarry Smith   Level: beginner
5305c6c1daeSBarry Smith 
531811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
5325c6c1daeSBarry Smith @*/
533d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer)
534d71ae5a4SJacob Faibussowitsch {
5355c6c1daeSBarry Smith   PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax;
53634a5a0e3SBarry Smith   PetscInt  i, j, dim = lg->dim, nopts = lg->nopts;
5375c6c1daeSBarry Smith 
5385c6c1daeSBarry Smith   PetscFunctionBegin;
5395c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
540e118a51fSLisandro Dalcin 
5413ba16761SJacob Faibussowitsch   if (nopts < 1) PetscFunctionReturn(PETSC_SUCCESS);
5423ba16761SJacob Faibussowitsch   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(PETSC_SUCCESS);
5435c6c1daeSBarry Smith 
54448a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer));
5459566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer));
5465c6c1daeSBarry Smith   for (i = 0; i < dim; i++) {
5479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i));
54848a46eb9SPierre 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]));
5495c6c1daeSBarry Smith   }
5503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5515c6c1daeSBarry Smith }
552287de1a7SBarry Smith 
553c2bac407SLisandro Dalcin /*@C
554c2bac407SLisandro Dalcin   PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
555811af0c4SBarry Smith   `PetscDrawLG` options in the database.
556c2bac407SLisandro Dalcin 
557c3339decSBarry Smith   Logically Collective
558c2bac407SLisandro Dalcin 
559d8d19677SJose E. Roman   Input Parameters:
560c2bac407SLisandro Dalcin + lg     - the line graph context
561c2bac407SLisandro Dalcin - prefix - the prefix to prepend to all option names
562c2bac407SLisandro Dalcin 
563c2bac407SLisandro Dalcin   Level: advanced
564c2bac407SLisandro Dalcin 
565811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()`
566c2bac407SLisandro Dalcin @*/
567d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[])
568d71ae5a4SJacob Faibussowitsch {
569c2bac407SLisandro Dalcin   PetscFunctionBegin;
570c2bac407SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5719566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix));
5723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
573c2bac407SLisandro Dalcin }
574c2bac407SLisandro Dalcin 
575287de1a7SBarry Smith /*@
576811af0c4SBarry Smith   PetscDrawLGSetFromOptions - Sets options related to the line graph object
577287de1a7SBarry Smith 
578c3339decSBarry Smith   Collective
579287de1a7SBarry Smith 
580811af0c4SBarry Smith   Input Parameters:
581811af0c4SBarry Smith . lg - the line graph context
582811af0c4SBarry Smith 
583811af0c4SBarry Smith   Options Database Key:
584811af0c4SBarry Smith . -lg_use_markers  <true,false> - true means it draws a marker for each point
585287de1a7SBarry Smith 
586287de1a7SBarry Smith   Level: intermediate
587287de1a7SBarry Smith 
588811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()`
589287de1a7SBarry Smith @*/
590d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg)
591d71ae5a4SJacob Faibussowitsch {
59271917b75SLisandro Dalcin   PetscBool           usemarkers, set;
59371917b75SLisandro Dalcin   PetscDrawMarkerType markertype;
594287de1a7SBarry Smith 
595287de1a7SBarry Smith   PetscFunctionBegin;
596e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
597e118a51fSLisandro Dalcin 
5989566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetMarkerType(lg->win, &markertype));
5999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set));
60071917b75SLisandro Dalcin   if (set) {
6019566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE));
6029566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetMarkerType(lg->win, markertype));
60371917b75SLisandro Dalcin   }
60471917b75SLisandro Dalcin   usemarkers = lg->use_markers;
6059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set));
6069566063dSJacob Faibussowitsch   if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers));
6073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
608287de1a7SBarry Smith }
609