opm-common
Loading...
Searching...
No Matches
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/TimingMacros.hpp>
35
36#include <algorithm>
37#include <cmath>
38#include <stdexcept>
39#include <type_traits>
40
41namespace Opm {
42
56template <class TraitsT,
57 class GasOilMaterialLawT,
58 class OilWaterMaterialLawT,
60class EclStone1Material : public TraitsT
61{
62public:
63 using GasOilMaterialLaw = GasOilMaterialLawT;
64 using OilWaterMaterialLaw = OilWaterMaterialLawT;
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 using Traits = TraitsT;
89 using Params = ParamsT;
90 using Scalar = typename Traits::Scalar;
91
92 static constexpr int numPhases = 3;
93 static constexpr int waterPhaseIdx = Traits::wettingPhaseIdx;
94 static constexpr int oilPhaseIdx = Traits::nonWettingPhaseIdx;
95 static constexpr int gasPhaseIdx = Traits::gasPhaseIdx;
96
99 static constexpr bool implementsTwoPhaseApi = false;
100
103 static constexpr bool implementsTwoPhaseSatApi = false;
104
107 static constexpr bool isSaturationDependent = true;
108
111 static constexpr bool isPressureDependent = false;
112
115 static constexpr bool isTemperatureDependent = false;
116
119 static constexpr bool isCompositionDependent = false;
120
135 template <class ContainerT, class FluidState, class ...Args>
136 static void capillaryPressures(ContainerT& values,
137 const Params& params,
138 const FluidState& state)
139 {
140 using Evaluation = typename std::remove_reference<decltype(values[0])>::type;
141 values[gasPhaseIdx] = pcgn<FluidState, Evaluation, Args...>(params, state);
142 values[oilPhaseIdx] = 0;
143 values[waterPhaseIdx] = - pcnw<FluidState, Evaluation, Args...>(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::soMax(...)
152 * @see EclHysteresisTwoPhaseLawParams::swMax(...)
153 * @see EclHysteresisTwoPhaseLawParams::swMin(...)
154 * \param params Parameters
155 */
156 static void oilWaterHysteresisParams(Scalar& soMax,
157 Scalar& swMax,
158 Scalar& swMin,
159 const Params& params)
160 {
161 if constexpr (Traits::enableHysteresis) {
162 soMax = 1.0 - params.oilWaterParams().krnSwMdc();
163 swMax = params.oilWaterParams().krwSwMdc();
164 swMin = params.oilWaterParams().pcSwMdc();
168 }
169 }
170
171 /*
172 * Hysteresis parameters for oil-water
173 * @see EclHysteresisTwoPhaseLawParams::soMax(...)
174 * @see EclHysteresisTwoPhaseLawParams::swMax(...)
175 * @see EclHysteresisTwoPhaseLawParams::swMin(...)
176 * \param params Parameters
177 */
178 static void setOilWaterHysteresisParams(const Scalar& soMax,
179 const Scalar& swMax,
180 const Scalar& swMin,
181 Params& params)
182 {
183 if constexpr (Traits::enableHysteresis) {
184 params.oilWaterParams().update(swMin, swMax, 1.0 - soMax);
185 }
186 }
187
188 /*
189 * Hysteresis parameters for gas-oil
190 * @see EclHysteresisTwoPhaseLawParams::sgMax(...)
191 * @see EclHysteresisTwoPhaseLawParams::shMax(...)
192 * @see EclHysteresisTwoPhaseLawParams::soMin(...)
193 * \param params Parameters
194 */
195 static void gasOilHysteresisParams(Scalar& sgMax,
196 Scalar& shMax,
197 Scalar& soMin,
198 const Params& params)
199 {
200 if constexpr (Traits::enableHysteresis) {
201 const auto Swco = params.Swl();
202 sgMax = 1.0 - params.gasOilParams().krnSwMdc() - Swco;
203 shMax = params.gasOilParams().krwSwMdc();
204 soMin = params.gasOilParams().pcSwMdc();
205 Valgrind::CheckDefined(sgMax);
206 Valgrind::CheckDefined(shMax);
207 Valgrind::CheckDefined(soMin);
208 }
209 }
210
211 /*
212 * Hysteresis parameters for gas-oil
213 * @see EclHysteresisTwoPhaseLawParams::sgMax(...)
214 * @see EclHysteresisTwoPhaseLawParams::shMax(...)
215 * @see EclHysteresisTwoPhaseLawParams::soMin(...)
216 * \param params Parameters
217 */
218 static void setGasOilHysteresisParams(const Scalar& sgMax,
219 const Scalar& shMax,
220 const Scalar& soMin,
221 Params& params)
222 {
223 if constexpr (Traits::enableHysteresis) {
224 const auto Swco = params.Swl();
225 params.gasOilParams().update(soMin, shMax, 1.0 - sgMax - Swco);
226 }
227 }
228
229 static Scalar trappedGasSaturation(const Params& params, bool maximumTrapping)
230 {
231 const auto Swco = params.Swl();
232 return params.gasOilParams().SnTrapped(maximumTrapping) - Swco;
233 }
234
235 static Scalar trappedOilSaturation(const Params& params, bool maximumTrapping)
236 {
237 return params.oilWaterParams().SnTrapped(maximumTrapping) + params.gasOilParams().SwTrapped();
238 }
239
240 static Scalar trappedWaterSaturation(const Params& params)
241 {
242 return params.oilWaterParams().SwTrapped();
243 }
244
245 static Scalar strandedGasSaturation(const Params& params, Scalar Sg, Scalar Kg)
246 {
247 const auto Swco = params.Swl();
248 return params.gasOilParams().SnStranded(Sg, Kg) - Swco;
249 }
259 template <class FluidState, class Evaluation, class ...Args>
260 static Evaluation pcgn(const Params& params,
261 const FluidState& fs)
262 {
263 // Maximum attainable oil saturation is 1-SWL
264 const auto Sw = 1.0 - params.Swl() - decay<Evaluation>(fs.saturation(gasPhaseIdx));
265 return GasOilMaterialLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.gasOilParams(), Sw);
266 }
267
277 template <class FluidState, class Evaluation, class ...Args>
278 static Evaluation pcnw(const Params& params,
279 const FluidState& fs)
280 {
281 const auto Sw = decay<Evaluation>(fs.saturation(waterPhaseIdx));
283
284 const auto result = OilWaterMaterialLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.oilWaterParams(), Sw);
286
287 return result;
288 }
289
293 template <class ContainerT, class FluidState>
294 static void saturations(ContainerT& /* values */,
295 const Params& /* params */,
296 const FluidState& /* fluidState */)
297 {
298 throw std::logic_error("Not implemented: saturations()");
299 }
300
304 template <class FluidState, class Evaluation = typename FluidState::ValueType>
305 static Evaluation Sg(const Params& /* params */,
306 const FluidState& /* fluidState */)
307 {
308 throw std::logic_error("Not implemented: Sg()");
309 }
310
314 template <class FluidState, class Evaluation = typename FluidState::ValueType>
315 static Evaluation Sn(const Params& /* params */,
316 const FluidState& /* fluidState */)
317 {
318 throw std::logic_error("Not implemented: Sn()");
319 }
320
324 template <class FluidState, class Evaluation = typename FluidState::ValueType>
325 static Evaluation Sw(const Params& /* params */,
326 const FluidState& /* fluidState */)
327 {
328 throw std::logic_error("Not implemented: Sw()");
329 }
330
346 template <class ContainerT, class FluidState, class ...Args>
347 static void relativePermeabilities(ContainerT& values,
348 const Params& params,
349 const FluidState& fluidState)
350 {
351 using Evaluation = typename std::remove_reference<decltype(values[0])>::type;
352
353 values[waterPhaseIdx] = krw<FluidState, Evaluation, Args...>(params, fluidState);
354 values[oilPhaseIdx] = krn<FluidState, Evaluation, Args...>(params, fluidState);
355 values[gasPhaseIdx] = krg<FluidState, Evaluation, Args...>(params, fluidState);
356 }
357
361 template <class FluidState, class Evaluation, class ...Args>
362 static Evaluation krg(const Params& params,
363 const FluidState& fluidState)
364 {
365 // Maximum attainable oil saturation is 1-SWL,
366 const Evaluation sw = 1 - params.Swl() - decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
367 return GasOilMaterialLaw::twoPhaseSatKrn(params.gasOilParams(), sw);
368 }
369
373 template <class FluidState, class Evaluation, class ...Args>
374 static Evaluation krw(const Params& params,
375 const FluidState& fluidState)
376 {
377 const Evaluation sw = decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
378 return OilWaterMaterialLaw::twoPhaseSatKrw(params.oilWaterParams(), sw);
379 }
380
384 template <class FluidState, class Evaluation, class ...Args>
385 static Evaluation krn(const Params& params,
386 const FluidState& fluidState)
387 {
388 // the Eclipse docu is inconsistent with naming the variable of connate water: In
389 // some places the connate water saturation is represented by "Swl", in others
390 // "Swco" is used.
391 const Scalar Swco = params.Swl();
392
393 // oil relperm at connate water saturations (with Sg=0)
394 const Scalar krocw = params.krocw();
395
396 const Evaluation sw = decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
397 const Evaluation sg = decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
398
399 const Evaluation kro_ow = relpermOilInOilWaterSystem<Evaluation, FluidState, Args...>(params, fluidState);
400 const Evaluation kro_go = relpermOilInOilGasSystem<Evaluation, FluidState, Args...>(params, fluidState);
401
402 Evaluation beta;
403 if (sw <= Swco) {
404 beta = 1.0;
405 } else {
406 // there seems to be an error in the ECL documentation: using the approach to
407 // the scaled saturations as described there leads to significant deviations
408 // from the results produced by Eclipse 100.
409 const Evaluation SSw = (sw - Swco) / (1.0 - Swco);
410 const Evaluation SSg = sg / (1.0 - Swco);
411 const Evaluation SSo = 1.0 - SSw - SSg;
412
413 if (SSw >= 1.0 || SSg >= 1.0)
414 beta = 1.0;
415 else
416 beta = pow( SSo/((1 - SSw)*(1 - SSg)), params.eta());
417 }
418
419 return max(0.0, min(1.0, beta*kro_ow*kro_go/krocw));
420 }
421
425 template <class Evaluation, class FluidState, class ...Args>
426 static Evaluation relpermOilInOilGasSystem(const Params& params,
427 const FluidState& fluidState)
428 {
429 const Evaluation sg = decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
430 return GasOilMaterialLaw::twoPhaseSatKrw(params.gasOilParams(), 1 - sg - params.Swl());
431 }
432
436 template <class Evaluation, class FluidState, class ...Args>
437 static Evaluation relpermOilInOilWaterSystem(const Params& params,
438 const FluidState& fluidState)
439 {
440 const Evaluation sw = decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
441 return OilWaterMaterialLaw::twoPhaseSatKrn(params.oilWaterParams(), sw);
442 }
443
451 template <class FluidState>
452 static bool updateHysteresis(Params& params, const FluidState& fluidState)
453 {
454 if constexpr (Traits::enableHysteresis) {
455 const Scalar Swco = params.Swl();
456 const Scalar sw = clampSaturation(fluidState, waterPhaseIdx);
457 const Scalar So = clampSaturation(fluidState, oilPhaseIdx);
458 const Scalar sg = clampSaturation(fluidState, gasPhaseIdx);
459 bool owChanged = params.oilWaterParams().update(/*pcSw=*/sw, /*krwSw=*/sw, /*krnSw=*/1 - So);
460 bool gochanged = params.gasOilParams().update(/*pcSw=*/So,
461 /*krwSw=*/So,
462 /*krnSw=*/1.0 - Swco - sg);
463 return owChanged || gochanged;
464 } else {
465 return false;
466 }
467 }
468
469 template <class FluidState>
470 static Scalar clampSaturation(const FluidState& fluidState, const int phaseIndex)
471 {
472 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
473 const auto sat = scalarValue(fluidState.saturation(phaseIndex));
474 return std::clamp(sat, Scalar{0.0}, Scalar{1.0});
475 }
476};
477
478} // namespace Opm
479
480#endif
Default implementation for the parameters required by the three-phase capillary pressure/relperm Ston...
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...
Some templates to wrap the valgrind client request macros.
OPM_HOST_DEVICE bool CheckDefined(const T &value)
Make valgrind complain if any of the memory occupied by an object is undefined.
Definition Valgrind.hpp:76
Default implementation for the parameters required by the three-phase capillary pressure/relperm Ston...
Definition EclStone1MaterialParams.hpp:46
const GasOilParams & gasOilParams() const
The parameter object for the gas-oil twophase law.
Definition EclStone1MaterialParams.hpp:74
Scalar Swl() const
Return the saturation of "connate" water.
Definition EclStone1MaterialParams.hpp:124
Scalar eta() const
Return the exponent of the extended Stone 1 model.
Definition EclStone1MaterialParams.hpp:143
Scalar krocw() const
Return the oil relperm for the oil-water system at the connate water saturation.
Definition EclStone1MaterialParams.hpp:131
const OilWaterParams & oilWaterParams() const
The parameter object for the oil-water twophase law.
Definition EclStone1MaterialParams.hpp:92
Implements the second phase capillary pressure/relperm law suggested by Stone as used by the ECLipse ...
Definition EclStone1Material.hpp:61
static constexpr bool isSaturationDependent
Definition EclStone1Material.hpp:107
static constexpr bool implementsTwoPhaseSatApi
Definition EclStone1Material.hpp:103
static constexpr bool isCompositionDependent
Definition EclStone1Material.hpp:119
static Evaluation pcgn(const Params &params, const FluidState &fs)
Definition EclStone1Material.hpp:260
static void relativePermeabilities(ContainerT &values, const Params &params, const FluidState &fluidState)
The relative permeability of all phases.
Definition EclStone1Material.hpp:347
static Evaluation relpermOilInOilGasSystem(const Params &params, const FluidState &fluidState)
Definition EclStone1Material.hpp:426
static Evaluation relpermOilInOilWaterSystem(const Params &params, const FluidState &fluidState)
Definition EclStone1Material.hpp:437
static void saturations(ContainerT &, const Params &, const FluidState &)
The inverse of the capillary pressure.
Definition EclStone1Material.hpp:294
static constexpr bool isTemperatureDependent
Definition EclStone1Material.hpp:115
static Evaluation krw(const Params &params, const FluidState &fluidState)
Definition EclStone1Material.hpp:374
static Evaluation krg(const Params &params, const FluidState &fluidState)
Definition EclStone1Material.hpp:362
static Evaluation Sg(const Params &, const FluidState &)
The saturation of the gas phase.
Definition EclStone1Material.hpp:305
static constexpr bool implementsTwoPhaseApi
Definition EclStone1Material.hpp:99
static Evaluation Sw(const Params &, const FluidState &)
Definition EclStone1Material.hpp:325
static constexpr bool isPressureDependent
Definition EclStone1Material.hpp:111
static bool updateHysteresis(Params &params, const FluidState &fluidState)
Update the hysteresis parameters after a time step.
Definition EclStone1Material.hpp:452
static Evaluation krn(const Params &params, const FluidState &fluidState)
Definition EclStone1Material.hpp:385
static Evaluation pcnw(const Params &params, const FluidState &fs)
Definition EclStone1Material.hpp:278
static Evaluation Sn(const Params &, const FluidState &)
The saturation of the non-wetting (i.e., oil) phase.
Definition EclStone1Material.hpp:315
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
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30