opm-common
Loading...
Searching...
No Matches
EclDefaultMaterial.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_DEFAULT_MATERIAL_HPP
28#define OPM_ECL_DEFAULT_MATERIAL_HPP
29
30#include <opm/common/TimingMacros.hpp>
31
35
36#include <algorithm>
37#include <stdexcept>
38#include <type_traits>
39
40namespace Opm {
41
55template <class TraitsT,
56 class GasOilMaterialLawT,
57 class OilWaterMaterialLawT,
58 class ParamsT = EclDefaultMaterialParams<TraitsT,
59 typename GasOilMaterialLawT::Params,
60 typename OilWaterMaterialLawT::Params> >
61class EclDefaultMaterial : public TraitsT
62{
63public:
64 using GasOilMaterialLaw = GasOilMaterialLawT;
65 using OilWaterMaterialLaw = OilWaterMaterialLawT;
66
67 // some safety checks
68 static_assert(TraitsT::numPhases == 3,
69 "The number of phases considered by this capillary pressure "
70 "law is always three!");
71 static_assert(GasOilMaterialLaw::numPhases == 2,
72 "The number of phases considered by the gas-oil capillary "
73 "pressure law must be two!");
74 static_assert(OilWaterMaterialLaw::numPhases == 2,
75 "The number of phases considered by the oil-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 static_assert(GasOilMaterialLaw::implementsTwoPhaseSatApi,
83 "The gas-oil material law must implement the two-phase saturation "
84 "only API to for the default Ecl capillary pressure law!");
85 static_assert(OilWaterMaterialLaw::implementsTwoPhaseSatApi,
86 "The oil-water material law must implement the two-phase saturation "
87 "only API to for the default Ecl capillary pressure law!");
88
89 using Traits = TraitsT;
90 using Params = ParamsT;
91 using Scalar = typename Traits::Scalar;
92
93 static constexpr int numPhases = 3;
94 static constexpr int waterPhaseIdx = Traits::wettingPhaseIdx;
95 static constexpr int oilPhaseIdx = Traits::nonWettingPhaseIdx;
96 static constexpr int gasPhaseIdx = Traits::gasPhaseIdx;
97
100 static constexpr bool implementsTwoPhaseApi = false;
101
104 static constexpr bool implementsTwoPhaseSatApi = false;
105
108 static constexpr bool isSaturationDependent = true;
109
112 static constexpr bool isPressureDependent = false;
113
116 static constexpr bool isTemperatureDependent = false;
117
120 static constexpr bool isCompositionDependent = false;
121
136 template <class ContainerT, class FluidState, class ...Args>
137 static void capillaryPressures(ContainerT& values,
138 const Params& params,
139 const FluidState& state)
140 {
141 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
142 using Evaluation = typename std::remove_reference<decltype(values[0])>::type;
143 values[gasPhaseIdx] = pcgn<FluidState, Evaluation, Args...>(params, state);
144 values[oilPhaseIdx] = 0;
145 values[waterPhaseIdx] = - pcnw<FluidState, Evaluation, Args...>(params, state);
146
147 Valgrind::CheckDefined(values[gasPhaseIdx]);
148 Valgrind::CheckDefined(values[oilPhaseIdx]);
149 Valgrind::CheckDefined(values[waterPhaseIdx]);
150 }
151
152 /*
153 * Hysteresis parameters for oil-water
154 * @see EclHysteresisTwoPhaseLawParams::soMax(...)
155 * @see EclHysteresisTwoPhaseLawParams::swMax(...)
156 * @see EclHysteresisTwoPhaseLawParams::swMin(...)
157 * \param params Parameters
158 */
159 static void oilWaterHysteresisParams(Scalar& soMax,
160 Scalar& swMax,
161 Scalar& swMin,
162 const Params& params)
163 {
164 if constexpr (Traits::enableHysteresis) {
165 soMax = 1.0 - params.oilWaterParams().krnSwMdc();
166 swMax = params.oilWaterParams().krwSwMdc();
167 swMin = params.oilWaterParams().pcSwMdc();
168 Valgrind::CheckDefined(soMax);
169 Valgrind::CheckDefined(swMax);
170 Valgrind::CheckDefined(swMin);
171 }
172 }
173
174 /*
175 * Hysteresis parameters for oil-water
176 * @see EclHysteresisTwoPhaseLawParams::soMax(...)
177 * @see EclHysteresisTwoPhaseLawParams::swMax(...)
178 * @see EclHysteresisTwoPhaseLawParams::swMin(...)
179 * \param params Parameters
180 */
181 static void setOilWaterHysteresisParams(const Scalar& soMax,
182 const Scalar& swMax,
183 const Scalar& swMin,
184 Params& params)
185 {
186 if constexpr (Traits::enableHysteresis) {
187 params.oilWaterParams().update(swMin, swMax, 1.0 - soMax);
188 }
189 }
190
191 /*
192 * Hysteresis parameters for gas-oil
193 * @see EclHysteresisTwoPhaseLawParams::sgMax(...)
194 * @see EclHysteresisTwoPhaseLawParams::shMax(...)
195 * @see EclHysteresisTwoPhaseLawParams::soMin(...)
196 * \param params Parameters
197 */
198 static void gasOilHysteresisParams(Scalar& sgMax,
199 Scalar& shMax,
200 Scalar& soMin,
201 const Params& params)
202 {
203 if constexpr (Traits::enableHysteresis) {
204 const auto Swco = params.Swl();
205 sgMax = 1.0 - params.gasOilParams().krnSwMdc() - Swco;
206 shMax = params.gasOilParams().krwSwMdc();
207 soMin = params.gasOilParams().pcSwMdc();
208 Valgrind::CheckDefined(sgMax);
209 Valgrind::CheckDefined(shMax);
210 Valgrind::CheckDefined(soMin);
211 }
212 }
213
214 /*
215 * Hysteresis parameters for gas-oil
216 * @see EclHysteresisTwoPhaseLawParams::sgMax(...)
217 * @see EclHysteresisTwoPhaseLawParams::shMax(...)
218 * @see EclHysteresisTwoPhaseLawParams::soMin(...)
219 * \param params Parameters
220 */
221 static void setGasOilHysteresisParams(const Scalar& sgMax,
222 const Scalar& shMax,
223 const Scalar& soMin,
224 Params& params)
225 {
226 if constexpr (Traits::enableHysteresis) {
227 const auto Swco = params.Swl();
228 params.gasOilParams().update(soMin, shMax, 1.0 - sgMax - Swco);
229 }
230 }
231
232 static Scalar trappedGasSaturation(const Params& params, bool maximumTrapping)
233 {
234 const auto Swco = params.Swl();
235 return params.gasOilParams().SnTrapped(maximumTrapping) - Swco;
236 }
237
238 static Scalar trappedOilSaturation(const Params& params, bool maximumTrapping)
239 {
240 return params.oilWaterParams().SnTrapped(maximumTrapping) + params.gasOilParams().SwTrapped();
241 }
242
243 static Scalar trappedWaterSaturation(const Params& params)
244 {
245 return params.oilWaterParams().SwTrapped();
246 }
247
248 static Scalar strandedGasSaturation(const Params& params, Scalar Sg, Scalar Kg)
249 {
250 const auto Swco = params.Swl();
251 return params.gasOilParams().SnStranded(Sg, Kg) - Swco;
252 }
253
263 template <class FluidState, class Evaluation, class ...Args>
264 static Evaluation pcgn(const Params& params,
265 const FluidState& fs)
266 {
267 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
268 // Maximum attainable oil saturation is 1-SWL.
269 const auto Sw = 1.0 - params.Swl() - decay<Evaluation>(fs.saturation(gasPhaseIdx));
270 return GasOilMaterialLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.gasOilParams(), Sw);
271 }
272
282 template <class FluidState, class Evaluation, class ...Args>
283 static Evaluation pcnw(const Params& params,
284 const FluidState& fs)
285 {
286 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
287 const auto Sw = decay<Evaluation>(fs.saturation(waterPhaseIdx));
288 return OilWaterMaterialLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.oilWaterParams(), Sw);
289 }
290
294 template <class ContainerT, class FluidState>
295 static void saturations(ContainerT& /*values*/,
296 const Params& /*params*/,
297 const FluidState& /*fluidState*/)
298 {
299 throw std::logic_error("Not implemented: saturations()");
300 }
301
305 template <class FluidState, class Evaluation = typename FluidState::Scalar>
306 static Evaluation Sg(const Params& /*params*/,
307 const FluidState& /*fluidState*/)
308 {
309 throw std::logic_error("Not implemented: Sg()");
310 }
311
315 template <class FluidState, class Evaluation = typename FluidState::Scalar>
316 static Evaluation Sn(const Params& /*params*/,
317 const FluidState& /*fluidState*/)
318 {
319 throw std::logic_error("Not implemented: Sn()");
320 }
321
325 template <class FluidState, class Evaluation = typename FluidState::Scalar>
326 static Evaluation Sw(const Params& /*params*/,
327 const FluidState& /*fluidState*/)
328 {
329 throw std::logic_error("Not implemented: Sw()");
330 }
331
347 template <class ContainerT, class FluidState, class ...Args>
348 static void relativePermeabilities(ContainerT& values,
349 const Params& params,
350 const FluidState& fluidState)
351 {
352 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
353 using Evaluation = typename std::remove_reference<decltype(values[0])>::type;
354
355 values[waterPhaseIdx] = krw<FluidState, Evaluation, Args...>(params, fluidState);
356 values[oilPhaseIdx] = krn<FluidState, Evaluation, Args...>(params, fluidState);
357 values[gasPhaseIdx] = krg<FluidState, Evaluation, Args...>(params, fluidState);
358 }
359
363 template <class FluidState, class Evaluation, class ...Args>
364 static Evaluation krg(const Params& params,
365 const FluidState& fluidState)
366 {
367 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
368 // Maximum attainable oil saturation is 1-SWL.
369 const Evaluation sw = 1.0 - params.Swl() - decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
370 return GasOilMaterialLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.gasOilParams(), sw);
371 }
372
376 template <class FluidState, class Evaluation, class ...Args>
377 static Evaluation krw(const Params& params,
378 const FluidState& fluidState)
379 {
380 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
381 const Evaluation sw = decay<Evaluation>(fluidState.saturation(waterPhaseIdx));
382 return OilWaterMaterialLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.oilWaterParams(), sw);
383 }
384
388 template <class FluidState, class Evaluation, class ...Args>
389 static Evaluation krn(const Params& params,
390 const FluidState& fluidState)
391 {
392 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
393 const Scalar Swco = params.Swl();
394
395 const Evaluation sw =
396 max(Evaluation(Swco),
397 decay<Evaluation>(fluidState.saturation(waterPhaseIdx)));
398
399 const Evaluation sg = decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
400
401 const Evaluation Sw_ow = sg + sw;
402 const Evaluation kro_ow = relpermOilInOilWaterSystem<Evaluation, FluidState, Args...>(params, fluidState);
403 const Evaluation kro_go = relpermOilInOilGasSystem<Evaluation, FluidState, Args...>(params, fluidState);
404
405 // avoid the division by zero: chose a regularized kro which is used if Sw - Swco
406 // < epsilon/2 and interpolate between the oridinary and the regularized kro between
407 // epsilon and epsilon/2
408 constexpr const Scalar epsilon = 1e-5;
409 if (scalarValue(Sw_ow) - Swco < epsilon) {
410 const Evaluation kro2 = (kro_ow + kro_go)/2;
411 if (scalarValue(Sw_ow) - Swco > epsilon/2) {
412 const Evaluation kro1 = (sg * kro_go + (sw - Swco) * kro_ow) / (Sw_ow - Swco);
413 const Evaluation alpha = (epsilon - (Sw_ow - Swco)) / (epsilon / 2);
414
415 return kro2 * alpha + kro1 * (1 - alpha);
416 }
417
418 return kro2;
419 }
420
421 return (sg * kro_go + (sw - Swco) * kro_ow) / (Sw_ow - Swco);
422 }
423
427 template <class Evaluation, class FluidState, class ...Args>
428 static Evaluation relpermOilInOilGasSystem(const Params& params,
429 const FluidState& fluidState)
430 {
431 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
432 const Evaluation sw =
433 max(Evaluation{ params.Swl() },
434 decay<Evaluation>(fluidState.saturation(waterPhaseIdx)));
435
436 const Evaluation sg = decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
437 const Evaluation So_go = 1.0 - (sg + sw);
438
439 return GasOilMaterialLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.gasOilParams(), So_go);
440 }
441
445 template <class Evaluation, class FluidState, class ...Args>
446 static Evaluation relpermOilInOilWaterSystem(const Params& params,
447 const FluidState& fluidState)
448 {
449 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
450 const Evaluation sw =
451 max(Evaluation{ params.Swl() },
452 decay<Evaluation>(fluidState.saturation(waterPhaseIdx)));
453
454 const Evaluation sg = decay<Evaluation>(fluidState.saturation(gasPhaseIdx));
455 const Evaluation Sw_ow = sg + sw;
456
457 return OilWaterMaterialLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.oilWaterParams(), Sw_ow);
458 }
459
467 template <class FluidState>
468 static bool updateHysteresis(Params& params, const FluidState& fluidState)
469 {
470 if constexpr (Traits::enableHysteresis) {
471 const Scalar Swco = params.Swl();
472 const Scalar sw = clampSaturation(fluidState, waterPhaseIdx);
473 const Scalar So = clampSaturation(fluidState, oilPhaseIdx);
474 const Scalar sg = clampSaturation(fluidState, gasPhaseIdx);
475 bool owChanged = params.oilWaterParams().update(/*pcSw=*/sw, /*krwSw=*/sw, /*krnSw=*/1 - So);
476 bool gochanged = params.gasOilParams().update(/*pcSw=*/So,
477 /*krwSw=*/So,
478 /*krnSw=*/1.0 - Swco - sg);
479 return owChanged || gochanged;
480 } else {
481 return false;
482 }
483 }
484
485 template <class FluidState>
486 static Scalar clampSaturation(const FluidState& fluidState, const int phaseIndex)
487 {
488 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
489 const auto sat = scalarValue(fluidState.saturation(phaseIndex));
490 return std::clamp(sat, Scalar{0.0}, Scalar{1.0});
491 }
492};
493
494} // namespace Opm
495
496#endif
Default implementation for the parameters required by the default three-phase capillary pressure mode...
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...
Some templates to wrap the valgrind client request macros.
Implements the default three phase capillary pressure law used by the ECLipse simulator.
Definition EclDefaultMaterial.hpp:62
static Evaluation krn(const Params &params, const FluidState &fluidState)
The relative permeability of the non-wetting (i.e., oil) phase.
Definition EclDefaultMaterial.hpp:389
static Evaluation relpermOilInOilWaterSystem(const Params &params, const FluidState &fluidState)
The relative permeability of oil in oil/water system.
Definition EclDefaultMaterial.hpp:446
static constexpr bool isCompositionDependent
Specify whether the quantities defined by this material law are dependent on the phase composition.
Definition EclDefaultMaterial.hpp:120
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 EclDefaultMaterial.hpp:283
static constexpr bool isTemperatureDependent
Specify whether the quantities defined by this material law are temperature dependent.
Definition EclDefaultMaterial.hpp:116
static Evaluation Sg(const Params &, const FluidState &)
The saturation of the gas phase.
Definition EclDefaultMaterial.hpp:306
static constexpr bool implementsTwoPhaseApi
Specify whether this material law implements the two-phase convenience API.
Definition EclDefaultMaterial.hpp:100
static void saturations(ContainerT &, const Params &, const FluidState &)
The inverse of the capillary pressure.
Definition EclDefaultMaterial.hpp:295
static Evaluation relpermOilInOilGasSystem(const Params &params, const FluidState &fluidState)
The relative permeability of oil in oil/gas system.
Definition EclDefaultMaterial.hpp:428
static Evaluation krw(const Params &params, const FluidState &fluidState)
The relative permeability of the wetting phase.
Definition EclDefaultMaterial.hpp:377
static Evaluation Sn(const Params &, const FluidState &)
The saturation of the non-wetting (i.e., oil) phase.
Definition EclDefaultMaterial.hpp:316
static constexpr bool isSaturationDependent
Specify whether the quantities defined by this material law are saturation dependent.
Definition EclDefaultMaterial.hpp:108
static bool updateHysteresis(Params &params, const FluidState &fluidState)
Update the hysteresis parameters after a time step.
Definition EclDefaultMaterial.hpp:468
static Evaluation krg(const Params &params, const FluidState &fluidState)
The relative permeability of the gas phase.
Definition EclDefaultMaterial.hpp:364
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 EclDefaultMaterial.hpp:137
static Evaluation pcgn(const Params &params, const FluidState &fs)
Capillary pressure between the gas and the non-wetting liquid (i.e., oil) phase.
Definition EclDefaultMaterial.hpp:264
static void relativePermeabilities(ContainerT &values, const Params &params, const FluidState &fluidState)
The relative permeability of all phases.
Definition EclDefaultMaterial.hpp:348
static Evaluation Sw(const Params &, const FluidState &)
The saturation of the wetting (i.e., water) phase.
Definition EclDefaultMaterial.hpp:326
static constexpr bool isPressureDependent
Specify whether the quantities defined by this material law are dependent on the absolute pressure.
Definition EclDefaultMaterial.hpp:112
static constexpr bool implementsTwoPhaseSatApi
Specify whether this material law implements the two-phase convenience API which only depends on the ...
Definition EclDefaultMaterial.hpp:104
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30