opm-common
EclTwoPhaseMaterial.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_TWO_PHASE_MATERIAL_HPP
28 #define OPM_ECL_TWO_PHASE_MATERIAL_HPP
29 
31 
32 #include <opm/common/TimingMacros.hpp>
33 #include <opm/common/utility/gpuDecorators.hpp>
34 
37 
38 namespace Opm {
39 
49 template <class TraitsT,
50  class GasOilMaterialLawT,
51  class OilWaterMaterialLawT,
52  class GasWaterMaterialLawT,
53  class ParamsT = EclTwoPhaseMaterialParams<TraitsT,
54  typename GasOilMaterialLawT::Params,
55  typename OilWaterMaterialLawT::Params,
56  typename GasWaterMaterialLawT::Params> >
57 class EclTwoPhaseMaterial : public TraitsT
58 {
59 public:
60  using GasOilMaterialLaw = GasOilMaterialLawT;
61  using OilWaterMaterialLaw = OilWaterMaterialLawT;
62  using GasWaterMaterialLaw = GasWaterMaterialLawT;
63 
64  // some safety checks
65  static_assert(TraitsT::numPhases == 3,
66  "The number of phases considered by this capillary pressure "
67  "law is always three!");
68  static_assert(GasOilMaterialLaw::numPhases == 2,
69  "The number of phases considered by the gas-oil capillary "
70  "pressure law must be two!");
71  static_assert(OilWaterMaterialLaw::numPhases == 2,
72  "The number of phases considered by the oil-water capillary "
73  "pressure law must be two!");
74  static_assert(GasWaterMaterialLaw::numPhases == 2,
75  "The number of phases considered by the gas-water capillary "
76  "pressure law must be two!");
77  static_assert(std::is_same<typename GasOilMaterialLaw::Scalar,
78  typename OilWaterMaterialLaw::Scalar>::value,
79  "The two two-phase capillary pressure laws must use the same "
80  "type of floating point values.");
81 
82  using Traits = TraitsT;
83  using Params = ParamsT;
84  using Scalar = typename Traits::Scalar;
85 
86  static constexpr int numPhases = 3;
87  static constexpr int waterPhaseIdx = Traits::wettingPhaseIdx;
88  static constexpr int oilPhaseIdx = Traits::nonWettingPhaseIdx;
89  static constexpr int gasPhaseIdx = Traits::gasPhaseIdx;
90 
93  static constexpr bool implementsTwoPhaseApi = false;
94 
97  static constexpr bool implementsTwoPhaseSatApi = false;
98 
101  static constexpr bool isSaturationDependent = true;
102 
105  static constexpr bool isPressureDependent = false;
106 
109  static constexpr bool isTemperatureDependent = false;
110 
113  static constexpr bool isCompositionDependent = false;
114 
115  template <class ContainerT, class FluidState>
116  static Scalar relpermOilInOilGasSystem(const Params& /*params*/,
117  const FluidState& /*fluidState*/) {
118  throw std::logic_error {
119  "relpermOilInOilGasSystem() is specific to three phases"
120  };
121  }
122  template <class ContainerT, class FluidState>
123  static Scalar relpermOilInOilWaterSystem(const Params& /*params*/,
124  const FluidState& /*fluidState*/) {
125  throw std::logic_error {
126  "relpermOilInOilWaterSystem() is specific to three phases"
127  };
128  }
129 
145  template <class ContainerT, class FluidState, class ...Args>
146  OPM_HOST_DEVICE static void capillaryPressures(ContainerT& values,
147  const Params& params,
148  const FluidState& fluidState)
149  {
150  OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
151  using Evaluation = typename std::remove_reference<decltype(values[0])>::type;
152 
153  switch (params.approach()) {
154  case EclTwoPhaseApproach::GasOil: {
155  const Evaluation& So =
156  decay<Evaluation>(fluidState.saturation(oilPhaseIdx));
157 
158  values[oilPhaseIdx] = 0.0;
159  values[gasPhaseIdx] = GasOilMaterialLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.gasOilParams(), So);
160  break;
161  }
162 
163  case EclTwoPhaseApproach::OilWater: {
164  const Evaluation& Sw =
165  decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
166 
167  values[waterPhaseIdx] = 0.0;
168  values[oilPhaseIdx] = OilWaterMaterialLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.oilWaterParams(), Sw);
169  break;
170  }
171 
172  case EclTwoPhaseApproach::GasWater: {
173  const Evaluation& Sw =
174  decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
175 
176  values[waterPhaseIdx] = 0.0;
177  values[gasPhaseIdx] = GasWaterMaterialLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.gasWaterParams(), Sw);
178  break;
179  }
180 
181  }
182  }
183 
184  /*
185  * Hysteresis parameters for oil-water
186  * @see EclHysteresisTwoPhaseLawParams::soMax(...)
187  * @see EclHysteresisTwoPhaseLawParams::swMax(...)
188  * @see EclHysteresisTwoPhaseLawParams::swMin(...)
189  * \param params Parameters
190  */
191  static void oilWaterHysteresisParams(Scalar& soMax,
192  Scalar& swMax,
193  Scalar& swMin,
194  const Params& params)
195  {
196  if constexpr (Traits::enableHysteresis) {
197  soMax = 1.0 - params.oilWaterParams().krnSwMdc();
198  swMax = params.oilWaterParams().krwSwMdc();
199  swMin = params.oilWaterParams().pcSwMdc();
200  Valgrind::CheckDefined(soMax);
201  Valgrind::CheckDefined(swMax);
202  Valgrind::CheckDefined(swMin);
203  }
204  }
205 
206  /*
207  * Hysteresis parameters for oil-water
208  * @see EclHysteresisTwoPhaseLawParams::soMax(...)
209  * @see EclHysteresisTwoPhaseLawParams::swMax(...)
210  * @see EclHysteresisTwoPhaseLawParams::swMin(...)
211  * \param params Parameters
212  */
213  static void setOilWaterHysteresisParams(const Scalar& soMax,
214  const Scalar& swMax,
215  const Scalar& swMin,
216  Params& params)
217  {
218  if constexpr (Traits::enableHysteresis) {
219  params.oilWaterParams().update(swMin, swMax, 1.0 - soMax);
220  }
221  }
222 
223 
224  /*
225  * Hysteresis parameters for gas-oil
226  * @see EclHysteresisTwoPhaseLawParams::sgmax(...)
227  * @see EclHysteresisTwoPhaseLawParams::shmax(...)
228  * @see EclHysteresisTwoPhaseLawParams::somin(...)
229  * \param params Parameters
230  */
231  static void gasOilHysteresisParams(Scalar& sgmax,
232  Scalar& shmax,
233  Scalar& somin,
234  const Params& params)
235  {
236  if constexpr (Traits::enableHysteresis) {
237  sgmax = 1.0 - params.gasOilParams().krnSwMdc();
238  shmax = params.gasOilParams().krwSwMdc();
239  somin = params.gasOilParams().pcSwMdc();
240  Valgrind::CheckDefined(sgmax);
241  Valgrind::CheckDefined(shmax);
242  Valgrind::CheckDefined(somin);
243  }
244  }
245 
246  /*
247  * Hysteresis parameters for gas-oil
248  * @see EclHysteresisTwoPhaseLawParams::sgmax(...)
249  * @see EclHysteresisTwoPhaseLawParams::shmax(...)
250  * \param params Parameters
251  */
252  static void setGasOilHysteresisParams(const Scalar& sgmax,
253  const Scalar& shmax,
254  const Scalar& somin,
255  Params& params)
256  {
257  if constexpr (Traits::enableHysteresis) {
258  params.gasOilParams().update(somin , shmax, 1.0 - sgmax);
259  }
260  }
261 
262  static Scalar trappedGasSaturation(const Params& params, bool maximumTrapping){
263  if(params.approach() == EclTwoPhaseApproach::GasOil)
264  return params.gasOilParams().SnTrapped(maximumTrapping);
265  if(params.approach() == EclTwoPhaseApproach::GasWater)
266  return params.gasWaterParams().SnTrapped(maximumTrapping);
267  return 0.0; // oil-water case
268  }
269 
270  static Scalar strandedGasSaturation(const Params& params, Scalar Sg, Scalar Kg){
271  if(params.approach() == EclTwoPhaseApproach::GasOil)
272  return params.gasOilParams().SnStranded(Sg, Kg);
273  if(params.approach() == EclTwoPhaseApproach::GasWater)
274  return params.gasWaterParams().SnStranded(Sg, Kg);
275  return 0.0; // oil-water case
276  }
277 
278  static Scalar trappedOilSaturation(const Params& params, bool maximumTrapping){
279  if(params.approach() == EclTwoPhaseApproach::GasOil)
280  return params.gasOilParams().SwTrapped();
281  if(params.approach() == EclTwoPhaseApproach::OilWater)
282  return params.oilWaterParams().SnTrapped(maximumTrapping);
283  return 0.0; // gas-water case
284  }
285 
286  static Scalar trappedWaterSaturation(const Params& params){
287  if(params.approach() == EclTwoPhaseApproach::GasWater)
288  return params.gasWaterParams().SwTrapped();
289  if(params.approach() == EclTwoPhaseApproach::OilWater)
290  return params.oilWaterParams().SwTrapped();
291  return 0.0; // gas-oil case
292  }
293 
294 
304  template <class FluidState, class Evaluation = typename FluidState::ValueType>
305  static Evaluation pcgn(const Params& /* params */,
306  const FluidState& /* fs */)
307  {
308  throw std::logic_error("Not implemented: pcgn()");
309  }
310 
320  template <class FluidState, class Evaluation = typename FluidState::ValueType>
321  static Evaluation pcnw(const Params& /* params */,
322  const FluidState& /* fs */)
323  {
324  throw std::logic_error("Not implemented: pcnw()");
325  }
326 
330  template <class ContainerT, class FluidState>
331  static void saturations(ContainerT& /* values */,
332  const Params& /* params */,
333  const FluidState& /* fs */)
334  {
335  throw std::logic_error("Not implemented: saturations()");
336  }
337 
341  template <class FluidState, class Evaluation = typename FluidState::ValueType>
342  static Evaluation Sg(const Params& /* params */,
343  const FluidState& /* fluidState */)
344  {
345  throw std::logic_error("Not implemented: Sg()");
346  }
347 
351  template <class FluidState, class Evaluation = typename FluidState::ValueType>
352  static Evaluation Sn(const Params& /* params */,
353  const FluidState& /* fluidState */)
354  {
355  throw std::logic_error("Not implemented: Sn()");
356  }
357 
361  template <class FluidState, class Evaluation = typename FluidState::ValueType>
362  static Evaluation Sw(const Params& /* params */,
363  const FluidState& /* fluidState */)
364  {
365  throw std::logic_error("Not implemented: Sw()");
366  }
367 
383  template <class ContainerT, class FluidState, class ...Args>
384  OPM_HOST_DEVICE static void relativePermeabilities(ContainerT& values,
385  const Params& params,
386  const FluidState& fluidState)
387  {
388  OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
389  using Evaluation = typename std::remove_reference<decltype(values[0])>::type;
390 
391  switch (params.approach()) {
392  case EclTwoPhaseApproach::GasOil: {
393  const Evaluation& So =
394  decay<Evaluation>(fluidState.saturation(oilPhaseIdx));
395 
396  values[oilPhaseIdx] = GasOilMaterialLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.gasOilParams(), So);
397  values[gasPhaseIdx] = GasOilMaterialLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.gasOilParams(), So);
398  break;
399  }
400 
401  case EclTwoPhaseApproach::OilWater: {
402  const Evaluation& sw =
403  decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
404 
405  values[waterPhaseIdx] = OilWaterMaterialLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.oilWaterParams(), sw);
406  values[oilPhaseIdx] = OilWaterMaterialLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.oilWaterParams(), sw);
407  break;
408  }
409 
410  case EclTwoPhaseApproach::GasWater: {
411  const Evaluation& sw =
412  decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
413 
414  values[waterPhaseIdx] = GasWaterMaterialLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.gasWaterParams(), sw);
415  values[gasPhaseIdx] = GasWaterMaterialLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.gasWaterParams(), sw);
416 
417  break;
418  }
419  }
420  }
421 
425  template <class FluidState, class Evaluation = typename FluidState::ValueType>
426  static Evaluation krg(const Params& /* params */,
427  const FluidState& /* fluidState */)
428  {
429  throw std::logic_error("Not implemented: krg()");
430  }
431 
435  template <class FluidState, class Evaluation = typename FluidState::ValueType>
436  static Evaluation krw(const Params& /* params */,
437  const FluidState& /* fluidState */)
438  {
439  throw std::logic_error("Not implemented: krw()");
440  }
441 
445  template <class FluidState, class Evaluation = typename FluidState::ValueType>
446  static Evaluation krn(const Params& /* params */,
447  const FluidState& /* fluidState */)
448  {
449  throw std::logic_error("Not implemented: krn()");
450  }
451 
452 
460  template <class FluidState>
461  static bool updateHysteresis(Params& params, const FluidState& fluidState)
462  {
463  if constexpr (Traits::enableHysteresis) {
464  OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
465  switch (params.approach()) {
466  case EclTwoPhaseApproach::GasOil: {
467  Scalar So = scalarValue(fluidState.saturation(oilPhaseIdx));
468  return params.gasOilParams().update(/*pcSw=*/So, /*krwSw=*/So, /*krnSw=*/So);
469  }
470  case EclTwoPhaseApproach::OilWater: {
471  Scalar sw = scalarValue(fluidState.saturation(waterPhaseIdx));
472  return params.oilWaterParams().update(/*pcSw=*/sw, /*krwSw=*/sw, /*krnSw=*/sw);
473  }
474  case EclTwoPhaseApproach::GasWater: {
475  Scalar sw = scalarValue(fluidState.saturation(waterPhaseIdx));
476  return params.gasWaterParams().update(/*pcSw=*/sw, /*krwSw=*/sw, /*krnSw=*/sw);
477  }
478  }
479  return false;
480  } else {
481  return false;
482  }
483  }
484 };
485 
486 } // namespace Opm
487 
488 #endif
static Evaluation krw(const Params &, const FluidState &)
The relative permeability of the wetting phase.
Definition: EclTwoPhaseMaterial.hpp:436
static constexpr bool isPressureDependent
Specify whether the quantities defined by this material law are dependent on the absolute pressure...
Definition: EclTwoPhaseMaterial.hpp:105
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...
static constexpr bool isCompositionDependent
Specify whether the quantities defined by this material law are dependent on the phase composition...
Definition: EclTwoPhaseMaterial.hpp:113
static Evaluation Sw(const Params &, const FluidState &)
The saturation of the wetting (i.e., water) phase.
Definition: EclTwoPhaseMaterial.hpp:362
static Evaluation Sn(const Params &, const FluidState &)
The saturation of the non-wetting (i.e., oil) phase.
Definition: EclTwoPhaseMaterial.hpp:352
static constexpr bool implementsTwoPhaseSatApi
Specify whether this material law implements the two-phase convenience API which only depends on the ...
Definition: EclTwoPhaseMaterial.hpp:97
static Evaluation krn(const Params &, const FluidState &)
The relative permeability of the non-wetting (i.e., oil) phase.
Definition: EclTwoPhaseMaterial.hpp:446
static constexpr bool isTemperatureDependent
Specify whether the quantities defined by this material law are temperature dependent.
Definition: EclTwoPhaseMaterial.hpp:109
static Evaluation krg(const Params &, const FluidState &)
The relative permeability of the gas phase.
Definition: EclTwoPhaseMaterial.hpp:426
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
static Evaluation pcnw(const Params &, const FluidState &)
Capillary pressure between the non-wetting liquid (i.e., oil) and the wetting liquid (i...
Definition: EclTwoPhaseMaterial.hpp:321
static Evaluation pcgn(const Params &, const FluidState &)
Capillary pressure between the gas and the non-wetting liquid (i.e., oil) phase.
Definition: EclTwoPhaseMaterial.hpp:305
static constexpr bool isSaturationDependent
Specify whether the quantities defined by this material law are saturation dependent.
Definition: EclTwoPhaseMaterial.hpp:101
static void saturations(ContainerT &, const Params &, const FluidState &)
The inverse of the capillary pressure.
Definition: EclTwoPhaseMaterial.hpp:331
static OPM_HOST_DEVICE void capillaryPressures(ContainerT &values, const Params &params, const FluidState &fluidState)
Implements the multiplexer three phase capillary pressure law used by the ECLipse simulator...
Definition: EclTwoPhaseMaterial.hpp:146
static OPM_HOST_DEVICE void relativePermeabilities(ContainerT &values, const Params &params, const FluidState &fluidState)
The relative permeability of all phases.
Definition: EclTwoPhaseMaterial.hpp:384
Some templates to wrap the valgrind client request macros.
static Evaluation Sg(const Params &, const FluidState &)
The saturation of the gas phase.
Definition: EclTwoPhaseMaterial.hpp:342
Implements a multiplexer class that provides ECL saturation functions for twophase simulations...
Definition: EclTwoPhaseMaterial.hpp:57
Implementation for the parameters required by the material law for two-phase simulations.
static bool updateHysteresis(Params &params, const FluidState &fluidState)
Update the hysteresis parameters after a time step.
Definition: EclTwoPhaseMaterial.hpp:461
static constexpr bool implementsTwoPhaseApi
Specify whether this material law implements the two-phase convenience API.
Definition: EclTwoPhaseMaterial.hpp:93