Cantera  2.5.1
MaskellSolidSolnPhase.cpp
Go to the documentation of this file.
1 /**
2  * @file MaskellSolidSolnPhase.cpp Implementation file for an ideal solid
3  * solution model with incompressible thermodynamics (see \ref
4  * thermoprops and \link Cantera::MaskellSolidSolnPhase
5  * MaskellSolidSolnPhase\endlink).
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at https://cantera.org/license.txt for license and copyright information.
10 
13 #include "cantera/base/xml.h"
14 
15 #include <cassert>
16 
17 namespace Cantera
18 {
19 
20 MaskellSolidSolnPhase::MaskellSolidSolnPhase() :
21  m_Pcurrent(OneAtm),
22  h_mixing(0.0),
23  product_species_index(-1),
24  reactant_species_index(-1)
25 {
26 }
27 
29 {
31  for (size_t sp = 0; sp < m_kk; ++sp) {
32  c[sp] *= moleFraction(sp);
33  }
34 }
35 
36 // Molar Thermodynamic Properties of the Solution
37 
39 {
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;
44 }
45 
46 doublereal xlogx(doublereal x)
47 {
48  return x * std::log(x);
49 }
50 
52 {
53  const doublereal s0 = GasConstant * mean_X(m_s0_R);
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));
58 }
59 
60 // Mechanical Equation of State
61 
62 void MaskellSolidSolnPhase::setDensity(const doublereal rho)
63 {
64  // Unless the input density is exactly equal to the density calculated and
65  // stored in the State object, we throw an exception. This is because the
66  // density is NOT an independent variable.
67  warn_deprecated("MaskellSolidSolnPhase::setDensity",
68  "Overloaded function to be removed after Cantera 2.5. "
69  "Error will be thrown by Phase::setDensity instead");
70  double dens = density();
71  if (rho != dens) {
72  throw CanteraError("MaskellSolidSolnPhase::setDensity",
73  "Density is not an independent variable");
74  }
75 }
76 
78 {
79  const vector_fp& vbar = getStandardVolumes();
80 
81  vector_fp moleFracs(m_kk);
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];
86  }
88 }
89 
91 {
92  m_Pcurrent = p;
93 }
94 
96 {
97  warn_deprecated("MaskellSolidSolnPhase::setMolarDensity",
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");
102 }
103 
104 // Chemical Potentials and Activities
105 
107 {
108  static const int cacheId = m_cache.getId();
109  CachedArray cached = m_cache.getArray(cacheId);
110  if (!cached.validate(temperature(), pressure(), stateMFNumber())) {
111  cached.value.resize(2);
112 
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);
121  }
122  std::copy(cached.value.begin(), cached.value.end(), ac);
123 }
124 
126 {
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 +
131  RT() *
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)) );
135  mu[reactant_species_index] = RT() * m_g0_RT[reactant_species_index] - DgbarDr;
136 }
137 
139 {
140  getChemPotentials(mu);
141  for (size_t sp=0; sp < m_kk; ++sp) {
142  mu[sp] *= 1.0 / RT();
143  }
144 }
145 
146 // Partial Molar Properties
147 
149 {
150  throw NotImplementedError("MaskellSolidSolnPhase::getPartialMolarEnthalpies");
151 }
152 
154 {
155  throw NotImplementedError("MaskellSolidSolnPhase::getPartialMolarEntropies");
156 }
157 
158 void MaskellSolidSolnPhase::getPartialMolarCp(doublereal* cpbar) const
159 {
160  throw NotImplementedError("MaskellSolidSolnPhase::getPartialMolarCp");
161 }
162 
164 {
165  getStandardVolumes(vbar);
166 }
167 
168 void MaskellSolidSolnPhase::getPureGibbs(doublereal* gpure) const
169 {
170  for (size_t sp=0; sp < m_kk; ++sp) {
171  gpure[sp] = RT() * m_g0_RT[sp];
172  }
173 }
174 
176 {
177  // What is the difference between this and getPureGibbs? IdealSolidSolnPhase
178  // gives the same for both
179  getPureGibbs(mu);
180 }
181 
182 // Utility Functions
183 
185 {
186  if (m_input.hasKey("excess-enthalpy")) {
187  set_h_mix(m_input.convert("excess-enthalpy", "J/kmol"));
188  }
189  if (m_input.hasKey("product-species")) {
190  setProductSpecies(m_input["product-species"].asString());
191  }
193 }
194 
195 
196 void MaskellSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string& id_)
197 {
198  if (id_.size() > 0 && phaseNode.id() != id_) {
199  throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
200  "phasenode and Id are incompatible");
201  }
202 
203  // Check on the thermo field. Must have:
204  // <thermo model="MaskellSolidSolution" />
205  if (phaseNode.hasChild("thermo")) {
206  XML_Node& thNode = phaseNode.child("thermo");
207  if (!caseInsensitiveEquals(thNode["model"], "maskellsolidsolnphase")) {
208  throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
209  "Unknown thermo model: " + thNode["model"]);
210  }
211 
212  // Parse the enthalpy of mixing constant
213  if (thNode.hasChild("h_mix")) {
214  set_h_mix(fpValue(thNode.child("h_mix").value()));
215  } else {
216  throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
217  "Mixing enthalpy parameter not specified.");
218  }
219 
220  if (thNode.hasChild("product_species")) {
221  setProductSpecies(thNode.child("product_species").value());
222  } else {
223  setProductSpecies(speciesName(0)); // default
224  }
225  } else {
226  throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
227  "Unspecified thermo model");
228  }
229 
230  // Confirm that the phase only contains 2 species
231  if (m_kk != 2) {
232  throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
233  "MaskellSolidSolution model requires exactly 2 species.");
234  }
235 
236  // Call the base initThermo, which handles setting the initial state.
237  VPStandardStateTP::initThermoXML(phaseNode, id_);
238 }
239 
240 void MaskellSolidSolnPhase::setProductSpecies(const std::string& name)
241 {
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);
246  }
247  reactant_species_index = (product_species_index == 0) ? 1 : 0;
248 }
249 
250 doublereal MaskellSolidSolnPhase::s() const
251 {
252  return 1 + std::exp(h_mixing / RT());
253 }
254 
255 doublereal MaskellSolidSolnPhase::fm(const doublereal r) const
256 {
257  return (1 - std::sqrt(1 - 4*r*(1-r)/s())) / (2*r);
258 }
259 
260 doublereal MaskellSolidSolnPhase::p(const doublereal r) const
261 {
262  const doublereal sval = s();
263  return (1 - 2*r) / std::sqrt(sval*sval - 4 * sval * r + 4 * sval * r * r);
264 }
265 
266 } // end namespace Cantera
Cantera::ThermoPhase::initThermoXML
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
Definition: ThermoPhase.cpp:1089
Cantera::VPStandardStateTP::m_g0_RT
vector_fp m_g0_RT
Vector containing the species reference Gibbs functions at T = m_tlast and P = p_ref.
Definition: VPStandardStateTP.h:302
Cantera::Phase::m_cache
ValueCache m_cache
Cached for saved calculations within each ThermoPhase.
Definition: Phase.h:922
Cantera::MaskellSolidSolnPhase::getStandardChemPotentials
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
Definition: MaskellSolidSolnPhase.cpp:175
Cantera::Phase::getMoleFractions
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
Definition: Phase.cpp:572
Cantera::AnyMap::convert
double convert(const std::string &key, const std::string &units) const
Convert the item stored by the given key to the units specified in units.
Definition: AnyMap.cpp:1055
Cantera::Phase::stateMFNumber
int stateMFNumber() const
Return the State Mole Fraction Number.
Definition: Phase.h:856
Cantera::VPStandardStateTP::m_s0_R
vector_fp m_s0_R
Vector containing the species reference entropies at T = m_tlast and P = p_ref.
Definition: VPStandardStateTP.h:306
Cantera::CachedValue
Definition: ValueCache.h:32
Cantera::ValueCache::getArray
CachedArray getArray(int id)
Get a reference to a CachedValue object representing an array (vector_fp) with the given id.
Definition: ValueCache.h:171
Cantera::warn_deprecated
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
Cantera::MaskellSolidSolnPhase::getActivityCoefficients
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
Definition: MaskellSolidSolnPhase.cpp:106
Cantera::NotImplementedError
An error indicating that an unimplemented function has been called.
Definition: ctexceptions.h:186
Cantera::XML_Node::id
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:538
Cantera::Phase::meanMolecularWeight
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:748
Cantera::XML_Node::hasChild
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:528
Cantera::AnyMap::hasKey
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:984
Cantera::Phase::assignDensity
void assignDensity(const double density_)
Set the internally stored constant density (kg/m^3) of the phase.
Definition: Phase.cpp:727
Cantera::MaskellSolidSolnPhase::getPartialMolarEnthalpies
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Definition: MaskellSolidSolnPhase.cpp:148
xml.h
Cantera::vector_fp
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:180
Cantera::Phase::name
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:84
Cantera::Phase::moleFraction
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:577
Cantera::MaskellSolidSolnPhase::getChemPotentials_RT
virtual void getChemPotentials_RT(doublereal *mu) const
Get the array of non-dimensional species chemical potentials.
Definition: MaskellSolidSolnPhase.cpp:138
Cantera::MaskellSolidSolnPhase::getPureGibbs
virtual void getPureGibbs(doublereal *gpure) const
Get the Gibbs functions for the standard state of the species at the current T and P of the solution.
Definition: MaskellSolidSolnPhase.cpp:168
Cantera::MaskellSolidSolnPhase::m_Pcurrent
doublereal m_Pcurrent
m_Pcurrent = The current pressure.
Definition: MaskellSolidSolnPhase.h:143
Cantera::Phase::m_kk
size_t m_kk
Number of species in the phase.
Definition: Phase.h:942
Cantera::XML_Node::value
std::string value() const
Return the value of an XML node as a string.
Definition: xml.cpp:441
Cantera::ThermoPhase::m_input
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1874
Cantera::Phase::density
virtual double density() const
Density (kg/m^3).
Definition: Phase.h:685
Cantera::ValueCache::getId
int getId()
Get a unique id for a cached value.
Definition: ValueCache.cpp:21
Cantera::MaskellSolidSolnPhase::entropy_mole
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
Definition: MaskellSolidSolnPhase.cpp:51
Cantera::VPStandardStateTP::m_h0_RT
vector_fp m_h0_RT
Vector containing the species reference enthalpies at T = m_tlast and P = p_ref.
Definition: VPStandardStateTP.h:294
MaskellSolidSolnPhase.h
Cantera::MaskellSolidSolnPhase::enthalpy_mole
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
Definition: MaskellSolidSolnPhase.cpp:38
Cantera::MaskellSolidSolnPhase::getPartialMolarEntropies
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
Definition: MaskellSolidSolnPhase.cpp:153
Cantera::MaskellSolidSolnPhase::initThermo
virtual void initThermo()
Definition: MaskellSolidSolnPhase.cpp:184
Cantera::MaskellSolidSolnPhase::initThermoXML
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
Definition: MaskellSolidSolnPhase.cpp:196
Cantera::Phase::speciesIndex
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:201
Cantera::XML_Node
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
Cantera::MaskellSolidSolnPhase::setPressure
virtual void setPressure(doublereal p)
Set the pressure at constant temperature.
Definition: MaskellSolidSolnPhase.cpp:90
Cantera::caseInsensitiveEquals
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
Definition: stringUtils.cpp:268
Cantera::OneAtm
const double OneAtm
One atmosphere [Pa].
Definition: ct_defs.h:78
Cantera::ThermoPhase::RT
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:776
Cantera::MaskellSolidSolnPhase::setDensity
virtual void setDensity(const doublereal rho)
Overridden setDensity() function is necessary because the density is not an independent variable.
Definition: MaskellSolidSolnPhase.cpp:62
stringUtils.h
Cantera::Phase::temperature
doublereal temperature() const
Temperature (K).
Definition: Phase.h:667
Cantera::MaskellSolidSolnPhase::pressure
virtual doublereal pressure() const
Pressure.
Definition: MaskellSolidSolnPhase.h:63
Cantera::VPStandardStateTP::initThermo
virtual void initThermo()
Definition: VPStandardStateTP.cpp:154
Cantera::MaskellSolidSolnPhase::setMolarDensity
virtual void setMolarDensity(const doublereal rho)
Overridden setMolarDensity() function is necessary because the density is not an independent variable...
Definition: MaskellSolidSolnPhase.cpp:95
Cantera::MaskellSolidSolnPhase::product_species_index
int product_species_index
Index of the species whose mole fraction defines the extent of reduction r.
Definition: MaskellSolidSolnPhase.h:150
Cantera::Phase::mean_X
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
Definition: Phase.cpp:746
Cantera::MaskellSolidSolnPhase::calcDensity
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
Definition: MaskellSolidSolnPhase.cpp:77
Cantera::CachedValue::value
T value
The value of the cached property.
Definition: ValueCache.h:118
Cantera::MaskellSolidSolnPhase::getPartialMolarVolumes
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: MaskellSolidSolnPhase.cpp:163
Cantera::GasConstant
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:109
Cantera::VPStandardStateTP::getStandardVolumes
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution.
Definition: VPStandardStateTP.cpp:98
Cantera::MaskellSolidSolnPhase::getChemPotentials
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: MaskellSolidSolnPhase.cpp:125
Cantera::CanteraError
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:60
Cantera::MaskellSolidSolnPhase::h_mixing
doublereal h_mixing
Value of the enthalpy change on mixing due to protons changing from type B to type A configurations.
Definition: MaskellSolidSolnPhase.h:147
Cantera::MaskellSolidSolnPhase::setProductSpecies
void setProductSpecies(const std::string &name)
Set the product Species. Must be called after species have been added.
Definition: MaskellSolidSolnPhase.cpp:240
Cantera::MaskellSolidSolnPhase::getActivityConcentrations
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
Definition: MaskellSolidSolnPhase.cpp:28
Cantera
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:263
Cantera::CachedValue::validate
bool validate(double state1New)
Check whether the currently cached value is valid based on a single state variable.
Definition: ValueCache.h:44
Cantera::Phase::speciesName
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:229
Cantera::fpValue
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
Definition: stringUtils.cpp:129
Cantera::XML_Node::child
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:546
Cantera::MaskellSolidSolnPhase::getPartialMolarCp
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
Definition: MaskellSolidSolnPhase.cpp:158