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_MULTIPLEXER_HPP
00028 #define OPM_OIL_PVT_MULTIPLEXER_HPP
00029
00030 #include "ConstantCompressibilityOilPvt.hpp"
00031 #include "DeadOilPvt.hpp"
00032 #include "LiveOilPvt.hpp"
00033 #include "OilPvtThermal.hpp"
00034
00035 namespace Opm {
00036 #define OPM_OIL_PVT_MULTIPLEXER_CALL(codeToCall) \
00037 switch (approach_) { \
00038 case ConstantCompressibilityOilPvt: { \
00039 auto& pvtImpl = getRealPvt<ConstantCompressibilityOilPvt>(); \
00040 codeToCall; \
00041 break; \
00042 } \
00043 case DeadOilPvt: { \
00044 auto& pvtImpl = getRealPvt<DeadOilPvt>(); \
00045 codeToCall; \
00046 break; \
00047 } \
00048 case LiveOilPvt: { \
00049 auto& pvtImpl = getRealPvt<LiveOilPvt>(); \
00050 codeToCall; \
00051 break; \
00052 } \
00053 case ThermalOilPvt: { \
00054 auto& pvtImpl = getRealPvt<ThermalOilPvt>(); \
00055 codeToCall; \
00056 break; \
00057 } \
00058 case NoOilPvt: \
00059 OPM_THROW(std::logic_error, "Not implemented: Oil PVT of this deck!"); \
00060 }
00061
00074 template <class Scalar, bool enableThermal = true>
00075 class OilPvtMultiplexer
00076 {
00077 public:
00078 typedef Opm::OilPvtThermal<Scalar> OilPvtThermal;
00079
00080 enum OilPvtApproach {
00081 NoOilPvt,
00082 LiveOilPvt,
00083 DeadOilPvt,
00084 ConstantCompressibilityOilPvt,
00085 ThermalOilPvt
00086 };
00087
00088 OilPvtMultiplexer()
00089 {
00090 approach_ = NoOilPvt;
00091 }
00092
00093 ~OilPvtMultiplexer()
00094 {
00095 switch (approach_) {
00096 case LiveOilPvt: {
00097 delete &getRealPvt<LiveOilPvt>();
00098 break;
00099 }
00100 case DeadOilPvt: {
00101 delete &getRealPvt<DeadOilPvt>();
00102 break;
00103 }
00104 case ConstantCompressibilityOilPvt: {
00105 delete &getRealPvt<ConstantCompressibilityOilPvt>();
00106 break;
00107 }
00108 case ThermalOilPvt: {
00109 delete &getRealPvt<ThermalOilPvt>();
00110 break;
00111 }
00112
00113 case NoOilPvt:
00114 break;
00115 }
00116 }
00117
00118 #if HAVE_OPM_PARSER
00119
00124 void initFromDeck(const Deck& deck, const EclipseState& eclState)
00125 {
00126 bool enableOil = deck.hasKeyword("OIL");
00127 if (!enableOil)
00128 return;
00129
00130 if (enableThermal
00131 && (deck.hasKeyword("THERMEX1")
00132 || deck.hasKeyword("VISCREF")))
00133 setApproach(ThermalOilPvt);
00134 else if (deck.hasKeyword("PVCDO"))
00135 setApproach(ConstantCompressibilityOilPvt);
00136 else if (deck.hasKeyword("PVDO"))
00137 setApproach(DeadOilPvt);
00138 else if (deck.hasKeyword("PVTO"))
00139 setApproach(LiveOilPvt);
00140
00141 OPM_OIL_PVT_MULTIPLEXER_CALL(pvtImpl.initFromDeck(deck, eclState));
00142 }
00143 #endif // HAVE_OPM_PARSER
00144
00145
00146 void initEnd()
00147 { OPM_OIL_PVT_MULTIPLEXER_CALL(pvtImpl.initEnd()); }
00148
00152 unsigned numRegions() const
00153 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.numRegions()); return 1; }
00154
00158 template <class Evaluation>
00159 Evaluation viscosity(unsigned regionIdx,
00160 const Evaluation& temperature,
00161 const Evaluation& pressure,
00162 const Evaluation& Rs) const
00163 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure, Rs)); return 0; }
00164
00168 template <class Evaluation>
00169 Evaluation saturatedViscosity(unsigned regionIdx,
00170 const Evaluation& temperature,
00171 const Evaluation& pressure) const
00172 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedViscosity(regionIdx, temperature, pressure)); return 0; }
00173
00177 template <class Evaluation>
00178 Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
00179 const Evaluation& temperature,
00180 const Evaluation& pressure,
00181 const Evaluation& Rs) const
00182 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rs)); return 0; }
00183
00187 template <class Evaluation>
00188 Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
00189 const Evaluation& temperature,
00190 const Evaluation& pressure) const
00191 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedInverseFormationVolumeFactor(regionIdx, temperature, pressure)); return 0; }
00192
00196 template <class Evaluation>
00197 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
00198 const Evaluation& temperature,
00199 const Evaluation& pressure) const
00200 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedGasDissolutionFactor(regionIdx, temperature, pressure)); return 0; }
00201
00205 template <class Evaluation>
00206 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
00207 const Evaluation& temperature,
00208 const Evaluation& pressure,
00209 const Evaluation& oilSaturation,
00210 Scalar maxOilSaturation) const
00211 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedGasDissolutionFactor(regionIdx, temperature, pressure, oilSaturation, maxOilSaturation)); return 0; }
00212
00220 template <class Evaluation>
00221 Evaluation saturationPressure(unsigned regionIdx,
00222 const Evaluation& temperature,
00223 const Evaluation& Rs) const
00224 { OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturationPressure(regionIdx, temperature, Rs)); return 0; }
00225
00226 void setApproach(OilPvtApproach appr)
00227 {
00228 switch (appr) {
00229 case LiveOilPvt:
00230 realOilPvt_ = new Opm::LiveOilPvt<Scalar>;
00231 break;
00232
00233 case DeadOilPvt:
00234 realOilPvt_ = new Opm::DeadOilPvt<Scalar>;
00235 break;
00236
00237 case ConstantCompressibilityOilPvt:
00238 realOilPvt_ = new Opm::ConstantCompressibilityOilPvt<Scalar>;
00239 break;
00240
00241 case ThermalOilPvt:
00242 realOilPvt_ = new Opm::OilPvtThermal<Scalar>;
00243 break;
00244
00245 case NoOilPvt:
00246 OPM_THROW(std::logic_error, "Not implemented: Oil PVT of this deck!");
00247 }
00248
00249 approach_ = appr;
00250 }
00251
00257 OilPvtApproach approach() const
00258 { return approach_; }
00259
00260
00261 template <OilPvtApproach approachV>
00262 typename std::enable_if<approachV == LiveOilPvt, Opm::LiveOilPvt<Scalar> >::type& getRealPvt()
00263 {
00264 assert(approach() == approachV);
00265 return *static_cast<Opm::LiveOilPvt<Scalar>* >(realOilPvt_);
00266 }
00267
00268 template <OilPvtApproach approachV>
00269 typename std::enable_if<approachV == LiveOilPvt, const Opm::LiveOilPvt<Scalar> >::type& getRealPvt() const
00270 {
00271 assert(approach() == approachV);
00272 return *static_cast<Opm::LiveOilPvt<Scalar>* >(realOilPvt_);
00273 }
00274
00275 template <OilPvtApproach approachV>
00276 typename std::enable_if<approachV == DeadOilPvt, Opm::DeadOilPvt<Scalar> >::type& getRealPvt()
00277 {
00278 assert(approach() == approachV);
00279 return *static_cast<Opm::DeadOilPvt<Scalar>* >(realOilPvt_);
00280 }
00281
00282 template <OilPvtApproach approachV>
00283 typename std::enable_if<approachV == DeadOilPvt, const Opm::DeadOilPvt<Scalar> >::type& getRealPvt() const
00284 {
00285 assert(approach() == approachV);
00286 return *static_cast<Opm::DeadOilPvt<Scalar>* >(realOilPvt_);
00287 }
00288
00289 template <OilPvtApproach approachV>
00290 typename std::enable_if<approachV == ConstantCompressibilityOilPvt, Opm::ConstantCompressibilityOilPvt<Scalar> >::type& getRealPvt()
00291 {
00292 assert(approach() == approachV);
00293 return *static_cast<Opm::ConstantCompressibilityOilPvt<Scalar>* >(realOilPvt_);
00294 }
00295
00296 template <OilPvtApproach approachV>
00297 typename std::enable_if<approachV == ConstantCompressibilityOilPvt, const Opm::ConstantCompressibilityOilPvt<Scalar> >::type& getRealPvt() const
00298 {
00299 assert(approach() == approachV);
00300 return *static_cast<Opm::ConstantCompressibilityOilPvt<Scalar>* >(realOilPvt_);
00301 }
00302
00303 template <OilPvtApproach approachV>
00304 typename std::enable_if<approachV == ThermalOilPvt, Opm::OilPvtThermal<Scalar> >::type& getRealPvt()
00305 {
00306 assert(approach() == approachV);
00307 return *static_cast<Opm::OilPvtThermal<Scalar>* >(realOilPvt_);
00308 }
00309
00310 template <OilPvtApproach approachV>
00311 typename std::enable_if<approachV == ThermalOilPvt, const Opm::OilPvtThermal<Scalar> >::type& getRealPvt() const
00312 {
00313 assert(approach() == approachV);
00314 return *static_cast<const Opm::OilPvtThermal<Scalar>* >(realOilPvt_);
00315 }
00316
00317 private:
00318 OilPvtApproach approach_;
00319 void* realOilPvt_;
00320 };
00321
00322 #undef OPM_OIL_PVT_MULTIPLEXER_CALL
00323
00324 }
00325
00326 #endif