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_OIL_PVT_THERMAL_HPP
00028 #define OPM_OIL_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 OilPvtMultiplexer;
00047
00054 template <class Scalar>
00055 class OilPvtThermal
00056 {
00057 typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
00058 typedef OilPvtMultiplexer<Scalar, false> IsothermalPvt;
00059
00060 public:
00061 ~OilPvtThermal()
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("THERMEX1");
00083 enableThermalViscosity_ = deck.hasKeyword("VISCREF");
00084
00085 unsigned numRegions = isothermalPvt_->numRegions();
00086 setNumRegions(numRegions);
00087
00088
00089 if (deck.hasKeyword("VISCREF")) {
00090 const auto& oilvisctTables = tables.getOilvisctTables();
00091 const auto& viscrefKeyword = deck.getKeyword("VISCREF");
00092
00093 assert(oilvisctTables.size() == numRegions);
00094 assert(viscrefKeyword.size() == numRegions);
00095
00096 for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
00097 const auto& TCol = oilvisctTables[regionIdx].getColumn("Temperature").vectorCopy();
00098 const auto& muCol = oilvisctTables[regionIdx].getColumn("Viscosity").vectorCopy();
00099 oilvisctCurves_[regionIdx].setXYContainers(TCol, muCol);
00100
00101 const auto& viscrefRecord = viscrefKeyword.getRecord(regionIdx);
00102 viscrefPress_[regionIdx] = viscrefRecord.getItem("REFERENCE_PRESSURE").getSIDouble(0);
00103 viscrefRs_[regionIdx] = viscrefRecord.getItem("REFERENCE_RS").getSIDouble(0);
00104
00105
00106
00107
00108 Scalar Tref = 273.15 + 20;
00109
00110
00111 viscRef_[regionIdx] =
00112 isothermalPvt_->viscosity(regionIdx,
00113 Tref,
00114 viscrefPress_[regionIdx],
00115 viscrefRs_[regionIdx]);
00116 }
00117 }
00118
00119
00120
00121 refTemp_ = 0.0;
00122 if (deck.hasKeyword("THERMEX1")) {
00123 int oilCompIdx = deck.getKeyword("OCOMPIDX").getRecord(0).getItem("OIL_COMPONENT_INDEX").get< int >(0) - 1;
00124
00125
00126 refTemp_ = deck.getKeyword("TREF").getRecord(0).getItem("TEMPERATURE").getSIDouble(oilCompIdx);
00127 refPress_ = deck.getKeyword("PREF").getRecord(0).getItem("PRESSURE").getSIDouble(oilCompIdx);
00128 refC_ = deck.getKeyword("CREF").getRecord(0).getItem("COMPRESSIBILITY").getSIDouble(oilCompIdx);
00129 thermex1_ = deck.getKeyword("THERMEX1").getRecord(0).getItem("EXPANSION_COEFF").getSIDouble(oilCompIdx);
00130 }
00131 }
00132 #endif // HAVE_OPM_PARSER
00133
00137 void setNumRegions(size_t numRegions)
00138 {
00139 oilvisctCurves_.resize(numRegions);
00140 viscrefPress_.resize(numRegions);
00141 viscrefRs_.resize(numRegions);
00142 viscRef_.resize(numRegions);
00143 }
00144
00148 void initEnd()
00149 { }
00150
00154 bool enableThermalDensity() const
00155 { return enableThermalDensity_; }
00156
00160 bool enableThermalViscosity() const
00161 { return enableThermalViscosity_; }
00162
00163 size_t numRegions() const
00164 { return viscrefRs_.size(); }
00165
00169 template <class Evaluation>
00170 Evaluation viscosity(unsigned regionIdx,
00171 const Evaluation& temperature,
00172 const Evaluation& pressure,
00173 const Evaluation& Rs) const
00174 {
00175 const auto& isothermalMu = isothermalPvt_->viscosity(regionIdx, temperature, pressure, Rs);
00176 if (!enableThermalViscosity())
00177 return isothermalMu;
00178
00179
00180 const auto& muOilvisct = oilvisctCurves_[regionIdx].eval(temperature);
00181 return muOilvisct/viscRef_[regionIdx]*isothermalMu;
00182 }
00183
00187 template <class Evaluation>
00188 Evaluation saturatedViscosity(unsigned regionIdx,
00189 const Evaluation& temperature,
00190 const Evaluation& pressure) const
00191 {
00192 const auto& isothermalMu = isothermalPvt_->saturatedViscosity(regionIdx, temperature, pressure);
00193 if (!enableThermalViscosity())
00194 return isothermalMu;
00195
00196
00197 const auto& muOilvisct = oilvisctCurves_[regionIdx].eval(temperature);
00198 return muOilvisct/viscRef_[regionIdx]*isothermalMu;
00199 }
00200
00201
00205 template <class Evaluation>
00206 Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
00207 const Evaluation& temperature,
00208 const Evaluation& pressure,
00209 const Evaluation& Rs) const
00210 {
00211 const auto& b =
00212 isothermalPvt_->inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rs);
00213 if (!enableThermalDensity())
00214 return b;
00215
00216
00217
00218
00219
00220
00221 const auto& alpha = 1.0/(1 + thermex1_*(temperature - refTemp_));
00222 return alpha*b;
00223 }
00224
00228 template <class Evaluation>
00229 Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
00230 const Evaluation& temperature,
00231 const Evaluation& pressure) const
00232 {
00233 const auto& b =
00234 isothermalPvt_->saturatedInverseFormationVolumeFactor(regionIdx, temperature, pressure);
00235 if (!enableThermalDensity())
00236 return b;
00237
00238
00239
00240
00241
00242
00243 const auto& alpha = 1.0/(1 + thermex1_*(temperature - refTemp_));
00244 return alpha*b;
00245 }
00246
00254 template <class Evaluation>
00255 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
00256 const Evaluation& temperature,
00257 const Evaluation& pressure) const
00258 { return isothermalPvt_->saturatedGasDissolutionFactor(regionIdx, temperature, pressure); }
00259
00267 template <class Evaluation>
00268 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
00269 const Evaluation& temperature,
00270 const Evaluation& pressure,
00271 const Evaluation& oilSaturation,
00272 Scalar maxOilSaturation) const
00273 { return isothermalPvt_->saturatedGasDissolutionFactor(regionIdx, temperature, pressure, oilSaturation, maxOilSaturation); }
00274
00282 template <class Evaluation>
00283 Evaluation saturationPressure(unsigned regionIdx,
00284 const Evaluation& temperature,
00285 const Evaluation& pressure) const
00286 { return isothermalPvt_->saturationPressure(regionIdx, temperature, pressure); }
00287
00288 private:
00289 IsothermalPvt* isothermalPvt_;
00290
00291
00292
00293 std::vector<TabulatedOneDFunction> oilvisctCurves_;
00294 std::vector<Scalar> viscrefPress_;
00295 std::vector<Scalar> viscrefRs_;
00296 std::vector<Scalar> viscRef_;
00297
00298
00299
00300
00301 Scalar refTemp_;
00302 Scalar refPress_;
00303 Scalar refC_;
00304 Scalar thermex1_;
00305
00306 bool enableThermalDensity_;
00307 bool enableThermalViscosity_;
00308 };
00309
00310 }
00311
00312 #endif