ThreePhaseParkerVanGenuchten.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  Copyright (C) 2008-2013 by Andreas Lauser
5  Copyright (C) 2012 by Holger Class
6  Copyright (C) 2012 by Vishal Jambhekar
7 
8  This file is part of the Open Porous Media project (OPM).
9 
10  OPM is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 2 of the License, or
13  (at your option) any later version.
14 
15  OPM is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with OPM. If not, see <http://www.gnu.org/licenses/>.
22 */
27 #ifndef OPM_THREE_PHASE_PARKER_VAN_GENUCHTEN_HPP
28 #define OPM_THREE_PHASE_PARKER_VAN_GENUCHTEN_HPP
29 
31 
33 
34 #include <algorithm>
35 
36 namespace Opm {
48 template <class TraitsT,
49  class ParamsT = ThreePhaseParkerVanGenuchtenParams<TraitsT> >
51 {
52 public:
53  static_assert(TraitsT::numPhases == 3,
54  "The number of phases considered by this capillary pressure "
55  "law is always three!");
56 
57  typedef TraitsT Traits;
58  typedef ParamsT Params;
59  typedef typename Traits::Scalar Scalar;
60 
61  static const int numPhases = 3;
62  static const int wettingPhaseIdx = Traits::wettingPhaseIdx;
63  static const int nonWettingPhaseIdx = Traits::nonWettingPhaseIdx;
64  static const int gasPhaseIdx = Traits::gasPhaseIdx;
65 
68  static const bool implementsTwoPhaseApi = false;
69 
72  static const bool implementsTwoPhaseSatApi = false;
73 
76  static const bool isSaturationDependent = true;
77 
80  static const bool isPressureDependent = false;
81 
84  static const bool isTemperatureDependent = false;
85 
88  static const bool isCompositionDependent = false;
89 
101  template <class ContainerT, class FluidState>
102  static void capillaryPressures(ContainerT &values,
103  const Params &params,
104  const FluidState &fluidState)
105  {
106  typedef typename std::remove_reference<decltype(values[0])>::type Evaluation;
107 
108  values[gasPhaseIdx] = pcgn<FluidState, Evaluation>(params, fluidState);
109  values[nonWettingPhaseIdx] = 0;
110  values[wettingPhaseIdx] = - pcnw<FluidState, Evaluation>(params, fluidState);
111  }
112 
122  template <class FluidState, class Evaluation = typename FluidState::Scalar>
123  static Evaluation pcgn(const Params &params, const FluidState &fluidState)
124  {
126  typedef MathToolbox<Evaluation> Toolbox;
127 
128  Scalar PC_VG_REG = 0.01;
129 
130  // sum of liquid saturations
131  const auto& St =
132  FsToolbox::template toLhs<Evaluation>(fluidState.saturation(wettingPhaseIdx))
133  + FsToolbox::template toLhs<Evaluation>(fluidState.saturation(nonWettingPhaseIdx));
134 
135  Evaluation Se = (St - params.Swrx())/(1. - params.Swrx());
136 
137  // regularization
138  if (Se < 0.0)
139  Se=0.0;
140  if (Se > 1.0)
141  Se=1.0;
142 
143  if (Se>PC_VG_REG && Se<1-PC_VG_REG)
144  {
145  const Evaluation& x = Toolbox::pow(Se,-1/params.vgM()) - 1;
146  return Toolbox::pow(x, 1.0 - params.vgM())/params.vgAlpha();
147  }
148 
149  // value and derivative at regularization point
150  Scalar Se_regu;
151  if (Se<=PC_VG_REG)
152  Se_regu = PC_VG_REG;
153  else
154  Se_regu = 1-PC_VG_REG;
155  const Evaluation& x = std::pow(Se_regu,-1/params.vgM())-1;
156  const Evaluation& pc = Toolbox::pow(x, 1.0/params.vgN())/params.vgAlpha();
157  const Evaluation& pc_prime =
158  Toolbox::pow(x, 1/params.vgN()-1)
159  * std::pow(Se_regu,-1/params.vgM()-1)
160  / (-params.vgM())
161  / params.vgAlpha()
162  / (1 - params.Sgr() - params.Swrx())
163  / params.vgN();
164 
165  // evaluate tangential
166  return ((Se-Se_regu)*pc_prime + pc)/params.betaGN();
167  }
168 
178  template <class FluidState, class Evaluation = typename FluidState::Scalar>
179  static Evaluation pcnw(const Params &params, const FluidState &fluidState)
180  {
182  typedef MathToolbox<Evaluation> Toolbox;
183 
184  const Evaluation& Sw =
185  FsToolbox::template toLhs<Evaluation>(fluidState.saturation(wettingPhaseIdx));
186  Evaluation Se = (Sw-params.Swr())/(1.-params.Snr());
187 
188  Scalar PC_VG_REG = 0.01;
189 
190  // regularization
191  if (Se<0.0)
192  Se=0.0;
193  if (Se>1.0)
194  Se=1.0;
195 
196  if (Se>PC_VG_REG && Se<1-PC_VG_REG) {
197  Evaluation x = Toolbox::pow(Se,-1/params.vgM()) - 1.0;
198  x = Toolbox::pow(x, 1 - params.vgM());
199  return x/params.vgAlpha();
200  }
201 
202  // value and derivative at regularization point
203  Scalar Se_regu;
204  if (Se<=PC_VG_REG)
205  Se_regu = PC_VG_REG;
206  else
207  Se_regu = 1.0 - PC_VG_REG;
208 
209  const Evaluation& x = std::pow(Se_regu,-1/params.vgM())-1;
210  const Evaluation& pc = Toolbox::pow(x, 1/params.vgN())/params.vgAlpha();
211  const Evaluation& pc_prime =
212  Toolbox::pow(x,1/params.vgN()-1)
213  * std::pow(Se_regu, -1.0/params.vgM() - 1)
214  / (-params.vgM())
215  / params.vgAlpha()
216  / (1-params.Snr()-params.Swr())
217  / params.vgN();
218 
219  // evaluate tangential
220  return ((Se-Se_regu)*pc_prime + pc)/params.betaNW();
221  }
222 
227  template <class ContainerT, class FluidState>
228  static void saturations(ContainerT &/*values*/,
229  const Params &/*params*/,
230  const FluidState &/*fluidState*/)
231  { OPM_THROW(std::logic_error, "Not implemented: inverse capillary pressures"); }
232 
236  template <class FluidState, class Evaluation = typename FluidState::Scalar>
237  static Evaluation Sg(const Params &/*params*/, const FluidState &/*fluidState*/)
238  { OPM_THROW(std::logic_error, "Not implemented: Sg()"); }
239 
243  template <class FluidState, class Evaluation = typename FluidState::Scalar>
244  static Evaluation Sn(const Params &/*params*/, const FluidState &/*fluidState*/)
245  { OPM_THROW(std::logic_error, "Not implemented: Sn()"); }
246 
250  template <class FluidState, class Evaluation = typename FluidState::Scalar>
251  static Evaluation Sw(const Params &/*params*/, const FluidState &/*fluidState*/)
252  { OPM_THROW(std::logic_error, "Not implemented: Sw()"); }
253 
257  template <class ContainerT, class FluidState>
258  static void relativePermeabilities(ContainerT &values,
259  const Params &params,
260  const FluidState &fluidState)
261  {
262  typedef typename std::remove_reference<decltype(values[0])>::type Evaluation;
263 
264  values[wettingPhaseIdx] = krw<FluidState, Evaluation>(params, fluidState);
265  values[nonWettingPhaseIdx] = krn<FluidState, Evaluation>(params, fluidState);
266  values[gasPhaseIdx] = krg<FluidState, Evaluation>(params, fluidState);
267  }
268 
277  template <class FluidState, class Evaluation = typename FluidState::Scalar>
278  static Evaluation krw(const Params &params, const FluidState &fluidState)
279  {
281  typedef MathToolbox<Evaluation> Toolbox;
282 
283  const Evaluation& Sw =
284  FsToolbox::template toLhs<Evaluation>(fluidState.saturation(wettingPhaseIdx));
285  // transformation to effective saturation
286  const Evaluation& Se = (Sw - params.Swr()) / (1-params.Swr());
287 
288  // regularization
289  if(Se > 1.0) return 1.;
290  if(Se < 0.0) return 0.;
291 
292  const Evaluation& r = 1. - Toolbox::pow(1 - Toolbox::pow(Se, 1/params.vgM()), params.vgM());
293  return Toolbox::sqrt(Se)*r*r;
294  }
295 
308  template <class FluidState, class Evaluation = typename FluidState::Scalar>
309  static Evaluation krn(const Params &params, const FluidState &fluidState)
310  {
312  typedef MathToolbox<Evaluation> Toolbox;
313 
314  const Evaluation& Sn =
315  FsToolbox::template toLhs<Evaluation>(fluidState.saturation(nonWettingPhaseIdx));
316  const Evaluation& Sw =
317  FsToolbox::template toLhs<Evaluation>(fluidState.saturation(wettingPhaseIdx));
318  Evaluation Swe = Toolbox::min((Sw - params.Swr()) / (1 - params.Swr()), 1.);
319  Evaluation Ste = Toolbox::min((Sw + Sn - params.Swr()) / (1 - params.Swr()), 1.);
320 
321  // regularization
322  if(Swe <= 0.0) Swe = 0.;
323  if(Ste <= 0.0) Ste = 0.;
324  if(Ste - Swe <= 0.0) return 0.;
325 
326  Evaluation krn_;
327  krn_ = Toolbox::pow(1 - Toolbox::pow(Swe, 1/params.vgM()), params.vgM());
328  krn_ -= Toolbox::pow(1 - Toolbox::pow(Ste, 1/params.vgM()), params.vgM());
329  krn_ *= krn_;
330 
331  if (params.krRegardsSnr())
332  {
333  // regard Snr in the permeability of the non-wetting
334  // phase, see Helmig1997
335  const Evaluation& resIncluded =
336  Toolbox::max(Toolbox::min(Sw - params.Snr() / (1-params.Swr()), 1.0), 0.0);
337  krn_ *= Toolbox::sqrt(resIncluded );
338  }
339  else
340  krn_ *= Toolbox::sqrt(Sn / (1 - params.Swr()));
341 
342  return krn_;
343  }
344 
345 
356  template <class FluidState, class Evaluation = typename FluidState::Scalar>
357  static Evaluation krg(const Params &params, const FluidState &fluidState)
358  {
360  typedef MathToolbox<Evaluation> Toolbox;
361 
362  const Evaluation& Sg =
363  FsToolbox::template toLhs<Evaluation>(fluidState.saturation(gasPhaseIdx));
364  const Evaluation& Se = Toolbox::min(((1-Sg) - params.Sgr()) / (1 - params.Sgr()), 1.);
365 
366  // regularization
367  if(Se > 1.0)
368  return 0.0;
369  if(Se < 0.0)
370  return 1.0;
371 
372  Evaluation scaleFactor = 1.;
373  if (Sg<=0.1) {
374  scaleFactor = (Sg - params.Sgr())/(0.1 - params.Sgr());
375  if (scaleFactor < 0.)
376  return 0.0;
377  }
378 
379  return scaleFactor
380  * Toolbox::pow(1 - Se, 1.0/3.)
381  * Toolbox::pow(1 - Toolbox::pow(Se, 1/params.vgM()), 2*params.vgM());
382  }
383 };
384 } // namespace Opm
385 
386 #endif
Definition: MathToolbox.hpp:39
Definition: Air_Mesitylene.hpp:31
Evaluation< Scalar, VarSetTag, numVars > max(const Evaluation< Scalar, VarSetTag, numVars > &x1, const Evaluation< Scalar, VarSetTag, numVars > &x2)
Definition: Math.hpp:114
Evaluation< Scalar, VarSetTag, numVars > sqrt(const Evaluation< Scalar, VarSetTag, numVars > &x)
Definition: Math.hpp:278
Specification of the material params for the three-phase van Genuchten capillary pressure model...
Evaluation< Scalar, VarSetTag, numVars > min(const Evaluation< Scalar, VarSetTag, numVars > &x1, const Evaluation< Scalar, VarSetTag, numVars > &x2)
Definition: Math.hpp:61
Implementation of three-phase capillary pressure and relative permeability relations proposed by Park...
Definition: ThreePhaseParkerVanGenuchten.hpp:50
Evaluation< Scalar, VarSetTag, numVars > pow(const Evaluation< Scalar, VarSetTag, numVars > &base, Scalar exp)
Definition: Math.hpp:312
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...