Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

b23curve.h

00001 /* 00002 00003 freesteam - IAPWS-IF97 steam tables library 00004 Copyright (C) 2004-2005 John Pye 00005 00006 This program is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU General Public License 00008 as published by the Free Software Foundation; either version 2 00009 of the License, or (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 00020 */ 00021 00022 #ifndef B23CURVE_H 00023 #define B23CURVE_H 00024 00025 #include "common.h" 00026 #include "exception.h" 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 // ZeroIn will be finding the TEMPERATURE at which B23Curve's ABSCISSA has the desired value: 00075 friend class ZeroIn<B23Curve,Temperature,Abscissa>; 00076 00077 public: 00078 00079 B23Curve(){ 00080 // Intentionally empty 00081 } 00082 00083 virtual ~B23Curve(){}; 00084 00085 Ordinate solve(const Abscissa &target){ 00086 00087 ZeroIn<B23Curve,Abscissa,Temperature> z; 00088 00089 try{ 00090 00091 //cerr << endl << "B23Curve::solve: Trying to solve for " << SteamProperty<Abscissa,AbscissaAlternative>::name() << " = " << target << endl; 00092 00093 this->target=target; 00094 this->state=state; 00095 00096 // Always try to solve to accuracy of 0.001% of the target value: 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 stringstream s; 00109 s.flags(ios_base::showbase); 00110 s << "Unable to solve for target " << target << " (error was " << z.getError() << ", max allowed is " << maxerror << ")"; 00111 throw new Exception(s.str()); 00112 } 00113 00114 00115 Temperature T = z.getSolution(); 00116 //cerr << endl << "Solution found was T = " << T; 00117 S.setB23_T(T); 00118 //cerr << endl << "At which abscissa = " << getAbscissa(S) << endl; 00119 //cerr << endl << "Found solution in region " << S.whichRegion() << ", T = " << S.temp() << ", p = " << S.pres() << ". "; 00120 00121 return B23CurveBase<Ordinate,Abscissa,OrdinateAlternative,AbscissaAlternative>::getOrdinate(S); 00122 00123 }catch(Exception *e){ 00124 stringstream s; 00125 s << "B23Curve::solve: " << e->what(); 00126 delete e; 00127 throw new Exception(s.str()); 00128 } 00129 } 00130 00131 private: 00132 00133 Abscissa getAbscissaError_T(const Temperature &T){ 00134 00135 //cerr << "B23Curve::getAbscissaError_T: T = " << T; 00136 00137 S.setB23_T(T); 00138 00139 //cerr << " --> " << SteamProperty<Abscissa,AbscissaAlternative>::name() << " = " << getAbscissa(S) << endl; 00140 00141 return B23CurveBase<Ordinate,Abscissa,OrdinateAlternative,AbscissaAlternative>::getAbscissa(S) - target; 00142 } 00143 00144 SteamCalculator S; 00145 Abscissa target; 00146 bool state; 00147 00148 }; 00149 00151 00154 template<class Ordinate,int OrdinateAlternative> 00155 class B23Curve<Ordinate,Temperature,OrdinateAlternative,0> 00156 : public B23CurveBase<Ordinate,Temperature,OrdinateAlternative,0>{ 00157 00158 public: 00159 00160 B23Curve() : B23CurveBase<Ordinate,Temperature,OrdinateAlternative,0>(){} 00161 virtual ~B23Curve(){}; 00162 00163 virtual Ordinate solve(const Temperature &T){ 00164 SteamCalculator S; 00165 S.setB23_T(T); 00166 return B23CurveBase<Ordinate,Temperature,OrdinateAlternative,0>::getOrdinate(S); 00167 } 00168 }; 00169 00171 00174 /* 00175 template<class Ordinate,int OrdinateAlternative> 00176 class B23Curve<Ordinate,Pressure,OrdinateAlternative,0> 00177 : public B23CurveBase<Ordinate,Pressure,OrdinateAlternative,0>{ 00178 00179 public: 00180 00181 B23Curve() : B23CurveBase<Ordinate,Pressure,OrdinateAlternative,0>(){} 00182 virtual ~B23Curve(){}; 00183 00184 virtual Ordinate solve(const Pressure &p){ 00185 SteamCalculator S; 00186 S.setB23_p(p); 00187 return B23CurveBase<Ordinate,Pressure,OrdinateAlternative,0>::getOrdinate(S); 00188 } 00189 }; 00190 */ 00191 #endif

Generated on Tue Mar 22 19:07:05 2005 for freesteam by doxygen 1.3.8