opm-common
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 
38 
41 
44 
45 #include <cmath>
46 #include <cassert>
47 
48 namespace Opm {
49 
63 template <class Scalar>
64 class H2O : public Component<Scalar, H2O<Scalar> >
65 {
70 
71  static const Scalar Rs; // specific gas constant of water
72 
73 public:
74  using Component<Scalar, H2O<Scalar>>::isTabulated;
75 
79  static std::string_view name()
80  { return "H2O"; }
81 
85  static const Scalar molarMass()
86  { return Common::molarMass; }
87 
91  static const Scalar acentricFactor()
92  { return Common::acentricFactor; }
93 
97  static const Scalar criticalTemperature()
98  { return Common::criticalTemperature; }
99 
103  static const Scalar criticalPressure()
104  { return Common::criticalPressure; }
105 
109  static const Scalar criticalVolume()
110  { return Common::criticalVolume; }
111 
115  static const Scalar criticalMolarVolume()
116  { return Common::criticalMolarVolume; }
117 
121  static const Scalar tripleTemperature()
122  { return Common::tripleTemperature; }
123 
127  static const Scalar triplePressure()
128  { return Common::triplePressure; }
129 
142  template <class Evaluation>
143  static Evaluation vaporPressure(Evaluation temperature)
144  {
145  if (temperature > criticalTemperature())
146  temperature = criticalTemperature();
147  if (temperature < tripleTemperature())
148  temperature = tripleTemperature();
149 
150  return Region4::saturationPressure(temperature);
151  }
164  template <class Evaluation>
165  static Evaluation vaporTemperature(const Evaluation& pressure)
166  {
167  if (pressure > criticalPressure())
168  pressure = criticalPressure();
169  if (pressure < triplePressure())
170  pressure = triplePressure();
171 
172  return Region4::vaporTemperature(pressure);
173  }
174 
187  template <class Evaluation>
188  static Evaluation gasEnthalpy(const Evaluation& temperature,
189  const Evaluation& pressure)
190  {
191  if (!Region2::isValid(temperature, pressure))
192  {
193  throw NumericalProblem(domainError("Enthalphy of steam",
194  temperature,
195  pressure));
196  }
197 
198  // regularization
199  if (pressure < triplePressure() - 100) {
200  // We assume an ideal gas for low pressures to avoid the
201  // 0/0 for the gas enthalpy at very low pressures. The
202  // enthalpy of an ideal gas does not exhibit any
203  // dependence on pressure, so we can just return the
204  // specific enthalpy at the point of regularization, i.e.
205  // the triple pressure - 100Pa
206  return enthalpyRegion2_<Evaluation>(temperature, triplePressure() - 100);
207  }
208  Evaluation pv = vaporPressure(temperature);
209  if (pressure > pv) {
210  // the pressure is too high, in this case we use the slope
211  // of the enthalpy at the vapor pressure to regularize
212  Evaluation dh_dp =
213  Rs*temperature*
214  Region2::tau(temperature)*
215  Region2::dpi_dp(pv)*
216  Region2::ddgamma_dtaudpi(temperature, pv);
217 
218  return
219  enthalpyRegion2_(temperature, pv) +
220  (pressure - pv)*dh_dp;
221  };
222 
223  return enthalpyRegion2_(temperature, pressure);
224  }
225 
238  template <class Evaluation>
239  static Evaluation liquidEnthalpy(const Evaluation& temperature,
240  const Evaluation& pressure)
241  {
242  if (!Region1::isValid(temperature, pressure))
243  {
244  throw NumericalProblem(domainError("Enthalphy of water",
245  temperature,
246  pressure));
247  }
248 
249  // regularization
250  const Evaluation& pv = vaporPressure(temperature);
251  if (pressure < pv) {
252  // the pressure is too low, in this case we use the slope
253  // of the enthalpy at the vapor pressure to regularize
254  const Evaluation& dh_dp =
255  Rs * temperature*
256  Region1::tau(temperature)*
257  Region1::dpi_dp(pv)*
258  Region1::ddgamma_dtaudpi(temperature, pv);
259 
260  return
261  enthalpyRegion1_(temperature, pv) +
262  (pressure - pv)*dh_dp;
263  };
264 
265  return enthalpyRegion1_(temperature, pressure);
266  }
267 
280  template <class Evaluation>
281  static Evaluation gasHeatCapacity(const Evaluation& temperature,
282  const Evaluation& pressure)
283  {
284  if (!Region2::isValid(temperature, pressure))
285  {
286  throw NumericalProblem(domainError("Heat capacity of steam",
287  temperature,
288  pressure));
289  }
290 
291  // regularization
292  if (pressure < triplePressure() - 100)
293  return heatCap_p_Region2_(temperature, Evaluation(triplePressure() - 100));
294  const Evaluation& pv = vaporPressure(temperature);
295  if (pressure > pv)
296  // the pressure is too high, in this case we use the heat
297  // cap at the vapor pressure to regularize
298  return heatCap_p_Region2_(temperature, pv);
299 
300  return heatCap_p_Region2_(temperature, pressure);
301  }
302 
315  template <class Evaluation>
316  static Evaluation liquidHeatCapacity(const Evaluation& temperature,
317  const Evaluation& pressure)
318  {
319  if (!Region1::isValid(temperature, pressure))
320  {
321  throw NumericalProblem(domainError("Heat capacity of water",
322  temperature,
323  pressure));
324  }
325 
326  // regularization
327  const Evaluation& pv = vaporPressure(temperature);
328  if (pressure < pv) {
329  // the pressure is too low, in this case we use the heat capacity at the
330  // vapor pressure to regularize
331  return heatCap_p_Region1_(temperature, pv);
332  };
333 
334  return heatCap_p_Region1_(temperature, pressure);
335  }
336 
349  template <class Evaluation>
350  static Evaluation liquidInternalEnergy(const Evaluation& temperature,
351  const Evaluation& pressure)
352  {
353  if (!Region1::isValid(temperature, pressure))
354  {
355  throw NumericalProblem(domainError("Internal energy of water",
356  temperature,
357  pressure));
358  }
359 
360 
361  // regularization
362  Scalar pv = vaporPressure<Scalar>(scalarValue(temperature));
363  if (pressure < pv) {
364  // the pressure is too low, in this case we use the slope
365  // of the internal energy at the vapor pressure to
366  // regularize
367 
368  /*
369  // calculate the partial derivative of the internal energy
370  // to the pressure at the vapor pressure.
371  Scalar tau = Region1::tau(temperature);
372  Scalar dgamma_dpi = Region1::dgamma_dpi(temperature, pv);
373  Scalar ddgamma_dtaudpi = Region1::ddgamma_dtaudpi(temperature, pv);
374  Scalar ddgamma_ddpi = Region1::ddgamma_ddpi(temperature, pv);
375  Scalar pi = Region1::pi(pv);
376  Scalar dpi_dp = Region1::dpi_dp(pv);
377  Scalar du_dp =
378  Rs*temperature*
379  (tau*dpi_dp*ddgamma_dtaudpi + dpi_dp*dpi_dp*dgamma_dpi + pi*dpi_dp*ddgamma_ddpi);
380  */
381 
382  // use a straight line for extrapolation. use forward
383  // differences to calculate the partial derivative to the
384  // pressure at the vapor pressure
385  Scalar eps = 1e-7;
386  const Evaluation& uv = internalEnergyRegion1_(temperature, Evaluation(pv));
387  const Evaluation& uvPEps = internalEnergyRegion1_(temperature, Evaluation(pv + eps));
388  const Evaluation& du_dp = (uvPEps - uv)/eps;
389  return uv + du_dp*(pressure - pv);
390  };
391 
392  return internalEnergyRegion1_(temperature, pressure);
393  }
394 
407  template <class Evaluation>
408  static Evaluation gasInternalEnergy(const Evaluation& temperature, const Evaluation& pressure)
409  {
410  if (!Region2::isValid(temperature, pressure))
411  {
412  throw NumericalProblem(domainError("Internal energy of steam",
413  temperature,
414  pressure));
415  }
416 
417  // regularization
418  if (pressure < triplePressure() - 100) {
419  // We assume an ideal gas for low pressures to avoid the
420  // 0/0 for the internal energy of gas at very low
421  // pressures. The enthalpy of an ideal gas does not
422  // exhibit any dependence on pressure, so we can just
423  // return the specific enthalpy at the point of
424  // regularization, i.e. the triple pressure - 100Pa, and
425  // subtract the work required to change the volume for an
426  // ideal gas.
427  return
428  enthalpyRegion2_(temperature, Evaluation(triplePressure() - 100.0))
429  -
430  Rs*temperature; // = p*v for an ideal gas!
431  }
432  Scalar pv = vaporPressure(scalarValue(temperature));
433  if (pressure > pv) {
434  // the pressure is too high, in this case we use the slope
435  // of the internal energy at the vapor pressure to
436  // regularize
437 
438  /*
439  // calculate the partial derivative of the internal energy
440  // to the pressure at the vapor pressure.
441  Scalar tau = Region2::tau(temperature);
442  Scalar dgamma_dpi = Region2::dgamma_dpi(temperature, pv);
443  Scalar ddgamma_dtaudpi = Region2::ddgamma_dtaudpi(temperature, pv);
444  Scalar ddgamma_ddpi = Region2::ddgamma_ddpi(temperature, pv);
445  Scalar pi = Region2::pi(pv);
446  Scalar dpi_dp = Region2::dpi_dp(pv);
447  Scalar du_dp =
448  Rs*temperature*
449  (tau*dpi_dp*ddgamma_dtaudpi + dpi_dp*dpi_dp*dgamma_dpi + pi*dpi_dp*ddgamma_ddpi);
450 
451  // use a straight line for extrapolation
452  Scalar uv = internalEnergyRegion2_(temperature, pv);
453  return uv + du_dp*(pressure - pv);
454  */
455 
456  // use a straight line for extrapolation. use backward
457  // differences to calculate the partial derivative to the
458  // pressure at the vapor pressure
459  Scalar eps = 1e-7;
460  const Evaluation& uv = internalEnergyRegion2_(temperature, Evaluation(pv));
461  const Evaluation& uvMEps = internalEnergyRegion2_(temperature, Evaluation(pv - eps));
462  const Evaluation& du_dp = (uv - uvMEps)/eps;
463  return uv + du_dp*(pressure - pv);
464  };
465 
466  return internalEnergyRegion2_(temperature, pressure);
467  }
468 
481  template <class Evaluation>
482  static Evaluation liquidHeatCapacityConstVolume(const Evaluation& temperature,
483  const Evaluation& pressure)
484  {
485  if (!Region1::isValid(temperature, pressure))
486  {
487  throw NumericalProblem(domainError("Heat capacity of water",
488  temperature,
489  pressure));
490  }
491 
492 
493  // regularization
494  Scalar pv = vaporPressure(temperature);
495  if (pressure < pv) {
496  // the pressure is too low, in this case we use the heat cap at the vapor pressure to regularize
497 
498  return heatCap_v_Region1_(temperature, pv);
499  }
500 
501  return heatCap_v_Region1_(temperature, pressure);
502  }
503 
516  template <class Evaluation>
517  static Evaluation gasHeatCapacityConstVolume(const Evaluation& temperature, const Evaluation& pressure)
518  {
519  if (!Region2::isValid(temperature, pressure))
520  {
521  throw NumericalProblem(domainError("Heat capacity of steam",
522  temperature,
523  pressure));
524  }
525 
526  // regularization
527  if (pressure < triplePressure() - 100) {
528  return
529  heatCap_v_Region2_(temperature, triplePressure() - 100);
530  }
531  Scalar pv = vaporPressure(temperature);
532  if (pressure > pv) {
533  return heatCap_v_Region2_(temperature, pv);
534  };
535 
536  return heatCap_v_Region2_(temperature, pressure);
537  }
538 
542  static bool gasIsCompressible()
543  { return true; }
544 
548  static bool liquidIsCompressible()
549  { return true; }
550 
563  template <class Evaluation>
564  static Evaluation gasDensity(const Evaluation& temperature, const Evaluation& pressure)
565  {
566  if (!Region2::isValid(temperature, pressure))
567  {
568  throw NumericalProblem(domainError("Density of steam",
569  temperature,
570  pressure));
571  }
572 
573  // regularization
574  if (pressure < triplePressure() - 100) {
575  // We assume an ideal gas for low pressures to avoid the
576  // 0/0 for the internal energy and enthalpy.
577  const Evaluation& rho0IAPWS =
578  1.0/volumeRegion2_(temperature,
579  Evaluation(triplePressure() - 100));
580  const Evaluation& rho0Id =
581  IdealGas<Scalar>::density(Evaluation(molarMass()),
582  temperature,
583  Evaluation(triplePressure() - 100));
584  return
585  rho0IAPWS/rho0Id
586  *IdealGas<Scalar>::density(Evaluation(molarMass()),
587  temperature,
588  pressure);
589  }
590  Evaluation pv = vaporPressure(temperature);
591  if (pressure > pv) {
592  // the pressure is too high, in this case we use the slope
593  // of the density energy at the vapor pressure to
594  // regularize
595 
596  // calculate the partial derivative of the specific volume
597  // to the pressure at the vapor pressure.
598  Scalar eps = scalarValue(pv)*1e-8;
599  Evaluation v0 = volumeRegion2_(temperature, pv);
600  Evaluation v1 = volumeRegion2_(temperature, pv + eps);
601  Evaluation dv_dp = (v1 - v0)/eps;
602  /*
603  Scalar pi = Region2::pi(pv);
604  Scalar dp_dpi = Region2::dp_dpi(pv);
605  Scalar dgamma_dpi = Region2::dgamma_dpi(temperature, pv);
606  Scalar ddgamma_ddpi = Region2::ddgamma_ddpi(temperature, pv);
607 
608  Scalar RT = Rs*temperature;
609  Scalar dv_dp =
610  RT/(dp_dpi*pv)
611  *
612  (dgamma_dpi + pi*ddgamma_ddpi - v0*dp_dpi/RT);
613  */
614 
615  // calculate the partial derivative of the density to the
616  // pressure at vapor pressure
617  Evaluation drho_dp = - 1/(v0*v0)*dv_dp;
618 
619  // use a straight line for extrapolation
620  return 1.0/v0 + (pressure - pv)*drho_dp;
621  };
622 
623  return 1.0/volumeRegion2_(temperature, pressure);
624  }
625 
629  static bool gasIsIdeal()
630  { return false; }
631 
644  template <class Evaluation>
645  static Evaluation gasPressure(const Evaluation& temperature, Scalar density)
646  {
647  Valgrind::CheckDefined(temperature);
648  Valgrind::CheckDefined(density);
649 
650  // We use the newton method for this. For the initial value we
651  // assume steam to be an ideal gas
652  Evaluation pressure = IdealGas<Scalar>::pressure(temperature, density/molarMass());
653  Scalar eps = pressure*1e-7;
654 
655  Evaluation deltaP = pressure*2;
656  Valgrind::CheckDefined(pressure);
657  Valgrind::CheckDefined(deltaP);
658  for (int i = 0; i < 5 && std::abs(scalarValue(pressure)*1e-9) < std::abs(scalarValue(deltaP)); ++i) {
659  Evaluation f = gasDensity(temperature, pressure) - density;
660 
661  Evaluation df_dp;
662  df_dp = gasDensity(temperature, pressure + eps);
663  df_dp -= gasDensity(temperature, pressure - eps);
664  df_dp /= 2*eps;
665 
666  deltaP = - f/df_dp;
667 
668  pressure += deltaP;
669  Valgrind::CheckDefined(pressure);
670  Valgrind::CheckDefined(deltaP);
671  }
672 
673  return pressure;
674  }
675 
689  template <class Evaluation>
690  static Evaluation liquidDensity(const Evaluation& temperature,
691  const Evaluation& pressure,
692  bool extrapolate = false)
693  {
694  if (!extrapolate && !Region1::isValid(temperature, pressure))
695  {
696  throw NumericalProblem(domainError("Density of water",
697  temperature,
698  pressure));
699  }
700 
701  // regularization
702  Evaluation pv = vaporPressure(temperature);
703  if (pressure < pv) {
704  // the pressure is too low, in this case we use the slope
705  // of the density at the vapor pressure to regularize
706 
707  // calculate the partial derivative of the specific volume
708  // to the pressure at the vapor pressure.
709  Scalar eps = scalarValue(pv)*1e-8;
710  Evaluation v0 = volumeRegion1_(temperature, pv);
711  Evaluation v1 = volumeRegion1_(temperature, pv + eps);
712  Evaluation dv_dp = (v1 - v0)/eps;
713 
714  /*
715  Scalar v0 = volumeRegion1_(temperature, pv);
716  Scalar pi = Region1::pi(pv);
717  Scalar dp_dpi = Region1::dp_dpi(pv);
718  Scalar dgamma_dpi = Region1::dgamma_dpi(temperature, pv);
719  Scalar ddgamma_ddpi = Region1::ddgamma_ddpi(temperature, pv);
720 
721  Scalar RT = Rs*temperature;
722  Scalar dv_dp =
723  RT/(dp_dpi*pv)
724  *
725  (dgamma_dpi + pi*ddgamma_ddpi - v0*dp_dpi/RT);
726  */
727 
728  // calculate the partial derivative of the density to the
729  // pressure at vapor pressure
730  Evaluation drho_dp = - 1/(v0*v0)*dv_dp;
731 
732  // use a straight line for extrapolation
733  return 1.0/v0 + (pressure - pv)*drho_dp;
734  };
735 
736  return 1/volumeRegion1_(temperature, pressure);
737  }
738 
752  template <class Evaluation>
753  static Evaluation liquidPressure(const Evaluation& temperature, Scalar density)
754  {
755  // We use the Newton method for this. For the initial value we
756  // assume the pressure to be 10% higher than the vapor
757  // pressure
758  Evaluation pressure = 1.1*vaporPressure(temperature);
759  Scalar eps = scalarValue(pressure)*1e-7;
760 
761  Evaluation deltaP = pressure*2;
762  for (int i = 0; i < 5 && std::abs(scalarValue(pressure)*1e-9) < std::abs(scalarValue(deltaP)); ++i) {
763  Evaluation f = liquidDensity(temperature, pressure) - density;
764 
765  Evaluation df_dp;
766  df_dp = liquidDensity(temperature, pressure + eps);
767  df_dp -= liquidDensity(temperature, pressure - eps);
768  df_dp /= 2*eps;
769 
770  deltaP = - f/df_dp;
771 
772  pressure += deltaP;
773  }
774 
775  return pressure;
776  }
777 
792  template <class Evaluation>
793  static Evaluation gasViscosity(const Evaluation& temperature, const Evaluation& pressure)
794  {
795  if (!Region2::isValid(temperature, pressure))
796  {
797  throw NumericalProblem(domainError("Viscosity of steam",
798  temperature,
799  pressure));
800  }
801 
802  Evaluation rho = gasDensity(temperature, pressure);
803  return Common::viscosity(temperature, rho);
804  }
805 
818  template <class Evaluation>
819  static Evaluation liquidViscosity(const Evaluation& temperature,
820  const Evaluation& pressure,
821  bool extrapolate = false)
822  {
823  if (!extrapolate && !Region1::isValid(temperature, pressure))
824  {
825  throw NumericalProblem(domainError("Viscosity of water",
826  temperature,
827  pressure));
828  };
829 
830  const Evaluation& rho = liquidDensity(temperature, pressure, extrapolate);
831  return Common::viscosity(temperature, rho);
832  }
833 
847  template <class Evaluation>
848  static Evaluation liquidThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
849  {
850  const Evaluation& rho = liquidDensity(temperature, pressure);
851  return Common::thermalConductivityIAPWS(temperature, rho);
852  }
853 
867  template <class Evaluation>
868  static Evaluation gasThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
869  {
870  const Evaluation& rho = gasDensity(temperature, pressure);
871  return Common::thermalConductivityIAPWS(temperature, rho);
872  }
873 
874 private:
875  // the unregularized specific enthalpy for liquid water
876  template <class Evaluation>
877  static Evaluation enthalpyRegion1_(const Evaluation& temperature, const Evaluation& pressure)
878  {
879  return
880  Region1::tau(temperature) *
881  Region1::dgamma_dtau(temperature, pressure) *
882  Rs*temperature;
883  }
884 
885  // the unregularized specific isobaric heat capacity
886  template <class Evaluation>
887  static Evaluation heatCap_p_Region1_(const Evaluation& temperature, const Evaluation& pressure)
888  {
889  return
890  - pow(Region1::tau(temperature), 2.0) *
891  Region1::ddgamma_ddtau(temperature, pressure) *
892  Rs;
893  }
894 
895  // the unregularized specific isochoric heat capacity
896  template <class Evaluation>
897  static Evaluation heatCap_v_Region1_(const Evaluation& temperature, const Evaluation& pressure)
898  {
899  double tau = Region1::tau(temperature);
900  double num = Region1::dgamma_dpi(temperature, pressure) - tau * Region1::ddgamma_dtaudpi(temperature, pressure);
901  double diff = std::pow(num, 2) / Region1::ddgamma_ddpi(temperature, pressure);
902 
903  return
904  - std::pow(tau, 2 ) *
905  Region1::ddgamma_ddtau(temperature, pressure) * Rs +
906  diff;
907  }
908 
909  // the unregularized specific internal energy for liquid water
910  template <class Evaluation>
911  static Evaluation internalEnergyRegion1_(const Evaluation& temperature, const Evaluation& pressure)
912  {
913  return
914  Rs * temperature *
915  ( Region1::tau(temperature)*Region1::dgamma_dtau(temperature, pressure) -
916  Region1::pi(pressure)*Region1::dgamma_dpi(temperature, pressure));
917  }
918 
919  // the unregularized specific volume for liquid water
920  template <class Evaluation>
921  static Evaluation volumeRegion1_(const Evaluation& temperature, const Evaluation& pressure)
922  {
923  return
924  Region1::pi(pressure)*
925  Region1::dgamma_dpi(temperature, pressure) *
926  Rs * temperature / pressure;
927  }
928 
929  // the unregularized specific enthalpy for steam
930  template <class Evaluation>
931  static Evaluation enthalpyRegion2_(const Evaluation& temperature, const Evaluation& pressure)
932  {
933  return
934  Region2::tau(temperature) *
935  Region2::dgamma_dtau(temperature, pressure) *
936  Rs*temperature;
937  }
938 
939  // the unregularized specific internal energy for steam
940  template <class Evaluation>
941  static Evaluation internalEnergyRegion2_(const Evaluation& temperature, const Evaluation& pressure)
942  {
943  return
944  Rs * temperature *
945  ( Region2::tau(temperature)*Region2::dgamma_dtau(temperature, pressure) -
946  Region2::pi(pressure)*Region2::dgamma_dpi(temperature, pressure));
947  }
948 
949  // the unregularized specific isobaric heat capacity
950  template <class Evaluation>
951  static Evaluation heatCap_p_Region2_(const Evaluation& temperature, const Evaluation& pressure)
952  {
953  return
954  - pow(Region2::tau(temperature), 2 ) *
955  Region2::ddgamma_ddtau(temperature, pressure) *
956  Rs;
957  }
958 
959  // the unregularized specific isochoric heat capacity
960  template <class Evaluation>
961  static Evaluation heatCap_v_Region2_(const Evaluation& temperature, const Evaluation& pressure)
962  {
963  const Evaluation& tau = Region2::tau(temperature);
964  const Evaluation& pi = Region2::pi(pressure);
965  const Evaluation& num = 1 + pi * Region2::dgamma_dpi(temperature, pressure) + tau * pi * Region2::ddgamma_dtaudpi(temperature, pressure);
966  const Evaluation& diff = num * num / (1 - pi * pi * Region2::ddgamma_ddpi(temperature, pressure));
967  return
968  - std::pow(tau, 2 ) *
969  Region2::ddgamma_ddtau(temperature, pressure) * Rs
970  - diff;
971  }
972 
973  // the unregularized specific volume for steam
974  template <class Evaluation>
975  static Evaluation volumeRegion2_(const Evaluation& temperature, const Evaluation& pressure)
976  {
977  return
978  Region2::pi(pressure)*
979  Region2::dgamma_dpi(temperature, pressure) *
980  Rs * temperature / pressure;
981  }
982 
983 private:
984  template<class Evaluation>
985  static std::string domainError(const std::string& type,
986  const Evaluation& temperature,
987  const Evaluation& pressure)
988  {
989  auto cast = [](const auto d)
990  {
991 #if HAVE_QUAD
992  if constexpr (std::is_same_v<decltype(d), const quad>)
993  return static_cast<double>(d);
994  else
995 #endif
996  return d;
997  };
998  auto tostring = [cast](const auto& val) -> std::string
999  {
1000  if constexpr (DenseAd::is_evaluation<Evaluation>::value) {
1001  return std::to_string(cast(getValue(val.value())));
1002  }
1003  else
1004  return std::to_string(cast(getValue(val)));
1005  };
1006 
1007  return type + " is only implemented for temperatures "
1008  "below 623.15K and pressures below 100MPa. (T = " +
1009  tostring(temperature) + ", p=" + tostring(pressure);
1010  }
1011 }; // end class
1012 
1013 template <class Scalar>
1014 const Scalar H2O<Scalar>::Rs = Common::Rs;
1015 } // namespace Opm
1016 
1017 #endif
Material properties of pure water .
Definition: H2O.hpp:64
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
static OPM_HOST_DEVICE Evaluation pressure(const Evaluation &temperature, const Evaluation &rhoMolar)
The pressure of the gas in , depending on the molar density and temperature.
Definition: IdealGas.hpp:59
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 bool gasIsIdeal()
Returns true iff the gas phase is assumed to be ideal.
Definition: H2O.hpp:629
static constexpr Scalar acentricFactor
The acentric factor of water .
Definition: Common.hpp:80
Definition: Exceptions.hpp:39
static const Scalar tripleTemperature()
Returns the temperature at water&#39;s triple point.
Definition: H2O.hpp:121
Relations valid for an ideal gas.
Abstract base class of a pure chemical species.
Definition: Component.hpp:43
static Evaluation vaporTemperature(const Evaluation &pressure)
Returns the saturation temperature in of pure water at a given pressure.
Definition: Region4.hpp:94
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 saturationPressure(const Evaluation &temperature)
Returns the saturation pressure in of pure water at a given temperature.
Definition: Region4.hpp:63
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
static bool liquidIsCompressible()
Returns true iff the liquid phase is assumed to be compressible.
Definition: H2O.hpp:548
static Evaluation gasViscosity(const Evaluation &temperature, const Evaluation &pressure)
The dynamic viscosity of steam.
Definition: H2O.hpp:793
Implements the equations for region 1 of the IAPWS &#39;97 formulation.
Definition: Region1.hpp:50
static const Scalar acentricFactor()
The acentric factor of water.
Definition: H2O.hpp:91
static bool gasIsCompressible()
Returns true iff the gas phase is assumed to be compressible.
Definition: H2O.hpp:542
static Evaluation liquidInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of liquid water .
Definition: H2O.hpp:350
Provides the OPM specific exception classes.
static Evaluation vaporTemperature(const Evaluation &pressure)
The vapor temperature in of pure water at a given pressure.
Definition: H2O.hpp:165
static Evaluation gasDensity(const Evaluation &temperature, const Evaluation &pressure)
The density of steam in at a given pressure and temperature.
Definition: H2O.hpp:564
static Evaluation liquidThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
Thermal conductivity of water (IAPWS) .
Definition: H2O.hpp:848
static Evaluation liquidEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of liquid water .
Definition: H2O.hpp:239
static Evaluation pi(const Evaluation &pressure)
Returns the reduced pressure (dimensionless) for IAPWS region 2.
Definition: Region2.hpp:101
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 gasInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of steam and water vapor .
Definition: H2O.hpp:408
static Evaluation liquidHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of liquid water .
Definition: H2O.hpp:316
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Implements the equations for region 1 of the IAPWS &#39;97 formulation.
static OPM_HOST_DEVICE Evaluation thermalConductivityIAPWS(const Evaluation &T, const Evaluation &rho)
Thermal conductivity water (IAPWS) .
Definition: Common.hpp:164
static Evaluation liquidHeatCapacityConstVolume(const Evaluation &temperature, const Evaluation &pressure)
Specific isochoric heat capacity of liquid water .
Definition: H2O.hpp:482
Implements the equations for region 2 of the IAPWS &#39;97 formulation.
Definition: Region2.hpp:51
static constexpr Scalar tripleTemperature
Triple temperature of water .
Definition: Common.hpp:83
Implements the equations for region 4 of the IAPWS &#39;97 formulation.
Definition: Region4.hpp:51
Abstract base class of a pure chemical species.
static constexpr Scalar criticalTemperature
Critical temperature of water .
Definition: Common.hpp:65
static const Scalar criticalVolume()
Returns the critical volume of water.
Definition: H2O.hpp:109
static const Scalar criticalTemperature()
Returns the critical temperature of water.
Definition: H2O.hpp:97
static constexpr Scalar criticalMolarVolume
Critical molar volume of water .
Definition: Common.hpp:77
static Evaluation gasHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of water steam .
Definition: H2O.hpp:281
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 Evaluation tau(const Evaluation &temperature)
Returns the reduced temperature for IAPWS region 1.
Definition: Region1.hpp:83
static Evaluation vaporPressure(Evaluation temperature)
The vapor pressure in of pure water at a given temperature.
Definition: H2O.hpp:143
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 const Scalar criticalMolarVolume()
Returns the molar volume of water at the critical point.
Definition: H2O.hpp:115
static OPM_HOST_DEVICE Evaluation viscosity(const Evaluation &temperature, const Evaluation &rho)
The dynamic viscosity of pure water.
Definition: Common.hpp:103
This file provides the infrastructure to use quad-precision floating point values in the numerical mo...
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 std::string_view name()
A human readable name for the water.
Definition: H2O.hpp:79
static Evaluation gasEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of water steam .
Definition: H2O.hpp:188
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:690
Implements relations which are common for all regions of the IAPWS &#39;97 formulation.
Definition: Common.hpp:55
static Evaluation liquidViscosity(const Evaluation &temperature, const Evaluation &pressure, bool extrapolate=false)
The dynamic viscosity of pure water.
Definition: H2O.hpp:819
static Evaluation gasThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
Thermal conductivity of water (IAPWS) .
Definition: H2O.hpp:868
Implements the equations for region 4 of the IAPWS &#39;97 formulation.
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 Evaluation pi(const Evaluation &pressure)
Returns the reduced pressure for IAPWS region 1.
Definition: Region1.hpp:102
static constexpr Scalar criticalVolume
Critical volume of water .
Definition: Common.hpp:74
static Evaluation tau(const Evaluation &temperature)
Returns the reduced temperature (dimensionless) for IAPWS region 2.
Definition: Region2.hpp:82
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 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 Evaluation gasPressure(const Evaluation &temperature, Scalar density)
The pressure of steam in at a given density and temperature.
Definition: H2O.hpp:645
static Evaluation gasHeatCapacityConstVolume(const Evaluation &temperature, const Evaluation &pressure)
Specific isochoric heat capacity of steam and water vapor .
Definition: H2O.hpp:517
static const Scalar molarMass()
The molar mass in of water.
Definition: H2O.hpp:85
Some templates to wrap the valgrind client request macros.
Implements the equations for region 2 of the IAPWS &#39;97 formulation.
static constexpr Scalar criticalPressure
Critical pressure of water .
Definition: Common.hpp:68
static constexpr Scalar molarMass
The molar mass of water .
Definition: Common.hpp:59
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
Implements relations which are common for all regions of the IAPWS &#39;97 formulation.
static const Scalar triplePressure()
Returns the pressure at water&#39;s triple point.
Definition: H2O.hpp:127
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 OPM_HOST_DEVICE 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:49
static const Scalar criticalPressure()
Returns the critical pressure of water.
Definition: H2O.hpp:103
Representation of an evaluation of a function and its derivatives w.r.t.
static constexpr Scalar triplePressure
Triple pressure of water .
Definition: Common.hpp:86
static Evaluation liquidPressure(const Evaluation &temperature, Scalar density)
The pressure of liquid water in at a given density and temperature.
Definition: H2O.hpp:753
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