opm-common
TabulatedComponent.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 */
28 #ifndef OPM_TABULATED_COMPONENT_HPP
29 #define OPM_TABULATED_COMPONENT_HPP
30 
32 
33 #include <cmath>
34 #include <cstddef>
35 #include <limits>
36 #include <cassert>
37 #include <stdexcept>
38 #include <vector>
39 
40 namespace Opm {
41 
42 template<class Scalar>
44 {
45  // 1D fields with the temperature as degree of freedom
46  std::vector<Scalar> vaporPressure_;
47 
48  std::vector<Scalar> minLiquidDensity__;
49  std::vector<Scalar> maxLiquidDensity__;
50 
51  std::vector<Scalar> minGasDensity__;
52  std::vector<Scalar> maxGasDensity__;
53 
54  // 2D fields with the temperature and pressure as degrees of
55  // freedom
56  std::vector<Scalar> gasEnthalpy_;
57  std::vector<Scalar> liquidEnthalpy_;
58 
59  std::vector<Scalar> gasHeatCapacity_;
60  std::vector<Scalar> liquidHeatCapacity_;
61 
62  std::vector<Scalar> gasDensity_;
63  std::vector<Scalar> liquidDensity_;
64 
65  std::vector<Scalar> gasViscosity_;
66  std::vector<Scalar> liquidViscosity_;
67 
68  std::vector<Scalar> gasThermalConductivity_;
69  std::vector<Scalar> liquidThermalConductivity_;
70 
71  // 2D fields with the temperature and density as degrees of
72  // freedom
73  std::vector<Scalar> gasPressure_;
74  std::vector<Scalar> liquidPressure_;
75 
76  // temperature, pressure and density ranges
77  Scalar tempMin_;
78  Scalar tempMax_;
79  unsigned nTemp_;
80 
81  Scalar pressMin_;
82  Scalar pressMax_;
83  unsigned nPress_;
84 
85  Scalar densityMin_;
86  Scalar densityMax_;
87  unsigned nDensity_;
88 
89  void init(Scalar tempMin, Scalar tempMax, unsigned nTemp,
90  Scalar pressMin, Scalar pressMax, unsigned nPress)
91  {
92  tempMin_ = tempMin;
93  tempMax_ = tempMax;
94  nTemp_ = nTemp;
95  pressMin_ = pressMin;
96  pressMax_ = pressMax;
97  nPress_ = nPress;
98  nDensity_ = nPress_;
99 
100  // allocate the arrays
101  vaporPressure_.resize(nTemp_);
102  minGasDensity__.resize(nTemp_);
103  maxGasDensity__.resize(nTemp_);
104  minLiquidDensity__.resize(nTemp_);
105  maxLiquidDensity__.resize(nTemp_);
106 
107  gasEnthalpy_.resize(nTemp_*nPress_);
108  liquidEnthalpy_.resize(nTemp_*nPress_);
109  gasHeatCapacity_.resize(nTemp_*nPress_);
110  liquidHeatCapacity_.resize(nTemp_*nPress_);
111  gasDensity_.resize(nTemp_*nPress_);
112  liquidDensity_.resize(nTemp_*nPress_);
113  gasViscosity_.resize(nTemp_*nPress_);
114  liquidViscosity_.resize(nTemp_*nPress_);
115  gasThermalConductivity_.resize(nTemp_*nPress_);
116  liquidThermalConductivity_.resize(nTemp_*nPress_);
117  gasPressure_.resize(nTemp_*nDensity_);
118  liquidPressure_.resize(nTemp_*nDensity_);
119  }
120 };
121 
137 template <class ScalarT, class RawComponent, bool useVaporPressure=true>
139 {
140 public:
141  using Scalar = ScalarT;
142 
143  static constexpr bool isTabulated = true;
144 
155  static void init(Scalar tempMin, Scalar tempMax, unsigned nTemp,
156  Scalar pressMin, Scalar pressMax, unsigned nPress)
157  {
158  data_.init(tempMin, tempMax, nTemp, pressMin, pressMax, nPress);
159 
160  assert(std::numeric_limits<Scalar>::has_quiet_NaN);
161  constexpr Scalar NaN = std::numeric_limits<Scalar>::quiet_NaN();
162 
163  // fill the temperature-pressure arrays
164  for (unsigned iT = 0; iT < data_.nTemp_; ++ iT) {
165  const Scalar temperature = iT * (data_.tempMax_ - data_.tempMin_) / (data_.nTemp_ - 1) + data_.tempMin_;
166 
167  try {
168  data_.vaporPressure_[iT] = RawComponent::vaporPressure(temperature);
169  }
170  catch (const std::exception&) {
171  data_.vaporPressure_[iT] = NaN;
172  }
173 
174  const Scalar pgMax = maxGasPressure_(iT);
175  const Scalar pgMin = minGasPressure_(iT);
176 
177  // fill the temperature, pressure gas arrays
178  for (unsigned iP = 0; iP < data_.nPress_; ++ iP) {
179  const Scalar pressure = iP * (pgMax - pgMin) / (data_.nPress_ - 1) + pgMin;
180 
181  const unsigned i = iT + iP * data_.nTemp_;
182 
183  try {
184  data_.gasEnthalpy_[i] = RawComponent::gasEnthalpy(temperature, pressure);
185  }
186  catch (const std::exception&) {
187  data_.gasEnthalpy_[i] = NaN;
188  }
189 
190  try {
191  data_.gasHeatCapacity_[i] = RawComponent::gasHeatCapacity(temperature, pressure);
192  }
193  catch (const std::exception&) {
194  data_.gasHeatCapacity_[i] = NaN;
195  }
196 
197  try {
198  data_.gasDensity_[i] = RawComponent::gasDensity(temperature, pressure);
199  }
200  catch (const std::exception&) {
201  data_.gasDensity_[i] = NaN;
202  }
203 
204  try {
205  data_.gasViscosity_[i] = RawComponent::gasViscosity(temperature, pressure);
206  }
207  catch (const std::exception&) {
208  data_.gasViscosity_[i] = NaN;
209  }
210 
211  try {
212  data_.gasThermalConductivity_[i] = RawComponent::gasThermalConductivity(temperature, pressure);
213  }
214  catch (const std::exception&) {
215  data_.gasThermalConductivity_[i] = NaN;
216  }
217  };
218 
219  const Scalar plMin = minLiquidPressure_(iT);
220  const Scalar plMax = maxLiquidPressure_(iT);
221  for (unsigned iP = 0; iP < data_.nPress_; ++ iP) {
222  Scalar pressure = iP * (plMax - plMin) / (data_.nPress_ - 1) + plMin;
223 
224  const unsigned i = iT + iP*data_.nTemp_;
225 
226  try {
227  data_.liquidEnthalpy_[i] = RawComponent::liquidEnthalpy(temperature, pressure);
228  }
229  catch (const std::exception&) {
230  data_.liquidEnthalpy_[i] = NaN;
231  }
232 
233  try {
234  data_.liquidHeatCapacity_[i] = RawComponent::liquidHeatCapacity(temperature, pressure);
235  }
236  catch (const std::exception&) {
237  data_.liquidHeatCapacity_[i] = NaN;
238  }
239 
240  try {
241  data_.liquidDensity_[i] = RawComponent::liquidDensity(temperature, pressure);
242  }
243  catch (const std::exception&) {
244  data_.liquidDensity_[i] = NaN;
245  }
246 
247  try {
248  data_.liquidViscosity_[i] = RawComponent::liquidViscosity(temperature, pressure);
249  }
250  catch (const std::exception&) {
251  data_.liquidViscosity_[i] = NaN;
252  }
253 
254  try {
255  data_.liquidThermalConductivity_[i] = RawComponent::liquidThermalConductivity(temperature, pressure);
256  }
257  catch (const std::exception&) {
258  data_.liquidThermalConductivity_[i] = NaN;
259  }
260  }
261  }
262 
263  // fill the temperature-density arrays
264  for (unsigned iT = 0; iT < data_.nTemp_; ++ iT) {
265  const Scalar temperature = iT * (data_.tempMax_ - data_.tempMin_) / (data_.nTemp_ - 1) + data_.tempMin_;
266 
267  // calculate the minimum and maximum values for the gas
268  // densities
269  data_.minGasDensity__[iT] = RawComponent::gasDensity(temperature, minGasPressure_(iT));
270  if (iT < data_.nTemp_ - 1) {
271  data_.maxGasDensity__[iT] = RawComponent::gasDensity(temperature, maxGasPressure_(iT + 1));
272  }
273  else {
274  data_.maxGasDensity__[iT] = RawComponent::gasDensity(temperature, maxGasPressure_(iT));
275  }
276 
277  // fill the temperature, density gas arrays
278  for (unsigned iRho = 0; iRho < data_.nDensity_; ++ iRho) {
279  const Scalar density =
280  Scalar(iRho) / (data_.nDensity_ - 1) *
281  (data_.maxGasDensity__[iT] - data_.minGasDensity__[iT])
282  +
283  data_.minGasDensity__[iT];
284 
285  const unsigned i = iT + iRho * data_.nTemp_;
286 
287  try {
288  data_.gasPressure_[i] = RawComponent::gasPressure(temperature, density);
289  }
290  catch (const std::exception&) {
291  data_.gasPressure_[i] = NaN;
292  }
293  }
294 
295  // calculate the minimum and maximum values for the liquid
296  // densities
297  data_.minLiquidDensity__[iT] = RawComponent::liquidDensity(temperature, minLiquidPressure_(iT));
298  if (iT < data_.nTemp_ - 1) {
299  data_.maxLiquidDensity__[iT] = RawComponent::liquidDensity(temperature, maxLiquidPressure_(iT + 1));
300  }
301  else {
302  data_.maxLiquidDensity__[iT] = RawComponent::liquidDensity(temperature, maxLiquidPressure_(iT));
303  }
304 
305  // fill the temperature, density liquid arrays
306  for (unsigned iRho = 0; iRho < data_.nDensity_; ++ iRho) {
307  const Scalar density =
308  Scalar(iRho) / (data_.nDensity_ - 1) *
309  (data_.maxLiquidDensity__[iT] - data_.minLiquidDensity__[iT])
310  +
311  data_.minLiquidDensity__[iT];
312 
313  const unsigned i = iT + iRho * data_.nTemp_;
314 
315  try {
316  data_.liquidPressure_[i] = RawComponent::liquidPressure(temperature, density);
317  }
318  catch (const std::exception&) {
319  data_.liquidPressure_[i] = NaN;
320  }
321  }
322  }
323  }
324 
328  static std::string_view name()
329  { return RawComponent::name(); }
330 
334  static Scalar molarMass()
335  { return RawComponent::molarMass(); }
336 
340  static Scalar criticalTemperature()
341  { return RawComponent::criticalTemperature(); }
342 
346  static Scalar criticalPressure()
347  { return RawComponent::criticalPressure(); }
348 
352  static Scalar acentricFactor()
353  { throw std::runtime_error("Not implemented: acentricFactor of the component"); }
354 
358  static Scalar criticalVolume()
359  { throw std::runtime_error("Not implemented: criticalVolume of the compoenent"); }
360 
364  static Scalar tripleTemperature()
365  { return RawComponent::tripleTemperature(); }
366 
370  static Scalar triplePressure()
371  { return RawComponent::triplePressure(); }
372 
379  template <class Evaluation>
380  static Evaluation vaporPressure(const Evaluation& temperature)
381  {
382  const Evaluation& result = interpolateT_(data_.vaporPressure_, temperature);
383  if (std::isnan(scalarValue(result))) {
384  return RawComponent::vaporPressure(temperature);
385  }
386  return result;
387  }
388 
395  template <class Evaluation>
396  static Evaluation gasEnthalpy(const Evaluation& temperature, const Evaluation& pressure)
397  {
398  const Evaluation& result = interpolateGasTP_(data_.gasEnthalpy_,
399  temperature,
400  pressure);
401  if (std::isnan(scalarValue(result))) {
402  return RawComponent::gasEnthalpy(temperature, pressure);
403  }
404  return result;
405  }
406 
413  template <class Evaluation>
414  static Evaluation liquidEnthalpy(const Evaluation& temperature, const Evaluation& pressure)
415  {
416  const Evaluation& result = interpolateLiquidTP_(data_.liquidEnthalpy_,
417  temperature,
418  pressure);
419  if (std::isnan(scalarValue(result))) {
420  return RawComponent::liquidEnthalpy(temperature, pressure);
421  }
422  return result;
423  }
424 
431  template <class Evaluation>
432  static Evaluation gasHeatCapacity(const Evaluation& temperature, const Evaluation& pressure)
433  {
434  const Evaluation& result = interpolateGasTP_(data_.gasHeatCapacity_,
435  temperature,
436  pressure);
437  if (std::isnan(scalarValue(result))) {
438  return RawComponent::gasHeatCapacity(temperature, pressure);
439  }
440  return result;
441  }
442 
449  template <class Evaluation>
450  static Evaluation liquidHeatCapacity(const Evaluation& temperature, const Evaluation& pressure)
451  {
452  const Evaluation& result = interpolateLiquidTP_(data_.liquidHeatCapacity_,
453  temperature,
454  pressure);
455  if (std::isnan(scalarValue(result))) {
456  return RawComponent::liquidHeatCapacity(temperature, pressure);
457  }
458  return result;
459  }
460 
467  template <class Evaluation>
468  static Evaluation gasInternalEnergy(const Evaluation& temperature, const Evaluation& pressure)
469  { return gasEnthalpy(temperature, pressure) - pressure / gasDensity(temperature, pressure); }
470 
477  template <class Evaluation>
478  static Evaluation liquidInternalEnergy(const Evaluation& temperature, const Evaluation& pressure)
479  { return liquidEnthalpy(temperature, pressure) - pressure / liquidDensity(temperature, pressure); }
480 
487  template <class Evaluation>
488  static Evaluation gasPressure(const Evaluation& temperature, Scalar density)
489  {
490  const Evaluation& result = interpolateGasTRho_(data_.gasPressure_,
491  temperature,
492  density);
493  if (std::isnan(scalarValue(result))) {
494  return RawComponent::gasPressure(temperature,
495  density);
496  }
497  return result;
498  }
499 
506  template <class Evaluation>
507  static Evaluation liquidPressure(const Evaluation& temperature, Scalar density)
508  {
509  const Evaluation& result = interpolateLiquidTRho_(data_.liquidPressure_,
510  temperature,
511  density);
512  if (std::isnan(scalarValue(result))) {
513  return RawComponent::liquidPressure(temperature,
514  density);
515  }
516  return result;
517  }
518 
522  static bool gasIsCompressible()
523  { return RawComponent::gasIsCompressible(); }
524 
528  static bool liquidIsCompressible()
529  { return RawComponent::liquidIsCompressible(); }
530 
534  static bool gasIsIdeal()
535  { return RawComponent::gasIsIdeal(); }
536 
544  template <class Evaluation>
545  static Evaluation gasDensity(const Evaluation& temperature, const Evaluation& pressure)
546  {
547  const Evaluation& result = interpolateGasTP_(data_.gasDensity_,
548  temperature,
549  pressure);
550  if (std::isnan(scalarValue(result))) {
551  return RawComponent::gasDensity(temperature, pressure);
552  }
553  return result;
554  }
555 
563  template <class Evaluation>
564  static Evaluation liquidDensity(const Evaluation& temperature, const Evaluation& pressure)
565  {
566  const Evaluation& result = interpolateLiquidTP_(data_.liquidDensity_,
567  temperature,
568  pressure);
569  if (std::isnan(scalarValue(result))) {
570  return RawComponent::liquidDensity(temperature, pressure);
571  }
572  return result;
573  }
574 
581  template <class Evaluation>
582  static Evaluation gasViscosity(const Evaluation& temperature, const Evaluation& pressure)
583  {
584  const Evaluation& result = interpolateGasTP_(data_.gasViscosity_,
585  temperature,
586  pressure);
587  if (std::isnan(scalarValue(result))) {
588  return RawComponent::gasViscosity(temperature, pressure);
589  }
590  return result;
591  }
592 
599  template <class Evaluation>
600  static Evaluation liquidViscosity(const Evaluation& temperature, const Evaluation& pressure)
601  {
602  const Evaluation& result = interpolateLiquidTP_(data_.liquidViscosity_,
603  temperature,
604  pressure);
605  if (std::isnan(scalarValue(result))) {
606  return RawComponent::liquidViscosity(temperature, pressure);
607  }
608  return result;
609  }
610 
617  template <class Evaluation>
618  static Evaluation gasThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
619  {
620  const Evaluation& result = interpolateGasTP_(data_.gasThermalConductivity_,
621  temperature,
622  pressure);
623  if (std::isnan(scalarValue(result))) {
624  return RawComponent::gasThermalConductivity(temperature, pressure);
625  }
626  return result;
627  }
628 
635  template <class Evaluation>
636  static Evaluation liquidThermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
637  {
638  const Evaluation& result = interpolateLiquidTP_(data_.liquidThermalConductivity_,
639  temperature,
640  pressure);
641  if (std::isnan(scalarValue(result))) {
642  return RawComponent::liquidThermalConductivity(temperature, pressure);
643  }
644  return result;
645  }
646 
647 private:
648  // returns an interpolated value depending on temperature
649  template <class Evaluation>
650  static Evaluation interpolateT_(const std::vector<Scalar>& values, const Evaluation& T)
651  {
652  Evaluation alphaT = tempIdx_(T);
653  if (alphaT < 0 || alphaT >= data_.nTemp_ - 1) {
654  return std::numeric_limits<Scalar>::quiet_NaN();
655  }
656 
657  const std::size_t iT = static_cast<std::size_t>(scalarValue(alphaT));
658  alphaT -= iT;
659 
660  return
661  values[iT ]*(1 - alphaT) +
662  values[iT + 1]*( alphaT);
663  }
664 
665  // returns an interpolated value for liquid depending on
666  // temperature and pressure
667  template <class Evaluation>
668  static Evaluation interpolateLiquidTP_(const std::vector<Scalar>& values,
669  const Evaluation& T,
670  const Evaluation& p)
671  {
672  Evaluation alphaT = tempIdx_(T);
673  if (alphaT < 0 || alphaT >= data_.nTemp_ - 1) {
674  return std::numeric_limits<Scalar>::quiet_NaN();
675  }
676 
677  const std::size_t iT = static_cast<std::size_t>(scalarValue(alphaT));
678  alphaT -= iT;
679 
680  Evaluation alphaP1 = pressLiquidIdx_(p, iT);
681  Evaluation alphaP2 = pressLiquidIdx_(p, iT + 1);
682 
683  const std::size_t iP1 =
684  static_cast<std::size_t>(
685  std::max<int>(0, std::min(static_cast<int>(data_.nPress_) - 2,
686  static_cast<int>(scalarValue(alphaP1)))));
687  const std::size_t iP2 =
688  static_cast<std::size_t>(
689  std::max(0, std::min(static_cast<int>(data_.nPress_) - 2,
690  static_cast<int>(scalarValue(alphaP2)))));
691  alphaP1 -= iP1;
692  alphaP2 -= iP2;
693 
694  return
695  values[(iT ) + (iP1 ) * data_.nTemp_] * (1 - alphaT) * (1 - alphaP1) +
696  values[(iT ) + (iP1 + 1) * data_.nTemp_] * (1 - alphaT) * ( alphaP1) +
697  values[(iT + 1) + (iP2 ) * data_.nTemp_] * ( alphaT) * (1 - alphaP2) +
698  values[(iT + 1) + (iP2 + 1) * data_.nTemp_] * ( alphaT) * ( alphaP2);
699  }
700 
701  // returns an interpolated value for gas depending on
702  // temperature and pressure
703  template <class Evaluation>
704  static Evaluation interpolateGasTP_(const std::vector<Scalar>& values,
705  const Evaluation& T,
706  const Evaluation& p)
707  {
708  Evaluation alphaT = tempIdx_(T);
709  if (alphaT < 0 || alphaT >= data_.nTemp_ - 1) {
710  return std::numeric_limits<Scalar>::quiet_NaN();
711  }
712 
713  const std::size_t iT =
714  static_cast<std::size_t>(
715  std::max(0, std::min(static_cast<int>(data_.nTemp_) - 2,
716  static_cast<int>(scalarValue(alphaT)))));
717  alphaT -= iT;
718 
719  Evaluation alphaP1 = pressGasIdx_(p, iT);
720  Evaluation alphaP2 = pressGasIdx_(p, iT + 1);
721  const std::size_t iP1 =
722  static_cast<std::size_t>(
723  std::max(0, std::min(static_cast<int>(data_.nPress_) - 2,
724  static_cast<int>(scalarValue(alphaP1)))));
725  const std::size_t iP2 =
726  static_cast<std::size_t>(
727  std::max(0, std::min(static_cast<int>(data_.nPress_) - 2,
728  static_cast<int>(scalarValue(alphaP2)))));
729  alphaP1 -= iP1;
730  alphaP2 -= iP2;
731 
732  return
733  values[(iT ) + (iP1 ) * data_.nTemp_] * (1 - alphaT) * (1 - alphaP1) +
734  values[(iT ) + (iP1 + 1) * data_.nTemp_] * (1 - alphaT) * ( alphaP1) +
735  values[(iT + 1) + (iP2 ) * data_.nTemp_] * ( alphaT) * (1 - alphaP2) +
736  values[(iT + 1) + (iP2 + 1) * data_.nTemp_] * ( alphaT) * ( alphaP2);
737  }
738 
739  // returns an interpolated value for gas depending on
740  // temperature and density
741  template <class Evaluation>
742  static Evaluation interpolateGasTRho_(const std::vector<Scalar>& values,
743  const Evaluation& T,
744  const Evaluation& rho)
745  {
746  Evaluation alphaT = tempIdx_(T);
747  const unsigned iT =
748  std::max(0,
749  std::min(static_cast<int>(data_.nTemp_ - 2),
750  static_cast<int>(alphaT)));
751  alphaT -= iT;
752 
753  Evaluation alphaP1 = densityGasIdx_(rho, iT);
754  Evaluation alphaP2 = densityGasIdx_(rho, iT + 1);
755  const unsigned iP1 =
756  std::max(0,
757  std::min(static_cast<int>(data_.nDensity_ - 2),
758  static_cast<int>(alphaP1)));
759  const unsigned iP2 =
760  std::max(0,
761  std::min(static_cast<int>(data_.nDensity_ - 2),
762  static_cast<int>(alphaP2)));
763  alphaP1 -= iP1;
764  alphaP2 -= iP2;
765 
766  return
767  values[(iT ) + (iP1 ) * data_.nTemp_] * (1 - alphaT) * (1 - alphaP1) +
768  values[(iT ) + (iP1 + 1) * data_.nTemp_] * (1 - alphaT) * ( alphaP1) +
769  values[(iT + 1) + (iP2 ) * data_.nTemp_] * ( alphaT) * (1 - alphaP2) +
770  values[(iT + 1) + (iP2 + 1) * data_.nTemp_] * ( alphaT) * ( alphaP2);
771  }
772 
773  // returns an interpolated value for liquid depending on
774  // temperature and density
775  template <class Evaluation>
776  static Evaluation interpolateLiquidTRho_(const std::vector<Scalar>& values,
777  const Evaluation& T,
778  const Evaluation& rho)
779  {
780  Evaluation alphaT = tempIdx_(T);
781  const unsigned iT = std::max<int>(0, std::min<int>(data_.nTemp_ - 2, static_cast<int>(alphaT)));
782  alphaT -= iT;
783 
784  Evaluation alphaP1 = densityLiquidIdx_(rho, iT);
785  Evaluation alphaP2 = densityLiquidIdx_(rho, iT + 1);
786  const unsigned iP1 = std::max<int>(0, std::min<int>(data_.nDensity_ - 2, static_cast<int>(alphaP1)));
787  const unsigned iP2 = std::max<int>(0, std::min<int>(data_.nDensity_ - 2, static_cast<int>(alphaP2)));
788  alphaP1 -= iP1;
789  alphaP2 -= iP2;
790 
791  return
792  values[(iT ) + (iP1 ) * data_.nTemp_] * (1 - alphaT) * (1 - alphaP1) +
793  values[(iT ) + (iP1 + 1) * data_.nTemp_] * (1 - alphaT) * ( alphaP1) +
794  values[(iT + 1) + (iP2 ) * data_.nTemp_] * ( alphaT) * (1 - alphaP2) +
795  values[(iT + 1) + (iP2 + 1) * data_.nTemp_] * ( alphaT) * ( alphaP2);
796  }
797 
798  // returns the index of an entry in a temperature field
799  template <class Evaluation>
800  static Evaluation tempIdx_(const Evaluation& temperature)
801  {
802  return (data_.nTemp_ - 1) * (temperature - data_.tempMin_) / (data_.tempMax_ - data_.tempMin_);
803  }
804 
805  // returns the index of an entry in a pressure field
806  template <class Evaluation>
807  static Evaluation pressLiquidIdx_(const Evaluation& pressure, std::size_t tempIdx)
808  {
809  const Scalar plMin = minLiquidPressure_(tempIdx);
810  const Scalar plMax = maxLiquidPressure_(tempIdx);
811 
812  return (data_.nPress_ - 1) * (pressure - plMin) / (plMax - plMin);
813  }
814 
815  // returns the index of an entry in a temperature field
816  template <class Evaluation>
817  static Evaluation pressGasIdx_(const Evaluation& pressure, std::size_t tempIdx)
818  {
819  const Scalar pgMin = minGasPressure_(tempIdx);
820  const Scalar pgMax = maxGasPressure_(tempIdx);
821 
822  return (data_.nPress_ - 1) * (pressure - pgMin) / (pgMax - pgMin);
823  }
824 
825  // returns the index of an entry in a density field
826  template <class Evaluation>
827  static Evaluation densityLiquidIdx_(const Evaluation& density, std::size_t tempIdx)
828  {
829  const Scalar densityMin = minLiquidDensity_(tempIdx);
830  const Scalar densityMax = maxLiquidDensity_(tempIdx);
831  return (data_.nDensity_ - 1) * (density - densityMin) / (densityMax - densityMin);
832  }
833 
834  // returns the index of an entry in a density field
835  template <class Evaluation>
836  static Evaluation densityGasIdx_(const Evaluation& density, std::size_t tempIdx)
837  {
838  const Scalar densityMin = minGasDensity_(tempIdx);
839  const Scalar densityMax = maxGasDensity_(tempIdx);
840  return (data_.nDensity_ - 1) * (density - densityMin) / (densityMax - densityMin);
841  }
842 
843  // returns the minimum tabulized liquid pressure at a given
844  // temperature index
845  static Scalar minLiquidPressure_(std::size_t tempIdx)
846  {
847  if (!useVaporPressure) {
848  return data_.pressMin_;
849  }
850  else {
851  return std::max<Scalar>(data_.pressMin_, data_.vaporPressure_[tempIdx] / 1.1);
852  }
853  }
854 
855  // returns the maximum tabulized liquid pressure at a given
856  // temperature index
857  static Scalar maxLiquidPressure_(std::size_t tempIdx)
858  {
859  if (!useVaporPressure) {
860  return data_.pressMax_;
861  }
862  else {
863  return std::max<Scalar>(data_.pressMax_, data_.vaporPressure_[tempIdx] * 1.1);
864  }
865  }
866 
867  // returns the minumum tabulized gas pressure at a given
868  // temperature index
869  static Scalar minGasPressure_(std::size_t tempIdx)
870  {
871  if (!useVaporPressure) {
872  return data_.pressMin_;
873  }
874  else {
875  return std::min<Scalar>(data_.pressMin_, data_.vaporPressure_[tempIdx] / 1.1);
876  }
877  }
878 
879  // returns the maximum tabulized gas pressure at a given
880  // temperature index
881  static Scalar maxGasPressure_(std::size_t tempIdx)
882  {
883  if (!useVaporPressure) {
884  return data_.pressMax_;
885  }
886  else {
887  return std::min<Scalar>(data_.pressMax_, data_.vaporPressure_[tempIdx] * 1.1);
888  }
889  }
890 
891  // returns the minimum tabulized liquid density at a given
892  // temperature index
893  static Scalar minLiquidDensity_(std::size_t tempIdx)
894  { return data_.minLiquidDensity__[tempIdx]; }
895 
896  // returns the maximum tabulized liquid density at a given
897  // temperature index
898  static Scalar maxLiquidDensity_(std::size_t tempIdx)
899  { return data_.maxLiquidDensity__[tempIdx]; }
900 
901  // returns the minumum tabulized gas density at a given
902  // temperature index
903  static Scalar minGasDensity_(std::size_t tempIdx)
904  { return data_.minGasDensity__[tempIdx]; }
905 
906  // returns the maximum tabulized gas density at a given
907  // temperature index
908  static Scalar maxGasDensity_(std::size_t tempIdx)
909  { return data_.maxGasDensity__[tempIdx]; }
910 
911  static TabulatedComponentData<Scalar> data_;
912 };
913 
914 template <class Scalar, class RawComponent, bool useVaporPressure>
915 TabulatedComponentData<Scalar> TabulatedComponent<Scalar, RawComponent, useVaporPressure>::data_;
916 
917 } // namespace Opm
918 
919 #endif
static std::string_view name()
A human readable name for the component.
Definition: TabulatedComponent.hpp:328
static Evaluation liquidDensity(const Evaluation &temperature, const Evaluation &pressure)
The density of liquid at a given pressure and temperature .
Definition: TabulatedComponent.hpp:564
static Evaluation liquidEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of the liquid .
Definition: TabulatedComponent.hpp:414
static Evaluation liquidHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of the liquid .
Definition: TabulatedComponent.hpp:450
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...
static Scalar molarMass()
The molar mass in of the component.
Definition: TabulatedComponent.hpp:334
static Scalar triplePressure()
Returns the pressure in at the component&#39;s triple point.
Definition: TabulatedComponent.hpp:370
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
static Evaluation liquidInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of the liquid .
Definition: TabulatedComponent.hpp:478
static Evaluation gasViscosity(const Evaluation &temperature, const Evaluation &pressure)
The dynamic viscosity of gas.
Definition: TabulatedComponent.hpp:582
static Scalar criticalVolume()
Returns the critical volume in of the component.
Definition: TabulatedComponent.hpp:358
static Evaluation gasDensity(const Evaluation &temperature, const Evaluation &pressure)
The density of gas at a given pressure and temperature .
Definition: TabulatedComponent.hpp:545
Definition: TabulatedComponent.hpp:43
static Evaluation liquidThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
The thermal conductivity of liquid water .
Definition: TabulatedComponent.hpp:636
static Evaluation vaporPressure(const Evaluation &temperature)
The vapor pressure in of the component at a given temperature.
Definition: TabulatedComponent.hpp:380
static Evaluation gasInternalEnergy(const Evaluation &temperature, const Evaluation &pressure)
Specific internal energy of the gas .
Definition: TabulatedComponent.hpp:468
static Scalar criticalPressure()
Returns the critical pressure in of the component.
Definition: TabulatedComponent.hpp:346
static Evaluation gasHeatCapacity(const Evaluation &temperature, const Evaluation &pressure)
Specific isobaric heat capacity of the gas .
Definition: TabulatedComponent.hpp:432
static Scalar criticalTemperature()
Returns the critical temperature in of the component.
Definition: TabulatedComponent.hpp:340
static Evaluation liquidPressure(const Evaluation &temperature, Scalar density)
The pressure of liquid in at a given density and temperature.
Definition: TabulatedComponent.hpp:507
static Scalar acentricFactor()
Returns the acentric factor of the component.
Definition: TabulatedComponent.hpp:352
A generic class which tabulates all thermodynamic properties of a given component.
Definition: TabulatedComponent.hpp:138
static void init(Scalar tempMin, Scalar tempMax, unsigned nTemp, Scalar pressMin, Scalar pressMax, unsigned nPress)
Initialize the tables.
Definition: TabulatedComponent.hpp:155
static Evaluation gasEnthalpy(const Evaluation &temperature, const Evaluation &pressure)
Specific enthalpy of the gas .
Definition: TabulatedComponent.hpp:396
static bool gasIsIdeal()
Returns true iff the gas phase is assumed to be ideal.
Definition: TabulatedComponent.hpp:534
static Evaluation liquidViscosity(const Evaluation &temperature, const Evaluation &pressure)
The dynamic viscosity of liquid.
Definition: TabulatedComponent.hpp:600
static Evaluation gasThermalConductivity(const Evaluation &temperature, const Evaluation &pressure)
The thermal conductivity of gaseous water .
Definition: TabulatedComponent.hpp:618
static bool gasIsCompressible()
Returns true iff the gas phase is assumed to be compressible.
Definition: TabulatedComponent.hpp:522
static Evaluation gasPressure(const Evaluation &temperature, Scalar density)
The pressure of gas in at a given density and temperature.
Definition: TabulatedComponent.hpp:488
static Scalar tripleTemperature()
Returns the temperature in at the component&#39;s triple point.
Definition: TabulatedComponent.hpp:364
static bool liquidIsCompressible()
Returns true iff the liquid phase is assumed to be compressible.
Definition: TabulatedComponent.hpp:528