Files
opm-core/opm/core/fluid/blackoil/BlackoilPVT.cpp
T

203 lines
7.1 KiB
C++

/*
Copyright 2010 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <opm/core/fluid/blackoil/BlackoilPVT.hpp>
#include <opm/core/fluid/blackoil/MiscibilityDead.hpp>
#include <opm/core/fluid/blackoil/MiscibilityLiveOil.hpp>
#include <opm/core/fluid/blackoil/MiscibilityLiveGas.hpp>
#include <opm/core/fluid/blackoil/MiscibilityWater.hpp>
#include <opm/core/eclipse/EclipseGridParser.hpp>
#include <opm/core/utility/Units.hpp>
#include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/linInt.hpp>
using namespace Opm;
namespace Opm
{
void BlackoilPVT::init(const EclipseGridParser& parser)
{
typedef std::vector<std::vector<std::vector<double> > > table_t;
region_number_ = 0;
// Surface densities. Accounting for different orders in eclipse and our code.
if (parser.hasField("DENSITY")) {
const int region_number = 0;
enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 };
const std::vector<double>& d = parser.getDENSITY().densities_[region_number];
densities_[Aqua] = d[ECL_water];
densities_[Vapour] = d[ECL_gas];
densities_[Liquid] = d[ECL_oil];
} else {
THROW("Input is missing DENSITY\n");
}
// Water PVT
if (parser.hasField("PVTW")) {
water_props_.reset(new MiscibilityWater(parser.getPVTW().pvtw_));
} else {
water_props_.reset(new MiscibilityWater(0.5*Opm::prefix::centi*Opm::unit::Poise)); // Eclipse 100 default
}
// Oil PVT
if (parser.hasField("PVDO")) {
oil_props_.reset(new MiscibilityDead(parser.getPVDO().pvdo_));
} else if (parser.hasField("PVTO")) {
oil_props_.reset(new MiscibilityLiveOil(parser.getPVTO().pvto_));
} else if (parser.hasField("PVCDO")) {
oil_props_.reset(new MiscibilityWater(parser.getPVCDO().pvcdo_));
} else {
THROW("Input is missing PVDO and PVTO\n");
}
// Gas PVT
if (parser.hasField("PVDG")) {
gas_props_.reset(new MiscibilityDead(parser.getPVDG().pvdg_));
} else if (parser.hasField("PVTG")) {
gas_props_.reset(new MiscibilityLiveGas(parser.getPVTG().pvtg_));
} else {
THROW("Input is missing PVDG and PVTG\n");
}
}
BlackoilPVT::CompVec BlackoilPVT::surfaceDensities() const
{
return densities_;
}
double BlackoilPVT::getViscosity(double press, const CompVec& surfvol, PhaseIndex phase) const
{
return propsForPhase(phase).getViscosity(region_number_, press, surfvol);
}
double BlackoilPVT::B(double press, const CompVec& surfvol, PhaseIndex phase) const
{
return propsForPhase(phase).B(region_number_, press, surfvol);
}
double BlackoilPVT::dBdp(double press, const CompVec& surfvol, PhaseIndex phase) const
{
return propsForPhase(phase).dBdp(region_number_, press, surfvol);
}
double BlackoilPVT::R(double press, const CompVec& surfvol, PhaseIndex phase) const
{
return propsForPhase(phase).R(region_number_, press, surfvol);
}
double BlackoilPVT::dRdp(double press, const CompVec& surfvol, PhaseIndex phase) const
{
return propsForPhase(phase).dRdp(region_number_, press, surfvol);
}
const MiscibilityProps& BlackoilPVT::propsForPhase(PhaseIndex phase) const
{
switch (phase) {
case Aqua:
return *water_props_;
case Liquid:
return *oil_props_;
case Vapour:
return *gas_props_;
default:
THROW("Unknown phase accessed: " << phase);
}
}
void BlackoilPVT::getViscosity(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
std::vector<PhaseVec>& output) const
{
int num = pressures.size();
output.resize(num);
for (int phase = 0; phase < numPhases; ++phase) {
propsForPhase(PhaseIndex(phase)).getViscosity(pressures, surfvol, phase, data1_);
for (int i = 0; i < num; ++i) {
output[i][phase] = data1_[i];
}
}
}
void BlackoilPVT::B(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
std::vector<PhaseVec>& output) const
{
int num = pressures.size();
output.resize(num);
for (int phase = 0; phase < numPhases; ++phase) {
propsForPhase(PhaseIndex(phase)).B(pressures, surfvol, phase, data1_);
for (int i = 0; i < num; ++i) {
output[i][phase] = data1_[i];
}
}
}
void BlackoilPVT::dBdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
std::vector<PhaseVec>& output_B,
std::vector<PhaseVec>& output_dBdp) const
{
int num = pressures.size();
output_B.resize(num);
output_dBdp.resize(num);
for (int phase = 0; phase < numPhases; ++phase) {
propsForPhase(PhaseIndex(phase)).dBdp(pressures, surfvol, phase, data1_, data2_);
for (int i = 0; i < num; ++i) {
output_B[i][phase] = data1_[i];
output_dBdp[i][phase] = data2_[i];
}
}
}
void BlackoilPVT::R(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
std::vector<PhaseVec>& output) const
{
int num = pressures.size();
output.resize(num);
for (int phase = 0; phase < numPhases; ++phase) {
propsForPhase(PhaseIndex(phase)).R(pressures, surfvol, phase, data1_);
for (int i = 0; i < num; ++i) {
output[i][phase] = data1_[i];
}
}
}
void BlackoilPVT::dRdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
std::vector<PhaseVec>& output_R,
std::vector<PhaseVec>& output_dRdp) const
{
int num = pressures.size();
output_R.resize(num);
output_dRdp.resize(num);
for (int phase = 0; phase < numPhases; ++phase) {
propsForPhase(PhaseIndex(phase)).dRdp(pressures, surfvol, phase, data1_, data2_);
for (int i = 0; i < num; ++i) {
output_R[i][phase] = data1_[i];
output_dRdp[i][phase] = data2_[i];
}
}
}
} // namespace Opm