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