27 #ifndef OPM_WATER_PVT_THERMAL_HPP
28 #define OPM_WATER_PVT_THERMAL_HPP
38 #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
39 #include <opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp>
40 #include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
44 template <
class Scalar,
bool enableThermal,
bool enableBrine>
45 class WaterPvtMultiplexer;
53 template <
class Scalar,
bool enableBrine>
62 enableThermalDensity_ =
false;
63 enableThermalViscosity_ =
false;
64 enableInternalEnergy_ =
false;
65 isothermalPvt_ =
nullptr;
69 const std::vector<Scalar>& viscrefPress,
70 const std::vector<Scalar>& watdentRefTemp,
71 const std::vector<Scalar>& watdentCT1,
72 const std::vector<Scalar>& watdentCT2,
73 const std::vector<Scalar>& pvtwRefPress,
74 const std::vector<Scalar>& pvtwRefB,
75 const std::vector<Scalar>& pvtwCompressibility,
76 const std::vector<Scalar>& pvtwViscosity,
77 const std::vector<Scalar>& pvtwViscosibility,
78 const std::vector<TabulatedOneDFunction>& watvisctCurves,
79 const std::vector<TabulatedOneDFunction>& internalEnergyCurves,
82 bool enableInternalEnergy)
83 : isothermalPvt_(isothermalPvt)
84 , viscrefPress_(viscrefPress)
85 , watdentRefTemp_(watdentRefTemp)
86 , watdentCT1_(watdentCT1)
87 , watdentCT2_(watdentCT2)
88 , pvtwRefPress_(pvtwRefPress)
90 , pvtwCompressibility_(pvtwCompressibility)
91 , pvtwViscosity_(pvtwViscosity)
92 , pvtwViscosibility_(pvtwViscosibility)
93 , watvisctCurves_(watvisctCurves)
94 , internalEnergyCurves_(internalEnergyCurves)
97 , enableInternalEnergy_(enableInternalEnergy)
104 {
delete isothermalPvt_; }
110 void initFromState(
const EclipseState& eclState,
const Schedule& schedule)
116 isothermalPvt_->initFromState(eclState, schedule);
121 const auto& tables = eclState.getTableManager();
123 enableThermalDensity_ = tables.WatDenT().size() > 0;
124 enableThermalViscosity_ = tables.hasTables(
"WATVISCT");
125 enableInternalEnergy_ = tables.hasTables(
"SPECHEAT");
127 unsigned numRegions = isothermalPvt_->
numRegions();
130 if (enableThermalDensity_) {
131 const auto& watDenT = tables.WatDenT();
133 assert(watDenT.size() == numRegions);
134 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
135 const auto& record = watDenT[regionIdx];
137 watdentRefTemp_[regionIdx] = record.T0;
138 watdentCT1_[regionIdx] = record.C1;
139 watdentCT2_[regionIdx] = record.C2;
143 if (enableThermalViscosity_) {
144 if (tables.getViscrefTable().empty())
145 throw std::runtime_error(
"VISCREF is required when WATVISCT is present");
147 const auto& watvisctTables = tables.getWatvisctTables();
148 const auto& viscrefTables = tables.getViscrefTable();
150 const auto& pvtwTables = tables.getPvtwTable();
152 assert(pvtwTables.size() == numRegions);
153 assert(watvisctTables.size() == numRegions);
154 assert(viscrefTables.size() == numRegions);
156 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
157 const auto& T = watvisctTables[regionIdx].getColumn(
"Temperature").vectorCopy();
158 const auto& mu = watvisctTables[regionIdx].getColumn(
"Viscosity").vectorCopy();
159 watvisctCurves_[regionIdx].setXYContainers(T, mu);
161 viscrefPress_[regionIdx] = viscrefTables[regionIdx].reference_pressure;
164 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
165 pvtwViscosity_[regionIdx] = pvtwTables[regionIdx].viscosity;
166 pvtwViscosibility_[regionIdx] = pvtwTables[regionIdx].viscosibility;
170 if (enableInternalEnergy_) {
174 for (
unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
175 const auto& specHeatTable = tables.getSpecheatTables()[regionIdx];
176 const auto& temperatureColumn = specHeatTable.getColumn(
"TEMPERATURE");
177 const auto& cvWaterColumn = specHeatTable.getColumn(
"CV_WATER");
179 std::vector<double> uSamples(temperatureColumn.size());
181 Scalar u = temperatureColumn[0]*cvWaterColumn[0];
182 for (
size_t i = 0;; ++i) {
185 if (i >= temperatureColumn.size() - 1)
190 Scalar c_v0 = cvWaterColumn[i];
191 Scalar c_v1 = cvWaterColumn[i + 1];
192 Scalar T0 = temperatureColumn[i];
193 Scalar T1 = temperatureColumn[i + 1];
194 u += 0.5*(c_v0 + c_v1)*(T1 - T0);
197 internalEnergyCurves_[regionIdx].setXYContainers(temperatureColumn.vectorCopy(), uSamples);
208 pvtwRefPress_.resize(numRegions);
209 pvtwRefB_.resize(numRegions);
210 pvtwCompressibility_.resize(numRegions);
211 pvtwViscosity_.resize(numRegions);
212 pvtwViscosibility_.resize(numRegions);
213 viscrefPress_.resize(numRegions);
214 watvisctCurves_.resize(numRegions);
215 watdentRefTemp_.resize(numRegions);
216 watdentCT1_.resize(numRegions);
217 watdentCT2_.resize(numRegions);
218 internalEnergyCurves_.resize(numRegions);
231 {
return enableThermalDensity_; }
237 {
return enableThermalViscosity_; }
239 size_t numRegions()
const
240 {
return pvtwRefPress_.size(); }
245 template <
class Evaluation>
247 const Evaluation& temperature,
248 const Evaluation&)
const
250 if (!enableInternalEnergy_)
251 throw std::runtime_error(
"Requested the internal energy of oil but it is disabled");
256 return internalEnergyCurves_[regionIdx].eval(temperature,
true);
262 template <
class Evaluation>
264 const Evaluation& temperature,
265 const Evaluation& pressure,
266 const Evaluation& saltconcentration)
const
268 const auto& isothermalMu = isothermalPvt_->
viscosity(regionIdx, temperature, pressure, saltconcentration);
272 Scalar x = -pvtwViscosibility_[regionIdx]*(viscrefPress_[regionIdx] - pvtwRefPress_[regionIdx]);
273 Scalar muRef = pvtwViscosity_[regionIdx]/(1.0 + x + 0.5*x*x);
276 const auto& muWatvisct = watvisctCurves_[regionIdx].eval(temperature,
true);
277 return isothermalMu * muWatvisct/muRef;
283 template <
class Evaluation>
285 const Evaluation& temperature,
286 const Evaluation& pressure,
287 const Evaluation& saltconcentration)
const
292 Scalar BwRef = pvtwRefB_[regionIdx];
293 Scalar TRef = watdentRefTemp_[regionIdx];
294 const Evaluation& X = pvtwCompressibility_[regionIdx]*(pressure - pvtwRefPress_[regionIdx]);
295 Scalar cT1 = watdentCT1_[regionIdx];
296 Scalar cT2 = watdentCT2_[regionIdx];
297 const Evaluation& Y = temperature - TRef;
302 return 1.0/(((1 - X)*(1 + cT1*Y + cT2*Y*Y))*BwRef);
305 const IsothermalPvt* isoThermalPvt()
const
306 {
return isothermalPvt_; }
308 const Scalar waterReferenceDensity(
unsigned regionIdx)
const
311 const std::vector<Scalar>& viscrefPress()
const
312 {
return viscrefPress_; }
314 const std::vector<Scalar>& watdentRefTemp()
const
315 {
return watdentRefTemp_; }
317 const std::vector<Scalar>& watdentCT1()
const
318 {
return watdentCT1_; }
320 const std::vector<Scalar>& watdentCT2()
const
321 {
return watdentCT2_; }
323 const std::vector<Scalar>& pvtwRefPress()
const
324 {
return pvtwRefPress_; }
326 const std::vector<Scalar>& pvtwRefB()
const
327 {
return pvtwRefB_; }
329 const std::vector<Scalar>& pvtwCompressibility()
const
330 {
return pvtwCompressibility_; }
332 const std::vector<Scalar>& pvtwViscosity()
const
333 {
return pvtwViscosity_; }
335 const std::vector<Scalar>& pvtwViscosibility()
const
336 {
return pvtwViscosibility_; }
338 const std::vector<TabulatedOneDFunction>& watvisctCurves()
const
339 {
return watvisctCurves_; }
341 const std::vector<TabulatedOneDFunction> internalEnergyCurves()
const
342 {
return internalEnergyCurves_; }
344 bool enableInternalEnergy()
const
345 {
return enableInternalEnergy_; }
347 bool operator==(
const WaterPvtThermal<Scalar, enableBrine>& data)
const
349 if (isothermalPvt_ && !data.isothermalPvt_)
351 if (!isothermalPvt_ && data.isothermalPvt_)
354 return (!this->isoThermalPvt() ||
355 (*this->isoThermalPvt() == *data.isoThermalPvt())) &&
356 this->viscrefPress() == data.viscrefPress() &&
357 this->watdentRefTemp() == data.watdentRefTemp() &&
358 this->watdentCT1() == data.watdentCT1() &&
359 this->watdentCT2() == data.watdentCT2() &&
360 this->pvtwRefPress() == data.pvtwRefPress() &&
361 this->pvtwRefB() == data.pvtwRefB() &&
362 this->pvtwCompressibility() == data.pvtwCompressibility() &&
363 this->pvtwViscosity() == data.pvtwViscosity() &&
364 this->pvtwViscosibility() == data.pvtwViscosibility() &&
365 this->watvisctCurves() == data.watvisctCurves() &&
366 this->internalEnergyCurves() == data.internalEnergyCurves() &&
369 this->enableInternalEnergy() == data.enableInternalEnergy();
372 WaterPvtThermal<Scalar, enableBrine>& operator=(
const WaterPvtThermal<Scalar, enableBrine>& data)
374 if (data.isothermalPvt_)
375 isothermalPvt_ =
new IsothermalPvt(*data.isothermalPvt_);
377 isothermalPvt_ =
nullptr;
378 viscrefPress_ = data.viscrefPress_;
379 watdentRefTemp_ = data.watdentRefTemp_;
380 watdentCT1_ = data.watdentCT1_;
381 watdentCT2_ = data.watdentCT2_;
382 pvtwRefPress_ = data.pvtwRefPress_;
383 pvtwRefB_ = data.pvtwRefB_;
384 pvtwCompressibility_ = data.pvtwCompressibility_;
385 pvtwViscosity_ = data.pvtwViscosity_;
386 pvtwViscosibility_ = data.pvtwViscosibility_;
387 watvisctCurves_ = data.watvisctCurves_;
388 internalEnergyCurves_ = data.internalEnergyCurves_;
389 enableThermalDensity_ = data.enableThermalDensity_;
390 enableThermalViscosity_ = data.enableThermalViscosity_;
391 enableInternalEnergy_ = data.enableInternalEnergy_;
397 IsothermalPvt* isothermalPvt_;
401 std::vector<Scalar> viscrefPress_;
403 std::vector<Scalar> watdentRefTemp_;
404 std::vector<Scalar> watdentCT1_;
405 std::vector<Scalar> watdentCT2_;
407 std::vector<Scalar> pvtwRefPress_;
408 std::vector<Scalar> pvtwRefB_;
409 std::vector<Scalar> pvtwCompressibility_;
410 std::vector<Scalar> pvtwViscosity_;
411 std::vector<Scalar> pvtwViscosibility_;
413 std::vector<TabulatedOneDFunction> watvisctCurves_;
416 std::vector<TabulatedOneDFunction> internalEnergyCurves_;
418 bool enableThermalDensity_;
419 bool enableThermalViscosity_;
420 bool enableInternalEnergy_;
A central place for various physical constants occuring in some equations.
This file provides a wrapper around the "final" C++-2011 statement.
Class implementing cubic splines.
Implements a linearly interpolated scalar function that depends on one variable.
Implements a linearly interpolated scalar function that depends on one variable.
Definition: Tabulated1DFunction.hpp:47
This class represents the Pressure-Volume-Temperature relations of the water phase in the black-oil m...
Definition: WaterPvtMultiplexer.hpp:75
unsigned numRegions() const
Return the number of PVT regions which are considered by this PVT-object.
Definition: WaterPvtMultiplexer.hpp:141
const Scalar waterReferenceDensity(unsigned regionIdx)
Return the reference density which are considered by this PVT-object.
Definition: WaterPvtMultiplexer.hpp:147
Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &saltconcentration) const
Returns the formation volume factor [-] of the fluid phase.
Definition: WaterPvtMultiplexer.hpp:176
Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &saltconcentration) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition: WaterPvtMultiplexer.hpp:163
This class implements temperature dependence of the PVT properties of water.
Definition: WaterPvtThermal.hpp:55
Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &saltconcentration) const
Returns the formation volume factor [-] of the fluid phase.
Definition: WaterPvtThermal.hpp:284
bool enableThermalViscosity() const
Returns true iff the viscosity of the water phase is temperature dependent.
Definition: WaterPvtThermal.hpp:236
Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &saltconcentration) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition: WaterPvtThermal.hpp:263
Evaluation internalEnergy(unsigned regionIdx, const Evaluation &temperature, const Evaluation &) const
Returns the specific internal energy [J/kg] of water given a set of parameters.
Definition: WaterPvtThermal.hpp:246
void initEnd()
Finish initializing the thermal part of the water phase PVT properties.
Definition: WaterPvtThermal.hpp:224
bool enableThermalDensity() const
Returns true iff the density of the water phase is temperature dependent.
Definition: WaterPvtThermal.hpp:230
void setNumRegions(size_t numRegions)
Set the number of PVT-regions considered by this object.
Definition: WaterPvtThermal.hpp:206