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
39namespace Opm {
40
41class EclipseState;
42
44template<class FluidSystem>
46{
47public:
48 using Scalar = typename FluidSystem::Scalar;
49
50 MixingRateControls(const Schedule& schedule);
52
53 static MixingRateControls serializationTestObject(const Schedule& schedule);
54
55 bool operator==(const MixingRateControls& rhs) const;
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
67 Scalar drsdtcon(const unsigned elemIdx,
68 int episodeIdx,
69 const int pvtRegionIdx) const;
70
76 unsigned globalDofIdx,
77 const int episodeIdx,
78 const int pvtRegionIdx) const;
79
84 Scalar maxOilVaporizationFactor(const unsigned timeIdx,
85 const unsigned globalDofIdx,
86 const int episodeIdx,
87 const int pvtRegionIdx) const;
88
89 void updateExplicitQuantities(const int episodeIdx,
90 const Scalar timeStepSize);
91
92 void updateLastValues(const unsigned elemIdx,
93 const Scalar Rs,
94 const Scalar Rv);
95
96 void updateMaxValues(const int episodeIdx,
97 const Scalar timeStepSize);
98
99 template<class Serializer>
100 void serializeOp(Serializer& serializer)
101 {
102 serializer(lastRv_);
103 serializer(maxDRv_);
104 serializer(convectiveDrs_);
105 serializer(lastRs_);
106 serializer(maxDRs_);
107 serializer(dRsDtOnlyFreeGas_);
108 }
109
110 template<class IntensiveQuantities>
111 void update(unsigned compressedDofIdx,
112 const IntensiveQuantities& iq,
113 const int episodeIdx,
114 const Scalar gravity,
115 const Scalar permZ,
116 const Scalar distZ,
117 const int pvtRegionIdx,
118 const std::array<bool,3>& active)
119 {
120 if (active[0]) {
121 // This implements the convective DRSDT as described in
122 // Sandve et al. "Convective dissolution in field scale CO2 storage simulations using the OPM Flow
123 // simulator" Submitted to TCCS 11, 2021
124 const auto& fs = iq.fluidState();
125 this->updateConvectiveDRsDt_(compressedDofIdx,
126 getValue(fs.temperature(FluidSystem::oilPhaseIdx)),
127 getValue(fs.pressure(FluidSystem::oilPhaseIdx)),
128 getValue(fs.Rs()),
129 getValue(fs.saturation(FluidSystem::oilPhaseIdx)),
130 getValue(iq.porosity()),
131 permZ,
132 distZ,
133 gravity,
134 fs.pvtRegionIndex());
135 }
136
137 if (active[1]) {
138 const auto& fs = iq.fluidState();
139
140 using FluidState = typename std::decay<decltype(fs)>::type;
141
142 const auto& oilVaporizationControl = schedule_[episodeIdx].oilvap();
143 constexpr Scalar freeGasMinSaturation_ = 1e-7;
144 if (oilVaporizationControl.getOption(pvtRegionIdx) ||
145 fs.saturation(FluidSystem::gasPhaseIdx) > freeGasMinSaturation_) {
146 lastRs_[compressedDofIdx]
147 = BlackOil::template getRs_<FluidSystem, FluidState, Scalar>(fs, iq.pvtRegionIndex());
148 }
149 else
150 lastRs_[compressedDofIdx] = std::numeric_limits<Scalar>::infinity();
151 }
152
153 if (active[2]) {
154 const auto& fs = iq.fluidState();
155 using FluidState = typename std::decay<decltype(fs)>::type;
156 lastRv_[compressedDofIdx]
157 = BlackOil::template getRv_<FluidSystem, FluidState, Scalar>(fs, iq.pvtRegionIndex());
158 }
159 }
160
161private:
162 void updateConvectiveDRsDt_(const unsigned compressedDofIdx,
163 const Scalar t,
164 const Scalar p,
165 const Scalar rs,
166 const Scalar so,
167 const Scalar poro,
168 const Scalar permz,
169 const Scalar distZ,
170 const Scalar gravity,
171 const int pvtRegionIndex);
172
173 std::vector<Scalar> lastRv_;
174 std::vector<Scalar> maxDRv_;
175
176 std::vector<Scalar> convectiveDrs_;
177 std::vector<Scalar> lastRs_;
178 std::vector<Scalar> maxDRs_;
179 std::vector<bool> dRsDtOnlyFreeGas_; // apply the DRSDT rate limit only to cells that exhibit free gas
180
181 const Schedule& schedule_;
182};
183
184} // namespace Opm
185
186#endif // OPM_MIXING_RATE_CONTROLS_HPP
Class handling mixing rate controls for a FlowProblem.
Definition: MixingRateControls.hpp:46
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...
void updateExplicitQuantities(const int episodeIdx, const Scalar timeStepSize)
typename FluidSystem::Scalar Scalar
Definition: MixingRateControls.hpp:48
bool drsdtConvective(int episodeIdx) const
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...
MixingRateControls(const MixingRateControls &rhs)
void serializeOp(Serializer &serializer)
Definition: MixingRateControls.hpp:100
void init(std::size_t numDof, int episodeIdx, const unsigned ntpvt)
bool drsdtActive(int episodeIdx) const
void update(unsigned compressedDofIdx, const IntensiveQuantities &iq, const int episodeIdx, const Scalar gravity, const Scalar permZ, const Scalar distZ, const int pvtRegionIdx, const std::array< bool, 3 > &active)
Definition: MixingRateControls.hpp:111
bool operator==(const MixingRateControls &rhs) const
MixingRateControls & operator=(const MixingRateControls &rhs)
void updateLastValues(const unsigned elemIdx, const Scalar Rs, const Scalar Rv)
bool drvdtActive(int episodeIdx) const
static MixingRateControls serializationTestObject(const Schedule &schedule)
MixingRateControls(const Schedule &schedule)
Scalar drsdtcon(const unsigned elemIdx, int episodeIdx, const int pvtRegionIdx) const
Returns the dynamic drsdt convective mixing value.
void updateMaxValues(const int episodeIdx, const Scalar timeStepSize)
Definition: BlackoilPhases.hpp:27