My Project
Loading...
Searching...
No Matches
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
27#include <opm/simulators/wells/RegionAttributeHelpers.hpp>
28
29#include <opm/simulators/utils/BlackoilPhases.hpp>
30#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
31#include <opm/simulators/utils/ParallelCommunication.hpp>
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>
71 class SurfaceToReservoirVoidage {
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
128 OPM_BEGIN_PARALLEL_TRY_CATCH();
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(simulator.vanguard().gridEquilIdxToGridIdx(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
216 using RegionId = typename RegionMapping<Region>::RegionId;
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>
345 inferDissolvedVaporisedRatio(const Scalar rsMax,
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,
425 Parallel::Communication comm);
426
427 RegionAttributeHelpers::RegionAttributes<RegionId, Attributes> attr_;
428 };
429
430 } // namespace RateConverter
431} // namespace Opm
432
433#endif /* OPM_RATECONVERTER_HPP_HEADER_INCLUDED */
SurfaceToReservoirVoidage(const PhaseUsage &phaseUsage, const Region &region)
Constructor.
Definition RateConverter.hpp:81
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:343
void calcCoeff(const RegionId r, const int pvtRegionIdx, Coeff &coeff) const
Compute coefficients for surface-to-reservoir voidage conversion.
Definition RateConverter.cpp:140
void defineState(const Simulator &simulator)
Compute pore volume averaged hydrocarbon state pressure, rs and rv.
Definition RateConverter.hpp:97
typename RegionMapping< Region >::RegionId RegionId
Region identifier.
Definition RateConverter.hpp:216
void calcCoeffSolvent(const RegionId r, const int pvtRegionIdx, Scalar &coeff) const
Compute coefficients for surface-to-reservoir voidage conversion for solvent.
Definition RateConverter.hpp:363
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
bool water(const PhaseUsage &pu)
Active water predicate.
Definition RegionAttributeHelpers.hpp:309
bool oil(const PhaseUsage &pu)
Active oil predicate.
Definition RegionAttributeHelpers.hpp:322
bool gas(const PhaseUsage &pu)
Active gas predicate.
Definition RegionAttributeHelpers.hpp:335
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilboundaryratevector.hh:37
PhaseUsage phaseUsage(const Phases &phases)
Determine the active phases.
Definition phaseUsageFromDeck.cpp:37
Definition BlackoilPhases.hpp:46