Cantera  2.3.0
WaterSSTP.cpp
Go to the documentation of this file.
1 /**
2  * @file WaterSSTP.cpp
3  * Definitions for a ThermoPhase class consisting of pure water (see \ref thermoprops
4  * and class \link Cantera::WaterSSTP WaterSSTP\endlink).
5  */
6 
7 // This file is part of Cantera. See License.txt in the top-level directory or
8 // at http://www.cantera.org/license.txt for license and copyright information.
9 
13 
14 using namespace std;
15 
16 namespace Cantera
17 {
18 WaterSSTP::WaterSSTP() :
19  m_mw(0.0),
20  EW_Offset(0.0),
21  SW_Offset(0.0),
22  m_ready(false),
23  m_allowGasPhase(false)
24 {
25 }
26 
27 WaterSSTP::WaterSSTP(const std::string& inputFile, const std::string& id) :
28  m_mw(0.0),
29  EW_Offset(0.0),
30  SW_Offset(0.0),
31  m_ready(false),
32  m_allowGasPhase(false)
33 {
34  initThermoFile(inputFile, id);
35 }
36 
37 WaterSSTP::WaterSSTP(XML_Node& phaseRoot, const std::string& id) :
38  m_mw(0.0),
39  EW_Offset(0.0),
40  SW_Offset(0.0),
41  m_ready(false),
42  m_allowGasPhase(false)
43 {
44  importPhase(phaseRoot, this);
45 }
46 
48  SingleSpeciesTP(b),
49  m_mw(b.m_mw),
50  EW_Offset(b.EW_Offset),
51  SW_Offset(b.SW_Offset),
52  m_ready(false),
53  m_allowGasPhase(b.m_allowGasPhase)
54 {
55  m_waterProps.reset(new WaterProps(&m_sub));
56 
57  // Use the assignment operator to do the brunt of the work for the copy
58  // constructor.
59  *this = b;
60 }
61 
62 WaterSSTP& WaterSSTP::operator=(const WaterSSTP& b)
63 {
64  if (&b == this) {
65  return *this;
66  }
67  m_sub = b.m_sub;
68  m_waterProps.reset(new WaterProps(&m_sub));
69 
70  m_mw = b.m_mw;
71  m_ready = b.m_ready;
72  m_allowGasPhase = b.m_allowGasPhase;
73  return *this;
74 }
75 
77 {
78  return new WaterSSTP(*this);
79 }
80 
81 void WaterSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id)
82 {
83  // Do initializations that don't depend on knowing the XML file
84  initThermo();
85 
86  // Calculate the molecular weight. Note while there may be a very good
87  // calculated weight in the steam table class, using this weight may lead to
88  // codes exhibiting mass loss issues. We need to grab the elemental atomic
89  // weights used in the Element class and calculate a consistent H2O
90  // molecular weight based on that.
91  size_t nH = elementIndex("H");
92  if (nH == npos) {
93  throw CanteraError("WaterSSTP::initThermo",
94  "H not an element");
95  }
96  double mw_H = atomicWeight(nH);
97  size_t nO = elementIndex("O");
98  if (nO == npos) {
99  throw CanteraError("WaterSSTP::initThermo",
100  "O not an element");
101  }
102  double mw_O = atomicWeight(nO);
103  m_mw = 2.0 * mw_H + mw_O;
105  double one = 1.0;
106  setMoleFractions(&one);
107 
108  // Set the baseline
109  doublereal T = 298.15;
110  Phase::setDensity(7.0E-8);
112 
113  doublereal presLow = 1.0E-2;
114  doublereal oneBar = 1.0E5;
115  doublereal dd = m_sub.density(T, presLow, WATER_GAS, 7.0E-8);
116  setDensity(dd);
117  setTemperature(T);
118  SW_Offset = 0.0;
119  doublereal s = entropy_mole();
120  s -= GasConstant * log(oneBar/presLow);
121  if (s != 188.835E3) {
122  SW_Offset = 188.835E3 - s;
123  }
124  s = entropy_mole();
125  s -= GasConstant * log(oneBar/presLow);
126 
127  doublereal h = enthalpy_mole();
128  if (h != -241.826E6) {
129  EW_Offset = -241.826E6 - h;
130  }
131  h = enthalpy_mole();
132 
133  // Set the initial state of the system to 298.15 K and 1 bar.
134  setTemperature(298.15);
135  double rho0 = m_sub.density(298.15, OneAtm, WATER_LIQUID);
136  setDensity(rho0);
137 
138  m_waterProps.reset(new WaterProps(&m_sub));
139 
140  // We have to do something with the thermo function here.
141  delete m_spthermo;
142  m_spthermo = 0;
143 
144  // Set the flag to say we are ready to calculate stuff
145  m_ready = true;
146 }
147 
149 {
150  eosdata._require("model","PureLiquidWater");
151 }
152 
153 void WaterSSTP::getEnthalpy_RT(doublereal* hrt) const
154 {
155  *hrt = (m_sub.enthalpy() + EW_Offset) / RT();
156 }
157 
158 void WaterSSTP::getIntEnergy_RT(doublereal* ubar) const
159 {
160  *ubar = (m_sub.intEnergy() + EW_Offset)/GasConstant;
161 }
162 
163 void WaterSSTP::getEntropy_R(doublereal* sr) const
164 {
165  sr[0] = (m_sub.entropy() + SW_Offset) / GasConstant;
166 }
167 
168 void WaterSSTP::getGibbs_RT(doublereal* grt) const
169 {
170  *grt = (m_sub.Gibbs() + EW_Offset) / RT() - SW_Offset / GasConstant;
171  if (!m_ready) {
172  throw CanteraError("waterSSTP::", "Phase not ready");
173  }
174 }
175 
176 void WaterSSTP::getStandardChemPotentials(doublereal* gss) const
177 {
178  *gss = (m_sub.Gibbs() + EW_Offset - SW_Offset*temperature());
179  if (!m_ready) {
180  throw CanteraError("waterSSTP::", "Phase not ready");
181  }
182 }
183 
184 void WaterSSTP::getCp_R(doublereal* cpr) const
185 {
186  cpr[0] = m_sub.cp() / GasConstant;
187 }
188 
189 doublereal WaterSSTP::cv_mole() const
190 {
191  return m_sub.cv();
192 }
193 
194 void WaterSSTP::getEnthalpy_RT_ref(doublereal* hrt) const
195 {
196  doublereal p = pressure();
197  double T = temperature();
198  double dens = density();
199  int waterState = WATER_GAS;
200  double rc = m_sub.Rhocrit();
201  if (dens > rc) {
202  waterState = WATER_LIQUID;
203  }
204  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
205  if (dd <= 0.0) {
206  throw CanteraError("setPressure", "error");
207  }
208  doublereal h = m_sub.enthalpy();
209  *hrt = (h + EW_Offset) / RT();
210  dd = m_sub.density(T, p, waterState, dens);
211 }
212 
213 void WaterSSTP::getGibbs_RT_ref(doublereal* grt) const
214 {
215  doublereal p = pressure();
216  double T = temperature();
217  double dens = density();
218  int waterState = WATER_GAS;
219  double rc = m_sub.Rhocrit();
220  if (dens > rc) {
221  waterState = WATER_LIQUID;
222  }
223  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
224  if (dd <= 0.0) {
225  throw CanteraError("setPressure", "error");
226  }
227  m_sub.setState_TR(T, dd);
228  doublereal g = m_sub.Gibbs();
229  *grt = (g + EW_Offset - SW_Offset*T)/ RT();
230  dd = m_sub.density(T, p, waterState, dens);
231 }
232 
233 void WaterSSTP::getGibbs_ref(doublereal* g) const
234 {
235  getGibbs_RT_ref(g);
236  for (size_t k = 0; k < m_kk; k++) {
237  g[k] *= RT();
238  }
239 }
240 
241 void WaterSSTP::getEntropy_R_ref(doublereal* sr) const
242 {
243  doublereal p = pressure();
244  double T = temperature();
245  double dens = density();
246  int waterState = WATER_GAS;
247  double rc = m_sub.Rhocrit();
248  if (dens > rc) {
249  waterState = WATER_LIQUID;
250  }
251  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
252 
253  if (dd <= 0.0) {
254  throw CanteraError("setPressure", "error");
255  }
256  m_sub.setState_TR(T, dd);
257 
258  doublereal s = m_sub.entropy();
259  *sr = (s + SW_Offset)/ GasConstant;
260  dd = m_sub.density(T, p, waterState, dens);
261 }
262 
263 void WaterSSTP::getCp_R_ref(doublereal* cpr) const
264 {
265  doublereal p = pressure();
266  double T = temperature();
267  double dens = density();
268  int waterState = WATER_GAS;
269  double rc = m_sub.Rhocrit();
270  if (dens > rc) {
271  waterState = WATER_LIQUID;
272  }
273  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
274  m_sub.setState_TR(T, dd);
275  if (dd <= 0.0) {
276  throw CanteraError("setPressure", "error");
277  }
278  doublereal cp = m_sub.cp();
279  *cpr = cp / GasConstant;
280  dd = m_sub.density(T, p, waterState, dens);
281 }
282 
283 void WaterSSTP::getStandardVolumes_ref(doublereal* vol) const
284 {
285  doublereal p = pressure();
286  double T = temperature();
287  double dens = density();
288  int waterState = WATER_GAS;
289  double rc = m_sub.Rhocrit();
290  if (dens > rc) {
291  waterState = WATER_LIQUID;
292  }
293  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
294  if (dd <= 0.0) {
295  throw CanteraError("setPressure", "error");
296  }
297  *vol = meanMolecularWeight() /dd;
298  dd = m_sub.density(T, p, waterState, dens);
299 }
300 
301 doublereal WaterSSTP::pressure() const
302 {
303  return m_sub.pressure();
304 }
305 
306 void WaterSSTP::setPressure(doublereal p)
307 {
308  double T = temperature();
309  double dens = density();
310  int waterState = WATER_GAS;
311  double rc = m_sub.Rhocrit();
312  if (dens > rc) {
313  waterState = WATER_LIQUID;
314  }
315  doublereal dd = m_sub.density(T, p, waterState, dens);
316  if (dd <= 0.0) {
317  throw CanteraError("setPressure", "error");
318  }
319  setDensity(dd);
320 }
321 
323 {
325 }
326 
328 {
329  return m_sub.coeffThermExp();
330 }
331 
333 {
334  doublereal pres = pressure();
335  doublereal dens_save = density();
336  double T = temperature();
337  double tt = T - 0.04;
338  doublereal dd = m_sub.density(tt, pres, WATER_LIQUID, dens_save);
339  if (dd < 0.0) {
340  throw CanteraError("WaterSSTP::dthermalExpansionCoeffdT",
341  "Unable to solve for the density at T = {}, P = {}", tt, pres);
342  }
343  doublereal vald = m_sub.coeffThermExp();
344  m_sub.setState_TR(T, dens_save);
345  doublereal val2 = m_sub.coeffThermExp();
346  return (val2 - vald) / 0.04;
347 }
348 
349 doublereal WaterSSTP::critTemperature() const
350 {
351  return m_sub.Tcrit();
352 }
353 
354 doublereal WaterSSTP::critPressure() const
355 {
356  return m_sub.Pcrit();
357 }
358 
359 doublereal WaterSSTP::critDensity() const
360 {
361  return m_sub.Rhocrit();
362 }
363 
364 void WaterSSTP::setTemperature(const doublereal temp)
365 {
366  Phase::setTemperature(temp);
367  m_sub.setState_TR(temp, density());
368 }
369 
370 void WaterSSTP::setDensity(const doublereal dens)
371 {
372  Phase::setDensity(dens);
373  m_sub.setState_TR(temperature(), dens);
374 }
375 
376 doublereal WaterSSTP::satPressure(doublereal t) {
377  doublereal tsave = temperature();
378  doublereal dsave = density();
379  doublereal pp = m_sub.psat(t);
380  m_sub.setState_TR(tsave, dsave);
381  return pp;
382 }
383 
384 doublereal WaterSSTP::vaporFraction() const
385 {
386  if (temperature() >= m_sub.Tcrit()) {
387  double dens = density();
388  if (dens >= m_sub.Rhocrit()) {
389  return 0.0;
390  }
391  return 1.0;
392  }
393  // If below tcrit we always return 0 from this class
394  return 0.0;
395 }
396 
397 }
virtual void getEnthalpy_RT_ref(doublereal *hrt) const
Definition: WaterSSTP.cpp:194
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
Definition: WaterSSTP.cpp:184
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
Definition: WaterSSTP.cpp:189
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Definition: WaterSSTP.cpp:153
virtual doublereal critPressure() const
Critical pressure (Pa).
Definition: WaterSSTP.cpp:354
virtual doublereal isothermalCompressibility() const
Returns the isothermal compressibility. Units: 1/Pa.
Definition: WaterSSTP.cpp:322
virtual void setDensity(const doublereal dens)
Set the density of the phase.
Definition: WaterSSTP.cpp:370
const doublereal OneAtm
One atmosphere [Pa].
Definition: ct_defs.h:69
doublereal temperature() const
Temperature (K).
Definition: Phase.h:601
doublereal enthalpy() const
Calculate the enthalpy in mks units of J kmol-1 using the last temperature and density.
doublereal Pcrit() const
Returns the critical pressure of water (22.064E6 Pa)
void setState_TR(doublereal temperature, doublereal rho)
Set the internal state of the object wrt temperature and density.
doublereal intEnergy() const
Calculate the internal energy in mks units of J kmol-1.
virtual ThermoPhase * duplMyselfAsThermoPhase() const
Duplication routine for objects which inherit from ThermoPhase.
Definition: WaterSSTP.cpp:76
doublereal entropy() const
Calculate the entropy in mks units of J kmol-1 K-1.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
virtual void setPressure(doublereal p)
Set the internally stored pressure (Pa) at constant temperature and composition.
Definition: WaterSSTP.cpp:306
size_t elementIndex(const std::string &name) const
Return the index of element named &#39;name&#39;.
Definition: Phase.cpp:186
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
doublereal density(doublereal temperature, doublereal pressure, int phase=-1, doublereal rhoguess=-1.0)
Calculates the density given the temperature and the pressure, and a guess at the density...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
Definition: WaterSSTP.cpp:301
STL namespace.
virtual doublereal density() const
Density (kg/m^3).
Definition: Phase.h:607
virtual void getEntropy_R_ref(doublereal *er) const
Returns the vector of nondimensional entropies of the reference state at the current temperature of t...
Definition: WaterSSTP.cpp:241
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
Definition: WaterSSTP.cpp:148
WaterSSTP()
Base constructor.
Definition: WaterSSTP.cpp:18
WaterPropsIAPWS m_sub
WaterPropsIAPWS that calculates the real properties of water.
Definition: WaterSSTP.h:251
virtual void getStandardVolumes_ref(doublereal *vol) const
Get the molar volumes of the species reference states at the current T and P_ref of the solution...
Definition: WaterSSTP.cpp:283
Declares a ThermoPhase class consisting of pure water (see Thermodynamic Properties and class WaterSS...
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:809
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
virtual doublereal critDensity() const
Critical density (kg/m3).
Definition: WaterSSTP.cpp:359
doublereal pressure() const
Calculates the pressure (Pascals), given the current value of the temperature and density...
doublereal cp() const
Calculate the constant pressure heat capacity in mks units of J kmol-1 K-1 at the last temperature an...
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
Definition: WaterSSTP.cpp:81
doublereal Rhocrit() const
Return the critical density of water (kg m-3)
doublereal atomicWeight(size_t m) const
Atomic weight of element m.
Definition: Phase.cpp:201
void _require(const std::string &a, const std::string &v) const
Require that the current XML node have an attribute named by the first argument, a, and that this attribute have the the string value listed in the second argument, v.
Definition: xml.cpp:576
doublereal EW_Offset
Offset constants used to obtain consistency with the NIST database.
Definition: WaterSSTP.h:269
virtual void getStandardChemPotentials(doublereal *gss) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
Definition: WaterSSTP.cpp:176
doublereal isothermalCompressibility() const
Returns the coefficient of isothermal compressibility for the state of the object.
virtual doublereal vaporFraction() const
Return the fraction of vapor at the current conditions.
Definition: WaterSSTP.cpp:384
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
Definition: WaterSSTP.cpp:163
The WaterProps class is used to house several approximation routines for properties of water...
Definition: WaterProps.h:93
doublereal m_mw
Molecular weight of Water -> Cantera assumption.
Definition: WaterSSTP.h:262
virtual doublereal critTemperature() const
Critical temperature (K).
Definition: WaterSSTP.cpp:349
virtual doublereal dthermalExpansionCoeffdT() const
Return the derivative of the volumetric thermal expansion coefficient.
Definition: WaterSSTP.cpp:332
Class for single-component water.
Definition: WaterSSTP.h:114
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
virtual doublereal satPressure(doublereal t)
Return the saturation pressure given the temperature.
Definition: WaterSSTP.cpp:376
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
virtual doublereal thermalExpansionCoeff() const
Return the volumetric thermal expansion coefficient. Units: 1/K.
Definition: WaterSSTP.cpp:327
MultiSpeciesThermo * m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
Definition: ThermoPhase.h:1693
doublereal coeffThermExp() const
Returns the coefficient of thermal expansion.
void setMolecularWeight(const int k, const double mw)
Set the molecular weight of a single species to a given value.
Definition: Phase.h:770
virtual void getGibbs_RT_ref(doublereal *grt) const
Returns the vector of nondimensional Gibbs Free Energies of the reference state at the current temper...
Definition: WaterSSTP.cpp:213
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:661
virtual void setTemperature(const doublereal temp)
Set the temperature of the phase.
Definition: WaterSSTP.cpp:364
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
Definition: Phase.h:637
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
virtual void getGibbs_ref(doublereal *g) const
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
Definition: WaterSSTP.cpp:233
doublereal Tcrit() const
Returns the critical temperature of water (Kelvin)
Contains declarations for string manipulation functions within Cantera.
doublereal SW_Offset
Offset constant used to obtain consistency with NIST convention.
Definition: WaterSSTP.h:276
doublereal Gibbs() const
Calculate the Gibbs free energy in mks units of J kmol-1 K-1.
size_t m_kk
Number of species in the phase.
Definition: Phase.h:784
doublereal cv() const
Calculate the constant volume heat capacity in mks units of J kmol-1 K-1 at the last temperature and ...
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void getCp_R_ref(doublereal *cprt) const
Returns the vector of nondimensional constant pressure heat capacities of the reference state at the ...
Definition: WaterSSTP.cpp:263
Namespace for the Cantera kernel.
Definition: application.cpp:29
std::unique_ptr< WaterProps > m_waterProps
Pointer to the WaterProps object.
Definition: WaterSSTP.h:259
virtual void getGibbs_RT(doublereal *grt) const
Get the nondimensional Gibbs functions for the species in their standard states at the current T and ...
Definition: WaterSSTP.cpp:168
bool m_allowGasPhase
Since this phase represents a liquid phase, it&#39;s an error to return a gas-phase answer.
Definition: WaterSSTP.h:287
The SingleSpeciesTP class is a filter class for ThermoPhase.
virtual void setDensity(const doublereal density_)
Set the internally stored density (kg/m^3) of the phase.
Definition: Phase.h:622
doublereal psat(doublereal temperature, int waterState=WATER_LIQUID)
This function returns the saturation pressure given the temperature as an input parameter, and sets the internal state to the saturated conditions.
virtual void setMoleFractions(const doublereal *const x)
Mole fractions are fixed, with x[0] = 1.0.
virtual void getIntEnergy_RT(doublereal *urt) const
Returns the vector of nondimensional Internal Energies of the standard state species at the current T...
Definition: WaterSSTP.cpp:158
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
bool m_ready
Boolean is true if object has been properly initialized for calculation.
Definition: WaterSSTP.h:279