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_WATER_PVT_MULTIPLEXER_HPP
00028 #define OPM_WATER_PVT_MULTIPLEXER_HPP
00029
00030 #include "ConstantCompressibilityWaterPvt.hpp"
00031 #include "WaterPvtThermal.hpp"
00032
00033 #define OPM_WATER_PVT_MULTIPLEXER_CALL(codeToCall) \
00034 switch (approach_) { \
00035 case ConstantCompressibilityWaterPvt: { \
00036 auto& pvtImpl = getRealPvt<ConstantCompressibilityWaterPvt>(); \
00037 codeToCall; \
00038 break; \
00039 } \
00040 case ThermalWaterPvt: { \
00041 auto& pvtImpl = getRealPvt<ThermalWaterPvt>(); \
00042 codeToCall; \
00043 break; \
00044 } \
00045 case NoWaterPvt: \
00046 OPM_THROW(std::logic_error, "Not implemented: Water PVT of this deck!"); \
00047 }
00048
00049 namespace Opm {
00054 template <class Scalar, bool enableThermal = true>
00055 class WaterPvtMultiplexer
00056 {
00057 public:
00058 typedef Opm::WaterPvtThermal<Scalar> WaterPvtThermal;
00059
00060 enum WaterPvtApproach {
00061 NoWaterPvt,
00062 ConstantCompressibilityWaterPvt,
00063 ThermalWaterPvt
00064 };
00065
00066 WaterPvtMultiplexer()
00067 {
00068 approach_ = NoWaterPvt;
00069 }
00070
00071 ~WaterPvtMultiplexer()
00072 {
00073 switch (approach_) {
00074 case ConstantCompressibilityWaterPvt: {
00075 delete &getRealPvt<ConstantCompressibilityWaterPvt>();
00076 break;
00077 }
00078 case ThermalWaterPvt: {
00079 delete &getRealPvt<ThermalWaterPvt>();
00080 break;
00081 }
00082 case NoWaterPvt:
00083 break;
00084 }
00085 }
00086
00087 #if HAVE_OPM_PARSER
00088
00093 void initFromDeck(const Deck& deck, const EclipseState& eclState)
00094 {
00095 bool enableWater = deck.hasKeyword("WATER");
00096 if (!enableWater)
00097 return;
00098
00099 if (enableThermal
00100 && (deck.hasKeyword("WATDENT")
00101 || deck.hasKeyword("VISCREF")))
00102 setApproach(ThermalWaterPvt);
00103 else if (deck.hasKeyword("PVTW"))
00104 setApproach(ConstantCompressibilityWaterPvt);
00105
00106 OPM_WATER_PVT_MULTIPLEXER_CALL(pvtImpl.initFromDeck(deck, eclState));
00107 }
00108 #endif // HAVE_OPM_PARSER
00109
00110 void initEnd()
00111 { OPM_WATER_PVT_MULTIPLEXER_CALL(pvtImpl.initEnd()); }
00112
00116 unsigned numRegions() const
00117 { OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.numRegions()); return 1; }
00118
00122 template <class Evaluation>
00123 Evaluation viscosity(unsigned regionIdx,
00124 const Evaluation& temperature,
00125 const Evaluation& pressure) const
00126 { OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure)); return 0; }
00127
00131 template <class Evaluation>
00132 Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
00133 const Evaluation& temperature,
00134 const Evaluation& pressure) const
00135 { OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.inverseFormationVolumeFactor(regionIdx, temperature, pressure)); return 0; }
00136
00137 void setApproach(WaterPvtApproach appr)
00138 {
00139 switch (appr) {
00140 case ConstantCompressibilityWaterPvt:
00141 realWaterPvt_ = new Opm::ConstantCompressibilityWaterPvt<Scalar>;
00142 break;
00143
00144 case ThermalWaterPvt:
00145 realWaterPvt_ = new Opm::WaterPvtThermal<Scalar>;
00146 break;
00147
00148 case NoWaterPvt:
00149 OPM_THROW(std::logic_error, "Not implemented: Water PVT of this deck!");
00150 }
00151
00152 approach_ = appr;
00153 }
00154
00160 WaterPvtApproach approach() const
00161 { return approach_; }
00162
00163
00164 template <WaterPvtApproach approachV>
00165 typename std::enable_if<approachV == ConstantCompressibilityWaterPvt, Opm::ConstantCompressibilityWaterPvt<Scalar> >::type& getRealPvt()
00166 {
00167 assert(approach() == approachV);
00168 return *static_cast<Opm::ConstantCompressibilityWaterPvt<Scalar>* >(realWaterPvt_);
00169 }
00170
00171 template <WaterPvtApproach approachV>
00172 typename std::enable_if<approachV == ConstantCompressibilityWaterPvt, const Opm::ConstantCompressibilityWaterPvt<Scalar> >::type& getRealPvt() const
00173 {
00174 assert(approach() == approachV);
00175 return *static_cast<Opm::ConstantCompressibilityWaterPvt<Scalar>* >(realWaterPvt_);
00176 }
00177
00178 template <WaterPvtApproach approachV>
00179 typename std::enable_if<approachV == ThermalWaterPvt, Opm::WaterPvtThermal<Scalar> >::type& getRealPvt()
00180 {
00181 assert(approach() == approachV);
00182 return *static_cast<Opm::WaterPvtThermal<Scalar>* >(realWaterPvt_);
00183 }
00184
00185 template <WaterPvtApproach approachV>
00186 typename std::enable_if<approachV == ThermalWaterPvt, const Opm::WaterPvtThermal<Scalar> >::type& getRealPvt() const
00187 {
00188 assert(approach() == approachV);
00189 return *static_cast<Opm::WaterPvtThermal<Scalar>* >(realWaterPvt_);
00190 }
00191
00192 private:
00193 WaterPvtApproach approach_;
00194 void* realWaterPvt_;
00195 };
00196
00197 #undef OPM_WATER_PVT_MULTIPLEXER_CALL
00198
00199 }
00200
00201 #endif