46 using EffectiveLaw = EffectiveLawT;
47 using EffectiveLawParams =
typename EffectiveLaw::Params;
49 using Traits =
typename EffectiveLaw::Traits;
50 using Params = ParamsT;
51 using Scalar =
typename EffectiveLaw::Scalar;
53 enum { wettingPhaseIdx = Traits::wettingPhaseIdx };
54 enum { nonWettingPhaseIdx = Traits::nonWettingPhaseIdx };
57 static constexpr int numPhases = EffectiveLaw::numPhases;
59 "The endpoint scaling applies to the nested twophase laws, not to "
60 "the threephase one!");
66 static_assert(EffectiveLaw::implementsTwoPhaseApi,
67 "The material laws put into EclEpsTwoPhaseLaw must implement the "
68 "two-phase material law API!");
74 static_assert(EffectiveLaw::implementsTwoPhaseSatApi,
75 "The material laws put into EclEpsTwoPhaseLaw must implement the "
76 "two-phase material law saturation API!");
104 template <
class Container,
class Flu
idState>
109 throw std::invalid_argument(
"The capillaryPressures(fs) method is not yet implemented");
122 template <
class Container,
class Flu
idState>
127 throw std::invalid_argument(
"The pcnw(fs) method is not yet implemented");
141 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
142 static Evaluation
pcnw(
const Params& ,
145 throw std::invalid_argument(
"The pcnw(fs) method is not yet implemented");
148 template <
class Evaluation>
149 static Evaluation twoPhaseSatPcnw(
const Params& params,
const Evaluation&
Sw)
151 OPM_TIMEFUNCTION_LOCAL();
153 if (!params.config().enableHysteresis() || params.config().pcHysteresisModel() < 0)
154 return EffectiveLaw::twoPhaseSatPcnw(params.drainageParams(),
Sw);
157 if (params.initialImb()) {
158 if (
Sw >= params.pcSwMic()) {
159 return EffectiveLaw::twoPhaseSatPcnw(params.imbibitionParams(),
Sw);
162 const Evaluation& F = (1.0/(params.pcSwMic()-
Sw+params.curvatureCapPrs())-1.0/params.curvatureCapPrs())
163 / (1.0/(params.pcSwMic()-params.Swcrd()+params.curvatureCapPrs())-1.0/params.curvatureCapPrs());
165 const Evaluation& Pcd = EffectiveLaw::twoPhaseSatPcnw(params.drainageParams(),
Sw);
166 const Evaluation& Pci = EffectiveLaw::twoPhaseSatPcnw(params.imbibitionParams(),
Sw);
167 const Evaluation& pc_Killough = Pci+F*(Pcd-Pci);
174 if (
Sw <= params.pcSwMdc())
175 return EffectiveLaw::twoPhaseSatPcnw(params.drainageParams(),
Sw);
178 Scalar Swma = 1.0-params.Sncrt();
180 const Evaluation& Pci = EffectiveLaw::twoPhaseSatPcnw(params.imbibitionParams(),
Sw);
184 Scalar pciwght = params.pcWght();
186 const Evaluation& SwEff =
Sw;
187 const Evaluation& Pci = pciwght*EffectiveLaw::twoPhaseSatPcnw(params.imbibitionParams(), SwEff);
189 const Evaluation& Pcd = EffectiveLaw::twoPhaseSatPcnw(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());
197 const Evaluation& pc_Killough = Pcd+F*(Pci-Pcd);
208 template <
class Container,
class Flu
idState>
213 throw std::invalid_argument(
"The saturations(fs) method is not yet implemented");
220 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
221 static Evaluation
Sw(
const Params& ,
224 throw std::invalid_argument(
"The Sw(fs) method is not yet implemented");
227 template <
class Evaluation>
228 static Evaluation twoPhaseSatSw(
const Params& ,
231 throw std::invalid_argument(
"The twoPhaseSatSw(pc) method is not yet implemented");
238 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
239 static Evaluation
Sn(
const Params& ,
242 throw std::invalid_argument(
"The Sn(pc) method is not yet implemented");
245 template <
class Evaluation>
246 static Evaluation twoPhaseSatSn(
const Params& ,
249 throw std::invalid_argument(
"The twoPhaseSatSn(pc) method is not yet implemented");
261 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
262 static Evaluation
krw(
const Params& ,
265 throw std::invalid_argument(
"The krw(fs) method is not yet implemented");
268 template <
class Evaluation>
269 static Evaluation twoPhaseSatKrw(
const Params& params,
const Evaluation&
Sw)
271 OPM_TIMEFUNCTION_LOCAL();
273 if (!params.config().enableHysteresis() || params.config().krHysteresisModel() < 0)
274 return EffectiveLaw::twoPhaseSatKrw(params.drainageParams(),
Sw);
276 if (params.config().krHysteresisModel() == 0 || params.config().krHysteresisModel() == 2)
278 return EffectiveLaw::twoPhaseSatKrw(params.drainageParams(),
Sw);
281 assert(params.config().krHysteresisModel() == 1 || params.config().krHysteresisModel() == 3);
282 return EffectiveLaw::twoPhaseSatKrw(params.imbibitionParams(),
Sw);
288 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::Scalar>
289 static Evaluation
krn(
const Params& ,
292 throw std::invalid_argument(
"The krn(fs) method is not yet implemented");
295 template <
class Evaluation>
296 static Evaluation twoPhaseSatKrn(
const Params& params,
const Evaluation&
Sw)
298 OPM_TIMEFUNCTION_LOCAL();
301 if (params.gasOilHysteresisWAG()) {
304 if (
Sw <= params.krnSwMdc()+params.tolWAG() && params.nState()==1) {
305 Evaluation
krn = EffectiveLaw::twoPhaseSatKrn(params.drainageParams(),
Sw);
311 if (params.nState()==1) {
312 Evaluation Swf = params.computeSwf(
Sw);
313 Evaluation
krn = EffectiveLaw::twoPhaseSatKrn(params.drainageParams(), Swf);
318 if (
Sw <= params.krnSwDrainRevert()+params.tolWAG() ) {
319 Evaluation Krg = EffectiveLaw::twoPhaseSatKrn(params.drainageParams(),
Sw);
320 Evaluation KrgDrain2 = (Krg-params.krnDrainStart())*params.reductionDrain() + params.krnImbStart();
325 if (
Sw >= params.krnSwWAG()-params.tolWAG() ) {
326 Evaluation KrgImb2 = params.computeKrImbWAG(
Sw);
330 Evaluation Krg = EffectiveLaw::twoPhaseSatKrn(params.drainageParams(),
Sw);
331 Evaluation KrgDrainNxt = (Krg-params.krnDrainStartNxt())*params.reductionDrainNxt() + params.krnImbStartNxt();
337 if (!params.config().enableHysteresis() || params.config().krHysteresisModel() < 0)
338 return EffectiveLaw::twoPhaseSatKrn(params.drainageParams(),
Sw);
343 if (
Sw <= params.krnSwMdc())
344 return EffectiveLaw::twoPhaseSatKrn(params.drainageParams(),
Sw);
346 if (params.config().krHysteresisModel() <= 1) {
347 return EffectiveLaw::twoPhaseSatKrn(params.imbibitionParams(),
348 Sw + params.deltaSwImbKrn());
352 assert(params.config().krHysteresisModel() == 2 || params.config().krHysteresisModel() == 3);
353 Evaluation Snorm = params.Sncri()+(1.0-
Sw-params.Sncrt())*(params.Snmaxd()-params.Sncri())/(params.Snhy()-params.Sncrt());
354 return params.krnWght()*EffectiveLaw::twoPhaseSatKrn(params.imbibitionParams(),1.0-Snorm);