Nasa9PolyMultiTempRegion.cpp

Go to the documentation of this file.
00001 /**
00002  *  @file Nasa9PolyMultiTempRegion.cpp
00003  *  Definitions for a single-species standard state object derived
00004  *  from \link Cantera::SpeciesThermoInterpType 
00005  *    SpeciesThermoInterpType\endlink  based 
00006  *  on the NASA 9 coefficient temperature polynomial form 
00007  *  applied to one temperature region
00008  *  (see \ref spthermo and class 
00009  *   \link Cantera::Nasa9Poly1 Nasa9Poly1\endlink).
00010  *
00011  *  This parameterization has one NASA temperature region.
00012  */
00013 
00014 /* $Author: hkmoffa $
00015  * $Revision: 279 $
00016  * $Date: 2009-12-05 14:08:43 -0500 (Sat, 05 Dec 2009) $
00017  */
00018 // Copyright 2007  Sandia National Laboratories
00019 
00020 #include "global.h"
00021 #include "ctexceptions.h"
00022 #include "Nasa9PolyMultiTempRegion.h"
00023 
00024 using namespace std;
00025 
00026 namespace Cantera {
00027  
00028   // The NASA 9 polynomial parameterization for a single species
00029   // encompassing multiple temperature regions.
00030   /*
00031    *  This parameterization expresses the heat capacity via a
00032    *  7 coefficient polynomial.
00033    *  Note that this is the form used in the
00034    *  2002 NASA equilibrium program. A reference to the form is
00035    *  provided below:
00036    *
00037    *  "NASA Glenn Coefficients for Calculating Thermodynamic
00038    *  Properties of Individual Species,"
00039    *  B. J. McBride, M. J. Zehe, S. Gordon
00040    *  NASA/TP-2002-211556, Sept. 2002
00041    *
00042    * Nine coefficients \f$(a_0,\dots,a_6)\f$ are used to represent
00043    * \f$ C_p^0(T)\f$, \f$ H^0(T)\f$, and \f$ S^0(T) \f$ as 
00044    * polynomials in \f$ T \f$ :  
00045    * \f[
00046    * \frac{c_p(T)}{R} = a_0 T^{-2} + a_1 T^{-1} + a_2 + a_3 T 
00047    *                  + a_4 T^2 + a_5 T^3 + a_6 T^4
00048    * \f]
00049    * 
00050    * \f[
00051    * \frac{H^0(T)}{RT} = - a_0 T^{-2} + a_1 \frac{\ln(T)}{T} + a_2 
00052    * + a_3 T + a_4 T^2  + a_5 T^3 + a_6 T^4 + \frac{a_7}{T}
00053    * \f]
00054    *
00055    * \f[
00056    * \frac{s^0(T)}{R} = - \frac{a_0}{2} T^{-2} - a_1 T^{-1} + a_2 \ln(T)
00057    +    + a_3 T  \frac{a_4}{2} T^2 + \frac{a_5}{3} T^3  
00058    *    + \frac{a_6}{4} T^4 + a_8 
00059    * \f]
00060    * 
00061    *  The standard state is assumed to be an ideal gas at the
00062    *  standard pressure of 1 bar, for gases.
00063    *  For condensed species, the standard state is the
00064    *  pure crystalline or liquid substance at the standard
00065    *  pressure of 1 atm.
00066    *
00067    * These NASA representations may have multiple temperature regions
00068    * through the use of this %Nasa9PolyMultiTempRegion object, which uses
00069    * multiple copies of the Nasa9Poly1 object to handle multiple temperature
00070    * regions.
00071    *
00072    * @ingroup spthermo
00073    */
00074  
00075 
00076   //! Empty constructor
00077   Nasa9PolyMultiTempRegion::Nasa9PolyMultiTempRegion() :
00078     m_lowT(0.0),
00079     m_highT (0.0),
00080     m_Pref(0.0),
00081     m_index (0), 
00082     m_numTempRegions(0),
00083     m_currRegion(0)
00084   {
00085   }
00086 
00087 
00088   // Constructor used in templated instantiations
00089   /*
00090    * @param regionPts Vector of pointers to Nasa9Poly1 objects. These
00091    *                  objects all refer to the temperature regions for the
00092    *                  same species. The vector must be in increasing
00093    *                  temperature region format.  Together they
00094    *                  represent the reference temperature parameterization
00095    *                  for a single species.
00096    */
00097   Nasa9PolyMultiTempRegion::
00098   Nasa9PolyMultiTempRegion(std::vector<Cantera::Nasa9Poly1 *> &regionPts) :
00099     m_lowT(0.0),
00100     m_highT (0.0),
00101     m_Pref(0.0), 
00102     m_index(0),
00103     m_numTempRegions(0),
00104     m_currRegion(0)
00105   {
00106     m_numTempRegions = regionPts.size();
00107     // Do a shallow copy of the pointers. From now on, we will
00108     // own these pointers and be responsible for deleting them.
00109     m_regionPts = regionPts;
00110     m_lowerTempBounds.resize(m_numTempRegions);
00111     m_lowT = m_regionPts[0]->minTemp();
00112     m_highT = m_regionPts[m_numTempRegions-1]->maxTemp();
00113     m_Pref = m_regionPts[0]->refPressure();
00114     m_index = m_regionPts[0]->speciesIndex();
00115     for (int i = 0; i < m_numTempRegions; i++) {
00116       m_lowerTempBounds[i] = m_regionPts[i]->minTemp();
00117       if (m_regionPts[i]->speciesIndex() != m_index) {
00118         throw CanteraError("Nasa9PolyMultiTempRegion::Nasa9PolyMultiTempRegion",
00119                            "m_index inconsistency");
00120       }
00121       if (fabs(m_regionPts[i]->refPressure() - m_Pref) > 0.0001) {
00122         throw CanteraError("Nasa9PolyMultiTempRegion::Nasa9PolyMultiTempRegion",
00123                            "refPressure inconsistency");
00124       }
00125       if (i > 0) {
00126         if (m_lowerTempBounds[i-1] >= m_lowerTempBounds[i]) {
00127           throw CanteraError("Nasa9PolyMultiTempRegion::Nasa9PolyMultiTempRegion",
00128                              "minTemp bounds inconsistency");
00129         }
00130         if (fabs(m_regionPts[i-1]->maxTemp() - m_lowerTempBounds[i]) > 0.0001) {
00131           throw CanteraError("Nasa9PolyMultiTempRegion::Nasa9PolyMultiTempRegion",
00132                              "Temp bounds inconsistency");
00133         }
00134       }
00135     }
00136   }
00137 
00138   // copy constructor
00139   /*
00140    * @param b object to be copied
00141    */
00142   Nasa9PolyMultiTempRegion::
00143   Nasa9PolyMultiTempRegion(const Nasa9PolyMultiTempRegion& b) :
00144     m_lowT      (b.m_lowT),
00145     m_highT     (b.m_highT),
00146     m_Pref      (b.m_Pref),
00147     m_index     (b.m_index),
00148     m_numTempRegions(b.m_numTempRegions),
00149     m_lowerTempBounds (b.m_lowerTempBounds),
00150     m_currRegion(b.m_currRegion)
00151   {
00152     m_regionPts.resize(m_numTempRegions);
00153     for (int i = 0; i < m_numTempRegions; i++) {
00154       Nasa9Poly1 * dptr = b.m_regionPts[i];
00155       m_regionPts[i] = new Nasa9Poly1(*dptr);
00156     }
00157   }
00158 
00159   // assignment operator
00160   /*
00161    * @param b object to be copied
00162    */
00163   Nasa9PolyMultiTempRegion& 
00164   Nasa9PolyMultiTempRegion::operator=(const Nasa9PolyMultiTempRegion& b) {
00165     if (&b != this) {
00166       for (int i = 0; i < m_numTempRegions; i++) {
00167         delete m_regionPts[i];
00168         m_regionPts[i] = 0;
00169       }
00170       m_lowT   = b.m_lowT;
00171       m_highT  = b.m_highT;
00172       m_Pref   = b.m_Pref;
00173       m_index  = b.m_index;
00174       m_numTempRegions = b.m_numTempRegions;
00175       m_lowerTempBounds = b.m_lowerTempBounds;
00176       m_currRegion = b.m_currRegion;
00177       m_regionPts.resize(m_numTempRegions);
00178       for (int i = 0; i < m_numTempRegions; i++) {
00179         m_regionPts[i] = new Nasa9Poly1(*(b.m_regionPts[i]));
00180       }
00181     }
00182     return *this;
00183   }
00184 
00185   // Destructor
00186   Nasa9PolyMultiTempRegion::~Nasa9PolyMultiTempRegion() {
00187     for (int i = 0; i < m_numTempRegions; i++) {
00188       delete m_regionPts[i];
00189       m_regionPts[i] = 0;
00190     }
00191   }
00192 
00193   // duplicator
00194   SpeciesThermoInterpType *
00195   Nasa9PolyMultiTempRegion::duplMyselfAsSpeciesThermoInterpType() const {
00196     Nasa9PolyMultiTempRegion* np = new Nasa9PolyMultiTempRegion(*this);
00197     return (SpeciesThermoInterpType *) np;
00198   }
00199 
00200   // Returns the minimum temperature that the thermo
00201   // parameterization is valid
00202   doublereal Nasa9PolyMultiTempRegion::minTemp() const { 
00203     return m_lowT;
00204   }
00205 
00206   // Returns the maximum temperature that the thermo
00207   // parameterization is valid
00208   doublereal Nasa9PolyMultiTempRegion::maxTemp() const  { 
00209     return m_highT;
00210   }
00211 
00212   // Returns the reference pressure (Pa)
00213   doublereal Nasa9PolyMultiTempRegion::refPressure() const { 
00214     return m_Pref; 
00215   }
00216 
00217   // Returns an integer representing the type of parameterization
00218   int Nasa9PolyMultiTempRegion::reportType() const { 
00219     return NASA9MULTITEMP;
00220   }
00221 
00222      
00223   // Returns an integer representing the species index
00224   int Nasa9PolyMultiTempRegion::speciesIndex() const { 
00225     return m_index;
00226   }
00227       
00228  
00229   // Update the properties for this species, given a temperature polynomial
00230   /*
00231    * This method is called with a pointer to an array containing the functions of
00232    * temperature needed by this  parameterization, and three pointers to arrays where the
00233    * computed property values should be written. This method updates only one value in
00234    * each array.
00235    *
00236    * Temperature Polynomial:
00237    *  tt[0] = t;
00238    *  tt[1] = t*t;
00239    *  tt[2] = t*t*t;
00240    *  tt[3] = t*t*t*t;
00241    *  tt[4] = 1.0/t;
00242    *  tt[5] = 1.0/(t*t);
00243    *  tt[6] = std::log(t);
00244    *
00245    * @param tt      vector of temperature polynomials
00246    * @param cp_R    Vector of Dimensionless heat capacities.
00247    *                (length m_kk).
00248    * @param h_RT    Vector of Dimensionless enthalpies.
00249    *                (length m_kk).
00250    * @param s_R     Vector of Dimensionless entropies.
00251    *                (length m_kk).
00252    */
00253   void Nasa9PolyMultiTempRegion::updateProperties(const doublereal* tt, 
00254                                                   doublereal* cp_R,
00255                                                   doublereal* h_RT,
00256                                                   doublereal* s_R) const {
00257     // Let's put some additional debugging here.
00258     // This is an external routine
00259 #ifdef DEBUG_HKM
00260     double temp = tt[0];
00261     if (temp < m_regionPts[m_currRegion]->minTemp() ) {
00262       if (m_currRegion != 0) {
00263         throw CanteraError("Nasa9PolyMultiTempRegion::updateProperties",
00264                            "region problem");
00265       }
00266     }
00267     if (temp > m_regionPts[m_currRegion]->maxTemp() ) {
00268       if (m_currRegion != m_numTempRegions - 1) {
00269         throw CanteraError("Nasa9PolyMultiTempRegion::updateProperties",
00270                            "region problem");
00271       }
00272     }
00273 #endif
00274     (m_regionPts[m_currRegion])->updateProperties(tt, cp_R, h_RT, s_R);
00275   }
00276 
00277  
00278   // Compute the reference-state property of one species
00279   /*
00280    * Given temperature T in K, this method updates the values of
00281    * the non-dimensional heat capacity at constant pressure,
00282    * enthalpy, and entropy, at the reference pressure, Pref
00283    * of one of the species. The species index is used
00284    * to reference into the cp_R, h_RT, and s_R arrays.
00285    *
00286    * Temperature Polynomial:
00287    *  tt[0] = t;
00288    *  tt[1] = t*t;
00289    *  tt[2] = t*t*t;
00290    *  tt[3] = t*t*t*t;
00291    *  tt[4] = 1.0/t;
00292    *  tt[5] = 1.0/(t*t);
00293    *  tt[6] = std::log(t);
00294    *
00295    * @param temp    Temperature (Kelvin)
00296    * @param cp_R    Vector of Dimensionless heat capacities.
00297    *                (length m_kk).
00298    * @param h_RT    Vector of Dimensionless enthalpies.
00299    *                (length m_kk).
00300    * @param s_R     Vector of Dimensionless entropies.
00301    *                (length m_kk).
00302    */
00303   void Nasa9PolyMultiTempRegion::updatePropertiesTemp(const doublereal temp, 
00304                                         doublereal* cp_R, doublereal* h_RT, 
00305                                         doublereal* s_R) const {
00306     double tPoly[7];
00307     tPoly[0]  = temp;
00308     tPoly[1]  = temp * temp;
00309     tPoly[2]  = tPoly[1] * temp;
00310     tPoly[3]  = tPoly[2] * temp;
00311     tPoly[4]  = 1.0 / temp;
00312     tPoly[5]  = tPoly[4] / temp;
00313     tPoly[6]  = std::log(temp);
00314     // Now find the region
00315     m_currRegion = 0;
00316     for (int i = 1; i < m_numTempRegions; i++) {
00317       if (temp < m_lowerTempBounds[i]) {
00318         break;
00319       }
00320       m_currRegion++;
00321     }
00322 
00323     updateProperties(tPoly, cp_R, h_RT, s_R);
00324   }
00325 
00326   //This utility function reports back the type of 
00327   // parameterization and all of the parameters for the 
00328   // species, index.
00329   /*
00330    * All parameters are output variables
00331    *
00332    * @param n         Species index
00333    * @param type      Integer type of the standard type
00334    * @param tlow      output - Minimum temperature
00335    * @param thigh     output - Maximum temperature
00336    * @param pref      output - reference pressure (Pa).
00337    * @param coeffs    Vector of coefficients used to set the
00338    *                  parameters for the standard state.
00339    */
00340   void Nasa9PolyMultiTempRegion::reportParameters(int &n, int &type,
00341                                     doublereal &tlow, doublereal &thigh,
00342                                     doublereal &pref,
00343                                     doublereal* const coeffs) const {
00344     n = m_index;
00345     type = NASA9MULTITEMP;
00346     tlow = m_lowT;
00347     thigh = m_highT;
00348     pref = m_Pref;
00349     double ctmp[12];
00350     coeffs[0] = m_numTempRegions;
00351     int index = 1;
00352     int n_tmp = 0;;
00353     int type_tmp = 0;
00354     double pref_tmp = 0.0;
00355     for (int iReg = 0; iReg < m_numTempRegions; iReg++) {
00356       m_regionPts[iReg]->reportParameters(n_tmp, type_tmp,
00357                                           coeffs[index], coeffs[index+1],
00358                                           pref_tmp, ctmp);
00359       for (int i = 0; i < 9; i++) {
00360         coeffs[index+2+i] = ctmp[3+i];
00361       }
00362       index += 11;
00363     }
00364 
00365   }
00366 
00367   // Modify parameters for the standard state
00368   /*
00369    * @param coeffs   Vector of coefficients used to set the
00370    *                 parameters for the standard state.
00371    */
00372   void Nasa9PolyMultiTempRegion::modifyParameters(doublereal* coeffs) {
00373     int index = 3;
00374     for (int iReg = 0; iReg < m_numTempRegions; iReg++) {
00375       m_regionPts[iReg]->modifyParameters(coeffs + index);
00376       index += 11;
00377     }   
00378   }
00379 
00380 
00381 }
00382 
Generated by  doxygen 1.6.3