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:
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()
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()
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
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 =
582 temperature,
583 Evaluation(triplePressure() - 100));
584 return
585 rho0IAPWS/rho0Id
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
688 template <class Evaluation>
689 static Evaluation liquidDensity(const Evaluation& temperature,
690 const Evaluation& pressure,
691 bool extrapolate = false)
692 {
693 if (!extrapolate && !Region1::isValid(temperature, pressure))
694 {
695 throw NumericalProblem(domainError("Density of water",
696 temperature,
697 pressure));
698 }
699
700 // regularization
701 Evaluation pv = vaporPressure(temperature);
702 if (pressure < pv) {
703 // the pressure is too low, in this case we use the slope
704 // of the density at the vapor pressure to regularize
705
706 // calculate the partial derivative of the specific volume
707 // to the pressure at the vapor pressure.
708 Scalar eps = scalarValue(pv)*1e-8;
709 Evaluation v0 = volumeRegion1_(temperature, pv);
710 Evaluation v1 = volumeRegion1_(temperature, pv + eps);
711 Evaluation dv_dp = (v1 - v0)/eps;
712
713 /*
714 Scalar v0 = volumeRegion1_(temperature, pv);
715 Scalar pi = Region1::pi(pv);
716 Scalar dp_dpi = Region1::dp_dpi(pv);
717 Scalar dgamma_dpi = Region1::dgamma_dpi(temperature, pv);
718 Scalar ddgamma_ddpi = Region1::ddgamma_ddpi(temperature, pv);
719
720 Scalar RT = Rs*temperature;
721 Scalar dv_dp =
722 RT/(dp_dpi*pv)
723 *
724 (dgamma_dpi + pi*ddgamma_ddpi - v0*dp_dpi/RT);
725 */
726
727 // calculate the partial derivative of the density to the
728 // pressure at vapor pressure
729 Evaluation drho_dp = - 1/(v0*v0)*dv_dp;
730
731 // use a straight line for extrapolation
732 return 1.0/v0 + (pressure - pv)*drho_dp;
733 };
734
735 return 1/volumeRegion1_(temperature, pressure);
736 }
737
751 template <class Evaluation>
752 static Evaluation liquidPressure(const Evaluation& temperature, Scalar density)
753 {
754 // We use the Newton method for this. For the initial value we
755 // assume the pressure to be 10% higher than the vapor
756 // pressure
757 Evaluation pressure = 1.1*vaporPressure(temperature);
758 Scalar eps = scalarValue(pressure)*1e-7;
759
760 Evaluation deltaP = pressure*2;
761 for (int i = 0; i < 5 && std::abs(scalarValue(pressure)*1e-9) < std::abs(scalarValue(deltaP)); ++i) {
762 Evaluation f = liquidDensity(temperature, pressure) - density;
763
764 Evaluation df_dp;
765 df_dp = liquidDensity(temperature, pressure + eps);
766 df_dp -= liquidDensity(temperature, pressure - eps);
767 df_dp /= 2*eps;
768
769 deltaP = - f/df_dp;
770
771 pressure += deltaP;
772 }
773
774 return pressure;
775 }
776
791 template <class Evaluation>
792 static Evaluation gasViscosity(const Evaluation& temperature, const Evaluation& pressure)
793 {
794 if (!Region2::isValid(temperature, pressure))
795 {
796 throw NumericalProblem(domainError("Viscosity of steam",
797 temperature,
798 pressure));
799 }
800
801 Evaluation rho = gasDensity(temperature, pressure);
802 return Common::viscosity(temperature, rho);
803 }
804
816 template <class Evaluation>
817 static Evaluation liquidViscosity(const Evaluation& temperature,
818 const Evaluation& pressure,
819 bool extrapolate = false)
820 {
821 if (!extrapolate && !Region1::isValid(temperature, pressure))
822 {
823 throw NumericalProblem(domainError("Viscosity of water",
824 temperature,
825 pressure));
826 };
827
828 const Evaluation& rho = liquidDensity(temperature, pressure, extrapolate);
829 return Common::viscosity(temperature, rho);
830 }
831
845 template <class Evaluation>
846 static Evaluation liquidThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
847 {
848 const Evaluation& rho = liquidDensity(temperature, pressure);
849 return Common::thermalConductivityIAPWS(temperature, rho);
850 }
851
865 template <class Evaluation>
866 static Evaluation gasThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
867 {
868 const Evaluation& rho = gasDensity(temperature, pressure);
869 return Common::thermalConductivityIAPWS(temperature, rho);
870 }
871
872private:
873 // the unregularized specific enthalpy for liquid water
874 template <class Evaluation>
875 static Evaluation enthalpyRegion1_(const Evaluation& temperature, const Evaluation& pressure)
876 {
877 return
878 Region1::tau(temperature) *
879 Region1::dgamma_dtau(temperature, pressure) *
880 Rs*temperature;
881 }
882
883 // the unregularized specific isobaric heat capacity
884 template <class Evaluation>
885 static Evaluation heatCap_p_Region1_(const Evaluation& temperature, const Evaluation& pressure)
886 {
887 return
888 - pow(Region1::tau(temperature), 2.0) *
889 Region1::ddgamma_ddtau(temperature, pressure) *
890 Rs;
891 }
892
893 // the unregularized specific isochoric heat capacity
894 template <class Evaluation>
895 static Evaluation heatCap_v_Region1_(const Evaluation& temperature, const Evaluation& pressure)
896 {
897 double tau = Region1::tau(temperature);
898 double num = Region1::dgamma_dpi(temperature, pressure) - tau * Region1::ddgamma_dtaudpi(temperature, pressure);
899 double diff = std::pow(num, 2) / Region1::ddgamma_ddpi(temperature, pressure);
900
901 return
902 - std::pow(tau, 2 ) *
903 Region1::ddgamma_ddtau(temperature, pressure) * Rs +
904 diff;
905 }
906
907 // the unregularized specific internal energy for liquid water
908 template <class Evaluation>
909 static Evaluation internalEnergyRegion1_(const Evaluation& temperature, const Evaluation& pressure)
910 {
911 return
912 Rs * temperature *
913 ( Region1::tau(temperature)*Region1::dgamma_dtau(temperature, pressure) -
914 Region1::pi(pressure)*Region1::dgamma_dpi(temperature, pressure));
915 }
916
917 // the unregularized specific volume for liquid water
918 template <class Evaluation>
919 static Evaluation volumeRegion1_(const Evaluation& temperature, const Evaluation& pressure)
920 {
921 return
922 Region1::pi(pressure)*
923 Region1::dgamma_dpi(temperature, pressure) *
924 Rs * temperature / pressure;
925 }
926
927 // the unregularized specific enthalpy for steam
928 template <class Evaluation>
929 static Evaluation enthalpyRegion2_(const Evaluation& temperature, const Evaluation& pressure)
930 {
931 return
932 Region2::tau(temperature) *
933 Region2::dgamma_dtau(temperature, pressure) *
934 Rs*temperature;
935 }
936
937 // the unregularized specific internal energy for steam
938 template <class Evaluation>
939 static Evaluation internalEnergyRegion2_(const Evaluation& temperature, const Evaluation& pressure)
940 {
941 return
942 Rs * temperature *
943 ( Region2::tau(temperature)*Region2::dgamma_dtau(temperature, pressure) -
944 Region2::pi(pressure)*Region2::dgamma_dpi(temperature, pressure));
945 }
946
947 // the unregularized specific isobaric heat capacity
948 template <class Evaluation>
949 static Evaluation heatCap_p_Region2_(const Evaluation& temperature, const Evaluation& pressure)
950 {
951 return
952 - pow(Region2::tau(temperature), 2 ) *
953 Region2::ddgamma_ddtau(temperature, pressure) *
954 Rs;
955 }
956
957 // the unregularized specific isochoric heat capacity
958 template <class Evaluation>
959 static Evaluation heatCap_v_Region2_(const Evaluation& temperature, const Evaluation& pressure)
960 {
961 const Evaluation& tau = Region2::tau(temperature);
962 const Evaluation& pi = Region2::pi(pressure);
963 const Evaluation& num = 1 + pi * Region2::dgamma_dpi(temperature, pressure) + tau * pi * Region2::ddgamma_dtaudpi(temperature, pressure);
964 const Evaluation& diff = num * num / (1 - pi * pi * Region2::ddgamma_ddpi(temperature, pressure));
965 return
966 - std::pow(tau, 2 ) *
967 Region2::ddgamma_ddtau(temperature, pressure) * Rs
968 - diff;
969 }
970
971 // the unregularized specific volume for steam
972 template <class Evaluation>
973 static Evaluation volumeRegion2_(const Evaluation& temperature, const Evaluation& pressure)
974 {
975 return
976 Region2::pi(pressure)*
977 Region2::dgamma_dpi(temperature, pressure) *
978 Rs * temperature / pressure;
979 }
980
981private:
982 template<class Evaluation>
983 static std::string domainError(const std::string& type,
984 const Evaluation& temperature,
985 const Evaluation& pressure)
986 {
987 auto cast = [](const auto d)
988 {
989#if HAVE_QUAD
990 if constexpr (std::is_same_v<decltype(d), const quad>)
991 return static_cast<double>(d);
992 else
993#endif
994 return d;
995 };
996 auto tostring = [cast](const auto& val) -> std::string
997 {
998 if constexpr (DenseAd::is_evaluation<Evaluation>::value) {
999 return std::to_string(cast(getValue(val.value())));
1000 }
1001 else
1002 return std::to_string(cast(getValue(val)));
1003 };
1004
1005 return type + " is only implemented for temperatures "
1006 "below 623.15K and pressures below 100MPa. (T = " +
1007 tostring(temperature) + ", p=" + tostring(pressure);
1008 }
1009}; // end class
1010
1011template <class Scalar>
1012const Scalar H2O<Scalar>::Rs = Common::Rs;
1013} // namespace Opm
1014
1015#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:689
static const Scalar criticalTemperature()
Returns the critical temperature of water.
Definition H2O.hpp:97
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 std::string_view name()
A human readable name for the water.
Definition H2O.hpp:79
static bool gasIsCompressible()
Returns true iff the gas phase is assumed to be compressible.
Definition H2O.hpp:542
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 vaporPressure(Evaluation temperature)
The vapor pressure in of pure water at a given temperature.
Definition H2O.hpp:143
static Evaluation gasViscosity(const Evaluation &temperature, const Evaluation &pressure)
The dynamic viscosity of steam.
Definition H2O.hpp:792
static Evaluation gasHeatCapacityConstVolume(const Evaluation &temperature, const Evaluation &pressure)
Specific isochoric heat capacity of steam and water vapor .
Definition H2O.hpp:517
static Evaluation gasHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of water steam .
Definition H2O.hpp:281
static const Scalar criticalMolarVolume()
Returns the molar volume of water at the critical point.
Definition H2O.hpp:115
static Evaluation liquidEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of liquid water .
Definition H2O.hpp:239
static Evaluation liquidThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
Thermal conductivity of water (IAPWS) .
Definition H2O.hpp:846
static const Scalar acentricFactor()
The acentric factor of water.
Definition H2O.hpp:91
static Evaluation liquidInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of liquid water .
Definition H2O.hpp:350
static bool gasIsIdeal()
Returns true iff the gas phase is assumed to be ideal.
Definition H2O.hpp:629
static const Scalar criticalPressure()
Returns the critical pressure of water.
Definition H2O.hpp:103
static const Scalar molarMass()
The molar mass in of water.
Definition H2O.hpp:85
static Evaluation vaporTemperature(const Evaluation &pressure)
The vapor temperature in of pure water at a given pressure.
Definition H2O.hpp:165
static bool liquidIsCompressible()
Returns true iff the liquid phase is assumed to be compressible.
Definition H2O.hpp:548
static Evaluation liquidViscosity(const Evaluation &temperature, const Evaluation &pressure, bool extrapolate=false)
The dynamic viscosity of pure water.
Definition H2O.hpp:817
static Evaluation gasInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of steam and water vapor .
Definition H2O.hpp:408
static Evaluation gasThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
Thermal conductivity of water (IAPWS) .
Definition H2O.hpp:866
static Evaluation gasEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of water steam .
Definition H2O.hpp:188
static Evaluation liquidHeatCapacityConstVolume(const Evaluation &temperature, const Evaluation &pressure)
Specific isochoric heat capacity of liquid water .
Definition H2O.hpp:482
static Evaluation liquidPressure(const Evaluation &temperature, Scalar density)
The pressure of liquid water in at a given density and temperature.
Definition H2O.hpp:752
static const Scalar tripleTemperature()
Returns the temperature at water's triple point.
Definition H2O.hpp:121
static Evaluation liquidHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of liquid water .
Definition H2O.hpp:316
static const Scalar triplePressure()
Returns the pressure at water's triple point.
Definition H2O.hpp:127
static const Scalar criticalVolume()
Returns the critical volume of water.
Definition H2O.hpp:109
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...