xref: /petsc/src/sys/classes/draw/utils/dscatter.c (revision f98b2f000af27288b2e6514cfaab9d6a9f06ed3e)
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 
31*f98b2f00SMatthew 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 
330afdd333SBarry Smith .seealso:  PetscDrawLGCreate(), PetscDrawLG, PetscDrawBarCreate(), PetscDrawBar, PetscDrawHGCreate(), PetscDrawHG, PetscDrawSPDestroy(), PetscDraw, PetscDrawSP, PetscDrawSPSetDimension(), PetscDrawSPReset(),
340afdd333SBarry Smith            PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPDraw(), PetscDrawSPSave(), PetscDrawSPSetLimits(), PetscDrawSPGetAxis(),PetscDrawAxis, PetscDrawSPGetDraw()
355c6c1daeSBarry Smith @*/
365c6c1daeSBarry Smith PetscErrorCode PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
375c6c1daeSBarry Smith {
385c6c1daeSBarry Smith   PetscDrawSP sp;
395c6c1daeSBarry Smith 
405c6c1daeSBarry Smith   PetscFunctionBegin;
415c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
425c6c1daeSBarry Smith   PetscValidPointer(drawsp, 3);
43e118a51fSLisandro Dalcin 
449566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(sp, PETSC_DRAWSP_CLASSID, "DrawSP", "Scatter Plot", "Draw", PetscObjectComm((PetscObject) draw), PetscDrawSPDestroy, NULL));
459566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject) draw, (PetscObject) sp));
469566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) draw));
475c6c1daeSBarry Smith   sp->win       = draw;
48e118a51fSLisandro Dalcin   sp->view      = NULL;
49e118a51fSLisandro Dalcin   sp->destroy   = NULL;
50e118a51fSLisandro Dalcin   sp->nopts     = 0;
51*f98b2f00SMatthew G. Knepley   sp->dim       = -1;
525c6c1daeSBarry Smith   sp->xmin      = 1.e20;
535c6c1daeSBarry Smith   sp->ymin      = 1.e20;
54*f98b2f00SMatthew G. Knepley   sp->zmin      = 1.e20;
555c6c1daeSBarry Smith   sp->xmax      = -1.e20;
565c6c1daeSBarry Smith   sp->ymax      = -1.e20;
57*f98b2f00SMatthew G. Knepley   sp->zmax      = -1.e20;
588c87cf4dSdanfinn   sp->colorized = PETSC_FALSE;
595c6c1daeSBarry Smith   sp->loc       = 0;
60a297a907SKarl Rupp 
61*f98b2f00SMatthew G. Knepley   PetscCall(PetscDrawSPSetDimension(sp, dim));
629566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &sp->axis));
639566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject) sp, (PetscObject) sp->axis));
64a297a907SKarl Rupp 
655c6c1daeSBarry Smith   *drawsp = sp;
665c6c1daeSBarry Smith   PetscFunctionReturn(0);
675c6c1daeSBarry Smith }
685c6c1daeSBarry Smith 
695c6c1daeSBarry Smith /*@
705c6c1daeSBarry Smith   PetscDrawSPSetDimension - Change the number of sets of points that are to be drawn.
715c6c1daeSBarry Smith 
72*f98b2f00SMatthew G. Knepley   Not collective
735c6c1daeSBarry Smith 
74d8d19677SJose E. Roman   Input Parameters:
755c6c1daeSBarry Smith + sp  - the line graph context.
76*f98b2f00SMatthew G. Knepley - dim - the number of curves on this process
775c6c1daeSBarry Smith 
785c6c1daeSBarry Smith   Level: intermediate
795c6c1daeSBarry Smith 
800afdd333SBarry Smith .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints()
815c6c1daeSBarry Smith @*/
825c6c1daeSBarry Smith PetscErrorCode PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
835c6c1daeSBarry Smith {
845c6c1daeSBarry Smith   PetscFunctionBegin;
855c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
865c6c1daeSBarry Smith   if (sp->dim == dim) PetscFunctionReturn(0);
875c6c1daeSBarry Smith   sp->dim = dim;
88*f98b2f00SMatthew G. Knepley   PetscCall(PetscFree3(sp->x, sp->y, sp->z));
89*f98b2f00SMatthew 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));
90*f98b2f00SMatthew G. Knepley   PetscCall(PetscLogObjectMemory((PetscObject) sp, 3*dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal)));
91999739cfSJacob Faibussowitsch   sp->len = dim*PETSC_DRAW_SP_CHUNK_SIZE;
925c6c1daeSBarry Smith   PetscFunctionReturn(0);
935c6c1daeSBarry Smith }
945c6c1daeSBarry Smith 
955c6c1daeSBarry Smith /*@
96*f98b2f00SMatthew G. Knepley   PetscDrawSPGetDimension - Get the number of sets of points that are to be drawn.
97*f98b2f00SMatthew G. Knepley 
98*f98b2f00SMatthew G. Knepley   Not collective
99*f98b2f00SMatthew G. Knepley 
100*f98b2f00SMatthew G. Knepley   Input Parameters:
101*f98b2f00SMatthew G. Knepley . sp  - the line graph context.
102*f98b2f00SMatthew G. Knepley 
103*f98b2f00SMatthew G. Knepley   Output Parameter:
104*f98b2f00SMatthew G. Knepley . dim - the number of curves on this process
105*f98b2f00SMatthew G. Knepley 
106*f98b2f00SMatthew G. Knepley   Level: intermediate
107*f98b2f00SMatthew G. Knepley 
108*f98b2f00SMatthew G. Knepley .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints()
109*f98b2f00SMatthew G. Knepley @*/
110*f98b2f00SMatthew G. Knepley PetscErrorCode PetscDrawSPGetDimension(PetscDrawSP sp, int *dim)
111*f98b2f00SMatthew G. Knepley {
112*f98b2f00SMatthew G. Knepley   PetscFunctionBegin;
113*f98b2f00SMatthew G. Knepley   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
114*f98b2f00SMatthew G. Knepley   PetscValidPointer(dim, 2);
115*f98b2f00SMatthew G. Knepley   *dim = sp->dim;
116*f98b2f00SMatthew G. Knepley   PetscFunctionReturn(0);
117*f98b2f00SMatthew G. Knepley }
118*f98b2f00SMatthew G. Knepley 
119*f98b2f00SMatthew G. Knepley /*@
1205c6c1daeSBarry Smith   PetscDrawSPReset - Clears line graph to allow for reuse with new data.
1215c6c1daeSBarry Smith 
122*f98b2f00SMatthew G. Knepley   Not collective
1235c6c1daeSBarry Smith 
1245c6c1daeSBarry Smith   Input Parameter:
1255c6c1daeSBarry Smith . sp - the line graph context.
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith   Level: intermediate
1285c6c1daeSBarry Smith 
1290afdd333SBarry Smith .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPDraw()
1305c6c1daeSBarry Smith @*/
1315c6c1daeSBarry Smith PetscErrorCode PetscDrawSPReset(PetscDrawSP sp)
1325c6c1daeSBarry Smith {
1335c6c1daeSBarry Smith   PetscFunctionBegin;
1345c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
1355c6c1daeSBarry Smith   sp->xmin  = 1.e20;
1365c6c1daeSBarry Smith   sp->ymin  = 1.e20;
1378c87cf4dSdanfinn   sp->zmin  = 1.e20;
1385c6c1daeSBarry Smith   sp->xmax  = -1.e20;
1395c6c1daeSBarry Smith   sp->ymax  = -1.e20;
1408c87cf4dSdanfinn   sp->zmax  = -1.e20;
1415c6c1daeSBarry Smith   sp->loc   = 0;
1425c6c1daeSBarry Smith   sp->nopts = 0;
1435c6c1daeSBarry Smith   PetscFunctionReturn(0);
1445c6c1daeSBarry Smith }
1455c6c1daeSBarry Smith 
146*f98b2f00SMatthew G. Knepley /*@
1475c6c1daeSBarry Smith   PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.
1485c6c1daeSBarry Smith 
1495b399a63SLisandro Dalcin   Collective on PetscDrawSP
1505c6c1daeSBarry Smith 
1515c6c1daeSBarry Smith   Input Parameter:
1525c6c1daeSBarry Smith . sp - the line graph context
1535c6c1daeSBarry Smith 
1545c6c1daeSBarry Smith   Level: intermediate
1555c6c1daeSBarry Smith 
1560afdd333SBarry Smith .seealso: PetscDrawSPCreate(), PetscDrawSP, PetscDrawSPReset()
1575c6c1daeSBarry Smith @*/
1585c6c1daeSBarry Smith PetscErrorCode PetscDrawSPDestroy(PetscDrawSP *sp)
1595c6c1daeSBarry Smith {
1605c6c1daeSBarry Smith   PetscFunctionBegin;
1615c6c1daeSBarry Smith   if (!*sp) PetscFunctionReturn(0);
162e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*sp,PETSC_DRAWSP_CLASSID,1);
163e118a51fSLisandro Dalcin   if (--((PetscObject)(*sp))->refct > 0) {*sp = NULL; PetscFunctionReturn(0);}
1645c6c1daeSBarry Smith 
1659566063dSJacob Faibussowitsch   PetscCall(PetscFree3((*sp)->x, (*sp)->y, (*sp)->z));
1669566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*sp)->axis));
1679566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*sp)->win));
1689566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(sp));
1695c6c1daeSBarry Smith   PetscFunctionReturn(0);
1705c6c1daeSBarry Smith }
1715c6c1daeSBarry Smith 
1725c6c1daeSBarry Smith /*@
1735c6c1daeSBarry Smith   PetscDrawSPAddPoint - Adds another point to each of the scatter plots.
1745c6c1daeSBarry Smith 
175*f98b2f00SMatthew G. Knepley   Not collective
1765c6c1daeSBarry Smith 
1775c6c1daeSBarry Smith   Input Parameters:
1785c6c1daeSBarry Smith + sp - the scatter plot data structure
1792cf5aabcSBarry 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()
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith   Level: intermediate
1825c6c1daeSBarry Smith 
18395452b02SPatrick Sanan   Notes:
184*f98b2f00SMatthew G. Knepley   The new points will not be displayed until a call to PetscDrawSPDraw() is made
1850afdd333SBarry Smith 
1868c87cf4dSdanfinn .seealso: PetscDrawSPAddPoints(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw(), PetscDrawSPAddPointColorized()
1875c6c1daeSBarry Smith @*/
1885c6c1daeSBarry Smith PetscErrorCode PetscDrawSPAddPoint(PetscDrawSP sp, PetscReal *x, PetscReal *y)
1895c6c1daeSBarry Smith {
1905c6c1daeSBarry Smith   PetscInt i;
1915c6c1daeSBarry Smith 
1925c6c1daeSBarry Smith   PetscFunctionBegin;
1935c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
194e118a51fSLisandro Dalcin 
1955c6c1daeSBarry Smith   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
196*f98b2f00SMatthew G. Knepley     PetscReal *tmpx, *tmpy, *tmpz;
197*f98b2f00SMatthew 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));
198*f98b2f00SMatthew G. Knepley     PetscCall(PetscLogObjectMemory((PetscObject) sp, 3*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal)));
1999566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpx, sp->x, sp->len));
2009566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpy, sp->y, sp->len));
201*f98b2f00SMatthew G. Knepley     PetscCall(PetscArraycpy(tmpz, sp->z, sp->len));
202*f98b2f00SMatthew G. Knepley     PetscCall(PetscFree3(sp->x, sp->y, sp->z));
2035c6c1daeSBarry Smith     sp->x = tmpx;
2045c6c1daeSBarry Smith     sp->y = tmpy;
205*f98b2f00SMatthew G. Knepley     sp->z = tmpz;
206999739cfSJacob Faibussowitsch     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
2075c6c1daeSBarry Smith   }
208*f98b2f00SMatthew G. Knepley   for (i = 0; i < sp->dim; ++i) {
2095c6c1daeSBarry Smith     if (x[i] > sp->xmax) sp->xmax = x[i];
2105c6c1daeSBarry Smith     if (x[i] < sp->xmin) sp->xmin = x[i];
2115c6c1daeSBarry Smith     if (y[i] > sp->ymax) sp->ymax = y[i];
2125c6c1daeSBarry Smith     if (y[i] < sp->ymin) sp->ymin = y[i];
2135c6c1daeSBarry Smith 
2145c6c1daeSBarry Smith     sp->x[sp->loc]   = x[i];
2155c6c1daeSBarry Smith     sp->y[sp->loc++] = y[i];
2165c6c1daeSBarry Smith   }
217*f98b2f00SMatthew G. Knepley   ++sp->nopts;
2185c6c1daeSBarry Smith   PetscFunctionReturn(0);
2195c6c1daeSBarry Smith }
2205c6c1daeSBarry Smith 
2215c6c1daeSBarry Smith /*@C
2225c6c1daeSBarry Smith   PetscDrawSPAddPoints - Adds several points to each of the scatter plots.
2235c6c1daeSBarry Smith 
224*f98b2f00SMatthew G. Knepley   Not collective
2255c6c1daeSBarry Smith 
2265c6c1daeSBarry Smith   Input Parameters:
2275c6c1daeSBarry Smith + sp - the LineGraph data structure
228*f98b2f00SMatthew G. Knepley . xx,yy - points to two arrays of pointers that point to arrays containing the new x and y points for each curve.
2295c6c1daeSBarry Smith - n - number of points being added
2305c6c1daeSBarry Smith 
2315c6c1daeSBarry Smith   Level: intermediate
2325c6c1daeSBarry Smith 
23395452b02SPatrick Sanan   Notes:
234*f98b2f00SMatthew G. Knepley   The new points will not be displayed until a call to PetscDrawSPDraw() is made
2350afdd333SBarry Smith 
2368c87cf4dSdanfinn .seealso: PetscDrawSPAddPoint(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw(), PetscDrawSPAddPointColorized()
2375c6c1daeSBarry Smith @*/
2385c6c1daeSBarry Smith PetscErrorCode PetscDrawSPAddPoints(PetscDrawSP sp, int n, PetscReal **xx, PetscReal **yy)
2395c6c1daeSBarry Smith {
2405c6c1daeSBarry Smith   PetscInt   i, j, k;
2415c6c1daeSBarry Smith   PetscReal *x, *y;
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith   PetscFunctionBegin;
2445c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
2455c6c1daeSBarry Smith 
2465c6c1daeSBarry Smith   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
247*f98b2f00SMatthew G. Knepley     PetscReal *tmpx, *tmpy, *tmpz;
248999739cfSJacob Faibussowitsch     PetscInt  chunk = PETSC_DRAW_SP_CHUNK_SIZE;
2495c6c1daeSBarry Smith     if (n > chunk) chunk = n;
250*f98b2f00SMatthew G. Knepley     PetscCall(PetscMalloc3(sp->len+sp->dim*chunk, &tmpx, sp->len+sp->dim*chunk, &tmpy, sp->len+sp->dim*chunk, &tmpz));
251*f98b2f00SMatthew G. Knepley     PetscCall(PetscLogObjectMemory((PetscObject) sp, 3*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal)));
2529566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpx, sp->x, sp->len));
2539566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpy, sp->y, sp->len));
254*f98b2f00SMatthew G. Knepley     PetscCall(PetscArraycpy(tmpz, sp->z, sp->len));
255*f98b2f00SMatthew G. Knepley     PetscCall(PetscFree3(sp->x, sp->y, sp->z));
256a297a907SKarl Rupp 
2575c6c1daeSBarry Smith     sp->x    = tmpx;
2585c6c1daeSBarry Smith     sp->y    = tmpy;
259*f98b2f00SMatthew G. Knepley     sp->z    = tmpz;
260999739cfSJacob Faibussowitsch     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
2615c6c1daeSBarry Smith   }
262*f98b2f00SMatthew G. Knepley   for (j = 0; j < sp->dim; ++j) {
2635c6c1daeSBarry Smith     x = xx[j]; y = yy[j];
2645c6c1daeSBarry Smith     k = sp->loc + j;
265*f98b2f00SMatthew G. Knepley     for (i = 0; i < n; ++i) {
2665c6c1daeSBarry Smith       if (x[i] > sp->xmax) sp->xmax = x[i];
2675c6c1daeSBarry Smith       if (x[i] < sp->xmin) sp->xmin = x[i];
2685c6c1daeSBarry Smith       if (y[i] > sp->ymax) sp->ymax = y[i];
2695c6c1daeSBarry Smith       if (y[i] < sp->ymin) sp->ymin = y[i];
2705c6c1daeSBarry Smith 
2715c6c1daeSBarry Smith       sp->x[k] = x[i];
2725c6c1daeSBarry Smith       sp->y[k] = y[i];
2735c6c1daeSBarry Smith       k       += sp->dim;
2745c6c1daeSBarry Smith     }
2755c6c1daeSBarry Smith   }
2765c6c1daeSBarry Smith   sp->loc   += n*sp->dim;
2775c6c1daeSBarry Smith   sp->nopts += n;
2785c6c1daeSBarry Smith   PetscFunctionReturn(0);
2795c6c1daeSBarry Smith }
2805c6c1daeSBarry Smith 
2815c6c1daeSBarry Smith /*@
2828c87cf4dSdanfinn   PetscDrawSPAddPointColorized - Adds another point to each of the scatter plots as well as a numeric value to be used to colorize the scatter point.
2838c87cf4dSdanfinn 
284*f98b2f00SMatthew G. Knepley   Not collective
2858c87cf4dSdanfinn 
2868c87cf4dSdanfinn   Input Parameters:
2878c87cf4dSdanfinn + sp - the scatter plot data structure
2888c87cf4dSdanfinn . 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()
2898c87cf4dSdanfinn - z - array of length dim containing the numeric values that will be mapped to [0,255] and used for scatter point colors.
2908c87cf4dSdanfinn 
2918c87cf4dSdanfinn   Level: intermediate
2928c87cf4dSdanfinn 
2938c87cf4dSdanfinn   Notes:
294*f98b2f00SMatthew G. Knepley   The new points will not be displayed until a call to PetscDrawSPDraw() is made
2958c87cf4dSdanfinn 
2968c87cf4dSdanfinn .seealso: PetscDrawSPAddPoints(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw(), PetscDrawSPAddPoint()
2978c87cf4dSdanfinn @*/
2988c87cf4dSdanfinn PetscErrorCode PetscDrawSPAddPointColorized(PetscDrawSP sp, PetscReal *x, PetscReal *y, PetscReal *z)
2998c87cf4dSdanfinn {
3008c87cf4dSdanfinn   PetscInt i;
3018c87cf4dSdanfinn 
3028c87cf4dSdanfinn   PetscFunctionBegin;
3038c87cf4dSdanfinn   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
3048c87cf4dSdanfinn   sp->colorized = PETSC_TRUE;
3058c87cf4dSdanfinn   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
3068c87cf4dSdanfinn     PetscReal *tmpx, *tmpy, *tmpz;
3079566063dSJacob 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));
308*f98b2f00SMatthew G. Knepley     PetscCall(PetscLogObjectMemory((PetscObject)sp, 3*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal)));
3099566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpx, sp->x, sp->len));
3109566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpy, sp->y, sp->len));
3119566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmpz, sp->z, sp->len));
3129566063dSJacob Faibussowitsch     PetscCall(PetscFree3(sp->x, sp->y, sp->z));
3138c87cf4dSdanfinn     sp->x    = tmpx;
3148c87cf4dSdanfinn     sp->y    = tmpy;
3158c87cf4dSdanfinn     sp->z    = tmpz;
3168c87cf4dSdanfinn     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
3178c87cf4dSdanfinn   }
318*f98b2f00SMatthew G. Knepley   for (i = 0; i < sp->dim; ++i) {
3198c87cf4dSdanfinn     if (x[i] > sp->xmax) sp->xmax = x[i];
3208c87cf4dSdanfinn     if (x[i] < sp->xmin) sp->xmin = x[i];
3218c87cf4dSdanfinn     if (y[i] > sp->ymax) sp->ymax = y[i];
3228c87cf4dSdanfinn     if (y[i] < sp->ymin) sp->ymin = y[i];
3238c87cf4dSdanfinn     if (z[i] < sp->zmin) sp->zmin = z[i];
3248c87cf4dSdanfinn     if (z[i] > sp->zmax) sp->zmax = z[i];
3258c87cf4dSdanfinn     // if (z[i] > sp->zmax && z[i] < 5.) sp->zmax = z[i];
3268c87cf4dSdanfinn 
3278c87cf4dSdanfinn     sp->x[sp->loc]   = x[i];
3288c87cf4dSdanfinn     sp->y[sp->loc]   = y[i];
3298c87cf4dSdanfinn     sp->z[sp->loc++] = z[i];
3308c87cf4dSdanfinn   }
331*f98b2f00SMatthew G. Knepley   ++sp->nopts;
3328c87cf4dSdanfinn   PetscFunctionReturn(0);
3338c87cf4dSdanfinn }
3348c87cf4dSdanfinn 
3358c87cf4dSdanfinn /*@
3365c6c1daeSBarry Smith   PetscDrawSPDraw - Redraws a scatter plot.
3375c6c1daeSBarry Smith 
3385b399a63SLisandro Dalcin   Collective on PetscDrawSP
3395c6c1daeSBarry Smith 
340d8d19677SJose E. Roman   Input Parameters:
3415c6c1daeSBarry Smith + sp - the line graph context
3425c6c1daeSBarry Smith - clear - clear the window before drawing the new plot
3435c6c1daeSBarry Smith 
3445c6c1daeSBarry Smith   Level: intermediate
3455c6c1daeSBarry Smith 
3460afdd333SBarry Smith .seealso: PetscDrawLGDraw(), PetscDrawLGSPDraw(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints()
3475c6c1daeSBarry Smith @*/
3485c6c1daeSBarry Smith PetscErrorCode PetscDrawSPDraw(PetscDrawSP sp, PetscBool clear)
3495c6c1daeSBarry Smith {
350e118a51fSLisandro Dalcin   PetscDraw      draw;
351*f98b2f00SMatthew G. Knepley   PetscBool      isnull;
352*f98b2f00SMatthew G. Knepley   PetscMPIInt    rank, size;
3535f80ce2aSJacob Faibussowitsch   PetscErrorCode ierr;
3545c6c1daeSBarry Smith 
3555c6c1daeSBarry Smith   PetscFunctionBegin;
3565c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
357*f98b2f00SMatthew G. Knepley   draw = sp->win;
358*f98b2f00SMatthew G. Knepley   PetscCall(PetscDrawIsNull(draw, &isnull));
3598f69470aSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
3609566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject) sp), &rank));
361*f98b2f00SMatthew G. Knepley   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) sp), &size));
362e118a51fSLisandro Dalcin 
3635c6c1daeSBarry Smith   if (clear) {
3649566063dSJacob Faibussowitsch     PetscCall(PetscDrawCheckResizedWindow(draw));
3659566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
3665c6c1daeSBarry Smith   }
367*f98b2f00SMatthew G. Knepley   {
368*f98b2f00SMatthew G. Knepley     PetscReal lower[2] = {sp->xmin, sp->ymin}, glower[2];
369*f98b2f00SMatthew G. Knepley     PetscReal upper[2] = {sp->xmax, sp->ymax}, gupper[2];
370*f98b2f00SMatthew G. Knepley     PetscCall(MPIU_Allreduce(lower, glower, 2, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) sp)));
371*f98b2f00SMatthew G. Knepley     PetscCall(MPIU_Allreduce(upper, gupper, 2, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject) sp)));
372*f98b2f00SMatthew G. Knepley     PetscCall(PetscDrawAxisSetLimits(sp->axis, glower[0], gupper[0], glower[1], gupper[1]));
3739566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(sp->axis));
374*f98b2f00SMatthew G. Knepley   }
3755c6c1daeSBarry Smith 
3769566063dSJacob Faibussowitsch   ierr = PetscDrawCollectiveBegin(draw);PetscCall(ierr);
377*f98b2f00SMatthew G. Knepley   {
378*f98b2f00SMatthew G. Knepley     const int dim = sp->dim, nopts = sp->nopts;
379*f98b2f00SMatthew G. Knepley 
380*f98b2f00SMatthew G. Knepley     for (int i = 0; i < dim; ++i) {
381*f98b2f00SMatthew G. Knepley       for (int p = 0; p < nopts; ++p) {
382*f98b2f00SMatthew 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);
383*f98b2f00SMatthew G. Knepley 
384*f98b2f00SMatthew G. Knepley         PetscCall(PetscDrawPoint(draw, sp->x[p*dim+i], sp->y[p*dim+i], color));
3855c6c1daeSBarry Smith       }
3865c6c1daeSBarry Smith     }
3878c87cf4dSdanfinn   }
3889566063dSJacob Faibussowitsch   ierr = PetscDrawCollectiveEnd(draw);PetscCall(ierr);
3895b399a63SLisandro Dalcin 
3909566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
3919566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
3925c6c1daeSBarry Smith   PetscFunctionReturn(0);
3935c6c1daeSBarry Smith }
3945c6c1daeSBarry Smith 
39557fd6651SLisandro Dalcin /*@
39657fd6651SLisandro Dalcin   PetscDrawSPSave - Saves a drawn image
39757fd6651SLisandro Dalcin 
39857fd6651SLisandro Dalcin   Collective on PetscDrawSP
39957fd6651SLisandro Dalcin 
40057fd6651SLisandro Dalcin   Input Parameter:
40157fd6651SLisandro Dalcin . sp - the scatter plot context
40257fd6651SLisandro Dalcin 
40357fd6651SLisandro Dalcin   Level: intermediate
40457fd6651SLisandro Dalcin 
40557fd6651SLisandro Dalcin .seealso: PetscDrawSPCreate(), PetscDrawSPGetDraw(), PetscDrawSetSave(), PetscDrawSave()
40657fd6651SLisandro Dalcin @*/
40757fd6651SLisandro Dalcin PetscErrorCode PetscDrawSPSave(PetscDrawSP sp)
40857fd6651SLisandro Dalcin {
40957fd6651SLisandro Dalcin   PetscFunctionBegin;
41057fd6651SLisandro Dalcin   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
4119566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(sp->win));
41257fd6651SLisandro Dalcin   PetscFunctionReturn(0);
41357fd6651SLisandro Dalcin }
41457fd6651SLisandro Dalcin 
4155c6c1daeSBarry Smith /*@
416*f98b2f00SMatthew 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.
4175c6c1daeSBarry Smith 
418*f98b2f00SMatthew G. Knepley   Not collective
4195c6c1daeSBarry Smith 
4205c6c1daeSBarry Smith   Input Parameters:
4215c6c1daeSBarry Smith + xsp - the line graph context
4225c6c1daeSBarry Smith - x_min,x_max,y_min,y_max - the limits
4235c6c1daeSBarry Smith 
4245c6c1daeSBarry Smith   Level: intermediate
4255c6c1daeSBarry Smith 
4260afdd333SBarry Smith .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPGetAxis()
4275c6c1daeSBarry Smith @*/
4285c6c1daeSBarry Smith PetscErrorCode PetscDrawSPSetLimits(PetscDrawSP sp, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max)
4295c6c1daeSBarry Smith {
4305c6c1daeSBarry Smith   PetscFunctionBegin;
4315c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
4325c6c1daeSBarry Smith   sp->xmin = x_min;
4335c6c1daeSBarry Smith   sp->xmax = x_max;
4345c6c1daeSBarry Smith   sp->ymin = y_min;
4355c6c1daeSBarry Smith   sp->ymax = y_max;
4365c6c1daeSBarry Smith   PetscFunctionReturn(0);
4375c6c1daeSBarry Smith }
4385c6c1daeSBarry Smith 
439*f98b2f00SMatthew G. Knepley /*@
4405c6c1daeSBarry Smith   PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
4415c6c1daeSBarry Smith 
442*f98b2f00SMatthew G. Knepley   Not Collective
4435c6c1daeSBarry Smith 
4445c6c1daeSBarry Smith   Input Parameter:
4455c6c1daeSBarry Smith . sp - the line graph context
4465c6c1daeSBarry Smith 
4475c6c1daeSBarry Smith   Output Parameter:
4485c6c1daeSBarry Smith . axis - the axis context
4495c6c1daeSBarry Smith 
450*f98b2f00SMatthew G. Knepley   Note:
451*f98b2f00SMatthew 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.
452*f98b2f00SMatthew G. Knepley 
4535c6c1daeSBarry Smith   Level: intermediate
4545c6c1daeSBarry Smith 
4550afdd333SBarry Smith .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawAxis, PetscDrawAxisCreate()
4565c6c1daeSBarry Smith @*/
4575c6c1daeSBarry Smith PetscErrorCode PetscDrawSPGetAxis(PetscDrawSP sp, PetscDrawAxis *axis)
4585c6c1daeSBarry Smith {
4595c6c1daeSBarry Smith   PetscFunctionBegin;
4605c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
46145f3bb6eSLisandro Dalcin   PetscValidPointer(axis, 2);
4625c6c1daeSBarry Smith   *axis = sp->axis;
4635c6c1daeSBarry Smith   PetscFunctionReturn(0);
4645c6c1daeSBarry Smith }
4655c6c1daeSBarry Smith 
466*f98b2f00SMatthew G. Knepley /*@
4675c6c1daeSBarry Smith   PetscDrawSPGetDraw - Gets the draw context associated with a line graph.
4685c6c1daeSBarry Smith 
469*f98b2f00SMatthew G. Knepley   Not Collective
4705c6c1daeSBarry Smith 
4715c6c1daeSBarry Smith   Input Parameter:
4725c6c1daeSBarry Smith . sp - the line graph context
4735c6c1daeSBarry Smith 
4745c6c1daeSBarry Smith   Output Parameter:
4755c6c1daeSBarry Smith . draw - the draw context
4765c6c1daeSBarry Smith 
4775c6c1daeSBarry Smith   Level: intermediate
4785c6c1daeSBarry Smith 
4790afdd333SBarry Smith .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDraw
4805c6c1daeSBarry Smith @*/
4815c6c1daeSBarry Smith PetscErrorCode PetscDrawSPGetDraw(PetscDrawSP sp, PetscDraw *draw)
4825c6c1daeSBarry Smith {
4835c6c1daeSBarry Smith   PetscFunctionBegin;
484e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(sp, PETSC_DRAWSP_CLASSID, 1);
48545f3bb6eSLisandro Dalcin   PetscValidPointer(draw, 2);
486e118a51fSLisandro Dalcin   *draw = sp->win;
4875c6c1daeSBarry Smith   PetscFunctionReturn(0);
4885c6c1daeSBarry Smith }
489