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