My Project
Loading...
Searching...
No Matches
OilPvtThermal.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*/
27#ifndef OPM_OIL_PVT_THERMAL_HPP
28#define OPM_OIL_PVT_THERMAL_HPP
29
31
32namespace Opm {
33
34#if HAVE_ECL_INPUT
35class EclipseState;
36class Schedule;
37#endif
38
39template <class Scalar, bool enableThermal>
40class OilPvtMultiplexer;
41
48template <class Scalar>
50{
51public:
53 using IsothermalPvt = OilPvtMultiplexer<Scalar, /*enableThermal=*/false>;
54
56 {
57 enableThermalDensity_ = false;
58 enableJouleThomson_ = false;
59 enableThermalViscosity_ = false;
60 enableInternalEnergy_ = false;
61 isothermalPvt_ = nullptr;
62 }
63
64 OilPvtThermal(IsothermalPvt* isothermalPvt,
65 const std::vector<TabulatedOneDFunction>& oilvisctCurves,
66 const std::vector<Scalar>& viscrefPress,
67 const std::vector<Scalar>& viscrefRs,
68 const std::vector<Scalar>& viscRef,
69 const std::vector<Scalar>& oildentRefTemp,
70 const std::vector<Scalar>& oildentCT1,
71 const std::vector<Scalar>& oildentCT2,
72 const std::vector<Scalar>& oilJTRefPres,
73 const std::vector<Scalar>& oilJTC,
74 const std::vector<TabulatedOneDFunction>& internalEnergyCurves,
78 bool enableInternalEnergy)
79 : isothermalPvt_(isothermalPvt)
80 , oilvisctCurves_(oilvisctCurves)
81 , viscrefPress_(viscrefPress)
82 , viscrefRs_(viscrefRs)
83 , viscRef_(viscRef)
84 , oildentRefTemp_(oildentRefTemp)
85 , oildentCT1_(oildentCT1)
86 , oildentCT2_(oildentCT2)
87 , oilJTRefPres_(oilJTRefPres)
88 , oilJTC_(oilJTC)
89 , internalEnergyCurves_(internalEnergyCurves)
90 , enableThermalDensity_(enableThermalDensity)
91 , enableJouleThomson_(enableJouleThomson)
92 , enableThermalViscosity_(enableThermalViscosity)
93 , enableInternalEnergy_(enableInternalEnergy)
94 { }
95
96 OilPvtThermal(const OilPvtThermal& data)
97 { *this = data; }
98
100 { delete isothermalPvt_; }
101
102#if HAVE_ECL_INPUT
106 void initFromState(const EclipseState& eclState, const Schedule& schedule);
107#endif // HAVE_ECL_INPUT
108
112 void setNumRegions(size_t numRegions)
113 {
114 oilvisctCurves_.resize(numRegions);
115 viscrefPress_.resize(numRegions);
116 viscrefRs_.resize(numRegions);
117 viscRef_.resize(numRegions);
118 internalEnergyCurves_.resize(numRegions);
119 oildentRefTemp_.resize(numRegions);
120 oildentCT1_.resize(numRegions);
121 oildentCT2_.resize(numRegions);
122 oilJTRefPres_.resize(numRegions);
123 oilJTC_.resize(numRegions);
124 rhoRefG_.resize(numRegions);
125 }
126
127 void setVapPars(const Scalar par1, const Scalar par2)
128 {
129 isothermalPvt_->setVapPars(par1, par2);
130 }
131
135 void initEnd()
136 { }
137
142 { return enableThermalDensity_; }
143
148 { return enableJouleThomson_; }
149
154 { return enableThermalViscosity_; }
155
156 size_t numRegions() const
157 { return viscrefRs_.size(); }
158
162 template <class Evaluation>
163 Evaluation internalEnergy(unsigned regionIdx,
164 const Evaluation& temperature,
165 const Evaluation& pressure,
166 const Evaluation& Rs) const
167 {
168 if (!enableInternalEnergy_)
169 throw std::runtime_error("Requested the internal energy of oil but it is disabled");
170
171 if (!enableJouleThomson_) {
172 // compute the specific internal energy for the specified tempature. We use linear
173 // interpolation here despite the fact that the underlying heat capacities are
174 // piecewise linear (which leads to a quadratic function)
175 return internalEnergyCurves_[regionIdx].eval(temperature, /*extrapolate=*/true);
176 }
177 else {
178 Evaluation Tref = oildentRefTemp_[regionIdx];
179 Evaluation Pref = oilJTRefPres_[regionIdx];
180 Scalar JTC = oilJTC_[regionIdx]; // if JTC is default then JTC is calculated
181
182 Evaluation invB = inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rs);
183 Evaluation Cp = internalEnergyCurves_[regionIdx].eval(temperature, /*extrapolate=*/true)/temperature;
184 Evaluation density = invB * (oilReferenceDensity(regionIdx) + Rs * rhoRefG_[regionIdx]);
185
186 Evaluation enthalpyPres;
187 if (JTC != 0) {
188 enthalpyPres = -Cp * JTC * (pressure -Pref);
189 }
190 else if(enableThermalDensity_) {
191 Scalar c1T = oildentCT1_[regionIdx];
192 Scalar c2T = oildentCT2_[regionIdx];
193
194 Evaluation alpha = (c1T + 2 * c2T * (temperature - Tref)) /
195 (1 + c1T *(temperature - Tref) + c2T * (temperature - Tref) * (temperature - Tref));
196
197 const int N = 100; // value is experimental
198 Evaluation deltaP = (pressure - Pref)/N;
199 Evaluation enthalpyPresPrev = 0;
200 for (size_t i = 0; i < N; ++i) {
201 Evaluation Pnew = Pref + i * deltaP;
202 Evaluation rho = inverseFormationVolumeFactor(regionIdx, temperature, Pnew, Rs) *
203 (oilReferenceDensity(regionIdx) + Rs * rhoRefG_[regionIdx]) ;
204 // see e.g.https://en.wikipedia.org/wiki/Joule-Thomson_effect for a derivation of the Joule-Thomson coeff.
205 Evaluation jouleThomsonCoefficient = -(1.0/Cp) * (1.0 - alpha * temperature)/rho;
206 Evaluation deltaEnthalpyPres = -Cp * jouleThomsonCoefficient * deltaP;
207 enthalpyPres = enthalpyPresPrev + deltaEnthalpyPres;
208 enthalpyPresPrev = enthalpyPres;
209 }
210 }
211 else {
212 throw std::runtime_error("Requested Joule-thomson calculation but thermal oil density (OILDENT) is not provided");
213 }
214
215 Evaluation enthalpy = Cp * (temperature - Tref) + enthalpyPres;
216
217 return enthalpy - pressure/density;
218 }
219 }
220
224 template <class Evaluation>
225 Evaluation viscosity(unsigned regionIdx,
226 const Evaluation& temperature,
227 const Evaluation& pressure,
228 const Evaluation& Rs) const
229 {
230 const auto& isothermalMu = isothermalPvt_->viscosity(regionIdx, temperature, pressure, Rs);
232 return isothermalMu;
233
234 // compute the viscosity deviation due to temperature
235 const auto& muOilvisct = oilvisctCurves_[regionIdx].eval(temperature, /*extrapolate=*/true);
236 return muOilvisct/viscRef_[regionIdx]*isothermalMu;
237 }
238
242 template <class Evaluation>
243 Evaluation saturatedViscosity(unsigned regionIdx,
244 const Evaluation& temperature,
245 const Evaluation& pressure) const
246 {
247 const auto& isothermalMu = isothermalPvt_->saturatedViscosity(regionIdx, temperature, pressure);
249 return isothermalMu;
250
251 // compute the viscosity deviation due to temperature
252 const auto& muOilvisct = oilvisctCurves_[regionIdx].eval(temperature, /*extrapolate=*/true);
253 return muOilvisct/viscRef_[regionIdx]*isothermalMu;
254 }
255
256
260 template <class Evaluation>
261 Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
262 const Evaluation& temperature,
263 const Evaluation& pressure,
264 const Evaluation& Rs) const
265 {
266 const auto& b =
267 isothermalPvt_->inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rs);
268
270 return b;
271
272 // we use the same approach as for the for water here, but with the OPM-specific
273 // OILDENT keyword.
274 Scalar TRef = oildentRefTemp_[regionIdx];
275 Scalar cT1 = oildentCT1_[regionIdx];
276 Scalar cT2 = oildentCT2_[regionIdx];
277 const Evaluation& Y = temperature - TRef;
278
279 return b/(1 + (cT1 + cT2*Y)*Y);
280 }
281
285 template <class Evaluation>
286 Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
287 const Evaluation& temperature,
288 const Evaluation& pressure) const
289 {
290 const auto& b =
291 isothermalPvt_->saturatedInverseFormationVolumeFactor(regionIdx, temperature, pressure);
292
294 return b;
295
296 // we use the same approach as for the for water here, but with the OPM-specific
297 // OILDENT keyword.
298 Scalar TRef = oildentRefTemp_[regionIdx];
299 Scalar cT1 = oildentCT1_[regionIdx];
300 Scalar cT2 = oildentCT2_[regionIdx];
301 const Evaluation& Y = temperature - TRef;
302
303 return b/(1 + (cT1 + cT2*Y)*Y);
304 }
305
313 template <class Evaluation>
314 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
315 const Evaluation& temperature,
316 const Evaluation& pressure) const
317 { return isothermalPvt_->saturatedGasDissolutionFactor(regionIdx, temperature, pressure); }
318
326 template <class Evaluation>
327 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
328 const Evaluation& temperature,
329 const Evaluation& pressure,
330 const Evaluation& oilSaturation,
331 const Evaluation& maxOilSaturation) const
332 { return isothermalPvt_->saturatedGasDissolutionFactor(regionIdx, temperature, pressure, oilSaturation, maxOilSaturation); }
333
341 template <class Evaluation>
342 Evaluation saturationPressure(unsigned regionIdx,
343 const Evaluation& temperature,
344 const Evaluation& pressure) const
345 { return isothermalPvt_->saturationPressure(regionIdx, temperature, pressure); }
346
347 template <class Evaluation>
348 Evaluation diffusionCoefficient(const Evaluation& temperature,
349 const Evaluation& pressure,
350 unsigned compIdx) const
351 {
352 return isothermalPvt_->diffusionCoefficient(temperature, pressure, compIdx);
353 }
354
355 const IsothermalPvt* isoThermalPvt() const
356 { return isothermalPvt_; }
357
358 const Scalar oilReferenceDensity(unsigned regionIdx) const
359 { return isothermalPvt_->oilReferenceDensity(regionIdx); }
360
361 const std::vector<TabulatedOneDFunction>& oilvisctCurves() const
362 { return oilvisctCurves_; }
363
364 const std::vector<Scalar>& viscrefPress() const
365 { return viscrefPress_; }
366
367 const std::vector<Scalar>& viscrefRs() const
368 { return viscrefRs_; }
369
370 const std::vector<Scalar>& viscRef() const
371 { return viscRef_; }
372
373 const std::vector<Scalar>& oildentRefTemp() const
374 { return oildentRefTemp_; }
375
376 const std::vector<Scalar>& oildentCT1() const
377 { return oildentCT1_; }
378
379 const std::vector<Scalar>& oildentCT2() const
380 { return oildentCT2_; }
381
382 const std::vector<TabulatedOneDFunction> internalEnergyCurves() const
383 { return internalEnergyCurves_; }
384
385 bool enableInternalEnergy() const
386 { return enableInternalEnergy_; }
387
388 const std::vector<Scalar>& oilJTRefPres() const
389 { return oilJTRefPres_; }
390
391 const std::vector<Scalar>& oilJTC() const
392 { return oilJTC_; }
393
394 bool operator==(const OilPvtThermal<Scalar>& data) const
395 {
396 if (isothermalPvt_ && !data.isothermalPvt_)
397 return false;
398 if (!isothermalPvt_ && data.isothermalPvt_)
399 return false;
400
401 return this->oilvisctCurves() == data.oilvisctCurves() &&
402 this->viscrefPress() == data.viscrefPress() &&
403 this->viscrefRs() == data.viscrefRs() &&
404 this->viscRef() == data.viscRef() &&
405 this->oildentRefTemp() == data.oildentRefTemp() &&
406 this->oildentCT1() == data.oildentCT1() &&
407 this->oildentCT2() == data.oildentCT2() &&
408 this->oilJTRefPres() == data.oilJTRefPres() &&
409 this->oilJTC() == data.oilJTC() &&
410 this->internalEnergyCurves() == data.internalEnergyCurves() &&
411 this->enableThermalDensity() == data.enableThermalDensity() &&
412 this->enableJouleThomson() == data.enableJouleThomson() &&
413 this->enableThermalViscosity() == data.enableThermalViscosity() &&
414 this->enableInternalEnergy() == data.enableInternalEnergy();
415 }
416
417 OilPvtThermal<Scalar>& operator=(const OilPvtThermal<Scalar>& data)
418 {
419 if (data.isothermalPvt_)
420 isothermalPvt_ = new IsothermalPvt(*data.isothermalPvt_);
421 else
422 isothermalPvt_ = nullptr;
423 oilvisctCurves_ = data.oilvisctCurves_;
424 viscrefPress_ = data.viscrefPress_;
425 viscrefRs_ = data.viscrefRs_;
426 viscRef_ = data.viscRef_;
427 oildentRefTemp_ = data.oildentRefTemp_;
428 oildentCT1_ = data.oildentCT1_;
429 oildentCT2_ = data.oildentCT2_;
430 oilJTRefPres_ = data.oilJTRefPres_;
431 oilJTC_ = data.oilJTC_;
432 internalEnergyCurves_ = data.internalEnergyCurves_;
433 enableThermalDensity_ = data.enableThermalDensity_;
434 enableJouleThomson_ = data.enableJouleThomson_;
435 enableThermalViscosity_ = data.enableThermalViscosity_;
436 enableInternalEnergy_ = data.enableInternalEnergy_;
437
438 return *this;
439 }
440
441private:
442 IsothermalPvt* isothermalPvt_;
443
444 // The PVT properties needed for temperature dependence of the viscosity. We need
445 // to store one value per PVT region.
446 std::vector<TabulatedOneDFunction> oilvisctCurves_;
447 std::vector<Scalar> viscrefPress_;
448 std::vector<Scalar> viscrefRs_;
449 std::vector<Scalar> viscRef_;
450
451 // The PVT properties needed for temperature dependence of the density.
452 std::vector<Scalar> oildentRefTemp_;
453 std::vector<Scalar> oildentCT1_;
454 std::vector<Scalar> oildentCT2_;
455
456 std::vector<Scalar> oilJTRefPres_;
457 std::vector<Scalar> oilJTC_;
458
459 std::vector<Scalar> rhoRefG_;
460
461 // piecewise linear curve representing the internal energy of oil
462 std::vector<TabulatedOneDFunction> internalEnergyCurves_;
463
464 bool enableThermalDensity_;
465 bool enableJouleThomson_;
466 bool enableThermalViscosity_;
467 bool enableInternalEnergy_;
468};
469
470} // namespace Opm
471
472#endif
Implements a linearly interpolated scalar function that depends on one variable.
Definition EclipseState.hpp:63
This class represents the Pressure-Volume-Temperature relations of the oil phase in the black-oil mod...
Definition OilPvtMultiplexer.hpp:104
Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs) const
Returns the formation volume factor [-] of the fluid phase.
Definition OilPvtMultiplexer.hpp:217
Evaluation saturatedViscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition OilPvtMultiplexer.hpp:208
Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the formation volume factor [-] of the fluid phase.
Definition OilPvtMultiplexer.hpp:227
Evaluation saturatedGasDissolutionFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the gas dissolution factor [m^3/m^3] of saturated oil.
Definition OilPvtMultiplexer.hpp:236
Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition OilPvtMultiplexer.hpp:198
Evaluation saturationPressure(unsigned regionIdx, const Evaluation &temperature, const Evaluation &Rs) const
Returns the saturation pressure [Pa] of oil given the mass fraction of the gas component in the oil p...
Definition OilPvtMultiplexer.hpp:260
const Scalar oilReferenceDensity(unsigned regionIdx) const
Return the reference density which are considered by this PVT-object.
Definition OilPvtMultiplexer.hpp:181
Evaluation diffusionCoefficient(const Evaluation &temperature, const Evaluation &pressure, unsigned compIdx) const
Calculate the binary molecular diffusion coefficient for a component in a fluid phase [mol^2 * s / (k...
Definition OilPvtMultiplexer.hpp:269
This class implements temperature dependence of the PVT properties of oil.
Definition OilPvtThermal.hpp:50
void initEnd()
Finish initializing the thermal part of the oil phase PVT properties.
Definition OilPvtThermal.hpp:135
bool enableThermalDensity() const
Returns true iff the density of the oil phase is temperature dependent.
Definition OilPvtThermal.hpp:141
Evaluation saturatedGasDissolutionFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the gas dissolution factor [m^3/m^3] of the oil phase.
Definition OilPvtThermal.hpp:314
Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs) const
Returns the formation volume factor [-] of the fluid phase.
Definition OilPvtThermal.hpp:261
Evaluation saturatedViscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition OilPvtThermal.hpp:243
Evaluation internalEnergy(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs) const
Returns the specific internal energy [J/kg] of oil given a set of parameters.
Definition OilPvtThermal.hpp:163
Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition OilPvtThermal.hpp:225
void setNumRegions(size_t numRegions)
Set the number of PVT-regions considered by this object.
Definition OilPvtThermal.hpp:112
bool enableThermalViscosity() const
Returns true iff the viscosity of the oil phase is temperature dependent.
Definition OilPvtThermal.hpp:153
Evaluation saturationPressure(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the saturation pressure of the oil phase [Pa].
Definition OilPvtThermal.hpp:342
Evaluation saturatedGasDissolutionFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &oilSaturation, const Evaluation &maxOilSaturation) const
Returns the gas dissolution factor [m^3/m^3] of the oil phase.
Definition OilPvtThermal.hpp:327
Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the formation volume factor [-] of gas-saturated oil phase.
Definition OilPvtThermal.hpp:286
bool enableJouleThomson() const
Returns true iff Joule-Thomson effect for the oil phase is active.
Definition OilPvtThermal.hpp:147
Definition Schedule.hpp:88
Implements a linearly interpolated scalar function that depends on one variable.
Definition Tabulated1DFunction.hpp:51
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30