20MaskellSolidSolnPhase::MaskellSolidSolnPhase() :
23 product_species_index(-1),
24 reactant_species_index(-1)
28void MaskellSolidSolnPhase::getActivityConcentrations(doublereal* c)
const
30 getActivityCoefficients(c);
31 for (
size_t sp = 0; sp < m_kk; ++sp) {
32 c[sp] *= moleFraction(sp);
38doublereal 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;
46doublereal xlogx(doublereal x)
48 return x * std::log(x);
51doublereal 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));
62void MaskellSolidSolnPhase::calcDensity()
64 const vector_fp& vbar = getStandardVolumes();
67 Phase::getMoleFractions(&moleFracs[0]);
68 doublereal vtotal = 0.0;
69 for (
size_t i = 0; i < m_kk; i++) {
70 vtotal += vbar[i] * moleFracs[i];
72 Phase::assignDensity(meanMolecularWeight() / vtotal);
75void MaskellSolidSolnPhase::setPressure(doublereal p)
82void MaskellSolidSolnPhase::getActivityCoefficients(doublereal* ac)
const
84 static const int cacheId = m_cache.getId();
86 if (!cached.
validate(temperature(), pressure(), stateMFNumber())) {
87 cached.
value.resize(2);
89 const doublereal r = moleFraction(product_species_index);
90 const doublereal pval = p(r);
91 const doublereal rfm = r * fm(r);
92 const doublereal A = (std::pow(1 - rfm, pval) * std::pow(rfm, pval) * std::pow(r - rfm, 1 - pval)) /
93 (std::pow(1 - r - rfm, 1 + pval) * (1 - r));
94 const doublereal B = pval * h_mixing / RT();
95 cached.
value[product_species_index] = A * std::exp(B);
96 cached.
value[reactant_species_index] = 1 / (A * r * (1-r) ) * std::exp(-B);
98 std::copy(cached.
value.begin(), cached.
value.end(), ac);
101void MaskellSolidSolnPhase::getChemPotentials(doublereal* mu)
const
103 const doublereal r = moleFraction(product_species_index);
104 const doublereal pval = p(r);
105 const doublereal rfm = r * fm(r);
106 const doublereal DgbarDr = pval * h_mixing +
108 std::log( (std::pow(1 - rfm, pval) * std::pow(rfm, pval) * std::pow(r - rfm, 1 - pval) * r) /
109 (std::pow(1 - r - rfm, 1 + pval) * (1 - r)) );
110 mu[product_species_index] = RT() * m_g0_RT[product_species_index] + DgbarDr;
111 mu[reactant_species_index] = RT() * m_g0_RT[reactant_species_index] - DgbarDr;
114void MaskellSolidSolnPhase::getChemPotentials_RT(doublereal* mu)
const
116 getChemPotentials(mu);
117 for (
size_t sp=0; sp < m_kk; ++sp) {
118 mu[sp] *= 1.0 / RT();
124void MaskellSolidSolnPhase::getPartialMolarEnthalpies(doublereal* hbar)
const
129void MaskellSolidSolnPhase::getPartialMolarEntropies(doublereal* sbar)
const
134void MaskellSolidSolnPhase::getPartialMolarCp(doublereal* cpbar)
const
139void MaskellSolidSolnPhase::getPartialMolarVolumes(doublereal* vbar)
const
141 getStandardVolumes(vbar);
144void MaskellSolidSolnPhase::getPureGibbs(doublereal* gpure)
const
146 for (
size_t sp=0; sp < m_kk; ++sp) {
147 gpure[sp] = RT() * m_g0_RT[sp];
151void MaskellSolidSolnPhase::getStandardChemPotentials(doublereal* mu)
const
160void MaskellSolidSolnPhase::initThermo()
162 if (!m_input.empty()) {
163 set_h_mix(m_input.convert(
"excess-enthalpy",
"J/kmol"));
164 setProductSpecies(m_input[
"product-species"].asString());
166 VPStandardStateTP::initThermo();
169void MaskellSolidSolnPhase::getParameters(
AnyMap& phaseNode)
const
171 VPStandardStateTP::getParameters(phaseNode);
172 phaseNode[
"excess-enthalpy"].setQuantity(h_mixing,
"J/kmol");
173 phaseNode[
"product-species"] = speciesName(product_species_index);
176void MaskellSolidSolnPhase::initThermoXML(
XML_Node& phaseNode,
const std::string& id_)
178 if (id_.size() > 0 && phaseNode.
id() != id_) {
179 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
180 "phasenode and Id are incompatible");
188 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
189 "Unknown thermo model: " + thNode[
"model"]);
196 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
197 "Mixing enthalpy parameter not specified.");
200 if (thNode.
hasChild(
"product_species")) {
201 setProductSpecies(thNode.
child(
"product_species").
value());
203 setProductSpecies(speciesName(0));
206 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
207 "Unspecified thermo model");
212 throw CanteraError(
"MaskellSolidSolnPhase::initThermoXML",
213 "MaskellSolidSolution model requires exactly 2 species.");
217 VPStandardStateTP::initThermoXML(phaseNode, id_);
220void MaskellSolidSolnPhase::setProductSpecies(
const std::string& name)
222 product_species_index =
static_cast<int>(speciesIndex(name));
223 if (product_species_index == -1) {
224 throw CanteraError(
"MaskellSolidSolnPhase::setProductSpecies",
225 "Species '{}' not found", name);
227 reactant_species_index = (product_species_index == 0) ? 1 : 0;
230doublereal MaskellSolidSolnPhase::s()
const
232 return 1 + std::exp(h_mixing / RT());
235doublereal MaskellSolidSolnPhase::fm(
const doublereal r)
const
237 return (1 - std::sqrt(1 - 4*r*(1-r)/s())) / (2*r);
240doublereal MaskellSolidSolnPhase::p(
const doublereal r)
const
242 const doublereal sval = s();
243 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.
A map of string keys to values whose type can vary at runtime.
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.
Namespace for the Cantera kernel.
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
const double OneAtm
One atmosphere [Pa].
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
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].
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.