From 595630e399ffa0cb4c841068d9cdbf769c0f2571 Mon Sep 17 00:00:00 2001 From: Harry Moffat Date: Thu, 25 Sep 2008 19:42:05 +0000 Subject: [PATCH] Added the entropy of the stable state of each element at 298 and 1 bar, as another entry in the file elements.xml. Took this information out of PDSS_HKFT.cpp, where it was inappropriately cached. This information is needed for conversion of Gibbs free energies of formations for speices and the NIST chemical potential formulation where the DelH_f is set to zero. The Gibbs free energies of formation is the fundamental way EQ3 specifies the reference state chemical potential of a species. --- Cantera/src/thermo/Constituents.cpp | 5 + Cantera/src/thermo/Constituents.h | 6 + Cantera/src/thermo/Elements.cpp | 191 +++++++++++++++------------ Cantera/src/thermo/Elements.h | 27 +++- Cantera/src/thermo/PDSS.h | 3 - Cantera/src/thermo/PDSS_ConstVol.cpp | 4 + Cantera/src/thermo/PDSS_HKFT.cpp | 21 ++- Cantera/src/thermo/PDSS_IdealGas.cpp | 3 + 8 files changed, 166 insertions(+), 94 deletions(-) diff --git a/Cantera/src/thermo/Constituents.cpp b/Cantera/src/thermo/Constituents.cpp index b3c09d71e..d28836816 100755 --- a/Cantera/src/thermo/Constituents.cpp +++ b/Cantera/src/thermo/Constituents.cpp @@ -98,6 +98,11 @@ namespace Cantera { return m_Elements->atomicWeight(m); } + + doublereal Constituents::entropyElement298(int m) const { + return m_Elements->entropyElement298(m); + } + /** * returns a reference to the vector of atomic weights pertinent * to this constituents object diff --git a/Cantera/src/thermo/Constituents.h b/Cantera/src/thermo/Constituents.h index dd3286765..e7ba28f53 100755 --- a/Cantera/src/thermo/Constituents.h +++ b/Cantera/src/thermo/Constituents.h @@ -130,6 +130,12 @@ namespace Cantera { */ doublereal atomicWeight(int m) const; + /// Entropy of the element in its standard state at 298 K and 1 bar + /*! + * @param m Element index + */ + doublereal entropyElement298(int m) const; + /// Atomic number of element m. /*! * @param m Element index diff --git a/Cantera/src/thermo/Elements.cpp b/Cantera/src/thermo/Elements.cpp index 221db2740..f4da84902 100644 --- a/Cantera/src/thermo/Elements.cpp +++ b/Cantera/src/thermo/Elements.cpp @@ -301,9 +301,19 @@ namespace Cantera { if (m >= 0 && m < nElements()) return m_elementNames[m]; else - throw ElementRangeError("Elements::elementName",m,nElements()); + throw ElementRangeError("Elements::elementName", m, nElements()); } - + + + + doublereal Elements::entropyElement298(int m) const { + AssertThrowMsg(m_entropy298[m] != ENTROPY298_UNKNOWN, + "Elements::entropy298", + "Entropy at 298 K of element is unknown"); + AssertTrace(m >= 0 && m < m_mm); + return (m_entropy298[m]); + } + /* * * Add an element to the current set of elements in the current object. @@ -345,93 +355,96 @@ namespace Cantera { addElement(symbol, weight); } - /* - * addUniqueElement(): - * - * Add a unique element to the set. This routine will not allow - * duplicate elements to be input. - * - * @param symbol symbol string - * @param weight atomic weight in kg/kmol. - * - * - * The default weight is a special value, which will cause the - * routine to look up the actual weight via a string lookup. - */ + /* + * addUniqueElement(): + * + * Add a unique element to the set. This routine will not allow + * duplicate elements to be input. + * + * @param symbol symbol string + * @param weight atomic weight in kg/kmol. + * + * + * The default weight is a special value, which will cause the + * routine to look up the actual weight via a string lookup. + */ #ifdef USE_DGG_CODE - void Elements:: - addUniqueElement(const std::string& symbol, doublereal weight, int atomicNumber) - { - if (m_elementsFrozen) - throw ElementsFrozen("addElement"); + void Elements:: + addUniqueElement(const std::string& symbol, doublereal weight, int atomicNumber, + doublereal entropy298) + { + if (m_elementsFrozen) + throw ElementsFrozen("addElement"); - if (weight == -12345.0) { - weight = LookupWtElements(symbol); - } - - /* - * First decide if this element has been previously added. - * If it unique, add it to the list. - */ - - int i = m_definedElements[symbol] - 1; - if (i < 0) { - m_atomicWeights.push_back(weight); - m_elementNames.push_back(symbol); - m_atomicNumbers.push_back(atomicNumber); - m_mm++; - } - else { - if (m_atomicWeights[i] != weight) { - throw CanteraError("AddUniqueElement", - "Duplicate Elements (" + symbol + - ") have different weights"); - } - } + if (weight == -12345.0) { + weight = LookupWtElements(symbol); } + /* + * First decide if this element has been previously added. + * If it unique, add it to the list. + */ + + int i = m_definedElements[symbol] - 1; + if (i < 0) { + m_atomicWeights.push_back(weight); + m_elementNames.push_back(symbol); + m_atomicNumbers.push_back(atomicNumber); + m_entropy298.push_back(entropy298); + m_mm++; + } + else { + if (m_atomicWeights[i] != weight) { + throw CanteraError("AddUniqueElement", + "Duplicate Elements (" + symbol + + ") have different weights"); + } + } + } + #else - void Elements:: - addUniqueElement(const std::string& symbol, - doublereal weight, int atomicNumber) - { - if (weight == -12345.0) { - weight = LookupWtElements(symbol); - if (weight < 0.0) { - throw ElementsFrozen("addElement"); - } - } - /* - * First decide if this element has been previously added - * by conducting a string search. If it unique, add it to - * the list. - */ - int ifound = 0; - int i = 0; - for (vector::const_iterator it = m_elementNames.begin(); - it < m_elementNames.end(); ++it, ++i) { - if (*it == symbol) { - ifound = 1; - break; - } - } - if (!ifound) { - if (m_elementsFrozen) { - throw ElementsFrozen("addElement"); - return; - } - m_atomicWeights.push_back(weight); - m_elementNames.push_back(symbol); - m_atomicNumbers.push_back(atomicNumber); - m_mm++; - } else { - if (m_atomicWeights[i] != weight) { - throw CanteraError("AddUniqueElement", - "Duplicate Elements (" + symbol + - ") have different weights"); - } + void Elements:: + addUniqueElement(const std::string& symbol, + doublereal weight, int atomicNumber, doublereal entropy298) + { + if (weight == -12345.0) { + weight = LookupWtElements(symbol); + if (weight < 0.0) { + throw ElementsFrozen("addElement"); } } + /* + * First decide if this element has been previously added + * by conducting a string search. If it unique, add it to + * the list. + */ + int ifound = 0; + int i = 0; + for (vector::const_iterator it = m_elementNames.begin(); + it < m_elementNames.end(); ++it, ++i) { + if (*it == symbol) { + ifound = 1; + break; + } + } + if (!ifound) { + if (m_elementsFrozen) { + throw ElementsFrozen("addElement"); + return; + } + m_atomicWeights.push_back(weight); + m_elementNames.push_back(symbol); + m_atomicNumbers.push_back(atomicNumber); + m_entropy298.push_back(entropy298); + m_mm++; + } else { + if (m_atomicWeights[i] != weight) { + throw CanteraError("AddUniqueElement", + "Duplicate Elements (" + symbol + + ") have different weights"); + } + } + } #endif @@ -448,11 +461,19 @@ namespace Cantera { if (e.hasAttrib("atomicNumber")) anum = atoi(stripws(e["atomicNumber"]).c_str()); string symbol = e["name"]; - if (weight != 0.0) - addUniqueElement(symbol, weight, anum); - else + doublereal entropy298 = ENTROPY298_UNKNOWN; + if (e.hasChild("entropy298")) { + XML_Node& e298Node = e.child("entropy298"); + if (e298Node.hasAttrib("value")) { + entropy298 = atofCheck(stripws(e298Node["value"]).c_str()); + } + } + if (weight != 0.0) { + addUniqueElement(symbol, weight, anum, entropy298); + } else { addUniqueElement(symbol); } + } /* * clear() diff --git a/Cantera/src/thermo/Elements.h b/Cantera/src/thermo/Elements.h index 9cf2381c4..4dbc7c7e4 100644 --- a/Cantera/src/thermo/Elements.h +++ b/Cantera/src/thermo/Elements.h @@ -19,14 +19,18 @@ #undef USE_DGG_CODE #include "ct_defs.h" -//#include "ctexceptions.h" + namespace Cantera { class XML_Node; class ElementRangeError; - + //! Positive number indicating we don't know the gibbs free energy + //! of the element in its most stable state at 298.15 K and 1 bar. + //#define GIBSSFE298_UNKNOWN 123456789. +#define ENTROPY298_UNKNOWN -123456789. + //! Object containing the elements that make up species in a phase. /*! * Class %Elements manages the elements that are part of a @@ -69,6 +73,14 @@ namespace Cantera { */ int atomicNumber(int m) const { return m_atomicNumbers[m]; } + + //! Entropy at 298.15 K and 1 bar of stable state + //! of the element + /*! + * units J kmol-1 K-1 + */ + doublereal entropyElement298(int m) const; + /// vector of element atomic weights const vector_fp& atomicWeights() const { return m_atomicWeights; } @@ -142,7 +154,8 @@ namespace Cantera { * @param atomicNumber defaults to 0 */ void addUniqueElement(const std::string& symbol, - doublereal weight = -12345.0, int atomicNumber = 0); + doublereal weight = -12345.0, int atomicNumber = 0, + doublereal entropy298 = ENTROPY298_UNKNOWN); //! Add an element to the current set of elements in the current object. /*! @@ -241,7 +254,13 @@ namespace Cantera { */ std::vector m_elementNames; - /** + //! Entropy at 298.15 K and 1 bar of stable state + /*! + * units J kmol-1 + */ + vector_fp m_entropy298; + + /** * Number of Constituents Objects that use this object * * Number of Constituents Objects that require this Elements object diff --git a/Cantera/src/thermo/PDSS.h b/Cantera/src/thermo/PDSS.h index f27dacf98..33e3b2fe0 100644 --- a/Cantera/src/thermo/PDSS.h +++ b/Cantera/src/thermo/PDSS.h @@ -617,6 +617,3 @@ namespace Cantera { } #endif - - - diff --git a/Cantera/src/thermo/PDSS_ConstVol.cpp b/Cantera/src/thermo/PDSS_ConstVol.cpp index dc9f334f7..99de493ea 100644 --- a/Cantera/src/thermo/PDSS_ConstVol.cpp +++ b/Cantera/src/thermo/PDSS_ConstVol.cpp @@ -181,6 +181,10 @@ namespace Cantera { void PDSS_ConstVol::initThermoXML(const XML_Node& phaseNode, std::string& id) { PDSS::initThermoXML(phaseNode, id); + m_minTemp = m_spthermo->minTemp(m_spindex); + m_maxTemp = m_spthermo->maxTemp(m_spindex); + m_p0 = m_spthermo->refPressure(m_spindex); + m_mw = m_tp->molecularWeight(m_spindex); } void PDSS_ConstVol::initThermo() { diff --git a/Cantera/src/thermo/PDSS_HKFT.cpp b/Cantera/src/thermo/PDSS_HKFT.cpp index 710cbbc1a..2bb0a486b 100644 --- a/Cantera/src/thermo/PDSS_HKFT.cpp +++ b/Cantera/src/thermo/PDSS_HKFT.cpp @@ -7,6 +7,7 @@ #include "PDSS_HKFT.h" #include "WaterProps.h" #include "PDSS_Water.h" +#include "Elements.h" #include "VPStandardStateTP.h" @@ -893,7 +894,7 @@ namespace Cantera { } - +#ifdef OLDWAY /* awData structure */ /** @@ -920,6 +921,7 @@ namespace Cantera { /*! * all units are Joules kmol-1 */ + static struct GeData geDataTable[] = { {"H", -19.48112E6}, // NIST Webbook - Cox, Wagman 1984 {"Na", -15.29509E6}, // NIST Webbook - Cox, Wagman 1984 @@ -930,9 +932,10 @@ namespace Cantera { {"S", -9.55690E6}, // Yellow - webbook {"Al", -8.42870E6}, // Webbook polynomial {"K", -19.26943E6}, // Webbook + {"Fe", -8.142476E6}, // Nist Webbook - Cox, Wagman 1984 {"E", 0.0} // Don't overcount }; - +#endif //! Static function to look up Element Free Energies /*! * @@ -949,6 +952,7 @@ namespace Cantera { * If a match is not found, a CanteraError is thrown as well */ double PDSS_HKFT::LookupGe(const std::string& s) { +#ifdef OLDWAY int num = sizeof(geDataTable) / sizeof(struct GeData); string s3 = s.substr(0,3); for (int i = 0; i < num; i++) { @@ -959,6 +963,19 @@ namespace Cantera { } throw CanteraError("LookupGe", "element " + s + " not found"); return -1.0; +#else + int iE = m_tp->elementIndex(s); + if (iE < 0) { + throw CanteraError("PDSS_HKFT::LookupGe", "element " + s + " not found"); + } + doublereal geValue = m_tp->entropyElement298(iE); + if (geValue == ENTROPY298_UNKNOWN) { + throw CanteraError("PDSS_HKFT::LookupGe", + "element " + s + " doesn not have a supplied entropy298"); + } + geValue *= (-298.15); + return geValue; +#endif } void PDSS_HKFT::convertDGFormation() { diff --git a/Cantera/src/thermo/PDSS_IdealGas.cpp b/Cantera/src/thermo/PDSS_IdealGas.cpp index baab1e084..7bfd7438e 100644 --- a/Cantera/src/thermo/PDSS_IdealGas.cpp +++ b/Cantera/src/thermo/PDSS_IdealGas.cpp @@ -149,6 +149,9 @@ namespace Cantera { PDSS::initThermo(); SpeciesThermo &sp = m_tp->speciesThermo(); m_p0 = sp.refPressure(m_spindex); + m_minTemp = m_spthermo->minTemp(m_spindex); + m_maxTemp = m_spthermo->maxTemp(m_spindex); + m_mw = m_tp->molecularWeight(m_spindex); } /**