27 #ifndef OPM_OIL_PVT_THERMAL_HPP
28 #define OPM_OIL_PVT_THERMAL_HPP
33 #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
34 #include <opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp>
35 #include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
39 template <
class Scalar,
bool enableThermal>
40 class OilPvtMultiplexer;
48 template <
class Scalar>
57 enableThermalDensity_ =
false;
58 enableJouleThomson_ =
false;
59 enableThermalViscosity_ =
false;
60 enableInternalEnergy_ =
false;
61 isothermalPvt_ =
nullptr;
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,
76 bool enableJouleThomson,
78 bool enableInternalEnergy)
79 : isothermalPvt_(isothermalPvt)
80 , oilvisctCurves_(oilvisctCurves)
81 , viscrefPress_(viscrefPress)
82 , viscrefRs_(viscrefRs)
84 , oildentRefTemp_(oildentRefTemp)
85 , oildentCT1_(oildentCT1)
86 , oildentCT2_(oildentCT2)
87 , oilJTRefPres_(oilJTRefPres)
89 , internalEnergyCurves_(internalEnergyCurves)
91 , enableJouleThomson_(enableJouleThomson)
93 , enableInternalEnergy_(enableInternalEnergy)
100 {
delete isothermalPvt_; }
106 void initFromState(
const EclipseState& eclState,
const Schedule& schedule)
112 isothermalPvt_->initFromState(eclState, schedule);
117 const auto& tables = eclState.getTableManager();
119 enableThermalDensity_ = tables.OilDenT().size() > 0;
120 enableThermalViscosity_ = tables.hasTables(
"OILVISCT");
121 enableInternalEnergy_ = tables.hasTables(
"SPECHEAT");
123 unsigned numRegions = isothermalPvt_->
numRegions();
127 if (enableThermalViscosity_) {
128 if (tables.getViscrefTable().empty())
129 throw std::runtime_error(
"VISCREF is required when OILVISCT is present");
131 const auto& oilvisctTables = tables.getOilvisctTables();
132 const auto& viscrefTable = tables.getViscrefTable();
134 assert(oilvisctTables.size() == numRegions);
135 assert(viscrefTable.size() == numRegions);
137 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
138 const auto& TCol = oilvisctTables[regionIdx].getColumn(
"Temperature").vectorCopy();
139 const auto& muCol = oilvisctTables[regionIdx].getColumn(
"Viscosity").vectorCopy();
140 oilvisctCurves_[regionIdx].setXYContainers(TCol, muCol);
142 viscrefPress_[regionIdx] = viscrefTable[regionIdx].reference_pressure;
143 viscrefRs_[regionIdx] = viscrefTable[regionIdx].reference_rs;
148 constexpr
const Scalar Tref = 273.15 + 20;
151 viscRef_[regionIdx] =
154 viscrefPress_[regionIdx],
155 viscrefRs_[regionIdx]);
160 const auto& oilDenT = tables.OilDenT();
161 if (oilDenT.size() > 0) {
162 assert(oilDenT.size() == numRegions);
163 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
164 const auto& record = oilDenT[regionIdx];
166 oildentRefTemp_[regionIdx] = record.T0;
167 oildentCT1_[regionIdx] = record.C1;
168 oildentCT2_[regionIdx] = record.C2;
173 if (enableJouleThomson_) {
174 const auto& oilJT = tables.OilJT();
176 assert(oilJT.size() == numRegions);
177 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
178 const auto& record = oilJT[regionIdx];
180 oilJTRefPres_[regionIdx] = record.P0;
181 oilJTC_[regionIdx] = record.C1;
184 const auto& densityTable = eclState.getTableManager().getDensityTable();
186 assert(densityTable.size() == numRegions);
187 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
188 rhoRefG_[regionIdx] = densityTable[regionIdx].gas;
192 if (enableInternalEnergy_) {
196 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
197 const auto& specheatTable = tables.getSpecheatTables()[regionIdx];
198 const auto& temperatureColumn = specheatTable.getColumn(
"TEMPERATURE");
199 const auto& cvOilColumn = specheatTable.getColumn(
"CV_OIL");
201 std::vector<double> uSamples(temperatureColumn.size());
203 Scalar u = temperatureColumn[0]*cvOilColumn[0];
204 for (
size_t i = 0;; ++i) {
207 if (i >= temperatureColumn.size() - 1)
212 Scalar c_v0 = cvOilColumn[i];
213 Scalar c_v1 = cvOilColumn[i + 1];
214 Scalar T0 = temperatureColumn[i];
215 Scalar T1 = temperatureColumn[i + 1];
216 u += 0.5*(c_v0 + c_v1)*(T1 - T0);
219 internalEnergyCurves_[regionIdx].setXYContainers(temperatureColumn.vectorCopy(), uSamples);
230 oilvisctCurves_.resize(numRegions);
231 viscrefPress_.resize(numRegions);
232 viscrefRs_.resize(numRegions);
233 viscRef_.resize(numRegions);
234 internalEnergyCurves_.resize(numRegions);
235 oildentRefTemp_.resize(numRegions);
236 oildentCT1_.resize(numRegions);
237 oildentCT2_.resize(numRegions);
238 oilJTRefPres_.resize(numRegions);
239 oilJTC_.resize(numRegions);
240 rhoRefG_.resize(numRegions);
253 {
return enableThermalDensity_; }
259 {
return enableJouleThomson_; }
265 {
return enableThermalViscosity_; }
267 size_t numRegions()
const
268 {
return viscrefRs_.size(); }
273 template <
class Evaluation>
275 const Evaluation& temperature,
276 const Evaluation& pressure,
277 const Evaluation& Rs)
const
279 if (!enableInternalEnergy_)
280 throw std::runtime_error(
"Requested the internal energy of oil but it is disabled");
282 if (!enableJouleThomson_) {
286 return internalEnergyCurves_[regionIdx].eval(temperature,
true);
289 Evaluation Tref = oildentRefTemp_[regionIdx];
290 Evaluation Pref = oilJTRefPres_[regionIdx];
291 Scalar JTC = oilJTC_[regionIdx];
294 Evaluation Cp = internalEnergyCurves_[regionIdx].eval(temperature,
true)/temperature;
295 Evaluation density = invB * (oilReferenceDensity(regionIdx) + Rs * rhoRefG_[regionIdx]);
297 Evaluation enthalpyPres;
299 enthalpyPres = -Cp * JTC * (pressure -Pref);
301 else if(enableThermalDensity_) {
302 Scalar c1T = oildentCT1_[regionIdx];
303 Scalar c2T = oildentCT2_[regionIdx];
305 Evaluation alpha = (c1T + 2 * c2T * (temperature - Tref)) /
306 (1 + c1T *(temperature - Tref) + c2T * (temperature - Tref) * (temperature - Tref));
309 Evaluation deltaP = (pressure - Pref)/N;
310 Evaluation enthalpyPresPrev = 0;
311 for (
size_t i = 0; i < N; ++i) {
312 Evaluation Pnew = Pref + i * deltaP;
314 (oilReferenceDensity(regionIdx) + Rs * rhoRefG_[regionIdx]) ;
316 Evaluation jouleThomsonCoefficient = -(1.0/Cp) * (1.0 - alpha * temperature)/rho;
317 Evaluation deltaEnthalpyPres = -Cp * jouleThomsonCoefficient * deltaP;
318 enthalpyPres = enthalpyPresPrev + deltaEnthalpyPres;
319 enthalpyPresPrev = enthalpyPres;
323 throw std::runtime_error(
"Requested Joule-thomson calculation but thermal oil density (OILDENT) is not provided");
326 Evaluation enthalpy = Cp * (temperature - Tref) + enthalpyPres;
328 return enthalpy - pressure/density;
335 template <
class Evaluation>
337 const Evaluation& temperature,
338 const Evaluation& pressure,
339 const Evaluation& Rs)
const
341 const auto& isothermalMu = isothermalPvt_->
viscosity(regionIdx, temperature, pressure, Rs);
346 const auto& muOilvisct = oilvisctCurves_[regionIdx].eval(temperature,
true);
347 return muOilvisct/viscRef_[regionIdx]*isothermalMu;
353 template <
class Evaluation>
355 const Evaluation& temperature,
356 const Evaluation& pressure)
const
358 const auto& isothermalMu = isothermalPvt_->
saturatedViscosity(regionIdx, temperature, pressure);
363 const auto& muOilvisct = oilvisctCurves_[regionIdx].eval(temperature,
true);
364 return muOilvisct/viscRef_[regionIdx]*isothermalMu;
371 template <
class Evaluation>
373 const Evaluation& temperature,
374 const Evaluation& pressure,
375 const Evaluation& Rs)
const
385 Scalar TRef = oildentRefTemp_[regionIdx];
386 Scalar cT1 = oildentCT1_[regionIdx];
387 Scalar cT2 = oildentCT2_[regionIdx];
388 const Evaluation& Y = temperature - TRef;
390 return b/(1 + (cT1 + cT2*Y)*Y);
396 template <
class Evaluation>
398 const Evaluation& temperature,
399 const Evaluation& pressure)
const
409 Scalar TRef = oildentRefTemp_[regionIdx];
410 Scalar cT1 = oildentCT1_[regionIdx];
411 Scalar cT2 = oildentCT2_[regionIdx];
412 const Evaluation& Y = temperature - TRef;
414 return b/(1 + (cT1 + cT2*Y)*Y);
424 template <
class Evaluation>
426 const Evaluation& temperature,
427 const Evaluation& pressure)
const
437 template <
class Evaluation>
439 const Evaluation& temperature,
440 const Evaluation& pressure,
441 const Evaluation& oilSaturation,
442 const Evaluation& maxOilSaturation)
const
452 template <
class Evaluation>
454 const Evaluation& temperature,
455 const Evaluation& pressure)
const
458 template <
class Evaluation>
459 Evaluation diffusionCoefficient(
const Evaluation& temperature,
460 const Evaluation& pressure,
461 unsigned compIdx)
const
466 const IsothermalPvt* isoThermalPvt()
const
467 {
return isothermalPvt_; }
469 const Scalar oilReferenceDensity(
unsigned regionIdx)
const
472 const std::vector<TabulatedOneDFunction>& oilvisctCurves()
const
473 {
return oilvisctCurves_; }
475 const std::vector<Scalar>& viscrefPress()
const
476 {
return viscrefPress_; }
478 const std::vector<Scalar>& viscrefRs()
const
479 {
return viscrefRs_; }
481 const std::vector<Scalar>& viscRef()
const
484 const std::vector<Scalar>& oildentRefTemp()
const
485 {
return oildentRefTemp_; }
487 const std::vector<Scalar>& oildentCT1()
const
488 {
return oildentCT1_; }
490 const std::vector<Scalar>& oildentCT2()
const
491 {
return oildentCT2_; }
493 const std::vector<TabulatedOneDFunction> internalEnergyCurves()
const
494 {
return internalEnergyCurves_; }
496 bool enableInternalEnergy()
const
497 {
return enableInternalEnergy_; }
499 const std::vector<Scalar>& oilJTRefPres()
const
500 {
return oilJTRefPres_; }
502 const std::vector<Scalar>& oilJTC()
const
505 bool operator==(
const OilPvtThermal<Scalar>& data)
const
507 if (isothermalPvt_ && !data.isothermalPvt_)
509 if (!isothermalPvt_ && data.isothermalPvt_)
512 return (!this->isoThermalPvt() ||
513 (*this->isoThermalPvt() == *data.isoThermalPvt())) &&
514 this->oilvisctCurves() == data.oilvisctCurves() &&
515 this->viscrefPress() == data.viscrefPress() &&
516 this->viscrefRs() == data.viscrefRs() &&
517 this->viscRef() == data.viscRef() &&
518 this->oildentRefTemp() == data.oildentRefTemp() &&
519 this->oildentCT1() == data.oildentCT1() &&
520 this->oildentCT2() == data.oildentCT2() &&
521 this->oilJTRefPres() == data.oilJTRefPres() &&
522 this->oilJTC() == data.oilJTC() &&
523 this->internalEnergyCurves() == data.internalEnergyCurves() &&
525 this->enableJouleThomson() == data.enableJouleThomson() &&
527 this->enableInternalEnergy() == data.enableInternalEnergy();
530 OilPvtThermal<Scalar>& operator=(
const OilPvtThermal<Scalar>& data)
532 if (data.isothermalPvt_)
533 isothermalPvt_ =
new IsothermalPvt(*data.isothermalPvt_);
535 isothermalPvt_ =
nullptr;
536 oilvisctCurves_ = data.oilvisctCurves_;
537 viscrefPress_ = data.viscrefPress_;
538 viscrefRs_ = data.viscrefRs_;
539 viscRef_ = data.viscRef_;
540 oildentRefTemp_ = data.oildentRefTemp_;
541 oildentCT1_ = data.oildentCT1_;
542 oildentCT2_ = data.oildentCT2_;
543 oilJTRefPres_ = data.oilJTRefPres_;
544 oilJTC_ = data.oilJTC_;
545 internalEnergyCurves_ = data.internalEnergyCurves_;
546 enableThermalDensity_ = data.enableThermalDensity_;
547 enableJouleThomson_ = data.enableJouleThomson_;
548 enableThermalViscosity_ = data.enableThermalViscosity_;
549 enableInternalEnergy_ = data.enableInternalEnergy_;
555 IsothermalPvt* isothermalPvt_;
559 std::vector<TabulatedOneDFunction> oilvisctCurves_;
560 std::vector<Scalar> viscrefPress_;
561 std::vector<Scalar> viscrefRs_;
562 std::vector<Scalar> viscRef_;
565 std::vector<Scalar> oildentRefTemp_;
566 std::vector<Scalar> oildentCT1_;
567 std::vector<Scalar> oildentCT2_;
569 std::vector<Scalar> oilJTRefPres_;
570 std::vector<Scalar> oilJTC_;
572 std::vector<Scalar> rhoRefG_;
575 std::vector<TabulatedOneDFunction> internalEnergyCurves_;
577 bool enableThermalDensity_;
578 bool enableJouleThomson_;
579 bool enableThermalViscosity_;
580 bool enableInternalEnergy_;
Implements a linearly interpolated scalar function that depends on one variable.
This class represents the Pressure-Volume-Temperature relations of the oil phase in the black-oil mod...
Definition: OilPvtMultiplexer.hpp:96
unsigned numRegions() const
Return the number of PVT regions which are considered by this PVT-object.
Definition: OilPvtMultiplexer.hpp:177
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:219
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:210
Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the formation volume factor [-] of the fluid phase.
Definition: OilPvtMultiplexer.hpp:229
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:238
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:200
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:262
const Scalar oilReferenceDensity(unsigned regionIdx) const
Return the reference density which are considered by this PVT-object.
Definition: OilPvtMultiplexer.hpp:183
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:271
This class implements temperature dependence of the PVT properties of oil.
Definition: OilPvtThermal.hpp:50
bool enableJouleThomsony() const
Returns true iff Joule-Thomson effect for the oil phase is active.
Definition: OilPvtThermal.hpp:258
void initEnd()
Finish initializing the thermal part of the oil phase PVT properties.
Definition: OilPvtThermal.hpp:246
bool enableThermalDensity() const
Returns true iff the density of the oil phase is temperature dependent.
Definition: OilPvtThermal.hpp:252
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:425
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:372
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:354
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:274
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:336
void setNumRegions(size_t numRegions)
Set the number of PVT-regions considered by this object.
Definition: OilPvtThermal.hpp:228
bool enableThermalViscosity() const
Returns true iff the viscosity of the oil phase is temperature dependent.
Definition: OilPvtThermal.hpp:264
Evaluation saturationPressure(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the saturation pressure of the oil phase [Pa].
Definition: OilPvtThermal.hpp:453
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:438
Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the formation volume factor [-] of gas-saturated oil phase.
Definition: OilPvtThermal.hpp:397
Implements a linearly interpolated scalar function that depends on one variable.
Definition: Tabulated1DFunction.hpp:48