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 "WetGasPvt.hpp"
32 #include "GasPvtThermal.hpp"
33 #include "Co2GasPvt.hpp"
34 
35 #if HAVE_ECL_INPUT
36 #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
37 #endif
38 
39 namespace Opm {
40 #define OPM_GAS_PVT_MULTIPLEXER_CALL(codeToCall) \
41  switch (gasPvtApproach_) { \
42  case GasPvtApproach::DryGasPvt: { \
43  auto& pvtImpl = getRealPvt<GasPvtApproach::DryGasPvt>(); \
44  codeToCall; \
45  break; \
46  } \
47  case GasPvtApproach::WetGasPvt: { \
48  auto& pvtImpl = getRealPvt<GasPvtApproach::WetGasPvt>(); \
49  codeToCall; \
50  break; \
51  } \
52  case GasPvtApproach::ThermalGasPvt: { \
53  auto& pvtImpl = getRealPvt<GasPvtApproach::ThermalGasPvt>(); \
54  codeToCall; \
55  break; \
56  } \
57  case GasPvtApproach::Co2GasPvt: { \
58  auto& pvtImpl = getRealPvt<GasPvtApproach::Co2GasPvt>(); \
59  codeToCall; \
60  break; \
61  } \
62  case GasPvtApproach::NoGasPvt: \
63  throw std::logic_error("Not implemented: Gas PVT of this deck!"); \
64  } \
65 
66 enum class GasPvtApproach {
67  NoGasPvt,
68  DryGasPvt,
69  WetGasPvt,
70  ThermalGasPvt,
71  Co2GasPvt
72 };
73 
84 template <class Scalar, bool enableThermal = true>
86 {
87 public:
89  {
90  gasPvtApproach_ = GasPvtApproach::NoGasPvt;
91  realGasPvt_ = nullptr;
92  }
93 
94  GasPvtMultiplexer(GasPvtApproach approach, void* realGasPvt)
95  : gasPvtApproach_(approach)
96  , realGasPvt_(realGasPvt)
97  { }
98 
100  {
101  *this = data;
102  }
103 
105  {
106  switch (gasPvtApproach_) {
107  case GasPvtApproach::DryGasPvt: {
108  delete &getRealPvt<GasPvtApproach::DryGasPvt>();
109  break;
110  }
111  case GasPvtApproach::WetGasPvt: {
112  delete &getRealPvt<GasPvtApproach::WetGasPvt>();
113  break;
114  }
115  case GasPvtApproach::ThermalGasPvt: {
116  delete &getRealPvt<GasPvtApproach::ThermalGasPvt>();
117  break;
118  }
119  case GasPvtApproach::Co2GasPvt: {
120  delete &getRealPvt<GasPvtApproach::Co2GasPvt>();
121  break;
122  }
123  case GasPvtApproach::NoGasPvt:
124  break;
125  }
126  }
127 
128 #if HAVE_ECL_INPUT
134  void initFromState(const EclipseState& eclState, const Schedule& schedule)
135  {
136  if (!eclState.runspec().phases().active(Phase::GAS))
137  return;
138  if (eclState.runspec().co2Storage())
139  setApproach(GasPvtApproach::Co2GasPvt);
140  else if (enableThermal && eclState.getSimulationConfig().isThermal())
141  setApproach(GasPvtApproach::ThermalGasPvt);
142  else if (!eclState.getTableManager().getPvtgTables().empty())
143  setApproach(GasPvtApproach::WetGasPvt);
144  else if (eclState.getTableManager().hasTables("PVDG"))
145  setApproach(GasPvtApproach::DryGasPvt);
146 
147  OPM_GAS_PVT_MULTIPLEXER_CALL(pvtImpl.initFromState(eclState, schedule));
148  }
149 #endif // HAVE_ECL_INPUT
150 
151  void setApproach(GasPvtApproach gasPvtAppr)
152  {
153  switch (gasPvtAppr) {
154  case GasPvtApproach::DryGasPvt:
155  realGasPvt_ = new DryGasPvt<Scalar>;
156  break;
157 
158  case GasPvtApproach::WetGasPvt:
159  realGasPvt_ = new WetGasPvt<Scalar>;
160  break;
161 
162  case GasPvtApproach::ThermalGasPvt:
163  realGasPvt_ = new GasPvtThermal<Scalar>;
164  break;
165 
166  case GasPvtApproach::Co2GasPvt:
167  realGasPvt_ = new Co2GasPvt<Scalar>;
168  break;
169 
170  case GasPvtApproach::NoGasPvt:
171  throw std::logic_error("Not implemented: Gas PVT of this deck!");
172  }
173 
174  gasPvtApproach_ = gasPvtAppr;
175  }
176 
177  void initEnd()
178  { OPM_GAS_PVT_MULTIPLEXER_CALL(pvtImpl.initEnd()); }
179 
183  unsigned numRegions() const
184  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.numRegions()); return 1; }
185 
189  const Scalar gasReferenceDensity(unsigned regionIdx)
190  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.gasReferenceDensity(regionIdx)); return 2.; }
191 
195  template <class Evaluation>
196  Evaluation internalEnergy(unsigned regionIdx,
197  const Evaluation& temperature,
198  const Evaluation& pressure,
199  const Evaluation& Rv) const
200  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.internalEnergy(regionIdx, temperature, pressure, Rv)); return 0; }
201 
205  template <class Evaluation = Scalar>
206  Evaluation viscosity(unsigned regionIdx,
207  const Evaluation& temperature,
208  const Evaluation& pressure,
209  const Evaluation& Rv) const
210  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure, Rv)); return 0; }
211 
215  template <class Evaluation = Scalar>
216  Evaluation saturatedViscosity(unsigned regionIdx,
217  const Evaluation& temperature,
218  const Evaluation& pressure) const
219  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedViscosity(regionIdx, temperature, pressure)); return 0; }
220 
224  template <class Evaluation = Scalar>
225  Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
226  const Evaluation& temperature,
227  const Evaluation& pressure,
228  const Evaluation& Rv) const
229  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rv)); return 0; }
230 
234  template <class Evaluation = Scalar>
235  Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
236  const Evaluation& temperature,
237  const Evaluation& pressure) const
238  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedInverseFormationVolumeFactor(regionIdx, temperature, pressure)); return 0; }
239 
243  template <class Evaluation = Scalar>
244  Evaluation saturatedOilVaporizationFactor(unsigned regionIdx,
245  const Evaluation& temperature,
246  const Evaluation& pressure) const
247  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilVaporizationFactor(regionIdx, temperature, pressure)); return 0; }
248 
252  template <class Evaluation = Scalar>
253  Evaluation saturatedOilVaporizationFactor(unsigned regionIdx,
254  const Evaluation& temperature,
255  const Evaluation& pressure,
256  const Evaluation& oilSaturation,
257  const Evaluation& maxOilSaturation) const
258  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilVaporizationFactor(regionIdx, temperature, pressure, oilSaturation, maxOilSaturation)); return 0; }
259 
266  template <class Evaluation = Scalar>
267  Evaluation saturationPressure(unsigned regionIdx,
268  const Evaluation& temperature,
269  const Evaluation& Rv) const
270  { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturationPressure(regionIdx, temperature, Rv)); return 0; }
271 
275  template <class Evaluation>
276  Evaluation diffusionCoefficient(const Evaluation& temperature,
277  const Evaluation& pressure,
278  unsigned compIdx) const
279  {
280  OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.diffusionCoefficient(temperature, pressure, compIdx)); return 0;
281  }
282 
288  GasPvtApproach gasPvtApproach() const
289  { return gasPvtApproach_; }
290 
291  // get the parameter object for the dry gas case
292  template <GasPvtApproach approachV>
293  typename std::enable_if<approachV == GasPvtApproach::DryGasPvt, DryGasPvt<Scalar> >::type& getRealPvt()
294  {
295  assert(gasPvtApproach() == approachV);
296  return *static_cast<DryGasPvt<Scalar>* >(realGasPvt_);
297  }
298 
299  template <GasPvtApproach approachV>
300  typename std::enable_if<approachV == GasPvtApproach::DryGasPvt, const DryGasPvt<Scalar> >::type& getRealPvt() const
301  {
302  assert(gasPvtApproach() == approachV);
303  return *static_cast<const DryGasPvt<Scalar>* >(realGasPvt_);
304  }
305 
306  // get the parameter object for the wet gas case
307  template <GasPvtApproach approachV>
308  typename std::enable_if<approachV == GasPvtApproach::WetGasPvt, WetGasPvt<Scalar> >::type& getRealPvt()
309  {
310  assert(gasPvtApproach() == approachV);
311  return *static_cast<WetGasPvt<Scalar>* >(realGasPvt_);
312  }
313 
314  template <GasPvtApproach approachV>
315  typename std::enable_if<approachV == GasPvtApproach::WetGasPvt, const WetGasPvt<Scalar> >::type& getRealPvt() const
316  {
317  assert(gasPvtApproach() == approachV);
318  return *static_cast<const WetGasPvt<Scalar>* >(realGasPvt_);
319  }
320 
321  // get the parameter object for the thermal gas case
322  template <GasPvtApproach approachV>
323  typename std::enable_if<approachV == GasPvtApproach::ThermalGasPvt, GasPvtThermal<Scalar> >::type& getRealPvt()
324  {
325  assert(gasPvtApproach() == approachV);
326  return *static_cast<GasPvtThermal<Scalar>* >(realGasPvt_);
327  }
328 
329  template <GasPvtApproach approachV>
330  typename std::enable_if<approachV == GasPvtApproach::ThermalGasPvt, const GasPvtThermal<Scalar> >::type& getRealPvt() const
331  {
332  assert(gasPvtApproach() == approachV);
333  return *static_cast<const GasPvtThermal<Scalar>* >(realGasPvt_);
334  }
335 
336  template <GasPvtApproach approachV>
337  typename std::enable_if<approachV == GasPvtApproach::Co2GasPvt, Co2GasPvt<Scalar> >::type& getRealPvt()
338  {
339  assert(gasPvtApproach() == approachV);
340  return *static_cast<Co2GasPvt<Scalar>* >(realGasPvt_);
341  }
342 
343  template <GasPvtApproach approachV>
344  typename std::enable_if<approachV == GasPvtApproach::Co2GasPvt, const Co2GasPvt<Scalar> >::type& getRealPvt() const
345  {
346  assert(gasPvtApproach() == approachV);
347  return *static_cast<const Co2GasPvt<Scalar>* >(realGasPvt_);
348  }
349 
350  const void* realGasPvt() const { return realGasPvt_; }
351 
352  bool operator==(const GasPvtMultiplexer<Scalar,enableThermal>& data) const
353  {
354  if (this->gasPvtApproach() != data.gasPvtApproach())
355  return false;
356 
357  switch (gasPvtApproach_) {
358  case GasPvtApproach::DryGasPvt:
359  return *static_cast<const DryGasPvt<Scalar>*>(realGasPvt_) ==
360  *static_cast<const DryGasPvt<Scalar>*>(data.realGasPvt_);
361  case GasPvtApproach::WetGasPvt:
362  return *static_cast<const WetGasPvt<Scalar>*>(realGasPvt_) ==
363  *static_cast<const WetGasPvt<Scalar>*>(data.realGasPvt_);
364  case GasPvtApproach::ThermalGasPvt:
365  return *static_cast<const GasPvtThermal<Scalar>*>(realGasPvt_) ==
366  *static_cast<const GasPvtThermal<Scalar>*>(data.realGasPvt_);
367  case GasPvtApproach::Co2GasPvt:
368  return *static_cast<const Co2GasPvt<Scalar>*>(realGasPvt_) ==
369  *static_cast<const Co2GasPvt<Scalar>*>(data.realGasPvt_);
370  default:
371  return true;
372  }
373  }
374 
375  GasPvtMultiplexer<Scalar,enableThermal>& operator=(const GasPvtMultiplexer<Scalar,enableThermal>& data)
376  {
377  gasPvtApproach_ = data.gasPvtApproach_;
378  switch (gasPvtApproach_) {
379  case GasPvtApproach::DryGasPvt:
380  realGasPvt_ = new DryGasPvt<Scalar>(*static_cast<const DryGasPvt<Scalar>*>(data.realGasPvt_));
381  break;
382  case GasPvtApproach::WetGasPvt:
383  realGasPvt_ = new WetGasPvt<Scalar>(*static_cast<const WetGasPvt<Scalar>*>(data.realGasPvt_));
384  break;
385  case GasPvtApproach::ThermalGasPvt:
386  realGasPvt_ = new GasPvtThermal<Scalar>(*static_cast<const GasPvtThermal<Scalar>*>(data.realGasPvt_));
387  break;
388  case GasPvtApproach::Co2GasPvt:
389  realGasPvt_ = new Co2GasPvt<Scalar>(*static_cast<const Co2GasPvt<Scalar>*>(data.realGasPvt_));
390  break;
391  default:
392  break;
393  }
394 
395  return *this;
396  }
397 
398 private:
399  GasPvtApproach gasPvtApproach_;
400  void* realGasPvt_;
401 };
402 
403 #undef OPM_GAS_PVT_MULTIPLEXER_CALL
404 
405 } // namespace Opm
406 
407 #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 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 for CO2.
Definition: Co2GasPvt.hpp:54
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 in the black-oil mod...
Definition: GasPvtMultiplexer.hpp:86
Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rv) const
Returns the formation volume factor [-] of the fluid phase.
Definition: GasPvtMultiplexer.hpp:225
GasPvtApproach gasPvtApproach() const
Returns the concrete approach for calculating the PVT relations.
Definition: GasPvtMultiplexer.hpp:288
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:235
unsigned numRegions() const
Return the number of PVT regions which are considered by this PVT-object.
Definition: GasPvtMultiplexer.hpp:183
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:276
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:244
const Scalar gasReferenceDensity(unsigned regionIdx)
Return the reference density which are considered by this PVT-object.
Definition: GasPvtMultiplexer.hpp:189
Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rv) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition: GasPvtMultiplexer.hpp:206
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:196
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:267
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:253
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:216
This class implements temperature dependence of the PVT properties of gas.
Definition: GasPvtThermal.hpp:55
This class represents the Pressure-Volume-Temperature relations of the gas phas with vaporized oil.
Definition: WetGasPvt.hpp:54