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