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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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; 253999739cfSJacob Faibussowitsch PetscReal coors[4], 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; 317*6497c311SBarry 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; 344*6497c311SBarry 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); 368*6497c311SBarry 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; 374*6497c311SBarry Smith 375*6497c311SBarry Smith if (axis->ylabelstr) x -= ((PetscReal)ytlen + .5) * tw; 3769566063dSJacob Faibussowitsch PetscCall(PetscStrlen(axis->ylabel, &len)); 377*6497c311SBarry 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 */ 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 */ 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 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 */ 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 */ 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 */ 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