PVT classes: implement temperature dependent viscosity

this is implemented such that if the simulation is unchanged,
viscosities are assumed to be not temperature dependent. (only if
pvtObject->set{Oil,Wat}visctTables() is called, temperature dependence
is considered.)
This commit is contained in:
Andreas Lauser 2015-01-29 12:24:17 +01:00
parent 034961c8ba
commit c4ca344026
8 changed files with 251 additions and 12 deletions

View File

@ -23,6 +23,8 @@
#include <opm/core/props/pvt/PvtInterface.hpp> #include <opm/core/props/pvt/PvtInterface.hpp>
#include <opm/core/utility/ErrorMacros.hpp> #include <opm/core/utility/ErrorMacros.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@ -98,7 +100,9 @@ namespace Opm
ref_B_(1, 1.0), ref_B_(1, 1.0),
comp_(1, 0.0), comp_(1, 0.0),
viscosity_(1, visc), viscosity_(1, visc),
visc_comp_(1, 0.0) visc_comp_(1, 0.0),
oilvisctTables_(0),
watvisctTables_(0)
{ {
} }
@ -119,6 +123,13 @@ namespace Opm
int tableIdx = getTableIndex_(pvtRegionIdx, i); int tableIdx = getTableIndex_(pvtRegionIdx, i);
double x = -visc_comp_[tableIdx]*(p[i] - ref_press_[tableIdx]); double x = -visc_comp_[tableIdx]*(p[i] - ref_press_[tableIdx]);
output_mu[i] = viscosity_[tableIdx]/(1.0 + x + 0.5*x*x); output_mu[i] = viscosity_[tableIdx]/(1.0 + x + 0.5*x*x);
if (oilvisctTables_ != 0 || watvisctTables_ != 0) {
// TODO: temperature dependence
OPM_THROW(std::logic_error,
"temperature dependent viscosity as a function of z "
"is not yet implemented!");
}
} }
} }
@ -146,7 +157,7 @@ namespace Opm
virtual void mu(const int n, virtual void mu(const int n,
const int* pvtRegionIdx, const int* pvtRegionIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* /*r*/, const double* /*r*/,
const PhasePresence* /*cond*/, const PhasePresence* /*cond*/,
double* output_mu, double* output_mu,
@ -161,6 +172,46 @@ namespace Opm
double d = (1.0 + x + 0.5*x*x); double d = (1.0 + x + 0.5*x*x);
output_mu[i] = viscosity_[tableIdx]/d; output_mu[i] = viscosity_[tableIdx]/d;
output_dmudp[i] = (viscosity_[tableIdx]/(d*d))*(1+x) * visc_comp_[tableIdx]; output_dmudp[i] = (viscosity_[tableIdx]/(d*d))*(1+x) * visc_comp_[tableIdx];
if (oilvisctTables_ != 0) {
// this object handles _either_ oil _or_ water
assert(watvisctTables_ == 0);
// temperature dependence of the oil phase
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(tableIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double muRef = -visc_comp_[tableIdx]*(pRef - ref_press_[tableIdx]);
double muOilvisct = (*oilvisctTables_)[tableIdx].evaluate("Viscosity", T[i]);
double alpha = muOilvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
if (watvisctTables_ != 0) {
// this object handles _either_ oil _or_ water
assert(oilvisctTables_ == 0);
// temperature dependence of the water phase
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(tableIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double muRef = -visc_comp_[tableIdx]*(pRef - ref_press_[tableIdx]);
double muWatvisct = (*watvisctTables_)[tableIdx].evaluate("Viscosity", T[i]);
double alpha = muWatvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
} }
std::fill(output_dmudr, output_dmudr + n, 0.0); std::fill(output_dmudr, output_dmudr + n, 0.0);
} }
@ -287,6 +338,22 @@ namespace Opm
std::fill(output_dRdp, output_dRdp + n, 0.0); std::fill(output_dRdp, output_dRdp + n, 0.0);
} }
/// set the tables which specify the temperature dependence of the oil viscosity
void setOilvisctTables(const std::vector<Opm::OilvisctTable>& oilvisctTables,
DeckKeywordConstPtr viscrefKeyword)
{
oilvisctTables_ = &oilvisctTables;
viscrefKeyword_ = viscrefKeyword;
}
/// set the tables which specify the temperature dependence of the water viscosity
void setWatvisctTables(const std::vector<Opm::WatvisctTable>& watvisctTables,
DeckKeywordConstPtr viscrefKeyword)
{
watvisctTables_ = &watvisctTables;
viscrefKeyword_ = viscrefKeyword;
}
private: private:
int getTableIndex_(const int* pvtTableIdx, int cellIdx) const int getTableIndex_(const int* pvtTableIdx, int cellIdx) const
{ {
@ -302,6 +369,10 @@ namespace Opm
std::vector<double> comp_; std::vector<double> comp_;
std::vector<double> viscosity_; std::vector<double> viscosity_;
std::vector<double> visc_comp_; std::vector<double> visc_comp_;
const std::vector<Opm::OilvisctTable>* oilvisctTables_;
const std::vector<Opm::WatvisctTable>* watvisctTables_;
DeckKeywordConstPtr viscrefKeyword_;
}; };
} }

View File

@ -123,13 +123,20 @@ namespace Opm
double tempInvB = b_[regionIdx](p[i]); double tempInvB = b_[regionIdx](p[i]);
double tempInvBmu = inverseBmu_[regionIdx](p[i]); double tempInvBmu = inverseBmu_[regionIdx](p[i]);
output_mu[i] = tempInvB / tempInvBmu; output_mu[i] = tempInvB / tempInvBmu;
if (oilvisctTables_ != 0) {
// TODO: temperature dependence
OPM_THROW(std::logic_error,
"temperature dependent viscosity as a function of z "
"is not yet implemented!");
}
} }
} }
void PvtDead::mu(const int n, void PvtDead::mu(const int n,
const int* pvtTableIdx, const int* pvtTableIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* /*r*/, const double* /*r*/,
double* output_mu, double* output_mu,
double* output_dmudp, double* output_dmudp,
@ -143,6 +150,24 @@ namespace Opm
output_mu[i] = tempInvB / tempInvBmu; output_mu[i] = tempInvB / tempInvBmu;
output_dmudp[i] = (tempInvBmu * b_[regionIdx].derivative(p[i]) output_dmudp[i] = (tempInvBmu * b_[regionIdx].derivative(p[i])
- tempInvB * inverseBmu_[regionIdx].derivative(p[i])) / (tempInvBmu * tempInvBmu); - tempInvB * inverseBmu_[regionIdx].derivative(p[i])) / (tempInvBmu * tempInvBmu);
if (oilvisctTables_ != 0) {
// temperature dependence of the oil phase
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(regionIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double muRef = b_[regionIdx](pRef)/inverseBmu_[regionIdx](pRef);
double muOilvisct = (*oilvisctTables_)[regionIdx].evaluate("Viscosity", T[i]);
double alpha = muOilvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
} }
std::fill(output_dmudr, output_dmudr + n, 0.0); std::fill(output_dmudr, output_dmudr + n, 0.0);
@ -151,7 +176,7 @@ namespace Opm
void PvtDead::mu(const int n, void PvtDead::mu(const int n,
const int* pvtTableIdx, const int* pvtTableIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* /*r*/, const double* /*r*/,
const PhasePresence* /*cond*/, const PhasePresence* /*cond*/,
double* output_mu, double* output_mu,
@ -167,6 +192,23 @@ namespace Opm
output_dmudp[i] = (tempInvBmu * b_[regionIdx].derivative(p[i]) output_dmudp[i] = (tempInvBmu * b_[regionIdx].derivative(p[i])
- tempInvB * inverseBmu_[regionIdx].derivative(p[i])) - tempInvB * inverseBmu_[regionIdx].derivative(p[i]))
/ (tempInvBmu * tempInvBmu); / (tempInvBmu * tempInvBmu);
if (oilvisctTables_ != 0) {
// temperature dependence of the oil phase
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(regionIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double muRef = b_[regionIdx](pRef)/inverseBmu_[regionIdx](pRef);
double muOilvisct = (*oilvisctTables_)[regionIdx].evaluate("Viscosity", T[i]);
double alpha = muOilvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
} }
std::fill(output_dmudr, output_dmudr + n, 0.0); std::fill(output_dmudr, output_dmudr + n, 0.0);

View File

@ -44,7 +44,11 @@ namespace Opm
class PvtDead : public PvtInterface class PvtDead : public PvtInterface
{ {
public: public:
PvtDead() {}; PvtDead()
{
// by default, specify no temperature dependence of the PVT properties
oilvisctTables_ = 0;
}
void initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables); void initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables);
void initFromGas(const std::vector<Opm::PvdgTable>& pvdgTables); void initFromGas(const std::vector<Opm::PvdgTable>& pvdgTables);
@ -150,6 +154,15 @@ namespace Opm
const double* z, const double* z,
double* output_R, double* output_R,
double* output_dRdp) const; double* output_dRdp) const;
/// set the tables which specify the temperature dependence of the oil viscosity
void setOilvisctTables(const std::vector<Opm::OilvisctTable>& oilvisctTables,
DeckKeywordConstPtr viscrefKeyword)
{
oilvisctTables_ = &oilvisctTables;
viscrefKeyword_ = viscrefKeyword;
}
private: private:
int getTableIndex_(const int* pvtTableIdx, int cellIdx) const int getTableIndex_(const int* pvtTableIdx, int cellIdx) const
{ {
@ -163,6 +176,9 @@ namespace Opm
std::vector<NonuniformTableLinear<double> > b_; std::vector<NonuniformTableLinear<double> > b_;
std::vector<NonuniformTableLinear<double> > viscosity_; std::vector<NonuniformTableLinear<double> > viscosity_;
std::vector<NonuniformTableLinear<double> > inverseBmu_; std::vector<NonuniformTableLinear<double> > inverseBmu_;
const std::vector<Opm::OilvisctTable>* oilvisctTables_;
DeckKeywordConstPtr viscrefKeyword_;
}; };
} }

View File

@ -36,7 +36,10 @@ namespace Opm
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PvtDeadSpline::PvtDeadSpline() PvtDeadSpline::PvtDeadSpline()
{} {
// by default, specify no temperature dependence of the PVT properties
oilvisctTables_ = 0;
}
void PvtDeadSpline::initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables, void PvtDeadSpline::initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables,
int numSamples) int numSamples)
@ -120,7 +123,7 @@ namespace Opm
void PvtDeadSpline::mu(const int n, void PvtDeadSpline::mu(const int n,
const int* pvtTableIdx, const int* pvtTableIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* /*r*/, const double* /*r*/,
double* output_mu, double* output_mu,
double* output_dmudp, double* output_dmudp,
@ -131,6 +134,23 @@ namespace Opm
int regionIdx = getTableIndex_(pvtTableIdx, i); int regionIdx = getTableIndex_(pvtTableIdx, i);
output_mu[i] = viscosity_[regionIdx](p[i]); output_mu[i] = viscosity_[regionIdx](p[i]);
output_dmudp[i] = viscosity_[regionIdx].derivative(p[i]); output_dmudp[i] = viscosity_[regionIdx].derivative(p[i]);
if (oilvisctTables_ != 0) {
// temperature dependence of the oil phase
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(regionIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double muRef = viscosity_[regionIdx](pRef);
double muOilvisct = (*oilvisctTables_)[regionIdx].evaluate("Viscosity", T[i]);
double alpha = muOilvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
} }
std::fill(output_dmudr, output_dmudr + n, 0.0); std::fill(output_dmudr, output_dmudr + n, 0.0);
} }
@ -138,7 +158,7 @@ namespace Opm
void PvtDeadSpline::mu(const int n, void PvtDeadSpline::mu(const int n,
const int* pvtTableIdx, const int* pvtTableIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* /*r*/, const double* /*r*/,
const PhasePresence* /*cond*/, const PhasePresence* /*cond*/,
double* output_mu, double* output_mu,
@ -151,6 +171,23 @@ namespace Opm
int regionIdx = getTableIndex_(pvtTableIdx, i); int regionIdx = getTableIndex_(pvtTableIdx, i);
output_mu[i] = viscosity_[regionIdx](p[i]); output_mu[i] = viscosity_[regionIdx](p[i]);
output_dmudp[i] = viscosity_[regionIdx].derivative(p[i]); output_dmudp[i] = viscosity_[regionIdx].derivative(p[i]);
if (oilvisctTables_ != 0) {
// temperature dependence of the oil phase
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(regionIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double muRef = viscosity_[regionIdx](pRef);
double muOilvisct = (*oilvisctTables_)[regionIdx].evaluate("Viscosity", T[i]);
double alpha = muOilvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
} }
std::fill(output_dmudr, output_dmudr + n, 0.0); std::fill(output_dmudr, output_dmudr + n, 0.0);
} }

View File

@ -148,6 +148,15 @@ namespace Opm
const double* z, const double* z,
double* output_R, double* output_R,
double* output_dRdp) const; double* output_dRdp) const;
/// set the tables which specify the temperature dependence of the oil viscosity
void setOilvisctTables(const std::vector<Opm::OilvisctTable>& oilvisctTables,
DeckKeywordConstPtr viscrefKeyword)
{
oilvisctTables_ = &oilvisctTables;
viscrefKeyword_ = viscrefKeyword;
}
private: private:
int getTableIndex_(const int* pvtTableIdx, int cellIdx) const int getTableIndex_(const int* pvtTableIdx, int cellIdx) const
{ {
@ -160,6 +169,9 @@ namespace Opm
// table per PVT region. // table per PVT region.
std::vector<UniformTableLinear<double> > b_; std::vector<UniformTableLinear<double> > b_;
std::vector<UniformTableLinear<double> > viscosity_; std::vector<UniformTableLinear<double> > viscosity_;
const std::vector<Opm::OilvisctTable>* oilvisctTables_;
DeckKeywordConstPtr viscrefKeyword_;
}; };
} }

View File

@ -114,6 +114,9 @@ namespace Opm
double inverseBMu = miscible_gas(p[i], z + num_phases_*i, getTableIndex_(pvtRegionIdx, i), 3, false); double inverseBMu = miscible_gas(p[i], z + num_phases_*i, getTableIndex_(pvtRegionIdx, i), 3, false);
output_mu[i] = inverseB / inverseBMu; output_mu[i] = inverseB / inverseBMu;
// temperature dependence: Since E100 does not implement temperature
// dependence of gas viscosity, we skip it here as well...
} }
} }
@ -162,6 +165,8 @@ namespace Opm
output_dmudr[i] = (inverseBMu * dinverseBdr - inverseB * dinverseBmudr) output_dmudr[i] = (inverseBMu * dinverseBdr - inverseB * dinverseBmudr)
/ (inverseBMu * inverseBMu); / (inverseBMu * inverseBMu);
// temperature dependence: Since E100 does not implement temperature
// dependence of gas viscosity, we skip it here as well...
} }
} }

View File

@ -36,6 +36,9 @@ namespace Opm
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PvtLiveOil::PvtLiveOil(const std::vector<Opm::PvtoTable>& pvtoTables) PvtLiveOil::PvtLiveOil(const std::vector<Opm::PvtoTable>& pvtoTables)
{ {
// by default, specify no temperature dependence of the PVT properties
oilvisctTables_ = 0;
int numTables = pvtoTables.size(); int numTables = pvtoTables.size();
saturated_oil_table_.resize(numTables); saturated_oil_table_.resize(numTables);
undersat_oil_tables_.resize(numTables); undersat_oil_tables_.resize(numTables);
@ -136,7 +139,7 @@ namespace Opm
void PvtLiveOil::mu(const int n, void PvtLiveOil::mu(const int n,
const int* pvtTableIdx, const int* pvtTableIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* z, const double* z,
double* output_mu) const double* output_mu) const
{ {
@ -149,13 +152,20 @@ namespace Opm
output_mu[i] = inverseB / inverseBMu; output_mu[i] = inverseB / inverseBMu;
} }
if (oilvisctTables_ != 0) {
// TODO: temperature dependence
OPM_THROW(std::logic_error,
"temperature dependent viscosity as a function of z "
"is not yet implemented!");
}
} }
/// Viscosity and its p and r derivatives as a function of p, T and r. /// Viscosity and its p and r derivatives as a function of p, T and r.
void PvtLiveOil::mu(const int n, void PvtLiveOil::mu(const int n,
const int* pvtTableIdx, const int* pvtTableIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* r, const double* r,
double* output_mu, double* output_mu,
double* output_dmudp, double* output_dmudp,
@ -183,14 +193,32 @@ namespace Opm
output_dmudr[i] = (inverseBMu * dinverseBdr - inverseB * dinverseBmudr) output_dmudr[i] = (inverseBMu * dinverseBdr - inverseB * dinverseBmudr)
/ (inverseBMu * inverseBMu); / (inverseBMu * inverseBMu);
if (oilvisctTables_ != 0) {
// temperature dependence
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(tableIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double rsRef = viscrefRecord->getItem("REFERENCE_RS")->getSIDouble(0);
double muRef = miscible_oil(pRef, rsRef, tableIdx, 3, 0)/miscible_oil(pRef, rsRef, tableIdx, 1, 0);
double muOilvisct = (*oilvisctTables_)[tableIdx].evaluate("Viscosity", T[i]);
double alpha = muOilvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
} }
} }
/// Viscosity and its p and r derivatives as a function of p, T and r. /// Viscosity and its p and r derivatives as a function of p, T and r.
void PvtLiveOil::mu(const int n, void PvtLiveOil::mu(const int n,
const int* pvtTableIdx, const int* pvtTableIdx,
const double* p, const double* p,
const double* /*T*/, const double* T,
const double* r, const double* r,
const PhasePresence* cond, const PhasePresence* cond,
double* output_mu, double* output_mu,
@ -220,6 +248,24 @@ namespace Opm
output_dmudr[i] = (inverseBMu * dinverseBdr - inverseB * dinverseBmudr) output_dmudr[i] = (inverseBMu * dinverseBdr - inverseB * dinverseBmudr)
/ (inverseBMu * inverseBMu); / (inverseBMu * inverseBMu);
if (oilvisctTables_ != 0) {
// temperature dependence
DeckRecordConstPtr viscrefRecord = viscrefKeyword_->getRecord(tableIdx);
double pRef = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0);
double rsRef = viscrefRecord->getItem("REFERENCE_RS")->getSIDouble(0);
double muRef = miscible_oil(pRef, rsRef, tableIdx, 3, 0)/miscible_oil(pRef, rsRef, tableIdx, 1, 0);
double muOilvisct = (*oilvisctTables_)[tableIdx].evaluate("Viscosity", T[i]);
double alpha = muOilvisct/muRef;
output_mu[i] *= alpha;
output_dmudp[i] *= alpha;
output_dmudr[i] *= alpha;
// TODO (?): derivative of oil viscosity w.r.t. temperature.
// probably requires a healthy portion of if-spaghetti
}
} }
} }
@ -645,5 +691,4 @@ namespace Opm
} }
} }
} }
} // namespace Opm } // namespace Opm

View File

@ -142,6 +142,14 @@ namespace Opm
double* output_R, double* output_R,
double* output_dRdp) const; double* output_dRdp) const;
/// set the tables which specify the temperature dependence of the oil viscosity
void setOilvisctTables(const std::vector<Opm::OilvisctTable>& oilvisctTables,
DeckKeywordConstPtr viscrefKeyword)
{
oilvisctTables_ = &oilvisctTables;
viscrefKeyword_ = viscrefKeyword;
}
private: private:
int getTableIndex_(const int* pvtTableIdx, int cellIdx) const int getTableIndex_(const int* pvtTableIdx, int cellIdx) const
{ {
@ -179,6 +187,9 @@ namespace Opm
// store one table per PVT region. // store one table per PVT region.
std::vector<std::vector<std::vector<double> > > saturated_oil_table_; std::vector<std::vector<std::vector<double> > > saturated_oil_table_;
std::vector<std::vector<std::vector<std::vector<double> > > > undersat_oil_tables_; std::vector<std::vector<std::vector<std::vector<double> > > > undersat_oil_tables_;
const std::vector<Opm::OilvisctTable>* oilvisctTables_;
DeckKeywordConstPtr viscrefKeyword_;
}; };
} }