45 using EffectiveLaw = EffectiveLawT;
46 using EffectiveLawParams =
typename EffectiveLaw::Params;
48 using Traits =
typename EffectiveLaw::Traits;
49 using Params = ParamsT;
50 using Scalar =
typename EffectiveLaw::Scalar;
52 enum { wettingPhaseIdx = Traits::wettingPhaseIdx };
53 enum { nonWettingPhaseIdx = Traits::nonWettingPhaseIdx };
56 static constexpr int numPhases = EffectiveLaw::numPhases;
58 "The endpoint scaling applies to the nested twophase laws, not to "
59 "the threephase one!");
65 static_assert(EffectiveLaw::implementsTwoPhaseApi,
66 "The material laws put into EclEpsTwoPhaseLaw must implement the "
67 "two-phase material law API!");
73 static_assert(EffectiveLaw::implementsTwoPhaseSatApi,
74 "The material laws put into EclEpsTwoPhaseLaw must implement the "
75 "two-phase material law saturation API!");
103 template <
class Container,
class Flu
idState>
108 throw std::invalid_argument(
"The capillaryPressures(fs) method is not yet implemented");
121 template <
class Container,
class Flu
idState>
126 throw std::invalid_argument(
"The pcnw(fs) method is not yet implemented");
140 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
141 static Evaluation
pcnw(
const Params& ,
144 throw std::invalid_argument(
"The pcnw(fs) method is not yet implemented");
147 template <
class Evaluation,
class ...Args>
148 static Evaluation twoPhaseSatPcnw(
const Params& params,
const Evaluation&
Sw)
150 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
152 if (!params.config().enableHysteresis() || params.config().pcHysteresisModel() < 0)
153 return EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.drainageParams(),
Sw);
156 if (params.initialImb()) {
157 if (
Sw >= params.pcSwMic()) {
158 return EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.imbibitionParams(),
Sw);
161 const Evaluation& F = (1.0/(params.pcSwMic()-
Sw+params.curvatureCapPrs())-1.0/params.curvatureCapPrs())
162 / (1.0/(params.pcSwMic()-params.Swcrd()+params.curvatureCapPrs())-1.0/params.curvatureCapPrs());
164 const Evaluation& Pcd = EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.drainageParams(),
Sw);
165 const Evaluation& Pci = EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.imbibitionParams(),
Sw);
166 const Evaluation& pc_Killough = Pci+F*(Pcd-Pci);
173 if (
Sw <= params.pcSwMdc())
174 return EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.drainageParams(),
Sw);
177 Scalar Swma = 1.0-params.Sncrt();
179 const Evaluation& Pci = EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.imbibitionParams(),
Sw);
183 Scalar pciwght = params.pcWght();
184 Evaluation SwScaled =
Sw;
185 if (params.config().enablePcScalingHyst()) {
186 const Evaluation SwScan = (
Sw-params.pcSwMdc())/(Swma-params.pcSwMdc());
187 SwScaled = params.Swcri() + (1 - params.Sncri() - params.Swcri()) * SwScan;
189 const Evaluation dPc = pciwght*EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.imbibitionParams(), SwScaled) - EffectiveLaw::twoPhaseSatPcnw(params.drainageParams(), SwScaled);
190 const Evaluation Pcd = EffectiveLaw::template twoPhaseSatPcnw<Evaluation, Args...>(params.drainageParams(),
Sw);
194 const Evaluation F = (1.0/(
Sw-params.pcSwMdc()+params.curvatureCapPrs())-1.0/params.curvatureCapPrs())
195 / (1.0/(Swma-params.pcSwMdc()+params.curvatureCapPrs())-1.0/params.curvatureCapPrs());
206 template <
class Container,
class Flu
idState>
211 throw std::invalid_argument(
"The saturations(fs) method is not yet implemented");
218 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
219 static Evaluation
Sw(
const Params& ,
222 throw std::invalid_argument(
"The Sw(fs) method is not yet implemented");
225 template <
class Evaluation>
226 static Evaluation twoPhaseSatSw(
const Params& ,
229 throw std::invalid_argument(
"The twoPhaseSatSw(pc) method is not yet implemented");
236 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
237 static Evaluation
Sn(
const Params& ,
240 throw std::invalid_argument(
"The Sn(pc) method is not yet implemented");
243 template <
class Evaluation>
244 static Evaluation twoPhaseSatSn(
const Params& ,
247 throw std::invalid_argument(
"The twoPhaseSatSn(pc) method is not yet implemented");
259 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
260 static Evaluation
krw(
const Params& ,
263 throw std::invalid_argument(
"The krw(fs) method is not yet implemented");
266 template <
class Evaluation,
class ...Args>
267 static Evaluation twoPhaseSatKrw(
const Params& params,
const Evaluation&
Sw)
270 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
272 if (!params.config().enableHysteresis() || params.config().krHysteresisModel() < 0)
273 return EffectiveLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.drainageParams(),
Sw);
275 if (params.config().krHysteresisModel() == 0 || params.config().krHysteresisModel() == 2)
277 return EffectiveLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.drainageParams(),
Sw);
280 if (params.config().krHysteresisModel() == 1 || params.config().krHysteresisModel() == 3)
281 return EffectiveLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.imbibitionParams(),
Sw);
283 if (
Sw <= params.krnSwMdc()) {
284 return EffectiveLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.drainageParams(),
Sw);
287 assert(params.config().krHysteresisModel() == 4);
289 if ( (1.0-
Sw-params.Sncrt()) < 0.0) {
290 return EffectiveLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.imbibitionParams(),
Sw);
292 Evaluation Snorm = params.Sncri()+(1.0-
Sw-params.Sncrt())*(params.Snmaxd()-params.Sncri())/(params.Snhy()-params.Sncrt());
293 Evaluation Krwi_snorm = EffectiveLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.imbibitionParams(), 1 - Snorm);
294 Evaluation Krwd = params.config().enableWettingPhaseKilloughFix()? EffectiveLaw::template twoPhaseSatKrw<Evaluation, Args...>(params.drainageParams(),
Sw) : params.KrwdHy();
295 return Krwd + params.krwWght(Krwd) * (Krwi_snorm - params.Krwi_snmax());
301 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
302 static Evaluation
krn(
const Params& ,
305 throw std::invalid_argument(
"The krn(fs) method is not yet implemented");
308 template <
class Evaluation,
class ...Args>
309 static Evaluation twoPhaseSatKrn(
const Params& params,
const Evaluation&
Sw)
311 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
314 if (params.gasOilHysteresisWAG()) {
317 if (
Sw <= params.krnSwMdc() + params.tolWAG() && params.nState() == 1) {
318 return EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.drainageParams(),
Sw);
323 if (params.nState() == 1) {
324 Evaluation Swf = params.computeSwf(
Sw);
325 return EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.drainageParams(), Swf);
329 if (
Sw <= params.krnSwDrainRevert()+params.tolWAG() ) {
330 Evaluation Krg = EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.drainageParams(),
Sw);
331 Evaluation KrgDrain2 = (Krg-params.krnDrainStart())*params.reductionDrain() + params.krnImbStart();
336 if (
Sw >= params.krnSwWAG()-params.tolWAG() ) {
337 Evaluation KrgImb2 = params.computeKrImbWAG(
Sw);
341 Evaluation Krg = EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.drainageParams(),
Sw);
342 Evaluation KrgDrainNxt = (Krg-params.krnDrainStartNxt())*params.reductionDrainNxt() + params.krnImbStartNxt();
347 if (!params.config().enableHysteresis() || params.config().krHysteresisModel() < 0)
348 return EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.drainageParams(),
Sw);
352 if (
Sw <= params.krnSwMdc()) {
353 return EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.drainageParams(),
Sw);
356 if (params.config().krHysteresisModel() <= 1) {
357 return EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.imbibitionParams(),
358 Sw + params.deltaSwImbKrn());
362 assert(params.config().krHysteresisModel() == 2 || params.config().krHysteresisModel() == 3 || params.config().krHysteresisModel() == 4);
363 Evaluation Snorm = params.Sncri()+(1.0-
Sw-params.Sncrt())*(params.Snmaxd()-params.Sncri())/(params.Snhy()-params.Sncrt());
364 return params.krnWght()*EffectiveLaw::template twoPhaseSatKrn<Evaluation, Args...>(params.imbibitionParams(),1.0-Snorm);