EclStone1Material.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
27 #ifndef OPM_ECL_STONE1_MATERIAL_HPP
28 #define OPM_ECL_STONE1_MATERIAL_HPP
29 
31 
32 #include <opm/common/Valgrind.hpp>
34 
35 #include <opm/common/Exceptions.hpp>
36 #include <opm/common/ErrorMacros.hpp>
37 
38 #include <algorithm>
39 #include <cmath>
40 
41 namespace Opm {
42 
56 template <class TraitsT,
57  class GasOilMaterialLawT,
58  class OilWaterMaterialLawT,
59  class ParamsT = EclStone1MaterialParams<TraitsT, GasOilMaterialLawT, OilWaterMaterialLawT> >
60 class EclStone1Material : public TraitsT
61 {
62 public:
63  typedef GasOilMaterialLawT GasOilMaterialLaw;
64  typedef OilWaterMaterialLawT OilWaterMaterialLaw;
65 
66  // some safety checks
67  static_assert(TraitsT::numPhases == 3,
68  "The number of phases considered by this capillary pressure "
69  "law is always three!");
70  static_assert(GasOilMaterialLaw::numPhases == 2,
71  "The number of phases considered by the gas-oil capillary "
72  "pressure law must be two!");
73  static_assert(OilWaterMaterialLaw::numPhases == 2,
74  "The number of phases considered by the oil-water capillary "
75  "pressure law must be two!");
76  static_assert(std::is_same<typename GasOilMaterialLaw::Scalar,
77  typename OilWaterMaterialLaw::Scalar>::value,
78  "The two two-phase capillary pressure laws must use the same "
79  "type of floating point values.");
80 
81  static_assert(GasOilMaterialLaw::implementsTwoPhaseSatApi,
82  "The gas-oil material law must implement the two-phase saturation "
83  "only API to for the default Ecl capillary pressure law!");
84  static_assert(OilWaterMaterialLaw::implementsTwoPhaseSatApi,
85  "The oil-water material law must implement the two-phase saturation "
86  "only API to for the default Ecl capillary pressure law!");
87 
88  typedef TraitsT Traits;
89  typedef ParamsT Params;
90  typedef typename Traits::Scalar Scalar;
91 
92  static const int numPhases = 3;
93  static const int waterPhaseIdx = Traits::wettingPhaseIdx;
94  static const int oilPhaseIdx = Traits::nonWettingPhaseIdx;
95  static const int gasPhaseIdx = Traits::gasPhaseIdx;
96 
99  static const bool implementsTwoPhaseApi = false;
100 
103  static const bool implementsTwoPhaseSatApi = false;
104 
107  static const bool isSaturationDependent = true;
108 
111  static const bool isPressureDependent = false;
112 
115  static const bool isTemperatureDependent = false;
116 
119  static const bool isCompositionDependent = false;
120 
135  template <class ContainerT, class FluidState>
136  static void capillaryPressures(ContainerT& values,
137  const Params& params,
138  const FluidState& state)
139  {
140  typedef typename std::remove_reference<decltype(values[0])>::type Evaluation;
141  values[gasPhaseIdx] = pcgn<FluidState, Evaluation>(params, state);
142  values[oilPhaseIdx] = 0;
143  values[waterPhaseIdx] = - pcnw<FluidState, Evaluation>(params, state);
144  Valgrind::CheckDefined(values[gasPhaseIdx]);
145  Valgrind::CheckDefined(values[oilPhaseIdx]);
146  Valgrind::CheckDefined(values[waterPhaseIdx]);
147  }
148 
149  /*
150  * Hysteresis parameters for oil-water
151  * @see EclHysteresisTwoPhaseLawParams::pcSwMdc(...)
152  * @see EclHysteresisTwoPhaseLawParams::krnSwMdc(...)
153  * \param params Parameters
154  */
155  static void oilWaterHysteresisParams(Scalar& pcSwMdc,
156  Scalar& krnSwMdc,
157  const Params& params)
158  {
159  pcSwMdc = params.oilWaterParams().pcSwMdc();
160  krnSwMdc = params.oilWaterParams().krnSwMdc();
161 
162  Valgrind::CheckDefined(pcSwMdc);
163  Valgrind::CheckDefined(krnSwMdc);
164  }
165 
166  /*
167  * Hysteresis parameters for oil-water
168  * @see EclHysteresisTwoPhaseLawParams::pcSwMdc(...)
169  * @see EclHysteresisTwoPhaseLawParams::krnSwMdc(...)
170  * \param params Parameters
171  */
172  static void setOilWaterHysteresisParams(const Scalar& pcSwMdc,
173  const Scalar& krnSwMdc,
174  Params& params)
175  {
176  const double krwSw = 2.0; //Should not be used
177  params.oilWaterParams().update(pcSwMdc, krwSw, krnSwMdc);
178  }
179 
180  /*
181  * Hysteresis parameters for gas-oil
182  * @see EclHysteresisTwoPhaseLawParams::pcSwMdc(...)
183  * @see EclHysteresisTwoPhaseLawParams::krnSwMdc(...)
184  * \param params Parameters
185  */
186  static void gasOilHysteresisParams(Scalar& pcSwMdc,
187  Scalar& krnSwMdc,
188  const Params& params)
189  {
190  pcSwMdc = params.gasOilParams().pcSwMdc();
191  krnSwMdc = params.gasOilParams().krnSwMdc();
192 
193  Valgrind::CheckDefined(pcSwMdc);
194  Valgrind::CheckDefined(krnSwMdc);
195  }
196 
197  /*
198  * Hysteresis parameters for gas-oil
199  * @see EclHysteresisTwoPhaseLawParams::pcSwMdc(...)
200  * @see EclHysteresisTwoPhaseLawParams::krnSwMdc(...)
201  * \param params Parameters
202  */
203  static void setGasOilHysteresisParams(const Scalar& pcSwMdc,
204  const Scalar& krnSwMdc,
205  Params& params)
206  {
207  const double krwSw = 2.0; //Should not be used
208  params.gasOilParams().update(pcSwMdc, krwSw, krnSwMdc);
209  }
210 
220  template <class FluidState, class Evaluation = typename FluidState::Scalar>
221  static Evaluation pcgn(const Params& params,
222  const FluidState& fs)
223  {
224  const auto& Sw = 1.0 - Opm::decay<Evaluation>(fs.saturation(gasPhaseIdx));
225  return GasOilMaterialLaw::twoPhaseSatPcnw(params.gasOilParams(), Sw);
226  }
227 
237  template <class FluidState, class Evaluation = typename FluidState::Scalar>
238  static Evaluation pcnw(const Params& params,
239  const FluidState& fs)
240  {
241  const auto& Sw = Opm::decay<Evaluation>(fs.saturation(waterPhaseIdx));
242  Valgrind::CheckDefined(Sw);
243  const auto& result = OilWaterMaterialLaw::twoPhaseSatPcnw(params.oilWaterParams(), Sw);
244  Valgrind::CheckDefined(result);
245  return result;
246  }
247 
251  template <class ContainerT, class FluidState>
252  static void saturations(ContainerT& /* values */,
253  const Params& /* params */,
254  const FluidState& /* fluidState */)
255  {
256  OPM_THROW(std::logic_error, "Not implemented: saturations()");
257  }
258 
262  template <class FluidState, class Evaluation = typename FluidState::Scalar>
263  static Evaluation Sg(const Params& /* params */,
264  const FluidState& /* fluidState */)
265  {
266  OPM_THROW(std::logic_error, "Not implemented: Sg()");
267  }
268 
272  template <class FluidState, class Evaluation = typename FluidState::Scalar>
273  static Evaluation Sn(const Params& /* params */,
274  const FluidState& /* fluidState */)
275  {
276  OPM_THROW(std::logic_error, "Not implemented: Sn()");
277  }
278 
282  template <class FluidState, class Evaluation = typename FluidState::Scalar>
283  static Evaluation Sw(const Params& /* params */,
284  const FluidState& /* fluidState */)
285  {
286  OPM_THROW(std::logic_error, "Not implemented: Sw()");
287  }
288 
304  template <class ContainerT, class FluidState>
305  static void relativePermeabilities(ContainerT& values,
306  const Params& params,
307  const FluidState& fluidState)
308  {
309  typedef typename std::remove_reference<decltype(values[0])>::type Evaluation;
310 
311  values[waterPhaseIdx] = krw<FluidState, Evaluation>(params, fluidState);
312  values[oilPhaseIdx] = krn<FluidState, Evaluation>(params, fluidState);
313  values[gasPhaseIdx] = krg<FluidState, Evaluation>(params, fluidState);
314  }
315 
319  template <class FluidState, class Evaluation = typename FluidState::Scalar>
320  static Evaluation krg(const Params& params,
321  const FluidState& fluidState)
322  {
323  const Evaluation& Sw = 1 - Opm::decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
324  return GasOilMaterialLaw::twoPhaseSatKrn(params.gasOilParams(), Sw);
325  }
326 
330  template <class FluidState, class Evaluation = typename FluidState::Scalar>
331  static Evaluation krw(const Params& params,
332  const FluidState& fluidState)
333  {
334  const Evaluation& Sw = Opm::decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
335  return OilWaterMaterialLaw::twoPhaseSatKrw(params.oilWaterParams(), Sw);
336  }
337 
341  template <class FluidState, class Evaluation = typename FluidState::Scalar>
342  static Evaluation krn(const Params& params,
343  const FluidState& fluidState)
344  {
345  // the Eclipse docu is inconsistent with naming the variable of connate water: In
346  // some places the connate water saturation is represented by "Swl", in others
347  // "Swco" is used.
348  Scalar Swco = params.Swl();
349 
350  // oil relperm at connate water saturations (with Sg=0)
351  Scalar krocw = params.krocw();
352 
353  const Evaluation& Sw = Opm::decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
354  const Evaluation& Sg = Opm::decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
355 
356  Evaluation kro_ow = OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), Sw);
357  Evaluation kro_go = GasOilMaterialLaw::twoPhaseSatKrw(params.gasOilParams(), 1 - Sg - Swco);
358 
359  Evaluation beta;
360  if (Sw <= Swco)
361  beta = 1.0;
362  else {
363  // there seems to be an error in the ECL documentation: using the approach to
364  // the scaled saturations as described there leads to significant deviations
365  // from the results produced by Eclipse 100.
366  Evaluation SSw = (Sw - Swco)/(1.0 - Swco);
367  Evaluation SSg = Sg/(1.0 - Swco);
368  Evaluation SSo = 1.0 - SSw - SSg;
369 
370  if (SSw >= 1.0 || SSg >= 1.0)
371  beta = 1.0;
372  else
373  beta = Opm::pow( SSo/((1 - SSw)*(1 - SSg)), params.eta());
374  }
375 
376  return Opm::max(0.0, Opm::min(1.0, beta*kro_ow*kro_go/krocw));
377  }
378 
386  template <class FluidState>
387  static void updateHysteresis(Params& params, const FluidState& fluidState)
388  {
389  Scalar Sw = Opm::scalarValue(fluidState.saturation(waterPhaseIdx));
390  Scalar Sg = Opm::scalarValue(fluidState.saturation(gasPhaseIdx));
391 
392  params.oilWaterParams().update(/*pcSw=*/Sw, /*krwSw=*/Sw, /*krnSw=*/Sw);
393  params.gasOilParams().update(/*pcSw=*/1 - Sg, /*krwSw=*/1 - Sg, /*krnSw=*/1 - Sg);
394  }
395 };
396 } // namespace Opm
397 
398 #endif
static void saturations(ContainerT &, const Params &, const FluidState &)
The inverse of the capillary pressure.
Definition: EclStone1Material.hpp:252
Default implementation for the parameters required by the three-phase capillary pressure/relperm Ston...
static Evaluation Sg(const Params &, const FluidState &)
The saturation of the gas phase.
Definition: EclStone1Material.hpp:263
static Evaluation Sn(const Params &, const FluidState &)
The saturation of the non-wetting (i.e., oil) phase.
Definition: EclStone1Material.hpp:273
static Evaluation pcnw(const Params &params, const FluidState &fs)
Capillary pressure between the non-wetting liquid (i.e., oil) and the wetting liquid (i...
Definition: EclStone1Material.hpp:238
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...
static const bool implementsTwoPhaseSatApi
Specify whether this material law implements the two-phase convenience API which only depends on the ...
Definition: EclStone1Material.hpp:103
static Evaluation Sw(const Params &, const FluidState &)
The saturation of the wetting (i.e., water) phase.
Definition: EclStone1Material.hpp:283
static Evaluation krg(const Params &params, const FluidState &fluidState)
The relative permeability of the gas phase.
Definition: EclStone1Material.hpp:320
Definition: Air_Mesitylene.hpp:33
static void relativePermeabilities(ContainerT &values, const Params &params, const FluidState &fluidState)
The relative permeability of all phases.
Definition: EclStone1Material.hpp:305
static void updateHysteresis(Params &params, const FluidState &fluidState)
Update the hysteresis parameters after a time step.
Definition: EclStone1Material.hpp:387
static void capillaryPressures(ContainerT &values, const Params &params, const FluidState &state)
Implements the default three phase capillary pressure law used by the ECLipse simulator.
Definition: EclStone1Material.hpp:136
Implements the second phase capillary pressure/relperm law suggested by Stone as used by the ECLipse ...
Definition: EclStone1Material.hpp:60
static const bool isPressureDependent
Specify whether the quantities defined by this material law are dependent on the absolute pressure...
Definition: EclStone1Material.hpp:111
static const bool implementsTwoPhaseApi
Specify whether this material law implements the two-phase convenience API.
Definition: EclStone1Material.hpp:99
static Evaluation krw(const Params &params, const FluidState &fluidState)
The relative permeability of the wetting phase.
Definition: EclStone1Material.hpp:331
static const bool isCompositionDependent
Specify whether the quantities defined by this material law are dependent on the phase composition...
Definition: EclStone1Material.hpp:119
static Evaluation krn(const Params &params, const FluidState &fluidState)
The relative permeability of the non-wetting (i.e., oil) phase.
Definition: EclStone1Material.hpp:342
static const bool isSaturationDependent
Specify whether the quantities defined by this material law are saturation dependent.
Definition: EclStone1Material.hpp:107
static const bool isTemperatureDependent
Specify whether the quantities defined by this material law are temperature dependent.
Definition: EclStone1Material.hpp:115
static Evaluation pcgn(const Params &params, const FluidState &fs)
Capillary pressure between the gas and the non-wetting liquid (i.e., oil) phase.
Definition: EclStone1Material.hpp:221