Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 /*
9  * Copyright (2005) Sandia Corporation. Under the terms of
10  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
11  * U.S. Government retains certain rights in this software.
12  *
13  * Copyright 2001 California Institute of Technology
14  */
15 #include "cantera/base/ctml.h"
20 
21 using namespace std;
22 
23 namespace Cantera
24 {
25 
26 /*
27  * ---- Constructors -------
28  */
29 
30 MineralEQ3::MineralEQ3(const std::string& infile, std::string id_)
31 {
32  XML_Node* root = get_XML_File(infile);
33  if (id_ == "-") {
34  id_ = "";
35  }
36  XML_Node* xphase = get_XML_NameID("phase", std::string("#")+id_, root);
37  if (!xphase) {
38  throw CanteraError("MineralEQ3::MineralEQ3",
39  "Couldn't find phase name in file:" + id_);
40  }
41  // Check the model name to ensure we have compatibility
42  std::string model = xphase->child("thermo")["model"];
43  if (model != "StoichSubstance" && model != "MineralEQ3") {
44  throw CanteraError("MineralEQ3::MineralEQ3",
45  "thermo model attribute must be StoichSubstance");
46  }
47  importPhase(*xphase, this);
48 }
49 
50 MineralEQ3::MineralEQ3(XML_Node& xmlphase, const std::string& id_)
51 {
52  if (id_ != "") {
53  if (id_ != xmlphase["id"]) {
54  throw CanteraError("MineralEQ3::MineralEQ3",
55  "id's don't match");
56  }
57  }
58  std::string model = xmlphase.child("thermo")["model"];
59  if (model != "StoichSubstance" && model != "MineralEQ3") {
60  throw CanteraError("MineralEQ3::MineralEQ3",
61  "thermo model attribute must be StoichSubstance");
62  }
63  importPhase(xmlphase, this);
64 }
65 
66 MineralEQ3::MineralEQ3(const MineralEQ3& right)
67 {
68  *this = right;
69 }
70 
72 MineralEQ3::operator=(const MineralEQ3& right)
73 {
74  if (&right == this) {
75  return *this;
76  }
77  StoichSubstanceSSTP::operator=(right);
78  m_Mu0_pr_tr = right.m_Mu0_pr_tr;
79  m_Entrop_pr_tr = right.m_Entrop_pr_tr;
80  m_deltaG_formation_pr_tr = right.m_deltaG_formation_pr_tr;
81  m_deltaH_formation_pr_tr = right.m_deltaH_formation_pr_tr;
82  m_V0_pr_tr = right.m_V0_pr_tr;
83  m_a = right.m_a;
84  m_b = right.m_b;
85  m_c = right.m_c;
86 
87  return *this;
88 }
89 
90 ThermoPhase* MineralEQ3::duplMyselfAsThermoPhase() const
91 {
92  return new MineralEQ3(*this);
93 }
94 
95 /*
96  * ---- Utilities -----
97  */
98 
99 int MineralEQ3::eosType() const
100 {
101  return cStoichSubstance;
102 }
103 
104 /*
105  * ----- Mechanical Equation of State ------
106  */
107 
108 doublereal MineralEQ3::pressure() const
109 {
110  return m_press;
111 }
112 
113 void MineralEQ3::setPressure(doublereal p)
114 {
115  m_press = p;
116 }
117 
118 doublereal MineralEQ3::isothermalCompressibility() const
119 {
120  return 0.0;
121 }
122 
123 doublereal MineralEQ3::thermalExpansionCoeff() const
124 {
125  return 0.0;
126 }
127 
128 /*
129  * ---- Chemical Potentials and Activities ----
130  */
131 
132 void MineralEQ3::getActivityConcentrations(doublereal* c) const
133 {
134  c[0] = 1.0;
135 }
136 
137 doublereal MineralEQ3::standardConcentration(size_t k) const
138 {
139  return 1.0;
140 }
141 
142 doublereal MineralEQ3::logStandardConc(size_t k) const
143 {
144  return 0.0;
145 }
146 
147 void MineralEQ3::getUnitsStandardConc(doublereal* uA, int k, int sizeUA) const
148 {
149  warn_deprecated("MineralEQ3::getUnitsStandardConc",
150  "To be removed after Cantera 2.2.");
151 
152  for (int i = 0; i < 6; i++) {
153  uA[i] = 0;
154  }
155 }
156 
157 /*
158  * Properties of the Standard State of the Species in the Solution
159  */
160 
161 void MineralEQ3::getStandardChemPotentials(doublereal* mu0) const
162 {
163  getGibbs_RT(mu0);
164  mu0[0] *= GasConstant * temperature();
165 }
166 
167 void MineralEQ3::getEnthalpy_RT(doublereal* hrt) const
168 {
169  getEnthalpy_RT_ref(hrt);
170  doublereal RT = GasConstant * temperature();
171  doublereal presCorrect = (m_press - m_p0) / molarDensity();
172  hrt[0] += presCorrect / RT;
173 }
174 
175 void MineralEQ3::getEntropy_R(doublereal* sr) const
176 {
177  getEntropy_R_ref(sr);
178 }
179 
180 void MineralEQ3::getGibbs_RT(doublereal* grt) const
181 {
182  getEnthalpy_RT(grt);
183  grt[0] -= m_s0_R[0];
184 }
185 
186 void MineralEQ3::getCp_R(doublereal* cpr) const
187 {
188  _updateThermo();
189  cpr[0] = m_cp0_R[0];
190 }
191 
192 void MineralEQ3::getIntEnergy_RT(doublereal* urt) const
193 {
194  _updateThermo();
195  doublereal RT = GasConstant * temperature();
196  urt[0] = m_h0_RT[0] - m_p0 / molarDensity() / RT;
197 }
198 
199 /*
200  * ---- Thermodynamic Values for the Species Reference States ----
201  */
202 
203 void MineralEQ3::getIntEnergy_RT_ref(doublereal* urt) const
204 {
205  _updateThermo();
206  doublereal RT = GasConstant * temperature();
207  urt[0] = m_h0_RT[0] - m_p0 / molarDensity() / RT;
208 }
209 
210 /*
211  * ---- Initialization and Internal functions
212  */
213 
214 void MineralEQ3::setParameters(int n, doublereal* const c)
215 {
216  setDensity(c[0]);
217 }
218 
219 void MineralEQ3::getParameters(int& n, doublereal* const c) const
220 {
221  n = 1;
222  c[0] = density();
223 }
224 
225 void MineralEQ3::initThermoXML(XML_Node& phaseNode, const std::string& id_)
226 {
227  /*
228  * Find the Thermo XML node
229  */
230  if (!phaseNode.hasChild("thermo")) {
231  throw CanteraError("HMWSoln::initThermoXML",
232  "no thermo XML node");
233  }
234 
235  const XML_Node* xsp = speciesData()[0];
236 
237  XML_Node* aStandardState = 0;
238  if (xsp->hasChild("standardState")) {
239  aStandardState = &xsp->child("standardState");
240  } else {
241  throw CanteraError("MineralEQ3::initThermoXML",
242  "no standard state mode");
243  }
244  doublereal volVal = 0.0;
245  if (aStandardState->attrib("model") != "constantVolume") {
246  throw CanteraError("MineralEQ3::initThermoXML",
247  "wrong standard state mode");
248  }
249  if (aStandardState->hasChild("V0_Pr_Tr")) {
250  XML_Node& aV = aStandardState->child("V0_Pr_Tr");
251  double Afactor = toSI("cm3/gmol");
252  if (aV.hasAttrib("units")) {
253  Afactor = toSI(aV.attrib("units"));
254  }
255  volVal = getFloat(*aStandardState, "V0_Pr_Tr");
256  m_V0_pr_tr= volVal;
257  volVal *= Afactor;
258  m_speciesSize[0] = volVal;
259  } else {
260  throw CanteraError("MineralEQ3::initThermoXML",
261  "wrong standard state mode");
262  }
263  setDensity(molecularWeight(0) / volVal);
264 
265  const XML_Node& MinEQ3node = xsp->child("thermo").child("MinEQ3");
266 
267  m_deltaG_formation_pr_tr =
268  getFloatDefaultUnits(MinEQ3node, "DG0_f_Pr_Tr", "cal/gmol", "actEnergy");
269  m_deltaH_formation_pr_tr =
270  getFloatDefaultUnits(MinEQ3node, "DH0_f_Pr_Tr", "cal/gmol", "actEnergy");
271  m_Entrop_pr_tr = getFloatDefaultUnits(MinEQ3node, "S0_Pr_Tr", "cal/gmol/K");
272  m_a = getFloatDefaultUnits(MinEQ3node, "a", "cal/gmol/K");
273  m_b = getFloatDefaultUnits(MinEQ3node, "b", "cal/gmol/K2");
274  m_c = getFloatDefaultUnits(MinEQ3node, "c", "cal-K/gmol");
275 
276  convertDGFormation();
277 }
278 
279 void MineralEQ3::setParametersFromXML(const XML_Node& eosdata)
280 {
281  if (eosdata["model"] != "MineralEQ3") {
282  throw CanteraError("MineralEQ3::MineralEQ3",
283  "thermo model attribute must be MineralEQ3");
284  }
285 }
286 
287 doublereal MineralEQ3::LookupGe(const std::string& elemName)
288 {
289  size_t iE = elementIndex(elemName);
290  if (iE == npos) {
291  throw CanteraError("PDSS_HKFT::LookupGe", "element " + elemName + " not found");
292  }
293  doublereal geValue = entropyElement298(iE);
294  if (geValue == ENTROPY298_UNKNOWN) {
295  throw CanteraError("PDSS_HKFT::LookupGe",
296  "element " + elemName + " does not have a supplied entropy298");
297  }
298  geValue *= (-298.15);
299  return geValue;
300 }
301 
302 void MineralEQ3::convertDGFormation()
303 {
304  /*
305  * Ok let's get the element compositions and conversion factors.
306  */
307 
308  doublereal totalSum = 0.0;
309  for (size_t m = 0; m < nElements(); m++) {
310  double na = nAtoms(0, m);
311  if (na > 0.0) {
312  totalSum += na * LookupGe(elementName(m));
313  }
314  }
315  // Ok, now do the calculation. Convert to joules kmol-1
316  doublereal dg = m_deltaG_formation_pr_tr * 4.184 * 1.0E3;
317  //! Store the result into an internal variable.
318  m_Mu0_pr_tr = dg + totalSum;
319 
320  double Hcalc = m_Mu0_pr_tr + 298.15 * m_Entrop_pr_tr * 4184.0;
321  double DHjmol = m_deltaH_formation_pr_tr * 4184.0;
322 
323  // If the discrepancy is greater than 100 cal gmol-1, print an error
324  if (fabs(Hcalc -DHjmol) > 10.* 1.0E6 * 4.184) {
325  throw CanteraError("installMinEQ3asShomateThermoFromXML()",
326  "DHjmol is not consistent with G and S" +
327  fp2str(Hcalc) + " vs " + fp2str(DHjmol));
328  }
329 }
330 
331 }
doublereal m_Entrop_pr_tr
Input value of S_j at Tr and Pr (cal gmol-1 K-1)
Definition: MineralEQ3.h:427
doublereal m_deltaH_formation_pr_tr
Input Value of deltaH of Formation at Tr and Pr (cal gmol-1)
Definition: MineralEQ3.h:445
XML_Node * get_XML_File(const std::string &file, int debug)
Return a pointer to the XML tree for a Cantera input file.
Definition: global.cpp:105
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:527
doublereal toSI(const std::string &unit)
Return the conversion factor to convert unit std::string 'unit' to SI units.
Definition: global.cpp:161
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:100
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:78
doublereal m_deltaG_formation_pr_tr
Input Value of deltaG of Formation at Tr and Pr (cal gmol-1)
Definition: MineralEQ3.h:436
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:573
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:97
doublereal m_c
c coefficient (cal K gmol-1 K) x 10^-5
Definition: MineralEQ3.h:460
bool importPhase(XML_Node &phase, ThermoPhase *th, SpeciesThermoFactory *spfactory)
Import a phase information into an empty ThermoPhase object.
doublereal m_a
a coefficient (cal gmol-1 K-1)
Definition: MineralEQ3.h:454
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
Definition: stringUtils.cpp:28
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:99
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:563
#define ENTROPY298_UNKNOWN
Number indicating we don't know the entropy of the element in its most stable state at 298...
Definition: Elements.h:84
doublereal m_V0_pr_tr
Input Value of the molar volume at T_r and P_r.
Definition: MineralEQ3.h:451
doublereal m_b
b coefficient (cal gmol-1 K-2) x 10^3
Definition: MineralEQ3.h:457
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:194
doublereal getFloatDefaultUnits(const XML_Node &parent, const std::string &name, const std::string &defaultUnits, const std::string &type)
Get a floating-point value from a child element with a defined units field.
Definition: ctml.cpp:264
Class MineralEQ3 represents a stoichiometric (fixed composition) incompressible substance based on EQ...
Definition: MineralEQ3.h:94
XML_Node * get_XML_NameID(const std::string &nameTarget, const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
Definition: global.cpp:252
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
Definition: xml.cpp:568
doublereal m_Mu0_pr_tr
Value of the Absolute Gibbs Free Energy NIST scale at T_r and P_r.
Definition: MineralEQ3.h:421