My Project
Spe5FluidSystem.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  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
27 #ifndef OPM_SPE5_FLUID_SYSTEM_HPP
28 #define OPM_SPE5_FLUID_SYSTEM_HPP
29 
30 #include "BaseFluidSystem.hpp"
31 #include "Spe5ParameterCache.hpp"
32 
35 
37 
38 namespace Opm {
39 
54 template <class Scalar>
56  : public BaseFluidSystem<Scalar, Spe5FluidSystem<Scalar> >
57 {
59 
60  typedef typename ::Opm::PengRobinsonMixture<Scalar, ThisType> PengRobinsonMixture;
61  typedef typename ::Opm::PengRobinson<Scalar> PengRobinson;
62 
63  static const Scalar R;
64 
65 public:
67  template <class Evaluation>
68  struct ParameterCache : public Spe5ParameterCache<Evaluation, ThisType>
69  {};
70 
71  /****************************************
72  * Fluid phase parameters
73  ****************************************/
74 
76  static const int numPhases = 3;
77 
79  static const int gasPhaseIdx = 0;
81  static const int waterPhaseIdx = 1;
83  static const int oilPhaseIdx = 2;
84 
86  typedef ::Opm::H2O<Scalar> H2O;
87 
89  static const char* phaseName(unsigned phaseIdx)
90  {
91  static const char* name[] = {
92  "gas",
93  "water",
94  "oil",
95  };
96 
97  assert(phaseIdx < numPhases);
98  return name[phaseIdx];
99  }
100 
102  static bool isLiquid(unsigned phaseIdx)
103  {
104  //assert(0 <= phaseIdx && phaseIdx < numPhases);
105  return phaseIdx != gasPhaseIdx;
106  }
107 
113  static bool isCompressible(unsigned /*phaseIdx*/)
114  {
115  //assert(0 <= phaseIdx && phaseIdx < numPhases);
116  return true;
117  }
118 
120  static bool isIdealGas(unsigned /*phaseIdx*/)
121  {
122  //assert(0 <= phaseIdx && phaseIdx < numPhases);
123  return false; // gas is not ideal here!
124  }
125 
127  static bool isIdealMixture(unsigned phaseIdx)
128  {
129  // always use the reference oil for the fugacity coefficents,
130  // so they cannot be dependent on composition and they the
131  // phases thus always an ideal mixture
132  return phaseIdx == waterPhaseIdx;
133  }
134 
135  /****************************************
136  * Component related parameters
137  ****************************************/
138 
140  static const int numComponents = 7;
141 
142  static const int H2OIdx = 0;
143  static const int C1Idx = 1;
144  static const int C3Idx = 2;
145  static const int C6Idx = 3;
146  static const int C10Idx = 4;
147  static const int C15Idx = 5;
148  static const int C20Idx = 6;
149 
151  static const char* componentName(unsigned compIdx)
152  {
153  static const char* name[] = {
154  H2O::name(),
155  "C1",
156  "C3",
157  "C6",
158  "C10",
159  "C15",
160  "C20"
161  };
162 
163  assert(0 <= compIdx && compIdx < numComponents);
164  return name[compIdx];
165  }
166 
168  static Scalar molarMass(unsigned compIdx)
169  {
170  return
171  (compIdx == H2OIdx)
172  ? H2O::molarMass()
173  : (compIdx == C1Idx)
174  ? 16.04e-3
175  : (compIdx == C3Idx)
176  ? 44.10e-3
177  : (compIdx == C6Idx)
178  ? 86.18e-3
179  : (compIdx == C10Idx)
180  ? 142.29e-3
181  : (compIdx == C15Idx)
182  ? 206.00e-3
183  : (compIdx == C20Idx)
184  ? 282.00e-3
185  : 1e30;
186  }
187 
191  static Scalar criticalTemperature(unsigned compIdx)
192  {
193  return
194  (compIdx == H2OIdx)
196  : (compIdx == C1Idx)
197  ? 343.0*5/9
198  : (compIdx == C3Idx)
199  ? 665.7*5/9
200  : (compIdx == C6Idx)
201  ? 913.4*5/9
202  : (compIdx == C10Idx)
203  ? 1111.8*5/9
204  : (compIdx == C15Idx)
205  ? 1270.0*5/9
206  : (compIdx == C20Idx)
207  ? 1380.0*5/9
208  : 1e30;
209  }
210 
214  static Scalar criticalPressure(unsigned compIdx)
215  {
216  return
217  (compIdx == H2OIdx)
219  : (compIdx == C1Idx)
220  ? 667.8 * 6894.7573
221  : (compIdx == C3Idx)
222  ? 616.3 * 6894.7573
223  : (compIdx == C6Idx)
224  ? 436.9 * 6894.7573
225  : (compIdx == C10Idx)
226  ? 304.0 * 6894.7573
227  : (compIdx == C15Idx)
228  ? 200.0 * 6894.7573
229  : (compIdx == C20Idx)
230  ? 162.0 * 6894.7573
231  : 1e30;
232  }
233 
237  static Scalar criticalMolarVolume(unsigned compIdx)
238  {
239  return
240  (compIdx == H2OIdx)
242  : (compIdx == C1Idx)
244  : (compIdx == C3Idx)
246  : (compIdx == C6Idx)
248  : (compIdx == C10Idx)
250  : (compIdx == C15Idx)
252  : (compIdx == C20Idx)
254  : 1e30;
255  }
256 
260  static Scalar acentricFactor(unsigned compIdx)
261  {
262  return
263  (compIdx == H2OIdx)
265  : (compIdx == C1Idx)
266  ? 0.0130
267  : (compIdx == C3Idx)
268  ? 0.1524
269  : (compIdx == C6Idx)
270  ? 0.3007
271  : (compIdx == C10Idx)
272  ? 0.4885
273  : (compIdx == C15Idx)
274  ? 0.6500
275  : (compIdx == C20Idx)
276  ? 0.8500
277  : 1e30;
278  }
279 
285  static Scalar interactionCoefficient(unsigned comp1Idx, unsigned comp2Idx)
286  {
287  unsigned i = std::min(comp1Idx, comp2Idx);
288  unsigned j = std::max(comp1Idx, comp2Idx);
289  if (i == C1Idx && (j == C15Idx || j == C20Idx))
290  return 0.05;
291  else if (i == C3Idx && (j == C15Idx || j == C20Idx))
292  return 0.005;
293  return 0;
294  }
295 
296  /****************************************
297  * Methods which compute stuff
298  ****************************************/
299 
308  static void init(Scalar minT = 273.15,
309  Scalar maxT = 373.15,
310  Scalar minP = 1e4,
311  Scalar maxP = 100e6)
312  {
313  PengRobinsonParamsMixture<Scalar, ThisType, gasPhaseIdx, /*useSpe5=*/true> prParams;
314 
315  // find envelopes of the 'a' and 'b' parameters for the range
316  // minT <= T <= maxT and minP <= p <= maxP. For
317  // this we take advantage of the fact that 'a' and 'b' for
318  // mixtures is just a convex combination of the attractive and
319  // repulsive parameters of the pure components
320 
321  Scalar minA = 1e30, maxA = -1e30;
322  Scalar minB = 1e30, maxB = -1e30;
323 
324  prParams.updatePure(minT, minP);
325  for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
326  minA = std::min(prParams.pureParams(compIdx).a(), minA);
327  maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
328  minB = std::min(prParams.pureParams(compIdx).b(), minB);
329  maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
330  };
331 
332  prParams.updatePure(maxT, minP);
333  for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
334  minA = std::min(prParams.pureParams(compIdx).a(), minA);
335  maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
336  minB = std::min(prParams.pureParams(compIdx).b(), minB);
337  maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
338  };
339 
340  prParams.updatePure(minT, maxP);
341  for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
342  minA = std::min(prParams.pureParams(compIdx).a(), minA);
343  maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
344  minB = std::min(prParams.pureParams(compIdx).b(), minB);
345  maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
346  };
347 
348  prParams.updatePure(maxT, maxP);
349  for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
350  minA = std::min(prParams.pureParams(compIdx).a(), minA);
351  maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
352  minB = std::min(prParams.pureParams(compIdx).b(), minB);
353  maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
354  };
355 
356  PengRobinson::init(/*aMin=*/minA, /*aMax=*/maxA, /*na=*/100,
357  /*bMin=*/minB, /*bMax=*/maxB, /*nb=*/200);
358  }
359 
361  template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
362  static LhsEval density(const FluidState& fluidState,
363  const ParameterCache<ParamCacheEval>& paramCache,
364  unsigned phaseIdx)
365  {
366  assert(phaseIdx < numPhases);
367 
368  return fluidState.averageMolarMass(phaseIdx)/paramCache.molarVolume(phaseIdx);
369  }
370 
372  template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
373  static LhsEval viscosity(const FluidState& /*fluidState*/,
374  const ParameterCache<ParamCacheEval>& /*paramCache*/,
375  unsigned phaseIdx)
376  {
377  assert(phaseIdx <= numPhases);
378 
379  if (phaseIdx == gasPhaseIdx) {
380  // given by SPE-5 in table on page 64. we use a constant
381  // viscosity, though...
382  return 0.0170e-2 * 0.1;
383  }
384  else if (phaseIdx == waterPhaseIdx)
385  // given by SPE-5: 0.7 centi-Poise = 0.0007 Pa s
386  return 0.7e-2 * 0.1;
387  else {
388  assert(phaseIdx == oilPhaseIdx);
389  // given by SPE-5 in table on page 64. we use a constant
390  // viscosity, though...
391  return 0.208e-2 * 0.1;
392  }
393  }
394 
396  template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
397  static LhsEval fugacityCoefficient(const FluidState& fluidState,
398  const ParameterCache<ParamCacheEval>& paramCache,
399  unsigned phaseIdx,
400  unsigned compIdx)
401  {
402  assert(phaseIdx <= numPhases);
403  assert(compIdx <= numComponents);
404 
405  if (phaseIdx == oilPhaseIdx || phaseIdx == gasPhaseIdx)
407  paramCache,
408  phaseIdx,
409  compIdx);
410  else {
411  assert(phaseIdx == waterPhaseIdx);
412  return
413  henryCoeffWater_(compIdx, fluidState.temperature(waterPhaseIdx))
414  / fluidState.pressure(waterPhaseIdx);
415  }
416  }
417 
418 protected:
419  template <class LhsEval>
420  static LhsEval henryCoeffWater_(unsigned compIdx, const LhsEval& temperature)
421  {
422  // use henry's law for the solutes and the vapor pressure for
423  // the solvent.
424  switch (compIdx) {
425  case H2OIdx: return H2O::vaporPressure(temperature);
426 
427  // the values of the Henry constant for the solutes have
428  // are faked so far...
429  case C1Idx: return 5.57601e+09;
430  case C3Idx: return 1e10;
431  case C6Idx: return 1e10;
432  case C10Idx: return 1e10;
433  case C15Idx: return 1e10;
434  case C20Idx: return 1e10;
435  default: throw std::logic_error("Unknown component index "+std::to_string(compIdx));
436  }
437  }
438 };
439 
440 template <class Scalar>
441 const Scalar Spe5FluidSystem<Scalar>::R = Constants<Scalar>::R;
442 
443 } // namespace Opm
444 
445 #endif
The base class for all fluid systems.
A central place for various physical constants occuring in some equations.
Implements the Peng-Robinson equation of state for a mixture.
Specifies the parameter cache used by the SPE-5 fluid system.
Class implementing cubic splines.
The base class for all fluid systems.
Definition: BaseFluidSystem.hpp:44
Scalar Scalar
The type used for scalar quantities.
Definition: BaseFluidSystem.hpp:49
static const Scalar R
The ideal gas constant [J/(mol K)].
Definition: Constants.hpp:45
static const Scalar criticalTemperature()
Returns the critical temperature of water.
Definition: H2O.hpp:92
static const char * name()
A human readable name for the water.
Definition: H2O.hpp:74
static Evaluation vaporPressure(Evaluation temperature)
The vapor pressure in of pure water at a given temperature.
Definition: H2O.hpp:138
static const Scalar criticalMolarVolume()
Returns the molar volume of water at the critical point.
Definition: H2O.hpp:110
static const Scalar acentricFactor()
The acentric factor of water.
Definition: H2O.hpp:86
static const Scalar criticalPressure()
Returns the critical pressure of water.
Definition: H2O.hpp:98
static const Scalar molarMass()
The molar mass in of water.
Definition: H2O.hpp:80
Implements the Peng-Robinson equation of state for a mixture.
Definition: PengRobinsonMixture.hpp:41
static LhsEval computeFugacityCoefficient(const FluidState &fs, const Params &params, unsigned phaseIdx, unsigned compIdx)
Returns the fugacity coefficient of an individual component in the phase.
Definition: PengRobinsonMixture.hpp:89
The mixing rule for the oil and the gas phases of the SPE5 problem.
Definition: PengRobinsonParamsMixture.hpp:60
void updatePure(const FluidState &fluidState)
Update Peng-Robinson parameters for the pure components.
Definition: PengRobinsonParamsMixture.hpp:82
const PureParams & pureParams(unsigned compIdx) const
Return the Peng-Robinson parameters of a pure substance,.
Definition: PengRobinsonParamsMixture.hpp:205
Scalar a() const
Returns the attractive parameter 'a' of the Peng-Robinson fluid.
Definition: PengRobinsonParams.hpp:50
Scalar b() const
Returns the repulsive parameter 'b' of the Peng-Robinson fluid.
Definition: PengRobinsonParams.hpp:57
Implements the Peng-Robinson equation of state for liquids and gases.
Definition: PengRobinson.hpp:56
The fluid system for the oil, gas and water phases of the SPE5 problem.
Definition: Spe5FluidSystem.hpp:57
static const int oilPhaseIdx
Index of the oil phase.
Definition: Spe5FluidSystem.hpp:83
static bool isIdealMixture(unsigned phaseIdx)
Returns true if and only if a fluid phase is assumed to be an ideal mixture.
Definition: Spe5FluidSystem.hpp:127
static const char * componentName(unsigned compIdx)
Return the human readable name of a component.
Definition: Spe5FluidSystem.hpp:151
static const int H2OIdx
Index of the water component.
Definition: Spe5FluidSystem.hpp:142
static const int numComponents
Number of chemical species in the fluid system.
Definition: Spe5FluidSystem.hpp:140
static const int C15Idx
Index of the C15 component.
Definition: Spe5FluidSystem.hpp:147
static const int numPhases
Number of fluid phases in the fluid system.
Definition: Spe5FluidSystem.hpp:76
static LhsEval fugacityCoefficient(const FluidState &fluidState, const ParameterCache< ParamCacheEval > &paramCache, unsigned phaseIdx, unsigned compIdx)
Calculate the fugacity coefficient [Pa] of an individual component in a fluid phase.
Definition: Spe5FluidSystem.hpp:397
static Scalar criticalPressure(unsigned compIdx)
Critical pressure of a component [Pa].
Definition: Spe5FluidSystem.hpp:214
static LhsEval density(const FluidState &fluidState, const ParameterCache< ParamCacheEval > &paramCache, unsigned phaseIdx)
Calculate the density [kg/m^3] of a fluid phase.
Definition: Spe5FluidSystem.hpp:362
static Scalar criticalTemperature(unsigned compIdx)
Critical temperature of a component [K].
Definition: Spe5FluidSystem.hpp:191
static Scalar criticalMolarVolume(unsigned compIdx)
Molar volume of a component at the critical point [m^3/mol].
Definition: Spe5FluidSystem.hpp:237
static const char * phaseName(unsigned phaseIdx)
Return the human readable name of a fluid phase.
Definition: Spe5FluidSystem.hpp:89
static Scalar acentricFactor(unsigned compIdx)
The acentric factor of a component [].
Definition: Spe5FluidSystem.hpp:260
static LhsEval viscosity(const FluidState &, const ParameterCache< ParamCacheEval > &, unsigned phaseIdx)
Calculate the dynamic viscosity of a fluid phase [Pa*s].
Definition: Spe5FluidSystem.hpp:373
static void init(Scalar minT=273.15, Scalar maxT=373.15, Scalar minP=1e4, Scalar maxP=100e6)
Initialize the fluid system's static parameters.
Definition: Spe5FluidSystem.hpp:308
static const int C1Idx
Index of the C1 component.
Definition: Spe5FluidSystem.hpp:143
static bool isCompressible(unsigned)
Returns true if and only if a fluid phase is assumed to be compressible.
Definition: Spe5FluidSystem.hpp:113
static const int C20Idx
Index of the C20 component.
Definition: Spe5FluidSystem.hpp:148
static const int C6Idx
Index of the C6 component.
Definition: Spe5FluidSystem.hpp:145
static const int C10Idx
Index of the C10 component.
Definition: Spe5FluidSystem.hpp:146
static Scalar interactionCoefficient(unsigned comp1Idx, unsigned comp2Idx)
Returns the interaction coefficient for two components.
Definition: Spe5FluidSystem.hpp:285
static const int waterPhaseIdx
Index of the water phase.
Definition: Spe5FluidSystem.hpp:81
static Scalar molarMass(unsigned compIdx)
Return the molar mass of a component in [kg/mol].
Definition: Spe5FluidSystem.hpp:168
::Opm::H2O< Scalar > H2O
The component for pure water to be used.
Definition: Spe5FluidSystem.hpp:86
static const int C3Idx
Index of the C3 component.
Definition: Spe5FluidSystem.hpp:144
static bool isLiquid(unsigned phaseIdx)
Return whether a phase is liquid.
Definition: Spe5FluidSystem.hpp:102
static const int gasPhaseIdx
Index of the gas phase.
Definition: Spe5FluidSystem.hpp:79
static bool isIdealGas(unsigned)
Returns true if and only if a fluid phase is assumed to be an ideal gas.
Definition: Spe5FluidSystem.hpp:120
Specifies the parameter cache used by the SPE-5 fluid system.
Definition: Spe5ParameterCache.hpp:47
Scalar molarVolume(unsigned phaseIdx) const
Returns the molar volume of a phase [m^3/mol].
Definition: Spe5ParameterCache.hpp:202
The type of the fluid system's parameter cache.
Definition: Spe5FluidSystem.hpp:69