20 MaskellSolidSolnPhase::MaskellSolidSolnPhase() :
23 product_species_index(-1),
24 reactant_species_index(-1)
28 void MaskellSolidSolnPhase::getActivityConcentrations(doublereal* c)
const
30 getActivityCoefficients(c);
31 for (
size_t sp = 0; sp < m_kk; ++sp) {
32 c[sp] *= moleFraction(sp);
38 doublereal MaskellSolidSolnPhase::enthalpy_mole()
const
40 const doublereal h0 = RT() * mean_X(m_h0_RT);
41 const doublereal r = moleFraction(product_species_index);
42 const doublereal fmval = fm(r);
43 return h0 + r * fmval * h_mixing;
46 doublereal xlogx(doublereal x)
48 return x * std::log(x);
51 doublereal MaskellSolidSolnPhase::entropy_mole()
const
54 const doublereal r = moleFraction(product_species_index);
55 const doublereal fmval = fm(r);
56 const doublereal rfm = r * fmval;
57 return s0 +
GasConstant * (xlogx(1-rfm) - xlogx(rfm) - xlogx(1-r-rfm) - xlogx((1-fmval)*r) - xlogx(1-r) - xlogx(r));
62 void MaskellSolidSolnPhase::setDensity(
const doublereal rho)
68 "Overloaded function to be removed after Cantera 2.5. "
69 "Error will be thrown by Phase::setDensity instead");
70 double dens = density();
73 "Density is not an independent variable");
77 void MaskellSolidSolnPhase::calcDensity()
79 const vector_fp& vbar = getStandardVolumes();
82 Phase::getMoleFractions(&moleFracs[0]);
83 doublereal vtotal = 0.0;
84 for (
size_t i = 0; i < m_kk; i++) {
85 vtotal += vbar[i] * moleFracs[i];
87 Phase::assignDensity(meanMolecularWeight() / vtotal);
90 void MaskellSolidSolnPhase::setPressure(doublereal p)
95 void MaskellSolidSolnPhase::setMolarDensity(
const doublereal n)
98 "Overloaded function to be removed after Cantera 2.5. "
99 "Error will be thrown by Phase::setMolarDensity instead");
100 throw CanteraError(
"MaskellSolidSolnPhase::setMolarDensity",
101 "Density is not an independent variable");
106 void MaskellSolidSolnPhase::getActivityCoefficients(doublereal* ac)
const
108 static const int cacheId = m_cache.getId();
110 if (!cached.
validate(temperature(), pressure(), stateMFNumber())) {
111 cached.
value.resize(2);
113 const doublereal r = moleFraction(product_species_index);
114 const doublereal pval = p(r);
115 const doublereal rfm = r * fm(r);
116 const doublereal A = (std::pow(1 - rfm, pval) * std::pow(rfm, pval) * std::pow(r - rfm, 1 - pval)) /
117 (std::pow(1 - r - rfm, 1 + pval) * (1 - r));
118 const doublereal B = pval * h_mixing / RT();
119 cached.
value[product_species_index] = A * std::exp(B);
120 cached.
value[reactant_species_index] = 1 / (A * r * (1-r) ) * std::exp(-B);
122 std::copy(cached.
value.begin(), cached.
value.end(), ac);
125 void MaskellSolidSolnPhase::getChemPotentials(doublereal* mu)
const
127 const doublereal r = moleFraction(product_species_index);
128 const doublereal pval = p(r);
129 const doublereal rfm = r * fm(r);
130 const doublereal DgbarDr = pval * h_mixing +
132 std::log( (std::pow(1 - rfm, pval) * std::pow(rfm, pval) * std::pow(r - rfm, 1 - pval) * r) /
133 (std::pow(1 - r - rfm, 1 + pval) * (1 - r)) );
134 mu[product_species_index] = RT() * m_g0_RT[product_species_index] + DgbarDr;
135 mu[reactant_species_index] = RT() * m_g0_RT[reactant_species_index] - DgbarDr;
138 void MaskellSolidSolnPhase::getChemPotentials_RT(doublereal* mu)
const
140 getChemPotentials(mu);
141 for (
size_t sp=0; sp < m_kk; ++sp) {
142 mu[sp] *= 1.0 / RT();
148 void MaskellSolidSolnPhase::getPartialMolarEnthalpies(doublereal* hbar)
const
153 void MaskellSolidSolnPhase::getPartialMolarEntropies(doublereal* sbar)
const
158 void MaskellSolidSolnPhase::getPartialMolarCp(doublereal* cpbar)
const
163 void MaskellSolidSolnPhase::getPartialMolarVolumes(doublereal* vbar)
const
165 getStandardVolumes(vbar);
168 void MaskellSolidSolnPhase::getPureGibbs(doublereal* gpure)
const
170 for (
size_t sp=0; sp < m_kk; ++sp) {
171 gpure[sp] = RT() * m_g0_RT[sp];
175 void MaskellSolidSolnPhase::getStandardChemPotentials(doublereal* mu)
const
184 void MaskellSolidSolnPhase::initThermo()
186 if (m_input.hasKey(
"excess-enthalpy")) {
187 set_h_mix(m_input.convert(
"excess-enthalpy",
"J/kmol"));
189 if (m_input.hasKey(
"product-species")) {
190 setProductSpecies(m_input[
"product-species"].asString());
192 VPStandardStateTP::initThermo();
196 void MaskellSolidSolnPhase::initThermoXML(
XML_Node& phaseNode,
const std::string& id_)
198 if (id_.size() > 0 && phaseNode.
id() != id_) {
199 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
200 "phasenode and Id are incompatible");
208 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
209 "Unknown thermo model: " + thNode[
"model"]);
216 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
217 "Mixing enthalpy parameter not specified.");
220 if (thNode.
hasChild(
"product_species")) {
221 setProductSpecies(thNode.
child(
"product_species").
value());
223 setProductSpecies(speciesName(0));
226 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
227 "Unspecified thermo model");
232 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
233 "MaskellSolidSolution model requires exactly 2 species.");
237 VPStandardStateTP::initThermoXML(phaseNode, id_);
240 void MaskellSolidSolnPhase::setProductSpecies(
const std::string& name)
242 product_species_index =
static_cast<int>(speciesIndex(name));
243 if (product_species_index == -1) {
244 throw CanteraError(
"MaskellSolidSolnPhase::setProductSpecies",
245 "Species '{}' not found", name);
247 reactant_species_index = (product_species_index == 0) ? 1 : 0;
250 doublereal MaskellSolidSolnPhase::s()
const
252 return 1 + std::exp(h_mixing / RT());
255 doublereal MaskellSolidSolnPhase::fm(
const doublereal r)
const
257 return (1 - std::sqrt(1 - 4*r*(1-r)/s())) / (2*r);
260 doublereal MaskellSolidSolnPhase::p(
const doublereal r)
const
262 const doublereal sval = s();
263 return (1 - 2*r) / std::sqrt(sval*sval - 4 * sval * r + 4 * sval * r * r);
Header file for a solid solution model following Maskell, Shaw, and Tye.
Base class for exceptions thrown by Cantera classes.
An error indicating that an unimplemented function has been called.
Class XML_Node is a tree-based representation of the contents of an XML file.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
std::string id() const
Return the id attribute, if present.
std::string value() const
Return the value of an XML node as a string.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
const double OneAtm
One atmosphere [Pa].
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
const double GasConstant
Universal Gas Constant [J/kmol/K].
Namespace for the Cantera kernel.
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
Contains declarations for string manipulation functions within Cantera.
T value
The value of the cached property.
bool validate(double state1New)
Check whether the currently cached value is valid based on a single state variable.
Classes providing support for XML data files.