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_ECL_MULTIPLEXER_MATERIAL_PARAMS_HPP
00028 #define OPM_ECL_MULTIPLEXER_MATERIAL_PARAMS_HPP
00029
00030 #include "EclStone1Material.hpp"
00031 #include "EclStone2Material.hpp"
00032 #include "EclDefaultMaterial.hpp"
00033 #include "EclTwoPhaseMaterial.hpp"
00034
00035 #include <type_traits>
00036 #include <cassert>
00037 #include <memory>
00038
00039 #include <opm/material/common/EnsureFinalized.hpp>
00040
00041 namespace Opm {
00042
00043 enum EclMultiplexerApproach {
00044 EclDefaultApproach,
00045 EclStone1Approach,
00046 EclStone2Approach,
00047 EclTwoPhaseApproach
00048 };
00049
00057 template<class Traits, class GasOilMaterialLawT, class OilWaterMaterialLawT>
00058 class EclMultiplexerMaterialParams : public Traits, public EnsureFinalized
00059 {
00060 typedef typename Traits::Scalar Scalar;
00061 enum { numPhases = 3 };
00062
00063 typedef Opm::EclStone1Material<Traits, GasOilMaterialLawT, OilWaterMaterialLawT> Stone1Material;
00064 typedef Opm::EclStone2Material<Traits, GasOilMaterialLawT, OilWaterMaterialLawT> Stone2Material;
00065 typedef Opm::EclDefaultMaterial<Traits, GasOilMaterialLawT, OilWaterMaterialLawT> DefaultMaterial;
00066 typedef Opm::EclTwoPhaseMaterial<Traits, GasOilMaterialLawT, OilWaterMaterialLawT> TwoPhaseMaterial;
00067
00068 typedef typename Stone1Material::Params Stone1Params;
00069 typedef typename Stone2Material::Params Stone2Params;
00070 typedef typename DefaultMaterial::Params DefaultParams;
00071 typedef typename TwoPhaseMaterial::Params TwoPhaseParams;
00072
00073 template <class ParamT>
00074 struct Deleter
00075 {
00076 inline void operator () ( void* ptr )
00077 {
00078 delete static_cast< ParamT* > (ptr);
00079 }
00080 };
00081
00082 typedef std::shared_ptr< void > ParamPointerType;
00083
00084 public:
00085 using EnsureFinalized :: finalize;
00086
00090 EclMultiplexerMaterialParams() : realParams_()
00091 {
00092 }
00093
00094 EclMultiplexerMaterialParams(const EclMultiplexerMaterialParams& other)
00095 : realParams_()
00096 {
00097 setApproach( other.approach() );
00098 }
00099
00100 EclMultiplexerMaterialParams& operator= ( const EclMultiplexerMaterialParams& other )
00101 {
00102 realParams_.reset();
00103 setApproach( other.approach() );
00104 return *this;
00105 }
00106
00107 void setApproach(EclMultiplexerApproach newApproach)
00108 {
00109 assert(realParams_ == 0);
00110 approach_ = newApproach;
00111
00112 switch (approach()) {
00113 case EclStone1Approach:
00114 realParams_ = ParamPointerType(new Stone1Params, Deleter< Stone1Params > () );
00115 break;
00116
00117 case EclStone2Approach:
00118 realParams_ = ParamPointerType(new Stone2Params, Deleter< Stone2Params > () );
00119 break;
00120
00121 case EclDefaultApproach:
00122 realParams_ = ParamPointerType(new DefaultParams, Deleter< DefaultParams > () );
00123 break;
00124
00125 case EclTwoPhaseApproach:
00126 realParams_ = ParamPointerType(new TwoPhaseParams, Deleter< TwoPhaseParams > () );
00127 break;
00128 }
00129 }
00130
00131 EclMultiplexerApproach approach() const
00132 { return approach_; }
00133
00134
00135 template <EclMultiplexerApproach approachV>
00136 typename std::enable_if<approachV == EclStone1Approach, Stone1Params>::type&
00137 getRealParams()
00138 {
00139 assert(approach() == approachV);
00140 return this->template castTo<Stone1Params>();
00141 }
00142
00143 template <EclMultiplexerApproach approachV>
00144 typename std::enable_if<approachV == EclStone1Approach, const Stone1Params>::type&
00145 getRealParams() const
00146 {
00147 assert(approach() == approachV);
00148 return this->template castTo<Stone1Params>();
00149 }
00150
00151
00152 template <EclMultiplexerApproach approachV>
00153 typename std::enable_if<approachV == EclStone2Approach, Stone2Params>::type&
00154 getRealParams()
00155 {
00156 assert(approach() == approachV);
00157 return this->template castTo<Stone2Params>();
00158 }
00159
00160 template <EclMultiplexerApproach approachV>
00161 typename std::enable_if<approachV == EclStone2Approach, const Stone2Params>::type&
00162 getRealParams() const
00163 {
00164 assert(approach() == approachV);
00165 return this->template castTo<Stone2Params>();
00166 }
00167
00168
00169 template <EclMultiplexerApproach approachV>
00170 typename std::enable_if<approachV == EclDefaultApproach, DefaultParams>::type&
00171 getRealParams()
00172 {
00173 assert(approach() == approachV);
00174 return this->template castTo<DefaultParams>();
00175 }
00176
00177 template <EclMultiplexerApproach approachV>
00178 typename std::enable_if<approachV == EclDefaultApproach, const DefaultParams>::type&
00179 getRealParams() const
00180 {
00181 assert(approach() == approachV);
00182 return this->template castTo<DefaultParams>();
00183 }
00184
00185
00186 template <EclMultiplexerApproach approachV>
00187 typename std::enable_if<approachV == EclTwoPhaseApproach, TwoPhaseParams>::type&
00188 getRealParams()
00189 {
00190 assert(approach() == approachV);
00191 return this->template castTo<TwoPhaseParams>();
00192 }
00193
00194 template <EclMultiplexerApproach approachV>
00195 typename std::enable_if<approachV == EclTwoPhaseApproach, const TwoPhaseParams>::type&
00196 getRealParams() const
00197 {
00198 assert(approach() == approachV);
00199 return this->template castTo<TwoPhaseParams>();
00200 }
00201
00202 private:
00203 template <class ParamT>
00204 ParamT& castTo()
00205 {
00206 return *(static_cast<ParamT *> (realParams_.operator->()));
00207 }
00208
00209 template <class ParamT>
00210 const ParamT& castTo() const
00211 {
00212 return *(static_cast<const ParamT *> (realParams_.operator->()));
00213 }
00214
00215 EclMultiplexerApproach approach_;
00216 ParamPointerType realParams_;
00217 };
00218 }
00219
00220 #endif