ThermalOilPvtWrapper.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2015 Andreas Lauser
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 3 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 
20 #ifndef OPM_THERMAL_OIL_PVT_WRAPPER_HPP
21 #define OPM_THERMAL_OIL_PVT_WRAPPER_HPP
22 
24 #include <opm/common/ErrorMacros.hpp>
25 
26 #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
27 
28 #include <vector>
29 
30 namespace Opm
31 {
35  {
36  public:
38  {}
39 
40 
42  void initFromDeck(std::shared_ptr<const PvtInterface> isothermalPvt,
43  Opm::DeckConstPtr deck,
44  Opm::EclipseStateConstPtr eclipseState)
45  {
46  isothermalPvt_ = isothermalPvt;
47 
48  int numRegions;
49  auto tables = eclipseState->getTableManager();
50 
51  if (deck->hasKeyword("PVTO"))
52  numRegions = tables->getPvtoTables().size();
53  else if (deck->hasKeyword("PVDO"))
54  numRegions = tables->getPvdoTables().size();
55  else if (deck->hasKeyword("PVCDO"))
56  numRegions = deck->getKeyword("PVCDO")->size();
57  else
58  OPM_THROW(std::runtime_error, "Oil phase was not initialized using a known way");
59 
60  // viscosity
61  if (deck->hasKeyword("VISCREF")) {
62  oilvisctTables_ = &tables->getOilvisctTables();
63  Opm::DeckKeywordConstPtr viscrefKeyword = deck->getKeyword("VISCREF");
64 
65  assert(int(oilvisctTables_->size()) == numRegions);
66  assert(int(viscrefKeyword->size()) == numRegions);
67 
68  viscrefPress_.resize(numRegions);
69  viscrefRs_.resize(numRegions);
70  muRef_.resize(numRegions);
71  for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
72  DeckRecordConstPtr viscrefRecord = viscrefKeyword->getRecord(regionIdx);
73  viscrefPress_[regionIdx] = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
74  viscrefRs_[regionIdx] = viscrefRecord->getItem("REFERENCE_RS")->getSIDouble(0);
75 
76  // temperature used to calculate the reference viscosity [K]. the
77  // value does not really matter if the underlying PVT object really
78  // is isothermal...
79  double Tref = 273.15 + 20;
80 
81  // compute the reference viscosity using the isothermal PVT object.
82  double tmp1, tmp2;
83  isothermalPvt_->mu(1,
84  &regionIdx,
85  &viscrefPress_[regionIdx],
86  &Tref,
87  &viscrefRs_[regionIdx],
88  &muRef_[regionIdx],
89  &tmp1,
90  &tmp2);
91  }
92  }
93 
94  // quantities required for density. note that we just always use the values
95  // for the first EOS. (since EOS != PVT region.)
96  tref_ = 0.0;
97  if (deck->hasKeyword("THERMEX1")) {
98  oilCompIdx_ = deck->getKeyword("OCOMPIDX")->getRecord(0)->getItem("OIL_COMPONENT_INDEX")->getInt(0) - 1;
99 
100  // always use the values of the first EOS
101  tref_ = deck->getKeyword("TREF")->getRecord(0)->getItem("TEMPERATURE")->getSIDouble(oilCompIdx_);
102  pref_ = deck->getKeyword("PREF")->getRecord(0)->getItem("PRESSURE")->getSIDouble(oilCompIdx_);
103  cref_ = deck->getKeyword("CREF")->getRecord(0)->getItem("COMPRESSIBILITY")->getSIDouble(oilCompIdx_);
104  thermex1_ = deck->getKeyword("THERMEX1")->getRecord(0)->getItem("EXPANSION_COEFF")->getSIDouble(oilCompIdx_);
105  }
106  }
107 
108  virtual void mu(const int n,
109  const int* pvtRegionIdx,
110  const double* p,
111  const double* T,
112  const double* z,
113  double* output_mu) const
114  {
115  if (oilvisctTables_)
116  // TODO: temperature dependence for viscosity depending on z
117  OPM_THROW(std::runtime_error,
118  "temperature dependent viscosity as a function of z "
119  "is not yet implemented!");
120 
121  // compute the isothermal viscosity
122  isothermalPvt_->mu(n, pvtRegionIdx, p, T, z, output_mu);
123  }
124 
125  virtual void mu(const int n,
126  const int* pvtRegionIdx,
127  const double* p,
128  const double* T,
129  const double* r,
130  double* output_mu,
131  double* output_dmudp,
132  double* output_dmudr) const
133  {
134  // compute the isothermal viscosity and its derivatives
135  isothermalPvt_->mu(n, pvtRegionIdx, p, T, r, output_mu, output_dmudp, output_dmudr);
136 
137  if (!oilvisctTables_)
138  // isothermal case
139  return;
140 
141  // temperature dependence
142  for (int i = 0; i < n; ++i) {
143  int regionIdx = getPvtRegionIndex_(pvtRegionIdx, i);
144 
145  // calculate the viscosity of the isothermal keyword for the reference
146  // pressure given by the VISCREF keyword.
147  double muRef = muRef_[regionIdx];
148 
149  // compute the viscosity deviation due to temperature
150  double alpha;
151  {
152  const OilvisctTable& oilvisctTable = oilvisctTables_->getTable<OilvisctTable>(regionIdx);
153  double muOilvisct = oilvisctTable.evaluate("Viscosity", T[i]);
154  alpha = muOilvisct/muRef;
155  }
156 
157  output_mu[i] *= alpha;
158  output_dmudp[i] *= alpha;
159  output_dmudr[i] *= alpha;
160  // TODO (?): derivative of viscosity w.r.t. temperature.
161  }
162  }
163 
164  virtual void mu(const int n,
165  const int* pvtRegionIdx,
166  const double* p,
167  const double* T,
168  const double* r,
169  const PhasePresence* cond,
170  double* output_mu,
171  double* output_dmudp,
172  double* output_dmudr) const
173  {
174  // compute the isothermal viscosity and its derivatives
175  isothermalPvt_->mu(n, pvtRegionIdx, p, T, r, cond, output_mu, output_dmudp, output_dmudr);
176 
177  if (!oilvisctTables_)
178  // isothermal case
179  return;
180 
181  // temperature dependence
182  for (int i = 0; i < n; ++i) {
183  int regionIdx = getPvtRegionIndex_(pvtRegionIdx, i);
184 
185  // calculate the viscosity of the isothermal keyword for the reference
186  // pressure given by the VISCREF keyword.
187  double muRef = muRef_[regionIdx];
188 
189  // compute the viscosity deviation due to temperature
190  double alpha;
191  {
192  const OilvisctTable& oilvisctTable = oilvisctTables_->getTable<OilvisctTable>(regionIdx);
193  double muOilvisct = oilvisctTable.evaluate("Viscosity", T[i]);
194  alpha = muOilvisct/muRef;
195  }
196  output_mu[i] *= alpha;
197  output_dmudp[i] *= alpha;
198  output_dmudr[i] *= alpha;
199  // TODO (?): derivative of viscosity w.r.t. temperature.
200  }
201  }
202 
203  virtual void B(const int n,
204  const int* pvtRegionIdx,
205  const double* p,
206  const double* T,
207  const double* z,
208  double* output_B) const
209  {
210  // isothermal case
211  isothermalPvt_->B(n, pvtRegionIdx, p, T, z, output_B);
212 
213  if (thermex1_ <= 0.0)
214  // isothermal case
215  return;
216 
217  // deal with the temperature dependence of the oil phase. we use equation
218  // (3.208) from the Eclipse 2011.1 Reference Manual, but we calculate rho_ref
219  // using the isothermal keyword instead of using the value for the
220  // components, so the oil compressibility is already dealt with there. Note
221  // that we only do the part for the oil component here, the part for
222  // dissolved gas is ignored so far.
223  double cT1 = thermex1_;
224  double TRef = tref_;
225  for (int i = 0; i < n; ++i) {
226  double alpha = (1 + cT1*(T[i] - TRef));
227  output_B[i] *= alpha;
228  }
229  }
230 
231  virtual void dBdp(const int n,
232  const int* pvtRegionIdx,
233  const double* p,
234  const double* T,
235  const double* z,
236  double* output_B,
237  double* output_dBdp) const
238  {
239  isothermalPvt_->dBdp(n, pvtRegionIdx, p, T, z, output_B, output_dBdp);
240 
241  if (thermex1_ <= 0.0)
242  // isothermal case
243  return;
244 
245  // deal with the temperature dependence of the oil phase. we use equation
246  // (3.208) from the Eclipse 2011.1 Reference Manual, but we calculate rho_ref
247  // using the isothermal keyword instead of using the value for the
248  // components, so the oil compressibility is already dealt with there. Note
249  // that we only do the part for the oil component here, the part for
250  // dissolved gas is ignored so far.
251  double cT1 = thermex1_;
252  double TRef = tref_;
253  for (int i = 0; i < n; ++i) {
254  double alpha = (1 + cT1*(T[i] - TRef));
255  output_B[i] *= alpha;
256  output_dBdp[i] *= alpha;
257  }
258  }
259 
260  virtual void b(const int n,
261  const int* pvtRegionIdx,
262  const double* p,
263  const double* T,
264  const double* r,
265  double* output_b,
266  double* output_dbdp,
267  double* output_dbdr) const
268  {
269  isothermalPvt_->b(n, pvtRegionIdx, p, T, r, output_b, output_dbdp, output_dbdr);
270 
271  if (thermex1_ <= 0.0)
272  // isothermal case
273  return;
274 
275  // deal with the temperature dependence of the oil phase. we use equation
276  // (3.208) from the Eclipse 2011.1 Reference Manual, but we calculate rho_ref
277  // using the isothermal keyword instead of using the value for the
278  // components, so the oil compressibility is already dealt with there. Note
279  // that we only do the part for the oil component here, the part for
280  // dissolved gas is ignored so far.
281  double cT1 = thermex1_;
282  double TRef = tref_;
283  for (int i = 0; i < n; ++i) {
284  double alpha = 1.0/(1 + cT1*(T[i] - TRef));
285  output_b[i] *= alpha;
286  output_dbdp[i] *= alpha;
287  output_dbdr[i] *= alpha;
288  }
289  }
290 
291  virtual void b(const int n,
292  const int* pvtRegionIdx,
293  const double* p,
294  const double* T,
295  const double* r,
296  const PhasePresence* cond,
297  double* output_b,
298  double* output_dbdp,
299  double* output_dbdr) const
300  {
301  isothermalPvt_->b(n, pvtRegionIdx, p, T, r, cond, output_b, output_dbdp, output_dbdr);
302 
303  if (thermex1_ <= 0.0)
304  // isothermal case
305  return;
306 
307  // deal with the temperature dependence of the oil phase. we use equation
308  // (3.208) from the Eclipse 2011.1 Reference Manual, but we calculate rho_ref
309  // using the isothermal keyword instead of using the value for the
310  // components, so the oil compressibility is already dealt with there. Note
311  // that we only do the part for the oil component here, the part for
312  // dissolved gas is ignored so far.
313  double cT1 = thermex1_;
314  double TRef = tref_;
315  for (int i = 0; i < n; ++i) {
316  double alpha = 1.0/(1 + cT1*(T[i] - TRef));
317  output_b[i] *= alpha;
318  output_dbdp[i] *= alpha;
319  output_dbdr[i] *= alpha;
320  }
321  }
322 
323  virtual void rsSat(const int n,
324  const int* pvtRegionIdx,
325  const double* p,
326  double* output_rsSat,
327  double* output_drsSatdp) const
328  {
329  isothermalPvt_->rsSat(n, pvtRegionIdx, p, output_rsSat, output_drsSatdp);
330  }
331 
332  virtual void rvSat(const int n,
333  const int* pvtRegionIdx,
334  const double* p,
335  double* output_rvSat,
336  double* output_drvSatdp) const
337  {
338  isothermalPvt_->rvSat(n, pvtRegionIdx, p, output_rvSat, output_drvSatdp);
339  }
340 
341  virtual void R(const int n,
342  const int* pvtRegionIdx,
343  const double* p,
344  const double* z,
345  double* output_R) const
346  {
347  isothermalPvt_->R(n, pvtRegionIdx, p, z, output_R);
348  }
349 
350  virtual void dRdp(const int n,
351  const int* pvtRegionIdx,
352  const double* p,
353  const double* z,
354  double* output_R,
355  double* output_dRdp) const
356  {
357  isothermalPvt_->dRdp(n, pvtRegionIdx, p, z, output_R, output_dRdp);
358  }
359 
360  private:
361  int getPvtRegionIndex_(const int* pvtRegionIdx, int cellIdx) const
362  {
363  if (!pvtRegionIdx)
364  return 0;
365  return pvtRegionIdx[cellIdx];
366  }
367 
368  // the PVT propertied for the isothermal case
369  std::shared_ptr<const PvtInterface> isothermalPvt_;
370 
371  // The PVT properties needed for temperature dependence of the viscosity. We need
372  // to store one value per PVT region.
373  std::vector<double> viscrefPress_;
374  std::vector<double> viscrefRs_;
375  std::vector<double> muRef_;
376 
377  const TableContainer* oilvisctTables_;
378 
379  // The PVT properties needed for temperature dependence of the density. This is
380  // specified as one value per EOS in the manual, but we unconditionally use the
381  // expansion coefficient of the first EOS...
382  int oilCompIdx_;
383  double tref_;
384  double pref_;
385  double cref_;
386  double thermex1_;
387  };
388 
389 }
390 
391 #endif
392 
Definition: BlackoilPhases.hpp:48
virtual void mu(const int n, const int *pvtRegionIdx, const double *p, const double *T, const double *r, double *output_mu, double *output_dmudp, double *output_dmudr) const
Definition: ThermalOilPvtWrapper.hpp:125
Definition: AnisotropicEikonal.hpp:43
virtual void b(const int n, const int *pvtRegionIdx, const double *p, const double *T, const double *r, const PhasePresence *cond, double *output_b, double *output_dbdp, double *output_dbdr) const
Definition: ThermalOilPvtWrapper.hpp:291
ThermalOilPvtWrapper()
Definition: ThermalOilPvtWrapper.hpp:37
Definition: ThermalOilPvtWrapper.hpp:34
virtual void R(const int n, const int *pvtRegionIdx, const double *p, const double *z, double *output_R) const
Solution factor as a function of p and z.
Definition: ThermalOilPvtWrapper.hpp:341
virtual void dRdp(const int n, const int *pvtRegionIdx, const double *p, const double *z, double *output_R, double *output_dRdp) const
Solution factor and p-derivative as functions of p and z.
Definition: ThermalOilPvtWrapper.hpp:350
virtual void rsSat(const int n, const int *pvtRegionIdx, const double *p, double *output_rsSat, double *output_drsSatdp) const
Solution gas/oil ratio and its derivatives at saturated conditions as a function of p...
Definition: ThermalOilPvtWrapper.hpp:323
virtual void b(const int n, const int *pvtRegionIdx, const double *p, const double *T, const double *r, double *output_b, double *output_dbdp, double *output_dbdr) const
Definition: ThermalOilPvtWrapper.hpp:260
void initFromDeck(std::shared_ptr< const PvtInterface > isothermalPvt, Opm::DeckConstPtr deck, Opm::EclipseStateConstPtr eclipseState)
set the tables which specify the temperature dependence of the oil viscosity
Definition: ThermalOilPvtWrapper.hpp:42
virtual void dBdp(const int n, const int *pvtRegionIdx, const double *p, const double *T, const double *z, double *output_B, double *output_dBdp) const
Formation volume factor and p-derivative as functions of p and z.
Definition: ThermalOilPvtWrapper.hpp:231
virtual void mu(const int n, const int *pvtRegionIdx, const double *p, const double *T, const double *z, double *output_mu) const
Viscosity as a function of p, T and z.
Definition: ThermalOilPvtWrapper.hpp:108
virtual void B(const int n, const int *pvtRegionIdx, const double *p, const double *T, const double *z, double *output_B) const
Formation volume factor as a function of p, T and z.
Definition: ThermalOilPvtWrapper.hpp:203
Definition: PvtInterface.hpp:30
virtual void mu(const int n, const int *pvtRegionIdx, const double *p, const double *T, const double *r, const PhasePresence *cond, double *output_mu, double *output_dmudp, double *output_dmudr) const
Definition: ThermalOilPvtWrapper.hpp:164
virtual void rvSat(const int n, const int *pvtRegionIdx, const double *p, double *output_rvSat, double *output_drvSatdp) const
Vapor oil/gas ratio and its derivatives at saturated conditions as a function of p.
Definition: ThermalOilPvtWrapper.hpp:332