00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef B23CURVE_H
00023 #define B23CURVE_H
00024
00025 #include "common.h"
00026 #include <stdexcept>
00027 #include "units.h"
00028 #include "zeroin.h"
00029 #include "steamcalculator.h"
00030 #include "steamproperty.h"
00031
00033
00045 template<class Ordinate,class Abscissa,int OrdinateAlternative=0, int AbscissaAlternative=0>
00046 class B23CurveBase{
00047
00048 public:
00049
00050 virtual Ordinate solve(const Abscissa &target) = 0;
00051
00052 protected:
00053
00054 B23CurveBase(){}
00055 virtual ~B23CurveBase(){};
00056
00057 Ordinate getOrdinate(SteamCalculator S){
00058 return SteamProperty<Ordinate,OrdinateAlternative>::get(S);
00059 }
00060
00061 Abscissa getAbscissa(SteamCalculator S){
00062 return SteamProperty<Abscissa,AbscissaAlternative>::get(S);
00063 }
00064
00065 };
00066
00068
00071 template<class Ordinate,class Abscissa,int OrdinateAlternative=0, int AbscissaAlternative=0>
00072 class B23Curve : public B23CurveBase<Ordinate,Abscissa,OrdinateAlternative,AbscissaAlternative>{
00073
00074
00075 friend class ZeroIn<B23Curve,Temperature,Abscissa>;
00076
00077 public:
00078
00079 B23Curve(){
00080
00081 }
00082
00083 virtual ~B23Curve(){};
00084
00085 Ordinate solve(const Abscissa &target){
00086
00087 ZeroIn<B23Curve,Abscissa,Temperature> z;
00088
00089 try{
00090
00091
00092
00093 this->target=target;
00094 this->state=state;
00095
00096
00097 Abscissa maxerror = fabs(target) * 0.001 * Percent;
00098
00099 z.setLowerBound(TB_LOW);
00100 z.setUpperBound(TB_HIGH);
00101 z.setTolerance(0.00001 * Kelvin);
00102
00103 z.setMethod(&B23Curve::getAbscissaError_T);
00104
00105 z.visit(this);
00106
00107 if(!z.isSolved(maxerror)){
00108 std::stringstream s;
00109 s.flags(std::ios_base::showbase);
00110 s << "Unable to solve for target " << target << " (error was " << z.getError() << ", max allowed is " << maxerror << ")";
00111 throw std::runtime_error(s.str());
00112 }
00113
00114
00115 Temperature T = z.getSolution();
00116
00117 S.setB23_T(T);
00118
00119
00120
00121 return B23CurveBase<Ordinate,Abscissa,OrdinateAlternative,AbscissaAlternative>::getOrdinate(S);
00122
00123 }catch(std::exception &e){
00124 std::stringstream s;
00125 s << "B23Curve::solve: " << e.what();
00126 throw std::runtime_error(s.str());
00127 }
00128 }
00129
00130 private:
00131
00132 Abscissa getAbscissaError_T(const Temperature &T){
00133
00134
00135
00136 S.setB23_T(T);
00137
00138
00139
00140 return B23CurveBase<Ordinate,Abscissa,OrdinateAlternative,AbscissaAlternative>::getAbscissa(S) - target;
00141 }
00142
00143 SteamCalculator S;
00144 Abscissa target;
00145 bool state;
00146
00147 };
00148
00150
00153 template<class Ordinate,int OrdinateAlternative>
00154 class B23Curve<Ordinate,Temperature,OrdinateAlternative,0>
00155 : public B23CurveBase<Ordinate,Temperature,OrdinateAlternative,0>{
00156
00157 public:
00158
00159 B23Curve() : B23CurveBase<Ordinate,Temperature,OrdinateAlternative,0>(){}
00160 virtual ~B23Curve(){};
00161
00162 virtual Ordinate solve(const Temperature &T){
00163 SteamCalculator S;
00164 S.setB23_T(T);
00165 return B23CurveBase<Ordinate,Temperature,OrdinateAlternative,0>::getOrdinate(S);
00166 }
00167 };
00168
00170
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 #endif