Add new fluid interface
- in progress
This commit is contained in:
committed by
Tor Harald Sandve
parent
268a810eb3
commit
1c904aa451
@@ -147,6 +147,7 @@ list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_column_extract.cpp
|
||||
tests/test_geom2d.cpp
|
||||
tests/test_param.cpp
|
||||
tests/not-unit/test_newfluidinterface.cpp
|
||||
)
|
||||
|
||||
# originally generated with the command:
|
||||
|
||||
@@ -81,12 +81,12 @@ namespace Opm
|
||||
if (phase_usage_.phase_used[Liquid]) {
|
||||
if (deck.hasField("PVDO")) {
|
||||
if (samples > 0) {
|
||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_, samples));
|
||||
// props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_, samples));
|
||||
} else {
|
||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_));
|
||||
}
|
||||
} else if (deck.hasField("PVTO")) {
|
||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_));
|
||||
//props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_));
|
||||
} else if (deck.hasField("PVCDO")) {
|
||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtConstCompr(deck.getPVCDO().pvcdo_));
|
||||
} else {
|
||||
@@ -97,12 +97,12 @@ namespace Opm
|
||||
if (phase_usage_.phase_used[Vapour]) {
|
||||
if (deck.hasField("PVDG")) {
|
||||
if (samples > 0) {
|
||||
props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_, samples));
|
||||
// props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_, samples));
|
||||
} else {
|
||||
props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_));
|
||||
}
|
||||
} else if (deck.hasField("PVTG")) {
|
||||
props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_));
|
||||
// props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_));
|
||||
} else {
|
||||
THROW("Input is missing PVDG or PVTG\n");
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ namespace Opm
|
||||
{
|
||||
|
||||
/// Class for constant compressible phases (PVTW or PVCDO).
|
||||
/// For all the virtual methods, the following apply: p and z
|
||||
/// are expected to be of size n and n*num_phases, respectively.
|
||||
/// The PVT properties can either be given as a function of pressure (p) and surface volume (z)
|
||||
/// or pressure (p) and gas resolution factor (r).
|
||||
/// For all the virtual methods, the following apply: p, r and z
|
||||
/// are expected to be of size n, size n and n*num_phases, respectively.
|
||||
/// Output arrays shall be of size n, and must be valid before
|
||||
/// calling the method.
|
||||
class SinglePvtConstCompr : public SinglePvtInterface
|
||||
@@ -83,6 +85,29 @@ namespace Opm
|
||||
}
|
||||
}
|
||||
|
||||
virtual void mu(const int n,
|
||||
const double* p,
|
||||
const double* /*r*/,
|
||||
double* output_mu,
|
||||
double* output_dmudp,
|
||||
double* output_dmudr) const
|
||||
{
|
||||
if (visc_comp_) {
|
||||
// #pragma omp parallel for
|
||||
for (int i = 0; i < n; ++i) {
|
||||
// Computing a polynomial approximation to the exponential.
|
||||
double x = -visc_comp_*(p[i] - ref_press_);
|
||||
double d = (1.0 + x + 0.5*x*x);
|
||||
output_mu[i] = viscosity_/d;
|
||||
output_dmudp[i] = (viscosity_/(d*d))*(1+x) * visc_comp_;
|
||||
}
|
||||
} else {
|
||||
std::fill(output_mu, output_mu + n, viscosity_);
|
||||
std::fill(output_dmudp, output_dmudp + n, 0.0);
|
||||
}
|
||||
std::fill(output_dmudr, output_dmudr + n, 0.0);
|
||||
}
|
||||
|
||||
virtual void B(const int n,
|
||||
const double* p,
|
||||
const double* /*z*/,
|
||||
@@ -120,6 +145,43 @@ namespace Opm
|
||||
}
|
||||
}
|
||||
|
||||
virtual void b(const int n,
|
||||
const double* p,
|
||||
const double* /*r*/,
|
||||
double* output_b,
|
||||
double* output_dbdp,
|
||||
double* output_dbdr) 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_);
|
||||
double d = (1.0 + x + 0.5*x*x);
|
||||
|
||||
// b = 1/B = d/ref_B_B;
|
||||
output_b[i] = d/ref_B_;
|
||||
output_dbdp[i] = (1 + x) * comp_/ref_B_;
|
||||
}
|
||||
} else {
|
||||
|
||||
std::fill(output_b, output_b + n, 1/ref_B_);
|
||||
std::fill(output_dbdp, output_dbdp + n, 0.0);
|
||||
}
|
||||
std::fill(output_dbdr, output_dbdr + n, 0.0);
|
||||
|
||||
}
|
||||
|
||||
virtual void rbub(const int n,
|
||||
const double* /*p*/,
|
||||
double* output_rbub,
|
||||
double* output_drbubdp) const
|
||||
|
||||
{
|
||||
std::fill(output_rbub, output_rbub + n, 0.0);
|
||||
std::fill(output_drbubdp, output_drbubdp + n, 0.0);
|
||||
}
|
||||
|
||||
virtual void R(const int n,
|
||||
const double* /*p*/,
|
||||
const double* /*z*/,
|
||||
|
||||
@@ -44,14 +44,14 @@ namespace Opm
|
||||
// Copy data
|
||||
const int sz = pvd_table[region_number][0].size();
|
||||
std::vector<double> press(sz);
|
||||
std::vector<double> B_inv(sz);
|
||||
std::vector<double> b(sz);
|
||||
std::vector<double> visc(sz);
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
press[i] = pvd_table[region_number][0][i];
|
||||
B_inv[i] = 1.0 / pvd_table[region_number][1][i];
|
||||
b[i] = 1.0 / pvd_table[region_number][1][i];
|
||||
visc[i] = pvd_table[region_number][2][i];
|
||||
}
|
||||
one_over_B_ = NonuniformTableLinear<double>(press, B_inv);
|
||||
b_ = NonuniformTableLinear<double>(press, b);
|
||||
viscosity_ = NonuniformTableLinear<double>(press, visc);
|
||||
|
||||
// Dumping the created tables.
|
||||
@@ -80,14 +80,31 @@ namespace Opm
|
||||
}
|
||||
}
|
||||
|
||||
void SinglePvtDead::mu(const int n,
|
||||
const double* p,
|
||||
const double* /*r*/,
|
||||
double* output_mu,
|
||||
double* output_dmudp,
|
||||
double* output_dmudr) const
|
||||
{
|
||||
// #pragma omp parallel for
|
||||
for (int i = 0; i < n; ++i) {
|
||||
output_mu[i] = viscosity_(p[i]);
|
||||
output_dmudp[i] = viscosity_.derivative(p[i]);
|
||||
}
|
||||
std::fill(output_dmudr, output_dmudr + n, 0.0);
|
||||
|
||||
}
|
||||
|
||||
void SinglePvtDead::B(const int n,
|
||||
const double* p,
|
||||
const double* /*z*/,
|
||||
double* output_B) const
|
||||
{
|
||||
// #pragma omp parallel for
|
||||
// B = 1/b
|
||||
for (int i = 0; i < n; ++i) {
|
||||
output_B[i] = 1.0/one_over_B_(p[i]);
|
||||
output_B[i] = 1.0/b_(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,10 +118,36 @@ namespace Opm
|
||||
// #pragma omp parallel for
|
||||
for (int i = 0; i < n; ++i) {
|
||||
double Bg = output_B[i];
|
||||
output_dBdp[i] = -Bg*Bg*one_over_B_.derivative(p[i]);
|
||||
output_dBdp[i] = -Bg*Bg*b_.derivative(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SinglePvtDead::b(const int n,
|
||||
const double* p,
|
||||
const double* /*r*/,
|
||||
double* output_b,
|
||||
double* output_dbdp,
|
||||
double* output_dbdr) const
|
||||
|
||||
{
|
||||
// #pragma omp parallel for
|
||||
for (int i = 0; i < n; ++i) {
|
||||
output_b[i] = b_(p[i]);
|
||||
output_dbdp[i] = b_.derivative(p[i]);
|
||||
|
||||
}
|
||||
std::fill(output_dbdr, output_dbdr + n, 0.0);
|
||||
|
||||
}
|
||||
|
||||
void SinglePvtDead::rbub(const int n,
|
||||
const double* /*p*/,
|
||||
double* output_rbub,
|
||||
double* output_drbubdp) const
|
||||
{
|
||||
std::fill(output_rbub, output_rbub + n, 0.0);
|
||||
std::fill(output_drbubdp, output_drbubdp + n, 0.0);
|
||||
}
|
||||
|
||||
void SinglePvtDead::R(const int n,
|
||||
const double* /*p*/,
|
||||
|
||||
@@ -29,8 +29,10 @@ namespace Opm
|
||||
{
|
||||
|
||||
/// Class for immiscible dead oil and dry gas.
|
||||
/// For all the virtual methods, the following apply: p and z
|
||||
/// are expected to be of size n and n*num_phases, respectively.
|
||||
/// The PVT properties can either be given as a function of pressure (p) and surface volume (z)
|
||||
/// or pressure (p) and gas resolution factor (r).
|
||||
/// For all the virtual methods, the following apply: p, r and z
|
||||
/// are expected to be of size n, size n and n*num_phases, respectively.
|
||||
/// Output arrays shall be of size n, and must be valid before
|
||||
/// calling the method.
|
||||
class SinglePvtDead : public SinglePvtInterface
|
||||
@@ -46,6 +48,14 @@ namespace Opm
|
||||
const double* z,
|
||||
double* output_mu) const;
|
||||
|
||||
/// Viscosity and its derivatives as a function of p and r.
|
||||
virtual void mu(const int n,
|
||||
const double* p,
|
||||
const double* r,
|
||||
double* output_mu,
|
||||
double* output_dmudp,
|
||||
double* output_dmudr) const;
|
||||
|
||||
/// Formation volume factor as a function of p and z.
|
||||
virtual void B(const int n,
|
||||
const double* p,
|
||||
@@ -59,6 +69,22 @@ namespace Opm
|
||||
double* output_B,
|
||||
double* output_dBdp) const;
|
||||
|
||||
/// The inverse of the formation volume factor b = 1 / B, and its derivatives as a function of p and r.
|
||||
virtual void b(const int n,
|
||||
const double* p,
|
||||
const double* r,
|
||||
double* output_b,
|
||||
double* output_dbdp,
|
||||
double* output_dbdr) const;
|
||||
|
||||
|
||||
|
||||
/// Gas resolution and its derivatives at bublepoint as a function of p.
|
||||
virtual void rbub(const int n,
|
||||
const double* p,
|
||||
double* output_rbub,
|
||||
double* output_drbubdp) const;
|
||||
|
||||
/// Solution factor as a function of p and z.
|
||||
virtual void R(const int n,
|
||||
const double* p,
|
||||
@@ -73,7 +99,7 @@ namespace Opm
|
||||
double* output_dRdp) const;
|
||||
private:
|
||||
// PVT properties of dry gas or dead oil
|
||||
NonuniformTableLinear<double> one_over_B_;
|
||||
NonuniformTableLinear<double> b_;
|
||||
NonuniformTableLinear<double> viscosity_;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,8 +42,10 @@ namespace Opm
|
||||
/// arbitrary two-phase and three-phase situations.
|
||||
void setPhaseConfiguration(const int num_phases, const int* phase_pos);
|
||||
|
||||
/// For all the virtual methods, the following apply: p and z
|
||||
/// are expected to be of size n and n*num_phases, respectively.
|
||||
/// The PVT properties can either be given as a function of pressure (p) and surface volume (z)
|
||||
/// or pressure (p) and gas resolution factor (r).
|
||||
/// For all the virtual methods, the following apply: p, r and z
|
||||
/// are expected to be of size n, size n and n*num_phases, respectively.
|
||||
/// Output arrays shall be of size n, and must be valid before
|
||||
/// calling the method.
|
||||
|
||||
@@ -53,6 +55,14 @@ namespace Opm
|
||||
const double* z,
|
||||
double* output_mu) const = 0;
|
||||
|
||||
/// Viscosity as a function of p and r.
|
||||
virtual void mu(const int n,
|
||||
const double* p,
|
||||
const double* r,
|
||||
double* output_mu,
|
||||
double* output_dmudp,
|
||||
double* output_dmudr) const = 0;
|
||||
|
||||
/// Formation volume factor as a function of p and z.
|
||||
virtual void B(const int n,
|
||||
const double* p,
|
||||
@@ -66,6 +76,21 @@ namespace Opm
|
||||
double* output_B,
|
||||
double* output_dBdp) const = 0;
|
||||
|
||||
/// The inverse of the volume factor b = 1 / B as a function of p and r.
|
||||
virtual void b(const int n,
|
||||
const double* p,
|
||||
const double* r,
|
||||
double* output_b,
|
||||
double* output_dbdp,
|
||||
double* output_dpdr) const = 0;
|
||||
|
||||
/// Gas resolution at bublepoint as a function of pressure
|
||||
virtual void rbub(const int n,
|
||||
const double* p,
|
||||
double* output_rbub,
|
||||
double* output_drbubdp) const = 0;
|
||||
|
||||
|
||||
/// Solution factor as a function of p and z.
|
||||
virtual void R(const int n,
|
||||
const double* p,
|
||||
@@ -78,6 +103,8 @@ namespace Opm
|
||||
const double* z,
|
||||
double* output_R,
|
||||
double* output_dRdp) const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
int num_phases_;
|
||||
int phase_pos_[MaxNumPhases];
|
||||
|
||||
112
tests/not-unit/test_newfluidinterface.cpp
Normal file
112
tests/not-unit/test_newfluidinterface.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include <opm/core/io/eclipse/EclipseGridParser.hpp>
|
||||
#include <opm/core/grid/GridManager.hpp>
|
||||
#include <opm/core/props/pvt/SinglePvtConstCompr.hpp>
|
||||
#include <opm/core/props/pvt/SinglePvtDead.hpp>
|
||||
#include <opm/core/props/phaseUsageFromDeck.hpp>
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
#include <opm/core/utility/Units.hpp>
|
||||
#include <opm/core/utility/ErrorMacros.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace Opm;
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
int main () {
|
||||
// read parameters from command-line
|
||||
const string filename = "../tests/SPE9small.DATA";
|
||||
cout << "Reading deck: " << filename << endl;
|
||||
const EclipseGridParser deck (filename);
|
||||
std::string mu_output = "mu_output";
|
||||
|
||||
PhaseUsage phase_usage_;
|
||||
|
||||
std::vector<std::tr1::shared_ptr<SinglePvtInterface> > props_;
|
||||
|
||||
phase_usage_ = phaseUsageFromDeck(deck);
|
||||
enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 };
|
||||
|
||||
int samples = 0;
|
||||
|
||||
std::fstream muos(mu_output.c_str(), std::fstream::out | std::fstream::trunc);
|
||||
if(!(muos.good())){
|
||||
std::cout << "Could not open"<< mu_output << std::endl;
|
||||
exit(3);
|
||||
}
|
||||
|
||||
// Set the properties.
|
||||
props_.resize(phase_usage_.num_phases);
|
||||
// Water PVT
|
||||
if (phase_usage_.phase_used[Aqua]) {
|
||||
if (deck.hasField("PVTW")) {
|
||||
props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(deck.getPVTW().pvtw_));
|
||||
} else {
|
||||
// Eclipse 100 default.
|
||||
props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(0.5*Opm::prefix::centi*Opm::unit::Poise));
|
||||
}
|
||||
}
|
||||
// Oil PVT
|
||||
if (phase_usage_.phase_used[Liquid]) {
|
||||
if (deck.hasField("PVDO")) {
|
||||
if (samples > 0) {
|
||||
//props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_, samples));
|
||||
} else {
|
||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_));
|
||||
}
|
||||
} else if (deck.hasField("PVTO")) {
|
||||
//props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_));
|
||||
} else if (deck.hasField("PVCDO")) {
|
||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtConstCompr(deck.getPVCDO().pvcdo_));
|
||||
} else {
|
||||
THROW("Input is missing PVDO or PVTO\n");
|
||||
}
|
||||
}
|
||||
// Gas PVT
|
||||
if (phase_usage_.phase_used[Vapour]) {
|
||||
if (deck.hasField("PVDG")) {
|
||||
if (samples > 0) {
|
||||
//props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_, samples));
|
||||
} else {
|
||||
props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_));
|
||||
}
|
||||
} else if (deck.hasField("PVTG")) {
|
||||
//props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_));
|
||||
} else {
|
||||
THROW("Input is missing PVDG or PVTG\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int n = 1;
|
||||
int np = 1; //phase_usage_.num_phases;
|
||||
double p[n];
|
||||
double r[n];
|
||||
double z[n];
|
||||
|
||||
double mu[n];
|
||||
double dmudp[n];
|
||||
double dmudr[n];
|
||||
double mu_new[n];
|
||||
|
||||
p[0] = 10000;
|
||||
|
||||
// not in use yet
|
||||
r[0] = 0;
|
||||
z[0] = 0;
|
||||
|
||||
|
||||
for (int phase = 0; phase < np; ++phase) {
|
||||
props_[phase]->mu(n, p, r, mu_new,dmudp,dmudr);
|
||||
props_[phase]->mu(n, z, r, mu);
|
||||
|
||||
}
|
||||
std::copy(mu,mu + np*n, std::ostream_iterator<double>(muos, " "));
|
||||
std::copy(mu_new,mu_new + np*n, std::ostream_iterator<double>(muos, " "));
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user