xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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 
125c6c1daeSBarry Smith    Not Collective, if PetscDrawLG is parallel then PetscDrawAxis 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 
22db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawAxis`
23ba1e01c4SBarry Smith 
245c6c1daeSBarry Smith @*/
259371c9d4SSatish Balay PetscErrorCode PetscDrawLGGetAxis(PetscDrawLG lg, PetscDrawAxis *axis) {
265c6c1daeSBarry Smith   PetscFunctionBegin;
27e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2845f3bb6eSLisandro Dalcin   PetscValidPointer(axis, 2);
295c6c1daeSBarry Smith   *axis = lg->axis;
305c6c1daeSBarry Smith   PetscFunctionReturn(0);
315c6c1daeSBarry Smith }
325c6c1daeSBarry Smith 
335c6c1daeSBarry Smith /*@
345c6c1daeSBarry Smith    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
355c6c1daeSBarry Smith 
365c6c1daeSBarry Smith    Not Collective, if PetscDrawLG is parallel then PetscDraw 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 
46db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDraw`
475c6c1daeSBarry Smith @*/
489371c9d4SSatish Balay PetscErrorCode PetscDrawLGGetDraw(PetscDrawLG lg, PetscDraw *draw) {
495c6c1daeSBarry Smith   PetscFunctionBegin;
505c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5145f3bb6eSLisandro Dalcin   PetscValidPointer(draw, 2);
525c6c1daeSBarry Smith   *draw = lg->win;
535c6c1daeSBarry Smith   PetscFunctionReturn(0);
545c6c1daeSBarry Smith }
555c6c1daeSBarry Smith 
565c6c1daeSBarry Smith /*@
575c6c1daeSBarry Smith    PetscDrawLGSPDraw - Redraws a line graph.
585c6c1daeSBarry Smith 
595b399a63SLisandro Dalcin    Collective on PetscDrawLG
605c6c1daeSBarry Smith 
615c6c1daeSBarry Smith    Input Parameter:
625c6c1daeSBarry Smith .  lg - the line graph context
635c6c1daeSBarry Smith 
645c6c1daeSBarry Smith    Level: intermediate
655c6c1daeSBarry Smith 
66db781477SPatrick Sanan .seealso: `PetscDrawLGDraw()`, `PetscDrawSPDraw()`
675c6c1daeSBarry Smith 
6895452b02SPatrick Sanan    Developer Notes:
6995452b02SPatrick Sanan     This code cheats and uses the fact that the LG and SP structs are the same
705c6c1daeSBarry Smith 
715c6c1daeSBarry Smith @*/
729371c9d4SSatish Balay PetscErrorCode PetscDrawLGSPDraw(PetscDrawLG lg, PetscDrawSP spin) {
735c6c1daeSBarry Smith   PetscDrawLG sp = (PetscDrawLG)spin;
745c6c1daeSBarry Smith   PetscReal   xmin, xmax, ymin, ymax;
75e118a51fSLisandro Dalcin   PetscBool   isnull;
76e118a51fSLisandro Dalcin   PetscMPIInt rank;
77e118a51fSLisandro Dalcin   PetscDraw   draw;
785c6c1daeSBarry Smith 
795c6c1daeSBarry Smith   PetscFunctionBegin;
805c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
81064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(sp, PETSC_DRAWLG_CLASSID, 2);
829566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
83e118a51fSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
849566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
855c6c1daeSBarry Smith 
865b399a63SLisandro Dalcin   draw = lg->win;
879566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
889566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
89e118a51fSLisandro Dalcin 
909371c9d4SSatish Balay   xmin = PetscMin(lg->xmin, sp->xmin);
919371c9d4SSatish Balay   ymin = PetscMin(lg->ymin, sp->ymin);
929371c9d4SSatish Balay   xmax = PetscMax(lg->xmax, sp->xmax);
939371c9d4SSatish Balay   ymax = PetscMax(lg->ymax, sp->ymax);
949566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
959566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
965c6c1daeSBarry Smith 
97d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
98dd400576SPatrick Sanan   if (rank == 0) {
99e118a51fSLisandro Dalcin     int i, j, dim, nopts;
1005c6c1daeSBarry Smith     dim   = lg->dim;
1015c6c1daeSBarry Smith     nopts = lg->nopts;
1025c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
1035c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
1049566063dSJacob 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));
105*48a46eb9SPierre Jolivet         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], PETSC_DRAW_RED));
1065c6c1daeSBarry Smith       }
1075c6c1daeSBarry Smith     }
1085c6c1daeSBarry Smith     dim   = sp->dim;
1095c6c1daeSBarry Smith     nopts = sp->nopts;
1105c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
111*48a46eb9SPierre Jolivet       for (j = 0; j < nopts; j++) PetscCall(PetscDrawMarker(draw, sp->x[j * dim + i], sp->y[j * dim + i], PETSC_DRAW_RED));
1125c6c1daeSBarry Smith     }
1135c6c1daeSBarry Smith   }
114d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
1155b399a63SLisandro Dalcin 
1169566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
1179566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
1185c6c1daeSBarry Smith   PetscFunctionReturn(0);
1195c6c1daeSBarry Smith }
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith /*@
1225c6c1daeSBarry Smith     PetscDrawLGCreate - Creates a line graph data structure.
1235c6c1daeSBarry Smith 
1245b399a63SLisandro Dalcin     Collective on PetscDraw
1255c6c1daeSBarry Smith 
1265c6c1daeSBarry Smith     Input Parameters:
1275c6c1daeSBarry Smith +   draw - the window where the graph will be made.
1285c6c1daeSBarry Smith -   dim - the number of curves which will be drawn
1295c6c1daeSBarry Smith 
1305c6c1daeSBarry Smith     Output Parameters:
131e118a51fSLisandro Dalcin .   outlg - the line graph context
1325c6c1daeSBarry Smith 
1335c6c1daeSBarry Smith     Level: intermediate
1345c6c1daeSBarry Smith 
13595452b02SPatrick Sanan     Notes:
13695452b02SPatrick Sanan     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
1377e25d57eSBarry Smith            zeroth MPI process in the communicator. All MPI processes in the communicator must call PetscDrawLGDraw() to display the updated graph.
1387e25d57eSBarry Smith 
139db781477SPatrick Sanan .seealso: `PetscDrawLGDestroy()`, `PetscDrawLGAddPoint()`, `PetscDrawLGAddCommonPoint()`, `PetscDrawLGAddPoints()`, `PetscDrawLGDraw()`, `PetscDrawLGSave()`,
140db781477SPatrick Sanan           `PetscDrawLGView()`, `PetscDrawLGReset()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()`, `PetscDrawLGSetLegend()`, `PetscDrawLGGetAxis()`,
141db781477SPatrick Sanan           `PetscDrawLGGetDraw()`, `PetscDrawLGSetUseMarkers()`, `PetscDrawLGSetLimits()`, `PetscDrawLGSetColors()`, `PetscDrawLGSetOptionsPrefix()`, `PetscDrawLGSetFromOptions()`
1425c6c1daeSBarry Smith @*/
1439371c9d4SSatish Balay PetscErrorCode PetscDrawLGCreate(PetscDraw draw, PetscInt dim, PetscDrawLG *outlg) {
1445c6c1daeSBarry Smith   PetscDrawLG lg;
1455c6c1daeSBarry Smith 
1465c6c1daeSBarry Smith   PetscFunctionBegin;
1475c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
148e118a51fSLisandro Dalcin   PetscValidLogicalCollectiveInt(draw, dim, 2);
149e118a51fSLisandro Dalcin   PetscValidPointer(outlg, 3);
150e118a51fSLisandro Dalcin 
1519566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(lg, PETSC_DRAWLG_CLASSID, "DrawLG", "Line Graph", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawLGDestroy, NULL));
1529566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)draw, (PetscObject)lg));
1539566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetOptionsPrefix(lg, ((PetscObject)draw)->prefix));
154e118a51fSLisandro Dalcin 
1559566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)draw));
156e118a51fSLisandro Dalcin   lg->win = draw;
157a297a907SKarl Rupp 
15869c83917SLisandro Dalcin   lg->view    = NULL;
15969c83917SLisandro Dalcin   lg->destroy = NULL;
1605c6c1daeSBarry Smith   lg->nopts   = 0;
1615c6c1daeSBarry Smith   lg->dim     = dim;
1625c6c1daeSBarry Smith   lg->xmin    = 1.e20;
1635c6c1daeSBarry Smith   lg->ymin    = 1.e20;
1645c6c1daeSBarry Smith   lg->xmax    = -1.e20;
1655c6c1daeSBarry Smith   lg->ymax    = -1.e20;
166a297a907SKarl Rupp 
1679566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
1689566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)lg, 2 * dim * PETSC_DRAW_LG_CHUNK_SIZE * sizeof(PetscReal)));
169a297a907SKarl Rupp 
170999739cfSJacob Faibussowitsch   lg->len         = dim * PETSC_DRAW_LG_CHUNK_SIZE;
1715c6c1daeSBarry Smith   lg->loc         = 0;
172b6fe0379SLisandro Dalcin   lg->use_markers = PETSC_FALSE;
173a297a907SKarl Rupp 
1749566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &lg->axis));
1759566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)lg, (PetscObject)lg->axis));
176a297a907SKarl Rupp 
177e118a51fSLisandro Dalcin   *outlg = lg;
1785c6c1daeSBarry Smith   PetscFunctionReturn(0);
1795c6c1daeSBarry Smith }
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith /*@
1825c6c1daeSBarry Smith    PetscDrawLGSetColors - Sets the color of each line graph drawn
1835c6c1daeSBarry Smith 
1845b399a63SLisandro Dalcin    Logically Collective on PetscDrawLG
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 
192db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`
193ba1e01c4SBarry Smith 
1945c6c1daeSBarry Smith @*/
1959371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg, const int colors[]) {
1965c6c1daeSBarry Smith   PetscFunctionBegin;
1975c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
19845f3bb6eSLisandro Dalcin   if (lg->dim) PetscValidIntPointer(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));
2035c6c1daeSBarry Smith   PetscFunctionReturn(0);
2045c6c1daeSBarry Smith }
2055c6c1daeSBarry Smith 
2065c6c1daeSBarry Smith /*@C
2075c6c1daeSBarry Smith    PetscDrawLGSetLegend - sets the names of each curve plotted
2085c6c1daeSBarry Smith 
2095b399a63SLisandro Dalcin    Logically Collective on PetscDrawLG
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 
21795452b02SPatrick Sanan    Notes:
21895452b02SPatrick Sanan     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()`
221ba1e01c4SBarry Smith 
2225c6c1daeSBarry Smith @*/
2239371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg, const char *const *names) {
2245c6c1daeSBarry Smith   PetscInt i;
2255c6c1daeSBarry Smith 
2265c6c1daeSBarry Smith   PetscFunctionBegin;
2275c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
22845f3bb6eSLisandro Dalcin   if (names) PetscValidPointer(names, 2);
2295c6c1daeSBarry Smith 
2305c6c1daeSBarry Smith   if (lg->legend) {
231*48a46eb9SPierre 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));
236*48a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscStrallocpy(names[i], &lg->legend[i]));
2375c6c1daeSBarry Smith   }
2385c6c1daeSBarry Smith   PetscFunctionReturn(0);
2395c6c1daeSBarry Smith }
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith /*@
2425c6c1daeSBarry Smith    PetscDrawLGGetDimension - Change the number of lines 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 
254db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`
255ba1e01c4SBarry Smith 
2565c6c1daeSBarry Smith @*/
2579371c9d4SSatish Balay PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg, PetscInt *dim) {
2585c6c1daeSBarry Smith   PetscFunctionBegin;
2595c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
26045f3bb6eSLisandro Dalcin   PetscValidIntPointer(dim, 2);
2615c6c1daeSBarry Smith   *dim = lg->dim;
2625c6c1daeSBarry Smith   PetscFunctionReturn(0);
2635c6c1daeSBarry Smith }
2645c6c1daeSBarry Smith 
2655c6c1daeSBarry Smith /*@
2665c6c1daeSBarry Smith    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.
2675c6c1daeSBarry Smith 
2685b399a63SLisandro Dalcin    Logically Collective on PetscDrawLG
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 @*/
2789371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg, PetscInt dim) {
2795c6c1daeSBarry Smith   PetscInt i;
2805c6c1daeSBarry Smith 
2815c6c1daeSBarry Smith   PetscFunctionBegin;
2825c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
2835c6c1daeSBarry Smith   PetscValidLogicalCollectiveInt(lg, dim, 2);
2845c6c1daeSBarry Smith   if (lg->dim == dim) PetscFunctionReturn(0);
2855c6c1daeSBarry Smith 
2869566063dSJacob Faibussowitsch   PetscCall(PetscFree2(lg->x, lg->y));
2875c6c1daeSBarry Smith   if (lg->legend) {
288*48a46eb9SPierre Jolivet     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
2899566063dSJacob Faibussowitsch     PetscCall(PetscFree(lg->legend));
2905c6c1daeSBarry Smith   }
2919566063dSJacob Faibussowitsch   PetscCall(PetscFree(lg->colors));
2925c6c1daeSBarry Smith   lg->dim = dim;
2939566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
2949566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)lg, 2 * dim * PETSC_DRAW_LG_CHUNK_SIZE * sizeof(PetscReal)));
295999739cfSJacob Faibussowitsch   lg->len = dim * PETSC_DRAW_LG_CHUNK_SIZE;
2965c6c1daeSBarry Smith   PetscFunctionReturn(0);
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 
30471917b75SLisandro Dalcin    Logically Collective on PetscDrawLG
30571917b75SLisandro Dalcin 
30671917b75SLisandro Dalcin    Input Parameters:
30771917b75SLisandro Dalcin +  xlg - the line graph context
30871917b75SLisandro Dalcin -  x_min,x_max,y_min,y_max - the limits
30971917b75SLisandro Dalcin 
31071917b75SLisandro Dalcin    Level: intermediate
31171917b75SLisandro Dalcin 
312db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`
313ba1e01c4SBarry Smith 
31471917b75SLisandro Dalcin @*/
3159371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max) {
31671917b75SLisandro Dalcin   PetscFunctionBegin;
31771917b75SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
31871917b75SLisandro Dalcin 
31971917b75SLisandro Dalcin   (lg)->xmin = x_min;
32071917b75SLisandro Dalcin   (lg)->xmax = x_max;
32171917b75SLisandro Dalcin   (lg)->ymin = y_min;
32271917b75SLisandro Dalcin   (lg)->ymax = y_max;
32371917b75SLisandro Dalcin   PetscFunctionReturn(0);
32471917b75SLisandro Dalcin }
32571917b75SLisandro Dalcin 
3265c6c1daeSBarry Smith /*@
3275c6c1daeSBarry Smith    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
3285c6c1daeSBarry Smith 
3295b399a63SLisandro Dalcin    Logically Collective on PetscDrawLG
3305c6c1daeSBarry Smith 
3315c6c1daeSBarry Smith    Input Parameter:
3325c6c1daeSBarry Smith .  lg - the line graph context.
3335c6c1daeSBarry Smith 
3345c6c1daeSBarry Smith    Level: intermediate
3355c6c1daeSBarry Smith 
336db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`
3375c6c1daeSBarry Smith @*/
3389371c9d4SSatish Balay PetscErrorCode PetscDrawLGReset(PetscDrawLG lg) {
3395c6c1daeSBarry Smith   PetscFunctionBegin;
3405c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
3415c6c1daeSBarry Smith   lg->xmin  = 1.e20;
3425c6c1daeSBarry Smith   lg->ymin  = 1.e20;
3435c6c1daeSBarry Smith   lg->xmax  = -1.e20;
3445c6c1daeSBarry Smith   lg->ymax  = -1.e20;
3455c6c1daeSBarry Smith   lg->loc   = 0;
3465c6c1daeSBarry Smith   lg->nopts = 0;
3475c6c1daeSBarry Smith   PetscFunctionReturn(0);
3485c6c1daeSBarry Smith }
3495c6c1daeSBarry Smith 
3505c6c1daeSBarry Smith /*@
3515c6c1daeSBarry Smith    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
3525c6c1daeSBarry Smith 
3535b399a63SLisandro Dalcin    Collective on PetscDrawLG
3545c6c1daeSBarry Smith 
3555c6c1daeSBarry Smith    Input Parameter:
3565c6c1daeSBarry Smith .  lg - the line graph context
3575c6c1daeSBarry Smith 
3585c6c1daeSBarry Smith    Level: intermediate
3595c6c1daeSBarry Smith 
360db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`
3615c6c1daeSBarry Smith @*/
3629371c9d4SSatish Balay PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg) {
3635c6c1daeSBarry Smith   PetscInt i;
3645c6c1daeSBarry Smith 
3655c6c1daeSBarry Smith   PetscFunctionBegin;
3665c6c1daeSBarry Smith   if (!*lg) PetscFunctionReturn(0);
367e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1);
3689371c9d4SSatish Balay   if (--((PetscObject)(*lg))->refct > 0) {
3699371c9d4SSatish Balay     *lg = NULL;
3709371c9d4SSatish Balay     PetscFunctionReturn(0);
3719371c9d4SSatish Balay   }
3725c6c1daeSBarry Smith 
3735c6c1daeSBarry Smith   if ((*lg)->legend) {
374*48a46eb9SPierre Jolivet     for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i]));
3759566063dSJacob Faibussowitsch     PetscCall(PetscFree((*lg)->legend));
3765c6c1daeSBarry Smith   }
3779566063dSJacob Faibussowitsch   PetscCall(PetscFree((*lg)->colors));
3789566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*lg)->x, (*lg)->y));
3799566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*lg)->axis));
3809566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*lg)->win));
3819566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lg));
3825c6c1daeSBarry Smith   PetscFunctionReturn(0);
3835c6c1daeSBarry Smith }
3845c6c1daeSBarry Smith /*@
385b6fe0379SLisandro Dalcin    PetscDrawLGSetUseMarkers - Causes LG to draw a marker for each data-point.
3865c6c1daeSBarry Smith 
3875b399a63SLisandro Dalcin    Logically Collective on PetscDrawLG
3885c6c1daeSBarry Smith 
3895c6c1daeSBarry Smith    Input Parameters:
390287de1a7SBarry Smith +  lg - the linegraph context
391287de1a7SBarry Smith -  flg - should mark each data point
392287de1a7SBarry Smith 
393287de1a7SBarry Smith    Options Database:
39410699b91SBarry Smith .  -lg_use_markers  <true,false> - true means the graphPetscDrawLG draws a marker for each point
3955c6c1daeSBarry Smith 
3965c6c1daeSBarry Smith    Level: intermediate
3975c6c1daeSBarry Smith 
398db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`
3995c6c1daeSBarry Smith @*/
4009371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg) {
4015c6c1daeSBarry Smith   PetscFunctionBegin;
402e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
40345f3bb6eSLisandro Dalcin   PetscValidLogicalCollectiveBool(lg, flg, 2);
404b6fe0379SLisandro Dalcin   lg->use_markers = flg;
4055c6c1daeSBarry Smith   PetscFunctionReturn(0);
4065c6c1daeSBarry Smith }
4075c6c1daeSBarry Smith 
4085c6c1daeSBarry Smith /*@
4095c6c1daeSBarry Smith    PetscDrawLGDraw - Redraws a line graph.
4105c6c1daeSBarry Smith 
4115b399a63SLisandro Dalcin    Collective on PetscDrawLG
4125c6c1daeSBarry Smith 
4135c6c1daeSBarry Smith    Input Parameter:
4145c6c1daeSBarry Smith .  lg - the line graph context
4155c6c1daeSBarry Smith 
4165c6c1daeSBarry Smith    Level: intermediate
4175c6c1daeSBarry Smith 
418db781477SPatrick Sanan .seealso: `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()`
4195c6c1daeSBarry Smith @*/
4209371c9d4SSatish Balay PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg) {
421e118a51fSLisandro Dalcin   PetscReal   xmin, xmax, ymin, ymax;
422e118a51fSLisandro Dalcin   PetscMPIInt rank;
423e118a51fSLisandro Dalcin   PetscDraw   draw;
4245c6c1daeSBarry Smith   PetscBool   isnull;
4255c6c1daeSBarry Smith 
4265c6c1daeSBarry Smith   PetscFunctionBegin;
4275c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
4289566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(lg->win, &isnull));
4298f69470aSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
4309566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));
4315c6c1daeSBarry Smith 
4325b399a63SLisandro Dalcin   draw = lg->win;
4339566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
4349566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
435e118a51fSLisandro Dalcin 
4369371c9d4SSatish Balay   xmin = lg->xmin;
4379371c9d4SSatish Balay   xmax = lg->xmax;
4389371c9d4SSatish Balay   ymin = lg->ymin;
4399371c9d4SSatish Balay   ymax = lg->ymax;
4409566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
4419566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDraw(lg->axis));
4425c6c1daeSBarry Smith 
443d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
444dd400576SPatrick Sanan   if (rank == 0) {
445e118a51fSLisandro Dalcin     int i, j, dim = lg->dim, nopts = lg->nopts, cl;
4465c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4475c6c1daeSBarry Smith       for (j = 1; j < nopts; j++) {
4480ed3bfb6SBarry Smith         cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
4499566063dSJacob 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));
4509566063dSJacob Faibussowitsch         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl));
4515c6c1daeSBarry Smith       }
4525c6c1daeSBarry Smith     }
4535c6c1daeSBarry Smith   }
454dd400576SPatrick Sanan   if (rank == 0 && lg->legend) {
455088d793eSMatthew G. Knepley     PetscBool right = PETSC_FALSE;
456e118a51fSLisandro Dalcin     int       i, dim = lg->dim, cl;
4575c6c1daeSBarry Smith     PetscReal xl, yl, xr, yr, tw, th;
45871917b75SLisandro Dalcin     size_t    slen, len = 0;
4599566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr));
4609566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
4615c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
4629566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(lg->legend[i], &slen));
46371917b75SLisandro Dalcin       len = PetscMax(len, slen);
4645c6c1daeSBarry Smith     }
465088d793eSMatthew G. Knepley     if (right) {
4669371c9d4SSatish Balay       xr = xr - 1.5 * tw;
4679371c9d4SSatish Balay       xl = xr - (len + 7) * tw;
468088d793eSMatthew G. Knepley     } else {
4699371c9d4SSatish Balay       xl = xl + 1.5 * tw;
4709371c9d4SSatish Balay       xr = xl + (len + 7) * tw;
471088d793eSMatthew G. Knepley     }
4729371c9d4SSatish Balay     yr = yr - 1.0 * th;
4739371c9d4SSatish Balay     yl = yr - (dim + 1) * th;
4749566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK));
4759566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK));
4769566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK));
4779566063dSJacob Faibussowitsch     PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK));
4785c6c1daeSBarry Smith     for (i = 0; i < dim; i++) {
47971917b75SLisandro Dalcin       cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
4809566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl));
4819566063dSJacob Faibussowitsch       PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i]));
4825c6c1daeSBarry Smith     }
4835c6c1daeSBarry Smith   }
484d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
4855b399a63SLisandro Dalcin 
4869566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
4879566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
4885c6c1daeSBarry Smith   PetscFunctionReturn(0);
4895c6c1daeSBarry Smith }
4905c6c1daeSBarry Smith 
49157fd6651SLisandro Dalcin /*@
49257fd6651SLisandro Dalcin   PetscDrawLGSave - Saves a drawn image
49357fd6651SLisandro Dalcin 
49457fd6651SLisandro Dalcin   Collective on PetscDrawLG
49557fd6651SLisandro Dalcin 
49657fd6651SLisandro Dalcin   Input Parameter:
49757fd6651SLisandro Dalcin . lg - The line graph context
49857fd6651SLisandro Dalcin 
49957fd6651SLisandro Dalcin   Level: intermediate
50057fd6651SLisandro Dalcin 
501db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`
50257fd6651SLisandro Dalcin @*/
5039371c9d4SSatish Balay PetscErrorCode PetscDrawLGSave(PetscDrawLG lg) {
50457fd6651SLisandro Dalcin   PetscFunctionBegin;
50557fd6651SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5069566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(lg->win));
50757fd6651SLisandro Dalcin   PetscFunctionReturn(0);
50857fd6651SLisandro Dalcin }
50957fd6651SLisandro Dalcin 
5105c6c1daeSBarry Smith /*@
51134a5a0e3SBarry Smith   PetscDrawLGView - Prints a line graph.
5125c6c1daeSBarry Smith 
5135b399a63SLisandro Dalcin   Collective on PetscDrawLG
5145c6c1daeSBarry Smith 
5155c6c1daeSBarry Smith   Input Parameter:
5165c6c1daeSBarry Smith . lg - the line graph context
5175c6c1daeSBarry Smith 
5185c6c1daeSBarry Smith   Level: beginner
5195c6c1daeSBarry Smith 
520db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`
521ba1e01c4SBarry Smith 
5225c6c1daeSBarry Smith @*/
5239371c9d4SSatish Balay PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer) {
5245c6c1daeSBarry Smith   PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax;
52534a5a0e3SBarry Smith   PetscInt  i, j, dim = lg->dim, nopts = lg->nopts;
5265c6c1daeSBarry Smith 
5275c6c1daeSBarry Smith   PetscFunctionBegin;
5285c6c1daeSBarry Smith   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
529e118a51fSLisandro Dalcin 
5305c6c1daeSBarry Smith   if (nopts < 1) PetscFunctionReturn(0);
5315c6c1daeSBarry Smith   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
5325c6c1daeSBarry Smith 
533*48a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer));
5349566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer));
5355c6c1daeSBarry Smith   for (i = 0; i < dim; i++) {
5369566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i));
537*48a46eb9SPierre 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]));
5385c6c1daeSBarry Smith   }
5395c6c1daeSBarry Smith   PetscFunctionReturn(0);
5405c6c1daeSBarry Smith }
541287de1a7SBarry Smith 
542c2bac407SLisandro Dalcin /*@C
543c2bac407SLisandro Dalcin    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
544c2bac407SLisandro Dalcin    PetscDrawLG options in the database.
545c2bac407SLisandro Dalcin 
546c2bac407SLisandro Dalcin    Logically Collective on PetscDrawLG
547c2bac407SLisandro Dalcin 
548d8d19677SJose E. Roman    Input Parameters:
549c2bac407SLisandro Dalcin +  lg - the line graph context
550c2bac407SLisandro Dalcin -  prefix - the prefix to prepend to all option names
551c2bac407SLisandro Dalcin 
552c2bac407SLisandro Dalcin    Level: advanced
553c2bac407SLisandro Dalcin 
554db781477SPatrick Sanan .seealso: `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()`
555c2bac407SLisandro Dalcin @*/
5569371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[]) {
557c2bac407SLisandro Dalcin   PetscFunctionBegin;
558c2bac407SLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
5599566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix));
560c2bac407SLisandro Dalcin   PetscFunctionReturn(0);
561c2bac407SLisandro Dalcin }
562c2bac407SLisandro Dalcin 
563287de1a7SBarry Smith /*@
564287de1a7SBarry Smith     PetscDrawLGSetFromOptions - Sets options related to the PetscDrawLG
565287de1a7SBarry Smith 
5665b399a63SLisandro Dalcin     Collective on PetscDrawLG
567287de1a7SBarry Smith 
568287de1a7SBarry Smith     Options Database:
569287de1a7SBarry Smith 
570287de1a7SBarry Smith     Level: intermediate
571287de1a7SBarry Smith 
572db781477SPatrick Sanan .seealso: `PetscDrawLGDestroy()`, `PetscDrawLGCreate()`
573287de1a7SBarry Smith @*/
5749371c9d4SSatish Balay PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg) {
57571917b75SLisandro Dalcin   PetscBool           usemarkers, set;
57671917b75SLisandro Dalcin   PetscDrawMarkerType markertype;
577287de1a7SBarry Smith 
578287de1a7SBarry Smith   PetscFunctionBegin;
579e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1);
580e118a51fSLisandro Dalcin 
5819566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetMarkerType(lg->win, &markertype));
5829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set));
58371917b75SLisandro Dalcin   if (set) {
5849566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE));
5859566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetMarkerType(lg->win, markertype));
58671917b75SLisandro Dalcin   }
58771917b75SLisandro Dalcin   usemarkers = lg->use_markers;
5889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set));
5899566063dSJacob Faibussowitsch   if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers));
590287de1a7SBarry Smith   PetscFunctionReturn(0);
591287de1a7SBarry Smith }
592