Cantera  2.4.0
MolarityIonicVPSSTP.cpp
Go to the documentation of this file.
1 /**
2  * @file MolarityIonicVPSSTP.cpp
3  * Definitions for intermediate ThermoPhase object for phases which
4  * employ excess Gibbs free energy formulations
5  * (see \ref thermoprops
6  * and class \link Cantera::MolarityIonicVPSSTP MolarityIonicVPSSTP\endlink).
7  *
8  * Header file for a derived class of ThermoPhase that handles variable pressure
9  * standard state methods for calculating thermodynamic properties that are
10  * further based upon expressions for the excess Gibbs free energy expressed as
11  * a function of the mole fractions.
12  */
13 
14 // This file is part of Cantera. See License.txt in the top-level directory or
15 // at http://www.cantera.org/license.txt for license and copyright information.
16 
20 
21 #include <cstdio>
22 
23 using namespace std;
24 
25 namespace Cantera
26 {
27 
28 MolarityIonicVPSSTP::MolarityIonicVPSSTP() :
29  PBType_(PBTYPE_PASSTHROUGH),
30  numPBSpecies_(m_kk),
31  neutralPBindexStart(0)
32 {
33  warn_deprecated("Class MolarityIonicVPSSTP", "To be removed after Cantera 2.4");
34 }
35 
36 MolarityIonicVPSSTP::MolarityIonicVPSSTP(const std::string& inputFile,
37  const std::string& id_) :
38  PBType_(PBTYPE_PASSTHROUGH),
39  numPBSpecies_(m_kk),
40  neutralPBindexStart(0)
41 {
42  warn_deprecated("Class MolarityIonicVPSSTP", "To be removed after Cantera 2.4");
43  initThermoFile(inputFile, id_);
44 }
45 
46 MolarityIonicVPSSTP::MolarityIonicVPSSTP(XML_Node& phaseRoot,
47  const std::string& id_) :
48  PBType_(PBTYPE_PASSTHROUGH),
49  numPBSpecies_(m_kk),
50  neutralPBindexStart(0)
51 {
52  warn_deprecated("Class MolarityIonicVPSSTP", "To be removed after Cantera 2.4");
53  importPhase(phaseRoot, this);
54 }
55 
56 // - Activities, Standard States, Activity Concentrations -----------
57 
59 {
60  // Update the activity coefficients
62 
63  // take the exp of the internally stored coefficients.
64  for (size_t k = 0; k < m_kk; k++) {
65  lnac[k] = lnActCoeff_Scaled_[k];
66  }
67 }
68 
69 void MolarityIonicVPSSTP::getChemPotentials(doublereal* mu) const
70 {
71  // First get the standard chemical potentials in molar form. This requires
72  // updates of standard state as a function of T and P
74 
75  // Update the activity coefficients
77  for (size_t k = 0; k < m_kk; k++) {
78  double xx = std::max(moleFractions_[k], SmallNumber);
79  mu[k] += RT() * (log(xx) + lnActCoeff_Scaled_[k]);
80  }
81 }
82 
84 {
85  // Get the nondimensional standard state enthalpies
86  getEnthalpy_RT(hbar);
87 
88  // dimensionalize it.
89  double T = temperature();
90  for (size_t k = 0; k < m_kk; k++) {
91  hbar[k] *= GasConstant * T;
92  }
93 
94  // Update the activity coefficients, This also update the internally stored
95  // molalities.
98  for (size_t k = 0; k < m_kk; k++) {
99  hbar[k] -= GasConstant * T * T * dlnActCoeffdT_Scaled_[k];
100  }
101 }
102 
103 void MolarityIonicVPSSTP::getPartialMolarCp(doublereal* cpbar) const
104 {
105  // Get the nondimensional standard state entropies
106  getCp_R(cpbar);
107  double T = temperature();
108 
109  // Update the activity coefficients, This also update the internally stored
110  // molalities.
113 
114  for (size_t k = 0; k < m_kk; k++) {
115  cpbar[k] -= 2 * T * dlnActCoeffdT_Scaled_[k] + T * T * d2lnActCoeffdT2_Scaled_[k];
116  }
117 
118  // dimensionalize it.
119  for (size_t k = 0; k < m_kk; k++) {
120  cpbar[k] *= GasConstant;
121  }
122 }
123 
125 {
126  // Get the nondimensional standard state entropies
127  getEntropy_R(sbar);
128  double T = temperature();
129 
130  // Update the activity coefficients, This also update the internally stored
131  // molalities.
134 
135  for (size_t k = 0; k < m_kk; k++) {
136  double xx = std::max(moleFractions_[k], SmallNumber);
137  sbar[k] += - lnActCoeff_Scaled_[k] -log(xx) - T * dlnActCoeffdT_Scaled_[k];
138  }
139 
140  // dimensionalize it.
141  for (size_t k = 0; k < m_kk; k++) {
142  sbar[k] *= GasConstant;
143  }
144 }
145 
147 {
148  // Get the standard state values in m^3 kmol-1
149  getStandardVolumes(vbar);
150  for (size_t iK = 0; iK < m_kk; iK++) {
151  vbar[iK] += 0.0;
152  }
153 }
154 
156 {
157  switch (PBType_) {
158  case PBTYPE_PASSTHROUGH:
159  for (size_t k = 0; k < m_kk; k++) {
160  PBMoleFractions_[k] = moleFractions_[k];
161  }
162  break;
163  case PBTYPE_SINGLEANION:
164  {
165  double sumCat = 0.0;
166  double sumAnion = 0.0;
167  for (size_t k = 0; k < m_kk; k++) {
168  moleFractionsTmp_[k] = moleFractions_[k];
169  }
170  size_t kMax = npos;
171  double sumMax = 0.0;
172  for (size_t k = 0; k < cationList_.size(); k++) {
173  size_t kCat = cationList_[k];
174  double chP = m_speciesCharge[kCat];
175  if (moleFractions_[kCat] > sumMax) {
176  kMax = k;
177  sumMax = moleFractions_[kCat];
178  }
179  sumCat += chP * moleFractions_[kCat];
180  }
181  size_t ka = anionList_[0];
182  sumAnion = moleFractions_[ka] * m_speciesCharge[ka];
183  double sum = sumCat - sumAnion;
184  if (fabs(sum) > 1.0E-16) {
185  moleFractionsTmp_[cationList_[kMax]] -= sum / m_speciesCharge[kMax];
186  sum = 0.0;
187  for (size_t k = 0; k < cationList_.size(); k++) {
188  sum += moleFractionsTmp_[k];
189  }
190  for (size_t k = 0; k < cationList_.size(); k++) {
191  moleFractionsTmp_[k]/= sum;
192  }
193  }
194 
195  for (size_t k = 0; k < cationList_.size(); k++) {
196  PBMoleFractions_[k] = moleFractionsTmp_[cationList_[k]];
197  }
198  for (size_t k = 0; k < passThroughList_.size(); k++) {
199  PBMoleFractions_[neutralPBindexStart + k] = moleFractions_[passThroughList_[k]];
200  }
201 
202  sum = std::max(0.0, PBMoleFractions_[0]);
203  for (size_t k = 1; k < numPBSpecies_; k++) {
204  sum += PBMoleFractions_[k];
205  }
206  for (size_t k = 0; k < numPBSpecies_; k++) {
207  PBMoleFractions_[k] /= sum;
208  }
209  break;
210  }
211  case PBTYPE_SINGLECATION:
212  throw CanteraError("eosType", "Unknown type");
213  case PBTYPE_MULTICATIONANION:
214  throw CanteraError("eosType", "Unknown type");
215  default:
216  throw CanteraError("eosType", "Unknown type");
217  }
218 }
219 
221 {
222  for (size_t k = 0; k < m_kk; k++) {
223  lnActCoeff_Scaled_[k] = 0.0;
224  }
225 }
226 
228 {
229 }
230 
232 {
233 }
234 
236 {
238  initLengths();
239 
240  // Go find the list of cations and anions
241  cationList_.clear();
242  anionList_.clear();
243  passThroughList_.clear();
244  for (size_t k = 0; k < m_kk; k++) {
245  double ch = m_speciesCharge[k];
246  if (ch > 0.0) {
247  cationList_.push_back(k);
248  } else if (ch < 0.0) {
249  anionList_.push_back(k);
250  } else {
251  passThroughList_.push_back(k);
252  }
253  }
254  numPBSpecies_ = cationList_.size() + anionList_.size() - 1;
255  neutralPBindexStart = numPBSpecies_;
256  PBType_ = PBTYPE_MULTICATIONANION;
257  if (anionList_.size() == 1) {
258  PBType_ = PBTYPE_SINGLEANION;
259  } else if (cationList_.size() == 1) {
260  PBType_ = PBTYPE_SINGLECATION;
261  }
262  if (anionList_.size() == 0 && cationList_.size() == 0) {
263  PBType_ = PBTYPE_PASSTHROUGH;
264  }
265 }
266 
268 {
269  moleFractionsTmp_.resize(m_kk);
270 }
271 
272 void MolarityIonicVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id)
273 {
274  if ((int) id.size() > 0 && phaseNode.id() != id) {
275  throw CanteraError("MolarityIonicVPSSTP::initThermoXML",
276  "phasenode and Id are incompatible");
277  }
278 
279  // Check on the thermo field. Must have one of:
280  // <thermo model="MolarityIonicVPSS" />
281  // <thermo model="MolarityIonicVPSSTP" />
282  if (!phaseNode.hasChild("thermo")) {
283  throw CanteraError("MolarityIonicVPSSTP::initThermoXML",
284  "no thermo XML node");
285  }
286  XML_Node& thermoNode = phaseNode.child("thermo");
287  if (!caseInsensitiveEquals(thermoNode["model"], "molarityionicvpss")
288  && !caseInsensitiveEquals(thermoNode["model"], "molarityionicvpsstp")) {
289  throw CanteraError("MolarityIonicVPSSTP::initThermoXML",
290  "Unknown thermo model: " + thermoNode["model"]
291  + " - This object only knows \"MolarityIonicVPSSTP\" ");
292  }
293 
294  // Go get all of the coefficients and factors in the activityCoefficients
295  // XML block
296  if (thermoNode.hasChild("activityCoefficients")) {
297  XML_Node& acNode = thermoNode.child("activityCoefficients");
298  for (size_t i = 0; i < acNode.nChildren(); i++) {
299  XML_Node& xmlACChild = acNode.child(i);
300  // Process a binary interaction
301  if (caseInsensitiveEquals(xmlACChild.name(), "binaryneutralspeciesparameters")) {
302  readXMLBinarySpecies(xmlACChild);
303  }
304  }
305  }
306 
307  // Go down the chain
308  GibbsExcessVPSSTP::initThermoXML(phaseNode, id);
309 }
310 
312 {
313  std::string xname = xmLBinarySpecies.name();
314 }
315 
316 std::string MolarityIonicVPSSTP::report(bool show_thermo, doublereal threshold) const
317 {
318  fmt::memory_buffer b;
319  try {
320  if (name() != "") {
321  format_to(b, "\n {}:\n", name());
322  }
323  format_to(b, "\n");
324  format_to(b, " temperature {:12.6g} K\n", temperature());
325  format_to(b, " pressure {:12.6g} Pa\n", pressure());
326  format_to(b, " density {:12.6g} kg/m^3\n", density());
327  format_to(b, " mean mol. weight {:12.6g} amu\n", meanMolecularWeight());
328 
329  doublereal phi = electricPotential();
330  format_to(b, " potential {:12.6g} V\n", phi);
331 
332  vector_fp x(m_kk);
333  vector_fp molal(m_kk);
334  vector_fp mu(m_kk);
335  vector_fp muss(m_kk);
336  vector_fp acMolal(m_kk);
337  vector_fp actMolal(m_kk);
338  getMoleFractions(&x[0]);
339 
340  getChemPotentials(&mu[0]);
341  getStandardChemPotentials(&muss[0]);
342  getActivities(&actMolal[0]);
343 
344  if (show_thermo) {
345  format_to(b, "\n");
346  format_to(b, " 1 kg 1 kmol\n");
347  format_to(b, " ----------- ------------\n");
348  format_to(b, " enthalpy {:12.6g} {:12.4g} J\n",
350  format_to(b, " internal energy {:12.6g} {:12.4g} J\n",
352  format_to(b, " entropy {:12.6g} {:12.4g} J/K\n",
354  format_to(b, " Gibbs function {:12.6g} {:12.4g} J\n",
355  gibbs_mass(), gibbs_mole());
356  format_to(b, " heat capacity c_p {:12.6g} {:12.4g} J/K\n",
357  cp_mass(), cp_mole());
358  try {
359  format_to(b, " heat capacity c_v {:12.6g} {:12.4g} J/K\n",
360  cv_mass(), cv_mole());
361  } catch (NotImplementedError&) {
362  format_to(b, " heat capacity c_v <not implemented>\n");
363  }
364  }
365  } catch (CanteraError& e) {
366  return to_string(b) + e.what();
367  }
368  return to_string(b);
369 }
370 
371 }
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
virtual double size(size_t k) const
Definition: Phase.h:411
std::string name() const
Returns the name of the XML node.
Definition: xml.h:370
virtual void calcPseudoBinaryMoleFractions() const
Calculate pseudo binary mole fractions.
doublereal temperature() const
Temperature (K).
Definition: Phase.h:601
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
Definition: ThermoPhase.h:230
An error indicating that an unimplemented function has been called.
Definition: ctexceptions.h:187
doublereal cp_mass() const
Specific heat at constant pressure. Units: J/kg/K.
Definition: ThermoPhase.h:734
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
void s_update_dlnActCoeff_dT() const
Update the derivative of the log of the activity coefficients wrt T.
vector_fp m_speciesCharge
Vector of species charges. length m_kk.
Definition: Phase.h:799
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
void readXMLBinarySpecies(XML_Node &xmlBinarySpecies)
Process an XML node called "binaryNeutralSpeciesParameters".
const char * what() const
Get a description of the error.
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
STL namespace.
virtual doublereal density() const
Density (kg/m^3).
Definition: Phase.h:607
doublereal enthalpy_mass() const
Specific enthalpy. Units: J/kg.
Definition: ThermoPhase.h:714
std::vector< size_t > cationList_
Vector of cation indices in the mixture.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
Definition: ThermoPhase.h:205
(see Thermodynamic Properties and class MolarityIonicVPSSTP).
void s_update_lnActCoeff() const
Update the activity coefficients.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:748
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
virtual doublereal intEnergy_mole() const
Molar internal energy. Units: J/kmol.
Definition: ThermoPhase.h:210
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
Definition: ThermoPhase.h:220
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
vector_fp d2lnActCoeffdT2_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
doublereal electricPotential() const
Returns the electric potential of this phase (V).
Definition: ThermoPhase.h:302
doublereal entropy_mass() const
Specific entropy. Units: J/kg/K.
Definition: ThermoPhase.h:724
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
Definition: ThermoPhase.h:225
void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
Definition: Phase.cpp:466
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
vector_fp lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
virtual doublereal pressure() const
Returns the current pressure of the phase.
void initLengths()
Initialize lengths of local variables after all species have been identified.
virtual void getActivities(doublereal *ac) const
Get the array of non-dimensional activities (molality based for this class and classes that derive fr...
void s_update_dlnActCoeff_dX_() const
Internal routine that calculates the derivative of the activity coefficients wrt the mole fractions...
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:536
XML_Node & child(const size_t n) const
Return a changeable reference to the n&#39;th child of the current node.
Definition: xml.cpp:546
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
doublereal cv_mass() const
Specific heat at constant volume. Units: J/kg/K.
Definition: ThermoPhase.h:739
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar entropies for the species in the mixture.
std::string id() const
Return the string id for the phase.
Definition: Phase.cpp:68
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
const doublereal SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:126
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:157
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:661
virtual std::string report(bool show_thermo=true, doublereal threshold=1e-14) const
returns a summary of the state of the phase as a string
doublereal gibbs_mass() const
Specific Gibbs function. Units: J/kg.
Definition: ThermoPhase.h:729
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:428
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:78
Contains declarations for string manipulation functions within Cantera.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
size_t numPBSpecies_
Number of pseudo binary species.
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
size_t m_kk
Number of species in the phase.
Definition: Phase.h:788
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:8
doublereal intEnergy_mass() const
Specific internal energy. Units: J/kg.
Definition: ThermoPhase.h:719
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
Definition: ThermoPhase.h:215
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:556
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution...
vector_fp dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...