RateConverter.hpp
Go to the documentation of this file.
1/*
2 Copyright 2014, 2015 SINTEF ICT, Applied Mathematics.
3 Copyright 2014, 2015 Statoil ASA.
4 Copyright 2017, IRIS
5
6 This file is part of the Open Porous Media Project (OPM).
7
8 OPM is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 OPM is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with OPM. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#ifndef OPM_RATECONVERTER_HPP_HEADER_INCLUDED
23#define OPM_RATECONVERTER_HPP_HEADER_INCLUDED
24
26#include <opm/grid/utility/RegionMapping.hpp>
29
31
32#include <dune/grid/common/gridenums.hh>
33#include <dune/grid/common/rangegenerators.hh>
34
35#include <array>
36#include <cassert>
37#include <unordered_map>
38#include <utility>
39#include <vector>
40
51namespace Opm {
52 namespace RateConverter {
53
69 template <class FluidSystem, class Region>
71 public:
79 const Region& region)
80 : phaseUsage_(phaseUsage)
81 , rmap_ (region)
82 , attr_ (rmap_, Attributes())
83 {}
84
93 template <typename ElementContext, class Simulator>
94 void defineState(const Simulator& simulator)
95 {
96 // create map from cell to region and set all attributes to
97 // zero
98 for (const auto& reg : rmap_.activeRegions()) {
99 auto& ra = attr_.attributes(reg);
100 ra.pressure = 0.0;
101 ra.temperature = 0.0;
102 ra.rs = 0.0;
103 ra.rv = 0.0;
104 ra.pv = 0.0;
105 ra.saltConcentration = 0.0;
106 ra.rsw = 0.0;
107 ra.rvw = 0.0;
108 }
109
110 // quantities for pore volume average
111 std::unordered_map<RegionId, Attributes> attributes_pv;
112
113 // quantities for hydrocarbon volume average
114 std::unordered_map<RegionId, Attributes> attributes_hpv;
115
116 for (const auto& reg : rmap_.activeRegions()) {
117 attributes_pv.insert({reg, Attributes()});
118 attributes_hpv.insert({reg, Attributes()});
119 }
120
121 ElementContext elemCtx( simulator );
122 const auto& gridView = simulator.gridView();
123 const auto& comm = gridView.comm();
124
126 for (const auto& elem : elements(gridView, Dune::Partitions::interior)) {
127 elemCtx.updatePrimaryStencil(elem);
128 elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
129 const unsigned cellIdx = elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0);
130 const auto& intQuants = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0);
131 const auto& fs = intQuants.fluidState();
132 // use pore volume weighted averages.
133 const double pv_cell =
134 simulator.model().dofTotalVolume(cellIdx)
135 * intQuants.porosity().value();
136
137 // only count oil and gas filled parts of the domain
138 double hydrocarbon = 1.0;
139 const auto& pu = phaseUsage_;
141 hydrocarbon -= fs.saturation(FluidSystem::waterPhaseIdx).value();
142 }
143
144 const int reg = rmap_.region(cellIdx);
145 assert(reg >= 0);
146
147 // sum p, rs, rv, and T.
148 const double hydrocarbonPV = pv_cell*hydrocarbon;
149 if (hydrocarbonPV > 0.) {
150 auto& attr = attributes_hpv[reg];
151 attr.pv += hydrocarbonPV;
153 attr.rs += fs.Rs().value() * hydrocarbonPV;
154 attr.rv += fs.Rv().value() * hydrocarbonPV;
155 }
157 attr.pressure += fs.pressure(FluidSystem::oilPhaseIdx).value() * hydrocarbonPV;
158 attr.temperature += fs.temperature(FluidSystem::oilPhaseIdx).value() * hydrocarbonPV;
159 } else {
161 attr.pressure += fs.pressure(FluidSystem::gasPhaseIdx).value() * hydrocarbonPV;
162 attr.temperature += fs.temperature(FluidSystem::gasPhaseIdx).value() * hydrocarbonPV;
163 }
164 attr.saltConcentration += fs.saltConcentration().value() * hydrocarbonPV;
165 if (FluidSystem::enableDissolvedGasInWater()) {
166 attr.rsw += fs.Rsw().value() * hydrocarbonPV; // scale with total volume?
167 }
168 if (FluidSystem::enableVaporizedWater()) {
169 attr.rvw += fs.Rvw().value() * hydrocarbonPV; // scale with total volume?
170 }
171 }
172
173 if (pv_cell > 0.) {
174 auto& attr = attributes_pv[reg];
175 attr.pv += pv_cell;
177 attr.rs += fs.Rs().value() * pv_cell;
178 attr.rv += fs.Rv().value() * pv_cell;
179 }
181 attr.pressure += fs.pressure(FluidSystem::oilPhaseIdx).value() * pv_cell;
182 attr.temperature += fs.temperature(FluidSystem::oilPhaseIdx).value() * pv_cell;
184 attr.pressure += fs.pressure(FluidSystem::gasPhaseIdx).value() * pv_cell;
185 attr.temperature += fs.temperature(FluidSystem::gasPhaseIdx).value() * pv_cell;
186 } else {
188 attr.pressure += fs.pressure(FluidSystem::waterPhaseIdx).value() * pv_cell;
189 attr.temperature += fs.temperature(FluidSystem::waterPhaseIdx).value() * pv_cell;
190 }
191 attr.saltConcentration += fs.saltConcentration().value() * pv_cell;
192 if (FluidSystem::enableDissolvedGasInWater()) {
193 attr.rsw += fs.Rsw().value() * pv_cell;
194 }
195 if (FluidSystem::enableVaporizedWater()) {
196 attr.rvw += fs.Rvw().value() * pv_cell;
197 }
198 }
199 }
200
201 OPM_END_PARALLEL_TRY_CATCH("SurfaceToReservoirVoidage::defineState() failed: ", simulator.vanguard().grid().comm());
202
203 this->sumRates(attributes_hpv,
204 attributes_pv,
205 comm);
206 }
207
214
242 template <class Coeff>
243 void
244 calcCoeff(const RegionId r, const int pvtRegionIdx, Coeff& coeff) const;
245
246 template <class Coeff , class Rates>
247 void
248 calcCoeff(const RegionId r, const int pvtRegionIdx, const Rates& surface_rates, Coeff& coeff) const;
249
250 template <class Coeff>
251 void
252 calcCoeff( const int pvtRegionIdx,
253 const double p,
254 const double rs,
255 const double rv,
256 const double rsw,
257 const double rvw,
258 const double T,
259 const double saltConcentration,
260 Coeff& coeff) const;
261
262 template <class Coeff>
263 void
264 calcInjCoeff(const RegionId r, const int pvtRegionIdx, Coeff& coeff) const;
265
288 template <class Rates>
290 const int pvtRegionIdx,
291 const Rates& surface_rates,
292 Rates& voidage_rates) const;
293
328 template <typename SurfaceRates, typename VoidageRates>
329 void calcReservoirVoidageRates(const int pvtRegionIdx,
330 const double p,
331 const double rs,
332 const double rv,
333 const double rsw,
334 const double rvw,
335 const double T,
336 const double saltConcentration,
337 const SurfaceRates& surface_rates,
338 VoidageRates& voidage_rates) const;
339
340 template <class Rates>
341 std::pair<double, double>
343 const double rvMax,
344 const Rates& surface_rates) const;
345
358 template <class SolventModule>
359 void
360 calcCoeffSolvent(const RegionId r, const int pvtRegionIdx, double& coeff) const
361 {
362 const auto& ra = attr_.attributes(r);
363 const double p = ra.pressure;
364 const double T = ra.temperature;
365 const auto& solventPvt = SolventModule::solventPvt();
366 const double bs = solventPvt.inverseFormationVolumeFactor(pvtRegionIdx, T, p);
367 coeff = 1.0 / bs;
368 }
369
370 private:
374 const PhaseUsage phaseUsage_;
375
379 const RegionMapping<Region> rmap_;
380
384 struct Attributes {
385 Attributes()
386 : data{0.0}
387 , pressure(data[0])
388 , temperature(data[1])
389 , rs(data[2])
390 , rv(data[3])
391 , rsw(data[4])
392 , rvw(data[5])
393 , pv(data[6])
394 , saltConcentration(data[7])
395 {}
396
397 Attributes(const Attributes& rhs)
398 : Attributes()
399 {
400 this->data = rhs.data;
401 }
402
403 Attributes& operator=(const Attributes& rhs)
404 {
405 this->data = rhs.data;
406 return *this;
407 }
408
409 std::array<double,8> data;
410 double& pressure;
411 double& temperature;
412 double& rs;
413 double& rv;
414 double& rsw;
415 double& rvw;
416 double& pv;
417 double& saltConcentration;
418 };
419
420 void sumRates(std::unordered_map<RegionId,Attributes>& attributes_hpv,
421 std::unordered_map<RegionId,Attributes>& attributes_pv,
423
424 RegionAttributeHelpers::RegionAttributes<RegionId, Attributes> attr_;
425 };
426
427 } // namespace RateConverter
428} // namespace Opm
429
430#endif /* OPM_RATECONVERTER_HPP_HEADER_INCLUDED */
#define OPM_END_PARALLEL_TRY_CATCH(prefix, comm)
Catch exception and throw in a parallel try-catch clause.
Definition: DeferredLoggingErrorHelpers.hpp:172
#define OPM_BEGIN_PARALLEL_TRY_CATCH()
Macro to setup the try of a parallel try-catch.
Definition: DeferredLoggingErrorHelpers.hpp:138
Definition: RateConverter.hpp:70
SurfaceToReservoirVoidage(const PhaseUsage &phaseUsage, const Region &region)
Definition: RateConverter.hpp:78
void calcCoeff(const int pvtRegionIdx, const double p, const double rs, const double rv, const double rsw, const double rvw, const double T, const double saltConcentration, Coeff &coeff) const
std::pair< double, double > inferDissolvedVaporisedRatio(const double rsMax, const double rvMax, const Rates &surface_rates) const
void calcCoeffSolvent(const RegionId r, const int pvtRegionIdx, double &coeff) const
Definition: RateConverter.hpp:360
void calcReservoirVoidageRates(const RegionId r, const int pvtRegionIdx, const Rates &surface_rates, Rates &voidage_rates) const
void calcCoeff(const RegionId r, const int pvtRegionIdx, const Rates &surface_rates, Coeff &coeff) const
void calcInjCoeff(const RegionId r, const int pvtRegionIdx, Coeff &coeff) const
void calcCoeff(const RegionId r, const int pvtRegionIdx, Coeff &coeff) const
void calcReservoirVoidageRates(const int pvtRegionIdx, const double p, const double rs, const double rv, const double rsw, const double rvw, const double T, const double saltConcentration, const SurfaceRates &surface_rates, VoidageRates &voidage_rates) const
void defineState(const Simulator &simulator)
Definition: RateConverter.hpp:94
typename RegionMapping< Region >::RegionId RegionId
Definition: RateConverter.hpp:213
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
bool water(const PhaseUsage &pu)
Definition: RegionAttributeHelpers.hpp:308
bool oil(const PhaseUsage &pu)
Definition: RegionAttributeHelpers.hpp:321
bool gas(const PhaseUsage &pu)
Definition: RegionAttributeHelpers.hpp:334
Definition: BlackoilPhases.hpp:27
PhaseUsage phaseUsage(const Phases &phases)
Determine the active phases.
int RegionId
Definition: WellConstraints.hpp:38
Definition: BlackoilPhases.hpp:46