00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #ifndef OPM_GAS_PVT_THERMAL_HPP
00028 #define OPM_GAS_PVT_THERMAL_HPP
00029
00030 #include <opm/material/Constants.hpp>
00031
00032 #include <opm/material/common/OpmFinal.hpp>
00033 #include <opm/material/common/UniformXTabulated2DFunction.hpp>
00034 #include <opm/material/common/Tabulated1DFunction.hpp>
00035 #include <opm/material/common/Spline.hpp>
00036
00037 #if HAVE_OPM_PARSER
00038 #include <opm/parser/eclipse/Deck/Deck.hpp>
00039 #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
00040 #include <opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp>
00041 #include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
00042 #endif
00043
00044 namespace Opm {
00045 template <class Scalar, bool enableThermal>
00046 class GasPvtMultiplexer;
00047
00054 template <class Scalar>
00055 class GasPvtThermal
00056 {
00057 typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
00058 typedef GasPvtMultiplexer<Scalar, false> IsothermalPvt;
00059
00060 public:
00061 ~GasPvtThermal()
00062 { delete isothermalPvt_; }
00063
00064 #if HAVE_OPM_PARSER
00065
00068 void initFromDeck(const Deck& deck,
00069 const EclipseState& eclState)
00070 {
00072
00074 isothermalPvt_ = new IsothermalPvt;
00075 isothermalPvt_->initFromDeck(deck, eclState);
00076
00078
00080 const auto& tables = eclState.getTableManager();
00081
00082 enableThermalDensity_ = deck.hasKeyword("TREF");
00083 enableThermalViscosity_ = deck.hasKeyword("GASVISCT");
00084
00085 unsigned numRegions = isothermalPvt_->numRegions();
00086 setNumRegions(numRegions);
00087
00088
00089 if (enableThermalViscosity_) {
00090 const auto& gasvisctTables = tables.getGasvisctTables();
00091 int gasCompIdx = deck.getKeyword("GCOMPIDX").getRecord(0).getItem("GAS_COMPONENT_INDEX").get< int >(0) - 1;
00092 std::string gasvisctColumnName = "Viscosity"+std::to_string(static_cast<long long>(gasCompIdx));
00093
00094 for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
00095 const auto& T = gasvisctTables[regionIdx].getColumn("Temperature").vectorCopy();
00096 const auto& mu = gasvisctTables[regionIdx].getColumn(gasvisctColumnName).vectorCopy();
00097 gasvisctCurves_[regionIdx].setXYContainers(T, mu);
00098 }
00099 }
00100
00101
00102
00103 refTemp_ = 0.0;
00104 if (enableThermalDensity_) {
00105 refTemp_ = deck.getKeyword("TREF").getRecord(0).getItem("TEMPERATURE").getSIDouble(0);
00106 }
00107 }
00108 #endif // HAVE_OPM_PARSER
00109
00113 void setNumRegions(size_t numRegions)
00114 { gasvisctCurves_.resize(numRegions); }
00115
00119 void initEnd()
00120 { }
00121
00122 size_t numRegions() const
00123 { return gasvisctCurves_.size(); }
00124
00128 bool enableThermalDensity() const
00129 { return enableThermalDensity_; }
00130
00134 bool enableThermalViscosity() const
00135 { return enableThermalViscosity_; }
00136
00140 template <class Evaluation>
00141 Evaluation viscosity(unsigned regionIdx,
00142 const Evaluation& temperature,
00143 const Evaluation& pressure,
00144 const Evaluation& Rv) const
00145 {
00146 if (!enableThermalViscosity())
00147 return isothermalPvt_->viscosity(regionIdx, temperature, pressure, Rv);
00148
00149
00150 const auto& muGasvisct = gasvisctCurves_[regionIdx].eval(temperature);
00151 return muGasvisct;
00152 }
00153
00157 template <class Evaluation>
00158 Evaluation saturatedViscosity(unsigned regionIdx,
00159 const Evaluation& temperature,
00160 const Evaluation& pressure) const
00161 {
00162 if (!enableThermalViscosity())
00163 return isothermalPvt_->saturatedViscosity(regionIdx, temperature, pressure);
00164
00165
00166 const auto& muGasvisct = gasvisctCurves_[regionIdx].eval(temperature);
00167 return muGasvisct;
00168 }
00169
00173 template <class Evaluation>
00174 Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
00175 const Evaluation& temperature,
00176 const Evaluation& pressure,
00177 const Evaluation& Rv) const
00178 {
00179 const auto& b =
00180 isothermalPvt_->inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rv);
00181 if (!enableThermalDensity())
00182 return b;
00183
00184
00185
00186
00187
00188 return b*temperature/refTemp_;
00189 }
00190
00194 template <class Evaluation>
00195 Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
00196 const Evaluation& temperature,
00197 const Evaluation& pressure) const
00198 {
00199 const auto& b =
00200 isothermalPvt_->saturatedInverseFormationVolumeFactor(regionIdx, temperature, pressure);
00201 if (!enableThermalDensity())
00202 return b;
00203
00204
00205
00206
00207
00208 return b*temperature/refTemp_;
00209 }
00210
00218 template <class Evaluation>
00219 Evaluation saturatedOilVaporizationFactor(unsigned regionIdx,
00220 const Evaluation& temperature,
00221 const Evaluation& pressure) const
00222 { return isothermalPvt_->saturatedOilVaporizationFactor(regionIdx, temperature, pressure); }
00223
00231 template <class Evaluation>
00232 Evaluation saturatedOilVaporizationFactor(unsigned regionIdx,
00233 const Evaluation& temperature,
00234 const Evaluation& pressure,
00235 const Evaluation& oilSaturation,
00236 Scalar maxOilSaturation) const
00237 { return isothermalPvt_->saturatedOilVaporizationFactor(regionIdx, temperature, pressure, oilSaturation, maxOilSaturation); }
00238
00246 template <class Evaluation>
00247 Evaluation saturationPressure(unsigned regionIdx,
00248 const Evaluation& temperature,
00249 const Evaluation& pressure) const
00250 { return isothermalPvt_->saturationPressure(regionIdx, temperature, pressure); }
00251
00252 private:
00253 IsothermalPvt* isothermalPvt_;
00254
00255
00256
00257 std::vector<TabulatedOneDFunction> gasvisctCurves_;
00258
00259
00260
00261
00262 Scalar refTemp_;
00263
00264 bool enableThermalDensity_;
00265 bool enableThermalViscosity_;
00266 };
00267
00268 }
00269
00270 #endif