00001 /** 00002 * @file State.h Header for the class State, that manages the 00003 * independent variables of temperature, mass density, and species 00004 * mass/mole fraction that define the thermodynamic state (see \ref 00005 * phases and class \link Cantera::State State\endlink). 00006 */ 00007 00008 /* 00009 * $Date: 2009-12-09 12:29:23 -0500 (Wed, 09 Dec 2009) $ 00010 * $Revision: 306 $ 00011 * 00012 * Copyright 2001-2003 California Institute of Technology 00013 * See file License.txt for licensing information 00014 * 00015 */ 00016 00017 #ifndef CT_STATE2_H 00018 #define CT_STATE2_H 00019 00020 #include "ct_defs.h" 00021 #include "utilities.h" 00022 00023 #ifdef WIN32 00024 #pragma warning(disable:4996) 00025 #endif 00026 00027 namespace Cantera { 00028 00029 00030 //! Manages the independent variables of temperature, mass density, 00031 //! and species mass/mole fraction that define the thermodynamic 00032 //! state. 00033 /*! 00034 * Class State stores just enough information about a 00035 * multicomponent solution to specify its intensive thermodynamic 00036 * state. It stores values for the temperature, mass density, and 00037 * an array of species mass fractions. It also stores an array of 00038 * species molecular weights, which are used to convert between 00039 * mole and mass representations of the composition. These are the 00040 * \e only properties of the species that class State knows about. 00041 * For efficiency in mass/mole conversion, the vector of mass 00042 * fractions divided by molecular weight \f$ Y_k/M_k \f$ is also 00043 * stored. 00044 * 00045 * Class State is not usually used directly in application 00046 * programs. Its primary use is as a base class for class 00047 * Phase. Class State has no virtual methods, and none of its 00048 * methods are meant to be overloaded. However, this is one exception. 00049 * If the phase is incompressible, then the density must be replaced 00050 * by the pressure as the independent variable. In this case, functions 00051 * such as setMassFraction within the class %State must actually now 00052 * calculate the density (at constant T and P) instead of leaving 00053 * it alone as befits an independent variable. Threfore, these type 00054 * of functions are virtual functions and need to be overloaded 00055 * for incompressible phases. Note, for almost incompressible phases 00056 * (or phases which utilize standard states based on a T and P) this 00057 * may be advantageous as well, and they need to overload these functions 00058 * too. 00059 * 00060 * @ingroup phases 00061 */ 00062 class State { 00063 00064 public: 00065 00066 /** 00067 * Constructor. 00068 */ 00069 State(); 00070 00071 /** 00072 * Destructor. Since no memory is allocated by methods of this 00073 * class, the destructor does nothing. 00074 */ 00075 virtual ~State(); 00076 00077 /** 00078 * Copy Constructor for the State Class 00079 * 00080 * @param right Reference to the class to be copied. 00081 */ 00082 State(const State& right); 00083 00084 /** 00085 * Assignment operator for the state class. 00086 * 00087 * @param right Reference to the class to be copied. 00088 */ 00089 State& operator=(const State& right); 00090 00091 00092 /// @name Species Information 00093 /// 00094 /// The only thing class State knows about the species is their 00095 /// molecular weights. 00096 //@{ 00097 00098 /// Return a read-only reference to the array of molecular 00099 /// weights. 00100 const array_fp& molecularWeights() const { return m_molwts; } 00101 00102 00103 //@} 00104 /// @name Composition 00105 //@{ 00106 00107 00108 //! Get the species mole fraction vector. 00109 /*! 00110 * @param x On return, x contains the mole fractions. Must have a 00111 * length greater than or equal to the number of species. 00112 */ 00113 void getMoleFractions(doublereal* const x) const; 00114 00115 00116 //! The mole fraction of species k. 00117 /*! 00118 * If k is ouside the valid 00119 * range, an exception will be thrown. Note that it is 00120 * somewhat more efficent to call getMoleFractions if the 00121 * mole fractions of all species are desired. 00122 * @param k species index 00123 */ 00124 doublereal moleFraction(const int k) const; 00125 00126 00127 //! Set the mole fractions to the specified values, and then 00128 //! normalize them so that they sum to 1.0. 00129 /*! 00130 * @param x Array of unnormalized mole fraction values (input). 00131 * Must have a length greater than or equal to the number of 00132 * species. 00133 * 00134 * @param x Input vector of mole fractions. There is no restriction 00135 * on the sum of the mole fraction vector. Internally, 00136 * the State object will normalize this vector before 00137 * storring its contents. 00138 * Length is m_kk. 00139 */ 00140 virtual void setMoleFractions(const doublereal* const x); 00141 00142 /** 00143 * Set the mole fractions to the specified values without 00144 * normalizing. This is useful when the normalization 00145 * condition is being handled by some other means, for example 00146 * by a constraint equation as part of a larger set of 00147 * equations. 00148 * 00149 * @param x Input vector of mole fractions. 00150 * Length is m_kk. 00151 */ 00152 virtual void setMoleFractions_NoNorm(const doublereal* const x); 00153 00154 /** 00155 * Get the species mass fractions. 00156 * @param y On return, y 00157 * contains the mass fractions. Array \a y must have a length 00158 * greater than or equal to the number of species. 00159 * 00160 * @param y Output vector of mass fractions. 00161 * Length is m_kk. 00162 */ 00163 void getMassFractions(doublereal* const y) const; 00164 00165 //! Mass fraction of species k. 00166 /*! 00167 * If k is outside the valid 00168 * range, an exception will be thrown. Note that it is 00169 * somewhat more efficent to call getMassFractions if the 00170 * mass fractions of all species are desired. 00171 * 00172 * @param k species index 00173 */ 00174 doublereal massFraction(const int k) const; 00175 00176 /** 00177 * Set the mass fractions to the specified values, and then 00178 * normalize them so that they sum to 1.0. 00179 * @param y Array of unnormalized mass fraction values (input). 00180 * Must have a length greater than or equal to the number of 00181 * species. 00182 * 00183 * @param y Input vector of mass fractions. There is no restriction 00184 * on the sum of the mass fraction vector. Internally, 00185 * the State object will normalize this vector before 00186 * storring its contents. 00187 * Length is m_kk. 00188 */ 00189 virtual void setMassFractions(const doublereal* const y); 00190 00191 /** 00192 * Set the mass fractions to the specified values without 00193 * normalizing. This is useful when the normalization 00194 * condition is being handled by some other means, for example 00195 * by a constraint equation as part of a larger set of 00196 * equations. 00197 * 00198 * @param y Input vector of mass fractions. 00199 * Length is m_kk. 00200 */ 00201 virtual void setMassFractions_NoNorm(const doublereal* const y); 00202 00203 /** 00204 * Get the species concentrations (kmol/m^3). @param c On 00205 * return, \a c contains the concentrations for all species. 00206 * Array \a c must have a length greater than or equal to the 00207 * number of species. 00208 */ 00209 void getConcentrations(doublereal* const c) const; 00210 00211 /** 00212 * Concentration of species k. If k is outside the valid 00213 * range, an exception will be thrown. 00214 * 00215 * @param k Index of species 00216 */ 00217 doublereal concentration(const int k) const; 00218 00219 //! Set the concentrations to the specified values within the 00220 //! phase. 00221 /*! 00222 * We set the concentrations here and therefore we set the 00223 * overall density of the phase. We hold the temperature constant 00224 * during this operation. Therefore, we have possibly changed 00225 * the pressure of the phase by calling this routine. 00226 * 00227 * @param conc The input vector to this routine is in dimensional 00228 * units. For volumetric phases c[k] is the 00229 * concentration of the kth species in kmol/m3. 00230 * For surface phases, c[k] is the concentration 00231 * in kmol/m2. The length of the vector is the number 00232 * of species in the phase. 00233 */ 00234 virtual void setConcentrations(const doublereal* const conc); 00235 00236 //! Returns a read-only pointer to the start of the 00237 //! massFraction array 00238 /*! 00239 * The pointer returned is readonly 00240 * @return returns a pointer to a vector of doubles of length m_kk. 00241 */ 00242 const doublereal* massFractions() const { 00243 return &m_y[0]; 00244 } 00245 00246 /** 00247 * Returns a read-only pointer to the start of the 00248 * moleFraction/MW array. This array is the array of mole 00249 * fractions, each divided by the mean molecular weight. 00250 */ 00251 const doublereal* moleFractdivMMW() const; 00252 00253 //@} 00254 00255 /// @name Mean Properties 00256 //@{ 00257 /** 00258 * Evaluate the mole-fraction-weighted mean of Q: 00259 * \f[ \sum_k X_k Q_k. \f] 00260 * Array Q should contain pure-species molar property 00261 * values. 00262 * 00263 * @param Q input vector of length m_kk that is to be averaged. 00264 * @return 00265 * mole-freaction-weighted mean of Q 00266 */ 00267 doublereal mean_X(const doublereal* const Q) const; 00268 00269 /** 00270 * Evaluate the mass-fraction-weighted mean of Q: 00271 * \f[ \sum_k Y_k Q_k \f] 00272 * 00273 * @param Q Array Q contains a vector of species property values in mass units. 00274 * @return 00275 * Return value containing the mass-fraction-weighted mean of Q. 00276 */ 00277 doublereal mean_Y(const doublereal* const Q) const; 00278 00279 /** 00280 * The mean molecular weight. Units: (kg/kmol) 00281 */ 00282 doublereal meanMolecularWeight() const { 00283 return m_mmw; 00284 } 00285 00286 //! Evaluate \f$ \sum_k X_k \log X_k \f$. 00287 /*! 00288 * @return 00289 * returns the indicated sum. units are dimensionless. 00290 */ 00291 doublereal sum_xlogx() const; 00292 00293 //! Evaluate \f$ \sum_k X_k \log Q_k \f$. 00294 /*! 00295 * @param Q Vector of length m_kk to take the log average of 00296 * @return Returns the indicated sum. 00297 */ 00298 doublereal sum_xlogQ(doublereal* const Q) const; 00299 //@} 00300 00301 /// @name Thermodynamic Properties 00302 /// Class State only stores enough thermodynamic data to 00303 /// specify the state. In addition to composition information, 00304 /// it stores the temperature and 00305 /// mass density. 00306 //@{ 00307 00308 /// Temperature (K). 00309 doublereal temperature() const { 00310 return m_temp; 00311 } 00312 00313 /// Density (kg/m^3). 00314 virtual doublereal density() const { 00315 return m_dens; 00316 } 00317 00318 /// Molar density (kmol/m^3). 00319 doublereal molarDensity() const; 00320 00321 //! Set the internally storred density (kg/m^3) of the phase 00322 /*! 00323 * Note the density of a phase is an indepedent variable. 00324 * 00325 * @param density Input density (kg/m^3). 00326 */ 00327 virtual void setDensity(const doublereal density) { 00328 m_dens = density; 00329 } 00330 00331 //! Set the internally storred molar density (kmol/m^3) of the phase. 00332 /*! 00333 * @param molarDensity Input molar density (kmol/m^3). 00334 */ 00335 virtual void setMolarDensity(const doublereal molarDensity); 00336 00337 //! Set the temperature (K). 00338 /*! 00339 * This function sets the internally storred temperature of the phase. 00340 * 00341 * @param temp Temperature in kelvin 00342 */ 00343 virtual void setTemperature(const doublereal temp) { 00344 m_temp = temp; 00345 } 00346 //@} 00347 00348 //! True if the number species has been set 00349 bool ready() const; 00350 00351 //! Every time the mole fractions have changed, this routine 00352 //! will increment the stateMFNumber 00353 /*! 00354 * @param forceChange If this is true then the stateMFNumber always 00355 * changes. This defaults to false. 00356 */ 00357 void stateMFChangeCalc(bool forceChange = false); 00358 00359 //! Return the state number 00360 int stateMFNumber() const; 00361 00362 protected: 00363 00364 /** 00365 * @internal 00366 * Initialize. Make a local copy of the vector of 00367 * molecular weights, and resize the composition arrays to 00368 * the appropriate size. The only information an instance of 00369 * State has about the species is their molecular weights. 00370 * 00371 * @param mw Vector of molecular weights of the species. 00372 */ 00373 void init(const array_fp& mw); //, density_is_independent = true); 00374 00375 /** 00376 * m_kk is the number of species in the phase 00377 */ 00378 int m_kk; 00379 00380 //! Set the molecular weight of a single species to a given value 00381 /*! 00382 * @param k id of the species 00383 * @param mw Molecular Weight (kg kmol-1) 00384 */ 00385 void setMolecularWeight(const int k, const double mw) { 00386 m_molwts[k] = mw; 00387 m_rmolwts[k] = 1.0/mw; 00388 } 00389 00390 private: 00391 00392 /** 00393 * Temperature. This is an independent variable 00394 * units = Kelvin 00395 */ 00396 doublereal m_temp; 00397 00398 /** 00399 * Density. This is an independent variable except in 00400 * the incompressible degenerate case. Thus, 00401 * the pressure is determined from this variable 00402 * not the other way round. 00403 * units = kg m-3 00404 */ 00405 doublereal m_dens; 00406 00407 /** 00408 * m_mmw is the mean molecular weight of the mixture 00409 * (kg kmol-1) 00410 */ 00411 doublereal m_mmw; 00412 00413 /** 00414 * m_ym[k] = mole fraction of species k divided by the 00415 * mean molecular weight of mixture. 00416 */ 00417 mutable array_fp m_ym; 00418 00419 /** 00420 * m_y[k] = mass fraction of species k 00421 */ 00422 mutable array_fp m_y; 00423 00424 /** 00425 * m_molwts[k] = molecular weight of species k (kg kmol-1) 00426 */ 00427 array_fp m_molwts; 00428 00429 /** 00430 * m_rmolwts[k] = inverse of the molecular weight of species k 00431 * units = kmol kg-1. 00432 */ 00433 array_fp m_rmolwts; 00434 00435 //! State Change variable 00436 /*! 00437 * Whenever the mole fraction vector changes, this int is 00438 * incremented. 00439 */ 00440 int m_stateNum; 00441 00442 }; 00443 00444 //! Return the State Mole Fraction Number 00445 inline int State::stateMFNumber() const { 00446 return m_stateNum; 00447 } 00448 00449 } 00450 00451 #endif