Cantera  2.3.0
MineralEQ3.cpp
Go to the documentation of this file.
1 /**
2  * @file MineralEQ3.cpp
3  * Definition file for the MineralEQ3 class, which represents a fixed-composition
4  * incompressible substance (see \ref thermoprops and
5  * class \link Cantera::MineralEQ3 MineralEQ3\endlink)
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at http://www.cantera.org/license.txt for license and copyright information.
10 
11 #include "cantera/base/ctml.h"
16 
17 using namespace std;
18 
19 namespace Cantera
20 {
21 
22 // ---- Constructors -------
23 
24 MineralEQ3::MineralEQ3(const std::string& infile, const std::string& id_)
25 {
26  initThermoFile(infile, id_);
27 }
28 
29 MineralEQ3::MineralEQ3(XML_Node& xmlphase, const std::string& id_)
30 {
31  importPhase(xmlphase, this);
32 }
33 
34 MineralEQ3::MineralEQ3(const MineralEQ3& right)
35 {
36  *this = right;
37 }
38 
39 MineralEQ3&
40 MineralEQ3::operator=(const MineralEQ3& right)
41 {
42  if (&right == this) {
43  return *this;
44  }
45  StoichSubstance::operator=(right);
46  m_Mu0_pr_tr = right.m_Mu0_pr_tr;
47  m_Entrop_pr_tr = right.m_Entrop_pr_tr;
48  m_deltaG_formation_pr_tr = right.m_deltaG_formation_pr_tr;
49  m_deltaH_formation_pr_tr = right.m_deltaH_formation_pr_tr;
50  m_V0_pr_tr = right.m_V0_pr_tr;
51  m_a = right.m_a;
52  m_b = right.m_b;
53  m_c = right.m_c;
54 
55  return *this;
56 }
57 
58 ThermoPhase* MineralEQ3::duplMyselfAsThermoPhase() const
59 {
60  return new MineralEQ3(*this);
61 }
62 
63 // ---- Utilities -----
64 
65 int MineralEQ3::eosType() const
66 {
67  warn_deprecated("MineralEQ3::eosType",
68  "To be removed after Cantera 2.3.");
69  return cStoichSubstance;
70 }
71 
72 // ----- Mechanical Equation of State ------
73 
74 doublereal MineralEQ3::pressure() const
75 {
76  return m_press;
77 }
78 
79 void MineralEQ3::setPressure(doublereal p)
80 {
81  m_press = p;
82 }
83 
84 doublereal MineralEQ3::isothermalCompressibility() const
85 {
86  return 0.0;
87 }
88 
89 doublereal MineralEQ3::thermalExpansionCoeff() const
90 {
91  return 0.0;
92 }
93 
94 // ---- Chemical Potentials and Activities ----
95 
96 void MineralEQ3::getActivityConcentrations(doublereal* c) const
97 {
98  c[0] = 1.0;
99 }
100 
101 doublereal MineralEQ3::standardConcentration(size_t k) const
102 {
103  return 1.0;
104 }
105 
106 doublereal MineralEQ3::logStandardConc(size_t k) const
107 {
108  return 0.0;
109 }
110 
111 // Properties of the Standard State of the Species in the Solution
112 
113 void MineralEQ3::getStandardChemPotentials(doublereal* mu0) const
114 {
115  getGibbs_RT(mu0);
116  mu0[0] *= RT();
117 }
118 
119 void MineralEQ3::getEnthalpy_RT(doublereal* hrt) const
120 {
121  getEnthalpy_RT_ref(hrt);
122  doublereal presCorrect = (m_press - m_p0) / molarDensity();
123  hrt[0] += presCorrect / RT();
124 }
125 
126 void MineralEQ3::getEntropy_R(doublereal* sr) const
127 {
128  getEntropy_R_ref(sr);
129 }
130 
131 void MineralEQ3::getGibbs_RT(doublereal* grt) const
132 {
133  getEnthalpy_RT(grt);
134  grt[0] -= m_s0_R;
135 }
136 
137 void MineralEQ3::getCp_R(doublereal* cpr) const
138 {
139  _updateThermo();
140  cpr[0] = m_cp0_R;
141 }
142 
143 void MineralEQ3::getIntEnergy_RT(doublereal* urt) const
144 {
145  _updateThermo();
146  urt[0] = m_h0_RT - m_p0 / molarDensity() / RT();
147 }
148 
149 // ---- Thermodynamic Values for the Species Reference States ----
150 
151 void MineralEQ3::getIntEnergy_RT_ref(doublereal* urt) const
152 {
153  _updateThermo();
154  urt[0] = m_h0_RT - m_p0 / molarDensity() / RT();
155 }
156 
157 // ---- Initialization and Internal functions
158 
159 void MineralEQ3::setParameters(int n, doublereal* const c)
160 {
161  setDensity(c[0]);
162 }
163 
164 void MineralEQ3::getParameters(int& n, doublereal* const c) const
165 {
166  n = 1;
167  c[0] = density();
168 }
169 
170 void MineralEQ3::initThermoXML(XML_Node& phaseNode, const std::string& id_)
171 {
172  // Find the Thermo XML node
173  if (!phaseNode.hasChild("thermo")) {
174  throw CanteraError("HMWSoln::initThermoXML",
175  "no thermo XML node");
176  }
177 
178  const XML_Node* xsp = speciesData()[0];
179 
180  XML_Node* aStandardState = 0;
181  if (xsp->hasChild("standardState")) {
182  aStandardState = &xsp->child("standardState");
183  } else {
184  throw CanteraError("MineralEQ3::initThermoXML",
185  "no standard state mode");
186  }
187  doublereal volVal = 0.0;
188  if (aStandardState->attrib("model") != "constantVolume") {
189  throw CanteraError("MineralEQ3::initThermoXML",
190  "wrong standard state mode");
191  }
192  if (aStandardState->hasChild("V0_Pr_Tr")) {
193  XML_Node& aV = aStandardState->child("V0_Pr_Tr");
194  double Afactor = toSI("cm3/gmol");
195  if (aV.hasAttrib("units")) {
196  Afactor = toSI(aV.attrib("units"));
197  }
198  volVal = getFloat(*aStandardState, "V0_Pr_Tr");
199  m_V0_pr_tr= volVal;
200  volVal *= Afactor;
201  m_speciesSize[0] = volVal;
202  } else {
203  throw CanteraError("MineralEQ3::initThermoXML",
204  "wrong standard state mode");
205  }
206  setDensity(molecularWeight(0) / volVal);
207 
208  const XML_Node& MinEQ3node = xsp->child("thermo").child("MinEQ3");
209 
210  m_deltaG_formation_pr_tr =
211  getFloat(MinEQ3node, "DG0_f_Pr_Tr", "actEnergy") / actEnergyToSI("cal/gmol");
212  m_deltaH_formation_pr_tr =
213  getFloat(MinEQ3node, "DH0_f_Pr_Tr", "actEnergy") / actEnergyToSI("cal/gmol");
214  m_Entrop_pr_tr = getFloat(MinEQ3node, "S0_Pr_Tr", "toSI") / toSI("cal/gmol/K");
215  m_a = getFloat(MinEQ3node, "a", "toSI") / toSI("cal/gmol/K");
216  m_b = getFloat(MinEQ3node, "b", "toSI") / toSI("cal/gmol/K2");
217  m_c = getFloat(MinEQ3node, "c", "toSI") / toSI("cal-K/gmol");
218 
219  convertDGFormation();
220 }
221 
222 void MineralEQ3::setParametersFromXML(const XML_Node& eosdata)
223 {
224  if (eosdata["model"] != "MineralEQ3") {
225  throw CanteraError("MineralEQ3::MineralEQ3",
226  "thermo model attribute must be MineralEQ3");
227  }
228 }
229 
230 doublereal MineralEQ3::LookupGe(const std::string& elemName)
231 {
232  size_t iE = elementIndex(elemName);
233  if (iE == npos) {
234  throw CanteraError("PDSS_HKFT::LookupGe", "element " + elemName + " not found");
235  }
236  doublereal geValue = entropyElement298(iE);
237  if (geValue == ENTROPY298_UNKNOWN) {
238  throw CanteraError("PDSS_HKFT::LookupGe",
239  "element " + elemName + " does not have a supplied entropy298");
240  }
241  geValue *= (-298.15);
242  return geValue;
243 }
244 
245 void MineralEQ3::convertDGFormation()
246 {
247  // Ok let's get the element compositions and conversion factors.
248  doublereal totalSum = 0.0;
249  for (size_t m = 0; m < nElements(); m++) {
250  double na = nAtoms(0, m);
251  if (na > 0.0) {
252  totalSum += na * LookupGe(elementName(m));
253  }
254  }
255  // Ok, now do the calculation. Convert to joules kmol-1
256  doublereal dg = m_deltaG_formation_pr_tr * toSI("cal/gmol");
257  //! Store the result into an internal variable.
258  m_Mu0_pr_tr = dg + totalSum;
259 
260  double Hcalc = m_Mu0_pr_tr + 298.15 * m_Entrop_pr_tr * toSI("cal/gmol");
261  double DHjmol = m_deltaH_formation_pr_tr * toSI("kal/gmol");
262 
263  // If the discrepancy is greater than 100 cal gmol-1, print an error
264  if (fabs(Hcalc -DHjmol) > 100 * toSI("cal/gmol")) {
265  throw CanteraError("installMinEQ3asShomateThermoFromXML()",
266  "DHjmol is not consistent with G and S: {} vs {}",
267  Hcalc, DHjmol);
268  }
269 }
270 
271 }
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
doublereal actEnergyToSI(const std::string &unit)
Return the conversion factor to convert activation energy unit std::string &#39;unit&#39; to Kelvin...
Definition: global.cpp:171
doublereal toSI(const std::string &unit)
Return the conversion factor to convert unit std::string &#39;unit&#39; to SI units.
Definition: global.cpp:160
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
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.
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
Definition: xml.cpp:541
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
#define ENTROPY298_UNKNOWN
Number indicating we don&#39;t know the entropy of the element in its most stable state at 298...
Definition: Elements.h:87
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
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:500
Header file for the MineralEQ3 class, which represents a fixed-composition incompressible substance b...
Contains declarations for string manipulation functions within Cantera.
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:178
Namespace for the Cantera kernel.
Definition: application.cpp:29
Class MineralEQ3 represents a stoichiometric (fixed composition) incompressible substance based on EQ...
Definition: MineralEQ3.h:95