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