opm-simulators
MixingRateControls.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 */
28 #ifndef OPM_MIXING_RATE_CONTROLS_HPP
29 #define OPM_MIXING_RATE_CONTROLS_HPP
30 
31 #include <opm/input/eclipse/Schedule/Schedule.hpp>
32 
33 #include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
34 #include <opm/material/common/MathToolbox.hpp>
35 
36 #include <limits>
37 #include <vector>
38 
39 namespace Opm {
40 
41 class EclipseState;
42 
44 template<class FluidSystem>
46 {
47 public:
48  using Scalar = typename FluidSystem::Scalar;
49 
50  explicit MixingRateControls(const Schedule& schedule);
52 
53  static MixingRateControls serializationTestObject(const Schedule& schedule);
54 
55  bool operator==(const MixingRateControls& rhs) const;
56  MixingRateControls& operator=(const MixingRateControls& rhs);
57 
58  void init(std::size_t numDof, int episodeIdx, const unsigned ntpvt);
59 
60  bool drsdtActive(int episodeIdx) const;
61  bool drvdtActive(int episodeIdx) const;
62  bool drsdtConvective(int episodeIdx) const;
63 
64  bool drsdtActive(int episodeIdx, std::size_t pvtRegionIdx) const;
65  bool drvdtActive(int episodeIdx, std::size_t pvtRegionIdx) const;
66  bool drsdtConvective(int episodeIdx, std::size_t pvtRegionIdx) const;
70  Scalar drsdtcon(const unsigned elemIdx,
71  int episodeIdx,
72  const int pvtRegionIdx) const;
73 
78  Scalar maxGasDissolutionFactor(unsigned timeIdx,
79  unsigned globalDofIdx,
80  const int episodeIdx,
81  const int pvtRegionIdx) const;
82 
87  Scalar maxOilVaporizationFactor(const unsigned timeIdx,
88  const unsigned globalDofIdx,
89  const int episodeIdx,
90  const int pvtRegionIdx) const;
91 
92  void updateExplicitQuantities(const int episodeIdx,
93  const Scalar timeStepSize);
94 
95  void updateLastValues(const unsigned elemIdx,
96  const Scalar Rs,
97  const Scalar Rv);
98 
99  void updateMaxValues(const int episodeIdx,
100  const Scalar timeStepSize);
101 
102  template<class Serializer>
103  void serializeOp(Serializer& serializer)
104  {
105  serializer(lastRv_);
106  serializer(maxDRv_);
107  serializer(convectiveDrs_);
108  serializer(lastRs_);
109  serializer(maxDRs_);
110  serializer(dRsDtOnlyFreeGas_);
111  }
112 
113  template<class IntensiveQuantities>
114  void update(unsigned compressedDofIdx,
115  const IntensiveQuantities& iq,
116  const int episodeIdx,
117  const Scalar gravity,
118  const Scalar permZ,
119  const Scalar distZ,
120  const int pvtRegionIdx)
121  {
122  const auto& oilVaporizationControl = schedule_[episodeIdx].oilvap();
123 
124  if (oilVaporizationControl.drsdtConvective(pvtRegionIdx)) {
125  // This implements the convective DRSDT as described in
126  // Sandve et al. "Convective dissolution in field scale CO2 storage simulations using the OPM Flow
127  // simulator" Submitted to TCCS 11, 2021
128  // modification and introduction of regimes following Mykkeltvedt et al. Submitted to TIMP 2024
129  const auto& fs = iq.fluidState();
130 
131  const auto& temperature = (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) ?
132  getValue(fs.temperature(FluidSystem::waterPhaseIdx)) :
133  getValue(fs.temperature(FluidSystem::oilPhaseIdx));
134  const auto& pressure = (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) ?
135  getValue(fs.pressure(FluidSystem::waterPhaseIdx)) :
136  getValue(fs.pressure(FluidSystem::oilPhaseIdx));
137  const auto& pressuregas = getValue(fs.pressure(FluidSystem::gasPhaseIdx));
138  const auto& rs = (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) ?
139  getValue(fs.Rsw()) :
140  getValue(fs.Rs());
141 
142  const auto& salt = getValue(fs.saltSaturation());
143 
144  this->updateConvectiveDRsDt_(compressedDofIdx,
145  temperature,
146  pressure,
147  pressuregas,
148  rs,
149  getValue(fs.saturation(FluidSystem::gasPhaseIdx)),
150  getValue(iq.porosity()),
151  permZ,
152  distZ,
153  gravity,
154  salt,
155  oilVaporizationControl.getMaxDRSDT(fs.pvtRegionIndex()),
156  oilVaporizationControl.getPsi(fs.pvtRegionIndex()),
157  oilVaporizationControl.getOmega(fs.pvtRegionIndex()),
158  fs.pvtRegionIndex());
159  }
160 
161  if (oilVaporizationControl.drsdtActive(pvtRegionIdx)) {
162  const auto& fs = iq.fluidState();
163 
164  using FluidState = typename std::decay<decltype(fs)>::type;
165  constexpr Scalar freeGasMinSaturation_ = 1e-7;
166  if (oilVaporizationControl.getOption(pvtRegionIdx) ||
167  fs.saturation(FluidSystem::gasPhaseIdx) > freeGasMinSaturation_) {
168  lastRs_[compressedDofIdx]
169  = ((FluidSystem::enableDissolvedGasInWater())) ?
170  BlackOil::template getRsw_<FluidSystem, FluidState, Scalar>(fs, iq.pvtRegionIndex()) :
171  BlackOil::template getRs_<FluidSystem, FluidState, Scalar>(fs, iq.pvtRegionIndex());
172  }
173  else
174  lastRs_[compressedDofIdx] = std::numeric_limits<Scalar>::infinity();
175  }
176 
177  if (oilVaporizationControl.drvdtActive(pvtRegionIdx)) {
178  const auto& fs = iq.fluidState();
179  using FluidState = typename std::decay<decltype(fs)>::type;
180  lastRv_[compressedDofIdx]
181  = BlackOil::template getRv_<FluidSystem, FluidState, Scalar>(fs, iq.pvtRegionIndex());
182  }
183  }
184 
185 private:
186  void updateConvectiveDRsDt_(const unsigned compressedDofIdx,
187  const Scalar t,
188  const Scalar p,
189  const Scalar pg,
190  const Scalar rs,
191  const Scalar sg,
192  const Scalar poro,
193  const Scalar permz,
194  const Scalar distZ,
195  const Scalar gravity,
196  const Scalar salt,
197  const Scalar Xhi,
198  const Scalar Psi,
199  const Scalar omegainn,
200  const int pvtRegionIndex);
201 
202  std::vector<Scalar> lastRv_;
203  std::vector<Scalar> maxDRv_;
204 
205  std::vector<Scalar> convectiveDrs_;
206  std::vector<Scalar> lastRs_;
207  std::vector<Scalar> maxDRs_;
208  std::vector<bool> dRsDtOnlyFreeGas_; // apply the DRSDT rate limit only to cells that exhibit free gas
209 
210  const Schedule& schedule_;
211 };
212 
213 } // namespace Opm
214 
215 #endif // OPM_MIXING_RATE_CONTROLS_HPP
Scalar drsdtcon(const unsigned elemIdx, int episodeIdx, const int pvtRegionIdx) const
Returns the dynamic drsdt convective mixing value.
Definition: MixingRateControls.cpp:224
Scalar maxGasDissolutionFactor(unsigned timeIdx, unsigned globalDofIdx, const int episodeIdx, const int pvtRegionIdx) const
Returns the maximum value of the gas dissolution factor at the current time for a given degree of fre...
Definition: MixingRateControls.cpp:246
Scalar maxOilVaporizationFactor(const unsigned timeIdx, const unsigned globalDofIdx, const int episodeIdx, const int pvtRegionIdx) const
Returns the maximum value of the oil vaporization factor at the current time for a given degree of fr...
Definition: MixingRateControls.cpp:272
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Class handling mixing rate controls for a FlowProblemBlackoil.
Definition: MixingRateControls.hpp:45