xref: /petsc/src/sys/classes/draw/utils/dscatter.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
15c6c1daeSBarry Smith /*
25c6c1daeSBarry Smith        Contains the data structure for drawing scatter plots
35c6c1daeSBarry Smith     graphs in a window with an axis. This is intended for scatter
45c6c1daeSBarry Smith     plots that change dynamically.
55c6c1daeSBarry Smith */
65c6c1daeSBarry Smith 
79804daf3SBarry Smith #include <petscdraw.h>              /*I "petscdraw.h" I*/
8999739cfSJacob Faibussowitsch #include <petsc/private/drawimpl.h> /*I "petscsys.h" I*/
95c6c1daeSBarry Smith 
105c6c1daeSBarry Smith PetscClassId PETSC_DRAWSP_CLASSID = 0;
115c6c1daeSBarry Smith 
125c6c1daeSBarry Smith /*@C
135c6c1daeSBarry Smith   PetscDrawSPCreate - Creates a scatter plot data structure.
145c6c1daeSBarry Smith 
155b399a63SLisandro Dalcin   Collective on PetscDraw
165c6c1daeSBarry Smith 
175c6c1daeSBarry Smith   Input Parameters:
185c6c1daeSBarry Smith + win - the window where the graph will be made.
195c6c1daeSBarry Smith - dim - the number of sets of points which will be drawn
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith   Output Parameters:
225c6c1daeSBarry Smith . drawsp - the scatter plot context
235c6c1daeSBarry Smith 
245c6c1daeSBarry Smith   Level: intermediate
255c6c1daeSBarry Smith 
2695452b02SPatrick Sanan   Notes:
2795452b02SPatrick Sanan   Add points to the plot with PetscDrawSPAddPoint() or PetscDrawSPAddPoints(); the new points are not displayed until PetscDrawSPDraw() is called.
280afdd333SBarry Smith 
290afdd333SBarry Smith   PetscDrawSPReset() removes all the points that have been added
300afdd333SBarry Smith 
31f98b2f00SMatthew G. Knepley   The MPI communicator that owns the PetscDraw owns this PetscDrawSP, and each processc can add points. All MPI processes in the communicator must call PetscDrawSPDraw() to display the updated graph.
327e25d57eSBarry Smith 
33db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawSPDestroy()`, `PetscDraw`, `PetscDrawSP`, `PetscDrawSPSetDimension()`, `PetscDrawSPReset()`,
34c2e3fba1SPatrick Sanan           `PetscDrawSPAddPoint()`, `PetscDrawSPAddPoints()`, `PetscDrawSPDraw()`, `PetscDrawSPSave()`, `PetscDrawSPSetLimits()`, `PetscDrawSPGetAxis()`, `PetscDrawAxis`, `PetscDrawSPGetDraw()`
355c6c1daeSBarry Smith @*/
36*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPCreate(PetscDraw draw, int dim, PetscDrawSP *drawsp) {
375c6c1daeSBarry Smith   PetscDrawSP sp;
385c6c1daeSBarry Smith 
395c6c1daeSBarry Smith   PetscFunctionBegin;
405c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
415c6c1daeSBarry Smith   PetscValidPointer(drawsp, 3);
42e118a51fSLisandro Dalcin 
439566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(sp, PETSC_DRAWSP_CLASSID, "DrawSP", "Scatter Plot", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawSPDestroy, NULL));
449566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)draw, (PetscObject)sp));
459566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)draw));
465c6c1daeSBarry Smith   sp->win       = draw;
47e118a51fSLisandro Dalcin   sp->view      = NULL;
48e118a51fSLisandro Dalcin   sp->destroy   = NULL;
49e118a51fSLisandro Dalcin   sp->nopts     = 0;
50f98b2f00SMatthew G. Knepley   sp->dim       = -1;
515c6c1daeSBarry Smith   sp->xmin      = 1.e20;
525c6c1daeSBarry Smith   sp->ymin      = 1.e20;
53f98b2f00SMatthew G. Knepley   sp->zmin      = 1.e20;
545c6c1daeSBarry Smith   sp->xmax      = -1.e20;
555c6c1daeSBarry Smith   sp->ymax      = -1.e20;
56f98b2f00SMatthew G. Knepley   sp->zmax      = -1.e20;
578c87cf4dSdanfinn   sp->colorized = PETSC_FALSE;
585c6c1daeSBarry Smith   sp->loc       = 0;
59a297a907SKarl Rupp 
60f98b2f00SMatthew G. Knepley   PetscCall(PetscDrawSPSetDimension(sp, dim));
619566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &sp->axis));
629566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)sp, (PetscObject)sp->axis));
63a297a907SKarl Rupp 
645c6c1daeSBarry Smith   *drawsp = sp;
655c6c1daeSBarry Smith   PetscFunctionReturn(0);
665c6c1daeSBarry Smith }
675c6c1daeSBarry Smith 
685c6c1daeSBarry Smith /*@
695c6c1daeSBarry Smith   PetscDrawSPSetDimension - Change the number of sets of points that are to be drawn.
705c6c1daeSBarry Smith 
71f98b2f00SMatthew G. Knepley   Not collective
725c6c1daeSBarry Smith 
73d8d19677SJose E. Roman   Input Parameters:
745c6c1daeSBarry Smith + sp  - the line graph context.
75f98b2f00SMatthew G. Knepley - dim - the number of curves on this process
765c6c1daeSBarry Smith 
775c6c1daeSBarry Smith   Level: intermediate
785c6c1daeSBarry Smith 
79db781477SPatrick Sanan .seealso: `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPAddPoint()`, `PetscDrawSPAddPoints()`
805c6c1daeSBarry Smith @*/
81*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPSetDimension(PetscDrawSP sp, int dim) {
825c6c1daeSBarry Smith   PetscFunctionBegin;
835c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
845c6c1daeSBarry Smith   if (sp->dim == dim) PetscFunctionReturn(0);
855c6c1daeSBarry Smith   sp->dim = dim;
86f98b2f00SMatthew G. Knepley   PetscCall(PetscFree3(sp->x, sp->y, sp->z));
87f98b2f00SMatthew G. Knepley   PetscCall(PetscMalloc3(dim * PETSC_DRAW_SP_CHUNK_SIZE, &sp->x, dim * PETSC_DRAW_SP_CHUNK_SIZE, &sp->y, dim * PETSC_DRAW_SP_CHUNK_SIZE, &sp->z));
88f98b2f00SMatthew G. Knepley   PetscCall(PetscLogObjectMemory((PetscObject)sp, 3 * dim * PETSC_DRAW_SP_CHUNK_SIZE * sizeof(PetscReal)));
89999739cfSJacob Faibussowitsch   sp->len = dim * PETSC_DRAW_SP_CHUNK_SIZE;
905c6c1daeSBarry Smith   PetscFunctionReturn(0);
915c6c1daeSBarry Smith }
925c6c1daeSBarry Smith 
935c6c1daeSBarry Smith /*@
94f98b2f00SMatthew G. Knepley   PetscDrawSPGetDimension - Get the number of sets of points that are to be drawn.
95f98b2f00SMatthew G. Knepley 
96f98b2f00SMatthew G. Knepley   Not collective
97f98b2f00SMatthew G. Knepley 
98f98b2f00SMatthew G. Knepley   Input Parameters:
99f98b2f00SMatthew G. Knepley . sp  - the line graph context.
100f98b2f00SMatthew G. Knepley 
101f98b2f00SMatthew G. Knepley   Output Parameter:
102f98b2f00SMatthew G. Knepley . dim - the number of curves on this process
103f98b2f00SMatthew G. Knepley 
104f98b2f00SMatthew G. Knepley   Level: intermediate
105f98b2f00SMatthew G. Knepley 
106db781477SPatrick Sanan .seealso: `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPAddPoint()`, `PetscDrawSPAddPoints()`
107f98b2f00SMatthew G. Knepley @*/
108*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPGetDimension(PetscDrawSP sp, int *dim) {
109f98b2f00SMatthew G. Knepley   PetscFunctionBegin;
110f98b2f00SMatthew G. Knepley   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
111f98b2f00SMatthew G. Knepley   PetscValidPointer(dim, 2);
112f98b2f00SMatthew G. Knepley   *dim = sp->dim;
113f98b2f00SMatthew G. Knepley   PetscFunctionReturn(0);
114f98b2f00SMatthew G. Knepley }
115f98b2f00SMatthew G. Knepley 
116f98b2f00SMatthew G. Knepley /*@
1175c6c1daeSBarry Smith   PetscDrawSPReset - Clears line graph to allow for reuse with new data.
1185c6c1daeSBarry Smith 
119f98b2f00SMatthew G. Knepley   Not collective
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith   Input Parameter:
1225c6c1daeSBarry Smith . sp - the line graph context.
1235c6c1daeSBarry Smith 
1245c6c1daeSBarry Smith   Level: intermediate
1255c6c1daeSBarry Smith 
126db781477SPatrick Sanan .seealso: `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPAddPoint()`, `PetscDrawSPAddPoints()`, `PetscDrawSPDraw()`
1275c6c1daeSBarry Smith @*/
128*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPReset(PetscDrawSP sp) {
1295c6c1daeSBarry Smith   PetscFunctionBegin;
1305c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
1315c6c1daeSBarry Smith   sp->xmin  = 1.e20;
1325c6c1daeSBarry Smith   sp->ymin  = 1.e20;
1338c87cf4dSdanfinn   sp->zmin  = 1.e20;
1345c6c1daeSBarry Smith   sp->xmax  = -1.e20;
1355c6c1daeSBarry Smith   sp->ymax  = -1.e20;
1368c87cf4dSdanfinn   sp->zmax  = -1.e20;
1375c6c1daeSBarry Smith   sp->loc   = 0;
1385c6c1daeSBarry Smith   sp->nopts = 0;
1395c6c1daeSBarry Smith   PetscFunctionReturn(0);
1405c6c1daeSBarry Smith }
1415c6c1daeSBarry Smith 
142f98b2f00SMatthew G. Knepley /*@
1435c6c1daeSBarry Smith   PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.
1445c6c1daeSBarry Smith 
1455b399a63SLisandro Dalcin   Collective on PetscDrawSP
1465c6c1daeSBarry Smith 
1475c6c1daeSBarry Smith   Input Parameter:
1485c6c1daeSBarry Smith . sp - the line graph context
1495c6c1daeSBarry Smith 
1505c6c1daeSBarry Smith   Level: intermediate
1515c6c1daeSBarry Smith 
152db781477SPatrick Sanan .seealso: `PetscDrawSPCreate()`, `PetscDrawSP`, `PetscDrawSPReset()`
1535c6c1daeSBarry Smith @*/
154*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPDestroy(PetscDrawSP *sp) {
1555c6c1daeSBarry Smith   PetscFunctionBegin;
1565c6c1daeSBarry Smith   if (!*sp) PetscFunctionReturn(0);
157e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*sp, PETSC_DRAWSP_CLASSID, 1);
158*9371c9d4SSatish Balay   if (--((PetscObject)(*sp))->refct > 0) {
159*9371c9d4SSatish Balay     *sp = NULL;
160*9371c9d4SSatish Balay     PetscFunctionReturn(0);
161*9371c9d4SSatish Balay   }
1625c6c1daeSBarry Smith 
1639566063dSJacob Faibussowitsch   PetscCall(PetscFree3((*sp)->x, (*sp)->y, (*sp)->z));
1649566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*sp)->axis));
1659566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*sp)->win));
1669566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(sp));
1675c6c1daeSBarry Smith   PetscFunctionReturn(0);
1685c6c1daeSBarry Smith }
1695c6c1daeSBarry Smith 
1705c6c1daeSBarry Smith /*@
1715c6c1daeSBarry Smith   PetscDrawSPAddPoint - Adds another point to each of the scatter plots.
1725c6c1daeSBarry Smith 
173f98b2f00SMatthew G. Knepley   Not collective
1745c6c1daeSBarry Smith 
1755c6c1daeSBarry Smith   Input Parameters:
1765c6c1daeSBarry Smith + sp - the scatter plot data structure
1772cf5aabcSBarry Smith - x, y - two arrays of length dim containing the new x and y coordinate values for each of the curves. Here  dim is the number of curves passed to PetscDrawSPCreate()
1785c6c1daeSBarry Smith 
1795c6c1daeSBarry Smith   Level: intermediate
1805c6c1daeSBarry Smith 
18195452b02SPatrick Sanan   Notes:
182f98b2f00SMatthew G. Knepley   The new points will not be displayed until a call to PetscDrawSPDraw() is made
1830afdd333SBarry Smith 
184db781477SPatrick Sanan .seealso: `PetscDrawSPAddPoints()`, `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPReset()`, `PetscDrawSPDraw()`, `PetscDrawSPAddPointColorized()`
1855c6c1daeSBarry Smith @*/
186*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPAddPoint(PetscDrawSP sp, PetscReal *x, PetscReal *y) {
1875c6c1daeSBarry Smith   PetscInt i;
1885c6c1daeSBarry Smith 
1895c6c1daeSBarry Smith   PetscFunctionBegin;
1905c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
191e118a51fSLisandro Dalcin 
1925c6c1daeSBarry Smith   if (sp->loc + sp->dim >= sp->len) { /* allocate more space */
193f98b2f00SMatthew G. Knepley     PetscReal *tmpx, *tmpy, *tmpz;
194f98b2f00SMatthew G. Knepley     PetscCall(PetscMalloc3(sp->len + sp->dim * PETSC_DRAW_SP_CHUNK_SIZE, &tmpx, sp->len + sp->dim * PETSC_DRAW_SP_CHUNK_SIZE, &tmpy, sp->len + sp->dim * PETSC_DRAW_SP_CHUNK_SIZE, &tmpz));
195f98b2f00SMatthew G. Knepley     PetscCall(PetscLogObjectMemory((PetscObject)sp, 3 * sp->dim * PETSC_DRAW_SP_CHUNK_SIZE * sizeof(PetscReal)));
1969566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpx, sp->x, sp->len));
1979566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpy, sp->y, sp->len));
198f98b2f00SMatthew G. Knepley     PetscCall(PetscArraycpy(tmpz, sp->z, sp->len));
199f98b2f00SMatthew G. Knepley     PetscCall(PetscFree3(sp->x, sp->y, sp->z));
2005c6c1daeSBarry Smith     sp->x = tmpx;
2015c6c1daeSBarry Smith     sp->y = tmpy;
202f98b2f00SMatthew G. Knepley     sp->z = tmpz;
203999739cfSJacob Faibussowitsch     sp->len += sp->dim * PETSC_DRAW_SP_CHUNK_SIZE;
2045c6c1daeSBarry Smith   }
205f98b2f00SMatthew G. Knepley   for (i = 0; i < sp->dim; ++i) {
2065c6c1daeSBarry Smith     if (x[i] > sp->xmax) sp->xmax = x[i];
2075c6c1daeSBarry Smith     if (x[i] < sp->xmin) sp->xmin = x[i];
2085c6c1daeSBarry Smith     if (y[i] > sp->ymax) sp->ymax = y[i];
2095c6c1daeSBarry Smith     if (y[i] < sp->ymin) sp->ymin = y[i];
2105c6c1daeSBarry Smith 
2115c6c1daeSBarry Smith     sp->x[sp->loc]   = x[i];
2125c6c1daeSBarry Smith     sp->y[sp->loc++] = y[i];
2135c6c1daeSBarry Smith   }
214f98b2f00SMatthew G. Knepley   ++sp->nopts;
2155c6c1daeSBarry Smith   PetscFunctionReturn(0);
2165c6c1daeSBarry Smith }
2175c6c1daeSBarry Smith 
2185c6c1daeSBarry Smith /*@C
2195c6c1daeSBarry Smith   PetscDrawSPAddPoints - Adds several points to each of the scatter plots.
2205c6c1daeSBarry Smith 
221f98b2f00SMatthew G. Knepley   Not collective
2225c6c1daeSBarry Smith 
2235c6c1daeSBarry Smith   Input Parameters:
2245c6c1daeSBarry Smith + sp - the LineGraph data structure
225f98b2f00SMatthew G. Knepley . xx,yy - points to two arrays of pointers that point to arrays containing the new x and y points for each curve.
2265c6c1daeSBarry Smith - n - number of points being added
2275c6c1daeSBarry Smith 
2285c6c1daeSBarry Smith   Level: intermediate
2295c6c1daeSBarry Smith 
23095452b02SPatrick Sanan   Notes:
231f98b2f00SMatthew G. Knepley   The new points will not be displayed until a call to PetscDrawSPDraw() is made
2320afdd333SBarry Smith 
233db781477SPatrick Sanan .seealso: `PetscDrawSPAddPoint()`, `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPReset()`, `PetscDrawSPDraw()`, `PetscDrawSPAddPointColorized()`
2345c6c1daeSBarry Smith @*/
235*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPAddPoints(PetscDrawSP sp, int n, PetscReal **xx, PetscReal **yy) {
2365c6c1daeSBarry Smith   PetscInt   i, j, k;
2375c6c1daeSBarry Smith   PetscReal *x, *y;
2385c6c1daeSBarry Smith 
2395c6c1daeSBarry Smith   PetscFunctionBegin;
2405c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
2415c6c1daeSBarry Smith 
2425c6c1daeSBarry Smith   if (sp->loc + n * sp->dim >= sp->len) { /* allocate more space */
243f98b2f00SMatthew G. Knepley     PetscReal *tmpx, *tmpy, *tmpz;
244999739cfSJacob Faibussowitsch     PetscInt   chunk = PETSC_DRAW_SP_CHUNK_SIZE;
2455c6c1daeSBarry Smith     if (n > chunk) chunk = n;
246f98b2f00SMatthew G. Knepley     PetscCall(PetscMalloc3(sp->len + sp->dim * chunk, &tmpx, sp->len + sp->dim * chunk, &tmpy, sp->len + sp->dim * chunk, &tmpz));
247f98b2f00SMatthew G. Knepley     PetscCall(PetscLogObjectMemory((PetscObject)sp, 3 * sp->dim * PETSC_DRAW_SP_CHUNK_SIZE * sizeof(PetscReal)));
2489566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpx, sp->x, sp->len));
2499566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpy, sp->y, sp->len));
250f98b2f00SMatthew G. Knepley     PetscCall(PetscArraycpy(tmpz, sp->z, sp->len));
251f98b2f00SMatthew G. Knepley     PetscCall(PetscFree3(sp->x, sp->y, sp->z));
252a297a907SKarl Rupp 
2535c6c1daeSBarry Smith     sp->x = tmpx;
2545c6c1daeSBarry Smith     sp->y = tmpy;
255f98b2f00SMatthew G. Knepley     sp->z = tmpz;
256999739cfSJacob Faibussowitsch     sp->len += sp->dim * PETSC_DRAW_SP_CHUNK_SIZE;
2575c6c1daeSBarry Smith   }
258f98b2f00SMatthew G. Knepley   for (j = 0; j < sp->dim; ++j) {
259*9371c9d4SSatish Balay     x = xx[j];
260*9371c9d4SSatish Balay     y = yy[j];
2615c6c1daeSBarry Smith     k = sp->loc + j;
262f98b2f00SMatthew G. Knepley     for (i = 0; i < n; ++i) {
2635c6c1daeSBarry Smith       if (x[i] > sp->xmax) sp->xmax = x[i];
2645c6c1daeSBarry Smith       if (x[i] < sp->xmin) sp->xmin = x[i];
2655c6c1daeSBarry Smith       if (y[i] > sp->ymax) sp->ymax = y[i];
2665c6c1daeSBarry Smith       if (y[i] < sp->ymin) sp->ymin = y[i];
2675c6c1daeSBarry Smith 
2685c6c1daeSBarry Smith       sp->x[k] = x[i];
2695c6c1daeSBarry Smith       sp->y[k] = y[i];
2705c6c1daeSBarry Smith       k += sp->dim;
2715c6c1daeSBarry Smith     }
2725c6c1daeSBarry Smith   }
2735c6c1daeSBarry Smith   sp->loc += n * sp->dim;
2745c6c1daeSBarry Smith   sp->nopts += n;
2755c6c1daeSBarry Smith   PetscFunctionReturn(0);
2765c6c1daeSBarry Smith }
2775c6c1daeSBarry Smith 
2785c6c1daeSBarry Smith /*@
2798c87cf4dSdanfinn   PetscDrawSPAddPointColorized - Adds another point to each of the scatter plots as well as a numeric value to be used to colorize the scatter point.
2808c87cf4dSdanfinn 
281f98b2f00SMatthew G. Knepley   Not collective
2828c87cf4dSdanfinn 
2838c87cf4dSdanfinn   Input Parameters:
2848c87cf4dSdanfinn + sp - the scatter plot data structure
2858c87cf4dSdanfinn . x, y - two arrays of length dim containing the new x and y coordinate values for each of the curves. Here  dim is the number of curves passed to PetscDrawSPCreate()
2868c87cf4dSdanfinn - z - array of length dim containing the numeric values that will be mapped to [0,255] and used for scatter point colors.
2878c87cf4dSdanfinn 
2888c87cf4dSdanfinn   Level: intermediate
2898c87cf4dSdanfinn 
2908c87cf4dSdanfinn   Notes:
291f98b2f00SMatthew G. Knepley   The new points will not be displayed until a call to PetscDrawSPDraw() is made
2928c87cf4dSdanfinn 
293db781477SPatrick Sanan .seealso: `PetscDrawSPAddPoints()`, `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPReset()`, `PetscDrawSPDraw()`, `PetscDrawSPAddPoint()`
2948c87cf4dSdanfinn @*/
295*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPAddPointColorized(PetscDrawSP sp, PetscReal *x, PetscReal *y, PetscReal *z) {
2968c87cf4dSdanfinn   PetscInt i;
2978c87cf4dSdanfinn 
2988c87cf4dSdanfinn   PetscFunctionBegin;
2998c87cf4dSdanfinn   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
3008c87cf4dSdanfinn   sp->colorized = PETSC_TRUE;
3018c87cf4dSdanfinn   if (sp->loc + sp->dim >= sp->len) { /* allocate more space */
3028c87cf4dSdanfinn     PetscReal *tmpx, *tmpy, *tmpz;
3039566063dSJacob Faibussowitsch     PetscCall(PetscMalloc3(sp->len + sp->dim * PETSC_DRAW_SP_CHUNK_SIZE, &tmpx, sp->len + sp->dim * PETSC_DRAW_SP_CHUNK_SIZE, &tmpy, sp->len + sp->dim * PETSC_DRAW_SP_CHUNK_SIZE, &tmpz));
304f98b2f00SMatthew G. Knepley     PetscCall(PetscLogObjectMemory((PetscObject)sp, 3 * sp->dim * PETSC_DRAW_SP_CHUNK_SIZE * sizeof(PetscReal)));
3059566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpx, sp->x, sp->len));
3069566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpy, sp->y, sp->len));
3079566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpz, sp->z, sp->len));
3089566063dSJacob Faibussowitsch     PetscCall(PetscFree3(sp->x, sp->y, sp->z));
3098c87cf4dSdanfinn     sp->x = tmpx;
3108c87cf4dSdanfinn     sp->y = tmpy;
3118c87cf4dSdanfinn     sp->z = tmpz;
3128c87cf4dSdanfinn     sp->len += sp->dim * PETSC_DRAW_SP_CHUNK_SIZE;
3138c87cf4dSdanfinn   }
314f98b2f00SMatthew G. Knepley   for (i = 0; i < sp->dim; ++i) {
3158c87cf4dSdanfinn     if (x[i] > sp->xmax) sp->xmax = x[i];
3168c87cf4dSdanfinn     if (x[i] < sp->xmin) sp->xmin = x[i];
3178c87cf4dSdanfinn     if (y[i] > sp->ymax) sp->ymax = y[i];
3188c87cf4dSdanfinn     if (y[i] < sp->ymin) sp->ymin = y[i];
3198c87cf4dSdanfinn     if (z[i] < sp->zmin) sp->zmin = z[i];
3208c87cf4dSdanfinn     if (z[i] > sp->zmax) sp->zmax = z[i];
3218c87cf4dSdanfinn     // if (z[i] > sp->zmax && z[i] < 5.) sp->zmax = z[i];
3228c87cf4dSdanfinn 
3238c87cf4dSdanfinn     sp->x[sp->loc]   = x[i];
3248c87cf4dSdanfinn     sp->y[sp->loc]   = y[i];
3258c87cf4dSdanfinn     sp->z[sp->loc++] = z[i];
3268c87cf4dSdanfinn   }
327f98b2f00SMatthew G. Knepley   ++sp->nopts;
3288c87cf4dSdanfinn   PetscFunctionReturn(0);
3298c87cf4dSdanfinn }
3308c87cf4dSdanfinn 
3318c87cf4dSdanfinn /*@
3325c6c1daeSBarry Smith   PetscDrawSPDraw - Redraws a scatter plot.
3335c6c1daeSBarry Smith 
3345b399a63SLisandro Dalcin   Collective on PetscDrawSP
3355c6c1daeSBarry Smith 
336d8d19677SJose E. Roman   Input Parameters:
3375c6c1daeSBarry Smith + sp - the line graph context
3385c6c1daeSBarry Smith - clear - clear the window before drawing the new plot
3395c6c1daeSBarry Smith 
3405c6c1daeSBarry Smith   Level: intermediate
3415c6c1daeSBarry Smith 
342db781477SPatrick Sanan .seealso: `PetscDrawLGDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPReset()`, `PetscDrawSPAddPoint()`, `PetscDrawSPAddPoints()`
3435c6c1daeSBarry Smith @*/
344*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPDraw(PetscDrawSP sp, PetscBool clear) {
345e118a51fSLisandro Dalcin   PetscDraw   draw;
346f98b2f00SMatthew G. Knepley   PetscBool   isnull;
347f98b2f00SMatthew G. Knepley   PetscMPIInt rank, size;
3485c6c1daeSBarry Smith 
3495c6c1daeSBarry Smith   PetscFunctionBegin;
3505c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
351f98b2f00SMatthew G. Knepley   draw = sp->win;
352f98b2f00SMatthew G. Knepley   PetscCall(PetscDrawIsNull(draw, &isnull));
3538f69470aSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
3549566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)sp), &rank));
355f98b2f00SMatthew G. Knepley   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sp), &size));
356e118a51fSLisandro Dalcin 
3575c6c1daeSBarry Smith   if (clear) {
3589566063dSJacob Faibussowitsch     PetscCall(PetscDrawCheckResizedWindow(draw));
3599566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
3605c6c1daeSBarry Smith   }
361f98b2f00SMatthew G. Knepley   {
362f98b2f00SMatthew G. Knepley     PetscReal lower[2] = {sp->xmin, sp->ymin}, glower[2];
363f98b2f00SMatthew G. Knepley     PetscReal upper[2] = {sp->xmax, sp->ymax}, gupper[2];
364f98b2f00SMatthew G. Knepley     PetscCall(MPIU_Allreduce(lower, glower, 2, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject)sp)));
365f98b2f00SMatthew G. Knepley     PetscCall(MPIU_Allreduce(upper, gupper, 2, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)sp)));
366f98b2f00SMatthew G. Knepley     PetscCall(PetscDrawAxisSetLimits(sp->axis, glower[0], gupper[0], glower[1], gupper[1]));
3679566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(sp->axis));
368f98b2f00SMatthew G. Knepley   }
3695c6c1daeSBarry Smith 
370d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
371f98b2f00SMatthew G. Knepley   {
372f98b2f00SMatthew G. Knepley     const int dim = sp->dim, nopts = sp->nopts;
373f98b2f00SMatthew G. Knepley 
374f98b2f00SMatthew G. Knepley     for (int i = 0; i < dim; ++i) {
375f98b2f00SMatthew G. Knepley       for (int p = 0; p < nopts; ++p) {
376f98b2f00SMatthew G. Knepley         PetscInt color = sp->colorized ? PetscDrawRealToColor(sp->z[p * dim], sp->zmin, sp->zmax) : (size > 1 ? PetscDrawRealToColor(rank, 0, size - 1) : PETSC_DRAW_RED);
377f98b2f00SMatthew G. Knepley 
378f98b2f00SMatthew G. Knepley         PetscCall(PetscDrawPoint(draw, sp->x[p * dim + i], sp->y[p * dim + i], color));
3795c6c1daeSBarry Smith       }
3805c6c1daeSBarry Smith     }
3818c87cf4dSdanfinn   }
382d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
3835b399a63SLisandro Dalcin 
3849566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
3859566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
3865c6c1daeSBarry Smith   PetscFunctionReturn(0);
3875c6c1daeSBarry Smith }
3885c6c1daeSBarry Smith 
38957fd6651SLisandro Dalcin /*@
39057fd6651SLisandro Dalcin   PetscDrawSPSave - Saves a drawn image
39157fd6651SLisandro Dalcin 
39257fd6651SLisandro Dalcin   Collective on PetscDrawSP
39357fd6651SLisandro Dalcin 
39457fd6651SLisandro Dalcin   Input Parameter:
39557fd6651SLisandro Dalcin . sp - the scatter plot context
39657fd6651SLisandro Dalcin 
39757fd6651SLisandro Dalcin   Level: intermediate
39857fd6651SLisandro Dalcin 
399db781477SPatrick Sanan .seealso: `PetscDrawSPCreate()`, `PetscDrawSPGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`
40057fd6651SLisandro Dalcin @*/
401*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPSave(PetscDrawSP sp) {
40257fd6651SLisandro Dalcin   PetscFunctionBegin;
40357fd6651SLisandro Dalcin   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
4049566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(sp->win));
40557fd6651SLisandro Dalcin   PetscFunctionReturn(0);
40657fd6651SLisandro Dalcin }
40757fd6651SLisandro Dalcin 
4085c6c1daeSBarry Smith /*@
409f98b2f00SMatthew G. Knepley   PetscDrawSPSetLimits - Sets the axis limits for a scatter plot. If more points are added after this call, the limits will be adjusted to include those additional points.
4105c6c1daeSBarry Smith 
411f98b2f00SMatthew G. Knepley   Not collective
4125c6c1daeSBarry Smith 
4135c6c1daeSBarry Smith   Input Parameters:
4145c6c1daeSBarry Smith + xsp - the line graph context
4155c6c1daeSBarry Smith - x_min,x_max,y_min,y_max - the limits
4165c6c1daeSBarry Smith 
4175c6c1daeSBarry Smith   Level: intermediate
4185c6c1daeSBarry Smith 
419db781477SPatrick Sanan .seealso: `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPDraw()`, `PetscDrawSPAddPoint()`, `PetscDrawSPAddPoints()`, `PetscDrawSPGetAxis()`
4205c6c1daeSBarry Smith @*/
421*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPSetLimits(PetscDrawSP sp, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max) {
4225c6c1daeSBarry Smith   PetscFunctionBegin;
4235c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
4245c6c1daeSBarry Smith   sp->xmin = x_min;
4255c6c1daeSBarry Smith   sp->xmax = x_max;
4265c6c1daeSBarry Smith   sp->ymin = y_min;
4275c6c1daeSBarry Smith   sp->ymax = y_max;
4285c6c1daeSBarry Smith   PetscFunctionReturn(0);
4295c6c1daeSBarry Smith }
4305c6c1daeSBarry Smith 
431f98b2f00SMatthew G. Knepley /*@
4325c6c1daeSBarry Smith   PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
4335c6c1daeSBarry Smith 
434f98b2f00SMatthew G. Knepley   Not Collective
4355c6c1daeSBarry Smith 
4365c6c1daeSBarry Smith   Input Parameter:
4375c6c1daeSBarry Smith . sp - the line graph context
4385c6c1daeSBarry Smith 
4395c6c1daeSBarry Smith   Output Parameter:
4405c6c1daeSBarry Smith . axis - the axis context
4415c6c1daeSBarry Smith 
442f98b2f00SMatthew G. Knepley   Note:
443f98b2f00SMatthew G. Knepley   This is useful if one wants to change some axis property, such as labels, color, etc. The axis context should not be destroyed by the application code.
444f98b2f00SMatthew G. Knepley 
4455c6c1daeSBarry Smith   Level: intermediate
4465c6c1daeSBarry Smith 
447db781477SPatrick Sanan .seealso: `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPDraw()`, `PetscDrawSPAddPoint()`, `PetscDrawSPAddPoints()`, `PetscDrawAxis`, `PetscDrawAxisCreate()`
4485c6c1daeSBarry Smith @*/
449*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPGetAxis(PetscDrawSP sp, PetscDrawAxis *axis) {
4505c6c1daeSBarry Smith   PetscFunctionBegin;
4515c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
45245f3bb6eSLisandro Dalcin   PetscValidPointer(axis, 2);
4535c6c1daeSBarry Smith   *axis = sp->axis;
4545c6c1daeSBarry Smith   PetscFunctionReturn(0);
4555c6c1daeSBarry Smith }
4565c6c1daeSBarry Smith 
457f98b2f00SMatthew G. Knepley /*@
4585c6c1daeSBarry Smith   PetscDrawSPGetDraw - Gets the draw context associated with a line graph.
4595c6c1daeSBarry Smith 
460f98b2f00SMatthew G. Knepley   Not Collective
4615c6c1daeSBarry Smith 
4625c6c1daeSBarry Smith   Input Parameter:
4635c6c1daeSBarry Smith . sp - the line graph context
4645c6c1daeSBarry Smith 
4655c6c1daeSBarry Smith   Output Parameter:
4665c6c1daeSBarry Smith . draw - the draw context
4675c6c1daeSBarry Smith 
4685c6c1daeSBarry Smith   Level: intermediate
4695c6c1daeSBarry Smith 
470db781477SPatrick Sanan .seealso: `PetscDrawSP`, `PetscDrawSPCreate()`, `PetscDrawSPDraw()`, `PetscDraw`
4715c6c1daeSBarry Smith @*/
472*9371c9d4SSatish Balay PetscErrorCode PetscDrawSPGetDraw(PetscDrawSP sp, PetscDraw *draw) {
4735c6c1daeSBarry Smith   PetscFunctionBegin;
474e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
47545f3bb6eSLisandro Dalcin   PetscValidPointer(draw, 2);
476e118a51fSLisandro Dalcin   *draw = sp->win;
4775c6c1daeSBarry Smith   PetscFunctionReturn(0);
4785c6c1daeSBarry Smith }
479