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_STONE2_MATERIAL_HPP
00028 #define OPM_ECL_STONE2_MATERIAL_HPP
00029
00030 #include "EclStone2MaterialParams.hpp"
00031
00032 #include <opm/common/Valgrind.hpp>
00033 #include <opm/material/common/MathToolbox.hpp>
00034
00035 #include <opm/common/Exceptions.hpp>
00036 #include <opm/common/ErrorMacros.hpp>
00037
00038 #include <algorithm>
00039
00040 namespace Opm {
00041
00055 template <class TraitsT,
00056 class GasOilMaterialLawT,
00057 class OilWaterMaterialLawT,
00058 class ParamsT = EclStone2MaterialParams<TraitsT,
00059 typename GasOilMaterialLawT::Params,
00060 typename OilWaterMaterialLawT::Params> >
00061 class EclStone2Material : public TraitsT
00062 {
00063 public:
00064 typedef GasOilMaterialLawT GasOilMaterialLaw;
00065 typedef OilWaterMaterialLawT OilWaterMaterialLaw;
00066
00067
00068 static_assert(TraitsT::numPhases == 3,
00069 "The number of phases considered by this capillary pressure "
00070 "law is always three!");
00071 static_assert(GasOilMaterialLaw::numPhases == 2,
00072 "The number of phases considered by the gas-oil capillary "
00073 "pressure law must be two!");
00074 static_assert(OilWaterMaterialLaw::numPhases == 2,
00075 "The number of phases considered by the oil-water capillary "
00076 "pressure law must be two!");
00077 static_assert(std::is_same<typename GasOilMaterialLaw::Scalar,
00078 typename OilWaterMaterialLaw::Scalar>::value,
00079 "The two two-phase capillary pressure laws must use the same "
00080 "type of floating point values.");
00081
00082 static_assert(GasOilMaterialLaw::implementsTwoPhaseSatApi,
00083 "The gas-oil material law must implement the two-phase saturation "
00084 "only API to for the default Ecl capillary pressure law!");
00085 static_assert(OilWaterMaterialLaw::implementsTwoPhaseSatApi,
00086 "The oil-water material law must implement the two-phase saturation "
00087 "only API to for the default Ecl capillary pressure law!");
00088
00089 typedef TraitsT Traits;
00090 typedef ParamsT Params;
00091 typedef typename Traits::Scalar Scalar;
00092
00093 static const int numPhases = 3;
00094 static const int waterPhaseIdx = Traits::wettingPhaseIdx;
00095 static const int oilPhaseIdx = Traits::nonWettingPhaseIdx;
00096 static const int gasPhaseIdx = Traits::gasPhaseIdx;
00097
00100 static const bool implementsTwoPhaseApi = false;
00101
00104 static const bool implementsTwoPhaseSatApi = false;
00105
00108 static const bool isSaturationDependent = true;
00109
00112 static const bool isPressureDependent = false;
00113
00116 static const bool isTemperatureDependent = false;
00117
00120 static const bool isCompositionDependent = false;
00121
00136 template <class ContainerT, class FluidState>
00137 static void capillaryPressures(ContainerT& values,
00138 const Params& params,
00139 const FluidState& state)
00140 {
00141 typedef typename std::remove_reference<decltype(values[0])>::type Evaluation;
00142 values[gasPhaseIdx] = pcgn<FluidState, Evaluation>(params, state);
00143 values[oilPhaseIdx] = 0;
00144 values[waterPhaseIdx] = - pcnw<FluidState, Evaluation>(params, state);
00145 Valgrind::CheckDefined(values[gasPhaseIdx]);
00146 Valgrind::CheckDefined(values[oilPhaseIdx]);
00147 Valgrind::CheckDefined(values[waterPhaseIdx]);
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 static void oilWaterHysteresisParams(Scalar& pcSwMdc,
00157 Scalar& krnSwMdc,
00158 const Params& params)
00159 {
00160 pcSwMdc = params.oilWaterParams().pcSwMdc();
00161 krnSwMdc = params.oilWaterParams().krnSwMdc();
00162
00163 Valgrind::CheckDefined(pcSwMdc);
00164 Valgrind::CheckDefined(krnSwMdc);
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 static void setOilWaterHysteresisParams(const Scalar& pcSwMdc,
00174 const Scalar& krnSwMdc,
00175 Params& params)
00176 {
00177 const double krwSw = 2.0;
00178 params.oilWaterParams().update(pcSwMdc, krwSw, krnSwMdc);
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 static void gasOilHysteresisParams(Scalar& pcSwMdc,
00188 Scalar& krnSwMdc,
00189 const Params& params)
00190 {
00191 pcSwMdc = params.gasOilParams().pcSwMdc();
00192 krnSwMdc = params.gasOilParams().krnSwMdc();
00193
00194 Valgrind::CheckDefined(pcSwMdc);
00195 Valgrind::CheckDefined(krnSwMdc);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 static void setGasOilHysteresisParams(const Scalar& pcSwMdc,
00205 const Scalar& krnSwMdc,
00206 Params& params)
00207 {
00208 const double krwSw = 2.0;
00209 params.gasOilParams().update(pcSwMdc, krwSw, krnSwMdc);
00210 }
00211
00221 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00222 static Evaluation pcgn(const Params& params,
00223 const FluidState& fs)
00224 {
00225 const auto& Sw = 1.0 - Opm::decay<Evaluation>(fs.saturation(gasPhaseIdx));
00226 return GasOilMaterialLaw::twoPhaseSatPcnw(params.gasOilParams(), Sw);
00227 }
00228
00238 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00239 static Evaluation pcnw(const Params& params,
00240 const FluidState& fs)
00241 {
00242 const auto& Sw = Opm::decay<Evaluation>(fs.saturation(waterPhaseIdx));
00243 Valgrind::CheckDefined(Sw);
00244 const auto& result = OilWaterMaterialLaw::twoPhaseSatPcnw(params.oilWaterParams(), Sw);
00245 Valgrind::CheckDefined(result);
00246 return result;
00247 }
00248
00252 template <class ContainerT, class FluidState>
00253 static void saturations(ContainerT& ,
00254 const Params& ,
00255 const FluidState& )
00256 {
00257 OPM_THROW(std::logic_error, "Not implemented: saturations()");
00258 }
00259
00263 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00264 static Evaluation Sg(const Params& ,
00265 const FluidState& )
00266 {
00267 OPM_THROW(std::logic_error, "Not implemented: Sg()");
00268 }
00269
00273 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00274 static Evaluation Sn(const Params& ,
00275 const FluidState& )
00276 {
00277 OPM_THROW(std::logic_error, "Not implemented: Sn()");
00278 }
00279
00283 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00284 static Evaluation Sw(const Params& ,
00285 const FluidState& )
00286 {
00287 OPM_THROW(std::logic_error, "Not implemented: Sw()");
00288 }
00289
00305 template <class ContainerT, class FluidState>
00306 static void relativePermeabilities(ContainerT& values,
00307 const Params& params,
00308 const FluidState& fluidState)
00309 {
00310 typedef typename std::remove_reference<decltype(values[0])>::type Evaluation;
00311
00312 values[waterPhaseIdx] = krw<FluidState, Evaluation>(params, fluidState);
00313 values[oilPhaseIdx] = krn<FluidState, Evaluation>(params, fluidState);
00314 values[gasPhaseIdx] = krg<FluidState, Evaluation>(params, fluidState);
00315 }
00316
00320 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00321 static Evaluation krg(const Params& params,
00322 const FluidState& fluidState)
00323 {
00324 const Evaluation& Sw = 1 - Opm::decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
00325 return GasOilMaterialLaw::twoPhaseSatKrn(params.gasOilParams(), Sw);
00326 }
00327
00331 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00332 static Evaluation krw(const Params& params,
00333 const FluidState& fluidState)
00334 {
00335 const Evaluation& Sw = Opm::decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
00336 return OilWaterMaterialLaw::twoPhaseSatKrw(params.oilWaterParams(), Sw);
00337 }
00338
00342 template <class FluidState, class Evaluation = typename FluidState::Scalar>
00343 static Evaluation krn(const Params& params,
00344 const FluidState& fluidState)
00345 {
00346 Scalar Swco = params.Swl();
00347 const Evaluation& Sw = Opm::decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
00348 const Evaluation& Sg = Opm::decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
00349
00350 Scalar krocw = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Swco);
00351 Evaluation krow = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Sw);
00352 Evaluation krw = OilWaterMaterialLaw::twoPhaseSatKrw(params.oilWaterParams(), Sw);
00353 Evaluation krg = GasOilMaterialLaw::twoPhaseSatKrn(params.gasOilParams(), 1 - Sg);
00354 Evaluation krog = GasOilMaterialLaw::twoPhaseSatKrw(params.gasOilParams(), 1 - Sg);
00355
00356 return krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg);
00357 }
00358
00366 template <class FluidState>
00367 static void updateHysteresis(Params& params, const FluidState& fluidState)
00368 {
00369 Scalar Sw = Opm::scalarValue(fluidState.saturation(waterPhaseIdx));
00370 Scalar Sg = Opm::scalarValue(fluidState.saturation(gasPhaseIdx));
00371
00372 params.oilWaterParams().update(Sw, Sw, Sw);
00373 params.gasOilParams().update(1 - Sg, 1 - Sg, 1 - Sg);
00374 }
00375 };
00376 }
00377
00378 #endif