Made all the SinglePvt* classes conform to new, more bare-bones interface.

This commit is contained in:
Atgeirr Flø Rasmussen
2012-01-04 22:15:26 +01:00
parent f8ad8b8bf0
commit 0ba5699d0a
11 changed files with 599 additions and 712 deletions

View File

@@ -22,6 +22,10 @@ opm/core/fluid/blackoil/MiscibilityDead.cpp \
opm/core/fluid/blackoil/MiscibilityLiveGas.cpp \ opm/core/fluid/blackoil/MiscibilityLiveGas.cpp \
opm/core/fluid/blackoil/MiscibilityLiveOil.cpp \ opm/core/fluid/blackoil/MiscibilityLiveOil.cpp \
opm/core/fluid/blackoil/MiscibilityProps.cpp \ opm/core/fluid/blackoil/MiscibilityProps.cpp \
opm/core/fluid/blackoil/SinglePvtDead.cpp \
opm/core/fluid/blackoil/SinglePvtLiveGas.cpp \
opm/core/fluid/blackoil/SinglePvtLiveOil.cpp \
opm/core/fluid/blackoil/SinglePvtInterface.cpp \
opm/core/fluid/BlackoilPropertiesFromDeck.cpp \ opm/core/fluid/BlackoilPropertiesFromDeck.cpp \
opm/core/utility/MonotCubicInterpolator.cpp \ opm/core/utility/MonotCubicInterpolator.cpp \
opm/core/utility/parameters/Parameter.cpp \ opm/core/utility/parameters/Parameter.cpp \
@@ -82,6 +86,7 @@ opm/core/fluid/BlackoilPropertiesFromDeck.hpp \
opm/core/fluid/RockFromDeck.hpp \ opm/core/fluid/RockFromDeck.hpp \
opm/core/fluid/SimpleFluid2p.hpp \ opm/core/fluid/SimpleFluid2p.hpp \
opm/core/fluid/blackoil/BlackoilDefs.hpp \ opm/core/fluid/blackoil/BlackoilDefs.hpp \
opm/core/fluid/blackoil/BlackoilPhases.hpp \
opm/core/fluid/blackoil/BlackoilPVT.hpp \ opm/core/fluid/blackoil/BlackoilPVT.hpp \
opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp \ opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp \
opm/core/fluid/blackoil/FluidStateBlackoil.hpp \ opm/core/fluid/blackoil/FluidStateBlackoil.hpp \
@@ -90,6 +95,11 @@ opm/core/fluid/blackoil/MiscibilityLiveGas.hpp \
opm/core/fluid/blackoil/MiscibilityLiveOil.hpp \ opm/core/fluid/blackoil/MiscibilityLiveOil.hpp \
opm/core/fluid/blackoil/MiscibilityProps.hpp \ opm/core/fluid/blackoil/MiscibilityProps.hpp \
opm/core/fluid/blackoil/MiscibilityWater.hpp \ opm/core/fluid/blackoil/MiscibilityWater.hpp \
opm/core/fluid/blackoil/SinglePvtDead.hpp \
opm/core/fluid/blackoil/SinglePvtLiveGas.hpp \
opm/core/fluid/blackoil/SinglePvtLiveOil.hpp \
opm/core/fluid/blackoil/SinglePvtInterface.hpp \
opm/core/fluid/blackoil/SinglePvtConstCompr.hpp \
opm/core/utility/Average.hpp \ opm/core/utility/Average.hpp \
opm/core/utility/ErrorMacros.hpp \ opm/core/utility/ErrorMacros.hpp \
opm/core/utility/Factory.hpp \ opm/core/utility/Factory.hpp \

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -17,85 +17,22 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef OPM_BLACKOILDEFS_HEADER_INCLUDED #ifndef OPM_BLACKOILPHASES_HEADER_INCLUDED
#define OPM_BLACKOILDEFS_HEADER_INCLUDED #define OPM_BLACKOILPHASES_HEADER_INCLUDED
#include <tr1/array>
#include <iostream>
#include <boost/static_assert.hpp>
namespace Opm namespace Opm
{ {
class BlackoilDefs class BlackoilPhases
{ {
public: public:
enum { numComponents = 3 }; static const int MaxNumPhases = 3;
enum { numPhases = 3 }; // enum ComponentIndex { Water = 0, Oil = 1, Gas = 2 };
enum ComponentIndex { Water = 0, Oil = 1, Gas = 2 };
enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 }; enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 };
// We need types with operator= and constructor taking scalars
// for the small vectors and matrices, to save us from having to
// rewrite a large amount of code.
template <typename T, int N>
class SmallVec
{
public:
SmallVec()
{}
SmallVec(const T& elem)
{ assign(elem); }
SmallVec& operator=(const T& elem)
{ assign(elem); return *this; }
const T& operator[](int i) const
{ return data_[i]; }
T& operator[](int i)
{ return data_[i]; }
template <typename U>
void assign(const U& elem)
{
for (int i = 0; i < N; ++i) {
data_[i] = elem;
}
}
private:
T data_[N];
};
template <typename T, int Rows, int Cols>
class SmallMat
{
public:
SmallMat()
{}
SmallMat(const T& elem)
{ data_.assign(elem); }
SmallMat& operator=(const T& elem)
{ data_.assign(elem); return *this; }
typedef SmallVec<T, Cols> RowType;
const RowType& operator[](int i) const
{ return data_[i]; }
RowType& operator[](int i)
{ return data_[i]; }
private:
SmallVec<RowType, Rows> data_;
};
typedef double Scalar;
typedef SmallVec<Scalar, numComponents> CompVec;
typedef SmallVec<Scalar, numPhases> PhaseVec;
BOOST_STATIC_ASSERT(int(numComponents) == int(numPhases));
typedef SmallMat<Scalar, numComponents, numPhases> PhaseToCompMatrix;
typedef SmallMat<Scalar, numPhases, numPhases> PhaseJacobian;
// Attempting to guard against alignment issues.
BOOST_STATIC_ASSERT(sizeof(CompVec) == numComponents*sizeof(Scalar));
BOOST_STATIC_ASSERT(sizeof(PhaseVec) == numPhases*sizeof(Scalar));
BOOST_STATIC_ASSERT(sizeof(PhaseToCompMatrix) == numComponents*numPhases*sizeof(Scalar));
BOOST_STATIC_ASSERT(sizeof(PhaseJacobian) == numPhases*numPhases*sizeof(Scalar));
}; };
} // namespace Opm } // namespace Opm
#endif // OPM_BLACKOILDEFS_HEADER_INCLUDED #endif // OPM_BLACKOILPHASES_HEADER_INCLUDED

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibilityLiveOil.hpp
//
// Created: Wed Feb 10 09:08:09 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,70 +17,119 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SINTEF_MISCIBILITYLIVEOIL_HEADER #ifndef OPM_SINGLEPVTCONSTCOMPR_HEADER_INCLUDED
#define SINTEF_MISCIBILITYLIVEOIL_HEADER #define OPM_SINGLEPVTCONSTCOMPR_HEADER_INCLUDED
/** Class for miscible live oil.
* Detailed description.
*/
#include "MiscibilityProps.hpp" #include <opm/core/fluid/blackoil/SinglePvtInterface.hpp>
#include <opm/core/utility/ErrorMacros.hpp>
#include <vector>
#include <algorithm>
namespace Opm namespace Opm
{ {
class MiscibilityLiveOil : public MiscibilityProps class SinglePvtConstCompr : public SinglePvtInterface
{ {
public: public:
typedef std::vector<std::vector<std::vector<double> > > table_t; typedef std::vector<std::vector<double> > table_t;
MiscibilityLiveOil(const table_t& pvto); SinglePvtConstCompr(const table_t& pvtw)
virtual ~MiscibilityLiveOil(); {
const int region_number = 0;
if (pvtw.size() != 1) {
THROW("More than one PVD-region");
}
ref_press_ = pvtw[region_number][0];
ref_B_ = pvtw[region_number][1];
comp_ = pvtw[region_number][2];
viscosity_ = pvtw[region_number][3];
if (pvtw[region_number].size() > 4 && pvtw[region_number][4] != 0.0) {
THROW("SinglePvtConstCompr does not support 'viscosibility'.");
}
}
virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; SinglePvtConstCompr(double visc)
virtual double R (int region, double press, const surfvol_t& surfvol) const; : ref_press_(0.0),
virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; ref_B_(1.0),
virtual double B (int region, double press, const surfvol_t& surfvol) const; comp_(0.0),
virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; viscosity_(visc)
{
}
virtual void getViscosity(const std::vector<PhaseVec>& pressures, virtual ~SinglePvtConstCompr()
const std::vector<CompVec>& surfvol, {
int phase, }
std::vector<double>& output) const;
virtual void B(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const;
virtual void dBdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_B,
std::vector<double>& output_dBdp) const;
virtual void R(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const;
virtual void dRdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_R,
std::vector<double>& output_dRdp) const;
protected: virtual void mu(const int n,
double evalR(double press, const surfvol_t& surfvol) const; const double* /*p*/,
void evalRDeriv(double press, const surfvol_t& surfvol, double& R, double& dRdp) const; const double* /*z*/,
double evalB(double press, const surfvol_t& surfvol) const; double* output_mu) const
void evalBDeriv(double press, const surfvol_t& surfvol, double& B, double& dBdp) const; {
std::fill(output_mu, output_mu + n, viscosity_);
}
// item: 1=B 2=mu; virtual void B(const int n,
double miscible_oil(double press, const surfvol_t& surfvol, int item, const double* p,
bool deriv = false) const; const double* /*z*/,
double* output_B) const
{
if (comp_) {
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
// Computing a polynomial approximation to the exponential.
double x = comp_*(p[i] - ref_press_);
output_B[i] = ref_B_/(1.0 + x + 0.5*x*x);
}
} else {
std::fill(output_B, output_B + n, ref_B_);
}
}
// PVT properties of live oil (with dissolved gas) virtual void dBdp(const int n,
std::vector<std::vector<double> > saturated_oil_table_; const double* p,
std::vector<std::vector<std::vector<double> > > undersat_oil_tables_; const double* /*z*/,
double* output_B,
double* output_dBdp) const
{
B(n, p, 0, output_B);
if (comp_) {
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
output_dBdp[i] = -comp_*output_B[i];
}
} else {
std::fill(output_dBdp, output_dBdp + n, 0.0);
}
}
virtual void R(const int n,
const double* /*p*/,
const double* /*z*/,
double* output_R) const
{
std::fill(output_R, output_R + n, 0.0);
}
virtual void dRdp(const int n,
const double* /*p*/,
const double* /*z*/,
double* output_R,
double* output_dRdp) const
{
std::fill(output_R, output_R + n, 0.0);
std::fill(output_dRdp, output_dRdp + n, 0.0);
}
private:
double ref_press_;
double ref_B_;
double comp_;
double viscosity_;
}; };
} }
#endif // SINTEF_MISCIBILITYLIVEOIL_HEADER
#endif // OPM_SINGLEPVTCONSTCOMPR_HEADER_INCLUDED

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibilityDead.cpp
//
// Created: Wed Feb 10 09:06:04 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,17 +17,14 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <opm/core/fluid/blackoil/MiscibilityDead.hpp> #include <opm/core/fluid/blackoil/SinglePvtDead.hpp>
#include <algorithm>
#include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/linInt.hpp>
#include <opm/core/utility/buildUniformMonotoneTable.hpp> #include <opm/core/utility/buildUniformMonotoneTable.hpp>
#include <boost/lexical_cast.hpp> #include <algorithm>
#include <string>
#include <fstream>
using namespace std; // Extra includes for debug dumping of tables.
using namespace Dune; // #include <boost/lexical_cast.hpp>
// #include <string>
// #include <fstream>
namespace Opm namespace Opm
{ {
@@ -48,7 +34,7 @@ namespace Opm
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/// Constructor /// Constructor
MiscibilityDead::MiscibilityDead(const table_t& pvd_table) SinglePvtDead::SinglePvtDead(const table_t& pvd_table)
{ {
const int region_number = 0; const int region_number = 0;
if (pvd_table.size() != 1) { if (pvd_table.size() != 1) {
@@ -78,102 +64,65 @@ namespace Opm
} }
// Destructor // Destructor
MiscibilityDead::~MiscibilityDead() SinglePvtDead::~SinglePvtDead()
{ {
} }
double MiscibilityDead::getViscosity(int /*region*/, double press, const surfvol_t& /*surfvol*/) const
{
return viscosity_(press);
}
void MiscibilityDead::getViscosity(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>&, void SinglePvtDead::mu(const int n,
int phase, const double* p,
std::vector<double>& output) const const double* /*z*/,
double* output_mu) const
{ {
int num = pressures.size();
output.resize(num);
#pragma omp parallel for #pragma omp parallel for
for (int i = 0; i < num; ++i) { for (int i = 0; i < n; ++i) {
output[i] = viscosity_(pressures[i][phase]); output_mu[i] = viscosity_(p[i]);
} }
} }
double MiscibilityDead::B(int /*region*/, double press, const surfvol_t& /*surfvol*/) const void SinglePvtDead::B(const int n,
const double* p,
const double* /*z*/,
double* output_B) const
{ {
// Interpolate 1/B
return 1.0/one_over_B_(press);
}
void MiscibilityDead::B(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>&,
int phase,
std::vector<double>& output) const
{
int num = pressures.size();
output.resize(num);
#pragma omp parallel for #pragma omp parallel for
for (int i = 0; i < num; ++i) { for (int i = 0; i < n; ++i) {
output[i] = 1.0/one_over_B_(pressures[i][phase]); output_B[i] = 1.0/one_over_B_(p[i]);
} }
} }
double MiscibilityDead::dBdp(int region, double press, const surfvol_t& /*surfvol*/) const void SinglePvtDead::dBdp(const int n,
const double* p,
const double* /*z*/,
double* output_B,
double* output_dBdp) const
{ {
// Interpolate 1/B B(n, p, 0, output_B);
surfvol_t dummy_surfvol;
double Bg = B(region, press, dummy_surfvol);
return -Bg*Bg*one_over_B_.derivative(press);
}
void MiscibilityDead::dBdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvols,
int phase,
std::vector<double>& output_B,
std::vector<double>& output_dBdp) const
{
B(pressures, surfvols, phase, output_B);
int num = pressures.size();
output_dBdp.resize(num);
#pragma omp parallel for #pragma omp parallel for
for (int i = 0; i < num; ++i) { for (int i = 0; i < n; ++i) {
double Bg = output_B[i]; double Bg = output_B[i];
output_dBdp[i] = -Bg*Bg*one_over_B_.derivative(pressures[i][phase]); output_dBdp[i] = -Bg*Bg*one_over_B_.derivative(p[i]);
} }
} }
double MiscibilityDead::R(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const
void SinglePvtDead::R(const int n,
const double* /*p*/,
const double* /*z*/,
double* output_R) const
{ {
return 0.0; std::fill(output_R, output_R + n, 0.0);
} }
void MiscibilityDead::R(const std::vector<PhaseVec>& pressures, void SinglePvtDead::dRdp(const int n,
const std::vector<CompVec>&, const double* /*p*/,
int, const double* /*z*/,
std::vector<double>& output) const double* output_R,
double* output_dRdp) const
{ {
int num = pressures.size(); std::fill(output_R, output_R + n, 0.0);
output.clear(); std::fill(output_dRdp, output_dRdp + n, 0.0);
output.resize(num, 0.0);
}
double MiscibilityDead::dRdp(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const
{
return 0.0;
}
void MiscibilityDead::dRdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>&,
int,
std::vector<double>& output_R,
std::vector<double>& output_dRdp) const
{
int num = pressures.size();
output_R.clear();
output_R.resize(num, 0.0);
output_dRdp.clear();
output_dRdp.resize(num, 0.0);
} }
} }

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibilityDead.hpp
//
// Created: Wed Feb 10 09:05:47 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,55 +17,57 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SINTEF_MISCIBILITYDEAD_HEADER #ifndef OPM_SINGLEPVTDEAD_HEADER_INCLUDED
#define SINTEF_MISCIBILITYDEAD_HEADER #define OPM_SINGLEPVTDEAD_HEADER_INCLUDED
/** Class for immiscible dead oil and dry gas.
* Detailed description.
*/
#include <opm/core/fluid/blackoil/MiscibilityProps.hpp> #include <opm/core/fluid/blackoil/SinglePvtInterface.hpp>
#include <opm/core/utility/UniformTableLinear.hpp> #include <opm/core/utility/UniformTableLinear.hpp>
#include <vector>
namespace Opm namespace Opm
{ {
class MiscibilityDead : public MiscibilityProps
/// Class for immiscible dead oil and dry gas.
class SinglePvtDead : public SinglePvtInterface
{ {
public: public:
typedef std::vector<std::vector<std::vector<double> > > table_t; typedef std::vector<std::vector<std::vector<double> > > table_t;
MiscibilityDead(const table_t& pvd_table); SinglePvtDead(const table_t& pvd_table);
virtual ~MiscibilityDead(); virtual ~SinglePvtDead();
virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; /// Viscosity as a function of p and z.
virtual double B(int region, double press, const surfvol_t& surfvol) const; virtual void mu(const int n,
virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; const double* p,
virtual double R(int region, double press, const surfvol_t& surfvol) const; const double* z,
virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; double* output_mu) const;
virtual void getViscosity(const std::vector<PhaseVec>& pressures, /// Formation volume factor as a function of p and z.
const std::vector<CompVec>& surfvol, virtual void B(const int n,
int phase, const double* p,
std::vector<double>& output) const; const double* z,
virtual void B(const std::vector<PhaseVec>& pressures, double* output_B) const;
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const;
virtual void dBdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_B,
std::vector<double>& output_dBdp) const;
virtual void R(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const;
virtual void dRdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_R,
std::vector<double>& output_dRdp) const;
/// Formation volume factor and p-derivative as functions of p and z.
virtual void dBdp(const int n,
const double* p,
const double* z,
double* output_B,
double* output_dBdp) const;
/// Solution factor as a function of p and z.
virtual void R(const int n,
const double* p,
const double* z,
double* output_R) const;
/// Solution factor and p-derivative as functions of p and z.
virtual void dRdp(const int n,
const double* p,
const double* z,
double* output_R,
double* output_dRdp) const;
private: private:
// PVT properties of dry gas or dead oil // PVT properties of dry gas or dead oil
Dune::utils::UniformTableLinear<double> one_over_B_; Dune::utils::UniformTableLinear<double> one_over_B_;
@@ -85,5 +76,5 @@ namespace Opm
} }
#endif // SINTEF_MISCIBILITYDEAD_HEADER #endif // OPM_SINGLEPVTDEAD_HEADER_INCLUDED

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibilityProps.cpp
//
// Created: Wed Feb 10 09:05:05 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,25 +17,31 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "MiscibilityProps.hpp" #include <opm/core/fluid/blackoil/SinglePvtInterface.hpp>
using namespace std;
namespace Opm namespace Opm
{ {
SinglePvtInterface::SinglePvtInterface()
: num_phases_(MaxNumPhases)
{
for (int i = 0; i < MaxNumPhases; ++i) {
phase_pos_[i] = i;
}
}
//------------------------------------------------------------------------ SinglePvtInterface::~SinglePvtInterface()
// Member functions
//-------------------------------------------------------------------------
/// Constructor
MiscibilityProps::MiscibilityProps()
{ {
} }
MiscibilityProps::~MiscibilityProps() void SinglePvtInterface::setPhaseConfiguration(const int num_phases, const int* phase_pos)
{ {
num_phases_ = num_phases;
for (int i = 0; i < MaxNumPhases; ++i) {
phase_pos_[i] = phase_pos[i];
}
} }
} // namespace Opm } // namespace Opm

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibilityProps.hpp
//
// Created: Wed Feb 10 09:04:35 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,60 +17,73 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SINTEF_MISCIBILITYPROPS_HEADER #ifndef OPM_SINGLEPVTINTERFACE_HEADER_INCLUDED
#define SINTEF_MISCIBILITYPROPS_HEADER #define OPM_SINGLEPVTINTERFACE_HEADER_INCLUDED
/** Base class for properties of fluids and rocks.
* Detailed description.
*/
#include "BlackoilDefs.hpp" #include <opm/core/fluid/blackoil/BlackoilPhases.hpp>
#include <vector>
#include <tr1/array>
namespace Opm namespace Opm
{ {
class SinglePvtInterface : public BlackoilPhases
class MiscibilityProps : public BlackoilDefs
{ {
public: public:
typedef CompVec surfvol_t; SinglePvtInterface();
MiscibilityProps(); virtual ~SinglePvtInterface();
virtual ~MiscibilityProps();
virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const = 0; /// \param[in] num_phases The number of active phases.
virtual double B (int region, double press, const surfvol_t& surfvol) const = 0; /// \param[in] phase_pos Array of BlackpoilPhases::MaxNumPhases
virtual double dBdp(int region, double press, const surfvol_t& surfvol) const = 0; /// integers, giving the relative
virtual double R (int region, double press, const surfvol_t& surfvol) const = 0; /// positions of the three canonical
virtual double dRdp(int region, double press, const surfvol_t& surfvol) const = 0; /// phases A, L, V in order to handle
/// arbitrary two-phase situations.
void setPhaseConfiguration(const int num_phases, const int* phase_pos);
virtual void getViscosity(const std::vector<PhaseVec>& pressures, /// For all the virtual methods, the following apply: p and z
const std::vector<CompVec>& surfvol, /// are expected to be of size n and n*num_phases, respectively.
int phase, /// Output arrays shall be of size n, and must be valid before
std::vector<double>& output) const = 0; /// calling the method.
virtual void B(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol, /// Viscosity as a function of p and z.
int phase, virtual void mu(const int n,
std::vector<double>& output) const = 0; const double* p,
virtual void dBdp(const std::vector<PhaseVec>& pressures, const double* z,
const std::vector<CompVec>& surfvol, double* output_mu) const = 0;
int phase,
std::vector<double>& output_B, /// Formation volume factor as a function of p and z.
std::vector<double>& output_dBdp) const = 0; virtual void B(const int n,
virtual void R(const std::vector<PhaseVec>& pressures, const double* p,
const std::vector<CompVec>& surfvol, const double* z,
int phase, double* output_B) const = 0;
std::vector<double>& output) const = 0;
virtual void dRdp(const std::vector<PhaseVec>& pressures, /// Formation volume factor and p-derivative as functions of p and z.
const std::vector<CompVec>& surfvol, virtual void dBdp(const int n,
int phase, const double* p,
std::vector<double>& output_R, const double* z,
std::vector<double>& output_dRdp) const = 0; double* output_B,
double* output_dBdp) const = 0;
/// Solution factor as a function of p and z.
virtual void R(const int n,
const double* p,
const double* z,
double* output_R) const = 0;
/// Solution factor and p-derivative as functions of p and z.
virtual void dRdp(const int n,
const double* p,
const double* z,
double* output_R,
double* output_dRdp) const = 0;
protected:
int num_phases_;
int phase_pos_[MaxNumPhases];
}; };
} // namespace Opm } // namespace Opm
#endif // SINTEF_MISCIBILITYPROPS_HEADER #endif // OPM_SINGLEPVTINTERFACE_HEADER_INCLUDED

View File

@@ -28,24 +28,24 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <opm/core/fluid/blackoil/SinglePvtLiveGas.hpp>
#include <opm/core/fluid/blackoil/MiscibilityLiveGas.hpp>
#include <algorithm>
#include <opm/core/utility/ErrorMacros.hpp> #include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/linInt.hpp> #include <opm/core/utility/linInt.hpp>
#include <algorithm>
using namespace std;
using namespace Dune;
namespace Opm namespace Opm
{ {
using Dune::linearInterpolationExtrap;
using Dune::linearInterpolDerivative;
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Member functions // Member functions
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/// Constructor /// Constructor
MiscibilityLiveGas::MiscibilityLiveGas(const table_t& pvtg) SinglePvtLiveGas::SinglePvtLiveGas(const table_t& pvtg)
{ {
// GAS, PVTG // GAS, PVTG
const int region_number = 0; const int region_number = 0;
@@ -81,135 +81,156 @@ namespace Opm
} }
// Destructor // Destructor
MiscibilityLiveGas::~MiscibilityLiveGas() SinglePvtLiveGas::~SinglePvtLiveGas()
{ {
} }
double MiscibilityLiveGas::getViscosity(int /*region*/, double press, const surfvol_t& surfvol) const
{
return miscible_gas(press, surfvol, 2, false);
}
void MiscibilityLiveGas::getViscosity(const std::vector<PhaseVec>& pressures, void SinglePvtLiveGas::mu(const int n,
const std::vector<CompVec>& surfvol, const double* p,
int phase, const double* z,
std::vector<double>& output) const double* output_mu) const
{ {
ASSERT(pressures.size() == surfvol.size()); #pragma omp parallel for
int num = pressures.size(); for (int i = 0; i < n; ++i) {
output.resize(num); output_mu[i] = miscible_gas(p[i], z + num_phases_*i, 2, false);
for (int i = 0; i < num; ++i) {
output[i] = miscible_gas(pressures[i][phase], surfvol[i], 2, false);
} }
} }
// Vaporised oil-gas ratio.
double MiscibilityLiveGas::R(int /*region*/, double press, const surfvol_t& surfvol) const /// Formation volume factor as a function of p and z.
void SinglePvtLiveGas::B(const int n,
const double* p,
const double* z,
double* output_B) const
{ {
if (surfvol[Liquid] == 0.0) { #pragma omp parallel for
for (int i = 0; i < n; ++i) {
output_B[i] = evalB(p[i], z + num_phases_*i);
}
}
/// Formation volume factor and p-derivative as functions of p and z.
void SinglePvtLiveGas::dBdp(const int n,
const double* p,
const double* z,
double* output_B,
double* output_dBdp) const
{
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
evalBDeriv(p[i], z + num_phases_*i, output_B[i], output_dBdp[i]);
}
}
/// Solution factor as a function of p and z.
void SinglePvtLiveGas::R(const int n,
const double* p,
const double* z,
double* output_R) const
{
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
output_R[i] = evalR(p[i], z + num_phases_*i);
}
}
/// Solution factor and p-derivative as functions of p and z.
void SinglePvtLiveGas::dRdp(const int n,
const double* p,
const double* z,
double* output_R,
double* output_dRdp) const
{
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
evalRDeriv(p[i], z + num_phases_*i, output_R[i], output_dRdp[i]);
}
}
// ---- Private methods ----
double SinglePvtLiveGas::evalB(const double press, const double* surfvol) const
{
if (surfvol[phase_pos_[Vapour]] == 0.0) {
// To handle no-gas case.
return 1.0;
}
return miscible_gas(press, surfvol, 1, false);
}
void SinglePvtLiveGas::evalBDeriv(const double press, const double* surfvol,
double& B, double& dBdp) const
{
if (surfvol[phase_pos_[Vapour]] == 0.0) {
// To handle no-gas case.
B = 1.0;
dBdp = 0.0;
return;
}
B = miscible_gas(press, surfvol, 1, false);
dBdp = miscible_gas(press, surfvol, 1, true);
}
double SinglePvtLiveGas::evalR(const double press, const double* surfvol) const
{
if (surfvol[phase_pos_[Liquid]] == 0.0) {
// To handle no-gas case.
return 0.0; return 0.0;
} }
double R = linearInterpolationExtrap(saturated_gas_table_[0], double satR = linearInterpolationExtrap(saturated_gas_table_[0],
saturated_gas_table_[3], press); saturated_gas_table_[3], press);
double maxR = surfvol[Liquid]/surfvol[Vapour]; double maxR = surfvol[phase_pos_[Liquid]]/surfvol[phase_pos_[Vapour]];
if (R < maxR ) { // Saturated case if (satR < maxR ) {
return R; // Saturated case
return satR;
} else { } else {
return maxR; // Undersaturated case // Undersaturated case
return maxR;
} }
} }
void MiscibilityLiveGas::R(const std::vector<PhaseVec>& pressures, void SinglePvtLiveGas::evalRDeriv(const double press, const double* surfvol,
const std::vector<CompVec>& surfvol, double& R, double& dRdp) const
int phase,
std::vector<double>& output) const
{ {
ASSERT(pressures.size() == surfvol.size()); if (surfvol[phase_pos_[Liquid]] == 0.0) {
int num = pressures.size(); // To handle no-gas case.
output.resize(num); R = 0.0;
for (int i = 0; i < num; ++i) { dRdp = 0.0;
output[i] = R(0, pressures[i][phase], surfvol[i]); return;
} }
} double satR = linearInterpolationExtrap(saturated_gas_table_[0],
// Vaporised oil-gas ratio derivative
double MiscibilityLiveGas::dRdp(int /*region*/, double press, const surfvol_t& surfvol) const
{
double R = linearInterpolationExtrap(saturated_gas_table_[0],
saturated_gas_table_[3], press); saturated_gas_table_[3], press);
double maxR = surfvol[Liquid]/surfvol[Vapour]; double maxR = surfvol[phase_pos_[Liquid]]/surfvol[phase_pos_[Vapour]];
if (R < maxR ) { // Saturated case if (satR < maxR ) {
return linearInterpolDerivative(saturated_gas_table_[0], // Saturated case
R = satR;
dRdp = linearInterpolDerivative(saturated_gas_table_[0],
saturated_gas_table_[3], saturated_gas_table_[3],
press); press);
} else { } else {
return 0.0; // Undersaturated case // Undersaturated case
R = maxR;
dRdp = 0.0;
} }
} }
void MiscibilityLiveGas::dRdp(const std::vector<PhaseVec>& pressures, double SinglePvtLiveGas::miscible_gas(const double press,
const std::vector<CompVec>& surfvol, const double* surfvol,
int phase, const int item,
std::vector<double>& output_R, const bool deriv) const
std::vector<double>& output_dRdp) const
{
ASSERT(pressures.size() == surfvol.size());
R(pressures, surfvol, phase, output_R);
int num = pressures.size();
output_dRdp.resize(num);
for (int i = 0; i < num; ++i) {
output_dRdp[i] = dRdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated R.
}
}
double MiscibilityLiveGas::B(int /*region*/, double press, const surfvol_t& surfvol) const
{
if (surfvol[Vapour] == 0.0) return 1.0; // To handle no-gas case.
return miscible_gas(press, surfvol, 1, false);
}
void MiscibilityLiveGas::B(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const
{
ASSERT(pressures.size() == surfvol.size());
int num = pressures.size();
output.resize(num);
for (int i = 0; i < num; ++i) {
output[i] = B(0, pressures[i][phase], surfvol[i]);
}
}
double MiscibilityLiveGas::dBdp(int /*region*/, double press, const surfvol_t& surfvol) const
{
if (surfvol[Vapour] == 0.0) return 0.0; // To handle no-gas case.
return miscible_gas(press, surfvol, 1, true);
}
void MiscibilityLiveGas::dBdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_B,
std::vector<double>& output_dBdp) const
{
ASSERT(pressures.size() == surfvol.size());
B(pressures, surfvol, phase, output_B);
int num = pressures.size();
output_dBdp.resize(num);
for (int i = 0; i < num; ++i) {
output_dBdp[i] = dBdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated B.
}
}
double MiscibilityLiveGas::miscible_gas(double press, const surfvol_t& surfvol, int item,
bool deriv) const
{ {
int section; int section;
double R = linearInterpolationExtrap(saturated_gas_table_[0], double R = linearInterpolationExtrap(saturated_gas_table_[0],
saturated_gas_table_[3], press, saturated_gas_table_[3], press,
section); section);
double maxR = surfvol[Liquid]/surfvol[Vapour]; double maxR = surfvol[phase_pos_[Liquid]]/surfvol[phase_pos_[Vapour]];
if (deriv) { if (deriv) {
if (R < maxR ) { // Saturated case if (R < maxR ) { // Saturated case
return linearInterpolDerivative(saturated_gas_table_[0], return linearInterpolDerivative(saturated_gas_table_[0],

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibilityLiveGas.hpp
//
// Created: Wed Feb 10 09:21:26 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,58 +17,66 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SINTEF_MISCIBILITYLIVEGAS_HEADER #ifndef OPM_SINGLEPVTLIVEGAS_HEADER_INCLUDED
#define SINTEF_MISCIBILITYLIVEGAS_HEADER #define OPM_SINGLEPVTLIVEGAS_HEADER_INCLUDED
/** Class for miscible wet gas. #include <opm/core/fluid/blackoil/SinglePvtInterface.hpp>
* Detailed description. #include <vector>
*/
#include "MiscibilityProps.hpp"
namespace Opm namespace Opm
{ {
class MiscibilityLiveGas : public MiscibilityProps /// Class for miscible wet gas.
class SinglePvtLiveGas : public SinglePvtInterface
{ {
public: public:
typedef std::vector<std::vector<std::vector<double> > > table_t; typedef std::vector<std::vector<std::vector<double> > > table_t;
MiscibilityLiveGas(const table_t& pvto); SinglePvtLiveGas(const table_t& pvto);
virtual ~MiscibilityLiveGas(); virtual ~SinglePvtLiveGas();
virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; /// Viscosity as a function of p and z.
virtual double R(int region, double press, const surfvol_t& surfvol) const; virtual void mu(const int n,
virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; const double* p,
virtual double B(int region, double press, const surfvol_t& surfvol) const; const double* z,
virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; double* output_mu) const;
virtual void getViscosity(const std::vector<PhaseVec>& pressures, /// Formation volume factor as a function of p and z.
const std::vector<CompVec>& surfvol, virtual void B(const int n,
int phase, const double* p,
std::vector<double>& output) const; const double* z,
virtual void B(const std::vector<PhaseVec>& pressures, double* output_B) const;
const std::vector<CompVec>& surfvol,
int phase, /// Formation volume factor and p-derivative as functions of p and z.
std::vector<double>& output) const; virtual void dBdp(const int n,
virtual void dBdp(const std::vector<PhaseVec>& pressures, const double* p,
const std::vector<CompVec>& surfvol, const double* z,
int phase, double* output_B,
std::vector<double>& output_B, double* output_dBdp) const;
std::vector<double>& output_dBdp) const;
virtual void R(const std::vector<PhaseVec>& pressures, /// Solution factor as a function of p and z.
const std::vector<CompVec>& surfvol, virtual void R(const int n,
int phase, const double* p,
std::vector<double>& output) const; const double* z,
virtual void dRdp(const std::vector<PhaseVec>& pressures, double* output_R) const;
const std::vector<CompVec>& surfvol,
int phase, /// Solution factor and p-derivative as functions of p and z.
std::vector<double>& output_R, virtual void dRdp(const int n,
std::vector<double>& output_dRdp) const; const double* p,
const double* z,
double* output_R,
double* output_dRdp) const;
protected: protected:
// item: 1=B 2=mu; double evalB(double press, const double* surfvol) const;
double miscible_gas(double press, const surfvol_t& surfvol, int item, void evalBDeriv(double press, const double* surfvol, double& B, double& dBdp) const;
bool deriv = false) const; double evalR(double press, const double* surfvol) const;
void evalRDeriv(double press, const double* surfvol, double& R, double& dRdp) const;
// item: 1=>B 2=>mu;
double miscible_gas(const double press,
const double* surfvol,
const int item,
const bool deriv = false) const;
// PVT properties of wet gas (with vaporised oil) // PVT properties of wet gas (with vaporised oil)
std::vector<std::vector<double> > saturated_gas_table_; std::vector<std::vector<double> > saturated_gas_table_;
std::vector<std::vector<std::vector<double> > > undersat_gas_tables_; std::vector<std::vector<std::vector<double> > > undersat_gas_tables_;
@@ -88,5 +85,5 @@ namespace Opm
} }
#endif // SINTEF_MISCIBILITYLIVEGAS_HEADER #endif // OPM_SINGLEPVTLIVEGAS_HEADER_INCLUDED

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibiltyLiveOil.cpp
//
// Created: Wed Feb 10 09:08:25 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,24 +17,26 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <opm/core/fluid/blackoil/MiscibilityLiveOil.hpp> #include <opm/core/fluid/blackoil/SinglePvtLiveOil.hpp>
#include <opm/core/utility/ErrorMacros.hpp> #include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/linInt.hpp> #include <opm/core/utility/linInt.hpp>
#include <algorithm> #include <algorithm>
using namespace std;
using namespace Dune;
namespace Opm namespace Opm
{ {
using Dune::linearInterpolationExtrap;
using Dune::linearInterpolDerivative;
using Dune::tableIndex;
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Member functions // Member functions
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/// Constructor /// Constructor
MiscibilityLiveOil::MiscibilityLiveOil(const table_t& pvto) SinglePvtLiveOil::SinglePvtLiveOil(const table_t& pvto)
{ {
// OIL, PVTO // OIL, PVTO
const int region_number = 0; const int region_number = 0;
@@ -164,132 +155,108 @@ namespace Opm
} }
} }
} }
// Destructor
MiscibilityLiveOil::~MiscibilityLiveOil() /// Destructor.
SinglePvtLiveOil::~SinglePvtLiveOil()
{ {
} }
double MiscibilityLiveOil::getViscosity(int /*region*/, double press, const surfvol_t& surfvol) const
{
return miscible_oil(press, surfvol, 2, false);
}
void MiscibilityLiveOil::getViscosity(const std::vector<PhaseVec>& pressures, /// Viscosity as a function of p and z.
const std::vector<CompVec>& surfvol, void SinglePvtLiveOil::mu(const int n,
int phase, const double* p,
std::vector<double>& output) const const double* z,
double* output_mu) const
{ {
ASSERT(pressures.size() == surfvol.size());
int num = pressures.size();
output.resize(num);
#pragma omp parallel for #pragma omp parallel for
for (int i = 0; i < num; ++i) { for (int i = 0; i < n; ++i) {
output[i] = miscible_oil(pressures[i][phase], surfvol[i], 2, false); output_mu[i] = miscible_oil(p[i], z + num_phases_*i, 2, false);
}
}
// Dissolved gas-oil ratio
double MiscibilityLiveOil::R(int /*region*/, double press, const surfvol_t& surfvol) const
{
return evalR(press, surfvol);
}
void MiscibilityLiveOil::R(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const
{
ASSERT(pressures.size() == surfvol.size());
int num = pressures.size();
output.resize(num);
#pragma omp parallel for
for (int i = 0; i < num; ++i) {
output[i] = evalR(pressures[i][phase], surfvol[i]);
}
}
// Dissolved gas-oil ratio derivative
double MiscibilityLiveOil::dRdp(int /*region*/, double press, const surfvol_t& surfvol) const
{
double R = linearInterpolationExtrap(saturated_oil_table_[0],
saturated_oil_table_[3], press);
double maxR = surfvol[Vapour]/surfvol[Liquid];
if (R < maxR ) { // Saturated case
return linearInterpolDerivative(saturated_oil_table_[0],
saturated_oil_table_[3],
press);
} else {
return 0.0; // Undersaturated case
}
}
void MiscibilityLiveOil::dRdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_R,
std::vector<double>& output_dRdp) const
{
ASSERT(pressures.size() == surfvol.size());
int num = pressures.size();
output_R.resize(num);
output_dRdp.resize(num);
#pragma omp parallel for
for (int i = 0; i < num; ++i) {
evalRDeriv(pressures[i][phase], surfvol[i], output_R[i], output_dRdp[i]);
}
}
double MiscibilityLiveOil::B(int /*region*/, double press, const surfvol_t& surfvol) const
{
return evalB(press, surfvol);
}
void MiscibilityLiveOil::B(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const
{
ASSERT(pressures.size() == surfvol.size());
int num = pressures.size();
output.resize(num);
#pragma omp parallel for
for (int i = 0; i < num; ++i) {
output[i] = evalB(pressures[i][phase], surfvol[i]);
}
}
double MiscibilityLiveOil::dBdp(int /*region*/, double press, const surfvol_t& surfvol) const
{
// if (surfvol[Liquid] == 0.0) return 0.0; // To handle no-oil case.
double Bo = evalB(press, surfvol); // \TODO check if we incur virtual call overhead here.
return -Bo*Bo*miscible_oil(press, surfvol, 1, true);
}
void MiscibilityLiveOil::dBdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_B,
std::vector<double>& output_dBdp) const
{
ASSERT(pressures.size() == surfvol.size());
B(pressures, surfvol, phase, output_B);
int num = pressures.size();
output_dBdp.resize(num);
#pragma omp parallel for
for (int i = 0; i < num; ++i) {
output_dBdp[i] = dBdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated B.
} }
} }
double MiscibilityLiveOil::evalR(double press, const surfvol_t& surfvol) const /// Formation volume factor as a function of p and z.
void SinglePvtLiveOil::B(const int n,
const double* p,
const double* z,
double* output_B) const
{ {
if (surfvol[Vapour] == 0.0) { #pragma omp parallel for
for (int i = 0; i < n; ++i) {
output_B[i] = evalB(p[i], z + num_phases_*i);
}
}
/// Formation volume factor and p-derivative as functions of p and z.
void SinglePvtLiveOil::dBdp(const int n,
const double* p,
const double* z,
double* output_B,
double* output_dBdp) const
{
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
evalBDeriv(p[i], z + num_phases_*i, output_B[i], output_dBdp[i]);
}
}
/// Solution factor as a function of p and z.
void SinglePvtLiveOil::R(const int n,
const double* p,
const double* z,
double* output_R) const
{
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
output_R[i] = evalR(p[i], z + num_phases_*i);
}
}
/// Solution factor and p-derivative as functions of p and z.
void SinglePvtLiveOil::dRdp(const int n,
const double* p,
const double* z,
double* output_R,
double* output_dRdp) const
{
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
evalRDeriv(p[i], z + num_phases_*i, output_R[i], output_dRdp[i]);
}
}
// ---- Private methods ----
double SinglePvtLiveOil::evalB(double press, const double* surfvol) const
{
// if (surfvol[phase_pos_[Liquid]] == 0.0) return 1.0; // To handle no-oil case.
return 1.0/miscible_oil(press, surfvol, 1, false);
}
void SinglePvtLiveOil::evalBDeriv(const double press, const double* surfvol,
double& B, double& dBdp) const
{
B = evalB(press, surfvol);
dBdp = -B*B*miscible_oil(press, surfvol, 1, true);
}
double SinglePvtLiveOil::evalR(double press, const double* surfvol) const
{
if (surfvol[phase_pos_[Vapour]] == 0.0) {
return 0.0; return 0.0;
} }
double R = linearInterpolationExtrap(saturated_oil_table_[0], double R = linearInterpolationExtrap(saturated_oil_table_[0],
saturated_oil_table_[3], press); saturated_oil_table_[3], press);
double maxR = surfvol[Vapour]/surfvol[Liquid]; double maxR = surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]];
if (R < maxR ) { // Saturated case if (R < maxR ) { // Saturated case
return R; return R;
} else { } else {
@@ -297,17 +264,17 @@ namespace Opm
} }
} }
void MiscibilityLiveOil::evalRDeriv(const double press, const surfvol_t& surfvol, void SinglePvtLiveOil::evalRDeriv(const double press, const double* surfvol,
double& R, double& dRdp) const double& R, double& dRdp) const
{ {
if (surfvol[Vapour] == 0.0) { if (surfvol[phase_pos_[Vapour]] == 0.0) {
R = 0.0; R = 0.0;
dRdp = 0.0; dRdp = 0.0;
return; return;
} }
R = linearInterpolationExtrap(saturated_oil_table_[0], R = linearInterpolationExtrap(saturated_oil_table_[0],
saturated_oil_table_[3], press); saturated_oil_table_[3], press);
double maxR = surfvol[Vapour]/surfvol[Liquid]; double maxR = surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]];
if (R < maxR ) { if (R < maxR ) {
// Saturated case // Saturated case
dRdp = linearInterpolDerivative(saturated_oil_table_[0], dRdp = linearInterpolDerivative(saturated_oil_table_[0],
@@ -321,29 +288,16 @@ namespace Opm
} }
double MiscibilityLiveOil::evalB(double press, const surfvol_t& surfvol) const double SinglePvtLiveOil::miscible_oil(const double press,
{ const double* surfvol,
// if (surfvol[Liquid] == 0.0) return 1.0; // To handle no-oil case. const int item,
return 1.0/miscible_oil(press, surfvol, 1, false); const bool deriv) const
}
void MiscibilityLiveOil::evalBDeriv(const double press, const surfvol_t& surfvol,
double& B, double& dBdp) const
{
B = evalB(press, surfvol);
dBdp = -B*B*miscible_oil(press, surfvol, 1, true);
}
double MiscibilityLiveOil::miscible_oil(double press, const surfvol_t& surfvol,
int item, bool deriv) const
{ {
int section; int section;
double R = linearInterpolationExtrap(saturated_oil_table_[0], double R = linearInterpolationExtrap(saturated_oil_table_[0],
saturated_oil_table_[3], saturated_oil_table_[3],
press, section); press, section);
double maxR = (surfvol[Liquid] == 0.0) ? 0.0 : surfvol[Vapour]/surfvol[Liquid]; double maxR = (surfvol[phase_pos_[Liquid]] == 0.0) ? 0.0 : surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]];
if (deriv) { if (deriv) {
if (R < maxR ) { // Saturated case if (R < maxR ) { // Saturated case
return linearInterpolDerivative(saturated_oil_table_[0], return linearInterpolDerivative(saturated_oil_table_[0],

View File

@@ -1,16 +1,5 @@
//===========================================================================
//
// File: MiscibilityLiveOil.hpp
//
// Created: Wed Feb 10 09:08:09 2010
//
// Author: Bjørn Spjelkavik <bsp@sintef.no>
//
// Revision: $Id$
//
//===========================================================================
/* /*
Copyright 2010 SINTEF ICT, Applied Mathematics. Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@@ -28,63 +17,67 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SINTEF_MISCIBILITYLIVEOIL_HEADER #ifndef OPM_SINGLEPVTLIVEOIL_HEADER_INCLUDED
#define SINTEF_MISCIBILITYLIVEOIL_HEADER #define OPM_SINGLEPVTLIVEOIL_HEADER_INCLUDED
/** Class for miscible live oil.
* Detailed description.
*/
#include "MiscibilityProps.hpp" #include <opm/core/fluid/blackoil/SinglePvtInterface.hpp>
#include <vector>
namespace Opm namespace Opm
{ {
class MiscibilityLiveOil : public MiscibilityProps /// Class for miscible live oil.
class SinglePvtLiveOil : public SinglePvtInterface
{ {
public: public:
typedef std::vector<std::vector<std::vector<double> > > table_t; typedef std::vector<std::vector<std::vector<double> > > table_t;
MiscibilityLiveOil(const table_t& pvto); SinglePvtLiveOil(const table_t& pvto);
virtual ~MiscibilityLiveOil(); virtual ~SinglePvtLiveOil();
virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; /// Viscosity as a function of p and z.
virtual double R (int region, double press, const surfvol_t& surfvol) const; virtual void mu(const int n,
virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; const double* p,
virtual double B (int region, double press, const surfvol_t& surfvol) const; const double* z,
virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; double* output_mu) const;
virtual void getViscosity(const std::vector<PhaseVec>& pressures, /// Formation volume factor as a function of p and z.
const std::vector<CompVec>& surfvol, virtual void B(const int n,
int phase, const double* p,
std::vector<double>& output) const; const double* z,
virtual void B(const std::vector<PhaseVec>& pressures, double* output_B) const;
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const;
virtual void dBdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_B,
std::vector<double>& output_dBdp) const;
virtual void R(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output) const;
virtual void dRdp(const std::vector<PhaseVec>& pressures,
const std::vector<CompVec>& surfvol,
int phase,
std::vector<double>& output_R,
std::vector<double>& output_dRdp) const;
protected: /// Formation volume factor and p-derivative as functions of p and z.
double evalR(double press, const surfvol_t& surfvol) const; virtual void dBdp(const int n,
void evalRDeriv(double press, const surfvol_t& surfvol, double& R, double& dRdp) const; const double* p,
double evalB(double press, const surfvol_t& surfvol) const; const double* z,
void evalBDeriv(double press, const surfvol_t& surfvol, double& B, double& dBdp) const; double* output_B,
double* output_dBdp) const;
// item: 1=B 2=mu; /// Solution factor as a function of p and z.
double miscible_oil(double press, const surfvol_t& surfvol, int item, virtual void R(const int n,
bool deriv = false) const; const double* p,
const double* z,
double* output_R) const;
/// Solution factor and p-derivative as functions of p and z.
virtual void dRdp(const int n,
const double* p,
const double* z,
double* output_R,
double* output_dRdp) const;
private:
double evalB(double press, const double* surfvol) const;
void evalBDeriv(double press, const double* surfvol, double& B, double& dBdp) const;
double evalR(double press, const double* surfvol) const;
void evalRDeriv(double press, const double* surfvol, double& R, double& dRdp) const;
// item: 1=>1/B 2=>mu;
double miscible_oil(const double press,
const double* surfvol,
const int item,
const bool deriv = false) const;
// PVT properties of live oil (with dissolved gas) // PVT properties of live oil (with dissolved gas)
std::vector<std::vector<double> > saturated_oil_table_; std::vector<std::vector<double> > saturated_oil_table_;
@@ -93,5 +86,5 @@ namespace Opm
} }
#endif // SINTEF_MISCIBILITYLIVEOIL_HEADER #endif // OPM_SINGLEPVTLIVEOIL_HEADER_INCLUDED