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
25#include <opm/grid/utility/RegionMapping.hpp>
26
28
32
33#include <dune/grid/common/gridenums.hh>
34#include <dune/grid/common/rangegenerators.hh>
35
36#include <array>
37#include <cassert>
38#include <unordered_map>
39#include <utility>
40#include <vector>
41
52namespace Opm {
53 namespace RateConverter {
54
70 template <class FluidSystem, class Region>
72 public:
73 using Scalar = typename FluidSystem::Scalar;
74
82 const Region& region)
83 : phaseUsage_(phaseUsage)
84 , rmap_ (region)
85 , attr_ (rmap_, Attributes())
86 {}
87
96 template <typename ElementContext, class Simulator>
97 void defineState(const Simulator& simulator)
98 {
99 // create map from cell to region and set all attributes to
100 // zero
101 for (const auto& reg : rmap_.activeRegions()) {
102 auto& ra = attr_.attributes(reg);
103 ra.pressure = 0.0;
104 ra.temperature = 0.0;
105 ra.rs = 0.0;
106 ra.rv = 0.0;
107 ra.pv = 0.0;
108 ra.saltConcentration = 0.0;
109 ra.rsw = 0.0;
110 ra.rvw = 0.0;
111 }
112
113 // quantities for pore volume average
114 std::unordered_map<RegionId, Attributes> attributes_pv;
115
116 // quantities for hydrocarbon volume average
117 std::unordered_map<RegionId, Attributes> attributes_hpv;
118
119 for (const auto& reg : rmap_.activeRegions()) {
120 attributes_pv.insert({reg, Attributes()});
121 attributes_hpv.insert({reg, Attributes()});
122 }
123
124 ElementContext elemCtx( simulator );
125 const auto& gridView = simulator.gridView();
126 const auto& comm = gridView.comm();
127
129 for (const auto& elem : elements(gridView, Dune::Partitions::interior)) {
130 elemCtx.updatePrimaryStencil(elem);
131 elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
132 const unsigned cellIdx = elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0);
133 const auto& intQuants = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0);
134 const auto& fs = intQuants.fluidState();
135 // use pore volume weighted averages.
136 const Scalar pv_cell =
137 simulator.model().dofTotalVolume(cellIdx)
138 * intQuants.porosity().value();
139
140 // only count oil and gas filled parts of the domain
141 Scalar hydrocarbon = 1.0;
142 const auto& pu = phaseUsage_;
144 hydrocarbon -= fs.saturation(FluidSystem::waterPhaseIdx).value();
145 }
146
147 const int reg = rmap_.region(cellIdx);
148 assert(reg >= 0);
149
150 // sum p, rs, rv, and T.
151 const Scalar hydrocarbonPV = pv_cell*hydrocarbon;
152 if (hydrocarbonPV > 0.) {
153 auto& attr = attributes_hpv[reg];
154 attr.pv += hydrocarbonPV;
156 attr.rs += fs.Rs().value() * hydrocarbonPV;
157 attr.rv += fs.Rv().value() * hydrocarbonPV;
158 }
160 attr.pressure += fs.pressure(FluidSystem::oilPhaseIdx).value() * hydrocarbonPV;
161 attr.temperature += fs.temperature(FluidSystem::oilPhaseIdx).value() * hydrocarbonPV;
162 } else {
164 attr.pressure += fs.pressure(FluidSystem::gasPhaseIdx).value() * hydrocarbonPV;
165 attr.temperature += fs.temperature(FluidSystem::gasPhaseIdx).value() * hydrocarbonPV;
166 }
167 attr.saltConcentration += fs.saltConcentration().value() * hydrocarbonPV;
168 if (FluidSystem::enableDissolvedGasInWater()) {
169 attr.rsw += fs.Rsw().value() * hydrocarbonPV; // scale with total volume?
170 }
171 if (FluidSystem::enableVaporizedWater()) {
172 attr.rvw += fs.Rvw().value() * hydrocarbonPV; // scale with total volume?
173 }
174 }
175
176 if (pv_cell > 0.) {
177 auto& attr = attributes_pv[reg];
178 attr.pv += pv_cell;
180 attr.rs += fs.Rs().value() * pv_cell;
181 attr.rv += fs.Rv().value() * pv_cell;
182 }
184 attr.pressure += fs.pressure(FluidSystem::oilPhaseIdx).value() * pv_cell;
185 attr.temperature += fs.temperature(FluidSystem::oilPhaseIdx).value() * pv_cell;
187 attr.pressure += fs.pressure(FluidSystem::gasPhaseIdx).value() * pv_cell;
188 attr.temperature += fs.temperature(FluidSystem::gasPhaseIdx).value() * pv_cell;
189 } else {
191 attr.pressure += fs.pressure(FluidSystem::waterPhaseIdx).value() * pv_cell;
192 attr.temperature += fs.temperature(FluidSystem::waterPhaseIdx).value() * pv_cell;
193 }
194 attr.saltConcentration += fs.saltConcentration().value() * pv_cell;
195 if (FluidSystem::enableDissolvedGasInWater()) {
196 attr.rsw += fs.Rsw().value() * pv_cell;
197 }
198 if (FluidSystem::enableVaporizedWater()) {
199 attr.rvw += fs.Rvw().value() * pv_cell;
200 }
201 }
202 }
203
204 OPM_END_PARALLEL_TRY_CATCH("SurfaceToReservoirVoidage::defineState() failed: ", simulator.vanguard().grid().comm());
205
206 this->sumRates(attributes_hpv,
207 attributes_pv,
208 comm);
209 }
210
217
245 template <class Coeff>
246 void
247 calcCoeff(const RegionId r, const int pvtRegionIdx, Coeff& coeff) const;
248
249 template <class Coeff , class Rates>
250 void
251 calcCoeff(const RegionId r, const int pvtRegionIdx, const Rates& surface_rates, Coeff& coeff) const;
252
253 template <class Coeff>
254 void
255 calcCoeff( const int pvtRegionIdx,
256 const Scalar p,
257 const Scalar rs,
258 const Scalar rv,
259 const Scalar rsw,
260 const Scalar rvw,
261 const Scalar T,
262 const Scalar saltConcentration,
263 Coeff& coeff) const;
264
265 template <class Coeff>
266 void
267 calcInjCoeff(const RegionId r, const int pvtRegionIdx, Coeff& coeff) const;
268
291 template <class Rates>
293 const int pvtRegionIdx,
294 const Rates& surface_rates,
295 Rates& voidage_rates) const;
296
331 template <typename SurfaceRates, typename VoidageRates>
332 void calcReservoirVoidageRates(const int pvtRegionIdx,
333 const Scalar p,
334 const Scalar rs,
335 const Scalar rv,
336 const Scalar rsw,
337 const Scalar rvw,
338 const Scalar T,
339 const Scalar saltConcentration,
340 const SurfaceRates& surface_rates,
341 VoidageRates& voidage_rates) const;
342
343 template <class Rates>
344 std::pair<Scalar, Scalar>
346 const Scalar rvMax,
347 const Rates& surface_rates) const;
348
361 template <class SolventModule>
362 void
363 calcCoeffSolvent(const RegionId r, const int pvtRegionIdx, Scalar& coeff) const
364 {
365 const auto& ra = attr_.attributes(r);
366 const Scalar p = ra.pressure;
367 const Scalar T = ra.temperature;
368 const auto& solventPvt = SolventModule::solventPvt();
369 const Scalar bs = solventPvt.inverseFormationVolumeFactor(pvtRegionIdx, T, p);
370 coeff = 1.0 / bs;
371 }
372
373 private:
377 const PhaseUsage phaseUsage_;
378
382 const RegionMapping<Region> rmap_;
383
387 struct Attributes {
388 Attributes()
389 : data{0.0}
390 , pressure(data[0])
391 , temperature(data[1])
392 , rs(data[2])
393 , rv(data[3])
394 , rsw(data[4])
395 , rvw(data[5])
396 , pv(data[6])
397 , saltConcentration(data[7])
398 {}
399
400 Attributes(const Attributes& rhs)
401 : Attributes()
402 {
403 this->data = rhs.data;
404 }
405
406 Attributes& operator=(const Attributes& rhs)
407 {
408 this->data = rhs.data;
409 return *this;
410 }
411
412 std::array<Scalar,8> data;
413 Scalar& pressure;
414 Scalar& temperature;
415 Scalar& rs;
416 Scalar& rv;
417 Scalar& rsw;
418 Scalar& rvw;
419 Scalar& pv;
420 Scalar& saltConcentration;
421 };
422
423 void sumRates(std::unordered_map<RegionId,Attributes>& attributes_hpv,
424 std::unordered_map<RegionId,Attributes>& attributes_pv,
426
427 RegionAttributeHelpers::RegionAttributes<RegionId, Attributes> attr_;
428 };
429
430 } // namespace RateConverter
431} // namespace Opm
432
433#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:192
#define OPM_BEGIN_PARALLEL_TRY_CATCH()
Macro to setup the try of a parallel try-catch.
Definition: DeferredLoggingErrorHelpers.hpp:158
Definition: RateConverter.hpp:71
std::pair< Scalar, Scalar > inferDissolvedVaporisedRatio(const Scalar rsMax, const Scalar rvMax, const Rates &surface_rates) const
SurfaceToReservoirVoidage(const PhaseUsage &phaseUsage, const Region &region)
Definition: RateConverter.hpp:81
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 calcCoeff(const int pvtRegionIdx, const Scalar p, const Scalar rs, const Scalar rv, const Scalar rsw, const Scalar rvw, const Scalar T, const Scalar saltConcentration, Coeff &coeff) const
void defineState(const Simulator &simulator)
Definition: RateConverter.hpp:97
typename RegionMapping< Region >::RegionId RegionId
Definition: RateConverter.hpp:216
void calcReservoirVoidageRates(const int pvtRegionIdx, const Scalar p, const Scalar rs, const Scalar rv, const Scalar rsw, const Scalar rvw, const Scalar T, const Scalar saltConcentration, const SurfaceRates &surface_rates, VoidageRates &voidage_rates) const
void calcCoeffSolvent(const RegionId r, const int pvtRegionIdx, Scalar &coeff) const
Definition: RateConverter.hpp:363
typename FluidSystem::Scalar Scalar
Definition: RateConverter.hpp:73
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:92
Vanguard & vanguard()
Return a reference to the grid manager of simulation.
Definition: simulator.hh:260
const GridView & gridView() const
Return the grid view for which the simulation is done.
Definition: simulator.hh:272
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:278
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
bool water(const PhaseUsage &pu)
Definition: RegionAttributeHelpers.hpp:309
bool oil(const PhaseUsage &pu)
Definition: RegionAttributeHelpers.hpp:322
bool gas(const PhaseUsage &pu)
Definition: RegionAttributeHelpers.hpp:335
Definition: blackoilboundaryratevector.hh:37
PhaseUsage phaseUsage(const Phases &phases)
Determine the active phases.
int RegionId
Definition: WellConstraints.hpp:37
Definition: BlackoilPhases.hpp:46