1999739cfSJacob Faibussowitsch #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/
25c6c1daeSBarry Smith
3999739cfSJacob Faibussowitsch #define PETSC_DRAW_AXIS_MAX_SEGMENTS 20
45c6c1daeSBarry Smith PetscClassId PETSC_DRAWAXIS_CLASSID = 0;
55c6c1daeSBarry Smith
65c6c1daeSBarry Smith /*@
75c6c1daeSBarry Smith PetscDrawAxisCreate - Generate the axis data structure.
85c6c1daeSBarry Smith
9c3339decSBarry Smith Collective
105c6c1daeSBarry Smith
112fe279fdSBarry Smith Input Parameter:
1215229ffcSPierre Jolivet . draw - `PetscDraw` object where axis to be made
135c6c1daeSBarry Smith
1401d2d390SJose E. Roman Output Parameter:
155c6c1daeSBarry Smith . axis - the axis datastructure
165c6c1daeSBarry Smith
17811af0c4SBarry Smith Note:
18811af0c4SBarry Smith The MPI communicator that owns the underlying draw object owns the `PetscDrawAxis` object, but calls to set `PetscDrawAxis` options are
19811af0c4SBarry Smith ignored by all processes except the first MPI rank in the communicator
207e25d57eSBarry Smith
215c6c1daeSBarry Smith Level: advanced
225c6c1daeSBarry Smith
23db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawSPCreate()`, `PetscDrawSP`, `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawLGGetAxis()`, `PetscDrawSPGetAxis()`,
24db781477SPatrick Sanan `PetscDrawHGGetAxis()`, `PetscDrawBarGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisDestroy()`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetHoldLimits()`,
25db781477SPatrick Sanan `PetscDrawAxisDraw()`
265c6c1daeSBarry Smith @*/
PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis * axis)27d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisCreate(PetscDraw draw, PetscDrawAxis *axis)
28d71ae5a4SJacob Faibussowitsch {
29e118a51fSLisandro Dalcin PetscDrawAxis ad;
305c6c1daeSBarry Smith
315c6c1daeSBarry Smith PetscFunctionBegin;
325c6c1daeSBarry Smith PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
334f572ea9SToby Isaac PetscAssertPointer(axis, 2);
34e118a51fSLisandro Dalcin
359566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(ad, PETSC_DRAWAXIS_CLASSID, "DrawAxis", "Draw Axis", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawAxisDestroy, NULL));
369566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)draw));
37e118a51fSLisandro Dalcin ad->win = draw;
385c6c1daeSBarry Smith ad->xticks = PetscADefTicks;
395c6c1daeSBarry Smith ad->yticks = PetscADefTicks;
405c6c1daeSBarry Smith ad->xlabelstr = PetscADefLabel;
415c6c1daeSBarry Smith ad->ylabelstr = PetscADefLabel;
425c6c1daeSBarry Smith ad->ac = PETSC_DRAW_BLACK;
435c6c1daeSBarry Smith ad->tc = PETSC_DRAW_BLACK;
445c6c1daeSBarry Smith ad->cc = PETSC_DRAW_BLACK;
45e5ab1681SLisandro Dalcin ad->xlabel = NULL;
46e5ab1681SLisandro Dalcin ad->ylabel = NULL;
47e5ab1681SLisandro Dalcin ad->toplabel = NULL;
485c6c1daeSBarry Smith *axis = ad;
493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
505c6c1daeSBarry Smith }
515c6c1daeSBarry Smith
525c6c1daeSBarry Smith /*@
535c6c1daeSBarry Smith PetscDrawAxisDestroy - Frees the space used by an axis structure.
545c6c1daeSBarry Smith
55c3339decSBarry Smith Collective
565c6c1daeSBarry Smith
572fe279fdSBarry Smith Input Parameter:
585c6c1daeSBarry Smith . axis - the axis context
595c6c1daeSBarry Smith
605c6c1daeSBarry Smith Level: advanced
615c6c1daeSBarry Smith
62811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`
635c6c1daeSBarry Smith @*/
PetscDrawAxisDestroy(PetscDrawAxis * axis)64d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis)
65d71ae5a4SJacob Faibussowitsch {
665c6c1daeSBarry Smith PetscFunctionBegin;
673ba16761SJacob Faibussowitsch if (!*axis) PetscFunctionReturn(PETSC_SUCCESS);
68e118a51fSLisandro Dalcin PetscValidHeaderSpecific(*axis, PETSC_DRAWAXIS_CLASSID, 1);
69f4f49eeaSPierre Jolivet if (--((PetscObject)*axis)->refct > 0) {
709371c9d4SSatish Balay *axis = NULL;
713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
729371c9d4SSatish Balay }
735c6c1daeSBarry Smith
749566063dSJacob Faibussowitsch PetscCall(PetscFree((*axis)->toplabel));
759566063dSJacob Faibussowitsch PetscCall(PetscFree((*axis)->xlabel));
769566063dSJacob Faibussowitsch PetscCall(PetscFree((*axis)->ylabel));
779566063dSJacob Faibussowitsch PetscCall(PetscDrawDestroy(&(*axis)->win));
789566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(axis));
793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
805c6c1daeSBarry Smith }
815c6c1daeSBarry Smith
825c6c1daeSBarry Smith /*@
835c6c1daeSBarry Smith PetscDrawAxisSetColors - Sets the colors to be used for the axis,
845c6c1daeSBarry Smith tickmarks, and text.
855c6c1daeSBarry Smith
86c3339decSBarry Smith Logically Collective
875c6c1daeSBarry Smith
885c6c1daeSBarry Smith Input Parameters:
895c6c1daeSBarry Smith + axis - the axis
905c6c1daeSBarry Smith . ac - the color of the axis lines
915c6c1daeSBarry Smith . tc - the color of the tick marks
925c6c1daeSBarry Smith - cc - the color of the text strings
935c6c1daeSBarry Smith
945c6c1daeSBarry Smith Level: advanced
955c6c1daeSBarry Smith
96811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisDraw()`, `PetscDrawAxisSetLimits()`
975c6c1daeSBarry Smith @*/
PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)98d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis, int ac, int tc, int cc)
99d71ae5a4SJacob Faibussowitsch {
1005c6c1daeSBarry Smith PetscFunctionBegin;
101e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
1025b399a63SLisandro Dalcin PetscValidLogicalCollectiveInt(axis, ac, 2);
1035b399a63SLisandro Dalcin PetscValidLogicalCollectiveInt(axis, tc, 3);
1045b399a63SLisandro Dalcin PetscValidLogicalCollectiveInt(axis, cc, 4);
1059371c9d4SSatish Balay axis->ac = ac;
1069371c9d4SSatish Balay axis->tc = tc;
1079371c9d4SSatish Balay axis->cc = cc;
1083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1095c6c1daeSBarry Smith }
1105c6c1daeSBarry Smith
111cc4c1da9SBarry Smith /*@
1125c6c1daeSBarry Smith PetscDrawAxisSetLabels - Sets the x and y axis labels.
1135c6c1daeSBarry Smith
114c3339decSBarry Smith Logically Collective
1155c6c1daeSBarry Smith
1165c6c1daeSBarry Smith Input Parameters:
1175c6c1daeSBarry Smith + axis - the axis
1185c6c1daeSBarry Smith . top - the label at the top of the image
11910450e9eSJacob Faibussowitsch . xlabel - the x axis label
12010450e9eSJacob Faibussowitsch - ylabel - the y axis label
1215c6c1daeSBarry Smith
1222fe279fdSBarry Smith Level: advanced
1232fe279fdSBarry Smith
12495452b02SPatrick Sanan Notes:
125811af0c4SBarry Smith Must be called before `PetscDrawAxisDraw()` or `PetscDrawLGDraw()`
126811af0c4SBarry Smith
1275c6c1daeSBarry Smith There should be no newlines in the arguments
1285c6c1daeSBarry Smith
129811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisDraw()`, `PetscDrawAxisSetLimits()`
1305c6c1daeSBarry Smith @*/
PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])131d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis, const char top[], const char xlabel[], const char ylabel[])
132d71ae5a4SJacob Faibussowitsch {
1335c6c1daeSBarry Smith PetscFunctionBegin;
134e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
1359566063dSJacob Faibussowitsch PetscCall(PetscFree(axis->xlabel));
1369566063dSJacob Faibussowitsch PetscCall(PetscFree(axis->ylabel));
1379566063dSJacob Faibussowitsch PetscCall(PetscFree(axis->toplabel));
1389566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(xlabel, &axis->xlabel));
1399566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ylabel, &axis->ylabel));
1409566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(top, &axis->toplabel));
1413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1425c6c1daeSBarry Smith }
1435c6c1daeSBarry Smith
14471917b75SLisandro Dalcin /*@
14571917b75SLisandro Dalcin PetscDrawAxisSetLimits - Sets the limits (in user coords) of the axis
14671917b75SLisandro Dalcin
147c3339decSBarry Smith Logically Collective
14871917b75SLisandro Dalcin
14971917b75SLisandro Dalcin Input Parameters:
15071917b75SLisandro Dalcin + axis - the axis
15110450e9eSJacob Faibussowitsch . xmin - the lower x limit
15210450e9eSJacob Faibussowitsch . xmax - the upper x limit
15310450e9eSJacob Faibussowitsch . ymin - the lower y limit
15410450e9eSJacob Faibussowitsch - ymax - the upper y limit
15571917b75SLisandro Dalcin
156811af0c4SBarry Smith Options Database Key:
15771917b75SLisandro Dalcin . -drawaxis_hold - hold the initial set of axis limits for future plotting
15871917b75SLisandro Dalcin
15971917b75SLisandro Dalcin Level: advanced
16071917b75SLisandro Dalcin
161db781477SPatrick Sanan .seealso: `PetscDrawAxisSetHoldLimits()`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
16271917b75SLisandro Dalcin @*/
PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetLimits(PetscDrawAxis axis, PetscReal xmin, PetscReal xmax, PetscReal ymin, PetscReal ymax)
164d71ae5a4SJacob Faibussowitsch {
16571917b75SLisandro Dalcin PetscFunctionBegin;
16671917b75SLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
1673ba16761SJacob Faibussowitsch if (axis->hold) PetscFunctionReturn(PETSC_SUCCESS);
16871917b75SLisandro Dalcin axis->xlow = xmin;
16971917b75SLisandro Dalcin axis->xhigh = xmax;
17071917b75SLisandro Dalcin axis->ylow = ymin;
17171917b75SLisandro Dalcin axis->yhigh = ymax;
1729566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)axis)->options, ((PetscObject)axis)->prefix, "-drawaxis_hold", &axis->hold));
1733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17471917b75SLisandro Dalcin }
17571917b75SLisandro Dalcin
17671917b75SLisandro Dalcin /*@
17771917b75SLisandro Dalcin PetscDrawAxisGetLimits - Gets the limits (in user coords) of the axis
17871917b75SLisandro Dalcin
17971917b75SLisandro Dalcin Not Collective
18071917b75SLisandro Dalcin
18171917b75SLisandro Dalcin Input Parameters:
18271917b75SLisandro Dalcin + axis - the axis
18310450e9eSJacob Faibussowitsch . xmin - the lower x limit
18410450e9eSJacob Faibussowitsch . xmax - the upper x limit
18510450e9eSJacob Faibussowitsch . ymin - the lower y limit
18610450e9eSJacob Faibussowitsch - ymax - the upper y limit
18771917b75SLisandro Dalcin
18871917b75SLisandro Dalcin Level: advanced
18971917b75SLisandro Dalcin
190db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetHoldLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
19171917b75SLisandro Dalcin @*/
PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal * xmin,PetscReal * xmax,PetscReal * ymin,PetscReal * ymax)192d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisGetLimits(PetscDrawAxis axis, PetscReal *xmin, PetscReal *xmax, PetscReal *ymin, PetscReal *ymax)
193d71ae5a4SJacob Faibussowitsch {
19471917b75SLisandro Dalcin PetscFunctionBegin;
19571917b75SLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
196bb046f40SHong Zhang if (xmin) *xmin = axis->xlow;
197bb046f40SHong Zhang if (xmax) *xmax = axis->xhigh;
198bb046f40SHong Zhang if (ymin) *ymin = axis->ylow;
199bb046f40SHong Zhang if (ymax) *ymax = axis->yhigh;
2003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
20171917b75SLisandro Dalcin }
20271917b75SLisandro Dalcin
2035c6c1daeSBarry Smith /*@
2045c6c1daeSBarry Smith PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called
2055c6c1daeSBarry Smith again
2065c6c1daeSBarry Smith
207c3339decSBarry Smith Logically Collective
2085c6c1daeSBarry Smith
2095c6c1daeSBarry Smith Input Parameters:
2105c6c1daeSBarry Smith + axis - the axis
211811af0c4SBarry Smith - hold - `PETSC_TRUE` - hold current limits, `PETSC_FALSE` allow limits to be changed
2125c6c1daeSBarry Smith
2135c6c1daeSBarry Smith Level: advanced
2145c6c1daeSBarry Smith
215811af0c4SBarry Smith Note:
216811af0c4SBarry Smith Once this has been called with `PETSC_TRUE` the limits will not change if you call
217811af0c4SBarry Smith `PetscDrawAxisSetLimits()` until you call this with `PETSC_FALSE`
2185c6c1daeSBarry Smith
219db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
2205c6c1daeSBarry Smith @*/
PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis, PetscBool hold)
222d71ae5a4SJacob Faibussowitsch {
2235c6c1daeSBarry Smith PetscFunctionBegin;
224e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
2255b399a63SLisandro Dalcin PetscValidLogicalCollectiveBool(axis, hold, 2);
2265c6c1daeSBarry Smith axis->hold = hold;
2273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2285c6c1daeSBarry Smith }
2295c6c1daeSBarry Smith
2305c6c1daeSBarry Smith /*@
231811af0c4SBarry Smith PetscDrawAxisDraw - draws an axis.
2325c6c1daeSBarry Smith
233c3339decSBarry Smith Collective
2345c6c1daeSBarry Smith
2355c6c1daeSBarry Smith Input Parameter:
236811af0c4SBarry Smith . axis - `PetscDrawAxis` structure
2375c6c1daeSBarry Smith
2385c6c1daeSBarry Smith Level: advanced
2395c6c1daeSBarry Smith
2405c6c1daeSBarry Smith Note:
2415c6c1daeSBarry Smith This draws the actual axis. The limits etc have already been set.
2425c6c1daeSBarry Smith By picking special routines for the ticks and labels, special
2435c6c1daeSBarry Smith effects may be generated. These routines are part of the Axis
2445c6c1daeSBarry Smith structure (axis).
2450afdd333SBarry Smith
246db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
2475c6c1daeSBarry Smith @*/
PetscDrawAxisDraw(PetscDrawAxis axis)248d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis)
249d71ae5a4SJacob Faibussowitsch {
250e118a51fSLisandro Dalcin int i, ntick, numx, numy, ac, tc, cc;
251e118a51fSLisandro Dalcin PetscMPIInt rank;
25271917b75SLisandro Dalcin size_t len, ytlen = 0;
253*dd460d27SBarry Smith PetscReal coors[4] = {0, 0, 0, 0}, tickloc[PETSC_DRAW_AXIS_MAX_SEGMENTS], sep, tw, th;
25471917b75SLisandro Dalcin PetscReal xl, xr, yl, yr, dxl = 0, dyl = 0, dxr = 0, dyr = 0;
2555c6c1daeSBarry Smith char *p;
256e118a51fSLisandro Dalcin PetscDraw draw;
257e118a51fSLisandro Dalcin PetscBool isnull;
2585c6c1daeSBarry Smith
2595c6c1daeSBarry Smith PetscFunctionBegin;
260e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
2619566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(axis->win, &isnull));
2623ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
2639566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)axis), &rank));
2645c6c1daeSBarry Smith
2658f69470aSLisandro Dalcin draw = axis->win;
2665b399a63SLisandro Dalcin
2679371c9d4SSatish Balay ac = axis->ac;
2689371c9d4SSatish Balay tc = axis->tc;
2699371c9d4SSatish Balay cc = axis->cc;
2709371c9d4SSatish Balay if (axis->xlow == axis->xhigh) {
2719371c9d4SSatish Balay axis->xlow -= .5;
2729371c9d4SSatish Balay axis->xhigh += .5;
2739371c9d4SSatish Balay }
2749371c9d4SSatish Balay if (axis->ylow == axis->yhigh) {
2759371c9d4SSatish Balay axis->ylow -= .5;
2769371c9d4SSatish Balay axis->yhigh += .5;
2779371c9d4SSatish Balay }
278e118a51fSLisandro Dalcin
279d0609cedSBarry Smith PetscDrawCollectiveBegin(draw);
28071917b75SLisandro Dalcin if (rank) goto finally;
28171917b75SLisandro Dalcin
282da81f932SPierre Jolivet /* get canonical string size */
2839566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, 0, 0, 1, 1));
2849566063dSJacob Faibussowitsch PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
28571917b75SLisandro Dalcin /* lower spacing */
28671917b75SLisandro Dalcin if (axis->xlabelstr) dyl += 1.5 * th;
28771917b75SLisandro Dalcin if (axis->xlabel) dyl += 1.5 * th;
28871917b75SLisandro Dalcin /* left spacing */
28971917b75SLisandro Dalcin if (axis->ylabelstr) dxl += 7.5 * tw;
29071917b75SLisandro Dalcin if (axis->ylabel) dxl += 2.0 * tw;
29171917b75SLisandro Dalcin /* right and top spacing */
29271917b75SLisandro Dalcin if (axis->xlabelstr) dxr = 2.5 * tw;
29371917b75SLisandro Dalcin if (axis->ylabelstr) dyr = 0.5 * th;
29471917b75SLisandro Dalcin if (axis->toplabel) dyr = 1.5 * th;
29571917b75SLisandro Dalcin /* extra spacing */
2969371c9d4SSatish Balay dxl += 0.7 * tw;
2979371c9d4SSatish Balay dxr += 0.5 * tw;
2989371c9d4SSatish Balay dyl += 0.2 * th;
2999371c9d4SSatish Balay dyr += 0.2 * th;
30071917b75SLisandro Dalcin /* determine coordinates */
30171917b75SLisandro Dalcin xl = (dxl * axis->xhigh + dxr * axis->xlow - axis->xlow) / (dxl + dxr - 1);
30271917b75SLisandro Dalcin xr = (dxl * axis->xhigh + dxr * axis->xlow - axis->xhigh) / (dxl + dxr - 1);
30371917b75SLisandro Dalcin yl = (dyl * axis->yhigh + dyr * axis->ylow - axis->ylow) / (dyl + dyr - 1);
30471917b75SLisandro Dalcin yr = (dyl * axis->yhigh + dyr * axis->ylow - axis->yhigh) / (dyl + dyr - 1);
3059566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
3069566063dSJacob Faibussowitsch PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
3075c6c1daeSBarry Smith
30871917b75SLisandro Dalcin /* PetscDraw the axis lines */
3099566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, axis->ylow, axis->xhigh, axis->ylow, ac));
3109566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, axis->ylow, axis->xlow, axis->yhigh, ac));
3119566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, axis->yhigh, axis->xhigh, axis->yhigh, ac));
3129566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xhigh, axis->ylow, axis->xhigh, axis->yhigh, ac));
3135c6c1daeSBarry Smith
31471917b75SLisandro Dalcin /* PetscDraw the top label */
3155c6c1daeSBarry Smith if (axis->toplabel) {
31671917b75SLisandro Dalcin PetscReal x = (axis->xlow + axis->xhigh) / 2, y = axis->yhigh + 0.5 * th;
3176497c311SBarry Smith
3189566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, x, y, cc, axis->toplabel));
3195c6c1daeSBarry Smith }
3205c6c1daeSBarry Smith
32171917b75SLisandro Dalcin /* PetscDraw the X ticks and labels */
3225c6c1daeSBarry Smith if (axis->xticks) {
3239371c9d4SSatish Balay numx = (int)(.15 * (axis->xhigh - axis->xlow) / tw);
3249371c9d4SSatish Balay numx = PetscClipInterval(numx, 2, 6);
3259566063dSJacob Faibussowitsch PetscCall((*axis->xticks)(axis->xlow, axis->xhigh, numx, &ntick, tickloc, PETSC_DRAW_AXIS_MAX_SEGMENTS));
3265c6c1daeSBarry Smith /* PetscDraw in tick marks */
3275c6c1daeSBarry Smith for (i = 0; i < ntick; i++) {
3289566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, tickloc[i], axis->ylow, tickloc[i], axis->ylow + .5 * th, tc));
3299566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, tickloc[i], axis->yhigh, tickloc[i], axis->yhigh - .5 * th, tc));
3305c6c1daeSBarry Smith }
3315c6c1daeSBarry Smith /* label ticks */
3325c6c1daeSBarry Smith if (axis->xlabelstr) {
33371917b75SLisandro Dalcin for (i = 0; i < ntick; i++) {
3345c6c1daeSBarry Smith if (i < ntick - 1) sep = tickloc[i + 1] - tickloc[i];
3355c6c1daeSBarry Smith else if (i > 0) sep = tickloc[i] - tickloc[i - 1];
3365c6c1daeSBarry Smith else sep = 0.0;
3379566063dSJacob Faibussowitsch PetscCall((*axis->xlabelstr)(tickloc[i], sep, &p));
3389566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, tickloc[i], axis->ylow - 1.5 * th, cc, p));
3395c6c1daeSBarry Smith }
3405c6c1daeSBarry Smith }
3415c6c1daeSBarry Smith }
3425c6c1daeSBarry Smith if (axis->xlabel) {
34371917b75SLisandro Dalcin PetscReal x = (axis->xlow + axis->xhigh) / 2, y = axis->ylow - 1.5 * th;
3446497c311SBarry Smith
34571917b75SLisandro Dalcin if (axis->xlabelstr) y -= 1.5 * th;
3469566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, x, y, cc, axis->xlabel));
3475c6c1daeSBarry Smith }
34871917b75SLisandro Dalcin
34971917b75SLisandro Dalcin /* PetscDraw the Y ticks and labels */
3505c6c1daeSBarry Smith if (axis->yticks) {
3519371c9d4SSatish Balay numy = (int)(.50 * (axis->yhigh - axis->ylow) / th);
3529371c9d4SSatish Balay numy = PetscClipInterval(numy, 2, 6);
3539566063dSJacob Faibussowitsch PetscCall((*axis->yticks)(axis->ylow, axis->yhigh, numy, &ntick, tickloc, PETSC_DRAW_AXIS_MAX_SEGMENTS));
3545c6c1daeSBarry Smith /* PetscDraw in tick marks */
3555c6c1daeSBarry Smith for (i = 0; i < ntick; i++) {
3569566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, tickloc[i], axis->xlow + .5 * tw, tickloc[i], tc));
3579566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xhigh, tickloc[i], axis->xhigh - .5 * tw, tickloc[i], tc));
3585c6c1daeSBarry Smith }
3595c6c1daeSBarry Smith /* label ticks */
3605c6c1daeSBarry Smith if (axis->ylabelstr) {
36171917b75SLisandro Dalcin for (i = 0; i < ntick; i++) {
3625c6c1daeSBarry Smith if (i < ntick - 1) sep = tickloc[i + 1] - tickloc[i];
3635c6c1daeSBarry Smith else if (i > 0) sep = tickloc[i] - tickloc[i - 1];
3645c6c1daeSBarry Smith else sep = 0.0;
3659566063dSJacob Faibussowitsch PetscCall((*axis->ylabelstr)(tickloc[i], sep, &p));
3669371c9d4SSatish Balay PetscCall(PetscStrlen(p, &len));
3679371c9d4SSatish Balay ytlen = PetscMax(ytlen, len);
3686497c311SBarry Smith PetscCall(PetscDrawString(draw, axis->xlow - ((PetscReal)len + .5) * tw, tickloc[i] - .5 * th, cc, p));
3695c6c1daeSBarry Smith }
3705c6c1daeSBarry Smith }
3715c6c1daeSBarry Smith }
3725c6c1daeSBarry Smith if (axis->ylabel) {
37371917b75SLisandro Dalcin PetscReal x = axis->xlow - 2.0 * tw, y = (axis->ylow + axis->yhigh) / 2;
3746497c311SBarry Smith
3756497c311SBarry Smith if (axis->ylabelstr) x -= ((PetscReal)ytlen + .5) * tw;
3769566063dSJacob Faibussowitsch PetscCall(PetscStrlen(axis->ylabel, &len));
3776497c311SBarry Smith PetscCall(PetscDrawStringVertical(draw, x, y + ((PetscReal)len) * th / 2, cc, axis->ylabel));
3785c6c1daeSBarry Smith }
3795b399a63SLisandro Dalcin
3809566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &coors[0], &coors[1], &coors[2], &coors[3]));
3815b399a63SLisandro Dalcin finally:
382d0609cedSBarry Smith PetscDrawCollectiveEnd(draw);
3839566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(coors, 4, MPIU_REAL, 0, PetscObjectComm((PetscObject)draw)));
3849566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, coors[0], coors[1], coors[2], coors[3]));
3853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3865c6c1daeSBarry Smith }
3875c6c1daeSBarry Smith
38836c9bc0dSBarry Smith /*
38936c9bc0dSBarry Smith Removes all zeros but one from .0000
39036c9bc0dSBarry Smith */
PetscStripe0(char * buf)391d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripe0(char *buf)
392d71ae5a4SJacob Faibussowitsch {
39336c9bc0dSBarry Smith size_t n;
39436c9bc0dSBarry Smith PetscBool flg;
395bbcf679cSJacob Faibussowitsch char *str = NULL;
39636c9bc0dSBarry Smith
39736c9bc0dSBarry Smith PetscFunctionBegin;
3989566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n));
3999566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(buf, "e00", &flg));
400a297a907SKarl Rupp if (flg) buf[n - 3] = 0;
4019566063dSJacob Faibussowitsch PetscCall(PetscStrstr(buf, "e0", &str));
40236c9bc0dSBarry Smith if (str) {
40336c9bc0dSBarry Smith buf[n - 2] = buf[n - 1];
40436c9bc0dSBarry Smith buf[n - 1] = 0;
40536c9bc0dSBarry Smith }
4069566063dSJacob Faibussowitsch PetscCall(PetscStrstr(buf, "e-0", &str));
40736c9bc0dSBarry Smith if (str) {
40836c9bc0dSBarry Smith buf[n - 2] = buf[n - 1];
40936c9bc0dSBarry Smith buf[n - 1] = 0;
41036c9bc0dSBarry Smith }
4113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
41236c9bc0dSBarry Smith }
41336c9bc0dSBarry Smith
4145c6c1daeSBarry Smith /*
4155c6c1daeSBarry Smith Removes all zeros but one from .0000
4165c6c1daeSBarry Smith */
PetscStripAllZeros(char * buf)417d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripAllZeros(char *buf)
418d71ae5a4SJacob Faibussowitsch {
4195c6c1daeSBarry Smith size_t i, n;
4205c6c1daeSBarry Smith
4215c6c1daeSBarry Smith PetscFunctionBegin;
4229566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n));
4233ba16761SJacob Faibussowitsch if (buf[0] != '.') PetscFunctionReturn(PETSC_SUCCESS);
4245c6c1daeSBarry Smith for (i = 1; i < n; i++) {
4253ba16761SJacob Faibussowitsch if (buf[i] != '0') PetscFunctionReturn(PETSC_SUCCESS);
4265c6c1daeSBarry Smith }
4275c6c1daeSBarry Smith buf[0] = '0';
4285c6c1daeSBarry Smith buf[1] = 0;
4293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4305c6c1daeSBarry Smith }
4315c6c1daeSBarry Smith
4325c6c1daeSBarry Smith /*
4335c6c1daeSBarry Smith Removes trailing zeros
4345c6c1daeSBarry Smith */
4354279555eSSatish Balay #if (PETSC_SIZEOF_SIZE_T == 8)
4364279555eSSatish Balay #define MAX_SIZE_T PETSC_INT64_MAX
4374279555eSSatish Balay #else
4384279555eSSatish Balay #define MAX_SIZE_T INT_MAX
4394279555eSSatish Balay #endif
PetscStripTrailingZeros(char * buf)440d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripTrailingZeros(char *buf)
441d71ae5a4SJacob Faibussowitsch {
442bbcf679cSJacob Faibussowitsch char *found = NULL;
4434279555eSSatish Balay size_t i, n, m = MAX_SIZE_T;
4445c6c1daeSBarry Smith
4455c6c1daeSBarry Smith PetscFunctionBegin;
4465c6c1daeSBarry Smith /* if there is an e in string DO NOT strip trailing zeros */
4479566063dSJacob Faibussowitsch PetscCall(PetscStrchr(buf, 'e', &found));
4483ba16761SJacob Faibussowitsch if (found) PetscFunctionReturn(PETSC_SUCCESS);
4495c6c1daeSBarry Smith
4509566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n));
4515c6c1daeSBarry Smith /* locate decimal point */
4525c6c1daeSBarry Smith for (i = 0; i < n; i++) {
4539371c9d4SSatish Balay if (buf[i] == '.') {
4549371c9d4SSatish Balay m = i;
4559371c9d4SSatish Balay break;
4569371c9d4SSatish Balay }
4575c6c1daeSBarry Smith }
4585c6c1daeSBarry Smith /* if not decimal point then no zeros to remove */
4594279555eSSatish Balay if (m == MAX_SIZE_T) PetscFunctionReturn(PETSC_SUCCESS);
4605c6c1daeSBarry Smith /* start at right end of string removing 0s */
4615c6c1daeSBarry Smith for (i = n - 1; i > m; i++) {
4623ba16761SJacob Faibussowitsch if (buf[i] != '0') PetscFunctionReturn(PETSC_SUCCESS);
4635c6c1daeSBarry Smith buf[i] = 0;
4645c6c1daeSBarry Smith }
4653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4665c6c1daeSBarry Smith }
4675c6c1daeSBarry Smith
4685c6c1daeSBarry Smith /*
4695c6c1daeSBarry Smith Removes leading 0 from 0.22 or -0.22
4705c6c1daeSBarry Smith */
PetscStripInitialZero(char * buf)471d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripInitialZero(char *buf)
472d71ae5a4SJacob Faibussowitsch {
4735c6c1daeSBarry Smith size_t i, n;
4745c6c1daeSBarry Smith
4755c6c1daeSBarry Smith PetscFunctionBegin;
4769566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n));
4775c6c1daeSBarry Smith if (buf[0] == '0') {
478a297a907SKarl Rupp for (i = 0; i < n; i++) buf[i] = buf[i + 1];
4795c6c1daeSBarry Smith } else if (buf[0] == '-' && buf[1] == '0') {
480a297a907SKarl Rupp for (i = 1; i < n; i++) buf[i] = buf[i + 1];
4815c6c1daeSBarry Smith }
4823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4835c6c1daeSBarry Smith }
4845c6c1daeSBarry Smith
4855c6c1daeSBarry Smith /*
4865c6c1daeSBarry Smith Removes the extraneous zeros in numbers like 1.10000e6
4875c6c1daeSBarry Smith */
PetscStripZeros(char * buf)488d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripZeros(char *buf)
489d71ae5a4SJacob Faibussowitsch {
4905c6c1daeSBarry Smith size_t i, j, n;
4915c6c1daeSBarry Smith
4925c6c1daeSBarry Smith PetscFunctionBegin;
4939566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n));
4943ba16761SJacob Faibussowitsch if (n < 5) PetscFunctionReturn(PETSC_SUCCESS);
4955c6c1daeSBarry Smith for (i = 1; i < n - 1; i++) {
4965c6c1daeSBarry Smith if (buf[i] == 'e' && buf[i - 1] == '0') {
4975c6c1daeSBarry Smith for (j = i; j < n + 1; j++) buf[j - 1] = buf[j];
4989566063dSJacob Faibussowitsch PetscCall(PetscStripZeros(buf));
4993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5005c6c1daeSBarry Smith }
5015c6c1daeSBarry Smith }
5023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5035c6c1daeSBarry Smith }
5045c6c1daeSBarry Smith
5055c6c1daeSBarry Smith /*
5065c6c1daeSBarry Smith Removes the plus in something like 1.1e+2 or 1.1e+02
5075c6c1daeSBarry Smith */
PetscStripZerosPlus(char * buf)508d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripZerosPlus(char *buf)
509d71ae5a4SJacob Faibussowitsch {
5105c6c1daeSBarry Smith size_t i, j, n;
5115c6c1daeSBarry Smith
5125c6c1daeSBarry Smith PetscFunctionBegin;
5139566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n));
5143ba16761SJacob Faibussowitsch if (n < 5) PetscFunctionReturn(PETSC_SUCCESS);
5155c6c1daeSBarry Smith for (i = 1; i < n - 2; i++) {
5165c6c1daeSBarry Smith if (buf[i] == '+') {
5175c6c1daeSBarry Smith if (buf[i + 1] == '0') {
5185c6c1daeSBarry Smith for (j = i + 1; j < n; j++) buf[j - 1] = buf[j + 1];
5193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5205c6c1daeSBarry Smith } else {
5215c6c1daeSBarry Smith for (j = i + 1; j < n + 1; j++) buf[j - 1] = buf[j];
5223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5235c6c1daeSBarry Smith }
5245c6c1daeSBarry Smith } else if (buf[i] == '-') {
5255c6c1daeSBarry Smith if (buf[i + 1] == '0') {
5265c6c1daeSBarry Smith for (j = i + 1; j < n; j++) buf[j] = buf[j + 1];
5273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5285c6c1daeSBarry Smith }
5295c6c1daeSBarry Smith }
5305c6c1daeSBarry Smith }
5313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5325c6c1daeSBarry Smith }
533