1 #include <../src/sys/classes/draw/utils/axisimpl.h>  /*I   "petscdraw.h"  I*/
2 
3 PetscClassId PETSC_DRAWAXIS_CLASSID = 0;
4 
5 /*@
6    PetscDrawAxisCreate - Generate the axis data structure.
7 
8    Collective on PetscDraw
9 
10    Input Parameters:
11 .  win - PetscDraw object where axis to to be made
12 
13    Ouput Parameters:
14 .  axis - the axis datastructure
15 
16    Notes:
17     the MPI communicator that owns the underlying draw object owns the PetscDrawAxis object, but calls to set PetscDrawAxis options are ignored by all processes
18           except the first MPI process in the communicator
19 
20    Level: advanced
21 
22 .seealso: PetscDrawLGCreate(), PetscDrawLG, PetscDrawSPCreate(), PetscDrawSP, PetscDrawHGCreate(), PetscDrawHG, PetscDrawBarCreate(), PetscDrawBar, PetscDrawLGGetAxis(), PetscDrawSPGetAxis(),
23           PetscDrawHGGetAxis(), PetscDrawBarGetAxis(), PetscDrawAxis, PetscDrawAxisDestroy(), PetscDrawAxisSetColors(), PetscDrawAxisSetLabels(), PetscDrawAxisSetLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetHoldLimits(),
24           PetscDrawAxisDraw()
25 @*/
PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis * axis)26 PetscErrorCode  PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis *axis)
27 {
28   PetscDrawAxis  ad;
29   PetscErrorCode ierr;
30 
31   PetscFunctionBegin;
32   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
33   PetscValidPointer(axis,2);
34 
35   ierr = PetscHeaderCreate(ad,PETSC_DRAWAXIS_CLASSID,"DrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)draw),PetscDrawAxisDestroy,NULL);CHKERRQ(ierr);
36   ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)ad);CHKERRQ(ierr);
37 
38   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
39   ad->win = draw;
40 
41   ad->xticks    = PetscADefTicks;
42   ad->yticks    = PetscADefTicks;
43   ad->xlabelstr = PetscADefLabel;
44   ad->ylabelstr = PetscADefLabel;
45   ad->ac        = PETSC_DRAW_BLACK;
46   ad->tc        = PETSC_DRAW_BLACK;
47   ad->cc        = PETSC_DRAW_BLACK;
48   ad->xlabel    = NULL;
49   ad->ylabel    = NULL;
50   ad->toplabel  = NULL;
51 
52   *axis = ad;
53   PetscFunctionReturn(0);
54 }
55 
56 /*@
57     PetscDrawAxisDestroy - Frees the space used by an axis structure.
58 
59     Collective on PetscDrawAxis
60 
61     Input Parameters:
62 .   axis - the axis context
63 
64     Level: advanced
65 
66 .seealso: PetscDrawAxisCreate(), PetscDrawAxis
67 @*/
PetscDrawAxisDestroy(PetscDrawAxis * axis)68 PetscErrorCode  PetscDrawAxisDestroy(PetscDrawAxis *axis)
69 {
70   PetscErrorCode ierr;
71 
72   PetscFunctionBegin;
73   if (!*axis) PetscFunctionReturn(0);
74   PetscValidHeaderSpecific(*axis,PETSC_DRAWAXIS_CLASSID,1);
75   if (--((PetscObject)(*axis))->refct > 0) {*axis = NULL; PetscFunctionReturn(0);}
76 
77   ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr);
78   ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr);
79   ierr = PetscFree((*axis)->ylabel);CHKERRQ(ierr);
80   ierr = PetscDrawDestroy(&(*axis)->win);CHKERRQ(ierr);
81   ierr = PetscHeaderDestroy(axis);CHKERRQ(ierr);
82   PetscFunctionReturn(0);
83 }
84 
85 /*@
86     PetscDrawAxisSetColors -  Sets the colors to be used for the axis,
87                          tickmarks, and text.
88 
89     Logically Collective on PetscDrawAxis
90 
91     Input Parameters:
92 +   axis - the axis
93 .   ac - the color of the axis lines
94 .   tc - the color of the tick marks
95 -   cc - the color of the text strings
96 
97     Level: advanced
98 
99 .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetLabels(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
100 @*/
PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)101 PetscErrorCode  PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
102 {
103   PetscFunctionBegin;
104   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
105   PetscValidLogicalCollectiveInt(axis,ac,2);
106   PetscValidLogicalCollectiveInt(axis,tc,3);
107   PetscValidLogicalCollectiveInt(axis,cc,4);
108   axis->ac = ac; axis->tc = tc; axis->cc = cc;
109   PetscFunctionReturn(0);
110 }
111 
112 /*@C
113     PetscDrawAxisSetLabels -  Sets the x and y axis labels.
114 
115     Logically Collective on PetscDrawAxis
116 
117     Input Parameters:
118 +   axis - the axis
119 .   top - the label at the top of the image
120 -   xlabel,ylabel - the labes for the x and y axis
121 
122     Notes:
123     Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
124            There should be no newlines in the arguments
125 
126     Level: advanced
127 
128 .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetColors(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
129 @*/
PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])130 PetscErrorCode  PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
131 {
132   PetscErrorCode ierr;
133 
134   PetscFunctionBegin;
135   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
136   ierr = PetscFree(axis->xlabel);CHKERRQ(ierr);
137   ierr = PetscFree(axis->ylabel);CHKERRQ(ierr);
138   ierr = PetscFree(axis->toplabel);CHKERRQ(ierr);
139   ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr);
140   ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr);
141   ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr);
142   PetscFunctionReturn(0);
143 }
144 
145 /*@
146     PetscDrawAxisSetLimits -  Sets the limits (in user coords) of the axis
147 
148     Logically Collective on PetscDrawAxis
149 
150     Input Parameters:
151 +   axis - the axis
152 .   xmin,xmax - limits in x
153 -   ymin,ymax - limits in y
154 
155     Options Database:
156 .   -drawaxis_hold - hold the initial set of axis limits for future plotting
157 
158     Level: advanced
159 
160 .seealso:  PetscDrawAxisSetHoldLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
161 
162 @*/
PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)163 PetscErrorCode  PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)
164 {
165   PetscErrorCode ierr;
166 
167   PetscFunctionBegin;
168   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
169   if (axis->hold) PetscFunctionReturn(0);
170   axis->xlow = xmin;
171   axis->xhigh= xmax;
172   axis->ylow = ymin;
173   axis->yhigh= ymax;
174   ierr = PetscOptionsHasName(((PetscObject)axis)->options,((PetscObject)axis)->prefix,"-drawaxis_hold",&axis->hold);CHKERRQ(ierr);
175   PetscFunctionReturn(0);
176 }
177 
178 /*@
179     PetscDrawAxisGetLimits -  Gets the limits (in user coords) of the axis
180 
181     Not Collective
182 
183     Input Parameters:
184 +   axis - the axis
185 .   xmin,xmax - limits in x
186 -   ymin,ymax - limits in y
187 
188     Level: advanced
189 
190 .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetHoldLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
191 
192 @*/
PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal * xmin,PetscReal * xmax,PetscReal * ymin,PetscReal * ymax)193 PetscErrorCode  PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax)
194 {
195   PetscFunctionBegin;
196   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
197   if (xmin) *xmin = axis->xlow;
198   if (xmax) *xmax = axis->xhigh;
199   if (ymin) *ymin = axis->ylow;
200   if (ymax) *ymax = axis->yhigh;
201   PetscFunctionReturn(0);
202 }
203 
204 /*@
205     PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
206         again
207 
208     Logically Collective on PetscDrawAxis
209 
210     Input Parameters:
211 +   axis - the axis
212 -   hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
213 
214     Level: advanced
215 
216     Notes:
217         Once this has been called with PETSC_TRUE the limits will not change if you call
218      PetscDrawAxisSetLimits() until you call this with PETSC_FALSE
219 
220 .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
221 
222 @*/
PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)223 PetscErrorCode  PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
224 {
225   PetscFunctionBegin;
226   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
227   PetscValidLogicalCollectiveBool(axis,hold,2);
228   axis->hold = hold;
229   PetscFunctionReturn(0);
230 }
231 
232 /*@
233     PetscDrawAxisDraw - PetscDraws an axis.
234 
235     Collective on PetscDrawAxis
236 
237     Input Parameter:
238 .   axis - Axis structure
239 
240     Level: advanced
241 
242     Note:
243     This draws the actual axis.  The limits etc have already been set.
244     By picking special routines for the ticks and labels, special
245     effects may be generated.  These routines are part of the Axis
246     structure (axis).
247 
248 .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
249 
250 @*/
PetscDrawAxisDraw(PetscDrawAxis axis)251 PetscErrorCode  PetscDrawAxisDraw(PetscDrawAxis axis)
252 {
253   int            i,ntick,numx,numy,ac,tc,cc;
254   PetscMPIInt    rank;
255   size_t         len,ytlen=0;
256   PetscReal      coors[4],tickloc[MAXSEGS],sep,tw,th;
257   PetscReal      xl,xr,yl,yr,dxl=0,dyl=0,dxr=0,dyr=0;
258   char           *p;
259   PetscDraw      draw;
260   PetscBool      isnull;
261   PetscErrorCode ierr;
262 
263   PetscFunctionBegin;
264   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
265   ierr = PetscDrawIsNull(axis->win,&isnull);CHKERRQ(ierr);
266   if (isnull) PetscFunctionReturn(0);
267   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);CHKERRQ(ierr);
268 
269   draw = axis->win;
270 
271   ac = axis->ac; tc = axis->tc; cc = axis->cc;
272   if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
273   if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}
274 
275   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
276   if (rank) goto finally;
277 
278   /* get cannonical string size */
279   ierr = PetscDrawSetCoordinates(draw,0,0,1,1);CHKERRQ(ierr);
280   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
281   /* lower spacing */
282   if (axis->xlabelstr) dyl += 1.5*th;
283   if (axis->xlabel)    dyl += 1.5*th;
284   /* left spacing */
285   if (axis->ylabelstr) dxl += 7.5*tw;
286   if (axis->ylabel)    dxl += 2.0*tw;
287   /* right and top spacing */
288   if (axis->xlabelstr) dxr = 2.5*tw;
289   if (axis->ylabelstr) dyr = 0.5*th;
290   if (axis->toplabel)  dyr = 1.5*th;
291   /* extra spacing */
292   dxl += 0.7*tw; dxr += 0.5*tw;
293   dyl += 0.2*th; dyr += 0.2*th;
294   /* determine coordinates */
295   xl = (dxl*axis->xhigh + dxr*axis->xlow - axis->xlow)  / (dxl + dxr - 1);
296   xr = (dxl*axis->xhigh + dxr*axis->xlow - axis->xhigh) / (dxl + dxr - 1);
297   yl = (dyl*axis->yhigh + dyr*axis->ylow - axis->ylow)  / (dyl + dyr - 1);
298   yr = (dyl*axis->yhigh + dyr*axis->ylow - axis->yhigh) / (dyl + dyr - 1);
299   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
300   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
301 
302   /* PetscDraw the axis lines */
303   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr);
304   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr);
305   ierr = PetscDrawLine(draw,axis->xlow,axis->yhigh,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr);
306   ierr = PetscDrawLine(draw,axis->xhigh,axis->ylow,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr);
307 
308   /* PetscDraw the top label */
309   if (axis->toplabel) {
310     PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->yhigh + 0.5*th;
311     ierr = PetscDrawStringCentered(draw,x,y,cc,axis->toplabel);CHKERRQ(ierr);
312   }
313 
314   /* PetscDraw the X ticks and labels */
315   if (axis->xticks) {
316     numx = (int)(.15*(axis->xhigh-axis->xlow)/tw); numx = PetscClipInterval(numx,2,6);
317     ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
318     /* PetscDraw in tick marks */
319     for (i=0; i<ntick; i++) {
320       ierr = PetscDrawLine(draw,tickloc[i],axis->ylow,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr);
321       ierr = PetscDrawLine(draw,tickloc[i],axis->yhigh,tickloc[i],axis->yhigh-.5*th,tc);CHKERRQ(ierr);
322     }
323     /* label ticks */
324     if (axis->xlabelstr) {
325       for (i=0; i<ntick; i++) {
326         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
327         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
328         else               sep = 0.0;
329         ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
330         ierr = PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.5*th,cc,p);CHKERRQ(ierr);
331       }
332     }
333   }
334   if (axis->xlabel) {
335     PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->ylow - 1.5*th;
336     if (axis->xlabelstr) y -= 1.5*th;
337     ierr = PetscDrawStringCentered(draw,x,y,cc,axis->xlabel);CHKERRQ(ierr);
338   }
339 
340   /* PetscDraw the Y ticks and labels */
341   if (axis->yticks) {
342     numy = (int)(.50*(axis->yhigh-axis->ylow)/th); numy = PetscClipInterval(numy,2,6);
343     ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
344     /* PetscDraw in tick marks */
345     for (i=0; i<ntick; i++) {
346       ierr = PetscDrawLine(draw,axis->xlow,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr);
347       ierr = PetscDrawLine(draw,axis->xhigh,tickloc[i],axis->xhigh-.5*tw,tickloc[i],tc);CHKERRQ(ierr);
348     }
349     /* label ticks */
350     if (axis->ylabelstr) {
351       for (i=0; i<ntick; i++) {
352         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
353         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
354         else               sep = 0.0;
355         ierr = (*axis->ylabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
356         ierr = PetscStrlen(p,&len);CHKERRQ(ierr); ytlen = PetscMax(ytlen,len);
357         ierr = PetscDrawString(draw,axis->xlow-(len+.5)*tw,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr);
358       }
359     }
360   }
361   if (axis->ylabel) {
362     PetscReal x = axis->xlow - 2.0*tw, y = (axis->ylow + axis->yhigh)/2;
363     if (axis->ylabelstr) x -= (ytlen+.5)*tw;
364     ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr);
365     ierr = PetscDrawStringVertical(draw,x,y+len*th/2,cc,axis->ylabel);CHKERRQ(ierr);
366   }
367 
368   ierr = PetscDrawGetCoordinates(draw,&coors[0],&coors[1],&coors[2],&coors[3]);CHKERRQ(ierr);
369 finally:
370   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
371   ierr = MPI_Bcast(coors,4,MPIU_REAL,0,PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
372   ierr = PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);CHKERRQ(ierr);
373   PetscFunctionReturn(0);
374 }
375 
376 /*
377     Removes all zeros but one from .0000
378 */
PetscStripe0(char * buf)379 PetscErrorCode PetscStripe0(char *buf)
380 {
381   PetscErrorCode ierr;
382   size_t         n;
383   PetscBool      flg;
384   char           *str;
385 
386   PetscFunctionBegin;
387   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
388   ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr);
389   if (flg) buf[n-3] = 0;
390   ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr);
391   if (str) {
392     buf[n-2] = buf[n-1];
393     buf[n-1] = 0;
394   }
395   ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr);
396   if (str) {
397     buf[n-2] = buf[n-1];
398     buf[n-1] = 0;
399   }
400   PetscFunctionReturn(0);
401 }
402 
403 /*
404     Removes all zeros but one from .0000
405 */
PetscStripAllZeros(char * buf)406 PetscErrorCode PetscStripAllZeros(char *buf)
407 {
408   PetscErrorCode ierr;
409   size_t         i,n;
410 
411   PetscFunctionBegin;
412   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
413   if (buf[0] != '.') PetscFunctionReturn(0);
414   for (i=1; i<n; i++) {
415     if (buf[i] != '0') PetscFunctionReturn(0);
416   }
417   buf[0] = '0';
418   buf[1] = 0;
419   PetscFunctionReturn(0);
420 }
421 
422 /*
423     Removes trailing zeros
424 */
PetscStripTrailingZeros(char * buf)425 PetscErrorCode PetscStripTrailingZeros(char *buf)
426 {
427   PetscErrorCode ierr;
428   char           *found;
429   size_t         i,n,m = PETSC_MAX_INT;
430 
431   PetscFunctionBegin;
432   /* if there is an e in string DO NOT strip trailing zeros */
433   ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr);
434   if (found) PetscFunctionReturn(0);
435 
436   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
437   /* locate decimal point */
438   for (i=0; i<n; i++) {
439     if (buf[i] == '.') {m = i; break;}
440   }
441   /* if not decimal point then no zeros to remove */
442   if (m == PETSC_MAX_INT) PetscFunctionReturn(0);
443   /* start at right end of string removing 0s */
444   for (i=n-1; i>m; i++) {
445     if (buf[i] != '0') PetscFunctionReturn(0);
446     buf[i] = 0;
447   }
448   PetscFunctionReturn(0);
449 }
450 
451 /*
452     Removes leading 0 from 0.22 or -0.22
453 */
PetscStripInitialZero(char * buf)454 PetscErrorCode PetscStripInitialZero(char *buf)
455 {
456   PetscErrorCode ierr;
457   size_t         i,n;
458 
459   PetscFunctionBegin;
460   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
461   if (buf[0] == '0') {
462     for (i=0; i<n; i++) buf[i] = buf[i+1];
463   } else if (buf[0] == '-' && buf[1] == '0') {
464     for (i=1; i<n; i++) buf[i] = buf[i+1];
465   }
466   PetscFunctionReturn(0);
467 }
468 
469 /*
470      Removes the extraneous zeros in numbers like 1.10000e6
471 */
PetscStripZeros(char * buf)472 PetscErrorCode PetscStripZeros(char *buf)
473 {
474   PetscErrorCode ierr;
475   size_t         i,j,n;
476 
477   PetscFunctionBegin;
478   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
479   if (n<5) PetscFunctionReturn(0);
480   for (i=1; i<n-1; i++) {
481     if (buf[i] == 'e' && buf[i-1] == '0') {
482       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
483       ierr = PetscStripZeros(buf);CHKERRQ(ierr);
484       PetscFunctionReturn(0);
485     }
486   }
487   PetscFunctionReturn(0);
488 }
489 
490 /*
491       Removes the plus in something like 1.1e+2 or 1.1e+02
492 */
PetscStripZerosPlus(char * buf)493 PetscErrorCode PetscStripZerosPlus(char *buf)
494 {
495   PetscErrorCode ierr;
496   size_t         i,j,n;
497 
498   PetscFunctionBegin;
499   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
500   if (n<5) PetscFunctionReturn(0);
501   for (i=1; i<n-2; i++) {
502     if (buf[i] == '+') {
503       if (buf[i+1] == '0') {
504         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
505         PetscFunctionReturn(0);
506       } else {
507         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
508         PetscFunctionReturn(0);
509       }
510     } else if (buf[i] == '-') {
511       if (buf[i+1] == '0') {
512         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
513         PetscFunctionReturn(0);
514       }
515     }
516   }
517   PetscFunctionReturn(0);
518 }
519