My Project
GasPvtMultiplexer.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_GAS_PVT_MULTIPLEXER_HPP
28 #define OPM_GAS_PVT_MULTIPLEXER_HPP
29 
30 #include "DryGasPvt.hpp"
31 #include "DryHumidGasPvt.hpp"
32 #include "WetHumidGasPvt.hpp"
33 #include "WetGasPvt.hpp"
34 #include "GasPvtThermal.hpp"
35 #include "Co2GasPvt.hpp"
36 
37 #if HAVE_ECL_INPUT
38 #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
39 #endif
40 
41 namespace Opm {
42 #define OPM_GAS_PVT_MULTIPLEXER_CALL(codeToCall) \
43  switch (gasPvtApproach_) { \
44  case GasPvtApproach::DryGasPvt: { \
45  auto& pvtImpl = getRealPvt<GasPvtApproach::DryGasPvt>(); \
46  codeToCall; \
47  break; \
48  } \
49  case GasPvtApproach::DryHumidGasPvt: { \
50  auto& pvtImpl = getRealPvt<GasPvtApproach::DryHumidGasPvt>(); \
51  codeToCall; \
52  break; \
53  } \
54  case GasPvtApproach::WetHumidGasPvt: { \
55  auto& pvtImpl = getRealPvt<GasPvtApproach::WetHumidGasPvt>(); \
56  codeToCall; \
57  break; \
58  } \
59  case GasPvtApproach::WetGasPvt: { \
60  auto& pvtImpl = getRealPvt<GasPvtApproach::WetGasPvt>(); \
61  codeToCall; \
62  break; \
63  } \
64  case GasPvtApproach::ThermalGasPvt: { \
65  auto& pvtImpl = getRealPvt<GasPvtApproach::ThermalGasPvt>(); \
66  codeToCall; \
67  break; \
68  } \
69  case GasPvtApproach::Co2GasPvt: { \
70  auto& pvtImpl = getRealPvt<GasPvtApproach::Co2GasPvt>(); \
71  codeToCall; \
72  break; \
73  } \
74  case GasPvtApproach::NoGasPvt: \
75  throw std::logic_error("Not implemented: Gas PVT of this deck!"); \
76  } \
77 
78 enum class GasPvtApproach {
79  NoGasPvt,
80  DryGasPvt,
81  DryHumidGasPvt,
82  WetHumidGasPvt,
83  WetGasPvt,
84  ThermalGasPvt,
85  Co2GasPvt
86 };
87 
98 template <class Scalar, bool enableThermal = true>
100 {
101 public:
103  {
104  gasPvtApproach_ = GasPvtApproach::NoGasPvt;
105  realGasPvt_ = nullptr;
106  }
107 
108  GasPvtMultiplexer(GasPvtApproach approach, void* realGasPvt)
109  : gasPvtApproach_(approach)
110  , realGasPvt_(realGasPvt)
111  { }
112 
114  {
115  *this = data;
116  }
117 
119  {
120  switch (gasPvtApproach_) {
121  case GasPvtApproach::DryGasPvt: {
122  delete &getRealPvt<GasPvtApproach::DryGasPvt>();
123  break;
124  }
125  case GasPvtApproach::DryHumidGasPvt: {
126  delete &getRealPvt<GasPvtApproach::DryHumidGasPvt>();
127  break;
128  }
129  case GasPvtApproach::WetHumidGasPvt: {
130  delete &getRealPvt<GasPvtApproach::WetHumidGasPvt>();
131  break;
132  }
133  case GasPvtApproach::WetGasPvt: {
134  delete &getRealPvt<GasPvtApproach::WetGasPvt>();
135  break;
136  }
137  case GasPvtApproach::ThermalGasPvt: {
138  delete &getRealPvt<GasPvtApproach::ThermalGasPvt>();
139  break;
140  }
141  case GasPvtApproach::Co2GasPvt: {
142  delete &getRealPvt<GasPvtApproach::Co2GasPvt>();
143  break;
144  }
145  case GasPvtApproach::NoGasPvt:
146  break;
147  }
148  }
149 
150 #if HAVE_ECL_INPUT
156  void initFromState(const EclipseState& eclState, const Schedule& schedule)
157  {
158  if (!eclState.runspec().phases().active(Phase::GAS))
159  return;
160  if (eclState.runspec().co2Storage())
161  setApproach(GasPvtApproach::Co2GasPvt);
162  else if (enableThermal && eclState.getSimulationConfig().isThermal())
163  setApproach(GasPvtApproach::ThermalGasPvt);
164  else if (!eclState.getTableManager().getPvtgwTables().empty() && !eclState.getTableManager().getPvtgTables().empty())
165  setApproach(GasPvtApproach::WetHumidGasPvt);
166  else if (!eclState.getTableManager().getPvtgTables().empty())
167  setApproach(GasPvtApproach::WetGasPvt);
168  else if (eclState.getTableManager().hasTables("PVDG"))
169  setApproach(GasPvtApproach::DryGasPvt);
170  else if (!eclState.getTableManager().getPvtgwTables().empty())
171  setApproach(GasPvtApproach::DryHumidGasPvt);
172 
173 
174  OPM_GAS_PVT_MULTIPLEXER_CALL(pvtImpl.initFromState(eclState, schedule));
175  }
176 #endif // HAVE_ECL_INPUT
177 
178  void setApproach(GasPvtApproach gasPvtAppr)
179  {
180  switch (gasPvtAppr) {
181  case GasPvtApproach::DryGasPvt:
182  realGasPvt_ = new DryGasPvt<Scalar>;
183  break;
184 
185  case GasPvtApproach::DryHumidGasPvt:
186  realGasPvt_ = new DryHumidGasPvt<Scalar>;
187  break;
188 
189  case GasPvtApproach::WetHumidGasPvt:
190  realGasPvt_ = new WetHumidGasPvt<Scalar>;
191  break;
192 
193  case GasPvtApproach::WetGasPvt:
194  realGasPvt_ = new WetGasPvt<Scalar>;
195  break;
196 
197  case GasPvtApproach::ThermalGasPvt:
198  realGasPvt_ = new GasPvtThermal<Scalar>;
199  break;
200 
201  case GasPvtApproach::Co2GasPvt:
202  realGasPvt_ = new Co2GasPvt<Scalar>;
203  break;
204 
205  case GasPvtApproach::NoGasPvt:
206  throw std::logic_error("Not implemented: Gas PVT of this deck!");
207  }
208 
209  gasPvtApproach_ = gasPvtAppr;
210  }
211 
212  void initEnd()
213  { OPM_GAS_PVT_MULTIPLEXER_CALL(pvtImpl.initEnd()); }
214 
218  unsigned numRegions() const
219  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.numRegions()); return 1; }
220 
224  const Scalar gasReferenceDensity(unsigned regionIdx)
225  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.gasReferenceDensity(regionIdx)); return 2.; }
226 
230  template <class Evaluation>
231  Evaluation internalEnergy(unsigned regionIdx,
232  const Evaluation& temperature,
233  const Evaluation& pressure,
234  const Evaluation& Rv) const
235  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.internalEnergy(regionIdx, temperature, pressure, Rv)); return 0; }
236 
240  template <class Evaluation = Scalar>
241  Evaluation viscosity(unsigned regionIdx,
242  const Evaluation& temperature,
243  const Evaluation& pressure,
244  const Evaluation& Rv,
245  const Evaluation& Rvw ) const
246  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure, Rv, Rvw)); return 0; }
247 
251  template <class Evaluation = Scalar>
252  Evaluation saturatedViscosity(unsigned regionIdx,
253  const Evaluation& temperature,
254  const Evaluation& pressure) const
255  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedViscosity(regionIdx, temperature, pressure)); return 0; }
256 
260  template <class Evaluation = Scalar>
261  Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
262  const Evaluation& temperature,
263  const Evaluation& pressure,
264  const Evaluation& Rv,
265  const Evaluation& Rvw) const
266  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rv, Rvw)); return 0; }
267 
271  template <class Evaluation = Scalar>
272  Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
273  const Evaluation& temperature,
274  const Evaluation& pressure) const
275  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedInverseFormationVolumeFactor(regionIdx, temperature, pressure)); return 0; }
276 
280  template <class Evaluation = Scalar>
281  Evaluation saturatedOilVaporizationFactor(unsigned regionIdx,
282  const Evaluation& temperature,
283  const Evaluation& pressure) const
284  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilVaporizationFactor(regionIdx, temperature, pressure)); return 0; }
285 
289  template <class Evaluation = Scalar>
290  Evaluation saturatedOilVaporizationFactor(unsigned regionIdx,
291  const Evaluation& temperature,
292  const Evaluation& pressure,
293  const Evaluation& oilSaturation,
294  const Evaluation& maxOilSaturation) const
295  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilVaporizationFactor(regionIdx, temperature, pressure, oilSaturation, maxOilSaturation)); return 0; }
296 
300  template <class Evaluation = Scalar>
301  Evaluation saturatedWaterVaporizationFactor(unsigned regionIdx,
302  const Evaluation& temperature,
303  const Evaluation& pressure) const
304  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedWaterVaporizationFactor(regionIdx, temperature, pressure)); return 0; }
305 
312  template <class Evaluation = Scalar>
313  Evaluation saturationPressure(unsigned regionIdx,
314  const Evaluation& temperature,
315  const Evaluation& Rv) const
316  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturationPressure(regionIdx, temperature, Rv)); return 0; }
317 
321  template <class Evaluation>
322  Evaluation diffusionCoefficient(const Evaluation& temperature,
323  const Evaluation& pressure,
324  unsigned compIdx) const
325  {
326  OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.diffusionCoefficient(temperature, pressure, compIdx)); return 0;
327  }
328 
334  GasPvtApproach gasPvtApproach() const
335  { return gasPvtApproach_; }
336 
337  // get the parameter object for the dry gas case
338  template <GasPvtApproach approachV>
339  typename std::enable_if<approachV == GasPvtApproach::DryGasPvt, DryGasPvt<Scalar> >::type& getRealPvt()
340  {
341  assert(gasPvtApproach() == approachV);
342  return *static_cast<DryGasPvt<Scalar>* >(realGasPvt_);
343  }
344 
345  template <GasPvtApproach approachV>
346  typename std::enable_if<approachV == GasPvtApproach::DryGasPvt, const DryGasPvt<Scalar> >::type& getRealPvt() const
347  {
348  assert(gasPvtApproach() == approachV);
349  return *static_cast<const DryGasPvt<Scalar>* >(realGasPvt_);
350  }
351 
352  // get the parameter object for the dry humid gas case
353  template <GasPvtApproach approachV>
354  typename std::enable_if<approachV == GasPvtApproach::DryHumidGasPvt, DryHumidGasPvt<Scalar> >::type& getRealPvt()
355  {
356  assert(gasPvtApproach() == approachV);
357  return *static_cast<DryHumidGasPvt<Scalar>* >(realGasPvt_);
358  }
359 
360  template <GasPvtApproach approachV>
361  typename std::enable_if<approachV == GasPvtApproach::DryHumidGasPvt, const DryHumidGasPvt<Scalar> >::type& getRealPvt() const
362  {
363  assert(gasPvtApproach() == approachV);
364  return *static_cast<const DryHumidGasPvt<Scalar>* >(realGasPvt_);
365  }
366 
367  // get the parameter object for the wet humid gas case
368  template <GasPvtApproach approachV>
369  typename std::enable_if<approachV == GasPvtApproach::WetHumidGasPvt, WetHumidGasPvt<Scalar> >::type& getRealPvt()
370  {
371  assert(gasPvtApproach() == approachV);
372  return *static_cast<WetHumidGasPvt<Scalar>* >(realGasPvt_);
373  }
374 
375  template <GasPvtApproach approachV>
376  typename std::enable_if<approachV == GasPvtApproach::WetHumidGasPvt, const WetHumidGasPvt<Scalar> >::type& getRealPvt() const
377  {
378  assert(gasPvtApproach() == approachV);
379  return *static_cast<const WetHumidGasPvt<Scalar>* >(realGasPvt_);
380  }
381 
382  // get the parameter object for the wet gas case
383  template <GasPvtApproach approachV>
384  typename std::enable_if<approachV == GasPvtApproach::WetGasPvt, WetGasPvt<Scalar> >::type& getRealPvt()
385  {
386  assert(gasPvtApproach() == approachV);
387  return *static_cast<WetGasPvt<Scalar>* >(realGasPvt_);
388  }
389 
390  template <GasPvtApproach approachV>
391  typename std::enable_if<approachV == GasPvtApproach::WetGasPvt, const WetGasPvt<Scalar> >::type& getRealPvt() const
392  {
393  assert(gasPvtApproach() == approachV);
394  return *static_cast<const WetGasPvt<Scalar>* >(realGasPvt_);
395  }
396 
397  // get the parameter object for the thermal gas case
398  template <GasPvtApproach approachV>
399  typename std::enable_if<approachV == GasPvtApproach::ThermalGasPvt, GasPvtThermal<Scalar> >::type& getRealPvt()
400  {
401  assert(gasPvtApproach() == approachV);
402  return *static_cast<GasPvtThermal<Scalar>* >(realGasPvt_);
403  }
404  template <GasPvtApproach approachV>
405  typename std::enable_if<approachV == GasPvtApproach::ThermalGasPvt, const GasPvtThermal<Scalar> >::type& getRealPvt() const
406  {
407  assert(gasPvtApproach() == approachV);
408  return *static_cast<const GasPvtThermal<Scalar>* >(realGasPvt_);
409  }
410 
411  template <GasPvtApproach approachV>
412  typename std::enable_if<approachV == GasPvtApproach::Co2GasPvt, Co2GasPvt<Scalar> >::type& getRealPvt()
413  {
414  assert(gasPvtApproach() == approachV);
415  return *static_cast<Co2GasPvt<Scalar>* >(realGasPvt_);
416  }
417 
418  template <GasPvtApproach approachV>
419  typename std::enable_if<approachV == GasPvtApproach::Co2GasPvt, const Co2GasPvt<Scalar> >::type& getRealPvt() const
420  {
421  assert(gasPvtApproach() == approachV);
422  return *static_cast<const Co2GasPvt<Scalar>* >(realGasPvt_);
423  }
424 
425  const void* realGasPvt() const { return realGasPvt_; }
426 
427  bool operator==(const GasPvtMultiplexer<Scalar,enableThermal>& data) const
428  {
429  if (this->gasPvtApproach() != data.gasPvtApproach())
430  return false;
431 
432  switch (gasPvtApproach_) {
433  case GasPvtApproach::DryGasPvt:
434  return *static_cast<const DryGasPvt<Scalar>*>(realGasPvt_) ==
435  *static_cast<const DryGasPvt<Scalar>*>(data.realGasPvt_);
436  case GasPvtApproach::DryHumidGasPvt:
437  return *static_cast<const DryHumidGasPvt<Scalar>*>(realGasPvt_) ==
438  *static_cast<const DryHumidGasPvt<Scalar>*>(data.realGasPvt_);
439  case GasPvtApproach::WetHumidGasPvt:
440  return *static_cast<const WetHumidGasPvt<Scalar>*>(realGasPvt_) ==
441  *static_cast<const WetHumidGasPvt<Scalar>*>(data.realGasPvt_);
442  case GasPvtApproach::WetGasPvt:
443  return *static_cast<const WetGasPvt<Scalar>*>(realGasPvt_) ==
444  *static_cast<const WetGasPvt<Scalar>*>(data.realGasPvt_);
445  case GasPvtApproach::ThermalGasPvt:
446  return *static_cast<const GasPvtThermal<Scalar>*>(realGasPvt_) ==
447  *static_cast<const GasPvtThermal<Scalar>*>(data.realGasPvt_);
448  case GasPvtApproach::Co2GasPvt:
449  return *static_cast<const Co2GasPvt<Scalar>*>(realGasPvt_) ==
450  *static_cast<const Co2GasPvt<Scalar>*>(data.realGasPvt_);
451  default:
452  return true;
453  }
454  }
455 
456  GasPvtMultiplexer<Scalar,enableThermal>& operator=(const GasPvtMultiplexer<Scalar,enableThermal>& data)
457  {
458  gasPvtApproach_ = data.gasPvtApproach_;
459  switch (gasPvtApproach_) {
460  case GasPvtApproach::DryGasPvt:
461  realGasPvt_ = new DryGasPvt<Scalar>(*static_cast<const DryGasPvt<Scalar>*>(data.realGasPvt_));
462  break;
463  case GasPvtApproach::DryHumidGasPvt:
464  realGasPvt_ = new DryHumidGasPvt<Scalar>(*static_cast<const DryHumidGasPvt<Scalar>*>(data.realGasPvt_));
465  break;
466  case GasPvtApproach::WetHumidGasPvt:
467  realGasPvt_ = new WetHumidGasPvt<Scalar>(*static_cast<const WetHumidGasPvt<Scalar>*>(data.realGasPvt_));
468  break;
469  case GasPvtApproach::WetGasPvt:
470  realGasPvt_ = new WetGasPvt<Scalar>(*static_cast<const WetGasPvt<Scalar>*>(data.realGasPvt_));
471  break;
472  case GasPvtApproach::ThermalGasPvt:
473  realGasPvt_ = new GasPvtThermal<Scalar>(*static_cast<const GasPvtThermal<Scalar>*>(data.realGasPvt_));
474  break;
475  case GasPvtApproach::Co2GasPvt:
476  realGasPvt_ = new Co2GasPvt<Scalar>(*static_cast<const Co2GasPvt<Scalar>*>(data.realGasPvt_));
477  break;
478  default:
479  break;
480  }
481 
482  return *this;
483  }
484 
485 private:
486  GasPvtApproach gasPvtApproach_;
487  void* realGasPvt_;
488 };
489 
490 #undef OPM_GAS_PVT_MULTIPLEXER_CALL
491 
492 } // namespace Opm
493 
494 #endif
This class represents the Pressure-Volume-Temperature relations of the gas phase for CO2.
This class represents the Pressure-Volume-Temperature relations of the gas phase without vaporized oi...
This class represents the Pressure-Volume-Temperature relations of the gas phase with vaporized water...
This class implements temperature dependence of the PVT properties of gas.
This class represents the Pressure-Volume-Temperature relations of the gas phas with vaporized oil.
This class represents the Pressure-Volume-Temperature relations of the gas phase with vaporized oil a...
This class represents the Pressure-Volume-Temperature relations of the gas phase for CO2.
Definition: Co2GasPvt.hpp:53
This class represents the Pressure-Volume-Temperature relations of the gas phase without vaporized oi...
Definition: DryGasPvt.hpp:50
This class represents the Pressure-Volume-Temperature relations of the gas phase with vaporized water...
Definition: DryHumidGasPvt.hpp:53
This class represents the Pressure-Volume-Temperature relations of the gas phase in the black-oil mod...
Definition: GasPvtMultiplexer.hpp:100
GasPvtApproach gasPvtApproach() const
Returns the concrete approach for calculating the PVT relations.
Definition: GasPvtMultiplexer.hpp:334
Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the formation volume factor [-] of oil saturated gas given a set of parameters.
Definition: GasPvtMultiplexer.hpp:272
unsigned numRegions() const
Return the number of PVT regions which are considered by this PVT-object.
Definition: GasPvtMultiplexer.hpp:218
Evaluation saturatedWaterVaporizationFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the water vaporization factor [m^3/m^3] of water saturated gas.
Definition: GasPvtMultiplexer.hpp:301
Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rv, const Evaluation &Rvw) const
Returns the formation volume factor [-] of the fluid phase.
Definition: GasPvtMultiplexer.hpp:261
Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rv, const Evaluation &Rvw) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition: GasPvtMultiplexer.hpp:241
Evaluation diffusionCoefficient(const Evaluation &temperature, const Evaluation &pressure, unsigned compIdx) const
Calculate the binary molecular diffusion coefficient for a component in a fluid phase [mol^2 * s / (k...
Definition: GasPvtMultiplexer.hpp:322
Evaluation saturatedOilVaporizationFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the oil vaporization factor [m^3/m^3] of oil saturated gas.
Definition: GasPvtMultiplexer.hpp:281
const Scalar gasReferenceDensity(unsigned regionIdx)
Return the reference density which are considered by this PVT-object.
Definition: GasPvtMultiplexer.hpp:224
Evaluation internalEnergy(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rv) const
Returns the specific enthalpy [J/kg] of gas given a set of parameters.
Definition: GasPvtMultiplexer.hpp:231
Evaluation saturationPressure(unsigned regionIdx, const Evaluation &temperature, const Evaluation &Rv) const
Returns the saturation pressure of the gas phase [Pa] depending on its mass fraction of the oil compo...
Definition: GasPvtMultiplexer.hpp:313
Evaluation saturatedOilVaporizationFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &oilSaturation, const Evaluation &maxOilSaturation) const
Returns the oil vaporization factor [m^3/m^3] of oil saturated gas.
Definition: GasPvtMultiplexer.hpp:290
Evaluation saturatedViscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the dynamic viscosity [Pa s] of oil saturated gas given a set of parameters.
Definition: GasPvtMultiplexer.hpp:252
This class implements temperature dependence of the PVT properties of gas.
Definition: GasPvtThermal.hpp:50
This class represents the Pressure-Volume-Temperature relations of the gas phas with vaporized oil.
Definition: WetGasPvt.hpp:52
This class represents the Pressure-Volume-Temperature relations of the gas phase with vaporized oil a...
Definition: WetHumidGasPvt.hpp:52