xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 655619b1f4941e49c75328be1d654eab6c0763e9)
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;
1645c6c1daeSBarry Smith   lg->xmin    = 1.e20;
1655c6c1daeSBarry Smith   lg->ymin    = 1.e20;
1665c6c1daeSBarry Smith   lg->xmax    = -1.e20;
1675c6c1daeSBarry Smith   lg->ymax    = -1.e20;
168835f2295SStefano Zampini   PetscCall(PetscCIntCast(dim, &lg->dim));
1699566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
170a297a907SKarl Rupp 
171835f2295SStefano Zampini   lg->len         = lg->dim * PETSC_DRAW_LG_CHUNK_SIZE;
1725c6c1daeSBarry Smith   lg->loc         = 0;
173b6fe0379SLisandro Dalcin   lg->use_markers = PETSC_FALSE;
174a297a907SKarl Rupp 
1759566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &lg->axis));
176a297a907SKarl Rupp 
177e118a51fSLisandro Dalcin   *outlg = lg;
1783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1795c6c1daeSBarry Smith }
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith /*@
1825c6c1daeSBarry Smith   PetscDrawLGSetColors - Sets the color of each line graph drawn
1835c6c1daeSBarry Smith 
184c3339decSBarry Smith   Logically Collective
1855c6c1daeSBarry Smith 
186d8d19677SJose E. Roman   Input Parameters:
1875c6c1daeSBarry Smith + lg     - the line graph context.
1885c6c1daeSBarry Smith - colors - the colors
1895c6c1daeSBarry Smith 
1905c6c1daeSBarry Smith   Level: intermediate
1915c6c1daeSBarry Smith 
192811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
1935c6c1daeSBarry Smith @*/
194d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg, const int colors[])
195d71ae5a4SJacob Faibussowitsch {
1965c6c1daeSBarry Smith   PetscFunctionBegin;
1975c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
1984f572ea9SToby Isaac   if (lg->dim) PetscAssertPointer(colors, 2);
199e118a51fSLisandro Dalcin 
2009566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
2019566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lg->dim, &lg->colors));
2029566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(lg->colors, colors, lg->dim));
2033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2045c6c1daeSBarry Smith }
2055c6c1daeSBarry Smith 
2065c6c1daeSBarry Smith /*@C
2075c6c1daeSBarry Smith   PetscDrawLGSetLegend - sets the names of each curve plotted
2085c6c1daeSBarry Smith 
209c3339decSBarry Smith   Logically Collective
2105c6c1daeSBarry Smith 
211d8d19677SJose E. Roman   Input Parameters:
2125c6c1daeSBarry Smith + lg    - the line graph context.
2135c6c1daeSBarry Smith - names - the names for each curve
2145c6c1daeSBarry Smith 
2155c6c1daeSBarry Smith   Level: intermediate
2165c6c1daeSBarry Smith 
217811af0c4SBarry Smith   Note:
218811af0c4SBarry Smith   Call `PetscDrawLGGetAxis()` and then change properties of the `PetscDrawAxis` for detailed control of the plot
219ba1e01c4SBarry Smith 
220db781477SPatrick Sanan .seealso: `PetscDrawLGGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetHoldLimits()`
2215c6c1daeSBarry Smith @*/
222cc4c1da9SBarry Smith PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg, const char *const names[])
223d71ae5a4SJacob Faibussowitsch {
2245c6c1daeSBarry Smith   PetscInt i;
2255c6c1daeSBarry Smith 
2265c6c1daeSBarry Smith   PetscFunctionBegin;
2275c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2284f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 2);
2295c6c1daeSBarry Smith 
2305c6c1daeSBarry Smith   if (lg->legend) {
23148a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2329566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2335c6c1daeSBarry Smith   }
2345c6c1daeSBarry Smith   if (names) {
2359566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(lg->dim, &lg->legend));
23648a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscStrallocpy(names[i], &lg->legend[i]));
2375c6c1daeSBarry Smith   }
2383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2395c6c1daeSBarry Smith }
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith /*@
242811af0c4SBarry Smith   PetscDrawLGGetDimension - Get the number of curves that are to be drawn.
2435c6c1daeSBarry Smith 
2445b399a63SLisandro Dalcin   Not Collective
2455c6c1daeSBarry Smith 
2465c6c1daeSBarry Smith   Input Parameter:
2475c6c1daeSBarry Smith . lg - the line graph context.
2485c6c1daeSBarry Smith 
2495c6c1daeSBarry Smith   Output Parameter:
2505c6c1daeSBarry Smith . dim - the number of curves.
2515c6c1daeSBarry Smith 
2525c6c1daeSBarry Smith   Level: intermediate
2535c6c1daeSBarry Smith 
254811af0c4SBarry Smith .seealso: `PetscDrawLGC`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`
2555c6c1daeSBarry Smith @*/
256d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg, PetscInt *dim)
257d71ae5a4SJacob Faibussowitsch {
2585c6c1daeSBarry Smith   PetscFunctionBegin;
2595c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2604f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
2615c6c1daeSBarry Smith   *dim = lg->dim;
2623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2635c6c1daeSBarry Smith }
2645c6c1daeSBarry Smith 
2655c6c1daeSBarry Smith /*@
266811af0c4SBarry Smith   PetscDrawLGSetDimension - Change the number of curves that are to be drawn.
2675c6c1daeSBarry Smith 
268c3339decSBarry Smith   Logically Collective
2695c6c1daeSBarry Smith 
270d8d19677SJose E. Roman   Input Parameters:
2715c6c1daeSBarry Smith + lg  - the line graph context.
2725c6c1daeSBarry Smith - dim - the number of curves.
2735c6c1daeSBarry Smith 
2745c6c1daeSBarry Smith   Level: intermediate
2755c6c1daeSBarry Smith 
276db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLGGetDimension()`
2775c6c1daeSBarry Smith @*/
278d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg, PetscInt dim)
279d71ae5a4SJacob Faibussowitsch {
2805c6c1daeSBarry Smith   PetscInt i;
2815c6c1daeSBarry Smith 
2825c6c1daeSBarry Smith   PetscFunctionBegin;
2835c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2845c6c1daeSBarry Smith   PetscValidLogicalCollectiveInt(lg, dim, 2);
2853ba16761SJacob Faibussowitsch   if (lg->dim == dim) PetscFunctionReturn(PETSC_SUCCESS);
2865c6c1daeSBarry Smith 
2879566063dSJacob Faibussowitsch   PetscCall(PetscFree2(lg->x, lg->y));
2885c6c1daeSBarry Smith   if (lg->legend) {
28948a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2909566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2915c6c1daeSBarry Smith   }
2929566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
293835f2295SStefano Zampini   PetscCall(PetscCIntCast(dim, &lg->dim));
2949566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
295835f2295SStefano Zampini   lg->len = lg->dim * PETSC_DRAW_LG_CHUNK_SIZE;
2963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2975c6c1daeSBarry Smith }
2985c6c1daeSBarry Smith 
29971917b75SLisandro Dalcin /*@
30071917b75SLisandro Dalcin   PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
30171917b75SLisandro Dalcin   points are added after this call, the limits will be adjusted to
30271917b75SLisandro Dalcin   include those additional points.
30371917b75SLisandro Dalcin 
304c3339decSBarry Smith   Logically Collective
30571917b75SLisandro Dalcin 
30671917b75SLisandro Dalcin   Input Parameters:
307aec76313SJacob Faibussowitsch + lg    - the line graph context
3082fe279fdSBarry Smith . x_min - the horizontal lower limit
309aaa8cc7dSPierre Jolivet . x_max - the horizontal upper limit
3102fe279fdSBarry Smith . y_min - the vertical lower limit
3112fe279fdSBarry Smith - y_max - the vertical upper limit
31271917b75SLisandro Dalcin 
31371917b75SLisandro Dalcin   Level: intermediate
31471917b75SLisandro Dalcin 
315811af0c4SBarry Smith .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis`
31671917b75SLisandro Dalcin @*/
317d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max)
318d71ae5a4SJacob Faibussowitsch {
31971917b75SLisandro Dalcin   PetscFunctionBegin;
32071917b75SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
32171917b75SLisandro Dalcin 
32271917b75SLisandro Dalcin   (lg)->xmin = x_min;
32371917b75SLisandro Dalcin   (lg)->xmax = x_max;
32471917b75SLisandro Dalcin   (lg)->ymin = y_min;
32571917b75SLisandro Dalcin   (lg)->ymax = y_max;
3263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32771917b75SLisandro Dalcin }
32871917b75SLisandro Dalcin 
3295c6c1daeSBarry Smith /*@
3305c6c1daeSBarry Smith   PetscDrawLGReset - Clears line graph to allow for reuse with new data.
3315c6c1daeSBarry Smith 
332c3339decSBarry Smith   Logically Collective
3335c6c1daeSBarry Smith 
3345c6c1daeSBarry Smith   Input Parameter:
3355c6c1daeSBarry Smith . lg - the line graph context.
3365c6c1daeSBarry Smith 
3375c6c1daeSBarry Smith   Level: intermediate
3385c6c1daeSBarry Smith 
339811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3405c6c1daeSBarry Smith @*/
341d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGReset(PetscDrawLG lg)
342d71ae5a4SJacob Faibussowitsch {
3435c6c1daeSBarry Smith   PetscFunctionBegin;
3445c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
3455c6c1daeSBarry Smith   lg->xmin  = 1.e20;
3465c6c1daeSBarry Smith   lg->ymin  = 1.e20;
3475c6c1daeSBarry Smith   lg->xmax  = -1.e20;
3485c6c1daeSBarry Smith   lg->ymax  = -1.e20;
3495c6c1daeSBarry Smith   lg->loc   = 0;
3505c6c1daeSBarry Smith   lg->nopts = 0;
3513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3525c6c1daeSBarry Smith }
3535c6c1daeSBarry Smith 
3545c6c1daeSBarry Smith /*@
3555c6c1daeSBarry Smith   PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
3565c6c1daeSBarry Smith 
357c3339decSBarry Smith   Collective
3585c6c1daeSBarry Smith 
3595c6c1daeSBarry Smith   Input Parameter:
3605c6c1daeSBarry Smith . lg - the line graph context
3615c6c1daeSBarry Smith 
3625c6c1daeSBarry Smith   Level: intermediate
3635c6c1daeSBarry Smith 
364811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
3655c6c1daeSBarry Smith @*/
366d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg)
367d71ae5a4SJacob Faibussowitsch {
3685c6c1daeSBarry Smith   PetscInt i;
3695c6c1daeSBarry Smith 
3705c6c1daeSBarry Smith   PetscFunctionBegin;
3713ba16761SJacob Faibussowitsch   if (!*lg) PetscFunctionReturn(PETSC_SUCCESS);
372e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1);
373f4f49eeaSPierre Jolivet   if (--((PetscObject)*lg)->refct > 0) {
3749371c9d4SSatish Balay     *lg = NULL;
3753ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
3769371c9d4SSatish Balay   }
3775c6c1daeSBarry Smith 
3785c6c1daeSBarry Smith   if ((*lg)->legend) {
37948a46eb9SPierre Jolivet     for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i]));
3809566063dSJacob Faibussowitsch     PetscCall(PetscFree((*lg)->legend));
3815c6c1daeSBarry Smith   }
3829566063dSJacob Faibussowitsch   PetscCall(PetscFree((*lg)->colors));
3839566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*lg)->x, (*lg)->y));
3849566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*lg)->axis));
3859566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*lg)->win));
3869566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lg));
3873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3885c6c1daeSBarry Smith }
3895c6c1daeSBarry Smith /*@
390811af0c4SBarry Smith   PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point.
3915c6c1daeSBarry Smith 
392c3339decSBarry Smith   Logically Collective
3935c6c1daeSBarry Smith 
3945c6c1daeSBarry Smith   Input Parameters:
395287de1a7SBarry Smith + lg  - the linegraph context
396287de1a7SBarry Smith - flg - should mark each data point
397287de1a7SBarry Smith 
398811af0c4SBarry Smith   Options Database Key:
399811af0c4SBarry Smith . -lg_use_markers  <true,false> - true means it draws a marker for each point
4005c6c1daeSBarry Smith 
4015c6c1daeSBarry Smith   Level: intermediate
4025c6c1daeSBarry Smith 
403811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
4045c6c1daeSBarry Smith @*/
405d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg)
406d71ae5a4SJacob Faibussowitsch {
4075c6c1daeSBarry Smith   PetscFunctionBegin;
408e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
40945f3bb6eSLisandro Dalcin   PetscValidLogicalCollectiveBool(lg, flg, 2);
410b6fe0379SLisandro Dalcin   lg->use_markers = flg;
4113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4125c6c1daeSBarry Smith }
4135c6c1daeSBarry Smith 
4145c6c1daeSBarry Smith /*@
4155c6c1daeSBarry Smith   PetscDrawLGDraw - Redraws a line graph.
4165c6c1daeSBarry Smith 
417c3339decSBarry Smith   Collective
4185c6c1daeSBarry Smith 
4195c6c1daeSBarry Smith   Input Parameter:
4205c6c1daeSBarry Smith . lg - the line graph context
4215c6c1daeSBarry Smith 
4225c6c1daeSBarry Smith   Level: intermediate
4235c6c1daeSBarry Smith 
424811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()`
4255c6c1daeSBarry Smith @*/
426d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg)
427d71ae5a4SJacob Faibussowitsch {
428e118a51fSLisandro Dalcin   PetscReal   xmin, xmax, ymin, ymax;
429e118a51fSLisandro Dalcin   PetscMPIInt rank;
430e118a51fSLisandro Dalcin   PetscDraw   draw;
4315c6c1daeSBarry Smith   PetscBool   isnull;
4325c6c1daeSBarry Smith 
4335c6c1daeSBarry Smith   PetscFunctionBegin;
4345c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
4359566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
4363ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
4379566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
4385c6c1daeSBarry Smith 
4395b399a63SLisandro Dalcin   draw = lg->win;
4409566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
4419566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
442e118a51fSLisandro Dalcin 
4439371c9d4SSatish Balay   xmin = lg->xmin;
4449371c9d4SSatish Balay   xmax = lg->xmax;
4459371c9d4SSatish Balay   ymin = lg->ymin;
4469371c9d4SSatish Balay   ymax = lg->ymax;
447*655619b1SMatthew G. Knepley   // Try not to freak out the axis
448*655619b1SMatthew G. Knepley   if (ymax - ymin < PETSC_SMALL) {
449*655619b1SMatthew G. Knepley     ymin -= 0.1 * ymax;
450*655619b1SMatthew G. Knepley     ymax += 0.1 * ymax;
451*655619b1SMatthew G. Knepley   }
4529566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
4539566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
4545c6c1daeSBarry Smith 
455d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
456dd400576SPatrick Sanan   if (rank == 0) {
457e118a51fSLisandro Dalcin     int i, j, dim = lg->dim, nopts = lg->nopts, cl;
4585c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4595c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
4600ed3bfb6SBarry Smith         cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
4619566063dSJacob 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));
4629566063dSJacob Faibussowitsch         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl));
4635c6c1daeSBarry Smith       }
4645c6c1daeSBarry Smith     }
4655c6c1daeSBarry Smith   }
466dd400576SPatrick Sanan   if (rank == 0 && lg->legend) {
467088d793eSMatthew G. Knepley     PetscBool right = PETSC_FALSE;
468e118a51fSLisandro Dalcin     int       i, dim = lg->dim, cl;
4695c6c1daeSBarry Smith     PetscReal xl, yl, xr, yr, tw, th;
47071917b75SLisandro Dalcin     size_t    slen, len = 0;
4716497c311SBarry Smith 
4729566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr));
4739566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
4745c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4759566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(lg->legend[i], &slen));
47671917b75SLisandro Dalcin       len = PetscMax(len, slen);
4775c6c1daeSBarry Smith     }
478088d793eSMatthew G. Knepley     if (right) {
4799371c9d4SSatish Balay       xr = xr - 1.5 * tw;
4806497c311SBarry Smith       xl = xr - ((PetscReal)len + 7) * tw;
481088d793eSMatthew G. Knepley     } else {
4829371c9d4SSatish Balay       xl = xl + 1.5 * tw;
4836497c311SBarry Smith       xr = xl + ((PetscReal)len + 7) * tw;
484088d793eSMatthew G. Knepley     }
4859371c9d4SSatish Balay     yr = yr - 1.0 * th;
4869371c9d4SSatish Balay     yl = yr - (dim + 1) * th;
4879566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK));
4889566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK));
4899566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK));
4909566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK));
4915c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
49271917b75SLisandro Dalcin       cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
4939566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl));
4949566063dSJacob Faibussowitsch       PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i]));
4955c6c1daeSBarry Smith     }
4965c6c1daeSBarry Smith   }
497d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
4985b399a63SLisandro Dalcin 
4999566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5009566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5025c6c1daeSBarry Smith }
5035c6c1daeSBarry Smith 
50457fd6651SLisandro Dalcin /*@
50557fd6651SLisandro Dalcin   PetscDrawLGSave - Saves a drawn image
50657fd6651SLisandro Dalcin 
507c3339decSBarry Smith   Collective
50857fd6651SLisandro Dalcin 
50957fd6651SLisandro Dalcin   Input Parameter:
51057fd6651SLisandro Dalcin . lg - The line graph context
51157fd6651SLisandro Dalcin 
51257fd6651SLisandro Dalcin   Level: intermediate
51357fd6651SLisandro Dalcin 
514aec76313SJacob Faibussowitsch .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()`
51557fd6651SLisandro Dalcin @*/
516d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSave(PetscDrawLG lg)
517d71ae5a4SJacob Faibussowitsch {
51857fd6651SLisandro Dalcin   PetscFunctionBegin;
51957fd6651SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5209566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(lg->win));
5213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
52257fd6651SLisandro Dalcin }
52357fd6651SLisandro Dalcin 
5245c6c1daeSBarry Smith /*@
52534a5a0e3SBarry Smith   PetscDrawLGView - Prints a line graph.
5265c6c1daeSBarry Smith 
527c3339decSBarry Smith   Collective
5285c6c1daeSBarry Smith 
52910450e9eSJacob Faibussowitsch   Input Parameters:
53010450e9eSJacob Faibussowitsch + lg     - the line graph context
53110450e9eSJacob Faibussowitsch - viewer - the viewer to view it with
5325c6c1daeSBarry Smith 
5335c6c1daeSBarry Smith   Level: beginner
5345c6c1daeSBarry Smith 
535811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
5365c6c1daeSBarry Smith @*/
537d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer)
538d71ae5a4SJacob Faibussowitsch {
5395c6c1daeSBarry Smith   PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax;
54034a5a0e3SBarry Smith   PetscInt  i, j, dim = lg->dim, nopts = lg->nopts;
5415c6c1daeSBarry Smith 
5425c6c1daeSBarry Smith   PetscFunctionBegin;
5435c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
544e118a51fSLisandro Dalcin 
5453ba16761SJacob Faibussowitsch   if (nopts < 1) PetscFunctionReturn(PETSC_SUCCESS);
5463ba16761SJacob Faibussowitsch   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(PETSC_SUCCESS);
5475c6c1daeSBarry Smith 
54848a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer));
5499566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer));
5505c6c1daeSBarry Smith   for (i = 0; i < dim; i++) {
5519566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i));
55248a46eb9SPierre 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]));
5535c6c1daeSBarry Smith   }
5543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5555c6c1daeSBarry Smith }
556287de1a7SBarry Smith 
557cc4c1da9SBarry Smith /*@
558c2bac407SLisandro Dalcin   PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
559811af0c4SBarry Smith   `PetscDrawLG` options in the database.
560c2bac407SLisandro Dalcin 
561c3339decSBarry Smith   Logically Collective
562c2bac407SLisandro Dalcin 
563d8d19677SJose E. Roman   Input Parameters:
564c2bac407SLisandro Dalcin + lg     - the line graph context
565c2bac407SLisandro Dalcin - prefix - the prefix to prepend to all option names
566c2bac407SLisandro Dalcin 
567c2bac407SLisandro Dalcin   Level: advanced
568c2bac407SLisandro Dalcin 
569811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()`
570c2bac407SLisandro Dalcin @*/
571d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[])
572d71ae5a4SJacob Faibussowitsch {
573c2bac407SLisandro Dalcin   PetscFunctionBegin;
574c2bac407SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5759566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix));
5763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
577c2bac407SLisandro Dalcin }
578c2bac407SLisandro Dalcin 
579287de1a7SBarry Smith /*@
580811af0c4SBarry Smith   PetscDrawLGSetFromOptions - Sets options related to the line graph object
581287de1a7SBarry Smith 
582c3339decSBarry Smith   Collective
583287de1a7SBarry Smith 
584811af0c4SBarry Smith   Input Parameters:
585811af0c4SBarry Smith . lg - the line graph context
586811af0c4SBarry Smith 
587811af0c4SBarry Smith   Options Database Key:
588811af0c4SBarry Smith . -lg_use_markers  <true,false> - true means it draws a marker for each point
589287de1a7SBarry Smith 
590287de1a7SBarry Smith   Level: intermediate
591287de1a7SBarry Smith 
592811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()`
593287de1a7SBarry Smith @*/
594d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg)
595d71ae5a4SJacob Faibussowitsch {
59671917b75SLisandro Dalcin   PetscBool           usemarkers, set;
59771917b75SLisandro Dalcin   PetscDrawMarkerType markertype;
598287de1a7SBarry Smith 
599287de1a7SBarry Smith   PetscFunctionBegin;
600e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
601e118a51fSLisandro Dalcin 
6029566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetMarkerType(lg->win, &markertype));
6039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set));
60471917b75SLisandro Dalcin   if (set) {
6059566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE));
6069566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetMarkerType(lg->win, markertype));
60771917b75SLisandro Dalcin   }
60871917b75SLisandro Dalcin   usemarkers = lg->use_markers;
6099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set));
6109566063dSJacob Faibussowitsch   if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers));
6113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
612287de1a7SBarry Smith }
613