xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 6497c311e7b976d467be1503c1effce92a60525c)
15ccc9f3cSMatthew G Knepley #include <petscviewer.h>
2999739cfSJacob Faibussowitsch #include <petsc/private/drawimpl.h> /*I   "petscdraw.h"  I*/
35c6c1daeSBarry Smith PetscClassId PETSC_DRAWLG_CLASSID = 0;
45c6c1daeSBarry Smith 
55c6c1daeSBarry Smith /*@
65c6c1daeSBarry Smith   PetscDrawLGGetAxis - Gets the axis context associated with a line graph.
75c6c1daeSBarry Smith   This is useful if one wants to change some axis property, such as
85c6c1daeSBarry Smith   labels, color, etc. The axis context should not be destroyed by the
95c6c1daeSBarry Smith   application code.
105c6c1daeSBarry Smith 
11811af0c4SBarry Smith   Not Collective, if lg is parallel then axis is parallel
125c6c1daeSBarry Smith 
135c6c1daeSBarry Smith   Input Parameter:
145c6c1daeSBarry Smith . lg - the line graph context
155c6c1daeSBarry Smith 
165c6c1daeSBarry Smith   Output Parameter:
175c6c1daeSBarry Smith . axis - the axis context
185c6c1daeSBarry Smith 
195c6c1daeSBarry Smith   Level: advanced
205c6c1daeSBarry Smith 
21811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawAxis`, `PetscDrawLG`
225c6c1daeSBarry Smith @*/
23d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGGetAxis(PetscDrawLG lg, PetscDrawAxis *axis)
24d71ae5a4SJacob Faibussowitsch {
255c6c1daeSBarry Smith   PetscFunctionBegin;
26e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
274f572ea9SToby Isaac   PetscAssertPointer(axis, 2);
285c6c1daeSBarry Smith   *axis = lg->axis;
293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
305c6c1daeSBarry Smith }
315c6c1daeSBarry Smith 
325c6c1daeSBarry Smith /*@
335c6c1daeSBarry Smith   PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
345c6c1daeSBarry Smith 
35811af0c4SBarry Smith   Not Collective, if lg is parallel then draw is parallel
365c6c1daeSBarry Smith 
375c6c1daeSBarry Smith   Input Parameter:
385c6c1daeSBarry Smith . lg - the line graph context
395c6c1daeSBarry Smith 
405c6c1daeSBarry Smith   Output Parameter:
415c6c1daeSBarry Smith . draw - the draw context
425c6c1daeSBarry Smith 
435c6c1daeSBarry Smith   Level: intermediate
445c6c1daeSBarry Smith 
45811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDraw`, `PetscDrawLG`
465c6c1daeSBarry Smith @*/
47d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGGetDraw(PetscDrawLG lg, PetscDraw *draw)
48d71ae5a4SJacob Faibussowitsch {
495c6c1daeSBarry Smith   PetscFunctionBegin;
505c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
514f572ea9SToby Isaac   PetscAssertPointer(draw, 2);
525c6c1daeSBarry Smith   *draw = lg->win;
533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
545c6c1daeSBarry Smith }
555c6c1daeSBarry Smith 
565c6c1daeSBarry Smith /*@
57811af0c4SBarry Smith   PetscDrawLGSPDraw - Redraws a line graph and a scatter plot on the same `PetscDraw` they must share
585c6c1daeSBarry Smith 
59c3339decSBarry Smith   Collective
605c6c1daeSBarry Smith 
61811af0c4SBarry Smith   Input Parameters:
62811af0c4SBarry Smith + lg   - the line graph context
63811af0c4SBarry Smith - spin - the scatter plot
645c6c1daeSBarry Smith 
655c6c1daeSBarry Smith   Level: intermediate
665c6c1daeSBarry Smith 
67aec76313SJacob Faibussowitsch   Developer Notes:
68811af0c4SBarry Smith   This code cheats and uses the fact that the `PetscDrawLG` and `PetscDrawSP` structs are the same
69811af0c4SBarry Smith 
70db781477SPatrick Sanan .seealso: `PetscDrawLGDraw()`, `PetscDrawSPDraw()`
715c6c1daeSBarry Smith @*/
72d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSPDraw(PetscDrawLG lg, PetscDrawSP spin)
73d71ae5a4SJacob Faibussowitsch {
745c6c1daeSBarry Smith   PetscDrawLG sp = (PetscDrawLG)spin;
755c6c1daeSBarry Smith   PetscReal   xmin, xmax, ymin, ymax;
76e118a51fSLisandro Dalcin   PetscBool   isnull;
77e118a51fSLisandro Dalcin   PetscMPIInt rank;
78e118a51fSLisandro Dalcin   PetscDraw   draw;
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith   PetscFunctionBegin;
815c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
82064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(sp, PETSC_DRAWLG_CLASSID, 2);
839566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
843ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
859566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
865c6c1daeSBarry Smith 
875b399a63SLisandro Dalcin   draw = lg->win;
889566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
899566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
90e118a51fSLisandro Dalcin 
919371c9d4SSatish Balay   xmin = PetscMin(lg->xmin, sp->xmin);
929371c9d4SSatish Balay   ymin = PetscMin(lg->ymin, sp->ymin);
939371c9d4SSatish Balay   xmax = PetscMax(lg->xmax, sp->xmax);
949371c9d4SSatish Balay   ymax = PetscMax(lg->ymax, sp->ymax);
959566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
969566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
975c6c1daeSBarry Smith 
98d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
99dd400576SPatrick Sanan   if (rank == 0) {
100e118a51fSLisandro Dalcin     int i, j, dim, nopts;
1015c6c1daeSBarry Smith     dim   = lg->dim;
1025c6c1daeSBarry Smith     nopts = lg->nopts;
1035c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
1045c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
1059566063dSJacob 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));
10648a46eb9SPierre Jolivet         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], PETSC_DRAW_RED));
1075c6c1daeSBarry Smith       }
1085c6c1daeSBarry Smith     }
1095c6c1daeSBarry Smith     dim   = sp->dim;
1105c6c1daeSBarry Smith     nopts = sp->nopts;
1115c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
11248a46eb9SPierre Jolivet       for (j = 0; j < nopts; j++) PetscCall(PetscDrawMarker(draw, sp->x[j * dim + i], sp->y[j * dim + i], PETSC_DRAW_RED));
1135c6c1daeSBarry Smith     }
1145c6c1daeSBarry Smith   }
115d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
1165b399a63SLisandro Dalcin 
1179566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
1189566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1205c6c1daeSBarry Smith }
1215c6c1daeSBarry Smith 
1225c6c1daeSBarry Smith /*@
1235c6c1daeSBarry Smith   PetscDrawLGCreate - Creates a line graph data structure.
1245c6c1daeSBarry Smith 
125c3339decSBarry Smith   Collective
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith   Input Parameters:
1285c6c1daeSBarry Smith + draw - the window where the graph will be made.
1295c6c1daeSBarry Smith - dim  - the number of curves which will be drawn
1305c6c1daeSBarry Smith 
1312fe279fdSBarry Smith   Output Parameter:
132e118a51fSLisandro Dalcin . outlg - the line graph context
1335c6c1daeSBarry Smith 
1345c6c1daeSBarry Smith   Level: intermediate
1355c6c1daeSBarry Smith 
13695452b02SPatrick Sanan   Notes:
137811af0c4SBarry 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
138811af0c4SBarry Smith   zeroth MPI process in the communicator.
1397e25d57eSBarry Smith 
140811af0c4SBarry Smith   All MPI ranks in the communicator must call `PetscDrawLGDraw()` to display the updated graph.
141811af0c4SBarry Smith 
14242747ad1SJacob Faibussowitsch .seealso: `PetscDrawLGDestroy()`, `PetscDrawLGAddPoint()`, `PetscDrawLGAddCommonPoint()`, `PetscDrawLGAddPoints()`, `PetscDrawLGDraw()`, `PetscDrawLGSave()`,
143db781477SPatrick Sanan           `PetscDrawLGView()`, `PetscDrawLGReset()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()`, `PetscDrawLGSetLegend()`, `PetscDrawLGGetAxis()`,
144db781477SPatrick Sanan           `PetscDrawLGGetDraw()`, `PetscDrawLGSetUseMarkers()`, `PetscDrawLGSetLimits()`, `PetscDrawLGSetColors()`, `PetscDrawLGSetOptionsPrefix()`, `PetscDrawLGSetFromOptions()`
1455c6c1daeSBarry Smith @*/
146d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGCreate(PetscDraw draw, PetscInt dim, PetscDrawLG *outlg)
147d71ae5a4SJacob Faibussowitsch {
1485c6c1daeSBarry Smith   PetscDrawLG lg;
1495c6c1daeSBarry Smith 
1505c6c1daeSBarry Smith   PetscFunctionBegin;
1515c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
152e118a51fSLisandro Dalcin   PetscValidLogicalCollectiveInt(draw, dim, 2);
1534f572ea9SToby Isaac   PetscAssertPointer(outlg, 3);
154e118a51fSLisandro Dalcin 
1559566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(lg, PETSC_DRAWLG_CLASSID, "DrawLG", "Line Graph", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawLGDestroy, NULL));
1569566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetOptionsPrefix(lg, ((PetscObject)draw)->prefix));
157e118a51fSLisandro Dalcin 
1589566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)draw));
159e118a51fSLisandro Dalcin   lg->win = draw;
160a297a907SKarl Rupp 
16169c83917SLisandro Dalcin   lg->view    = NULL;
16269c83917SLisandro Dalcin   lg->destroy = NULL;
1635c6c1daeSBarry Smith   lg->nopts   = 0;
164*6497c311SBarry Smith   lg->dim     = (int)dim;
1655c6c1daeSBarry Smith   lg->xmin    = 1.e20;
1665c6c1daeSBarry Smith   lg->ymin    = 1.e20;
1675c6c1daeSBarry Smith   lg->xmax    = -1.e20;
1685c6c1daeSBarry Smith   lg->ymax    = -1.e20;
169a297a907SKarl Rupp 
1709566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
171a297a907SKarl Rupp 
172*6497c311SBarry Smith   lg->len         = (int)(dim * PETSC_DRAW_LG_CHUNK_SIZE);
1735c6c1daeSBarry Smith   lg->loc         = 0;
174b6fe0379SLisandro Dalcin   lg->use_markers = PETSC_FALSE;
175a297a907SKarl Rupp 
1769566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &lg->axis));
177a297a907SKarl Rupp 
178e118a51fSLisandro Dalcin   *outlg = lg;
1793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1805c6c1daeSBarry Smith }
1815c6c1daeSBarry Smith 
1825c6c1daeSBarry Smith /*@
1835c6c1daeSBarry Smith   PetscDrawLGSetColors - Sets the color of each line graph drawn
1845c6c1daeSBarry Smith 
185c3339decSBarry Smith   Logically Collective
1865c6c1daeSBarry Smith 
187d8d19677SJose E. Roman   Input Parameters:
1885c6c1daeSBarry Smith + lg     - the line graph context.
1895c6c1daeSBarry Smith - colors - the colors
1905c6c1daeSBarry Smith 
1915c6c1daeSBarry Smith   Level: intermediate
1925c6c1daeSBarry Smith 
193811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
1945c6c1daeSBarry Smith @*/
195d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg, const int colors[])
196d71ae5a4SJacob Faibussowitsch {
1975c6c1daeSBarry Smith   PetscFunctionBegin;
1985c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
1994f572ea9SToby Isaac   if (lg->dim) PetscAssertPointer(colors, 2);
200e118a51fSLisandro Dalcin 
2019566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
2029566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lg->dim, &lg->colors));
2039566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(lg->colors, colors, lg->dim));
2043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2055c6c1daeSBarry Smith }
2065c6c1daeSBarry Smith 
2075c6c1daeSBarry Smith /*@C
2085c6c1daeSBarry Smith   PetscDrawLGSetLegend - sets the names of each curve plotted
2095c6c1daeSBarry Smith 
210c3339decSBarry Smith   Logically Collective
2115c6c1daeSBarry Smith 
212d8d19677SJose E. Roman   Input Parameters:
2135c6c1daeSBarry Smith + lg    - the line graph context.
2145c6c1daeSBarry Smith - names - the names for each curve
2155c6c1daeSBarry Smith 
2165c6c1daeSBarry Smith   Level: intermediate
2175c6c1daeSBarry Smith 
218811af0c4SBarry Smith   Note:
219811af0c4SBarry Smith   Call `PetscDrawLGGetAxis()` and then change properties of the `PetscDrawAxis` for detailed control of the plot
220ba1e01c4SBarry Smith 
221db781477SPatrick Sanan .seealso: `PetscDrawLGGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetHoldLimits()`
2225c6c1daeSBarry Smith @*/
223cc4c1da9SBarry Smith PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg, const char *const names[])
224d71ae5a4SJacob Faibussowitsch {
2255c6c1daeSBarry Smith   PetscInt i;
2265c6c1daeSBarry Smith 
2275c6c1daeSBarry Smith   PetscFunctionBegin;
2285c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2294f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 2);
2305c6c1daeSBarry Smith 
2315c6c1daeSBarry Smith   if (lg->legend) {
23248a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2339566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2345c6c1daeSBarry Smith   }
2355c6c1daeSBarry Smith   if (names) {
2369566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(lg->dim, &lg->legend));
23748a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscStrallocpy(names[i], &lg->legend[i]));
2385c6c1daeSBarry Smith   }
2393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2405c6c1daeSBarry Smith }
2415c6c1daeSBarry Smith 
2425c6c1daeSBarry Smith /*@
243811af0c4SBarry Smith   PetscDrawLGGetDimension - Get the number of curves that are to be drawn.
2445c6c1daeSBarry Smith 
2455b399a63SLisandro Dalcin   Not Collective
2465c6c1daeSBarry Smith 
2475c6c1daeSBarry Smith   Input Parameter:
2485c6c1daeSBarry Smith . lg - the line graph context.
2495c6c1daeSBarry Smith 
2505c6c1daeSBarry Smith   Output Parameter:
2515c6c1daeSBarry Smith . dim - the number of curves.
2525c6c1daeSBarry Smith 
2535c6c1daeSBarry Smith   Level: intermediate
2545c6c1daeSBarry Smith 
255811af0c4SBarry Smith .seealso: `PetscDrawLGC`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`
2565c6c1daeSBarry Smith @*/
257d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg, PetscInt *dim)
258d71ae5a4SJacob Faibussowitsch {
2595c6c1daeSBarry Smith   PetscFunctionBegin;
2605c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2614f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
2625c6c1daeSBarry Smith   *dim = lg->dim;
2633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2645c6c1daeSBarry Smith }
2655c6c1daeSBarry Smith 
2665c6c1daeSBarry Smith /*@
267811af0c4SBarry Smith   PetscDrawLGSetDimension - Change the number of curves that are to be drawn.
2685c6c1daeSBarry Smith 
269c3339decSBarry Smith   Logically Collective
2705c6c1daeSBarry Smith 
271d8d19677SJose E. Roman   Input Parameters:
2725c6c1daeSBarry Smith + lg  - the line graph context.
2735c6c1daeSBarry Smith - dim - the number of curves.
2745c6c1daeSBarry Smith 
2755c6c1daeSBarry Smith   Level: intermediate
2765c6c1daeSBarry Smith 
277db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLGGetDimension()`
2785c6c1daeSBarry Smith @*/
279d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg, PetscInt dim)
280d71ae5a4SJacob Faibussowitsch {
2815c6c1daeSBarry Smith   PetscInt i;
2825c6c1daeSBarry Smith 
2835c6c1daeSBarry Smith   PetscFunctionBegin;
2845c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2855c6c1daeSBarry Smith   PetscValidLogicalCollectiveInt(lg, dim, 2);
2863ba16761SJacob Faibussowitsch   if (lg->dim == dim) PetscFunctionReturn(PETSC_SUCCESS);
2875c6c1daeSBarry Smith 
2889566063dSJacob Faibussowitsch   PetscCall(PetscFree2(lg->x, lg->y));
2895c6c1daeSBarry Smith   if (lg->legend) {
29048a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2919566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2925c6c1daeSBarry Smith   }
2939566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
294*6497c311SBarry Smith   lg->dim = (int)dim;
2959566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
296*6497c311SBarry Smith   lg->len = (int)(dim * PETSC_DRAW_LG_CHUNK_SIZE);
2973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2985c6c1daeSBarry Smith }
2995c6c1daeSBarry Smith 
30071917b75SLisandro Dalcin /*@
30171917b75SLisandro Dalcin   PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
30271917b75SLisandro Dalcin   points are added after this call, the limits will be adjusted to
30371917b75SLisandro Dalcin   include those additional points.
30471917b75SLisandro Dalcin 
305c3339decSBarry Smith   Logically Collective
30671917b75SLisandro Dalcin 
30771917b75SLisandro Dalcin   Input Parameters:
308aec76313SJacob Faibussowitsch + lg    - the line graph context
3092fe279fdSBarry Smith . x_min - the horizontal lower limit
310aaa8cc7dSPierre Jolivet . x_max - the horizontal upper limit
3112fe279fdSBarry Smith . y_min - the vertical lower limit
3122fe279fdSBarry Smith - y_max - the vertical upper limit
31371917b75SLisandro Dalcin 
31471917b75SLisandro Dalcin   Level: intermediate
31571917b75SLisandro Dalcin 
316811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis`
31771917b75SLisandro Dalcin @*/
318d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max)
319d71ae5a4SJacob Faibussowitsch {
32071917b75SLisandro Dalcin   PetscFunctionBegin;
32171917b75SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
32271917b75SLisandro Dalcin 
32371917b75SLisandro Dalcin   (lg)->xmin = x_min;
32471917b75SLisandro Dalcin   (lg)->xmax = x_max;
32571917b75SLisandro Dalcin   (lg)->ymin = y_min;
32671917b75SLisandro Dalcin   (lg)->ymax = y_max;
3273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32871917b75SLisandro Dalcin }
32971917b75SLisandro Dalcin 
3305c6c1daeSBarry Smith /*@
3315c6c1daeSBarry Smith   PetscDrawLGReset - Clears line graph to allow for reuse with new data.
3325c6c1daeSBarry Smith 
333c3339decSBarry Smith   Logically Collective
3345c6c1daeSBarry Smith 
3355c6c1daeSBarry Smith   Input Parameter:
3365c6c1daeSBarry Smith . lg - the line graph context.
3375c6c1daeSBarry Smith 
3385c6c1daeSBarry Smith   Level: intermediate
3395c6c1daeSBarry Smith 
340811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3415c6c1daeSBarry Smith @*/
342d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGReset(PetscDrawLG lg)
343d71ae5a4SJacob Faibussowitsch {
3445c6c1daeSBarry Smith   PetscFunctionBegin;
3455c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
3465c6c1daeSBarry Smith   lg->xmin  = 1.e20;
3475c6c1daeSBarry Smith   lg->ymin  = 1.e20;
3485c6c1daeSBarry Smith   lg->xmax  = -1.e20;
3495c6c1daeSBarry Smith   lg->ymax  = -1.e20;
3505c6c1daeSBarry Smith   lg->loc   = 0;
3515c6c1daeSBarry Smith   lg->nopts = 0;
3523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3535c6c1daeSBarry Smith }
3545c6c1daeSBarry Smith 
3555c6c1daeSBarry Smith /*@
3565c6c1daeSBarry Smith   PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
3575c6c1daeSBarry Smith 
358c3339decSBarry Smith   Collective
3595c6c1daeSBarry Smith 
3605c6c1daeSBarry Smith   Input Parameter:
3615c6c1daeSBarry Smith . lg - the line graph context
3625c6c1daeSBarry Smith 
3635c6c1daeSBarry Smith   Level: intermediate
3645c6c1daeSBarry Smith 
365811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3665c6c1daeSBarry Smith @*/
367d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg)
368d71ae5a4SJacob Faibussowitsch {
3695c6c1daeSBarry Smith   PetscInt i;
3705c6c1daeSBarry Smith 
3715c6c1daeSBarry Smith   PetscFunctionBegin;
3723ba16761SJacob Faibussowitsch   if (!*lg) PetscFunctionReturn(PETSC_SUCCESS);
373e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1);
374f4f49eeaSPierre Jolivet   if (--((PetscObject)*lg)->refct > 0) {
3759371c9d4SSatish Balay     *lg = NULL;
3763ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
3779371c9d4SSatish Balay   }
3785c6c1daeSBarry Smith 
3795c6c1daeSBarry Smith   if ((*lg)->legend) {
38048a46eb9SPierre Jolivet     for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i]));
3819566063dSJacob Faibussowitsch     PetscCall(PetscFree((*lg)->legend));
3825c6c1daeSBarry Smith   }
3839566063dSJacob Faibussowitsch   PetscCall(PetscFree((*lg)->colors));
3849566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*lg)->x, (*lg)->y));
3859566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*lg)->axis));
3869566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*lg)->win));
3879566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lg));
3883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3895c6c1daeSBarry Smith }
3905c6c1daeSBarry Smith /*@
391811af0c4SBarry Smith   PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point.
3925c6c1daeSBarry Smith 
393c3339decSBarry Smith   Logically Collective
3945c6c1daeSBarry Smith 
3955c6c1daeSBarry Smith   Input Parameters:
396287de1a7SBarry Smith + lg  - the linegraph context
397287de1a7SBarry Smith - flg - should mark each data point
398287de1a7SBarry Smith 
399811af0c4SBarry Smith   Options Database Key:
400811af0c4SBarry Smith . -lg_use_markers  <true,false> - true means it draws a marker for each point
4015c6c1daeSBarry Smith 
4025c6c1daeSBarry Smith   Level: intermediate
4035c6c1daeSBarry Smith 
404811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
4055c6c1daeSBarry Smith @*/
406d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg)
407d71ae5a4SJacob Faibussowitsch {
4085c6c1daeSBarry Smith   PetscFunctionBegin;
409e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
41045f3bb6eSLisandro Dalcin   PetscValidLogicalCollectiveBool(lg, flg, 2);
411b6fe0379SLisandro Dalcin   lg->use_markers = flg;
4123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4135c6c1daeSBarry Smith }
4145c6c1daeSBarry Smith 
4155c6c1daeSBarry Smith /*@
4165c6c1daeSBarry Smith   PetscDrawLGDraw - Redraws a line graph.
4175c6c1daeSBarry Smith 
418c3339decSBarry Smith   Collective
4195c6c1daeSBarry Smith 
4205c6c1daeSBarry Smith   Input Parameter:
4215c6c1daeSBarry Smith . lg - the line graph context
4225c6c1daeSBarry Smith 
4235c6c1daeSBarry Smith   Level: intermediate
4245c6c1daeSBarry Smith 
425811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()`
4265c6c1daeSBarry Smith @*/
427d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg)
428d71ae5a4SJacob Faibussowitsch {
429e118a51fSLisandro Dalcin   PetscReal   xmin, xmax, ymin, ymax;
430e118a51fSLisandro Dalcin   PetscMPIInt rank;
431e118a51fSLisandro Dalcin   PetscDraw   draw;
4325c6c1daeSBarry Smith   PetscBool   isnull;
4335c6c1daeSBarry Smith 
4345c6c1daeSBarry Smith   PetscFunctionBegin;
4355c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
4369566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
4373ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
4389566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
4395c6c1daeSBarry Smith 
4405b399a63SLisandro Dalcin   draw = lg->win;
4419566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
4429566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
443e118a51fSLisandro Dalcin 
4449371c9d4SSatish Balay   xmin = lg->xmin;
4459371c9d4SSatish Balay   xmax = lg->xmax;
4469371c9d4SSatish Balay   ymin = lg->ymin;
4479371c9d4SSatish Balay   ymax = lg->ymax;
4489566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
4499566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
4505c6c1daeSBarry Smith 
451d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
452dd400576SPatrick Sanan   if (rank == 0) {
453e118a51fSLisandro Dalcin     int i, j, dim = lg->dim, nopts = lg->nopts, cl;
4545c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4555c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
4560ed3bfb6SBarry Smith         cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
4579566063dSJacob 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));
4589566063dSJacob Faibussowitsch         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl));
4595c6c1daeSBarry Smith       }
4605c6c1daeSBarry Smith     }
4615c6c1daeSBarry Smith   }
462dd400576SPatrick Sanan   if (rank == 0 && lg->legend) {
463088d793eSMatthew G. Knepley     PetscBool right = PETSC_FALSE;
464e118a51fSLisandro Dalcin     int       i, dim = lg->dim, cl;
4655c6c1daeSBarry Smith     PetscReal xl, yl, xr, yr, tw, th;
46671917b75SLisandro Dalcin     size_t    slen, len = 0;
467*6497c311SBarry Smith 
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;
476*6497c311SBarry Smith       xl = xr - ((PetscReal)len + 7) * tw;
477088d793eSMatthew G. Knepley     } else {
4789371c9d4SSatish Balay       xl = xl + 1.5 * tw;
479*6497c311SBarry Smith       xr = xl + ((PetscReal)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 
52510450e9eSJacob Faibussowitsch   Input Parameters:
52610450e9eSJacob Faibussowitsch + lg     - the line graph context
52710450e9eSJacob 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 
553cc4c1da9SBarry Smith /*@
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