My Project
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/core/props/BlackoilPhases.hpp>
26#include <opm/grid/utility/RegionMapping.hpp>
27#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
28#include <opm/simulators/wells/RegionAttributeHelpers.hpp>
29
30#include <opm/simulators/utils/ParallelCommunication.hpp>
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 EbosSimulator>
94 void defineState(const EbosSimulator& 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
125 OPM_BEGIN_PARALLEL_TRY_CATCH();
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
213 using RegionId = typename RegionMapping<Region>::RegionId;
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>
342 inferDissolvedVaporisedRatio(const double rsMax,
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,
422 Parallel::Communication comm);
423
424 RegionAttributeHelpers::RegionAttributes<RegionId, Attributes> attr_;
425 };
426
427 } // namespace RateConverter
428} // namespace Opm
429
430#endif /* OPM_RATECONVERTER_HPP_HEADER_INCLUDED */
Convert component rates at surface conditions to phase (voidage) rates at reservoir conditions.
Definition: RateConverter.hpp:70
SurfaceToReservoirVoidage(const PhaseUsage &phaseUsage, const Region &region)
Constructor.
Definition: RateConverter.hpp:78
void calcCoeffSolvent(const RegionId r, const int pvtRegionIdx, double &coeff) const
Compute coefficients for surface-to-reservoir voidage conversion for solvent.
Definition: RateConverter.hpp:360
void calcReservoirVoidageRates(const RegionId r, const int pvtRegionIdx, const Rates &surface_rates, Rates &voidage_rates) const
Convert surface volume flow rates to reservoir voidage flow rates.
Definition: RateConverter.cpp:332
void calcCoeff(const RegionId r, const int pvtRegionIdx, Coeff &coeff) const
Compute coefficients for surface-to-reservoir voidage conversion.
Definition: RateConverter.cpp:129
typename RegionMapping< Region >::RegionId RegionId
Region identifier.
Definition: RateConverter.hpp:213
void defineState(const EbosSimulator &simulator)
Compute pore volume averaged hydrocarbon state pressure, rs and rv.
Definition: RateConverter.hpp:94
bool water(const PhaseUsage &pu)
Active water predicate.
Definition: RegionAttributeHelpers.hpp:308
bool oil(const PhaseUsage &pu)
Active oil predicate.
Definition: RegionAttributeHelpers.hpp:321
bool gas(const PhaseUsage &pu)
Active gas predicate.
Definition: RegionAttributeHelpers.hpp:334
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27
PhaseUsage phaseUsage(const Phases &phases)
Determine the active phases.
Definition: phaseUsageFromDeck.cpp:37
Definition: BlackoilPhases.hpp:46