00001 /** 00002 * @file SimpleThermo.h 00003 * Header for the SimpleThermo (constant heat capacity) species reference-state model 00004 * for multiple species in a phase, derived from the 00005 * \link Cantera::SpeciesThermo SpeciesThermo\endlink base class (see \ref spthermo and 00006 * \link Cantera::SimpleThermo SimpleThermo\endlink). 00007 */ 00008 /* 00009 * $Id: SimpleThermo.h 279 2009-12-05 19:08:43Z hkmoffa $ 00010 */ 00011 00012 #ifndef CT_SIMPLETHERMO_H 00013 #define CT_SIMPLETHERMO_H 00014 00015 #include "SpeciesThermoMgr.h" 00016 00017 namespace Cantera { 00018 00019 /*! 00020 * A constant-heat capacity species thermodynamic property manager class. 00021 * This makes the 00022 * assumption that the heat capacity is a constant. Then, the following 00023 * relations are used to complete the specification of the thermodynamic 00024 * functions for each species in the phase. 00025 * 00026 * \f[ 00027 * \frac{c_p(T)}{R} = Cp0\_R 00028 * \f] 00029 * \f[ 00030 * \frac{h^0(T)}{RT} = \frac{1}{T} * (h0\_R + (T - T_0) * Cp0\_R) 00031 * \f] 00032 * \f[ 00033 * \frac{s^0(T)}{R} = (s0\_R + (log(T) - log(T_0)) * Cp0\_R) 00034 * \f] 00035 * 00036 * This parameterization takes 4 input values. These are: 00037 * - c[0] = \f$ T_0 \f$(Kelvin) 00038 * - c[1] = \f$ H_k^o(T_0, p_{ref}) \f$ (J/kmol) 00039 * - c[2] = \f$ S_k^o(T_0, p_{ref}) \f$ (J/kmol K) 00040 * - c[3] = \f$ {Cp}_k^o(T_0, p_{ref}) \f$ (J(kmol K) 00041 * 00042 * All species must have the same reference pressure. 00043 * The single-species standard-state property Manager ConstCpPoly has the same 00044 * parameterization as the SimpleThermo class does. 00045 * 00046 * @see ConstCpPoly 00047 * 00048 * @ingroup mgrsrefcalc 00049 */ 00050 class SimpleThermo : public SpeciesThermo { 00051 00052 public: 00053 00054 //! Initialized to the type of parameterization 00055 /*!A 00056 * Note, this value is used in some template functions. For this object the 00057 * value is SIMPLE. 00058 */ 00059 const int ID; 00060 00061 //! Constructor 00062 SimpleThermo() : 00063 ID(SIMPLE), 00064 m_tlow_max(0.0), 00065 m_thigh_min(1.e30), 00066 m_p0(-1.0), 00067 m_nspData(0) {} 00068 00069 //! Destructor 00070 virtual ~SimpleThermo() {} 00071 00072 //! Copy constructor 00073 /*! 00074 * @param right Object to be copied 00075 */ 00076 SimpleThermo(const SimpleThermo &right) : 00077 ID(SIMPLE), 00078 m_tlow_max(0.0), 00079 m_thigh_min(1.e30), 00080 m_p0(-1.0), 00081 m_nspData(0) { 00082 /* 00083 * Call the assignment operator 00084 */ 00085 *this = operator=(right); 00086 } 00087 00088 //! Assignment operator 00089 /*! 00090 * @param right Object to be copied 00091 */ 00092 SimpleThermo& operator=(const SimpleThermo &right) { 00093 /* 00094 * Check for self assignment. 00095 */ 00096 if (this == &right) return *this; 00097 00098 m_loc = right.m_loc; 00099 m_index = right.m_index; 00100 m_tlow_max = right.m_tlow_max; 00101 m_thigh_min = right.m_thigh_min; 00102 m_tlow = right.m_tlow; 00103 m_thigh = right.m_thigh; 00104 m_t0 = right.m_t0; 00105 m_logt0 = right.m_logt0; 00106 m_h0_R = right.m_h0_R; 00107 m_s0_R = right.m_s0_R; 00108 m_cp0_R = right.m_cp0_R; 00109 m_p0 = right.m_p0; 00110 m_nspData = right.m_nspData; 00111 00112 return *this; 00113 } 00114 00115 //! Duplication routine for objects which inherit from 00116 //! %SpeciesThermo 00117 /*! 00118 * This virtual routine can be used to duplicate %SpeciesThermo objects 00119 * inherited from %SpeciesThermo even if the application only has 00120 * a pointer to %SpeciesThermo to work with. 00121 * ->commented out because we first need to add copy constructors 00122 * and assignment operators to all of the derived classes. 00123 */ 00124 virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const { 00125 SimpleThermo *nt = new SimpleThermo(*this); 00126 return (SpeciesThermo *) nt; 00127 } 00128 00129 //! Install a new species thermodynamic property 00130 //! parameterization for one species. 00131 /*! 00132 * 00133 * @param name String name of the species 00134 * @param index Species index, k 00135 * @param type int flag specifying the type of parameterization to be 00136 * installed. 00137 * @param c Vector of coefficients for the parameterization. 00138 * There are 4 coefficients. The values (and units) are the following 00139 * - c[0] = \f$ T_0 \f$(Kelvin) 00140 * - c[1] = \f$ H_k^o(T_0, p_{ref}) \f$ (J/kmol) 00141 * - c[2] = \f$ S_k^o(T_0, p_{ref}) \f$ (J/kmol K) 00142 * - c[3] = \f$ {Cp}_k^o(T_0, p_{ref}) \f$ (J(kmol K) 00143 * 00144 * @param minTemp minimum temperature for which this parameterization 00145 * is valid. 00146 * @param maxTemp maximum temperature for which this parameterization 00147 * is valid. 00148 * @param refPressure standard-state pressure for this 00149 * parameterization. 00150 * 00151 * @see ConstCpPoly 00152 */ 00153 virtual void install(string name, int index, int type, 00154 const doublereal* c, 00155 doublereal minTemp, doublereal maxTemp, doublereal refPressure) { 00156 //writelog("installing const_cp for species "+name+"\n"); 00157 m_logt0.push_back(log(c[0])); 00158 m_t0.push_back(c[0]); 00159 m_h0_R.push_back(c[1]/GasConstant); 00160 m_s0_R.push_back(c[2]/GasConstant); 00161 m_cp0_R.push_back(c[3]/GasConstant); 00162 m_index.push_back(index); 00163 m_loc[index] = m_nspData; 00164 m_nspData++; 00165 doublereal tlow = minTemp; 00166 doublereal thigh = maxTemp; 00167 00168 if (tlow > m_tlow_max) m_tlow_max = tlow; 00169 if (thigh < m_thigh_min) m_thigh_min = thigh; 00170 00171 if ((int) m_tlow.size() < index + 1) { 00172 m_tlow.resize(index + 1, tlow); 00173 m_thigh.resize(index + 1, thigh); 00174 } 00175 m_tlow[index] = tlow; 00176 m_thigh[index] = thigh; 00177 00178 if (m_p0 < 0.0) { 00179 m_p0 = refPressure; 00180 } else if (fabs(m_p0 - refPressure) > 0.1) { 00181 string logmsg = " WARNING SimpleThermo: New Species, " + name + 00182 ", has a different reference pressure, " 00183 + fp2str(refPressure) + ", than existing reference pressure, " + fp2str(m_p0) + "\n"; 00184 writelog(logmsg); 00185 logmsg = " This may become a fatal error in the future \n"; 00186 writelog(logmsg); 00187 } 00188 m_p0 = refPressure; 00189 } 00190 00191 //! Install a new species thermodynamic property 00192 //! parameterization for one species. 00193 /*! 00194 * @param stit_ptr Pointer to the SpeciesThermoInterpType object 00195 * This will set up the thermo for one species 00196 */ 00197 virtual void install_STIT(SpeciesThermoInterpType *stit_ptr) { 00198 throw CanteraError("install_STIT", "not implemented"); 00199 } 00200 00201 //! Compute the reference-state properties for all species. 00202 /*! 00203 * Given temperature T in K, this method updates the values of 00204 * the non-dimensional heat capacity at constant pressure, 00205 * enthalpy, and entropy, at the reference pressure, Pref 00206 * of each of the standard states. 00207 * 00208 * @param t Temperature (Kelvin) 00209 * @param cp_R Vector of Dimensionless heat capacities. 00210 * (length m_kk). 00211 * @param h_RT Vector of Dimensionless enthalpies. 00212 * (length m_kk). 00213 * @param s_R Vector of Dimensionless entropies. 00214 * (length m_kk). 00215 */ 00216 virtual void update(doublereal t, doublereal* cp_R, 00217 doublereal* h_RT, doublereal* s_R) const { 00218 int k, ki; 00219 doublereal logt = log(t); 00220 doublereal rt = 1.0/t; 00221 for (k = 0; k < m_nspData; k++) { 00222 ki = m_index[k]; 00223 cp_R[ki] = m_cp0_R[k]; 00224 h_RT[ki] = rt*(m_h0_R[k] + (t - m_t0[k]) * m_cp0_R[k]); 00225 s_R[ki] = m_s0_R[k] + m_cp0_R[k] * (logt - m_logt0[k]); 00226 } 00227 } 00228 00229 //! Like update(), but only updates the single species k. 00230 /*! 00231 * @param k species index 00232 * @param t Temperature (Kelvin) 00233 * @param cp_R Vector of Dimensionless heat capacities. 00234 * (length m_kk). 00235 * @param h_RT Vector of Dimensionless enthalpies. 00236 * (length m_kk). 00237 * @param s_R Vector of Dimensionless entropies. 00238 * (length m_kk). 00239 */ 00240 virtual void update_one(int k, doublereal t, doublereal* cp_R, 00241 doublereal* h_RT, doublereal* s_R) const { 00242 doublereal logt = log(t); 00243 doublereal rt = 1.0/t; 00244 int loc = m_loc[k]; 00245 cp_R[k] = m_cp0_R[loc]; 00246 h_RT[k] = rt*(m_h0_R[loc] + (t - m_t0[loc]) * m_cp0_R[loc]); 00247 s_R[k] = m_s0_R[loc] + m_cp0_R[loc] * (logt - m_logt0[loc]); 00248 } 00249 00250 //! Minimum temperature. 00251 /*! 00252 * If no argument is supplied, this 00253 * method returns the minimum temperature for which \e all 00254 * parameterizations are valid. If an integer index k is 00255 * supplied, then the value returned is the minimum 00256 * temperature for species k in the phase. 00257 * 00258 * @param k Species index 00259 */ 00260 virtual doublereal minTemp(int k=-1) const { 00261 if (k < 0) 00262 return m_tlow_max; 00263 else 00264 return m_tlow[m_loc[k]]; 00265 } 00266 00267 //! Maximum temperature. 00268 /*! 00269 * If no argument is supplied, this 00270 * method returns the maximum temperature for which \e all 00271 * parameterizations are valid. If an integer index k is 00272 * supplied, then the value returned is the maximum 00273 * temperature for parameterization k. 00274 * 00275 * @param k Species Index 00276 */ 00277 virtual doublereal maxTemp(int k=-1) const { 00278 if (k < 0) 00279 return m_thigh_min; 00280 else 00281 return m_thigh[m_loc[k]]; 00282 } 00283 00284 //! The reference-state pressure for species k. 00285 /*! 00286 * 00287 * returns the reference state pressure in Pascals for 00288 * species k. If k is left out of the argument list, 00289 * it returns the reference state pressure for the first 00290 * species. 00291 * Note that some SpeciesThermo implementations, such 00292 * as those for ideal gases, require that all species 00293 * in the same phase have the same reference state pressures. 00294 * 00295 * @param k Species Index 00296 */ 00297 virtual doublereal refPressure(int k=-1) const {return m_p0;} 00298 00299 //! This utility function reports the type of parameterization 00300 //! used for the species with index number index. 00301 /*! 00302 * 00303 * @param index Species index 00304 */ 00305 virtual int reportType(int index) const { return SIMPLE; } 00306 00307 /*! 00308 * This utility function reports back the type of 00309 * parameterization and all of the parameters for the 00310 * species, index. 00311 * 00312 * @param index Species index 00313 * @param type Integer type of the standard type 00314 * @param c Vector of coefficients used to set the 00315 * parameters for the standard state. 00316 * For the SimpleThermo object, there are 4 coefficients. 00317 * @param minTemp output - Minimum temperature 00318 * @param maxTemp output - Maximum temperature 00319 * @param refPressure output - reference pressure (Pa). 00320 * 00321 */ 00322 virtual void reportParams(int index, int &type, 00323 doublereal * const c, 00324 doublereal &minTemp, 00325 doublereal &maxTemp, 00326 doublereal &refPressure) const { 00327 type = reportType(index); 00328 int loc = m_loc[index]; 00329 if (type == SIMPLE) { 00330 c[0] = m_t0[loc]; 00331 c[1] = m_h0_R[loc] * GasConstant; 00332 c[2] = m_s0_R[loc] * GasConstant; 00333 c[3] = m_cp0_R[loc] * GasConstant; 00334 minTemp = m_tlow[loc]; 00335 maxTemp = m_thigh[loc]; 00336 refPressure = m_p0; 00337 } 00338 } 00339 00340 //! Modify parameters for the standard state 00341 /*! 00342 * The thermo parameterization for a single species is overwritten. 00343 * 00344 * @param index Species index 00345 * @param c Vector of coefficients used to set the 00346 * parameters for the standard state. 00347 * Must be length >= 4. 00348 */ 00349 virtual void modifyParams(int index, doublereal *c) { 00350 int loc = m_loc[index]; 00351 if (loc < 0) { 00352 throw CanteraError("SimpleThermo::modifyParams", 00353 "modifying parameters for species which hasn't been set yet"); 00354 } 00355 /* 00356 * Change the data 00357 */ 00358 m_t0[loc] = c[0]; 00359 m_h0_R[loc] = c[1] / GasConstant; 00360 m_s0_R[loc] = c[2] / GasConstant; 00361 m_cp0_R[loc] = c[3] / GasConstant; 00362 } 00363 00364 #ifdef H298MODIFY_CAPABILITY 00365 00366 virtual doublereal reportOneHf298(int k) const { 00367 throw CanteraError("reportHF298", "unimplemented"); 00368 } 00369 00370 virtual void modifyOneHf298(const int k, const doublereal Hf298New) { 00371 throw CanteraError("reportHF298", "unimplemented"); 00372 } 00373 00374 00375 #endif 00376 protected: 00377 00378 //! Mapping between the species index and the vector index where the coefficients are kept 00379 /*! 00380 * This object doesn't have a one-to one correspondence between the species index, kspec, 00381 * and the data location index,indexData, m_cp0_R[indexData]. 00382 * This index keeps track of it. 00383 * indexData = m_loc[kspec] 00384 */ 00385 mutable map<int, int> m_loc; 00386 00387 //! Map between the vector index where the coefficients are kept and the species index 00388 /*! 00389 * Length is equal to the number of dataPoints. 00390 * kspec = m_index[indexData] 00391 */ 00392 vector_int m_index; 00393 00394 //! Maximum value of the low temperature limit 00395 doublereal m_tlow_max; 00396 00397 //! Minimum value of the high temperature limit 00398 doublereal m_thigh_min; 00399 00400 //! Vector of low temperature limits (species index) 00401 /*! 00402 * Length is equal to number of data points 00403 */ 00404 vector_fp m_tlow; 00405 00406 //! Vector of low temperature limits (species index) 00407 /*! 00408 * Length is equal to number of data points 00409 */ 00410 vector_fp m_thigh; 00411 00412 //! Vector of base temperatures (kelvin) 00413 /*! 00414 * Length is equal to the number of species data points 00415 */ 00416 vector_fp m_t0; 00417 00418 //! Vector of base log temperatures (kelvin) 00419 /*! 00420 * Length is equal to the number of species data points 00421 */ 00422 vector_fp m_logt0; 00423 00424 //! Vector of base dimensionless Enthalpies 00425 /*! 00426 * Length is equal to the number of species data points 00427 */ 00428 vector_fp m_h0_R; 00429 00430 //! Vector of base dimensionless Entropies 00431 /*! 00432 * Length is equal to the number of species data points 00433 */ 00434 vector_fp m_s0_R; 00435 00436 //! Vector of base dimensionless heat capacities 00437 /*! 00438 * Length is equal to the number of species data points 00439 */ 00440 vector_fp m_cp0_R; 00441 00442 //! Reference pressure (Pa) 00443 /*! 00444 * all species must have the same reference pressure. 00445 */ 00446 doublereal m_p0; 00447 00448 //! Number of species data points in the object. 00449 /*! 00450 * This is less than or equal to the number of species in the phase. 00451 */ 00452 int m_nspData; 00453 00454 }; 00455 00456 } 00457 00458 #endif