0026586: Eliminate compile warnings obtained by building occt with vc14: declaration...
[occt.git] / src / FairCurve / FairCurve_Batten.cxx
1 // Created on: 1996-02-05
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #ifndef OCCT_DEBUG
18 #define No_Standard_RangeError
19 #define No_Standard_OutOfRange
20 #endif
21
22
23 #include <BSplCLib.hxx>
24 #include <FairCurve_Batten.hxx>
25 #include <FairCurve_BattenLaw.hxx>
26 #include <FairCurve_EnergyOfBatten.hxx>
27 #include <FairCurve_Newton.hxx>
28 #include <Geom2d_BSplineCurve.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <gp_Vec2d.hxx>
31 #include <math_Matrix.hxx>
32 #include <PLib.hxx>
33 #include <Precision.hxx>
34 #include <Standard_NegativeValue.hxx>
35 #include <Standard_NullValue.hxx>
36
37 // ==================================================================
38 FairCurve_Batten::FairCurve_Batten(const gp_Pnt2d& P1, 
39                                    const gp_Pnt2d& P2, 
40                                    const Standard_Real Height, 
41                                    const Standard_Real Slope)
42 // ==================================================================
43                   : myCode(FairCurve_OK),
44                     OldP1(P1),
45                     OldP2(P2),
46                     OldAngle1(0),
47                     OldAngle2(0),
48                     OldHeight(Height),
49                     OldSlope(Slope),
50                     OldSlidingFactor(1),
51                     OldFreeSliding(0),
52                     OldConstraintOrder1(1),
53                     OldConstraintOrder2(1),
54                     NewP1(P1),
55                     NewP2(P2),
56                     NewAngle1(0),
57                     NewAngle2(0),
58                     NewHeight(Height),
59                     NewSlope(Slope),
60                     NewSlidingFactor(1),
61                     NewFreeSliding(0),
62                     NewConstraintOrder1(1),
63                     NewConstraintOrder2(1),
64                     Degree(9)
65 {
66   if (P1.IsEqual(P2, Precision::Confusion())) 
67     Standard_NullValue::Raise("FairCurve : P1 and P2 are confused");
68   if (Height <= 0) 
69     Standard_NegativeValue::Raise("FairCurve : Height is not positive");
70 //
71 //   Initialize by a straight line (2 poles)
72 //
73   Handle(TColStd_HArray1OfReal)    Iknots =  new TColStd_HArray1OfReal(1,2);
74   Handle(TColStd_HArray1OfInteger) Imults =  new TColStd_HArray1OfInteger(1,2);
75   Handle(TColgp_HArray1OfPnt2d)    Ipoles = new TColgp_HArray1OfPnt2d(1,2);
76
77   Iknots->SetValue(1, 0);
78   Iknots->SetValue(2, 1);
79   
80   Imults->SetValue(1, 2);
81   Imults->SetValue(2, 2);
82
83   Ipoles->SetValue(1, P1);
84   Ipoles->SetValue(2, P2);
85
86 //  Increase the degree
87   
88   Handle(TColgp_HArray1OfPnt2d) Npoles = new  TColgp_HArray1OfPnt2d(1, Degree+1);
89   Handle(TColStd_HArray1OfReal) Nweight = new TColStd_HArray1OfReal(1, 2);
90   Handle(TColStd_HArray1OfReal) Nknots = new TColStd_HArray1OfReal(1, 2);
91   Handle(TColStd_HArray1OfInteger) Nmults = new TColStd_HArray1OfInteger(1, 2);
92     
93   BSplCLib::IncreaseDegree (1, Degree, Standard_False,
94                             Ipoles->Array1(),
95                             BSplCLib::NoWeights(),
96                             Iknots->Array1(), 
97                             Imults->Array1(), 
98                             Npoles->ChangeArray1(),
99                             Nweight->ChangeArray1(),
100                             Nknots->ChangeArray1(),
101                             Nmults->ChangeArray1() );
102
103    // and impact the result in our fields
104
105   Poles = Npoles;
106   Knots = Nknots;
107   Mults = Nmults;
108
109    // calculate "plane" nodes
110
111   Flatknots = new TColStd_HArray1OfReal
112     (1, BSplCLib::KnotSequenceLength(Mults->Array1(), Degree, Standard_False));
113
114   BSplCLib::KnotSequence (Knots->Array1(), 
115                           Mults->Array1(),
116                           Degree, Standard_False,
117                           Flatknots->ChangeArray1());     
118 }
119 // ==================================================================
120 void FairCurve_Batten::Delete()
121 {}
122 // ==================================================================
123 void FairCurve_Batten::Angles(const gp_Pnt2d& P1, 
124                               const gp_Pnt2d& P2)
125 // ==================================================================
126 {
127   gp_Vec2d VOld(NewP1, NewP2), VNew(P1, P2);
128   Standard_Real Dangle = VOld.Angle(VNew);
129   NewAngle1 -= Dangle;
130   NewAngle2 += Dangle; 
131 }
132
133 // ==================================================================
134 void FairCurve_Batten::SetP1(const gp_Pnt2d& P1)
135 // ==================================================================
136 {
137   if (P1.IsEqual(NewP2, Precision::Confusion())) 
138     Standard_NullValue::Raise("FairCurve : P1 and P2 are confused");  
139   Angles(P1, NewP2);
140   NewP1 = P1;
141 }
142
143 // ==================================================================
144 void FairCurve_Batten::SetP2(const gp_Pnt2d& P2)
145 // ==================================================================
146 {
147  if (NewP1.IsEqual(P2, Precision::Confusion())) 
148     Standard_NullValue::Raise("FairCurve : P1 and P2 are confused");
149   Angles(NewP1, P2);
150   NewP2 = P2;
151 }
152
153 // ==================================================================
154 Standard_Boolean FairCurve_Batten::Compute(FairCurve_AnalysisCode& ACode, 
155                                            const Standard_Integer NbIterations, 
156                                            const Standard_Real Tolerance)
157 // ==================================================================
158 {
159   Standard_Boolean Ok=Standard_True, End=Standard_False;
160   Standard_Real AngleMax = 0.7;      // parameter ruling the function of increment ( 40 degrees )
161   Standard_Real AngleMin = 2*M_PI/100; // parameter ruling the function of increment 
162                                      // full passage should not cost more than 100 steps.
163   Standard_Real DAngle1, DAngle2,  Ratio, Fraction, Toler;
164   Standard_Real OldDist, NewDist;
165
166 //  Loop of Homotopy : calculation of the step and optimisation 
167
168   while (Ok && !End) {
169      DAngle1 = NewAngle1-OldAngle1;
170      DAngle2 = NewAngle2-OldAngle2;
171      Ratio = 1;
172      if (NewConstraintOrder1>0) {
173         Fraction = Abs(DAngle1) / (AngleMax * Exp (-Abs(OldAngle1)/AngleMax) + AngleMin);
174         if (Fraction > 1) Ratio = 1 / Fraction;
175      }
176      if (NewConstraintOrder2>0) {
177         Fraction = Abs(DAngle2) / (AngleMax * Exp (-Abs(OldAngle2)/AngleMax) + AngleMin);
178         if (Fraction > 1)  Ratio = (Ratio < 1 / Fraction ? Ratio : 1 / Fraction);
179      }
180      
181      OldDist = OldP1.Distance(OldP2);
182      NewDist = NewP1.Distance(NewP2);
183      Fraction = Abs(OldDist-NewDist) / (OldDist/3);
184      if ( Fraction > 1) Ratio = (Ratio < 1 / Fraction ? Ratio : 1 / Fraction);     
185
186      gp_Vec2d DeltaP1(OldP1, NewP1) , DeltaP2(OldP2, NewP2);
187      if ( Ratio == 1) {
188         End = Standard_True;
189         Toler = Tolerance;
190       }
191      else {
192        DeltaP1 *= Ratio;
193        DeltaP2 *= Ratio;
194        DAngle1 *= Ratio;
195        DAngle2 *= Ratio;
196        Toler =  10 * Tolerance;
197      }
198  
199      Ok = Compute( DeltaP1, DeltaP2, 
200                    DAngle1, DAngle2,
201                    ACode,
202                    NbIterations,
203                    Toler);
204
205      if (ACode != FairCurve_OK) End = Standard_True;
206      if (NewFreeSliding) NewSlidingFactor = OldSlidingFactor;
207      if (NewConstraintOrder1 == 0) NewAngle1 = OldAngle1;
208      if (NewConstraintOrder2 == 0) NewAngle2 = OldAngle2; 
209   }
210   myCode = ACode;  
211   return Ok;
212 }
213 // =============================================================================
214 Standard_Boolean FairCurve_Batten::Compute(const gp_Vec2d& DeltaP1, 
215                                            const gp_Vec2d& DeltaP2, 
216                                            const Standard_Real DeltaAngle1, 
217                                            const Standard_Real DeltaAngle2,
218                                            FairCurve_AnalysisCode& ACode, 
219                                            const Standard_Integer NbIterations, 
220                                            const Standard_Real Tolerance)
221 // =============================================================================
222 {
223  Standard_Boolean Ok, OkCompute=Standard_True;
224  ACode = FairCurve_OK;
225
226 // Deformation of the curve by adding a polynom of interpolation
227    Standard_Integer L = 2 + NewConstraintOrder1 + NewConstraintOrder2, kk, ii;
228    TColStd_Array1OfReal knots (1,2);
229    knots(1) = 0;
230    knots(2) = 1;
231    TColStd_Array1OfInteger mults (1,2);
232    TColgp_Array1OfPnt2d HermitePoles(1,L);
233    TColgp_Array1OfPnt2d Interpolation(1,L);
234    Handle(TColgp_HArray1OfPnt2d) NPoles = new  TColgp_HArray1OfPnt2d(1, Poles->Length());
235
236 // Polynoms of Hermite
237    math_Matrix HermiteCoef(1, L, 1, L);
238    Ok = PLib::HermiteCoefficients(0,1, NewConstraintOrder1,  NewConstraintOrder2,
239                                   HermiteCoef);
240    if (!Ok) return Standard_False;
241
242 // Definition of constraints of interpolation
243    TColgp_Array1OfXY ADelta(1,L);
244    gp_Vec2d VOld(OldP1, OldP2), VNew( -(OldP1.XY()+DeltaP1.XY()) + (OldP2.XY()+DeltaP2.XY()) );
245    Standard_Real DAngleRef = VNew.Angle(VOld);
246
247    ADelta(1) = DeltaP1.XY();
248    kk = 2;
249    if (NewConstraintOrder1>0) {
250       gp_Vec2d OldDerive( Poles->Value(Poles->Lower()), 
251                           Poles->Value(Poles->Lower()+1) );
252       OldDerive *= Degree / (Knots->Value(2) - Knots->Value(1));
253       ADelta(kk) = (OldDerive.Rotated(DeltaAngle1-DAngleRef) -  OldDerive).XY();
254       kk += 1;
255    }
256    ADelta(kk) = DeltaP2.XY();
257    kk += 1;  
258    if (NewConstraintOrder2>0) {
259       gp_Vec2d OldDerive( Poles->Value(Poles->Upper()-1), 
260                           Poles->Value(Poles->Upper()) );
261       OldDerive *= Degree / (Knots->Value(Knots->Upper())  - Knots->Value(Knots->Upper()-1) );
262       ADelta(kk) = (OldDerive.Rotated(DAngleRef-DeltaAngle2) -  OldDerive).XY();
263    }
264
265 // Interpolation
266   gp_XY AuxXY (0,0);
267   for (ii=1; ii<=L; ii++) {
268       AuxXY.SetCoord(0.0, 0);
269       for (kk=1; kk<=L; kk++) {
270           AuxXY +=  HermiteCoef(kk, ii) * ADelta(kk);       
271       }
272       Interpolation(ii).SetXY(AuxXY);
273   }
274 // Conversion into BSpline of the same structure as the current batten.
275   PLib::CoefficientsPoles( Interpolation, PLib::NoWeights(), 
276                            HermitePoles,  PLib::NoWeights() ); 
277
278   mults.Init(L);
279
280   Handle(Geom2d_BSplineCurve) DeltaCurve = 
281     new  Geom2d_BSplineCurve( HermitePoles, 
282                               knots, mults, L-1);
283
284   DeltaCurve->IncreaseDegree(Degree);
285   if (Mults->Length()>2) {
286      DeltaCurve->InsertKnots(Knots->Array1(), Mults->Array1(), 1.e-10);
287   }
288
289 // Summing
290   DeltaCurve->Poles( NPoles->ChangeArray1() );
291   for (kk= NPoles->Lower(); kk<=NPoles->Upper(); kk++) { 
292      NPoles->ChangeValue(kk).ChangeCoord() += Poles->Value(kk).Coord(); 
293    }
294
295 // Intermediary data
296
297  Standard_Real Angle1, Angle2, SlidingLength, 
298                Alph1 =  OldAngle1 + DeltaAngle1, 
299                Alph2 =  OldAngle2 + DeltaAngle2,
300                Dist  =  NPoles->Value(NPoles->Upper()) 
301                       . Distance( NPoles->Value( NPoles->Lower() ) ),
302                LReference = SlidingOfReference(Dist, Alph1, Alph2);
303  gp_Vec2d Ox(1, 0),
304                 P1P2 (  NPoles->Value(NPoles->Upper()).Coord()
305                       - NPoles->Value(NPoles->Lower()).Coord() );
306
307 // Angles corresponding to axis ox
308
309  Angle1 =  Ox.Angle(P1P2) + Alph1;
310  Angle2 = -Ox.Angle(P1P2) + Alph2;
311
312 // Calculation of the length of sliding (imposed or intial);
313  
314  if (!NewFreeSliding) {
315     SlidingLength = NewSlidingFactor * LReference;
316   }
317  else {
318    if (OldFreeSliding) {
319      SlidingLength = OldSlidingFactor *  LReference;
320    }
321    else {
322      SlidingLength = SlidingOfReference(Dist, Alph1, Alph2);
323    }
324  }
325
326
327      
328 // Energy and vectors of initialisation
329  FairCurve_BattenLaw LBatten (NewHeight, NewSlope, SlidingLength ); 
330  FairCurve_EnergyOfBatten EBatten (Degree+1, Flatknots, NPoles,  
331                                    NewConstraintOrder1,  NewConstraintOrder2, 
332                                    LBatten, SlidingLength, NewFreeSliding,
333                                    Angle1, Angle2);
334  math_Vector VInit (1, EBatten.NbVariables());
335
336  // The valeur below is the smallest value of the criterion of flexion.
337  Standard_Real VConvex = 0.01 * pow(NewHeight / SlidingLength, 3);
338  if (VConvex < 1.e-12) {VConvex = 1.e-12;}
339
340  Ok = EBatten.Variable(VInit);
341  
342 // Minimisation
343  FairCurve_Newton Newton(EBatten,
344                          Tolerance*P1P2.Magnitude()/10,
345                          Tolerance,
346                          NbIterations,
347                          VConvex);
348  Newton.Perform(EBatten, VInit);
349  Ok = Newton.IsDone();
350  
351  if (Ok) {
352     Poles = NPoles;
353     Newton.Location(VInit);
354     if (NewFreeSliding) { OldSlidingFactor = VInit(VInit.Upper()) / LReference;}
355     else                { OldSlidingFactor = NewSlidingFactor; }
356
357     if (NewConstraintOrder1 == 0) {
358        gp_Vec2d Tangente (  Poles->Value(Poles->Lower()+1).Coord()
359                                    - Poles->Value(Poles->Lower()).Coord() );
360        OldAngle1 = P1P2.Angle(Tangente);
361      }
362     else {OldAngle1 = Alph1;}
363
364     if (NewConstraintOrder2 == 0) {
365        gp_Vec2d Tangente (  Poles->Value(Poles->Upper()).Coord()
366                                    - Poles->Value(Poles->Upper()-1).Coord() );
367        OldAngle2 = (-Tangente).Angle(-P1P2);
368      } 
369     else {OldAngle2 = Alph2;}
370
371     OldP1 = Poles->Value(Poles->Lower());
372     OldP2 = Poles->Value(Poles->Upper());
373     OldConstraintOrder1 = NewConstraintOrder1;
374     OldConstraintOrder2 = NewConstraintOrder2;
375     OldFreeSliding      = NewFreeSliding;
376     OldSlope = NewSlope;
377     OldHeight = NewHeight;
378   }
379   else {
380     Standard_Real V;
381     ACode = EBatten.Status();
382     if (!LBatten.Value(0, V) || !LBatten.Value(1, V)) {
383        ACode = FairCurve_NullHeight;
384     }
385     else { OkCompute = Standard_False;}
386     return OkCompute;
387   }
388
389  Ok = EBatten.Variable(VInit);
390
391  // Processing of non-convergence
392  if (!Newton.IsConverged()) {
393     ACode = FairCurve_NotConverged;
394   }
395
396
397  // Prevention of infinite sliding
398  if (NewFreeSliding &&  VInit(VInit.Upper()) > 2*LReference) 
399    ACode = FairCurve_InfiniteSliding;  
400     
401
402 // Eventual insertion of Nodes
403  Standard_Boolean  NewKnots = Standard_False;
404  Standard_Integer NbKnots = Knots->Length();
405  Standard_Real ValAngles = (Abs(OldAngle1) +  Abs(OldAngle2) 
406                          + 2 * Abs(OldAngle2 - OldAngle1) ) ;
407  while ( ValAngles > (2*(NbKnots-2) + 1)*(1+2*NbKnots) ) {
408    NewKnots = Standard_True;
409    NbKnots += NbKnots-1;
410  }
411
412  if  (NewKnots) {  
413    Handle(Geom2d_BSplineCurve) NewBS = 
414     new  Geom2d_BSplineCurve( NPoles->Array1(), Knots->Array1(), 
415                               Mults->Array1(), Degree);
416
417    Handle(TColStd_HArray1OfInteger) NMults  =
418       new TColStd_HArray1OfInteger (1,NbKnots);
419    NMults->Init(Degree-3);
420
421     Handle(TColStd_HArray1OfReal) NKnots  =
422       new TColStd_HArray1OfReal (1,NbKnots);
423    for (ii=1; ii<=NbKnots; ii++) {
424        NKnots->ChangeValue(ii) = (double) (ii-1) / (NbKnots-1);
425    } 
426
427    NewBS -> InsertKnots(NKnots->Array1(), NMults->Array1(), 1.e-10);
428    Handle(TColgp_HArray1OfPnt2d) NewNPoles =
429       new  TColgp_HArray1OfPnt2d(1, NewBS->NbPoles());
430    NewBS -> Poles(NewNPoles->ChangeArray1() );
431    NewBS -> Multiplicities( NMults->ChangeArray1() );
432    NewBS -> Knots( NKnots->ChangeArray1() );
433    Handle(TColStd_HArray1OfReal) FKnots  =
434       new TColStd_HArray1OfReal (1, NewBS->NbPoles() + Degree+1);
435    NewBS -> KnotSequence( FKnots->ChangeArray1()); 
436
437    Poles = NewNPoles;
438    Mults = NMults;
439    Knots = NKnots;
440    Flatknots = FKnots;                
441  } 
442
443 // For eventual debug
444 //  Newton.Dump(cout);
445    
446  return OkCompute;
447
448
449
450 // ==================================================================
451 Standard_Real FairCurve_Batten::SlidingOfReference() const
452 // ================================================================== 
453 {
454  return SlidingOfReference(NewP1.Distance(NewP2), NewAngle1, NewAngle2 );
455 }
456 // ==================================================================
457 Standard_Real FairCurve_Batten::SlidingOfReference(const Standard_Real Dist,
458                                                    const Standard_Real Angle1,
459                                                    const Standard_Real Angle2) const
460 // ==================================================================
461 {
462  Standard_Real a1, a2;
463
464 // case of angle without constraints
465  if ( (NewConstraintOrder1 == 0) && (NewConstraintOrder2 == 0)) return Dist;
466
467  if (NewConstraintOrder1 == 0) a1 = Abs( Abs(NewAngle2)<M_PI ? Angle2/2 : M_PI/2);
468  else a1 = Abs(Angle1);
469
470  if (NewConstraintOrder2 == 0) a2 = Abs( Abs(NewAngle1)<M_PI ? Angle1/2 : M_PI/2);
471  else a2 = Abs(Angle2);
472
473 // case of angle of the same sign 
474  if (Angle1 * Angle2 >= 0 ) {
475      return Compute(Dist, a1, a2);
476    }
477
478 // case of angle of opposite sign
479  else {
480     Standard_Real Ratio = a1 / ( a1 + a2 );
481     Standard_Real AngleMilieu = pow(1-Ratio,2) * a1 + pow(Ratio,2) * a2;
482     if (AngleMilieu > M_PI/2) AngleMilieu = M_PI/2;
483
484     return   Ratio     * Compute(Dist, a1,  AngleMilieu )
485            + (1-Ratio) * Compute(Dist, a2,  AngleMilieu );
486   }
487 }
488
489
490 // ==================================================================
491 Standard_Real FairCurve_Batten::Compute(const Standard_Real Dist,
492                                         const Standard_Real Angle1,
493                                         const Standard_Real Angle2) const
494 // ==================================================================
495 {
496     Standard_Real L1 = Compute(Dist, Angle1);
497     Standard_Real L2 = Compute(Dist, Angle2), Aux;
498     if (L1 < L2) { 
499       Aux = L2;
500       L2 = L1;
501       L1 = Aux;
502     }
503     return 0.3 * L1 + 0.7 * L2;
504 }
505
506 // ==================================================================
507 Standard_Real FairCurve_Batten::Compute(const Standard_Real Dist,
508                                         const Standard_Real Angle) const
509 // ==================================================================
510 {
511   if (Angle < Precision::Angular() ) { return Dist; } // length of segment P1P2
512   if (Angle < M_PI/2) { return Angle*Dist / sin(Angle); } // length of circle P1P2 respecting ANGLE
513   if (Angle > M_PI) { return Sqrt(Angle*M_PI) * Dist;}
514   else  { return Angle * Dist; }                      // linear interpolation
515 }
516
517 // ==================================================================
518 Handle(Geom2d_BSplineCurve) FairCurve_Batten::Curve() const
519 // ================================================================== 
520 {
521    Handle(Geom2d_BSplineCurve) TheCurve = new 
522                         Geom2d_BSplineCurve ( Poles->Array1(),
523                                               Knots->Array1(),
524                                               Mults->Array1(),
525                                               Degree);
526    return TheCurve; 
527 }
528
529 // ==================================================================
530 void FairCurve_Batten::Dump(Standard_OStream& o) const 
531 // ==================================================================
532 {
533
534 o << "  Batten       |"; o.width(7); o<< "Old " << " | " << "  New" << endl;
535 o << "  P1    X      |"; o.width(7); o<<  OldP1.X() << " | " << NewP1.X() << endl;
536 o << "        Y      |"; o.width(7); o<<  OldP1.Y() << " | " << NewP1.Y() << endl;
537 o << "  P2    X      |"; o.width(7); o<<  OldP2.X() << " | " << NewP2.X() << endl;
538 o << "        Y      |"; o.width(7); o<<  OldP2.Y() << " | " << NewP2.Y() << endl;
539 o << "      Angle1   |"; o.width(7); o<<  OldAngle1 << " | " << NewAngle1 << endl;
540 o << "      Angle2   |"; o.width(7); o<<  OldAngle2 << " | " << NewAngle2 << endl;
541 o << "      Height   |"; o.width(7); o<<  OldHeight << " | " << NewHeight << endl;
542 o << "      Slope    |"; o.width(7); o<<  OldSlope  << " | " << NewSlope << endl; 
543 o << " SlidingFactor |"; o.width(7); o<<  OldSlidingFactor << " | " << NewSlidingFactor << endl;
544 o << " FreeSliding   |"; o.width(7); o<<  OldFreeSliding << " | " << NewFreeSliding << endl; 
545 o << " ConstrOrder1  |"; o.width(7); o<<  OldConstraintOrder1 << " | " << NewConstraintOrder1 << endl; 
546 o << " ConstrOrder2  |" ; o.width(7); o<<  OldConstraintOrder2 << " | " << NewConstraintOrder2 << endl;
547  switch (myCode) {
548    case FairCurve_OK : 
549      o  << "AnalysisCode : Ok" << endl;
550        break;
551    case  FairCurve_NotConverged : 
552      o << "AnalysisCode : NotConverged" << endl;
553        break;
554    case  FairCurve_InfiniteSliding : 
555      o << "AnalysisCode : InfiniteSliding" << endl;
556        break;
557    case  FairCurve_NullHeight : 
558      o << "AnalysisCode : NullHeight" << endl;
559        break;
560      } 
561 }
562