1 /**
2  *  @file WaterSSTP.h
3  * Declares 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 
10 #ifndef CT_WATERSSTP_H
11 #define CT_WATERSSTP_H
12 
13 #include "SingleSpeciesTP.h"
14 #include "cantera/thermo/WaterPropsIAPWS.h"
15 #include "cantera/thermo/WaterProps.h"
16 
17 namespace Cantera
18 {
19 
20 class WaterPropsIAPWS;
21 class WaterProps;
22 //! Class for single-component water. This is designed to cover just the liquid
23 //! and supercritical phases of water.
24 /*!
25  * The reference is W. Wagner, A. Pruss, "The IAPWS Formulation 1995 for the
26  * Thermodynamic Properties of Ordinary Water Substance for General and
27  * Scientific Use," J. Phys. Chem. Ref. Dat, 31, 387, 2002.
28  *
29  * ## Specification of Species Standard State Properties
30  *
31  * The offsets used in the steam tables are different than NIST's. They assume
32  * u_liq(TP) = 0.0, s_liq(TP) = 0.0, where TP is the triple point conditions:
33  *
34  *      -  u(273.16, rho)    = 0.0
35  *      -  s(273.16, rho)    = 0.0
36  *      -  psat(273.16)      = 611.655 Pascal
37  *      -  rho(273.16, psat) = 999.793 kg m-3
38  *
39  * These "steam table" assumptions are used by the WaterPropsIAPWS class.
40  * Therefore, offsets must be calculated to make the thermodynamic properties
41  * calculated within this class to be consistent with thermo properties within
42  * Cantera.
43  *
44  * The thermodynamic base state for water is set to the NIST basis here by
45  * specifying constants, #EW_Offset and #SW_Offset, one for energy quantities
46  * and one for entropy quantities. The offsets are specified so that the
47  * following properties hold:
48  *
49  * - Delta_Hfo_idealgas(298.15) = -241.826 kJ/gmol
50  * - So_idealgas(298.15, 1bar)  =  188.835 J/gmolK
51  *
52  * (From http://webbook.nist.gov)
53  *
54  * The "o" here refers to a hypothetical ideal gas state. The way we achieve
55  * this in practice is to evaluate at a very low pressure and then use the
56  * theoretical ideal gas results to scale up to higher pressures:
57  *
58  * Ho(1bar) = H(P0)
59  *
60  * So(1bar) = S(P0) + RT ln(1bar/P0)
61  *
62  * ## %Application within Kinetics Managers
63  *
64  * This is unimplemented.
65  *
66  * ## Instantiation of the Class
67  *
68  * A new WaterSSTP object may be created by the following code snippets,
69  * combined with an XML file given in the XML example section.
70  *
71  * @code
72  *      ThermoPhase* w = newPhase("waterSSTPphase.xml");
73  * @endcode
74  *
75  * or
76  *
77  * @code
78  *      WaterSSTP *w = new WaterSSTP("waterSSTPphase.xml","");
79  * @endcode
80  *
81  * or
82  *
83  * @code
84  *    XML_Node *xm = get_XML_NameID("phase", "waterSSTPphase.xml#water", 0);
85  *    WaterSSTP *w = new WaterSSTP(*xm);
86  * @endcode
87  *
88  * or by the following call to importPhase():
89  *
90  * @code
91  *    XML_Node *xm = get_XML_NameID("phase", "waterSSTPphase.xml#water", 0);
92  *    WaterSSTP water;
93  *    importPhase(*xm, &water);
94  * @endcode
95  *
96  * ## XML Example
97  *
98  * An example of an XML Element named phase setting up a WaterSSTP object with
99  * id "water" is given below.
100  *
101  * @code
102  * <!-- phase water     -->
103  * <phase dim="3" id="water">
104  *   <elementArray datasrc="elements.xml">O  H </elementArray>
105  *   <speciesArray datasrc="#species_data">H2O</speciesArray>
106  *   <state>
107  *     <temperature units="K">300.0</temperature>
108  *     <pressure units="Pa">101325.0</pressure>
109  *   </state>
110  *   <thermo model="PureLiquidWater"/>
111  *   <kinetics model="none"/>
112  * </phase>
113  * @endcode
114  *
115  *  Note the model "PureLiquidWater" indicates the usage of the WaterSSTP object.
116  *
117  * @ingroup thermoprops
118  */
119 class WaterSSTP : public SingleSpeciesTP
120 {
121 public:
122     //! Full constructor for a water phase
123     /*!
124      * @param inputFile String name of the input file
125      * @param id        string id of the phase name
126      */
127     explicit WaterSSTP(const std::string& inputFile="",
128                        const std::string& id="");
129 
130     //! Full constructor for a water phase
131     /*!
132      * @param phaseRef  XML node referencing the water phase.
133      * @param id        string id of the phase name
134      *
135      * @deprecated The XML input format is deprecated and will be removed in
136      *     Cantera 3.0.
137      */
138     explicit WaterSSTP(XML_Node& phaseRef, const std::string& id = "");
139 
type()140     virtual std::string type() const {
141         return "liquid-water-IAPWS95";
142     }
143 
144     virtual std::string phaseOfMatter() const;
145 
146     //! @name  Molar Thermodynamic Properties of the Solution
147     //! @{
148 
149     virtual doublereal cv_mole() const;
150 
151     //@}
152     /// @name Mechanical Equation of State Properties
153     //@{
154 
155     virtual doublereal pressure() const;
156     virtual void setPressure(doublereal p);
157     virtual doublereal isothermalCompressibility() const;
158     virtual doublereal thermalExpansionCoeff() const;
159 
160     //! Return the derivative of the volumetric thermal expansion coefficient.
161     //! Units: 1/K2.
162     virtual doublereal dthermalExpansionCoeffdT() const;
163 
164     //! @}
165     //! @name Properties of the Standard State of the Species in the Solution
166     //! @{
167 
168     virtual void getStandardChemPotentials(doublereal* gss) const;
169     virtual void getGibbs_RT(doublereal* grt) const;
170     virtual void getEnthalpy_RT(doublereal* hrt) const;
171     virtual void getEntropy_R(doublereal* sr) const;
172     virtual void getCp_R(doublereal* cpr) const;
173     virtual void getIntEnergy_RT(doublereal* urt) const;
174 
175     //@}
176     //! @name Thermodynamic Values for the Species Reference State
177     /*!
178      *  All functions in this group need to be overridden, because the
179      *  m_spthermo MultiSpeciesThermo function is not adequate for the real
180      *  equation of state.
181      */
182     //@{
183 
184     virtual void getEnthalpy_RT_ref(doublereal* hrt) const;
185     virtual void getGibbs_RT_ref(doublereal* grt) const;
186     virtual void getGibbs_ref(doublereal* g) const;
187     virtual void getEntropy_R_ref(doublereal* er) const;
188     virtual void getCp_R_ref(doublereal* cprt) const;
189     virtual void getStandardVolumes_ref(doublereal* vol) const;
190     //! @}
191 
192     virtual doublereal critTemperature() const;
193     virtual doublereal critPressure() const;
194     virtual doublereal critDensity() const;
195 
196     virtual doublereal satPressure(doublereal t);
197 
compatibleWithMultiPhase()198     virtual bool compatibleWithMultiPhase() const {
199         return false;
200     }
201 
202     //! Return the fraction of vapor at the current conditions
203     /*!
204      * Below Tcrit, this routine will always return 0, by definition of the
205      * functionality of the routine. Above Tcrit, we query the density to toggle
206      * between 0 and 1.
207      */
208     virtual doublereal vaporFraction() const;
209 
210     //! Set the temperature of the phase
211     /*!
212      * The density and composition of the phase is constant during this
213      * operator.
214      *
215      * @param temp Temperature (Kelvin)
216      */
217     virtual void setTemperature(const doublereal temp);
218 
219     //! Set the density of the phase
220     /*!
221      * The temperature and composition of the phase is constant during this
222      * operator.
223      *
224      * @param dens value of the density in kg m-3
225      */
226     virtual void setDensity(const doublereal dens);
227 
228     virtual void initThermo();
229     virtual void setParametersFromXML(const XML_Node& eosdata);
230 
231     //! Get a pointer to a changeable WaterPropsIAPWS object
getWater()232     WaterPropsIAPWS* getWater() {
233         return &m_sub;
234     }
235 
236     //! Get a pointer to a changeable WaterPropsIAPWS object
getWaterProps()237     WaterProps* getWaterProps() {
238         return m_waterProps.get();
239     }
240 
241     //! Switch that enables calculations in the gas phase
242     /**
243      *  Since this phase represents a liquid (or supercritical) phase, it is an
244      *  error to return a gas-phase answer. The sole intended use for this
245      *  member function is to check the thermodynamic consistency of the
246      *  underlying WaterProps class with ideal-gas thermo functions.
247      */
_allowGasPhase(bool flag)248     void _allowGasPhase(bool flag) { m_allowGasPhase = flag; }
249 
250 protected:
251     /**
252      * @internal This internal routine must be overridden because it is not
253      *        applicable.
254      */
255     void _updateThermo() const;
256 
257 private:
258     //! WaterPropsIAPWS that calculates the real properties of water.
259     mutable WaterPropsIAPWS m_sub;
260 
261     //! Pointer to the WaterProps object
262     /*!
263      * This class is used to house several approximation routines for properties
264      * of water. This object owns m_waterProps, and the WaterPropsIAPWS object
265      * used by WaterProps is m_sub, which is defined above.
266      */
267     std::unique_ptr<WaterProps> m_waterProps;
268 
269     //! Molecular weight of Water -> Cantera assumption
270     doublereal m_mw;
271 
272     //! Offset constants used to obtain consistency with the NIST database.
273     /*!
274      *  This is added to all internal energy and enthalpy results.
275      *  units = J kmol-1.
276      */
277     doublereal EW_Offset;
278 
279     //! Offset constant used to obtain consistency with NIST convention.
280     /*!
281      *  This is added to all internal entropy results.
282      *  units = J kmol-1 K-1.
283      */
284     doublereal SW_Offset;
285 
286     //! Boolean is true if object has been properly initialized for calculation
287     bool m_ready;
288 
289     /**
290      *  Since this phase represents a liquid (or supercritical) phase, it is an
291      *  error to return a gas-phase answer. However, if the below is true, then
292      *  a gas-phase answer is allowed. This is used to check the thermodynamic
293      *  consistency with ideal-gas thermo functions for example.
294      */
295     bool m_allowGasPhase;
296 };
297 
298 }
299 
300 #endif
301