27#ifndef OPM_ECL_EPS_TWO_PHASE_LAW_HPP
28#define OPM_ECL_EPS_TWO_PHASE_LAW_HPP
48template <
class EffLawT,
49 class ParamsT = EclEpsTwoPhaseLawParams<EffLawT> >
52 typedef EffLawT EffLaw;
55 typedef typename EffLaw::Traits
Traits;
57 typedef typename EffLaw::Scalar
Scalar;
65 "The endpoint scaling applies to the nested twophase laws, not to "
66 "the threephase one!");
72 static_assert(EffLaw::implementsTwoPhaseApi,
73 "The material laws put into EclEpsTwoPhaseLaw must implement the "
74 "two-phase material law API!");
80 static_assert(EffLaw::implementsTwoPhaseSatApi,
81 "The material laws put into EclEpsTwoPhaseLaw must implement the "
82 "two-phase material law saturation API!");
110 template <
class Container,
class Flu
idState>
113 throw std::invalid_argument(
"The capillaryPressures(fs) method is not yet implemented");
126 template <
class Container,
class Flu
idState>
129 throw std::invalid_argument(
"The pcnw(fs) method is not yet implemented");
143 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
146 throw std::invalid_argument(
"The pcnw(fs) method is not yet implemented");
149 template <
class Evaluation>
153 const Evaluation pcUnscaled = EffLaw::twoPhaseSatPcnw(params.effectiveLawParams(), SwUnscaled);
154 return unscaledToScaledPcnw_(params, pcUnscaled);
157 template <
class Evaluation>
160 const Evaluation pcnwUnscaled = scaledToUnscaledPcnw_(params, pcnwScaled);
161 const Evaluation SwUnscaled = EffLaw::twoPhaseSatPcnwInv(params.effectiveLawParams(), pcnwUnscaled);
168 template <
class Container,
class Flu
idState>
171 throw std::invalid_argument(
"The saturations(fs) method is not yet implemented");
178 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
179 static Evaluation
Sw(
const Params& ,
const FluidState& )
181 throw std::invalid_argument(
"The Sw(fs) method is not yet implemented");
184 template <
class Evaluation>
187 throw std::invalid_argument(
"The twoPhaseSatSw(pc) method is not yet implemented");
194 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
195 static Evaluation
Sn(
const Params& ,
const FluidState& )
197 throw std::invalid_argument(
"The Sn(pc) method is not yet implemented");
200 template <
class Evaluation>
203 throw std::invalid_argument(
"The twoPhaseSatSn(pc) method is not yet implemented");
215 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
216 static Evaluation
krw(
const Params& ,
const FluidState& )
218 throw std::invalid_argument(
"The krw(fs) method is not yet implemented");
221 template <
class Evaluation>
225 const Evaluation krwUnscaled = EffLaw::twoPhaseSatKrw(params.effectiveLawParams(), SwUnscaled);
226 return unscaledToScaledKrw_(SwScaled, params, krwUnscaled);
229 template <
class Evaluation>
232 const Evaluation krwUnscaled = scaledToUnscaledKrw_(params, krwScaled);
233 const Evaluation SwUnscaled = EffLaw::twoPhaseSatKrwInv(params.effectiveLawParams(), krwUnscaled);
240 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
241 static Evaluation
krn(
const Params& ,
const FluidState& )
243 throw std::invalid_argument(
"The krn(fs) method is not yet implemented");
246 template <
class Evaluation>
250 const Evaluation krnUnscaled = EffLaw::twoPhaseSatKrn(params.effectiveLawParams(), SwUnscaled);
251 return unscaledToScaledKrn_(SwScaled, params, krnUnscaled);
254 template <
class Evaluation>
257 const Evaluation krnUnscaled = scaledToUnscaledKrn_(params, krnScaled);
258 const Evaluation SwUnscaled = EffLaw::twoPhaseSatKrnInv(params.effectiveLawParams(), krnUnscaled);
267 template <
class Evaluation>
270 if (!params.config().enableSatScaling())
275 return scaledToUnscaledSatTwoPoint_(SwScaled,
276 params.unscaledPoints().saturationPcPoints(),
277 params.scaledPoints().saturationPcPoints());
280 template <
class Evaluation>
283 if (!params.config().enableSatScaling())
288 return unscaledToScaledSatTwoPoint_(SwUnscaled,
289 params.unscaledPoints().saturationPcPoints(),
290 params.scaledPoints().saturationPcPoints());
297 template <
class Evaluation>
300 if (!params.config().enableSatScaling())
303 if (params.config().enableThreePointKrSatScaling()) {
304 return scaledToUnscaledSatThreePoint_(SwScaled,
305 params.unscaledPoints().saturationKrwPoints(),
306 params.scaledPoints().saturationKrwPoints());
309 return scaledToUnscaledSatTwoPoint_(SwScaled,
310 params.unscaledPoints().saturationKrwPoints(),
311 params.scaledPoints().saturationKrwPoints());
315 template <
class Evaluation>
318 if (!params.config().enableSatScaling())
321 if (params.config().enableThreePointKrSatScaling()) {
322 return unscaledToScaledSatThreePoint_(SwUnscaled,
323 params.unscaledPoints().saturationKrwPoints(),
324 params.scaledPoints().saturationKrwPoints());
327 return unscaledToScaledSatTwoPoint_(SwUnscaled,
328 params.unscaledPoints().saturationKrwPoints(),
329 params.scaledPoints().saturationKrwPoints());
337 template <
class Evaluation>
340 if (!params.config().enableSatScaling())
343 if (params.config().enableThreePointKrSatScaling())
344 return scaledToUnscaledSatThreePoint_(SwScaled,
345 params.unscaledPoints().saturationKrnPoints(),
346 params.scaledPoints().saturationKrnPoints());
348 return scaledToUnscaledSatTwoPoint_(SwScaled,
349 params.unscaledPoints().saturationKrnPoints(),
350 params.scaledPoints().saturationKrnPoints());
354 template <
class Evaluation>
357 if (!params.config().enableSatScaling())
360 if (params.config().enableThreePointKrSatScaling()) {
361 return unscaledToScaledSatThreePoint_(SwUnscaled,
362 params.unscaledPoints().saturationKrnPoints(),
363 params.scaledPoints().saturationKrnPoints());
366 return unscaledToScaledSatTwoPoint_(SwUnscaled,
367 params.unscaledPoints().saturationKrnPoints(),
368 params.scaledPoints().saturationKrnPoints());
373 template <
class Evaluation,
class Po
intsContainer>
374 static Evaluation scaledToUnscaledSatTwoPoint_(
const Evaluation& scaledSat,
375 const PointsContainer& unscaledSats,
376 const PointsContainer& scaledSats)
381 (scaledSat - scaledSats[0])*((unscaledSats[2] - unscaledSats[0])/(scaledSats[2] - scaledSats[0]));
384 template <
class Evaluation,
class Po
intsContainer>
385 static Evaluation unscaledToScaledSatTwoPoint_(
const Evaluation& unscaledSat,
386 const PointsContainer& unscaledSats,
387 const PointsContainer& scaledSats)
392 (unscaledSat - unscaledSats[0])*((scaledSats[2] - scaledSats[0])/(unscaledSats[2] - unscaledSats[0]));
395 template <
class Evaluation,
class Po
intsContainer>
396 static Evaluation scaledToUnscaledSatThreePoint_(
const Evaluation& scaledSat,
397 const PointsContainer& unscaledSats,
398 const PointsContainer& scaledSats)
400 using UnscaledSat = std::remove_cv_t<std::remove_reference_t<
decltype(unscaledSats[0])>>;
402 auto map = [&scaledSat, &unscaledSats, &scaledSats](
const std::size_t i)
404 const auto distance = (scaledSat - scaledSats[i])
405 / (scaledSats[i + 1] - scaledSats[i]);
407 const auto displacement =
408 std::max(unscaledSats[i + 1] - unscaledSats[i], UnscaledSat{ 0 });
410 return std::min(unscaledSats[i] + distance*displacement,
411 Evaluation { unscaledSats[i + 1] });
414 if (! (scaledSat > scaledSats[0])) {
416 return unscaledSats[0];
418 else if (scaledSat <
std::min(scaledSats[1], scaledSats[2])) {
423 else if (scaledSat < scaledSats[2]) {
431 return unscaledSats[2];
435 template <
class Evaluation,
class Po
intsContainer>
436 static Evaluation unscaledToScaledSatThreePoint_(
const Evaluation& unscaledSat,
437 const PointsContainer& unscaledSats,
438 const PointsContainer& scaledSats)
440 using ScaledSat = std::remove_cv_t<std::remove_reference_t<
decltype(scaledSats[0])>>;
442 auto map = [&unscaledSat, &unscaledSats, &scaledSats](
const std::size_t i)
444 const auto distance = (unscaledSat - unscaledSats[i])
445 / (unscaledSats[i + 1] - unscaledSats[i]);
447 const auto displacement =
448 std::max(scaledSats[i + 1] - scaledSats[i], ScaledSat{ 0 });
450 return std::min(scaledSats[i] + distance*displacement,
451 Evaluation { scaledSats[i + 1] });
454 if (! (unscaledSat > unscaledSats[0])) {
455 return scaledSats[0];
457 else if (unscaledSat < unscaledSats[1]) {
462 else if (unscaledSat < unscaledSats[2]) {
468 return scaledSats[2];
475 template <
class Evaluation>
476 static Evaluation unscaledToScaledPcnw_(
const Params& params,
const Evaluation& unscaledPcnw)
478 if (params.config().enableLeverettScaling()) {
479 Scalar alpha = params.scaledPoints().leverettFactor();
480 return unscaledPcnw*alpha;
482 else if (params.config().enablePcScaling()) {
483 const auto& scaled_maxPcnw = params.scaledPoints().maxPcnw();
484 const auto& unscaled_maxPcnw = params.unscaledPoints().maxPcnw();
487 if (scaled_maxPcnw == unscaled_maxPcnw)
490 alpha = params.scaledPoints().maxPcnw()/params.unscaledPoints().maxPcnw();
492 return unscaledPcnw*alpha;
498 template <
class Evaluation>
499 static Evaluation scaledToUnscaledPcnw_(
const Params& params,
const Evaluation& scaledPcnw)
501 if (params.config().enableLeverettScaling()) {
502 Scalar alpha = params.scaledPoints().leverettFactor();
503 return scaledPcnw/alpha;
505 else if (params.config().enablePcScaling()) {
506 const auto& scaled_maxPcnw = params.scaledPoints().maxPcnw();
507 const auto& unscaled_maxPcnw = params.unscaledPoints().maxPcnw();
510 if (scaled_maxPcnw == unscaled_maxPcnw)
513 alpha = params.scaledPoints().maxPcnw()/params.unscaledPoints().maxPcnw();
515 return scaledPcnw/alpha;
524 template <
class Evaluation>
525 static Evaluation unscaledToScaledKrw_(
const Evaluation& SwScaled,
527 const Evaluation& unscaledKrw)
529 const auto& cfg = params.config();
531 if (! cfg.enableKrwScaling())
534 const auto& scaled = params.scaledPoints();
535 const auto& unscaled = params.unscaledPoints();
537 if (! cfg.enableThreePointKrwScaling()) {
539 const Scalar alpha = scaled.maxKrw() / unscaled.maxKrw();
540 return unscaledKrw * alpha;
544 const auto fdisp = unscaled.krwr();
545 const auto fmax = unscaled.maxKrw();
547 const auto sm = scaled.saturationKrwPoints()[2];
548 const auto sr =
std::min(scaled.saturationKrwPoints()[1], sm);
549 const auto fr = scaled.krwr();
550 const auto fm = scaled.maxKrw();
552 if (! (SwScaled > sr)) {
554 return unscaledKrw * (fr / fdisp);
556 else if (fmax > fdisp) {
563 const auto t = (unscaledKrw - fdisp) / (fmax - fdisp);
565 return fr + t*(fm - fr);
574 const auto t = (SwScaled - sr) / (sm - sr);
576 return fr + t*(fm - fr);
584 template <
class Evaluation>
585 static Evaluation scaledToUnscaledKrw_(
const Params& params,
const Evaluation& scaledKrw)
587 if (!params.config().enableKrwScaling())
590 Scalar alpha = params.unscaledPoints().maxKrw()/params.scaledPoints().maxKrw();
591 return scaledKrw*alpha;
597 template <
class Evaluation>
598 static Evaluation unscaledToScaledKrn_(
const Evaluation& SwScaled,
600 const Evaluation& unscaledKrn)
602 const auto& cfg = params.config();
604 if (! cfg.enableKrnScaling())
607 const auto& scaled = params.scaledPoints();
608 const auto& unscaled = params.unscaledPoints();
610 if (! cfg.enableThreePointKrnScaling()) {
613 const Scalar alpha = scaled.maxKrn() / unscaled.maxKrn();
614 return unscaledKrn * alpha;
618 const auto fdisp = unscaled.krnr();
619 const auto fmax = unscaled.maxKrn();
621 const auto sl = scaled.saturationKrnPoints()[0];
622 const auto sr =
std::max(scaled.saturationKrnPoints()[1], sl);
623 const auto fr = scaled.krnr();
624 const auto fm = scaled.maxKrn();
630 if (! (SwScaled < sr)) {
632 return unscaledKrn * (fr / fdisp);
634 else if (fmax > fdisp) {
641 const auto t = (unscaledKrn - fdisp) / (fmax - fdisp);
643 return fr + t*(fm - fr);
652 const auto t = (sr - SwScaled) / (sr - sl);
654 return fr + t*(fm - fr);
662 template <
class Evaluation>
663 static Evaluation scaledToUnscaledKrn_(
const Params& params,
const Evaluation& scaledKrn)
665 if (!params.config().enableKrnScaling())
668 Scalar alpha = params.unscaledPoints().maxKrn()/params.scaledPoints().maxKrn();
669 return scaledKrn*alpha;
This material law takes a material law defined for unscaled saturation and converts it to a material ...
Definition: EclEpsTwoPhaseLaw.hpp:51
static Evaluation unscaledToScaledSatPc(const Params ¶ms, const Evaluation &SwUnscaled)
Definition: EclEpsTwoPhaseLaw.hpp:281
static Evaluation unscaledToScaledSatKrn(const Params ¶ms, const Evaluation &SwUnscaled)
Definition: EclEpsTwoPhaseLaw.hpp:355
static Evaluation krw(const Params &, const FluidState &)
The relative permeability for the wetting phase.
Definition: EclEpsTwoPhaseLaw.hpp:216
static const int numPhases
The number of fluid phases.
Definition: EclEpsTwoPhaseLaw.hpp:63
EffLaw::Scalar Scalar
Definition: EclEpsTwoPhaseLaw.hpp:57
ParamsT Params
Definition: EclEpsTwoPhaseLaw.hpp:56
@ nonWettingPhaseIdx
Definition: EclEpsTwoPhaseLaw.hpp:60
@ wettingPhaseIdx
Definition: EclEpsTwoPhaseLaw.hpp:59
static Evaluation twoPhaseSatKrn(const Params ¶ms, const Evaluation &SwScaled)
Definition: EclEpsTwoPhaseLaw.hpp:247
static Evaluation twoPhaseSatKrwInv(const Params ¶ms, const Evaluation &krwScaled)
Definition: EclEpsTwoPhaseLaw.hpp:230
static Evaluation scaledToUnscaledSatKrn(const Params ¶ms, const Evaluation &SwScaled)
Convert an absolute saturation to an effective one for the scaling of the relperm of the non-wetting ...
Definition: EclEpsTwoPhaseLaw.hpp:338
static Evaluation twoPhaseSatPcnwInv(const Params ¶ms, const Evaluation &pcnwScaled)
Definition: EclEpsTwoPhaseLaw.hpp:158
static Evaluation unscaledToScaledSatKrw(const Params ¶ms, const Evaluation &SwUnscaled)
Definition: EclEpsTwoPhaseLaw.hpp:316
static Evaluation twoPhaseSatPcnw(const Params ¶ms, const Evaluation &SwScaled)
Definition: EclEpsTwoPhaseLaw.hpp:150
static Evaluation Sw(const Params &, const FluidState &)
Calculate wetting liquid phase saturation given that the rest of the fluid state has been initialized...
Definition: EclEpsTwoPhaseLaw.hpp:179
static void saturations(Container &, const Params &, const FluidState &)
The saturation-capillary pressure curves.
Definition: EclEpsTwoPhaseLaw.hpp:169
static Evaluation krn(const Params &, const FluidState &)
The relative permeability of the non-wetting phase.
Definition: EclEpsTwoPhaseLaw.hpp:241
static Evaluation twoPhaseSatSw(const Params &, const Evaluation &)
Definition: EclEpsTwoPhaseLaw.hpp:185
static const bool implementsTwoPhaseApi
Definition: EclEpsTwoPhaseLaw.hpp:70
EffLaw::Traits Traits
Definition: EclEpsTwoPhaseLaw.hpp:55
static Evaluation scaledToUnscaledSatPc(const Params ¶ms, const Evaluation &SwScaled)
Convert an absolute saturation to an effective one for capillary pressure.
Definition: EclEpsTwoPhaseLaw.hpp:268
static Evaluation twoPhaseSatSn(const Params &, const Evaluation &)
Definition: EclEpsTwoPhaseLaw.hpp:201
static const bool isSaturationDependent
Definition: EclEpsTwoPhaseLaw.hpp:86
static void relativePermeabilities(Container &, const Params &, const FluidState &)
The relative permeability-saturation curves depending on absolute saturations.
Definition: EclEpsTwoPhaseLaw.hpp:127
static Evaluation twoPhaseSatKrnInv(const Params ¶ms, const Evaluation &krnScaled)
Definition: EclEpsTwoPhaseLaw.hpp:255
static const bool isCompositionDependent
Definition: EclEpsTwoPhaseLaw.hpp:98
static Evaluation pcnw(const Params &, const FluidState &)
The capillary pressure-saturation curve.
Definition: EclEpsTwoPhaseLaw.hpp:144
static Evaluation twoPhaseSatKrw(const Params ¶ms, const Evaluation &SwScaled)
Definition: EclEpsTwoPhaseLaw.hpp:222
static void capillaryPressures(Container &, const Params &, const FluidState &)
The capillary pressure-saturation curves depending on absolute saturations.
Definition: EclEpsTwoPhaseLaw.hpp:111
static Evaluation scaledToUnscaledSatKrw(const Params ¶ms, const Evaluation &SwScaled)
Convert an absolute saturation to an effective one for the scaling of the relperm of the wetting phas...
Definition: EclEpsTwoPhaseLaw.hpp:298
static Evaluation Sn(const Params &, const FluidState &)
Calculate non-wetting liquid phase saturation given that the rest of the fluid state has been initial...
Definition: EclEpsTwoPhaseLaw.hpp:195
static const bool isTemperatureDependent
Definition: EclEpsTwoPhaseLaw.hpp:94
static const bool implementsTwoPhaseSatApi
Definition: EclEpsTwoPhaseLaw.hpp:78
static const bool isPressureDependent
Definition: EclEpsTwoPhaseLaw.hpp:90
Definition: Air_Mesitylene.hpp:34
ReturnEval_< Evaluation1, Evaluation2 >::type min(const Evaluation1 &arg1, const Evaluation2 &arg2)
Definition: MathToolbox.hpp:346
ReturnEval_< Evaluation1, Evaluation2 >::type max(const Evaluation1 &arg1, const Evaluation2 &arg2)
Definition: MathToolbox.hpp:341