27 #ifndef OPM_PIECEWISE_LINEAR_TWO_PHASE_MATERIAL_HPP 28 #define OPM_PIECEWISE_LINEAR_TWO_PHASE_MATERIAL_HPP 32 #include <opm/common/TimingMacros.hpp> 35 #include <opm/common/utility/gpuDecorators.hpp> 39 #include <type_traits> 52 template <
class TraitsT,
class ParamsT = PiecewiseLinearTwoPhaseMaterialParams<TraitsT> >
55 using ValueVector =
typename ParamsT::ValueVector;
65 using Scalar =
typename Traits::Scalar;
70 "The piecewise linear two-phase capillary pressure law only" 71 "applies to the case of two fluid phases");
100 template <
class Container,
class Flu
idState>
103 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
104 using Evaluation =
typename std::remove_reference<decltype(values[0])>::type;
106 values[Traits::wettingPhaseIdx] = 0.0;
107 values[Traits::nonWettingPhaseIdx] = pcnw<FluidState, Evaluation>(params, fs);
114 template <
class Container,
class Flu
idState>
116 {
throw std::logic_error(
"Not implemented: saturations()"); }
121 template <
class Container,
class Flu
idState>
124 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
125 using Evaluation =
typename std::remove_reference<decltype(values[0])>::type;
127 values[Traits::wettingPhaseIdx] = krw<FluidState, Evaluation>(params, fs);
128 values[Traits::nonWettingPhaseIdx] = krn<FluidState, Evaluation>(params, fs);
134 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
135 OPM_HOST_DEVICE
static Evaluation
pcnw(
const Params& params,
const FluidState& fs)
137 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
139 decay<Evaluation>(fs.saturation(Traits::wettingPhaseIdx));
147 template <
class Evaluation>
150 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
151 return eval_(params.SwPcwnSamples(), params.pcwnSamples(),
Sw);
154 template <
class Evaluation>
155 static Evaluation twoPhaseSatPcnwInv(
const Params& params,
const Evaluation&
pcnw)
156 {
return eval_(params.pcwnSamples(), params.SwPcwnSamples(),
pcnw); }
161 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
162 OPM_HOST_DEVICE
static Evaluation
Sw(
const Params& ,
const FluidState& )
163 {
throw std::logic_error(
"Not implemented: Sw()"); }
165 template <
class Evaluation>
166 OPM_HOST_DEVICE
static Evaluation twoPhaseSatSw(
const Params& ,
const Evaluation& )
167 {
throw std::logic_error(
"Not implemented: twoPhaseSatSw()"); }
173 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
174 OPM_HOST_DEVICE
static Evaluation
Sn(
const Params& params,
const FluidState& fs)
175 {
return 1 - Sw<FluidState, Scalar>(params, fs); }
177 template <
class Evaluation>
178 OPM_HOST_DEVICE
static Evaluation twoPhaseSatSn(
const Params& params,
const Evaluation& pC)
179 {
return 1 - twoPhaseSatSw(params, pC); }
185 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
186 OPM_HOST_DEVICE
static Evaluation
krw(
const Params& params,
const FluidState& fs)
188 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
190 decay<Evaluation>(fs.saturation(Traits::wettingPhaseIdx));
192 return twoPhaseSatKrw(params, sw);
195 template <
class Evaluation>
196 OPM_HOST_DEVICE
static Evaluation twoPhaseSatKrw(
const Params& params,
const Evaluation&
Sw)
198 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
199 return eval_(params.SwKrwSamples(), params.krwSamples(),
Sw);
202 template <
class Evaluation>
203 OPM_HOST_DEVICE
static Evaluation twoPhaseSatKrwInv(
const Params& params,
const Evaluation&
krw)
205 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
206 return eval_(params.krwSamples(), params.SwKrwSamples(),
krw);
213 template <
class Flu
idState,
class Evaluation =
typename Flu
idState::ValueType>
214 OPM_HOST_DEVICE
static Evaluation
krn(
const Params& params,
const FluidState& fs)
216 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
218 decay<Evaluation>(fs.saturation(Traits::wettingPhaseIdx));
220 return twoPhaseSatKrn(params, sw);
223 template <
class Evaluation>
224 OPM_HOST_DEVICE
static Evaluation twoPhaseSatKrn(
const Params& params,
const Evaluation&
Sw)
226 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
227 return eval_(params.SwKrnSamples(), params.krnSamples(),
Sw);
230 template <
class Evaluation>
231 OPM_HOST_DEVICE
static Evaluation twoPhaseSatKrnInv(
const Params& params,
const Evaluation&
krn)
232 {
return eval_(params.krnSamples(), params.SwKrnSamples(),
krn); }
234 template <
class Evaluation>
235 OPM_HOST_DEVICE
static std::size_t findSegmentIndex(
const ValueVector& xValues,
const Evaluation& x){
236 return findSegmentIndex_(xValues, scalarValue(x));
239 template <
class Evaluation>
240 OPM_HOST_DEVICE
static std::size_t findSegmentIndexDescending(
const ValueVector& xValues,
const Evaluation& x){
241 return findSegmentIndexDescending_(xValues, scalarValue(x));
244 template <
class Evaluation>
245 OPM_HOST_DEVICE
static Evaluation eval(
const ValueVector& xValues,
const ValueVector& yValues,
const Evaluation& x,
unsigned segIdx){
246 Scalar x0 = xValues[segIdx];
247 Scalar x1 = xValues[segIdx + 1];
249 Scalar y0 = yValues[segIdx];
250 Scalar y1 = yValues[segIdx + 1];
252 Scalar m = (y1 - y0)/(x1 - x0);
254 return y0 + (x - x0)*m;
258 template <
class Evaluation>
259 OPM_HOST_DEVICE
static Evaluation eval_(
const ValueVector& xValues,
260 const ValueVector& yValues,
263 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
264 if (xValues.front() < xValues.back())
265 return evalAscending_(xValues, yValues, x);
266 return evalDescending_(xValues, yValues, x);
269 template <
class Evaluation>
270 OPM_HOST_DEVICE
static Evaluation evalAscending_(
const ValueVector& xValues,
271 const ValueVector& yValues,
274 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
275 if (x <= xValues.front())
276 return yValues.front();
277 if (x >= xValues.back())
278 return yValues.back();
280 std::size_t segIdx = findSegmentIndex_(xValues, scalarValue(x));
282 return eval(xValues, yValues, x, segIdx);
285 template <
class Evaluation>
286 OPM_HOST_DEVICE
static Evaluation evalDescending_(
const ValueVector& xValues,
287 const ValueVector& yValues,
290 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
291 if (x >= xValues.front())
292 return yValues.front();
293 if (x <= xValues.back())
294 return yValues.back();
296 std::size_t segIdx = findSegmentIndexDescending_(xValues, scalarValue(x));
298 return eval(xValues, yValues, x, segIdx);
301 template <
class Evaluation>
302 OPM_HOST_DEVICE
static Evaluation evalDeriv_(
const ValueVector& xValues,
303 const ValueVector& yValues,
306 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
307 if (x <= xValues.front())
309 if (x >= xValues.back())
312 std::size_t segIdx = findSegmentIndex_(xValues, scalarValue(x));
314 Scalar x0 = xValues[segIdx];
315 Scalar x1 = xValues[segIdx + 1];
317 Scalar y0 = yValues[segIdx];
318 Scalar y1 = yValues[segIdx + 1];
320 return (y1 - y0)/(x1 - x0);
322 template<
class ScalarT>
323 OPM_HOST_DEVICE
static std::size_t findSegmentIndex_(
const ValueVector& xValues,
const ScalarT& x)
325 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
326 assert(xValues.size() > 1);
327 std::size_t n = xValues.size() - 1;
328 if (xValues.back() <= x)
330 else if (x <= xValues.front())
334 std::size_t lowIdx = 0, highIdx = n;
335 while (lowIdx + 1 < highIdx) {
336 std::size_t curIdx = (lowIdx + highIdx)/2;
337 if (xValues[curIdx] < x)
346 OPM_HOST_DEVICE
static std::size_t findSegmentIndexDescending_(
const ValueVector& xValues,
Scalar x)
348 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
349 assert(xValues.size() > 1);
350 std::size_t n = xValues.size() - 1;
351 if (x <= xValues.back())
353 else if (xValues.front() <= x)
357 std::size_t lowIdx = 0, highIdx = n;
358 while (lowIdx + 1 < highIdx) {
359 std::size_t curIdx = (lowIdx + highIdx)/2;
360 if (xValues[curIdx] >= x)
static OPM_HOST_DEVICE void saturations(Container &, const Params &, const FluidState &)
The saturations of the fluid phases starting from their pressure differences.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:115
static constexpr bool isTemperatureDependent
Specify whether the quantities defined by this material law are temperature dependent.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:91
static constexpr bool isSaturationDependent
Specify whether the quantities defined by this material law are saturation dependent.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:83
static constexpr bool implementsTwoPhaseApi
Specify whether this material law implements the two-phase convenience API.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:75
static OPM_HOST_DEVICE void relativePermeabilities(Container &values, const Params ¶ms, const FluidState &fs)
The relative permeabilities.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:122
typename Traits::Scalar Scalar
The type of the scalar values for this law.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:65
ParamsT Params
The type of the parameter objects for this law.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:62
static constexpr bool implementsTwoPhaseSatApi
Specify whether this material law implements the two-phase convenience API which only depends on the ...
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:79
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Implementation of a tabulated, piecewise linear capillary pressure law.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:53
static OPM_HOST_DEVICE void capillaryPressures(Container &values, const Params ¶ms, const FluidState &fs)
The capillary pressure-saturation curve.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:101
TraitsT Traits
The traits class for this material law.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:59
Specification of the material parameters for a two-phase material law which uses a table and piecewis...
static OPM_HOST_DEVICE Evaluation krn(const Params ¶ms, const FluidState &fs)
The relative permeability for the non-wetting phase of the porous medium.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:214
static OPM_HOST_DEVICE Evaluation krw(const Params ¶ms, const FluidState &fs)
The relative permeability for the wetting phase of the porous medium.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:186
static OPM_HOST_DEVICE Evaluation Sw(const Params &, const FluidState &)
The saturation-capillary pressure curve.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:162
static OPM_HOST_DEVICE Evaluation twoPhaseSatPcnw(const Params ¶ms, const Evaluation &Sw)
The saturation-capillary pressure curve.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:148
static constexpr bool isCompositionDependent
Specify whether the quantities defined by this material law are dependent on the phase composition...
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:95
static OPM_HOST_DEVICE Evaluation pcnw(const Params ¶ms, const FluidState &fs)
The capillary pressure-saturation curve.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:135
static OPM_HOST_DEVICE Evaluation Sn(const Params ¶ms, const FluidState &fs)
Calculate the non-wetting phase saturations depending on the phase pressures.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:174
static constexpr bool isPressureDependent
Specify whether the quantities defined by this material law are dependent on the absolute pressure...
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:87
static constexpr int numPhases
The number of fluid phases.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:68