opm-common
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
32#include <cstddef>
33
34namespace Opm {
35
36class EclipseState;
37class Schedule;
38
39template <class Scalar, bool enableThermal>
41
48template <class Scalar>
49class OilPvtThermal
50{
51public:
52 using TabulatedOneDFunction = Tabulated1DFunction<Scalar>;
53 using IsothermalPvt = OilPvtMultiplexer<Scalar, /*enableThermal=*/false>;
54
55 OilPvtThermal() = default;
56
57 OilPvtThermal(IsothermalPvt* isothermalPvt,
58 const std::vector<TabulatedOneDFunction>& oilvisctCurves,
59 const std::vector<Scalar>& viscrefPress,
60 const std::vector<Scalar>& viscrefRs,
61 const std::vector<Scalar>& viscRef,
62 const std::vector<Scalar>& oildentRefTemp,
63 const std::vector<Scalar>& oildentCT1,
64 const std::vector<Scalar>& oildentCT2,
65 const std::vector<Scalar>& oilJTRefPres,
66 const std::vector<Scalar>& oilJTC,
67 const std::vector<TabulatedOneDFunction>& internalEnergyCurves,
71 bool enableInternalEnergy)
72 : isothermalPvt_(isothermalPvt)
73 , oilvisctCurves_(oilvisctCurves)
74 , viscrefPress_(viscrefPress)
75 , viscrefRs_(viscrefRs)
76 , viscRef_(viscRef)
77 , oildentRefTemp_(oildentRefTemp)
78 , oildentCT1_(oildentCT1)
79 , oildentCT2_(oildentCT2)
80 , oilJTRefPres_(oilJTRefPres)
81 , oilJTC_(oilJTC)
82 , internalEnergyCurves_(internalEnergyCurves)
83 , enableThermalDensity_(enableThermalDensity)
84 , enableJouleThomson_(enableJouleThomson)
85 , enableThermalViscosity_(enableThermalViscosity)
86 , enableInternalEnergy_(enableInternalEnergy)
87 { }
88
89 OilPvtThermal(const OilPvtThermal& data)
90 { *this = data; }
91
92 ~OilPvtThermal()
93 { delete isothermalPvt_; }
94
98 void initFromState(const EclipseState& eclState, const Schedule& schedule);
99
103 void setNumRegions(std::size_t numRegions);
104
105 void setVapPars(const Scalar par1, const Scalar par2)
106 {
107 isothermalPvt_->setVapPars(par1, par2);
108 }
109
113 void initEnd()
114 { }
115
120 { return enableThermalDensity_; }
121
126 { return enableJouleThomson_; }
127
132 { return enableThermalViscosity_; }
133
134 std::size_t numRegions() const
135 { return viscrefRs_.size(); }
136
140 template <class Evaluation>
141 Evaluation internalEnergy(unsigned regionIdx,
142 const Evaluation& temperature,
143 const Evaluation& pressure,
144 const Evaluation& Rs) const
145 {
146 if (!enableInternalEnergy_) {
147 throw std::runtime_error("Requested the internal energy of oil but it is disabled");
148 }
149
150 if (!enableJouleThomson_) {
151 // compute the specific internal energy for the specified tempature. We use linear
152 // interpolation here despite the fact that the underlying heat capacities are
153 // piecewise linear (which leads to a quadratic function)
154 return internalEnergyCurves_[regionIdx].eval(temperature, /*extrapolate=*/true);
155 }
156 else {
157 OpmLog::warning("Experimental code for jouleThomson: simulation will be slower");
158 Evaluation Tref = oildentRefTemp_[regionIdx];
159 Evaluation Pref = oilJTRefPres_[regionIdx];
160 Scalar JTC = oilJTC_[regionIdx]; // if JTC is default then JTC is calculated
161
162 Evaluation invB = inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rs);
163 Evaluation Cp = internalEnergyCurves_[regionIdx].eval(temperature, /*extrapolate=*/true)/temperature;
164 Evaluation density = invB * (oilReferenceDensity(regionIdx) + Rs * rhoRefG_[regionIdx]);
165
166 Evaluation enthalpyPres;
167 if (JTC != 0) {
168 enthalpyPres = -Cp * JTC * (pressure - Pref);
169 }
170 else if (enableThermalDensity_) {
171 Scalar c1T = oildentCT1_[regionIdx];
172 Scalar c2T = oildentCT2_[regionIdx];
173
174 Evaluation alpha = (c1T + 2 * c2T * (temperature - Tref)) /
175 (1 + c1T *(temperature - Tref) + c2T * (temperature - Tref) * (temperature - Tref));
176
177 const int N = 100; // value is experimental
178 Evaluation deltaP = (pressure - Pref) / N;
179 Evaluation enthalpyPresPrev = 0;
180 for (std::size_t i = 0; i < N; ++i) {
181 Evaluation Pnew = Pref + i * deltaP;
182 Evaluation rho = inverseFormationVolumeFactor(regionIdx, temperature, Pnew, Rs) *
183 (oilReferenceDensity(regionIdx) + Rs * rhoRefG_[regionIdx]) ;
184 // see e.g.https://en.wikipedia.org/wiki/Joule-Thomson_effect for a derivation of the Joule-Thomson coeff.
185 Evaluation jouleThomsonCoefficient = -(1.0/Cp) * (1.0 - alpha * temperature)/rho;
186 Evaluation deltaEnthalpyPres = -Cp * jouleThomsonCoefficient * deltaP;
187 enthalpyPres = enthalpyPresPrev + deltaEnthalpyPres;
188 enthalpyPresPrev = enthalpyPres;
189 }
190 }
191 else {
192 throw std::runtime_error("Requested Joule-thomson calculation but thermal oil"
193 "density (OILDENT) is not provided");
194 }
195
196 Evaluation enthalpy = Cp * (temperature - Tref) + enthalpyPres;
197
198 return enthalpy - pressure/density;
199 }
200 }
201
205 template <class Evaluation>
206 Evaluation viscosity(unsigned regionIdx,
207 const Evaluation& temperature,
208 const Evaluation& pressure,
209 const Evaluation& Rs) const
210 {
211 const auto& isothermalMu = isothermalPvt_->viscosity(regionIdx, temperature, pressure, Rs);
212 if (!enableThermalViscosity()) {
213 return isothermalMu;
214 }
215
216 // compute the viscosity deviation due to temperature
217 const auto& muOilvisct = oilvisctCurves_[regionIdx].eval(temperature, /*extrapolate=*/true);
218 return muOilvisct / viscRef_[regionIdx] * isothermalMu;
219 }
220
224 template <class Evaluation>
225 Evaluation saturatedViscosity(unsigned regionIdx,
226 const Evaluation& temperature,
227 const Evaluation& pressure) const
228 {
229 const auto& isothermalMu = isothermalPvt_->saturatedViscosity(regionIdx, temperature, pressure);
230 if (!enableThermalViscosity()) {
231 return isothermalMu;
232 }
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 inverseFormationVolumeFactor(unsigned regionIdx,
244 const Evaluation& temperature,
245 const Evaluation& pressure,
246 const Evaluation& Rs) const
247 {
248 const auto& b =
249 isothermalPvt_->inverseFormationVolumeFactor(regionIdx, temperature, pressure, Rs);
250
251 if (!enableThermalDensity()) {
252 return b;
253 }
254
255 // we use the same approach as for the for water here, but with the OPM-specific
256 // OILDENT keyword.
257 Scalar TRef = oildentRefTemp_[regionIdx];
258 Scalar cT1 = oildentCT1_[regionIdx];
259 Scalar cT2 = oildentCT2_[regionIdx];
260 const Evaluation& Y = temperature - TRef;
261
262 return b / (1 + (cT1 + cT2 * Y) * Y);
263 }
264
268 template <class FluidState, class LhsEval = typename FluidState::ValueType>
269 std::pair<LhsEval, LhsEval>
270 inverseFormationVolumeFactorAndViscosity(const FluidState& fluidState, unsigned regionIdx)
271 {
272 auto [b, mu] = isothermalPvt_->inverseFormationVolumeFactorAndViscosity(fluidState, regionIdx);
273 const LhsEval& temperature = decay<LhsEval>(fluidState.temperature(FluidState::oilPhaseIdx));
274 if (enableThermalDensity()) {
275 // we use the same approach as for the for water here, but with the OPM-specific
276 // OILDENT keyword.
277 Scalar TRef = oildentRefTemp_[regionIdx];
278 Scalar cT1 = oildentCT1_[regionIdx];
279 Scalar cT2 = oildentCT2_[regionIdx];
280 const LhsEval Y = temperature - TRef;
281 b /= (1.0 + (cT1 + cT2 * Y) * Y);
282 }
284 // compute the viscosity deviation due to temperature
285 const auto muOilvisct = oilvisctCurves_[regionIdx].eval(temperature, /*extrapolate=*/true);
286 mu *= (muOilvisct / viscRef_[regionIdx]);
287 }
288 return { b, mu };
289 }
290
294 template <class Evaluation>
295 Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
296 const Evaluation& temperature,
297 const Evaluation& pressure) const
298 {
299 const auto& b =
300 isothermalPvt_->saturatedInverseFormationVolumeFactor(regionIdx, temperature, pressure);
301
302 if (!enableThermalDensity()) {
303 return b;
304 }
305
306 // we use the same approach as for the for water here, but with the OPM-specific
307 // OILDENT keyword.
308 Scalar TRef = oildentRefTemp_[regionIdx];
309 Scalar cT1 = oildentCT1_[regionIdx];
310 Scalar cT2 = oildentCT2_[regionIdx];
311 const Evaluation& Y = temperature - TRef;
312
313 return b / (1 + (cT1 + cT2 * Y) * Y);
314 }
315
323 template <class Evaluation>
324 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
325 const Evaluation& temperature,
326 const Evaluation& pressure) const
327 { return isothermalPvt_->saturatedGasDissolutionFactor(regionIdx, temperature, pressure); }
328
336 template <class Evaluation>
337 Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
338 const Evaluation& temperature,
339 const Evaluation& pressure,
340 const Evaluation& oilSaturation,
341 const Evaluation& maxOilSaturation) const
342 { return isothermalPvt_->saturatedGasDissolutionFactor(regionIdx, temperature, pressure, oilSaturation, maxOilSaturation); }
343
351 template <class Evaluation>
352 Evaluation saturationPressure(unsigned regionIdx,
353 const Evaluation& temperature,
354 const Evaluation& pressure) const
355 { return isothermalPvt_->saturationPressure(regionIdx, temperature, pressure); }
356
357 template <class Evaluation>
358 Evaluation diffusionCoefficient(const Evaluation& temperature,
359 const Evaluation& pressure,
360 unsigned compIdx) const
361 {
362 return isothermalPvt_->diffusionCoefficient(temperature, pressure, compIdx);
363 }
364
365 const IsothermalPvt* isoThermalPvt() const
366 { return isothermalPvt_; }
367
368 Scalar oilReferenceDensity(unsigned regionIdx) const
369 { return isothermalPvt_->oilReferenceDensity(regionIdx); }
370
371 Scalar hVap(unsigned regionIdx) const
372 { return this->hVap_[regionIdx]; }
373
374 const std::vector<TabulatedOneDFunction>& oilvisctCurves() const
375 { return oilvisctCurves_; }
376
377 const std::vector<Scalar>& viscrefPress() const
378 { return viscrefPress_; }
379
380 const std::vector<Scalar>& viscrefRs() const
381 { return viscrefRs_; }
382
383 const std::vector<Scalar>& viscRef() const
384 { return viscRef_; }
385
386 const std::vector<Scalar>& oildentRefTemp() const
387 { return oildentRefTemp_; }
388
389 const std::vector<Scalar>& oildentCT1() const
390 { return oildentCT1_; }
391
392 const std::vector<Scalar>& oildentCT2() const
393 { return oildentCT2_; }
394
395 const std::vector<TabulatedOneDFunction>& internalEnergyCurves() const
396 { return internalEnergyCurves_; }
397
398 bool enableInternalEnergy() const
399 { return enableInternalEnergy_; }
400
401 const std::vector<Scalar>& oilJTRefPres() const
402 { return oilJTRefPres_; }
403
404 const std::vector<Scalar>& oilJTC() const
405 { return oilJTC_; }
406
407 bool operator==(const OilPvtThermal<Scalar>& data) const;
408
409 OilPvtThermal<Scalar>& operator=(const OilPvtThermal<Scalar>& data);
410
411private:
412 IsothermalPvt* isothermalPvt_{nullptr};
413
414 // The PVT properties needed for temperature dependence of the viscosity. We need
415 // to store one value per PVT region.
416 std::vector<TabulatedOneDFunction> oilvisctCurves_{};
417 std::vector<Scalar> viscrefPress_{};
418 std::vector<Scalar> viscrefRs_{};
419 std::vector<Scalar> viscRef_{};
420
421 // The PVT properties needed for temperature dependence of the density.
422 std::vector<Scalar> oildentRefTemp_{};
423 std::vector<Scalar> oildentCT1_{};
424 std::vector<Scalar> oildentCT2_{};
425
426 std::vector<Scalar> oilJTRefPres_{};
427 std::vector<Scalar> oilJTC_{};
428
429 std::vector<Scalar> rhoRefG_{};
430 std::vector<Scalar> hVap_{};
431
432 // piecewise linear curve representing the internal energy of oil
433 std::vector<TabulatedOneDFunction> internalEnergyCurves_{};
434
435 bool enableThermalDensity_{false};
436 bool enableJouleThomson_{false};
437 bool enableThermalViscosity_{false};
438 bool enableInternalEnergy_{false};
439};
440
441} // namespace Opm
442
443#endif
Implements a linearly interpolated scalar function that depends on one variable.
Definition EclipseState.hpp:66
This class represents the Pressure-Volume-Temperature relations of the oil phase in the black-oil mod...
Definition OilPvtMultiplexer.hpp:110
Scalar oilReferenceDensity(unsigned regionIdx) const
Return the reference density which are considered by this PVT-object.
Definition OilPvtMultiplexer.cpp:130
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:256
std::pair< LhsEval, LhsEval > inverseFormationVolumeFactorAndViscosity(const FluidState &fluidState, unsigned regionIdx)
Returns the formation volume factor [-] and viscosity [Pa s] of the fluid phase.
Definition OilPvtThermal.hpp:270
void initEnd()
Finish initializing the thermal part of the oil phase PVT properties.
Definition OilPvtThermal.hpp:113
bool enableThermalDensity() const
Returns true iff the density of the oil phase is temperature dependent.
Definition OilPvtThermal.hpp:119
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:324
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:243
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:225
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:141
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:206
void setNumRegions(std::size_t numRegions)
Set the number of PVT-regions considered by this object.
Definition OilPvtThermal.cpp:181
bool enableThermalViscosity() const
Returns true iff the viscosity of the oil phase is temperature dependent.
Definition OilPvtThermal.hpp:131
void initFromState(const EclipseState &eclState, const Schedule &schedule)
Implement the temperature part of the oil PVT properties.
Definition OilPvtThermal.cpp:41
Evaluation saturationPressure(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the saturation pressure of the oil phase [Pa].
Definition OilPvtThermal.hpp:352
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:337
Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the formation volume factor [-] of gas-saturated oil phase.
Definition OilPvtThermal.hpp:295
bool enableJouleThomson() const
Returns true iff Joule-Thomson effect for the oil phase is active.
Definition OilPvtThermal.hpp:125
Definition Schedule.hpp:101
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