3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
tabulatedcomponent.hh
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program 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 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
28#ifndef DUMUX_TABULATED_COMPONENT_HH
29#define DUMUX_TABULATED_COMPONENT_HH
30
31#include <cmath>
32#include <limits>
33#include <cassert>
34#include <vector>
35#include <iostream>
36#include <iomanip>
37
40
41namespace Dumux {
42namespace Components {
43// forward declaration
44template<class RawComponent, bool useVaporPressure>
45class TabulatedComponent;
46} // end namespace Components
47
49template<class RawComponent, bool useVaporPressure>
50struct ComponentTraits<Components::TabulatedComponent<RawComponent, useVaporPressure>>
51{
52 using Scalar = typename RawComponent::Scalar;
53
55 static constexpr bool hasSolidState = std::is_base_of<Components::Solid<Scalar, RawComponent>, RawComponent>::value;
56
58 static constexpr bool hasLiquidState = std::is_base_of<Components::Liquid<Scalar, RawComponent>, RawComponent>::value;
59
61 static constexpr bool hasGasState = std::is_base_of<Components::Gas<Scalar, RawComponent>, RawComponent>::value;
62};
63
64namespace Components {
65
80template <class RawComponent, bool useVaporPressure=true>
82{
83public:
85 using Scalar = typename RawComponent::Scalar;
86
88 static constexpr bool isTabulated = true;
89
100 static void init(Scalar tempMin, Scalar tempMax, std::size_t nTemp,
101 Scalar pressMin, Scalar pressMax, std::size_t nPress)
102 {
103 tempMin_ = tempMin;
104 tempMax_ = tempMax;
105 nTemp_ = nTemp;
106 pressMin_ = pressMin;
107 pressMax_ = pressMax;
108 nPress_ = nPress;
109 nDensity_ = nPress_;
110
111 std::cout << "-------------------------------------------------------------------------\n"
112 << "Initializing tables for the " << RawComponent::name()
113 << " fluid properties (" << nTemp*nPress << " entries).\n"
114 << "Temperature -> min: " << std::scientific << std::setprecision(3)
115 << tempMin << ", max: " << tempMax << ", n: " << nTemp << '\n'
116 << "Pressure -> min: " << std::scientific << std::setprecision(3)
117 << pressMin << ", max: " << pressMax << ", n: " << nPress << '\n'
118 << "-------------------------------------------------------------------------" << std::endl;
119
120 // resize & initilialize the arrays with NaN
121 assert(std::numeric_limits<Scalar>::has_quiet_NaN);
122 const auto NaN = std::numeric_limits<Scalar>::quiet_NaN();
123
124 vaporPressure_.resize(nTemp_, NaN);
125 minGasDensity_.resize(nTemp_, NaN);
126 maxGasDensity_.resize(nTemp_, NaN);
127 minLiquidDensity_.resize(nTemp_, NaN);
128 maxLiquidDensity_.resize(nTemp_, NaN);
129
130 const std::size_t numEntriesTp = nTemp_*nPress_; // = nTemp_*nDensity_
131 gasEnthalpy_.resize(numEntriesTp, NaN);
132 liquidEnthalpy_.resize(numEntriesTp, NaN);
133 gasHeatCapacity_.resize(numEntriesTp, NaN);
134 liquidHeatCapacity_.resize(numEntriesTp, NaN);
135 gasDensity_.resize(numEntriesTp, NaN);
136 liquidDensity_.resize(numEntriesTp, NaN);
137 gasViscosity_.resize(numEntriesTp, NaN);
138 liquidViscosity_.resize(numEntriesTp, NaN);
139 gasThermalConductivity_.resize(numEntriesTp, NaN);
140 liquidThermalConductivity_.resize(numEntriesTp, NaN);
141 gasPressure_.resize(numEntriesTp, NaN);
142 liquidPressure_.resize(numEntriesTp, NaN);
143
144 // reset all flags
145 minMaxLiquidDensityInitialized_ = false;
146 minMaxGasDensityInitialized_ = false;
147 gasEnthalpyInitialized_ = false;
148 liquidEnthalpyInitialized_ = false;
149 gasHeatCapacityInitialized_ = false;
150 liquidHeatCapacityInitialized_ = false;
151 gasDensityInitialized_ = false;
152 liquidDensityInitialized_ = false;
153 gasViscosityInitialized_ = false;
154 liquidViscosityInitialized_ = false;
155 gasThermalConductivityInitialized_ = false;
156 liquidThermalConductivityInitialized_ = false;
157 gasPressureInitialized_ = false;
158 liquidPressureInitialized_ = false;
159
161 initVaporPressure_();
162
163#ifndef NDEBUG
164 initialized_ = true;
165 warningPrinted_ = false;
166#endif
167 }
168
172 static std::string name()
173 { return RawComponent::name(); }
174
178 static constexpr Scalar molarMass()
179 { return RawComponent::molarMass(); }
180
185 { return RawComponent::criticalTemperature(); }
186
191 { return RawComponent::criticalPressure(); }
192
197 { return RawComponent::tripleTemperature(); }
198
203 { return RawComponent::triplePressure(); }
204
212 {
213 using std::isnan;
214 Scalar result = interpolateT_(vaporPressure_, T);
215 if (isnan(result))
216 return RawComponent::vaporPressure(T);
217 return result;
218 }
219
228 {
229 return RawComponent::vaporTemperature(pressure);
230 }
231
239 {
240 Scalar result = interpolateTP_(gasEnthalpy_, temperature, pressure,
241 pressGasIdx_, minGasPressure_, maxGasPressure_);
242 using std::isnan;
243 if (isnan(result))
244 {
245 if (!gasEnthalpyInitialized_)
246 {
247 auto gasEnth = [] (auto T, auto p) { return RawComponent::gasEnthalpy(T, p); };
248 initTPArray_(gasEnth, minGasPressure_, maxGasPressure_, gasEnthalpy_);
249 gasEnthalpyInitialized_ = true;
251 }
252
253 printWarning_("gasEnthalpy", temperature, pressure);
254 return RawComponent::gasEnthalpy(temperature, pressure);
255 }
256 return result;
257 }
258
266 {
267 Scalar result = interpolateTP_(liquidEnthalpy_, temperature, pressure,
268 pressLiquidIdx_, minLiquidPressure_, maxLiquidPressure_);
269 using std::isnan;
270 if (isnan(result))
271 {
272 if (!liquidEnthalpyInitialized_)
273 {
274 auto liqEnth = [] (auto T, auto p) { return RawComponent::liquidEnthalpy(T, p); };
275 initTPArray_(liqEnth, minLiquidPressure_, maxLiquidPressure_, liquidEnthalpy_);
276 liquidEnthalpyInitialized_ = true;
278 }
279
280 printWarning_("liquidEnthalpy", temperature, pressure);
281 return RawComponent::liquidEnthalpy(temperature, pressure);
282 }
283 return result;
284 }
285
293 {
294 Scalar result = interpolateTP_(gasHeatCapacity_, temperature, pressure,
295 pressGasIdx_, minGasPressure_, maxGasPressure_);
296 using std::isnan;
297 if (isnan(result))
298 {
299 if (!gasHeatCapacityInitialized_)
300 {
301 auto gasHC = [] (auto T, auto p) { return RawComponent::gasHeatCapacity(T, p); };
302 initTPArray_(gasHC, minGasPressure_, maxGasPressure_, gasHeatCapacity_);
303 gasHeatCapacityInitialized_ = true;
305 }
306
307 printWarning_("gasHeatCapacity", temperature, pressure);
308 return RawComponent::gasHeatCapacity(temperature, pressure);
309 }
310 return result;
311 }
312
320 {
321 Scalar result = interpolateTP_(liquidHeatCapacity_, temperature, pressure,
322 pressLiquidIdx_, minLiquidPressure_, maxLiquidPressure_);
323 using std::isnan;
324 if (isnan(result))
325 {
326 if (!liquidHeatCapacityInitialized_)
327 {
328 auto liqHC = [] (auto T, auto p) { return RawComponent::liquidHeatCapacity(T, p); };
329 initTPArray_(liqHC, minLiquidPressure_, maxLiquidPressure_, liquidHeatCapacity_);
330 liquidHeatCapacityInitialized_ = true;
332 }
333
334 printWarning_("liquidHeatCapacity", temperature, pressure);
335 return RawComponent::liquidHeatCapacity(temperature, pressure);
336 }
337 return result;
338 }
339
347 {
349 }
350
358 {
360 }
361
369 {
371 if (!minMaxGasDensityInitialized_)
372 {
373 auto gasRho = [] (auto T, auto p) { return RawComponent::gasDensity(T, p); };
374 initMinMaxRhoArray_(gasRho, minGasPressure_, maxGasPressure_, minGasDensity_, maxGasDensity_);
375 minMaxGasDensityInitialized_ = true;
376 }
377
378 Scalar result = interpolateTRho_(gasPressure_, temperature, density, densityGasIdx_);
379 using std::isnan;
380 if (isnan(result))
381 {
382 if (!gasPressureInitialized_)
383 {
384 auto gasPFunc = [] (auto T, auto rho) { return RawComponent::gasPressure(T, rho); };
385 initPressureArray_(gasPressure_, gasPFunc, minGasDensity_, maxGasDensity_);
386 gasPressureInitialized_ = true;
388 }
389
390 printWarning_("gasPressure", temperature, density);
391 return RawComponent::gasPressure(temperature, density);
392 }
393 return result;
394 }
395
403 {
405 if (!minMaxLiquidDensityInitialized_)
406 {
407 auto liqRho = [] (auto T, auto p) { return RawComponent::liquidDensity(T, p); };
408 initMinMaxRhoArray_(liqRho, minLiquidPressure_, maxLiquidPressure_, minLiquidDensity_, maxLiquidDensity_);
409 minMaxLiquidDensityInitialized_ = true;
410 }
411
412 Scalar result = interpolateTRho_(liquidPressure_, temperature, density, densityLiquidIdx_);
413 using std::isnan;
414 if (isnan(result))
415 {
416 if (!liquidPressureInitialized_)
417 {
418 auto liqPFunc = [] (auto T, auto rho) { return RawComponent::liquidPressure(T, rho); };
419 initPressureArray_(liquidPressure_, liqPFunc, minLiquidDensity_, maxLiquidDensity_);
420 liquidPressureInitialized_ = true;
422 }
423
424 printWarning_("liquidPressure", temperature, density);
425 return RawComponent::liquidPressure(temperature, density);
426 }
427 return result;
428 }
429
433 static constexpr bool gasIsCompressible()
434 { return RawComponent::gasIsCompressible(); }
435
439 static constexpr bool liquidIsCompressible()
440 { return RawComponent::liquidIsCompressible(); }
441
445 static constexpr bool gasIsIdeal()
446 { return RawComponent::gasIsIdeal(); }
447
448
457 {
458 Scalar result = interpolateTP_(gasDensity_, temperature, pressure,
459 pressGasIdx_, minGasPressure_, maxGasPressure_);
460 using std::isnan;
461 if (isnan(result))
462 {
463 if (!gasDensityInitialized_)
464 {
465 auto gasRho = [] (auto T, auto p) { return RawComponent::gasDensity(T, p); };
466 initTPArray_(gasRho, minGasPressure_, maxGasPressure_, gasDensity_);
467 gasDensityInitialized_ = true;
469 }
470
471 printWarning_("gasDensity", temperature, pressure);
472 return RawComponent::gasDensity(temperature, pressure);
473 }
474 return result;
475 }
476
487
496 {
497 Scalar result = interpolateTP_(liquidDensity_, temperature, pressure,
498 pressLiquidIdx_, minLiquidPressure_, maxLiquidPressure_);
499 using std::isnan;
500 if (isnan(result))
501 {
502 if (!liquidDensityInitialized_)
503 {
504 // TODO: we could get rid of the lambdas and pass the functor irectly. But,
505 // currently Brine is a component (and not a fluid system) expecting a
506 // third argument with a default, which cannot be wrapped in a function pointer.
507 // For this reason we have to wrap this into a lambda here.
508 auto liqRho = [] (auto T, auto p) { return RawComponent::liquidDensity(T, p); };
509 initTPArray_(liqRho, minLiquidPressure_, maxLiquidPressure_, liquidDensity_);
510 liquidDensityInitialized_ = true;
512 }
513
514 printWarning_("liquidDensity", temperature, pressure);
515 return RawComponent::liquidDensity(temperature, pressure);
516 }
517
518 return result;
519 }
520
531
539 {
540 Scalar result = interpolateTP_(gasViscosity_, temperature, pressure,
541 pressGasIdx_, minGasPressure_, maxGasPressure_);
542 using std::isnan;
543 if (isnan(result))
544 {
545 if (!gasViscosityInitialized_)
546 {
547 auto gasVisc = [] (auto T, auto p) { return RawComponent::gasViscosity(T, p); };
548 initTPArray_(gasVisc, minGasPressure_, maxGasPressure_, gasViscosity_);
549 gasViscosityInitialized_ = true;
551 }
552
553 printWarning_("gasViscosity", temperature, pressure);
554 return RawComponent::gasViscosity(temperature, pressure);
555 }
556 return result;
557 }
558
566 {
567 Scalar result = interpolateTP_(liquidViscosity_, temperature, pressure,
568 pressLiquidIdx_, minLiquidPressure_, maxLiquidPressure_);
569 using std::isnan;
570 if (isnan(result))
571 {
572 if (!liquidViscosityInitialized_)
573 {
574 auto liqVisc = [] (auto T, auto p) { return RawComponent::liquidViscosity(T, p); };
575 initTPArray_(liqVisc, minLiquidPressure_, maxLiquidPressure_, liquidViscosity_);
576 liquidViscosityInitialized_ = true;
578 }
579
580 printWarning_("liquidViscosity",temperature, pressure);
581 return RawComponent::liquidViscosity(temperature, pressure);
582 }
583 return result;
584 }
585
593 {
594 Scalar result = interpolateTP_(gasThermalConductivity_, temperature, pressure,
595 pressGasIdx_, minGasPressure_, maxGasPressure_);
596 using std::isnan;
597 if (isnan(result))
598 {
599 if (!gasThermalConductivityInitialized_)
600 {
601 auto gasTC = [] (auto T, auto p) { return RawComponent::gasThermalConductivity(T, p); };
602 initTPArray_(gasTC, minGasPressure_, maxGasPressure_, gasThermalConductivity_);
603 gasThermalConductivityInitialized_ = true;
605 }
606
607 printWarning_("gasThermalConductivity", temperature, pressure);
608 return RawComponent::gasThermalConductivity(temperature, pressure);
609 }
610 return result;
611 }
612
620 {
621 Scalar result = interpolateTP_(liquidThermalConductivity_, temperature, pressure,
622 pressLiquidIdx_, minLiquidPressure_, maxLiquidPressure_);
623 using std::isnan;
624 if (isnan(result))
625 {
626 if (!liquidThermalConductivityInitialized_)
627 {
628 auto liqTC = [] (auto T, auto p) { return RawComponent::liquidThermalConductivity(T, p); };
629 initTPArray_(liqTC, minLiquidPressure_, maxLiquidPressure_, liquidThermalConductivity_);
630 liquidThermalConductivityInitialized_ = true;
632 }
633
634 printWarning_("liquidThermalConductivity", temperature, pressure);
635 return RawComponent::liquidThermalConductivity(temperature, pressure);
636 }
637 return result;
638 }
639
640
641private:
643 static void printWarning_(const std::string& quantity, Scalar arg1, Scalar arg2)
644 {
645#ifndef NDEBUG
646 if (warningPrinted_)
647 return;
648
649 if (!initialized_)
650 std::cerr << "Warning: tabulated component '" << name()
651 << "' has not been initialized. "
652 << "Call FluidSystem::init() to use the tabulation in order to reduce runtime. \n";
653 else
654 std::cerr << "Warning: "<<quantity<<"(T="<<arg1<<", p="<<arg2<<") of component '"<<name()
655 << "' is outside tabulation range: ("<< tempMin_<<"<=T<="<<tempMax_<<"), ("
656 << pressMin_<<"<=p<=" <<pressMax_<<"). "
657 << "Forwarded to FluidSystem for direct evaluation of "<<quantity<<". \n";
658 warningPrinted_ = true;
659#endif
660 }
661
663 template< bool useVP = useVaporPressure, std::enable_if_t<useVP, int> = 0 >
664 static void initVaporPressure_()
665 {
666 // fill the temperature-pressure arrays
667 for (unsigned iT = 0; iT < nTemp_; ++ iT)
668 {
669 Scalar temperature = iT * (tempMax_ - tempMin_)/(nTemp_ - 1) + tempMin_;
670 vaporPressure_[iT] = RawComponent::vaporPressure(temperature);
671 }
672 }
673
675 template< bool useVP = useVaporPressure, std::enable_if_t<!useVP, int> = 0 >
676 static void initVaporPressure_() {}
677
692 template<class PropFunc, class MinPFunc, class MaxPFunc>
693 static void initTPArray_(PropFunc&& f, MinPFunc&& minP, MaxPFunc&& maxP, std::vector<typename RawComponent::Scalar>& values)
694 {
695 for (unsigned iT = 0; iT < nTemp_; ++ iT)
696 {
697 Scalar temperature = iT * (tempMax_ - tempMin_)/(nTemp_ - 1) + tempMin_;
698
699 Scalar pMax = maxP(iT);
700 Scalar pMin = minP(iT);
701 for (unsigned iP = 0; iP < nPress_; ++ iP)
702 {
703 Scalar pressure = iP * (pMax - pMin)/(nPress_ - 1) + pMin;
704 values[iT + iP*nTemp_] = f(temperature, pressure);
705 }
706 }
707 }
708
724 template<class RhoFunc, class MinPFunc, class MaxPFunc>
725 static void initMinMaxRhoArray_(RhoFunc&& rho,
726 MinPFunc&& minP,
727 MaxPFunc&& maxP,
728 std::vector<typename RawComponent::Scalar>& rhoMin,
729 std::vector<typename RawComponent::Scalar>& rhoMax)
730 {
731 for (unsigned iT = 0; iT < nTemp_; ++ iT)
732 {
733 Scalar temperature = iT * (tempMax_ - tempMin_)/(nTemp_ - 1) + tempMin_;
734
735 rhoMin[iT] = rho(temperature, minP(iT));
736 if (iT < nTemp_ - 1)
737 rhoMax[iT] = rho(temperature, maxP(iT + 1));
738 else
739 rhoMax[iT] = rho(temperature, maxP(iT));
740 }
741 }
742
753 template<class PFunc>
754 static void initPressureArray_(std::vector<typename RawComponent::Scalar>& pressure, PFunc&& p,
755 const std::vector<typename RawComponent::Scalar>& rhoMin,
756 const std::vector<typename RawComponent::Scalar>& rhoMax)
757 {
758 for (unsigned iT = 0; iT < nTemp_; ++ iT)
759 {
760 Scalar temperature = iT * (tempMax_ - tempMin_)/(nTemp_ - 1) + tempMin_;
761
762 for (unsigned iRho = 0; iRho < nDensity_; ++ iRho)
763 {
764 Scalar density = Scalar(iRho)/(nDensity_ - 1)
765 * (rhoMax[iT] - rhoMin[iT])
766 + rhoMin[iT];
767 pressure[iT + iRho*nTemp_] = p(temperature, density);
768 }
769 }
770 }
771
773 static Scalar interpolateT_(const std::vector<typename RawComponent::Scalar>& values, Scalar T)
774 {
775 Scalar alphaT = tempIdx_(T);
776 if (alphaT < 0 || alphaT >= nTemp_ - 1)
777 return std::numeric_limits<Scalar>::quiet_NaN();
778
779 unsigned iT = (unsigned) alphaT;
780 alphaT -= iT;
781
782 return values[iT ]*(1 - alphaT) +
783 values[iT + 1]*( alphaT);
784 }
785
787 template<class GetPIdx, class MinPFunc, class MaxPFunc>
788 static Scalar interpolateTP_(const std::vector<typename RawComponent::Scalar>& values, Scalar T, Scalar p,
789 GetPIdx&& getPIdx, MinPFunc&& minP, MaxPFunc&& maxP)
790 {
791 Scalar alphaT = tempIdx_(T);
792 if (alphaT < 0 || alphaT >= nTemp_ - 1) {
793 return std::numeric_limits<Scalar>::quiet_NaN();
794 }
795 using std::min;
796 using std::max;
797 unsigned iT = max<int>(0, min<int>(nTemp_ - 2, (int) alphaT));
798 alphaT -= iT;
799
800 Scalar alphaP1 = getPIdx(p, iT);
801 Scalar alphaP2 = getPIdx(p, iT + 1);
802
803 unsigned iP1 = max<int>(0, min<int>(nPress_ - 2, (int) alphaP1));
804 unsigned iP2 = max<int>(0, min<int>(nPress_ - 2, (int) alphaP2));
805 alphaP1 -= iP1;
806 alphaP2 -= iP2;
807
808#if 0 && !defined NDEBUG
809 if(!(0 <= alphaT && alphaT <= 1.0))
810 DUNE_THROW(NumericalProblem, "Temperature out of range: "
811 << "T=" << T << " range: [" << tempMin_ << ", " << tempMax_ << "]");
812 if(!(0 <= alphaP1 && alphaP1 <= 1.0))
813 DUNE_THROW(NumericalProblem, "First pressure out of range: "
814 << "p=" << p << " range: [" << minP(tempIdx_(T)) << ", " << maxP(tempIdx_(T)) << "]");
815 if(!(0 <= alphaP2 && alphaP2 <= 1.0))
816 DUNE_THROW(NumericalProblem, "Second pressure out of range: "
817 << "p=" << p << " range: [" << minP(tempIdx_(T) + 1) << ", " << maxP(tempIdx_(T) + 1) << "]");
818#endif
819
820 return values[(iT ) + (iP1 )*nTemp_]*(1 - alphaT)*(1 - alphaP1) +
821 values[(iT ) + (iP1 + 1)*nTemp_]*(1 - alphaT)*( alphaP1) +
822 values[(iT + 1) + (iP2 )*nTemp_]*( alphaT)*(1 - alphaP2) +
823 values[(iT + 1) + (iP2 + 1)*nTemp_]*( alphaT)*( alphaP2);
824 }
825
827 template<class GetRhoIdx>
828 static Scalar interpolateTRho_(const std::vector<typename RawComponent::Scalar>& values, Scalar T, Scalar rho, GetRhoIdx&& rhoIdx)
829 {
830 using std::min;
831 using std::max;
832 Scalar alphaT = tempIdx_(T);
833 unsigned iT = max<int>(0, min<int>(nTemp_ - 2, (int) alphaT));
834 alphaT -= iT;
835
836 Scalar alphaP1 = rhoIdx(rho, iT);
837 Scalar alphaP2 = rhoIdx(rho, iT + 1);
838 unsigned iP1 = max<int>(0, min<int>(nDensity_ - 2, (int) alphaP1));
839 unsigned iP2 = max<int>(0, min<int>(nDensity_ - 2, (int) alphaP2));
840 alphaP1 -= iP1;
841 alphaP2 -= iP2;
842
843 return values[(iT ) + (iP1 )*nTemp_]*(1 - alphaT)*(1 - alphaP1) +
844 values[(iT ) + (iP1 + 1)*nTemp_]*(1 - alphaT)*( alphaP1) +
845 values[(iT + 1) + (iP2 )*nTemp_]*( alphaT)*(1 - alphaP2) +
846 values[(iT + 1) + (iP2 + 1)*nTemp_]*( alphaT)*( alphaP2);
847 }
848
850 static Scalar tempIdx_(Scalar temperature)
851 {
852 return (nTemp_ - 1)*(temperature - tempMin_)/(tempMax_ - tempMin_);
853 }
854
856 static Scalar pressLiquidIdx_(Scalar pressure, unsigned tempIdx)
857 {
858 Scalar plMin = minLiquidPressure_(tempIdx);
859 Scalar plMax = maxLiquidPressure_(tempIdx);
860
861 return (nPress_ - 1)*(pressure - plMin)/(plMax - plMin);
862 }
863
865 static Scalar pressGasIdx_(Scalar pressure, unsigned tempIdx)
866 {
867 Scalar pgMin = minGasPressure_(tempIdx);
868 Scalar pgMax = maxGasPressure_(tempIdx);
869
870 return (nPress_ - 1)*(pressure - pgMin)/(pgMax - pgMin);
871 }
872
874 static Scalar densityLiquidIdx_(Scalar density, unsigned tempIdx)
875 {
876 Scalar densityMin = minLiquidDensity_[tempIdx];
877 Scalar densityMax = maxLiquidDensity_[tempIdx];
878 return (nDensity_ - 1) * (density - densityMin)/(densityMax - densityMin);
879 }
880
882 static Scalar densityGasIdx_(Scalar density, unsigned tempIdx)
883 {
884 Scalar densityMin = minGasDensity_[tempIdx];
885 Scalar densityMax = maxGasDensity_[tempIdx];
886 return (nDensity_ - 1) * (density - densityMin)/(densityMax - densityMin);
887 }
888
890 static Scalar minLiquidPressure_(int tempIdx)
891 {
892 using std::max;
893 if (!useVaporPressure)
894 return pressMin_;
895 else
896 return max(pressMin_, vaporPressure_[tempIdx] / 1.1);
897 }
898
900 static Scalar maxLiquidPressure_(int tempIdx)
901 {
902 using std::max;
903 if (!useVaporPressure)
904 return pressMax_;
905 else
906 return max(pressMax_, vaporPressure_[tempIdx] * 1.1);
907 }
908
910 static Scalar minGasPressure_(int tempIdx)
911 {
912 using std::min;
913 if (!useVaporPressure)
914 return pressMin_;
915 else
916 return min(pressMin_, vaporPressure_[tempIdx] / 1.1 );
917 }
918
920 static Scalar maxGasPressure_(int tempIdx)
921 {
922 using std::min;
923 if (!useVaporPressure)
924 return pressMax_;
925 else
926 return min(pressMax_, vaporPressure_[tempIdx] * 1.1);
927 }
928
929#ifndef NDEBUG
930 // specifies whether the table was initialized
931 static bool initialized_;
932 // specifies whether some warning was printed
933 static bool warningPrinted_;
934#endif
935
936 // 1D fields with the temperature as degree of freedom
937 static std::vector<typename RawComponent::Scalar> vaporPressure_;
938
939 static std::vector<typename RawComponent::Scalar> minLiquidDensity_;
940 static std::vector<typename RawComponent::Scalar> maxLiquidDensity_;
941 static bool minMaxLiquidDensityInitialized_;
942
943 static std::vector<typename RawComponent::Scalar> minGasDensity_;
944 static std::vector<typename RawComponent::Scalar> maxGasDensity_;
945 static bool minMaxGasDensityInitialized_;
946
947 // 2D fields with the temperature and pressure as degrees of freedom
948 static std::vector<typename RawComponent::Scalar> gasEnthalpy_;
949 static std::vector<typename RawComponent::Scalar> liquidEnthalpy_;
950 static bool gasEnthalpyInitialized_;
951 static bool liquidEnthalpyInitialized_;
952
953 static std::vector<typename RawComponent::Scalar> gasHeatCapacity_;
954 static std::vector<typename RawComponent::Scalar> liquidHeatCapacity_;
955 static bool gasHeatCapacityInitialized_;
956 static bool liquidHeatCapacityInitialized_;
957
958 static std::vector<typename RawComponent::Scalar> gasDensity_;
959 static std::vector<typename RawComponent::Scalar> liquidDensity_;
960 static bool gasDensityInitialized_;
961 static bool liquidDensityInitialized_;
962
963 static std::vector<typename RawComponent::Scalar> gasViscosity_;
964 static std::vector<typename RawComponent::Scalar> liquidViscosity_;
965 static bool gasViscosityInitialized_;
966 static bool liquidViscosityInitialized_;
967
968 static std::vector<typename RawComponent::Scalar> gasThermalConductivity_;
969 static std::vector<typename RawComponent::Scalar> liquidThermalConductivity_;
970 static bool gasThermalConductivityInitialized_;
971 static bool liquidThermalConductivityInitialized_;
972
973 // 2D fields with the temperature and density as degrees of freedom
974 static std::vector<typename RawComponent::Scalar> gasPressure_;
975 static std::vector<typename RawComponent::Scalar> liquidPressure_;
976 static bool gasPressureInitialized_;
977 static bool liquidPressureInitialized_;
978
979 // temperature, pressure and density ranges
980 static Scalar tempMin_;
981 static Scalar tempMax_;
982 static unsigned nTemp_;
983
984 static Scalar pressMin_;
985 static Scalar pressMax_;
986 static unsigned nPress_;
987
988 static Scalar densityMin_;
989 static Scalar densityMax_;
990 static unsigned nDensity_;
991};
992
993#ifndef NDEBUG
994template <class RawComponent, bool useVaporPressure>
995bool TabulatedComponent<RawComponent, useVaporPressure>::initialized_ = false;
996
997template <class RawComponent, bool useVaporPressure>
998bool TabulatedComponent<RawComponent, useVaporPressure>::warningPrinted_ = false;
999#endif
1000
1001template <class RawComponent, bool useVaporPressure>
1002bool TabulatedComponent<RawComponent, useVaporPressure>::minMaxLiquidDensityInitialized_ = false;
1003template <class RawComponent, bool useVaporPressure>
1004bool TabulatedComponent<RawComponent, useVaporPressure>::minMaxGasDensityInitialized_ = false;
1005template <class RawComponent, bool useVaporPressure>
1006bool TabulatedComponent<RawComponent, useVaporPressure>::gasEnthalpyInitialized_ = false;
1007template <class RawComponent, bool useVaporPressure>
1008bool TabulatedComponent<RawComponent, useVaporPressure>::liquidEnthalpyInitialized_ = false;
1009template <class RawComponent, bool useVaporPressure>
1010bool TabulatedComponent<RawComponent, useVaporPressure>::gasHeatCapacityInitialized_ = false;
1011template <class RawComponent, bool useVaporPressure>
1012bool TabulatedComponent<RawComponent, useVaporPressure>::liquidHeatCapacityInitialized_ = false;
1013template <class RawComponent, bool useVaporPressure>
1014bool TabulatedComponent<RawComponent, useVaporPressure>::gasDensityInitialized_ = false;
1015template <class RawComponent, bool useVaporPressure>
1016bool TabulatedComponent<RawComponent, useVaporPressure>::liquidDensityInitialized_ = false;
1017template <class RawComponent, bool useVaporPressure>
1018bool TabulatedComponent<RawComponent, useVaporPressure>::gasViscosityInitialized_ = false;
1019template <class RawComponent, bool useVaporPressure>
1020bool TabulatedComponent<RawComponent, useVaporPressure>::liquidViscosityInitialized_ = false;
1021template <class RawComponent, bool useVaporPressure>
1022bool TabulatedComponent<RawComponent, useVaporPressure>::gasThermalConductivityInitialized_ = false;
1023template <class RawComponent, bool useVaporPressure>
1024bool TabulatedComponent<RawComponent, useVaporPressure>::liquidThermalConductivityInitialized_ = false;
1025template <class RawComponent, bool useVaporPressure>
1026bool TabulatedComponent<RawComponent, useVaporPressure>::gasPressureInitialized_ = false;
1027template <class RawComponent, bool useVaporPressure>
1028bool TabulatedComponent<RawComponent, useVaporPressure>::liquidPressureInitialized_ = false;
1029
1030template <class RawComponent, bool useVaporPressure>
1031std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::vaporPressure_;
1032template <class RawComponent, bool useVaporPressure>
1033std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::minLiquidDensity_;
1034template <class RawComponent, bool useVaporPressure>
1035std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::maxLiquidDensity_;
1036template <class RawComponent, bool useVaporPressure>
1037std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::minGasDensity_;
1038template <class RawComponent, bool useVaporPressure>
1039std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::maxGasDensity_;
1040template <class RawComponent, bool useVaporPressure>
1041std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::gasEnthalpy_;
1042template <class RawComponent, bool useVaporPressure>
1043std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::liquidEnthalpy_;
1044template <class RawComponent, bool useVaporPressure>
1045std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::gasHeatCapacity_;
1046template <class RawComponent, bool useVaporPressure>
1047std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::liquidHeatCapacity_;
1048template <class RawComponent, bool useVaporPressure>
1049std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::gasDensity_;
1050template <class RawComponent, bool useVaporPressure>
1051std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::liquidDensity_;
1052template <class RawComponent, bool useVaporPressure>
1053std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::gasViscosity_;
1054template <class RawComponent, bool useVaporPressure>
1055std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::liquidViscosity_;
1056template <class RawComponent, bool useVaporPressure>
1057std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::gasThermalConductivity_;
1058template <class RawComponent, bool useVaporPressure>
1059std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::liquidThermalConductivity_;
1060template <class RawComponent, bool useVaporPressure>
1061std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::gasPressure_;
1062template <class RawComponent, bool useVaporPressure>
1063std::vector<typename RawComponent::Scalar> TabulatedComponent<RawComponent, useVaporPressure>::liquidPressure_;
1064template <class RawComponent, bool useVaporPressure>
1065typename RawComponent::Scalar TabulatedComponent<RawComponent, useVaporPressure>::tempMin_;
1066template <class RawComponent, bool useVaporPressure>
1067typename RawComponent::Scalar TabulatedComponent<RawComponent, useVaporPressure>::tempMax_;
1068template <class RawComponent, bool useVaporPressure>
1069unsigned TabulatedComponent<RawComponent, useVaporPressure>::nTemp_;
1070template <class RawComponent, bool useVaporPressure>
1071typename RawComponent::Scalar TabulatedComponent<RawComponent, useVaporPressure>::pressMin_;
1072template <class RawComponent, bool useVaporPressure>
1073typename RawComponent::Scalar TabulatedComponent<RawComponent, useVaporPressure>::pressMax_;
1074template <class RawComponent, bool useVaporPressure>
1075unsigned TabulatedComponent<RawComponent, useVaporPressure>::nPress_;
1076template <class RawComponent, bool useVaporPressure>
1077typename RawComponent::Scalar TabulatedComponent<RawComponent, useVaporPressure>::densityMin_;
1078template <class RawComponent, bool useVaporPressure>
1079typename RawComponent::Scalar TabulatedComponent<RawComponent, useVaporPressure>::densityMax_;
1080template <class RawComponent, bool useVaporPressure>
1081unsigned TabulatedComponent<RawComponent, useVaporPressure>::nDensity_;
1082
1083// forward declaration
1084template <class Component>
1085struct IsAqueous;
1086
1087// we are aqueous if the raw compont is so
1088template <class RawComponent, bool useVaporPressure>
1089struct IsAqueous<TabulatedComponent<RawComponent, useVaporPressure>> : public IsAqueous<RawComponent> {};
1090
1091} // end namespace Components
1092
1093} // end namespace Dumux
1094
1095#endif
Some exceptions thrown in DuMux
Component traits, i.e. information extracted from components.
Definition: adapt.hh:29
std::string temperature() noexcept
I/O name of temperature for equilibrium models.
Definition: name.hh:51
std::string pressure(int phaseIdx) noexcept
I/O name of pressure for multiphase systems.
Definition: name.hh:34
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
IsAqueous struct.
Definition: components/base.hh:47
Component traits, i.e. information extracted from components.
Definition: componenttraits.hh:43
static constexpr bool hasLiquidState
if the component implements a liquid state
Definition: componenttraits.hh:50
static constexpr bool hasSolidState
if the component implements a solid state
Definition: componenttraits.hh:47
static constexpr bool hasGasState
if the component implements a gaseous state
Definition: componenttraits.hh:53
Tabulates all thermodynamic properties of a given untabulated chemical species.
Definition: tabulatedcomponent.hh:82
static const Scalar gasEnthalpy(Scalar temperature, Scalar pressure)
Specific enthalpy of the gas .
Definition: tabulatedcomponent.hh:238
static Scalar gasPressure(Scalar temperature, Scalar density)
The pressure of gas in at a given density and temperature.
Definition: tabulatedcomponent.hh:368
static Scalar criticalTemperature()
Returns the critical temperature in of the component.
Definition: tabulatedcomponent.hh:184
static Scalar liquidPressure(Scalar temperature, Scalar density)
The pressure of liquid in at a given density and temperature.
Definition: tabulatedcomponent.hh:402
static const Scalar gasHeatCapacity(Scalar temperature, Scalar pressure)
Specific isobaric heat capacity of the gas .
Definition: tabulatedcomponent.hh:292
static std::string name()
A human readable name for the component.
Definition: tabulatedcomponent.hh:172
static Scalar vaporTemperature(Scalar pressure)
The vapor pressure in of the component at a given temperature.
Definition: tabulatedcomponent.hh:227
static Scalar liquidThermalConductivity(Scalar temperature, Scalar pressure)
The thermal conductivity of liquid water .
Definition: tabulatedcomponent.hh:619
static Scalar gasDensity(Scalar temperature, Scalar pressure)
The density of gas at a given pressure and temperature .
Definition: tabulatedcomponent.hh:456
static const Scalar liquidEnthalpy(Scalar temperature, Scalar pressure)
Specific enthalpy of the liquid .
Definition: tabulatedcomponent.hh:265
static Scalar triplePressure()
Returns the pressure in at the component's triple point.
Definition: tabulatedcomponent.hh:202
static Scalar criticalPressure()
Returns the critical pressure in of the component.
Definition: tabulatedcomponent.hh:190
static const Scalar gasInternalEnergy(Scalar temperature, Scalar pressure)
Specific internal energy of the gas .
Definition: tabulatedcomponent.hh:346
static Scalar liquidMolarDensity(Scalar temperature, Scalar pressure)
The molar density of liquid in at a given pressure and temperature.
Definition: tabulatedcomponent.hh:529
static constexpr Scalar molarMass()
The molar mass in of the component.
Definition: tabulatedcomponent.hh:178
static Scalar liquidViscosity(Scalar temperature, Scalar pressure)
The dynamic viscosity of liquid.
Definition: tabulatedcomponent.hh:565
static Scalar gasViscosity(Scalar temperature, Scalar pressure)
The dynamic viscosity of gas.
Definition: tabulatedcomponent.hh:538
static Scalar tripleTemperature()
Returns the temperature in at the component's triple point.
Definition: tabulatedcomponent.hh:196
static constexpr bool liquidIsCompressible()
Returns true if the liquid phase is assumed to be compressible.
Definition: tabulatedcomponent.hh:439
static Scalar liquidDensity(Scalar temperature, Scalar pressure)
The density of liquid at a given pressure and temperature .
Definition: tabulatedcomponent.hh:495
static Scalar gasThermalConductivity(Scalar temperature, Scalar pressure)
The thermal conductivity of gaseous water .
Definition: tabulatedcomponent.hh:592
static Scalar gasMolarDensity(Scalar temperature, Scalar pressure)
The molar density of gas in at a given pressure and temperature.
Definition: tabulatedcomponent.hh:485
static constexpr bool isTabulated
state that we are tabulated
Definition: tabulatedcomponent.hh:88
static const Scalar liquidInternalEnergy(Scalar temperature, Scalar pressure)
Specific internal energy of the liquid .
Definition: tabulatedcomponent.hh:357
static Scalar vaporPressure(Scalar T)
The vapor pressure in of the component at a given temperature.
Definition: tabulatedcomponent.hh:211
static constexpr bool gasIsCompressible()
Returns true if the gas phase is assumed to be compressible.
Definition: tabulatedcomponent.hh:433
static void init(Scalar tempMin, Scalar tempMax, std::size_t nTemp, Scalar pressMin, Scalar pressMax, std::size_t nPress)
Initialize the tables.
Definition: tabulatedcomponent.hh:100
static constexpr bool gasIsIdeal()
Returns true if the gas phase is assumed to be ideal.
Definition: tabulatedcomponent.hh:445
static const Scalar liquidHeatCapacity(Scalar temperature, Scalar pressure)
Specific isobaric heat capacity of the liquid .
Definition: tabulatedcomponent.hh:319
typename RawComponent::Scalar Scalar
export scalar type
Definition: tabulatedcomponent.hh:85
typename RawComponent::Scalar Scalar
Definition: tabulatedcomponent.hh:52