My Project
H2O.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
27 #ifndef OPM_H2O_HPP
28 #define OPM_H2O_HPP
29 
30 #include "iapws/Common.hpp"
31 #include "iapws/Region1.hpp"
32 #include "iapws/Region2.hpp"
33 #include "iapws/Region4.hpp"
34 
35 #include "Component.hpp"
36 
40 
41 #include <cmath>
42 #include <cassert>
43 #include <sstream>
44 
45 namespace Opm {
46 
60 template <class Scalar>
61 class H2O : public Component<Scalar, H2O<Scalar> >
62 {
67 
68  static const Scalar Rs; // specific gas constant of water
69 
70 public:
74  static const char* name()
75  { return "H2O"; }
76 
80  static const Scalar molarMass()
81  { return Common::molarMass; }
82 
86  static const Scalar acentricFactor()
87  { return Common::acentricFactor; }
88 
92  static const Scalar criticalTemperature()
93  { return Common::criticalTemperature; }
94 
98  static const Scalar criticalPressure()
99  { return Common::criticalPressure; }
100 
104  static const Scalar criticalMolarVolume()
105  { return Common::criticalMolarVolume; }
106 
110  static const Scalar tripleTemperature()
111  { return Common::tripleTemperature; }
112 
116  static const Scalar triplePressure()
117  { return Common::triplePressure; }
118 
131  template <class Evaluation>
132  static Evaluation vaporPressure(Evaluation temperature)
133  {
134  if (temperature > criticalTemperature())
135  temperature = criticalTemperature();
136  if (temperature < tripleTemperature())
137  temperature = tripleTemperature();
138 
139  return Region4::saturationPressure(temperature);
140  }
153  template <class Evaluation>
154  static Evaluation vaporTemperature(const Evaluation& pressure)
155  {
156  if (pressure > criticalPressure())
157  pressure = criticalPressure();
158  if (pressure < triplePressure())
159  pressure = triplePressure();
160 
161  return Region4::vaporTemperature(pressure);
162  }
163 
176  template <class Evaluation>
177  static Evaluation gasEnthalpy(const Evaluation& temperature,
178  const Evaluation& pressure)
179  {
180  if (!Region2::isValid(temperature, pressure))
181  {
182  std::ostringstream oss;
183  oss << "Enthalpy of steam is only implemented for temperatures below 623.15K and "
184  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
185 
186  throw NumericalIssue(oss.str());
187  }
188 
189  // regularization
190  if (pressure < triplePressure() - 100) {
191  // We assume an ideal gas for low pressures to avoid the
192  // 0/0 for the gas enthalpy at very low pressures. The
193  // enthalpy of an ideal gas does not exhibit any
194  // dependence on pressure, so we can just return the
195  // specific enthalpy at the point of regularization, i.e.
196  // the triple pressure - 100Pa
197  return enthalpyRegion2_<Evaluation>(temperature, triplePressure() - 100);
198  }
199  Evaluation pv = vaporPressure(temperature);
200  if (pressure > pv) {
201  // the pressure is too high, in this case we use the slope
202  // of the enthalpy at the vapor pressure to regularize
203  Evaluation dh_dp =
204  Rs*temperature*
205  Region2::tau(temperature)*
206  Region2::dpi_dp(pv)*
207  Region2::ddgamma_dtaudpi(temperature, pv);
208 
209  return
210  enthalpyRegion2_(temperature, pv) +
211  (pressure - pv)*dh_dp;
212  };
213 
214  return enthalpyRegion2_(temperature, pressure);
215  }
216 
229  template <class Evaluation>
230  static Evaluation liquidEnthalpy(const Evaluation& temperature,
231  const Evaluation& pressure)
232  {
233  if (!Region1::isValid(temperature, pressure))
234  {
235  std::ostringstream oss;
236  oss << "Enthalpy of water is only implemented for temperatures below 623.15K and "
237  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
238 
239  throw NumericalIssue(oss.str());
240  }
241 
242  // regularization
243  const Evaluation& pv = vaporPressure(temperature);
244  if (pressure < pv) {
245  // the pressure is too low, in this case we use the slope
246  // of the enthalpy at the vapor pressure to regularize
247  const Evaluation& dh_dp =
248  Rs * temperature*
249  Region1::tau(temperature)*
250  Region1::dpi_dp(pv)*
251  Region1::ddgamma_dtaudpi(temperature, pv);
252 
253  return
254  enthalpyRegion1_(temperature, pv) +
255  (pressure - pv)*dh_dp;
256  };
257 
258  return enthalpyRegion1_(temperature, pressure);
259  }
260 
273  template <class Evaluation>
274  static Evaluation gasHeatCapacity(const Evaluation& temperature,
275  const Evaluation& pressure)
276  {
277  if (!Region2::isValid(temperature, pressure))
278  {
279  std::ostringstream oss;
280  oss << "Heat capacity of steam is only implemented for temperatures below 623.15K and "
281  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
282 
283  throw NumericalIssue(oss.str());
284  }
285 
286  // regularization
287  if (pressure < triplePressure() - 100)
288  return heatCap_p_Region2_(temperature, Evaluation(triplePressure() - 100));
289  const Evaluation& pv = vaporPressure(temperature);
290  if (pressure > pv)
291  // the pressure is too high, in this case we use the heat
292  // cap at the vapor pressure to regularize
293  return heatCap_p_Region2_(temperature, pv);
294 
295  return heatCap_p_Region2_(temperature, pressure);
296  }
297 
310  template <class Evaluation>
311  static Evaluation liquidHeatCapacity(const Evaluation& temperature,
312  const Evaluation& pressure)
313  {
314  if (!Region1::isValid(temperature, pressure))
315  {
316  std::ostringstream oss;
317  oss << "Heat capacity of water is only implemented for temperatures below 623.15K and "
318  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
319  throw NumericalIssue(oss.str());
320  }
321 
322  // regularization
323  const Evaluation& pv = vaporPressure(temperature);
324  if (pressure < pv) {
325  // the pressure is too low, in this case we use the heat capacity at the
326  // vapor pressure to regularize
327  return heatCap_p_Region1_(temperature, pv);
328  };
329 
330  return heatCap_p_Region1_(temperature, pressure);
331  }
332 
345  template <class Evaluation>
346  static Evaluation liquidInternalEnergy(const Evaluation& temperature,
347  const Evaluation& pressure)
348  {
349  if (!Region1::isValid(temperature, pressure))
350  {
351  std::ostringstream oss;
352  oss << "Internal Energy of water is only implemented for temperatures below 623.15K and "
353  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
354 
355  throw NumericalIssue(oss.str());
356  }
357 
358 
359  // regularization
360  Scalar pv = vaporPressure<Scalar>(scalarValue(temperature));
361  if (pressure < pv) {
362  // the pressure is too low, in this case we use the slope
363  // of the internal energy at the vapor pressure to
364  // regularize
365 
366  /*
367  // calculate the partial derivative of the internal energy
368  // to the pressure at the vapor pressure.
369  Scalar tau = Region1::tau(temperature);
370  Scalar dgamma_dpi = Region1::dgamma_dpi(temperature, pv);
371  Scalar ddgamma_dtaudpi = Region1::ddgamma_dtaudpi(temperature, pv);
372  Scalar ddgamma_ddpi = Region1::ddgamma_ddpi(temperature, pv);
373  Scalar pi = Region1::pi(pv);
374  Scalar dpi_dp = Region1::dpi_dp(pv);
375  Scalar du_dp =
376  Rs*temperature*
377  (tau*dpi_dp*ddgamma_dtaudpi + dpi_dp*dpi_dp*dgamma_dpi + pi*dpi_dp*ddgamma_ddpi);
378  */
379 
380  // use a straight line for extrapolation. use forward
381  // differences to calculate the partial derivative to the
382  // pressure at the vapor pressure
383  Scalar eps = 1e-7;
384  const Evaluation& uv = internalEnergyRegion1_(temperature, Evaluation(pv));
385  const Evaluation& uvPEps = internalEnergyRegion1_(temperature, Evaluation(pv + eps));
386  const Evaluation& du_dp = (uvPEps - uv)/eps;
387  return uv + du_dp*(pressure - pv);
388  };
389 
390  return internalEnergyRegion1_(temperature, pressure);
391  }
392 
405  template <class Evaluation>
406  static Evaluation gasInternalEnergy(const Evaluation& temperature, const Evaluation& pressure)
407  {
408  if (!Region2::isValid(temperature, pressure))
409  {
410  std::ostringstream oss;
411  oss <<"Internal energy of steam is only implemented for temperatures below 623.15K and "
412  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
413  throw NumericalIssue(oss.str());
414  }
415 
416  // regularization
417  if (pressure < triplePressure() - 100) {
418  // We assume an ideal gas for low pressures to avoid the
419  // 0/0 for the internal energy of gas at very low
420  // pressures. The enthalpy of an ideal gas does not
421  // exhibit any dependence on pressure, so we can just
422  // return the specific enthalpy at the point of
423  // regularization, i.e. the triple pressure - 100Pa, and
424  // subtract the work required to change the volume for an
425  // ideal gas.
426  return
427  enthalpyRegion2_(temperature, Evaluation(triplePressure() - 100.0))
428  -
429  Rs*temperature; // = p*v for an ideal gas!
430  }
431  Scalar pv = vaporPressure(scalarValue(temperature));
432  if (pressure > pv) {
433  // the pressure is too high, in this case we use the slope
434  // of the internal energy at the vapor pressure to
435  // regularize
436 
437  /*
438  // calculate the partial derivative of the internal energy
439  // to the pressure at the vapor pressure.
440  Scalar tau = Region2::tau(temperature);
441  Scalar dgamma_dpi = Region2::dgamma_dpi(temperature, pv);
442  Scalar ddgamma_dtaudpi = Region2::ddgamma_dtaudpi(temperature, pv);
443  Scalar ddgamma_ddpi = Region2::ddgamma_ddpi(temperature, pv);
444  Scalar pi = Region2::pi(pv);
445  Scalar dpi_dp = Region2::dpi_dp(pv);
446  Scalar du_dp =
447  Rs*temperature*
448  (tau*dpi_dp*ddgamma_dtaudpi + dpi_dp*dpi_dp*dgamma_dpi + pi*dpi_dp*ddgamma_ddpi);
449 
450  // use a straight line for extrapolation
451  Scalar uv = internalEnergyRegion2_(temperature, pv);
452  return uv + du_dp*(pressure - pv);
453  */
454 
455  // use a straight line for extrapolation. use backward
456  // differences to calculate the partial derivative to the
457  // pressure at the vapor pressure
458  Scalar eps = 1e-7;
459  const Evaluation& uv = internalEnergyRegion2_(temperature, Evaluation(pv));
460  const Evaluation& uvMEps = internalEnergyRegion2_(temperature, Evaluation(pv - eps));
461  const Evaluation& du_dp = (uv - uvMEps)/eps;
462  return uv + du_dp*(pressure - pv);
463  };
464 
465  return internalEnergyRegion2_(temperature, pressure);
466  }
467 
480  template <class Evaluation>
481  static Evaluation liquidHeatCapacityConstVolume(const Evaluation& temperature,
482  const Evaluation& pressure)
483  {
484  if (!Region1::isValid(temperature, pressure))
485  {
486  std::ostringstream oss;
487  oss << "Heat capacity of water is only implemented for temperatures below 623.15K and "
488  "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
489 
490  throw NumericalIssue(oss.str());
491  }
492 
493 
494  // regularization
495  Scalar pv = vaporPressure(temperature);
496  if (pressure < pv) {
497  // the pressure is too low, in this case we use the heat cap at the vapor pressure to regularize
498 
499  return heatCap_v_Region1_(temperature, pv);
500  }
501 
502  return heatCap_v_Region1_(temperature, pressure);
503  }
504 
517  template <class Evaluation>
518  static Evaluation gasHeatCapacityConstVolume(const Evaluation& temperature, const Evaluation& pressure)
519  {
520  if (!Region2::isValid(temperature, pressure))
521  {
522  std::ostringstream oss;
523  oss << "Heat capacity of steam is only implemented for temperatures below 623.15K and "
524  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
525  throw NumericalIssue(oss.str());
526  }
527 
528  // regularization
529  if (pressure < triplePressure() - 100) {
530  return
531  heatCap_v_Region2_(temperature, triplePressure() - 100);
532  }
533  Scalar pv = vaporPressure(temperature);
534  if (pressure > pv) {
535  return heatCap_v_Region2_(temperature, pv);
536  };
537 
538  return heatCap_v_Region2_(temperature, pressure);
539  }
540 
544  static bool gasIsCompressible()
545  { return true; }
546 
550  static bool liquidIsCompressible()
551  { return true; }
552 
565  template <class Evaluation>
566  static Evaluation gasDensity(const Evaluation& temperature, const Evaluation& pressure)
567  {
568  if (!Region2::isValid(temperature, pressure))
569  {
570  std::ostringstream oss;
571  oss << "Density of steam is only implemented for temperatures below 623.15K and "
572  "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
573  throw NumericalIssue(oss.str());
574  }
575 
576  // regularization
577  if (pressure < triplePressure() - 100) {
578  // We assume an ideal gas for low pressures to avoid the
579  // 0/0 for the internal energy and enthalpy.
580  const Evaluation& rho0IAPWS =
581  1.0/volumeRegion2_(temperature,
582  Evaluation(triplePressure() - 100));
583  const Evaluation& rho0Id =
584  IdealGas<Scalar>::density(Evaluation(molarMass()),
585  temperature,
586  Evaluation(triplePressure() - 100));
587  return
588  rho0IAPWS/rho0Id
589  *IdealGas<Scalar>::density(Evaluation(molarMass()),
590  temperature,
591  pressure);
592  }
593  Evaluation pv = vaporPressure(temperature);
594  if (pressure > pv) {
595  // the pressure is too high, in this case we use the slope
596  // of the density energy at the vapor pressure to
597  // regularize
598 
599  // calculate the partial derivative of the specific volume
600  // to the pressure at the vapor pressure.
601  Scalar eps = scalarValue(pv)*1e-8;
602  Evaluation v0 = volumeRegion2_(temperature, pv);
603  Evaluation v1 = volumeRegion2_(temperature, pv + eps);
604  Evaluation dv_dp = (v1 - v0)/eps;
605  /*
606  Scalar pi = Region2::pi(pv);
607  Scalar dp_dpi = Region2::dp_dpi(pv);
608  Scalar dgamma_dpi = Region2::dgamma_dpi(temperature, pv);
609  Scalar ddgamma_ddpi = Region2::ddgamma_ddpi(temperature, pv);
610 
611  Scalar RT = Rs*temperature;
612  Scalar dv_dp =
613  RT/(dp_dpi*pv)
614  *
615  (dgamma_dpi + pi*ddgamma_ddpi - v0*dp_dpi/RT);
616  */
617 
618  // calculate the partial derivative of the density to the
619  // pressure at vapor pressure
620  Evaluation drho_dp = - 1/(v0*v0)*dv_dp;
621 
622  // use a straight line for extrapolation
623  return 1.0/v0 + (pressure - pv)*drho_dp;
624  };
625 
626  return 1.0/volumeRegion2_(temperature, pressure);
627  }
628 
632  static bool gasIsIdeal()
633  { return false; }
634 
647  template <class Evaluation>
648  static Evaluation gasPressure(const Evaluation& temperature, Scalar density)
649  {
650  Valgrind::CheckDefined(temperature);
651  Valgrind::CheckDefined(density);
652 
653  // We use the newton method for this. For the initial value we
654  // assume steam to be an ideal gas
655  Evaluation pressure = IdealGas<Scalar>::pressure(temperature, density/molarMass());
656  Scalar eps = pressure*1e-7;
657 
658  Evaluation deltaP = pressure*2;
659  Valgrind::CheckDefined(pressure);
660  Valgrind::CheckDefined(deltaP);
661  for (int i = 0; i < 5 && std::abs(scalarValue(pressure)*1e-9) < std::abs(scalarValue(deltaP)); ++i) {
662  Evaluation f = gasDensity(temperature, pressure) - density;
663 
664  Evaluation df_dp;
665  df_dp = gasDensity(temperature, pressure + eps);
666  df_dp -= gasDensity(temperature, pressure - eps);
667  df_dp /= 2*eps;
668 
669  deltaP = - f/df_dp;
670 
671  pressure += deltaP;
672  Valgrind::CheckDefined(pressure);
673  Valgrind::CheckDefined(deltaP);
674  }
675 
676  return pressure;
677  }
678 
691  template <class Evaluation>
692  static Evaluation liquidDensity(const Evaluation& temperature,
693  const Evaluation& pressure,
694  bool extrapolate = false)
695  {
696  if (!extrapolate && !Region1::isValid(temperature, pressure))
697  {
698  std::ostringstream oss;
699  oss << "Density of water is only implemented for temperatures below 623.15K and "
700  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
701  throw NumericalIssue(oss.str());
702  }
703 
704  // regularization
705  Evaluation pv = vaporPressure(temperature);
706  if (pressure < pv) {
707  // the pressure is too low, in this case we use the slope
708  // of the density at the vapor pressure to regularize
709 
710  // calculate the partial derivative of the specific volume
711  // to the pressure at the vapor pressure.
712  Scalar eps = scalarValue(pv)*1e-8;
713  Evaluation v0 = volumeRegion1_(temperature, pv);
714  Evaluation v1 = volumeRegion1_(temperature, pv + eps);
715  Evaluation dv_dp = (v1 - v0)/eps;
716 
717  /*
718  Scalar v0 = volumeRegion1_(temperature, pv);
719  Scalar pi = Region1::pi(pv);
720  Scalar dp_dpi = Region1::dp_dpi(pv);
721  Scalar dgamma_dpi = Region1::dgamma_dpi(temperature, pv);
722  Scalar ddgamma_ddpi = Region1::ddgamma_ddpi(temperature, pv);
723 
724  Scalar RT = Rs*temperature;
725  Scalar dv_dp =
726  RT/(dp_dpi*pv)
727  *
728  (dgamma_dpi + pi*ddgamma_ddpi - v0*dp_dpi/RT);
729  */
730 
731  // calculate the partial derivative of the density to the
732  // pressure at vapor pressure
733  Evaluation drho_dp = - 1/(v0*v0)*dv_dp;
734 
735  // use a straight line for extrapolation
736  return 1.0/v0 + (pressure - pv)*drho_dp;
737  };
738 
739  return 1/volumeRegion1_(temperature, pressure);
740  }
741 
755  template <class Evaluation>
756  static Evaluation liquidPressure(const Evaluation& temperature, Scalar density)
757  {
758  // We use the Newton method for this. For the initial value we
759  // assume the pressure to be 10% higher than the vapor
760  // pressure
761  Evaluation pressure = 1.1*vaporPressure(temperature);
762  Scalar eps = scalarValue(pressure)*1e-7;
763 
764  Evaluation deltaP = pressure*2;
765  for (int i = 0; i < 5 && std::abs(scalarValue(pressure)*1e-9) < std::abs(scalarValue(deltaP)); ++i) {
766  Evaluation f = liquidDensity(temperature, pressure) - density;
767 
768  Evaluation df_dp;
769  df_dp = liquidDensity(temperature, pressure + eps);
770  df_dp -= liquidDensity(temperature, pressure - eps);
771  df_dp /= 2*eps;
772 
773  deltaP = - f/df_dp;
774 
775  pressure += deltaP;
776  }
777 
778  return pressure;
779  }
780 
795  template <class Evaluation>
796  static Evaluation gasViscosity(const Evaluation& temperature, const Evaluation& pressure)
797  {
798  if (!Region2::isValid(temperature, pressure))
799  {
800  std::ostringstream oss;
801  oss << "Viscosity of steam is only implemented for temperatures below 623.15K and "
802  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
803  throw NumericalIssue(oss.str());
804  }
805 
806  Evaluation rho = gasDensity(temperature, pressure);
807  return Common::viscosity(temperature, rho);
808  }
809 
821  template <class Evaluation>
822  static Evaluation liquidViscosity(const Evaluation& temperature,
823  const Evaluation& pressure,
824  bool extrapolate = false)
825  {
826  if (!extrapolate && !Region1::isValid(temperature, pressure))
827  {
828  std::ostringstream oss;
829  oss << "Viscosity of water is only implemented for temperatures below 623.15K and "
830  << "pressures below 100MPa. (T = " << temperature << ", p=" << pressure;
831  throw NumericalIssue(oss.str());
832  };
833 
834  const Evaluation& rho = liquidDensity(temperature, pressure, extrapolate);
835  return Common::viscosity(temperature, rho);
836  }
837 
851  template <class Evaluation>
852  static Evaluation liquidThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
853  {
854  const Evaluation& rho = liquidDensity(temperature, pressure);
855  return Common::thermalConductivityIAPWS(temperature, rho);
856  }
857 
871  template <class Evaluation>
872  static Evaluation gasThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
873  {
874  const Evaluation& rho = gasDensity(temperature, pressure);
875  return Common::thermalConductivityIAPWS(temperature, rho);
876  }
877 
878 private:
879  // the unregularized specific enthalpy for liquid water
880  template <class Evaluation>
881  static Evaluation enthalpyRegion1_(const Evaluation& temperature, const Evaluation& pressure)
882  {
883  return
884  Region1::tau(temperature) *
885  Region1::dgamma_dtau(temperature, pressure) *
886  Rs*temperature;
887  }
888 
889  // the unregularized specific isobaric heat capacity
890  template <class Evaluation>
891  static Evaluation heatCap_p_Region1_(const Evaluation& temperature, const Evaluation& pressure)
892  {
893  return
894  - pow(Region1::tau(temperature), 2.0) *
895  Region1::ddgamma_ddtau(temperature, pressure) *
896  Rs;
897  }
898 
899  // the unregularized specific isochoric heat capacity
900  template <class Evaluation>
901  static Evaluation heatCap_v_Region1_(const Evaluation& temperature, const Evaluation& pressure)
902  {
903  double tau = Region1::tau(temperature);
904  double num = Region1::dgamma_dpi(temperature, pressure) - tau * Region1::ddgamma_dtaudpi(temperature, pressure);
905  double diff = std::pow(num, 2) / Region1::ddgamma_ddpi(temperature, pressure);
906 
907  return
908  - std::pow(tau, 2 ) *
909  Region1::ddgamma_ddtau(temperature, pressure) * Rs +
910  diff;
911  }
912 
913  // the unregularized specific internal energy for liquid water
914  template <class Evaluation>
915  static Evaluation internalEnergyRegion1_(const Evaluation& temperature, const Evaluation& pressure)
916  {
917  return
918  Rs * temperature *
919  ( Region1::tau(temperature)*Region1::dgamma_dtau(temperature, pressure) -
920  Region1::pi(pressure)*Region1::dgamma_dpi(temperature, pressure));
921  }
922 
923  // the unregularized specific volume for liquid water
924  template <class Evaluation>
925  static Evaluation volumeRegion1_(const Evaluation& temperature, const Evaluation& pressure)
926  {
927  return
928  Region1::pi(pressure)*
929  Region1::dgamma_dpi(temperature, pressure) *
930  Rs * temperature / pressure;
931  }
932 
933  // the unregularized specific enthalpy for steam
934  template <class Evaluation>
935  static Evaluation enthalpyRegion2_(const Evaluation& temperature, const Evaluation& pressure)
936  {
937  return
938  Region2::tau(temperature) *
939  Region2::dgamma_dtau(temperature, pressure) *
940  Rs*temperature;
941  }
942 
943  // the unregularized specific internal energy for steam
944  template <class Evaluation>
945  static Evaluation internalEnergyRegion2_(const Evaluation& temperature, const Evaluation& pressure)
946  {
947  return
948  Rs * temperature *
949  ( Region2::tau(temperature)*Region2::dgamma_dtau(temperature, pressure) -
950  Region2::pi(pressure)*Region2::dgamma_dpi(temperature, pressure));
951  }
952 
953  // the unregularized specific isobaric heat capacity
954  template <class Evaluation>
955  static Evaluation heatCap_p_Region2_(const Evaluation& temperature, const Evaluation& pressure)
956  {
957  return
958  - pow(Region2::tau(temperature), 2 ) *
959  Region2::ddgamma_ddtau(temperature, pressure) *
960  Rs;
961  }
962 
963  // the unregularized specific isochoric heat capacity
964  template <class Evaluation>
965  static Evaluation heatCap_v_Region2_(const Evaluation& temperature, const Evaluation& pressure)
966  {
967  const Evaluation& tau = Region2::tau(temperature);
968  const Evaluation& pi = Region2::pi(pressure);
969  const Evaluation& num = 1 + pi * Region2::dgamma_dpi(temperature, pressure) + tau * pi * Region2::ddgamma_dtaudpi(temperature, pressure);
970  const Evaluation& diff = num * num / (1 - pi * pi * Region2::ddgamma_ddpi(temperature, pressure));
971  return
972  - std::pow(tau, 2 ) *
973  Region2::ddgamma_ddtau(temperature, pressure) * Rs
974  - diff;
975  }
976 
977  // the unregularized specific volume for steam
978  template <class Evaluation>
979  static Evaluation volumeRegion2_(const Evaluation& temperature, const Evaluation& pressure)
980  {
981  return
982  Region2::pi(pressure)*
983  Region2::dgamma_dpi(temperature, pressure) *
984  Rs * temperature / pressure;
985  }
986 }; // end class
987 
988 template <class Scalar>
989 const Scalar H2O<Scalar>::Rs = Common::Rs;
990 } // namespace Opm
991 
992 #endif
Implements relations which are common for all regions of the IAPWS '97 formulation.
Abstract base class of a pure chemical species.
Provides the opm-material specific exception classes.
Relations valid for an ideal gas.
Implements the equations for region 1 of the IAPWS '97 formulation.
Implements the equations for region 2 of the IAPWS '97 formulation.
Implements the equations for region 4 of the IAPWS '97 formulation.
Some templates to wrap the valgrind client request macros.
Abstract base class of a pure chemical species.
Definition: Component.hpp:42
Material properties of pure water .
Definition: H2O.hpp:62
static Evaluation liquidDensity(const Evaluation &temperature, const Evaluation &pressure, bool extrapolate=false)
The density of pure water in at a given pressure and temperature.
Definition: H2O.hpp:692
static const Scalar criticalTemperature()
Returns the critical temperature of water.
Definition: H2O.hpp:92
static Evaluation gasDensity(const Evaluation &temperature, const Evaluation &pressure)
The density of steam in at a given pressure and temperature.
Definition: H2O.hpp:566
static bool gasIsCompressible()
Returns true iff the gas phase is assumed to be compressible.
Definition: H2O.hpp:544
static const char * name()
A human readable name for the water.
Definition: H2O.hpp:74
static Evaluation gasPressure(const Evaluation &temperature, Scalar density)
The pressure of steam in at a given density and temperature.
Definition: H2O.hpp:648
static Evaluation vaporPressure(Evaluation temperature)
The vapor pressure in of pure water at a given temperature.
Definition: H2O.hpp:132
static Evaluation gasViscosity(const Evaluation &temperature, const Evaluation &pressure)
The dynamic viscosity of steam.
Definition: H2O.hpp:796
static Evaluation gasHeatCapacityConstVolume(const Evaluation &temperature, const Evaluation &pressure)
Specific isochoric heat capacity of steam and water vapor .
Definition: H2O.hpp:518
static Evaluation gasHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of water steam .
Definition: H2O.hpp:274
static const Scalar criticalMolarVolume()
Returns the molar volume of water at the critical point.
Definition: H2O.hpp:104
static Evaluation liquidEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of liquid water .
Definition: H2O.hpp:230
static Evaluation liquidThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
Thermal conductivity of water (IAPWS) .
Definition: H2O.hpp:852
static const Scalar acentricFactor()
The acentric factor of water.
Definition: H2O.hpp:86
static Evaluation liquidInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of liquid water .
Definition: H2O.hpp:346
static bool gasIsIdeal()
Returns true iff the gas phase is assumed to be ideal.
Definition: H2O.hpp:632
static const Scalar criticalPressure()
Returns the critical pressure of water.
Definition: H2O.hpp:98
static const Scalar molarMass()
The molar mass in of water.
Definition: H2O.hpp:80
static Evaluation vaporTemperature(const Evaluation &pressure)
The vapor temperature in of pure water at a given pressure.
Definition: H2O.hpp:154
static bool liquidIsCompressible()
Returns true iff the liquid phase is assumed to be compressible.
Definition: H2O.hpp:550
static Evaluation liquidViscosity(const Evaluation &temperature, const Evaluation &pressure, bool extrapolate=false)
The dynamic viscosity of pure water.
Definition: H2O.hpp:822
static Evaluation gasInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of steam and water vapor .
Definition: H2O.hpp:406
static Evaluation gasThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
Thermal conductivity of water (IAPWS) .
Definition: H2O.hpp:872
static Evaluation gasEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of water steam .
Definition: H2O.hpp:177
static Evaluation liquidHeatCapacityConstVolume(const Evaluation &temperature, const Evaluation &pressure)
Specific isochoric heat capacity of liquid water .
Definition: H2O.hpp:481
static Evaluation liquidPressure(const Evaluation &temperature, Scalar density)
The pressure of liquid water in at a given density and temperature.
Definition: H2O.hpp:756
static const Scalar tripleTemperature()
Returns the temperature at water's triple point.
Definition: H2O.hpp:110
static Evaluation liquidHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of liquid water .
Definition: H2O.hpp:311
static const Scalar triplePressure()
Returns the pressure at water's triple point.
Definition: H2O.hpp:116
Implements relations which are common for all regions of the IAPWS '97 formulation.
Definition: Common.hpp:55
static const Scalar criticalPressure
Critical pressure of water .
Definition: Common.hpp:67
static Evaluation viscosity(const Evaluation &temperature, const Evaluation &rho)
The dynamic viscosity of pure water.
Definition: Common.hpp:99
static const Scalar criticalMolarVolume
Critical molar volume of water .
Definition: Common.hpp:73
static const Scalar criticalTemperature
Critical temperature of water .
Definition: Common.hpp:64
static Evaluation thermalConductivityIAPWS(const Evaluation &T, const Evaluation &rho)
Thermal conductivity water (IAPWS) .
Definition: Common.hpp:159
static const Scalar tripleTemperature
Triple temperature of water .
Definition: Common.hpp:79
static const Scalar triplePressure
Triple pressure of water .
Definition: Common.hpp:82
static const Scalar molarMass
The molar mass of water .
Definition: Common.hpp:58
static const Scalar acentricFactor
The acentric factor of water .
Definition: Common.hpp:76
Implements the equations for region 1 of the IAPWS '97 formulation.
Definition: Region1.hpp:51
static Evaluation ddgamma_ddpi(const Evaluation &temperature, const Evaluation &pressure)
The second partial derivative of the Gibbs free energy to the normalized pressure for IAPWS region 1 ...
Definition: Region1.hpp:252
static Evaluation tau(const Evaluation &temperature)
Returns the reduced temperature for IAPWS region 1.
Definition: Region1.hpp:83
static Evaluation ddgamma_ddtau(const Evaluation &temperature, const Evaluation &pressure)
The second partial derivative of the Gibbs free energy to the normalized temperature for IAPWS region...
Definition: Region1.hpp:282
static Evaluation pi(const Evaluation &pressure)
Returns the reduced pressure for IAPWS region 1.
Definition: Region1.hpp:102
static Evaluation dgamma_dtau(const Evaluation &temperature, const Evaluation &pressure)
The partial derivative of the Gibbs free energy to the normalized temperature for IAPWS region 1 (i....
Definition: Region1.hpp:162
static bool isValid(const Evaluation &temperature, const Evaluation &pressure)
Returns true if IAPWS region 1 applies for a (temperature in , pressure in ) pair.
Definition: Region1.hpp:61
static Evaluation ddgamma_dtaudpi(const Evaluation &temperature, const Evaluation &pressure)
The partial derivative of the Gibbs free energy to the normalized pressure and to the normalized temp...
Definition: Region1.hpp:221
static Scalar dpi_dp(const Evaluation &)
Returns the derivative of the reduced pressure to the pressure for IAPWS region 1 in .
Definition: Region1.hpp:112
static Evaluation dgamma_dpi(const Evaluation &temperature, const Evaluation &pressure)
The partial derivative of the Gibbs free energy to the normalized pressure for IAPWS region 1 (i....
Definition: Region1.hpp:191
Implements the equations for region 2 of the IAPWS '97 formulation.
Definition: Region2.hpp:52
static Scalar dpi_dp(const Evaluation &)
Returns the derivative of the reduced pressure to the pressure for IAPWS region 2 in .
Definition: Region2.hpp:111
static Evaluation ddgamma_ddtau(const Evaluation &temperature, const Evaluation &pressure)
The second partial derivative of the Gibbs free energy to the normalized temperature for IAPWS region...
Definition: Region2.hpp:310
static Evaluation ddgamma_ddpi(const Evaluation &temperature, const Evaluation &pressure)
The second partial derivative of the Gibbs free energy to the normalized pressure for IAPWS region 2 ...
Definition: Region2.hpp:276
static Evaluation pi(const Evaluation &pressure)
Returns the reduced pressure (dimensionless) for IAPWS region 2.
Definition: Region2.hpp:101
static Evaluation dgamma_dtau(const Evaluation &temperature, const Evaluation &pressure)
The partial derivative of the Gibbs free energy to the normalized temperature for IAPWS region 2 (i....
Definition: Region2.hpp:170
static Evaluation tau(const Evaluation &temperature)
Returns the reduced temperature (dimensionless) for IAPWS region 2.
Definition: Region2.hpp:82
static Evaluation ddgamma_dtaudpi(const Evaluation &temperature, const Evaluation &pressure)
The partial derivative of the Gibbs free energy to the normalized pressure and to the normalized temp...
Definition: Region2.hpp:242
static bool isValid(const Evaluation &temperature, const Evaluation &pressure)
Returns true if IAPWS region 2 applies for a (temperature, pressure) pair.
Definition: Region2.hpp:62
static Evaluation dgamma_dpi(const Evaluation &temperature, const Evaluation &pressure)
The partial derivative of the Gibbs free energy to the normalized pressure for IAPWS region 2 (i....
Definition: Region2.hpp:209
Implements the equations for region 4 of the IAPWS '97 formulation.
Definition: Region4.hpp:52
static Evaluation vaporTemperature(const Evaluation &pressure)
Returns the saturation temperature in of pure water at a given pressure.
Definition: Region4.hpp:94
static Evaluation saturationPressure(const Evaluation &temperature)
Returns the saturation pressure in of pure water at a given temperature.
Definition: Region4.hpp:63
static Evaluation pressure(const Evaluation &temperature, const Evaluation &rhoMolar)
The pressure of the gas in , depending on the molar density and temperature.
Definition: IdealGas.hpp:58
static Evaluation density(const Evaluation &avgMolarMass, const Evaluation &temperature, const Evaluation &pressure)
The density of the gas in , depending on pressure, temperature and average molar mass of the gas.
Definition: IdealGas.hpp:48
Definition: Exceptions.hpp:46