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.
This commit is contained in:
Harry Moffat 2008-09-25 19:42:05 +00:00
parent c884917c95
commit 595630e399
8 changed files with 166 additions and 94 deletions

View file

@ -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

View file

@ -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

View file

@ -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<string>::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<string>::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()

View file

@ -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<std::string> 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

View file

@ -617,6 +617,3 @@ namespace Cantera {
}
#endif

View file

@ -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() {

View file

@ -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() {

View file

@ -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);
}
/**