Cantera  2.5.1
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 https://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 
47 std::string WaterSSTP::phaseOfMatter() const {
48  const vector<std::string> phases = {
49  "gas", "liquid", "supercritical", "unstable-liquid", "unstable-gas"
50  };
51  return phases[m_sub.phaseState()];
52 }
53 
55 {
57 
58  // Calculate the molecular weight. Note while there may be a very good
59  // calculated weight in the steam table class, using this weight may lead to
60  // codes exhibiting mass loss issues. We need to grab the elemental atomic
61  // weights used in the Element class and calculate a consistent H2O
62  // molecular weight based on that.
63  size_t nH = elementIndex("H");
64  if (nH == npos) {
65  throw CanteraError("WaterSSTP::initThermo",
66  "H not an element");
67  }
68  double mw_H = atomicWeight(nH);
69  size_t nO = elementIndex("O");
70  if (nO == npos) {
71  throw CanteraError("WaterSSTP::initThermo",
72  "O not an element");
73  }
74  double mw_O = atomicWeight(nO);
75  m_mw = 2.0 * mw_H + mw_O;
77 
78  // Set the baseline
79  doublereal T = 298.15;
80  Phase::setDensity(7.0E-8);
82 
83  doublereal presLow = 1.0E-2;
84  doublereal oneBar = 1.0E5;
85  doublereal dd = m_sub.density(T, presLow, WATER_GAS, 7.0E-8);
86  setDensity(dd);
87  setTemperature(T);
88  SW_Offset = 0.0;
89  doublereal s = entropy_mole();
90  s -= GasConstant * log(oneBar/presLow);
91  if (s != 188.835E3) {
92  SW_Offset = 188.835E3 - s;
93  }
94  s = entropy_mole();
95  s -= GasConstant * log(oneBar/presLow);
96 
97  doublereal h = enthalpy_mole();
98  if (h != -241.826E6) {
99  EW_Offset = -241.826E6 - h;
100  }
101  h = enthalpy_mole();
102 
103  // Set the initial state of the system to 298.15 K and 1 bar.
104  setTemperature(298.15);
105  double rho0 = m_sub.density(298.15, OneAtm, WATER_LIQUID);
106  setDensity(rho0);
107 
108  m_waterProps.reset(new WaterProps(&m_sub));
109 
110  // Set the flag to say we are ready to calculate stuff
111  m_ready = true;
112 }
113 
115 {
116  eosdata._require("model","PureLiquidWater");
117 }
118 
119 void WaterSSTP::getEnthalpy_RT(doublereal* hrt) const
120 {
121  *hrt = (m_sub.enthalpy() + EW_Offset) / RT();
122 }
123 
124 void WaterSSTP::getIntEnergy_RT(doublereal* ubar) const
125 {
126  *ubar = (m_sub.intEnergy() + EW_Offset)/GasConstant;
127 }
128 
129 void WaterSSTP::getEntropy_R(doublereal* sr) const
130 {
131  sr[0] = (m_sub.entropy() + SW_Offset) / GasConstant;
132 }
133 
134 void WaterSSTP::getGibbs_RT(doublereal* grt) const
135 {
136  *grt = (m_sub.Gibbs() + EW_Offset) / RT() - SW_Offset / GasConstant;
137  if (!m_ready) {
138  throw CanteraError("waterSSTP::getGibbs_RT", "Phase not ready");
139  }
140 }
141 
142 void WaterSSTP::getStandardChemPotentials(doublereal* gss) const
143 {
144  *gss = (m_sub.Gibbs() + EW_Offset - SW_Offset*temperature());
145  if (!m_ready) {
146  throw CanteraError("waterSSTP::getStandardChemPotentials",
147  "Phase not ready");
148  }
149 }
150 
151 void WaterSSTP::getCp_R(doublereal* cpr) const
152 {
153  cpr[0] = m_sub.cp() / GasConstant;
154 }
155 
156 doublereal WaterSSTP::cv_mole() const
157 {
158  return m_sub.cv();
159 }
160 
161 void WaterSSTP::getEnthalpy_RT_ref(doublereal* hrt) const
162 {
163  doublereal p = pressure();
164  double T = temperature();
165  double dens = density();
166  int waterState = WATER_GAS;
167  double rc = m_sub.Rhocrit();
168  if (dens > rc) {
169  waterState = WATER_LIQUID;
170  }
171  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
172  if (dd <= 0.0) {
173  throw CanteraError("WaterSSTP::getEnthalpy_RT_ref", "error");
174  }
175  doublereal h = m_sub.enthalpy();
176  *hrt = (h + EW_Offset) / RT();
177  dd = m_sub.density(T, p, waterState, dens);
178 }
179 
180 void WaterSSTP::getGibbs_RT_ref(doublereal* grt) const
181 {
182  doublereal p = pressure();
183  double T = temperature();
184  double dens = density();
185  int waterState = WATER_GAS;
186  double rc = m_sub.Rhocrit();
187  if (dens > rc) {
188  waterState = WATER_LIQUID;
189  }
190  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
191  if (dd <= 0.0) {
192  throw CanteraError("WaterSSTP::getGibbs_RT_ref", "error");
193  }
194  m_sub.setState_TR(T, dd);
195  doublereal g = m_sub.Gibbs();
196  *grt = (g + EW_Offset - SW_Offset*T)/ RT();
197  dd = m_sub.density(T, p, waterState, dens);
198 }
199 
200 void WaterSSTP::getGibbs_ref(doublereal* g) const
201 {
202  getGibbs_RT_ref(g);
203  for (size_t k = 0; k < m_kk; k++) {
204  g[k] *= RT();
205  }
206 }
207 
208 void WaterSSTP::getEntropy_R_ref(doublereal* sr) const
209 {
210  doublereal p = pressure();
211  double T = temperature();
212  double dens = density();
213  int waterState = WATER_GAS;
214  double rc = m_sub.Rhocrit();
215  if (dens > rc) {
216  waterState = WATER_LIQUID;
217  }
218  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
219 
220  if (dd <= 0.0) {
221  throw CanteraError("WaterSSTP::getEntropy_R_ref", "error");
222  }
223  m_sub.setState_TR(T, dd);
224 
225  doublereal s = m_sub.entropy();
226  *sr = (s + SW_Offset)/ GasConstant;
227  dd = m_sub.density(T, p, waterState, dens);
228 }
229 
230 void WaterSSTP::getCp_R_ref(doublereal* cpr) const
231 {
232  doublereal p = pressure();
233  double T = temperature();
234  double dens = density();
235  int waterState = WATER_GAS;
236  double rc = m_sub.Rhocrit();
237  if (dens > rc) {
238  waterState = WATER_LIQUID;
239  }
240  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
241  m_sub.setState_TR(T, dd);
242  if (dd <= 0.0) {
243  throw CanteraError("WaterSSTP::getCp_R_ref", "error");
244  }
245  doublereal cp = m_sub.cp();
246  *cpr = cp / GasConstant;
247  dd = m_sub.density(T, p, waterState, dens);
248 }
249 
250 void WaterSSTP::getStandardVolumes_ref(doublereal* vol) const
251 {
252  doublereal p = pressure();
253  double T = temperature();
254  double dens = density();
255  int waterState = WATER_GAS;
256  double rc = m_sub.Rhocrit();
257  if (dens > rc) {
258  waterState = WATER_LIQUID;
259  }
260  doublereal dd = m_sub.density(T, OneAtm, waterState, dens);
261  if (dd <= 0.0) {
262  throw CanteraError("WaterSSTP::getStandardVolumes_ref", "error");
263  }
264  *vol = meanMolecularWeight() /dd;
265  dd = m_sub.density(T, p, waterState, dens);
266 }
267 
268 doublereal WaterSSTP::pressure() const
269 {
270  return m_sub.pressure();
271 }
272 
273 void WaterSSTP::setPressure(doublereal p)
274 {
275  double T = temperature();
276  double dens = density();
277  double pp = m_sub.psat(T);
278  int waterState = WATER_SUPERCRIT;
279  if (T < m_sub.Tcrit()) {
280  if (p >= pp) {
281  waterState = WATER_LIQUID;
282  dens = 1000.;
283  } else if (!m_allowGasPhase) {
284  throw CanteraError("WaterSSTP::setPressure",
285  "Model assumes liquid phase; pressure p = {} lies below\n"
286  "the saturation pressure (P_sat = {}).", p, pp);
287  }
288  }
289 
290  double dd = m_sub.density(T, p, waterState, dens);
291  if (dd <= 0.0) {
292  throw CanteraError("WaterSSTP::setPressure", "Error");
293  }
294  setDensity(dd);
295 }
296 
298 {
300 }
301 
303 {
304  return m_sub.coeffThermExp();
305 }
306 
308 {
309  doublereal pres = pressure();
310  doublereal dens_save = density();
311  double T = temperature();
312  double tt = T - 0.04;
313  doublereal dd = m_sub.density(tt, pres, WATER_LIQUID, dens_save);
314  if (dd < 0.0) {
315  throw CanteraError("WaterSSTP::dthermalExpansionCoeffdT",
316  "Unable to solve for the density at T = {}, P = {}", tt, pres);
317  }
318  doublereal vald = m_sub.coeffThermExp();
319  m_sub.setState_TR(T, dens_save);
320  doublereal val2 = m_sub.coeffThermExp();
321  return (val2 - vald) / 0.04;
322 }
323 
324 doublereal WaterSSTP::critTemperature() const
325 {
326  return m_sub.Tcrit();
327 }
328 
329 doublereal WaterSSTP::critPressure() const
330 {
331  return m_sub.Pcrit();
332 }
333 
334 doublereal WaterSSTP::critDensity() const
335 {
336  return m_sub.Rhocrit();
337 }
338 
339 void WaterSSTP::setTemperature(const doublereal temp)
340 {
341  if (temp < 273.16) {
342  throw CanteraError("WaterSSTP::setTemperature",
343  "Model assumes liquid phase; temperature T = {} lies below\n"
344  "the triple point temperature (T_triple = 273.16).", temp);
345  }
346  Phase::setTemperature(temp);
347  m_sub.setState_TR(temp, density());
348 }
349 
350 void WaterSSTP::setDensity(const doublereal dens)
351 {
352  Phase::setDensity(dens);
353  m_sub.setState_TR(temperature(), dens);
354 }
355 
356 doublereal WaterSSTP::satPressure(doublereal t) {
357  doublereal tsave = temperature();
358  doublereal dsave = density();
359  doublereal pp = m_sub.psat(t);
360  m_sub.setState_TR(tsave, dsave);
361  return pp;
362 }
363 
364 doublereal WaterSSTP::vaporFraction() const
365 {
366  if (temperature() >= m_sub.Tcrit()) {
367  double dens = density();
368  if (dens >= m_sub.Rhocrit()) {
369  return 0.0;
370  }
371  return 1.0;
372  }
373  // If below tcrit we always return 0 from this class
374  return 0.0;
375 }
376 
377 }
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
Declares a ThermoPhase class consisting of pure water (see Thermodynamic Properties and class WaterSS...
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
size_t m_kk
Number of species in the phase.
Definition: Phase.h:942
doublereal atomicWeight(size_t m) const
Atomic weight of element m.
Definition: Phase.cpp:135
size_t elementIndex(const std::string &name) const
Return the index of element named 'name'.
Definition: Phase.cpp:120
virtual void setDensity(const double density_)
Set the internally stored density (kg/m^3) of the phase.
Definition: Phase.cpp:716
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:748
virtual double density() const
Density (kg/m^3).
Definition: Phase.h:685
doublereal temperature() const
Temperature (K).
Definition: Phase.h:667
void setMolecularWeight(const int k, const double mw)
Set the molecular weight of a single species to a given value.
Definition: Phase.cpp:1018
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
Definition: Phase.h:724
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:776
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
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.
doublereal coeffThermExp() const
Returns the coefficient of thermal expansion.
doublereal cp() const
Calculate the constant pressure heat capacity in mks units of J kmol-1 K-1 at the last temperature an...
doublereal pressure() const
Calculates the pressure (Pascals), given the current value of the temperature and density.
doublereal enthalpy() const
Calculate the enthalpy in mks units of J kmol-1 using the last temperature and density.
doublereal Tcrit() const
Returns the critical temperature of water (Kelvin)
doublereal cv() const
Calculate the constant volume heat capacity in mks units of J kmol-1 K-1 at the last temperature and ...
doublereal entropy() const
Calculate the entropy in mks units of J kmol-1 K-1.
doublereal intEnergy() const
Calculate the internal energy in mks units of J kmol-1.
doublereal Rhocrit() const
Return the critical density of water (kg m-3)
doublereal Gibbs() const
Calculate the Gibbs free energy in mks units of J kmol-1 K-1.
doublereal psat(doublereal temperature, int waterState=WATER_LIQUID)
This function returns the saturation pressure given the temperature as an input parameter,...
void setState_TR(doublereal temperature, doublereal rho)
Set the internal state of the object wrt temperature and density.
int phaseState(bool checkState=false) const
Returns the Phase State flag for the current state of the object.
doublereal isothermalCompressibility() const
Returns the coefficient of isothermal compressibility for the state of the object.
doublereal Pcrit() const
Returns the critical pressure of water (22.064E6 Pa)
The WaterProps class is used to house several approximation routines for properties of water.
Definition: WaterProps.h:100
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:180
WaterSSTP()
Base constructor.
Definition: WaterSSTP.cpp:18
WaterPropsIAPWS m_sub
WaterPropsIAPWS that calculates the real properties of water.
Definition: WaterSSTP.h:261
bool m_ready
Boolean is true if object has been properly initialized for calculation.
Definition: WaterSSTP.h:289
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:134
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
Definition: WaterSSTP.cpp:268
virtual doublereal critPressure() const
Critical pressure (Pa).
Definition: WaterSSTP.cpp:329
doublereal EW_Offset
Offset constants used to obtain consistency with the NIST database.
Definition: WaterSSTP.h:279
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
Definition: WaterSSTP.cpp:156
virtual doublereal vaporFraction() const
Return the fraction of vapor at the current conditions.
Definition: WaterSSTP.cpp:364
virtual doublereal thermalExpansionCoeff() const
Return the volumetric thermal expansion coefficient. Units: 1/K.
Definition: WaterSSTP.cpp:302
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:151
virtual doublereal dthermalExpansionCoeffdT() const
Return the derivative of the volumetric thermal expansion coefficient.
Definition: WaterSSTP.cpp:307
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:129
virtual void setPressure(doublereal p)
Set the internally stored pressure (Pa) at constant temperature and composition.
Definition: WaterSSTP.cpp:273
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
Definition: WaterSSTP.cpp:54
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:142
virtual doublereal critTemperature() const
Critical temperature (K).
Definition: WaterSSTP.cpp:324
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:208
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:124
virtual void setTemperature(const doublereal temp)
Set the temperature of the phase.
Definition: WaterSSTP.cpp:339
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:230
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
Definition: WaterSSTP.cpp:114
doublereal m_mw
Molecular weight of Water -> Cantera assumption.
Definition: WaterSSTP.h:272
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:250
virtual void setDensity(const doublereal dens)
Set the density of the phase.
Definition: WaterSSTP.cpp:350
virtual doublereal satPressure(doublereal t)
Return the saturation pressure given the temperature.
Definition: WaterSSTP.cpp:356
doublereal SW_Offset
Offset constant used to obtain consistency with NIST convention.
Definition: WaterSSTP.h:286
bool m_allowGasPhase
Since this phase represents a liquid (or supercritical) phase, it is an error to return a gas-phase a...
Definition: WaterSSTP.h:297
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:200
std::unique_ptr< WaterProps > m_waterProps
Pointer to the WaterProps object.
Definition: WaterSSTP.h:269
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:119
virtual doublereal critDensity() const
Critical density (kg/m3).
Definition: WaterSSTP.cpp:334
virtual std::string phaseOfMatter() const
String indicating the mechanical phase of the matter in this Phase.
Definition: WaterSSTP.cpp:47
virtual void getEnthalpy_RT_ref(doublereal *hrt) const
Definition: WaterSSTP.cpp:161
virtual doublereal isothermalCompressibility() const
Returns the isothermal compressibility. Units: 1/Pa.
Definition: WaterSSTP.cpp:297
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:104
void _require(const std::string &a, const std::string &v) const
Require that the current XML node has an attribute named by the first argument, a,...
Definition: xml.cpp:576
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:188
const double OneAtm
One atmosphere [Pa].
Definition: ct_defs.h:78
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:109
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
Contains declarations for string manipulation functions within Cantera.