Merge pull request #652 from andlaus/table_improvements

adapt the the table related API changes of opm-parser
This commit is contained in:
Joakim Hove 2014-09-19 15:27:29 +02:00
commit cb3b1c18fe
24 changed files with 501 additions and 493 deletions

View File

@ -108,7 +108,7 @@ try
// check_well_controls = param.getDefault("check_well_controls", false); // check_well_controls = param.getDefault("check_well_controls", false);
// max_well_control_iterations = param.getDefault("max_well_control_iterations", 10); // max_well_control_iterations = param.getDefault("max_well_control_iterations", 10);
// Rock compressibility. // Rock compressibility.
rock_comp.reset(new RockCompressibility(deck)); rock_comp.reset(new RockCompressibility(deck, eclipseState));
// Gravity. // Gravity.
gravity[2] = deck->hasKeyword("NOGRAV") ? 0.0 : unit::gravity; gravity[2] = deck->hasKeyword("NOGRAV") ? 0.0 : unit::gravity;
// Init state variables (saturation and pressure). // Init state variables (saturation and pressure).

View File

@ -121,7 +121,7 @@ try
// check_well_controls = param.getDefault("check_well_controls", false); // check_well_controls = param.getDefault("check_well_controls", false);
// max_well_control_iterations = param.getDefault("max_well_control_iterations", 10); // max_well_control_iterations = param.getDefault("max_well_control_iterations", 10);
// Rock compressibility. // Rock compressibility.
rock_comp.reset(new RockCompressibility(deck)); rock_comp.reset(new RockCompressibility(deck, eclipseState));
// Gravity. // Gravity.
gravity[2] = deck->hasKeyword("NOGRAV") ? 0.0 : unit::gravity; gravity[2] = deck->hasKeyword("NOGRAV") ? 0.0 : unit::gravity;
// Init state variables (saturation and pressure). // Init state variables (saturation and pressure).

View File

@ -44,7 +44,7 @@ try
// Define rock and fluid properties // Define rock and fluid properties
IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid()); IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid());
RockCompressibility rock_comp(deck); RockCompressibility rock_comp(deck, eclipseState);
// Finally handle the wells // Finally handle the wells
WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability());

View File

@ -53,7 +53,7 @@ namespace Opm
if (init_rock){ if (init_rock){
rock_.init(eclState, number_of_cells, global_cell, cart_dims); rock_.init(eclState, number_of_cells, global_cell, cart_dims);
} }
pvt_.init(deck, /*numSamples=*/0); pvt_.init(deck, eclState, /*numSamples=*/0);
SaturationPropsFromDeck<SatFuncSimpleNonuniform>* ptr SaturationPropsFromDeck<SatFuncSimpleNonuniform>* ptr
= new SaturationPropsFromDeck<SatFuncSimpleNonuniform>(); = new SaturationPropsFromDeck<SatFuncSimpleNonuniform>();
satprops_.reset(ptr); satprops_.reset(ptr);
@ -86,7 +86,7 @@ namespace Opm
} }
const int pvt_samples = param.getDefault("pvt_tab_size", -1); const int pvt_samples = param.getDefault("pvt_tab_size", -1);
pvt_.init(deck, pvt_samples); pvt_.init(deck, eclState, pvt_samples);
// Unfortunate lack of pointer smartness here... // Unfortunate lack of pointer smartness here...
const int sat_samples = param.getDefault("sat_tab_size", -1); const int sat_samples = param.getDefault("sat_tab_size", -1);

View File

@ -31,9 +31,8 @@
#include <opm/core/utility/ErrorMacros.hpp> #include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/linearInterpolation.hpp> #include <opm/core/utility/linearInterpolation.hpp>
#include <opm/parser/eclipse/Utility/PvtwTable.hpp>
#include <opm/parser/eclipse/Utility/PvcdoTable.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
namespace Opm namespace Opm
{ {
@ -43,6 +42,7 @@ namespace Opm
} }
void BlackoilPvtProperties::init(Opm::DeckConstPtr deck, void BlackoilPvtProperties::init(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int numSamples) int numSamples)
{ {
phase_usage_ = phaseUsageFromDeck(deck); phase_usage_ = phaseUsageFromDeck(deck);
@ -83,19 +83,20 @@ namespace Opm
if (phase_usage_.phase_used[Liquid]) { if (phase_usage_.phase_used[Liquid]) {
// for oil, we support the "PVDO", "PVTO" and "PVCDO" // for oil, we support the "PVDO", "PVTO" and "PVCDO"
// keywords... // keywords...
if (deck->hasKeyword("PVDO")) { const auto &pvdoTables = eclipseState->getPvdoTables();
Opm::DeckKeywordConstPtr pvdoKeyword = deck->getKeyword("PVDO"); const auto &pvtoTables = eclipseState->getPvtoTables();
if (pvdoTables.size() > 0) {
if (numSamples > 0) { if (numSamples > 0) {
auto splinePvt = std::shared_ptr<PvtDeadSpline>(new PvtDeadSpline); auto splinePvt = std::shared_ptr<PvtDeadSpline>(new PvtDeadSpline);
splinePvt->initFromOil(pvdoKeyword, numSamples); splinePvt->initFromOil(pvdoTables, numSamples);
props_[phase_usage_.phase_pos[Liquid]] = splinePvt; props_[phase_usage_.phase_pos[Liquid]] = splinePvt;
} else { } else {
auto deadPvt = std::shared_ptr<PvtDead>(new PvtDead); auto deadPvt = std::shared_ptr<PvtDead>(new PvtDead);
deadPvt->initFromOil(pvdoKeyword); deadPvt->initFromOil(pvdoTables);
props_[phase_usage_.phase_pos[Liquid]] = deadPvt; props_[phase_usage_.phase_pos[Liquid]] = deadPvt;
} }
} else if (deck->hasKeyword("PVTO")) { } else if (pvtoTables.size() > 0) {
props_[phase_usage_.phase_pos[Liquid]].reset(new PvtLiveOil(deck->getKeyword("PVTO"))); props_[phase_usage_.phase_pos[Liquid]].reset(new PvtLiveOil(pvtoTables));
} else if (deck->hasKeyword("PVCDO")) { } else if (deck->hasKeyword("PVCDO")) {
std::shared_ptr<PvtConstCompr> pvcdo(new PvtConstCompr); std::shared_ptr<PvtConstCompr> pvcdo(new PvtConstCompr);
pvcdo->initFromOil(deck->getKeyword("PVCDO")); pvcdo->initFromOil(deck->getKeyword("PVCDO"));
@ -108,22 +109,22 @@ namespace Opm
// Gas PVT // Gas PVT
if (phase_usage_.phase_used[Vapour]) { if (phase_usage_.phase_used[Vapour]) {
// gas can be specified using the "PVDG" or "PVTG" keywords... // gas can be specified using the "PVDG" or "PVTG" keywords...
if (deck->hasKeyword("PVDG")) { const auto &pvdgTables = eclipseState->getPvdgTables();
Opm::DeckKeywordConstPtr pvdgKeyword = deck->getKeyword("PVDG"); const auto &pvtgTables = eclipseState->getPvtgTables();
if (pvdgTables.size() > 0) {
if (numSamples > 0) { if (numSamples > 0) {
std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline); std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline);
splinePvt->initFromGas(pvdgKeyword, numSamples); splinePvt->initFromGas(pvdgTables, numSamples);
props_[phase_usage_.phase_pos[Vapour]] = splinePvt; props_[phase_usage_.phase_pos[Vapour]] = splinePvt;
} else { } else {
std::shared_ptr<PvtDead> deadPvt(new PvtDead); std::shared_ptr<PvtDead> deadPvt(new PvtDead);
deadPvt->initFromGas(pvdgKeyword); deadPvt->initFromGas(pvdgTables);
props_[phase_usage_.phase_pos[Vapour]] = deadPvt; props_[phase_usage_.phase_pos[Vapour]] = deadPvt;
} }
} else if (deck->hasKeyword("PVTG")) { } else if (pvtgTables.size() > 0) {
props_[phase_usage_.phase_pos[Vapour]].reset(new PvtLiveGas(deck->getKeyword("PVTG"))); props_[phase_usage_.phase_pos[Vapour]].reset(new PvtLiveGas(pvtgTables));
} else { } else {
OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n"); OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n");
} }

View File

@ -24,7 +24,7 @@
#include <opm/core/props/BlackoilPhases.hpp> #include <opm/core/props/BlackoilPhases.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Utility/PvtoTable.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <string> #include <string>
#include <memory> #include <memory>
@ -54,6 +54,7 @@ namespace Opm
/// ///
/// \param deck An input deck from the opm-parser module. /// \param deck An input deck from the opm-parser module.
void init(Opm::DeckConstPtr deck, void init(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int samples); int samples);
/// \return Object describing the active phases. /// \return Object describing the active phases.

View File

@ -23,9 +23,6 @@
#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/Utility/PvtwTable.hpp>
#include <opm/parser/eclipse/Utility/PvcdoTable.hpp>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>

View File

@ -34,16 +34,17 @@ namespace Opm
// Member functions // Member functions
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/// Constructor /// Constructor
void PvtDead::initFromOil(Opm::DeckKeywordConstPtr pvdoKeyword) void PvtDead::initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables)
{ {
int numRegions = Opm::PvdoTable::numTables(pvdoKeyword); int numRegions = pvdoTables.size();
// resize the attributes of the object // resize the attributes of the object
b_.resize(numRegions); b_.resize(numRegions);
viscosity_.resize(numRegions); viscosity_.resize(numRegions);
for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
Opm::PvdoTable pvdoTable(pvdoKeyword, regionIdx); const Opm::PvdoTable& pvdoTable = pvdoTables[regionIdx];
// Copy data // Copy data
const std::vector<double>& press = pvdoTable.getPressureColumn(); const std::vector<double>& press = pvdoTable.getPressureColumn();
const std::vector<double>& b = pvdoTable.getFormationFactorColumn(); const std::vector<double>& b = pvdoTable.getFormationFactorColumn();
@ -60,16 +61,16 @@ namespace Opm
} }
void PvtDead::initFromGas(Opm::DeckKeywordConstPtr pvdgKeyword) void PvtDead::initFromGas(const std::vector<Opm::PvdgTable>& pvdgTables)
{ {
int numRegions = Opm::PvdgTable::numTables(pvdgKeyword); int numRegions = pvdgTables.size();
// resize the attributes of the object // resize the attributes of the object
b_.resize(numRegions); b_.resize(numRegions);
viscosity_.resize(numRegions); viscosity_.resize(numRegions);
for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
Opm::PvdgTable pvdgTable(pvdgKeyword, regionIdx); const Opm::PvdgTable& pvdgTable = pvdgTables[regionIdx];
// Copy data // Copy data
const std::vector<double>& press = pvdgTable.getPressureColumn(); const std::vector<double>& press = pvdgTable.getPressureColumn();

View File

@ -20,12 +20,10 @@
#ifndef OPM_PVTDEAD_HEADER_INCLUDED #ifndef OPM_PVTDEAD_HEADER_INCLUDED
#define OPM_PVTDEAD_HEADER_INCLUDED #define OPM_PVTDEAD_HEADER_INCLUDED
#include <opm/core/props/pvt/PvtInterface.hpp> #include <opm/core/props/pvt/PvtInterface.hpp>
#include <opm/core/utility/NonuniformTableLinear.hpp> #include <opm/core/utility/NonuniformTableLinear.hpp>
#include <opm/parser/eclipse/Utility/PvdoTable.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/Utility/PvdgTable.hpp>
#include <vector> #include <vector>
@ -48,8 +46,8 @@ namespace Opm
public: public:
PvtDead() {}; PvtDead() {};
void initFromOil(Opm::DeckKeywordConstPtr pvdoKeyword); void initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables);
void initFromGas(Opm::DeckKeywordConstPtr pvdgKeyword); void initFromGas(const std::vector<Opm::PvdgTable>& pvdgTables);
virtual ~PvtDead(); virtual ~PvtDead();
/// Viscosity as a function of p and z. /// Viscosity as a function of p and z.

View File

@ -21,7 +21,6 @@
#include <opm/core/props/pvt/PvtDeadSpline.hpp> #include <opm/core/props/pvt/PvtDeadSpline.hpp>
#include <opm/core/utility/buildUniformMonotoneTable.hpp> #include <opm/core/utility/buildUniformMonotoneTable.hpp>
#include <opm/parser/eclipse/Utility/SingleRecordTable.hpp>
#include <algorithm> #include <algorithm>
@ -39,17 +38,17 @@ namespace Opm
PvtDeadSpline::PvtDeadSpline() PvtDeadSpline::PvtDeadSpline()
{} {}
void PvtDeadSpline::initFromOil(Opm::DeckKeywordConstPtr pvdoKeyword, void PvtDeadSpline::initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables,
int numSamples) int numSamples)
{ {
int numRegions = Opm::PvdoTable::numTables(pvdoKeyword); int numRegions = pvdoTables.size();
// resize the attributes of the object // resize the attributes of the object
b_.resize(numRegions); b_.resize(numRegions);
viscosity_.resize(numRegions); viscosity_.resize(numRegions);
for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
Opm::PvdoTable pvdoTable(pvdoKeyword, regionIdx); const Opm::PvdoTable& pvdoTable = pvdoTables[regionIdx];
int numRows = pvdoTable.numRows(); int numRows = pvdoTable.numRows();
@ -68,17 +67,17 @@ namespace Opm
} }
} }
void PvtDeadSpline::initFromGas(Opm::DeckKeywordConstPtr pvdgKeyword, void PvtDeadSpline::initFromGas(const std::vector<Opm::PvdgTable>& pvdgTables,
int numSamples) int numSamples)
{ {
int numRegions = Opm::PvdgTable::numTables(pvdgKeyword); int numRegions = pvdgTables.size();
// resize the attributes of the object // resize the attributes of the object
b_.resize(numRegions); b_.resize(numRegions);
viscosity_.resize(numRegions); viscosity_.resize(numRegions);
for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
Opm::PvdgTable pvdgTable(pvdgKeyword, regionIdx); const Opm::PvdgTable& pvdgTable = pvdgTables[regionIdx];
int numRows = pvdgTable.numRows(); int numRows = pvdgTable.numRows();

View File

@ -23,8 +23,7 @@
#include <opm/core/props/pvt/PvtInterface.hpp> #include <opm/core/props/pvt/PvtInterface.hpp>
#include <opm/core/utility/UniformTableLinear.hpp> #include <opm/core/utility/UniformTableLinear.hpp>
#include <opm/parser/eclipse/Utility/PvdoTable.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/Utility/PvdgTable.hpp>
#include <vector> #include <vector>
@ -43,9 +42,9 @@ namespace Opm
public: public:
PvtDeadSpline(); PvtDeadSpline();
void initFromOil(Opm::DeckKeywordConstPtr pvdoKeyword, void initFromOil(const std::vector<Opm::PvdoTable>& pvdoTables,
int numSamples); int numSamples);
void initFromGas(Opm::DeckKeywordConstPtr pvdgKeyword, void initFromGas(const std::vector<Opm::PvdgTable>& pvdgTables,
int numSamples); int numSamples);
virtual ~PvtDeadSpline(); virtual ~PvtDeadSpline();

View File

@ -46,14 +46,14 @@ namespace Opm
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Member functions // Member functions
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PvtLiveGas::PvtLiveGas(Opm::DeckKeywordConstPtr pvtgKeyword) PvtLiveGas::PvtLiveGas(const std::vector<Opm::PvtgTable>& pvtgTables)
{ {
int numTables = Opm::PvtgTable::numTables(pvtgKeyword); int numTables = pvtgTables.size();
saturated_gas_table_.resize(numTables); saturated_gas_table_.resize(numTables);
undersat_gas_tables_.resize(numTables); undersat_gas_tables_.resize(numTables);
for (int pvtTableIdx = 0; pvtTableIdx < numTables; ++pvtTableIdx) { for (int pvtTableIdx = 0; pvtTableIdx < numTables; ++pvtTableIdx) {
Opm::PvtgTable pvtgTable(pvtgKeyword, pvtTableIdx); const Opm::PvtgTable& pvtgTable = pvtgTables[pvtTableIdx];
// GAS, PVTG // GAS, PVTG
saturated_gas_table_[pvtTableIdx].resize(4); saturated_gas_table_[pvtTableIdx].resize(4);

View File

@ -22,7 +22,7 @@
#include <opm/core/props/pvt/PvtInterface.hpp> #include <opm/core/props/pvt/PvtInterface.hpp>
#include <opm/parser/eclipse/Utility/PvtgTable.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <vector> #include <vector>
@ -38,7 +38,7 @@ namespace Opm
class PvtLiveGas : public PvtInterface class PvtLiveGas : public PvtInterface
{ {
public: public:
PvtLiveGas(Opm::DeckKeywordConstPtr pvtgKeyword); PvtLiveGas(const std::vector<Opm::PvtgTable>& pvtgTables);
virtual ~PvtLiveGas(); virtual ~PvtLiveGas();
/// Viscosity as a function of p and z. /// Viscosity as a function of p and z.

View File

@ -34,14 +34,14 @@ namespace Opm
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Member functions // Member functions
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PvtLiveOil::PvtLiveOil(Opm::DeckKeywordConstPtr pvtoKeyword) PvtLiveOil::PvtLiveOil(const std::vector<Opm::PvtoTable>& pvtoTables)
{ {
int numTables = Opm::PvtoTable::numTables(pvtoKeyword); int numTables = pvtoTables.size();
saturated_oil_table_.resize(numTables); saturated_oil_table_.resize(numTables);
undersat_oil_tables_.resize(numTables); undersat_oil_tables_.resize(numTables);
for (int pvtTableIdx = 0; pvtTableIdx < numTables; ++pvtTableIdx) { for (int pvtTableIdx = 0; pvtTableIdx < numTables; ++pvtTableIdx) {
Opm::PvtoTable pvtoTable(pvtoKeyword, pvtTableIdx); Opm::PvtoTable pvtoTable = pvtoTables[pvtTableIdx];
const auto saturatedPvto = pvtoTable.getOuterTable(); const auto saturatedPvto = pvtoTable.getOuterTable();

View File

@ -23,7 +23,7 @@
#include <opm/core/props/pvt/PvtInterface.hpp> #include <opm/core/props/pvt/PvtInterface.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Utility/PvtoTable.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <vector> #include <vector>
@ -39,7 +39,7 @@ namespace Opm
class PvtLiveOil : public PvtInterface class PvtLiveOil : public PvtInterface
{ {
public: public:
PvtLiveOil(Opm::DeckKeywordConstPtr pvtoKeyword); PvtLiveOil(const std::vector<Opm::PvtoTable>& pvtoTables);
virtual ~PvtLiveOil(); virtual ~PvtLiveOil();
/// Viscosity as a function of p and z. /// Viscosity as a function of p and z.

View File

@ -24,8 +24,6 @@
#include <opm/core/utility/ErrorMacros.hpp> #include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/linearInterpolation.hpp> #include <opm/core/utility/linearInterpolation.hpp>
#include <opm/parser/eclipse/Utility/RocktabTable.hpp>
#include <opm/parser/eclipse/Utility/RockTable.hpp>
#include <iostream> #include <iostream>
@ -40,39 +38,30 @@ namespace Opm
rock_comp_ = param.getDefault("rock_compressibility", 0.0)/unit::barsa; rock_comp_ = param.getDefault("rock_compressibility", 0.0)/unit::barsa;
} }
RockCompressibility::RockCompressibility(Opm::DeckConstPtr deck) RockCompressibility::RockCompressibility(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState)
: pref_(0.0), : pref_(0.0),
rock_comp_(0.0) rock_comp_(0.0)
{ {
if (deck->hasKeyword("ROCKTAB")) { const auto& rocktabTables = eclipseState->getRocktabTables();
Opm::DeckKeywordConstPtr rtKeyword = deck->getKeyword("ROCKTAB"); if (rocktabTables.size() > 0) {
if (rtKeyword->size() != 1) if (rocktabTables.size() != 1)
OPM_THROW(std::runtime_error, "Can only handle a single region in ROCKTAB."); OPM_THROW(std::runtime_error, "Can only handle a single region in ROCKTAB.");
// the number of colums of the "ROCKTAB" keyword p_ = rocktabTables[0].getPressureColumn();
// depends on the presence of the "RKTRMDIR" poromult_ = rocktabTables[0].getPoreVolumeMultiplierColumn();
// keyword. Messy stuff... transmult_ = rocktabTables[0].getTransmissibilityMultiplierColumn();
bool isDirectional = deck->hasKeyword("RKTRMDIR");
if (isDirectional)
{
// well, okay. we don't support non-isotropic
// transmissibility multipliers yet
OPM_THROW(std::runtime_error, "Support for non-isotropic "
"transmissibility multipliers is not implemented yet.");
};
Opm::RocktabTable rocktabTable(rtKeyword, isDirectional);
p_ = rocktabTable.getPressureColumn();
poromult_ = rocktabTable.getPoreVolumeMultiplierColumn();
transmult_ = rocktabTable.getTransmissibilityMultiplierColumn();
} else if (deck->hasKeyword("ROCK")) { } else if (deck->hasKeyword("ROCK")) {
Opm::RockTable rockTable(deck->getKeyword("ROCK")); Opm::DeckKeywordConstPtr rockKeyword = deck->getKeyword("ROCK");
if (rockTable.numRows() != 1) if (rockKeyword->size() != 1) {
OPM_THROW(std::runtime_error, "Can only handle a single region in ROCK."); // here it would be better not to use std::cout directly but to add the
// warning to some "warning list"...
std::cout << "Can only handle a single region in ROCK ("<<rockKeyword->size()<<" regions specified)."
<< " Ignoring all except for the first.\n";
}
pref_ = rockTable.getPressureColumn()[0]; pref_ = rockKeyword->getRecord(0)->getItem("PREF")->getSIDouble(0);
rock_comp_ = rockTable.getCompressibilityColumn()[0]; rock_comp_ = rockKeyword->getRecord(0)->getItem("COMPRESSIBILITY")->getSIDouble(0);
} else { } else {
std::cout << "**** warning: no rock compressibility data found in deck (ROCK or ROCKTAB)." << std::endl; std::cout << "**** warning: no rock compressibility data found in deck (ROCK or ROCKTAB)." << std::endl;
} }

View File

@ -21,6 +21,7 @@
#define OPM_ROCKCOMPRESSIBILITY_HEADER_INCLUDED #define OPM_ROCKCOMPRESSIBILITY_HEADER_INCLUDED
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <vector> #include <vector>
@ -34,7 +35,8 @@ namespace Opm
public: public:
/// Construct from input deck. /// Construct from input deck.
/// Looks for the keywords ROCK and ROCKTAB. /// Looks for the keywords ROCK and ROCKTAB.
RockCompressibility(Opm::DeckConstPtr deck); RockCompressibility(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState);
/// Construct from parameters. /// Construct from parameters.
/// Accepts the following parameters (with defaults). /// Accepts the following parameters (with defaults).

View File

@ -1,321 +1,319 @@
/* /*
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
OPM is distributed in the hope that it will be useful, OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SATFUNCBASE_HPP #ifndef SATFUNCBASE_HPP
#define SATFUNCBASE_HPP #define SATFUNCBASE_HPP
#include <opm/core/utility/UniformTableLinear.hpp> #include <opm/core/utility/UniformTableLinear.hpp>
#include <opm/core/utility/buildUniformMonotoneTable.hpp> #include <opm/core/utility/buildUniformMonotoneTable.hpp>
#include <opm/core/utility/NonuniformTableLinear.hpp> #include <opm/core/utility/NonuniformTableLinear.hpp>
#include <opm/core/props/BlackoilPhases.hpp> #include <opm/core/props/BlackoilPhases.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/Utility/SwofTable.hpp>
#include <opm/parser/eclipse/Utility/SgofTable.hpp> #include <vector>
#include <vector> namespace Opm
{
namespace Opm // Transforms for saturation table scaling
{ struct EPSTransforms {
// Transforms for saturation table scaling struct Transform {
struct EPSTransforms { bool doNotScale;
struct Transform { bool do_3pt;
bool doNotScale; double smin;
bool do_3pt; double scr;
double smin; double sr;
double scr; double smax;
double sr; double slope1;
double smax; double slope2;
double slope1; double scaleSat(double ss, double s_r, double s_cr, double s_max) const;
double slope2; double scaleSatInv(double s, double s_r, double s_cr, double s_max) const;
double scaleSat(double ss, double s_r, double s_cr, double s_max) const; double scaleSatDeriv(double s, double s_r, double s_cr, double s_max) const; // Returns scaleSat'(s)
double scaleSatInv(double s, double s_r, double s_cr, double s_max) const; double scaleSatPc(double s, double s_min, double s_max) const;
double scaleSatDeriv(double s, double s_r, double s_cr, double s_max) const; // Returns scaleSat'(s) double scaleSatDerivPc(double s, double s_min, double s_max) const; // Returns scaleSatPc'(s)
double scaleSatPc(double s, double s_min, double s_max) const; bool doKrMax;
double scaleSatDerivPc(double s, double s_min, double s_max) const; // Returns scaleSatPc'(s) bool doKrCrit;
bool doKrMax; bool doSatInterp;
bool doKrCrit; double krsr;
bool doSatInterp; double krmax;
double krsr; double krSlopeMax;
double krmax; double krSlopeCrit;
double krSlopeMax; double scaleKr(double s, double kr, double krsr_tab) const;
double krSlopeCrit; double scaleKrDeriv(double s, double krDeriv) const; // Returns scaleKr'(kr(scaleSat(s)))*kr'((scaleSat(s))
double scaleKr(double s, double kr, double krsr_tab) const; double pcFactor; // Scaling factor for capillary pressure.
double scaleKrDeriv(double s, double krDeriv) const; // Returns scaleKr'(kr(scaleSat(s)))*kr'((scaleSat(s)) void printMe(std::ostream & out);
double pcFactor; // Scaling factor for capillary pressure. };
void printMe(std::ostream & out);
}; Transform wat;
Transform watoil;
Transform wat; Transform gas;
Transform watoil; Transform gasoil;
Transform gas; };
Transform gasoil;
}; // Hysteresis
struct SatHyst {
// Hysteresis double sg_hyst;
struct SatHyst { double sg_shift;
double sg_hyst; double sow_hyst;
double sg_shift; double sow_shift;
double sow_hyst; void printMe(std::ostream & out);
double sow_shift; };
void printMe(std::ostream & out);
};
template <class TableType>
class SatFuncBase : public BlackoilPhases
template <class TableType> {
class SatFuncBase : public BlackoilPhases public:
{ void init(Opm::EclipseStateConstPtr eclipseState,
public: const int table_num,
void init(Opm::DeckConstPtr deck, const PhaseUsage phase_usg,
const int table_num, const int samples);
const PhaseUsage phase_usg, void updateSatHyst(const double* s,
const int samples); const EPSTransforms* epst,
void updateSatHyst(const double* s, const EPSTransforms* epst_hyst,
const EPSTransforms* epst, SatHyst* sat_hyst) const;
const EPSTransforms* epst_hyst, double smin_[PhaseUsage::MaxNumPhases];
SatHyst* sat_hyst) const; double smax_[PhaseUsage::MaxNumPhases];
double smin_[PhaseUsage::MaxNumPhases]; double krwmax_; // Max water relperm
double smax_[PhaseUsage::MaxNumPhases]; double krgmax_; // Max gas relperm
double krwmax_; // Max water relperm double kromax_; // Max oil relperm
double krgmax_; // Max gas relperm double swcr_; // Critical water saturation.
double kromax_; // Max oil relperm double sgcr_; // Critical gas saturation.
double swcr_; // Critical water saturation. double krwr_; // Water relperm at critical oil-in-water saturation.
double sgcr_; // Critical gas saturation. double krgr_; // Gas relperm at critical oil-in-gas saturation.
double krwr_; // Water relperm at critical oil-in-water saturation. double sowcr_; // Critical oil-in-water saturation.
double krgr_; // Gas relperm at critical oil-in-gas saturation. double sogcr_; // Critical oil-in-gas-and-connate-water saturation.
double sowcr_; // Critical oil-in-water saturation. double krorw_; // Oil relperm at critical water saturation.
double sogcr_; // Critical oil-in-gas-and-connate-water saturation. double krorg_; // Oil relperm at critical gas saturation.
double krorw_; // Oil relperm at critical water saturation. double pcwmax_; // Max oil-water capillary pressure.
double krorg_; // Oil relperm at critical gas saturation. double pcgmax_; // Max gas-oil capillary pressure.
double pcwmax_; // Max oil-water capillary pressure.
double pcgmax_; // Max gas-oil capillary pressure. protected:
PhaseUsage phase_usage; // A copy of the outer class' phase_usage_.
protected: TableType krw_;
PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. TableType krow_;
TableType krw_; TableType pcow_;
TableType krow_; TableType krg_;
TableType pcow_; TableType krog_;
TableType krg_; TableType pcog_;
TableType krog_; double krocw_; // = krow_(s_wc)
TableType pcog_;
double krocw_; // = krow_(s_wc) private:
void extendTable(const std::vector<double>& xv,
private: std::vector<double>& xv_ex,
void extendTable(const std::vector<double>& xv, double pm) const;
std::vector<double>& xv_ex, void initializeTableType(TableType& table,
double pm) const; const std::vector<double>& arg,
void initializeTableType(TableType& table, const std::vector<double>& value,
const std::vector<double>& arg, const int samples);
const std::vector<double>& value, };
const int samples);
}; template <class TableType>
void SatFuncBase<TableType>::init(Opm::EclipseStateConstPtr eclipseState,
template <class TableType> const int table_num,
void SatFuncBase<TableType>::init(Opm::DeckConstPtr deck, const PhaseUsage phase_usg,
const int table_num, const int samples)
const PhaseUsage phase_usg, {
const int samples) phase_usage = phase_usg;
{ double swco = 0.0;
phase_usage = phase_usg; double swmax = 1.0;
double swco = 0.0; if (phase_usage.phase_used[Aqua]) {
double swmax = 1.0; const Opm::SwofTable& swof(eclipseState->getSwofTables()[table_num]);
if (phase_usage.phase_used[Aqua]) { const std::vector<double>& sw = swof.getSwColumn();
Opm::SwofTable swof(deck->getKeyword("SWOF"), table_num); const std::vector<double>& krw = swof.getKrwColumn();
const std::vector<double>& sw = swof.getSwColumn(); const std::vector<double>& krow = swof.getKrowColumn();
const std::vector<double>& krw = swof.getKrwColumn(); const std::vector<double>& pcow = swof.getPcowColumn();
const std::vector<double>& krow = swof.getKrowColumn(); if (krw.front() != 0.0 || krow.back() != 0.0) {
const std::vector<double>& pcow = swof.getPcowColumn(); OPM_THROW(std::runtime_error, "Error SWOF data - non-zero krw(swco) and/or krow(1-sor)");
if (krw.front() != 0.0 || krow.back() != 0.0) { }
OPM_THROW(std::runtime_error, "Error SWOF data - non-zero krw(swco) and/or krow(1-sor)");
} // Extend the tables with constant values such that the
// derivatives at the endpoints are zero
// Extend the tables with constant values such that the int n = sw.size();
// derivatives at the endpoints are zero std::vector<double> sw_ex(n+2);
int n = sw.size(); std::vector<double> krw_ex(n+2);
std::vector<double> sw_ex(n+2); std::vector<double> krow_ex(n+2);
std::vector<double> krw_ex(n+2); std::vector<double> pcow_ex(n+2);
std::vector<double> krow_ex(n+2);
std::vector<double> pcow_ex(n+2); extendTable(sw,sw_ex,1);
extendTable(krw,krw_ex,0);
extendTable(sw,sw_ex,1); extendTable(krow,krow_ex,0);
extendTable(krw,krw_ex,0); extendTable(pcow,pcow_ex,0);
extendTable(krow,krow_ex,0);
extendTable(pcow,pcow_ex,0); initializeTableType(krw_,sw_ex, krw_ex, samples);
initializeTableType(krow_,sw_ex, krow_ex, samples);
initializeTableType(krw_,sw_ex, krw_ex, samples); initializeTableType(pcow_,sw_ex, pcow_ex, samples);
initializeTableType(krow_,sw_ex, krow_ex, samples);
initializeTableType(pcow_,sw_ex, pcow_ex, samples); krocw_ = krow[0]; // At connate water -> ecl. SWOF
swco = sw[0];
krocw_ = krow[0]; // At connate water -> ecl. SWOF smin_[phase_usage.phase_pos[Aqua]] = sw[0];
swco = sw[0]; swmax = sw.back();
smin_[phase_usage.phase_pos[Aqua]] = sw[0]; smax_[phase_usage.phase_pos[Aqua]] = sw.back();
swmax = sw.back();
smax_[phase_usage.phase_pos[Aqua]] = sw.back(); krwmax_ = krw.back();
kromax_ = krow.front();
krwmax_ = krw.back(); swcr_ = swmax;
kromax_ = krow.front(); sowcr_ = 1.0 - swco;
swcr_ = swmax; krwr_ = krw.back();
sowcr_ = 1.0 - swco; krorw_ = krow.front();
krwr_ = krw.back(); for (std::vector<double>::size_type i=1; i<sw.size(); ++i) {
krorw_ = krow.front(); if (krw[i]> 0.0) {
for (std::vector<double>::size_type i=1; i<sw.size(); ++i) { swcr_ = sw[i-1];
if (krw[i]> 0.0) { krorw_ = krow[i-1];
swcr_ = sw[i-1]; break;
krorw_ = krow[i-1]; }
break; }
} for (std::vector<double>::size_type i=sw.size()-1; i>=1; --i) {
} if (krow[i-1]> 0.0) {
for (std::vector<double>::size_type i=sw.size()-1; i>=1; --i) { sowcr_ = 1.0 - sw[i];
if (krow[i-1]> 0.0) { krwr_ = krw[i];
sowcr_ = 1.0 - sw[i]; break;
krwr_ = krw[i]; }
break; }
} pcwmax_ = pcow.front();
} }
pcwmax_ = pcow.front(); if (phase_usage.phase_used[Vapour]) {
} const Opm::SgofTable& sgof = eclipseState->getSgofTables()[table_num];
if (phase_usage.phase_used[Vapour]) { const std::vector<double>& sg = sgof.getSgColumn();
Opm::SgofTable sgof(deck->getKeyword("SGOF"), table_num); const std::vector<double>& krg = sgof.getKrgColumn();
const std::vector<double>& sg = sgof.getSgColumn(); const std::vector<double>& krog = sgof.getKrogColumn();
const std::vector<double>& krg = sgof.getKrgColumn(); const std::vector<double>& pcog = sgof.getPcogColumn();
const std::vector<double>& krog = sgof.getKrogColumn();
const std::vector<double>& pcog = sgof.getPcogColumn(); // Extend the tables with constant values such that the
// derivatives at the endpoints are zero
// Extend the tables with constant values such that the int n = sg.size();
// derivatives at the endpoints are zero std::vector<double> sg_ex(n+2);
int n = sg.size(); std::vector<double> krg_ex(n+2);
std::vector<double> sg_ex(n+2); std::vector<double> krog_ex(n+2);
std::vector<double> krg_ex(n+2); std::vector<double> pcog_ex(n+2);
std::vector<double> krog_ex(n+2);
std::vector<double> pcog_ex(n+2); extendTable(sg,sg_ex,1);
extendTable(krg,krg_ex,0);
extendTable(sg,sg_ex,1); extendTable(krog,krog_ex,0);
extendTable(krg,krg_ex,0); extendTable(pcog,pcog_ex,0);
extendTable(krog,krog_ex,0);
extendTable(pcog,pcog_ex,0); initializeTableType(krg_,sg_ex, krg_ex, samples);
initializeTableType(krog_,sg_ex, krog_ex, samples);
initializeTableType(krg_,sg_ex, krg_ex, samples); initializeTableType(pcog_,sg_ex, pcog_ex, samples);
initializeTableType(krog_,sg_ex, krog_ex, samples);
initializeTableType(pcog_,sg_ex, pcog_ex, samples); smin_[phase_usage.phase_pos[Vapour]] = sg[0];
if (std::fabs(sg.back() + swco - 1.0) > 1e-3) {
smin_[phase_usage.phase_pos[Vapour]] = sg[0]; OPM_THROW(std::runtime_error, "Gas maximum saturation in SGOF table = " << sg.back() <<
if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { ", should equal (1.0 - connate water sat) = " << (1.0 - swco));
OPM_THROW(std::runtime_error, "Gas maximum saturation in SGOF table = " << sg.back() << }
", should equal (1.0 - connate water sat) = " << (1.0 - swco)); smax_[phase_usage.phase_pos[Vapour]] = sg.back();
} smin_[phase_usage.phase_pos[Vapour]] = sg.front();
smax_[phase_usage.phase_pos[Vapour]] = sg.back(); krgmax_ = krg.back();
smin_[phase_usage.phase_pos[Vapour]] = sg.front();
krgmax_ = krg.back(); sgcr_ = sg.front();
sogcr_ = 1.0 - sg.back();
sgcr_ = sg.front(); krgr_ = krg.back();
sogcr_ = 1.0 - sg.back(); krorg_ = krg.front();
krgr_ = krg.back(); for (std::vector<double>::size_type i=1; i<sg.size(); ++i) {
krorg_ = krg.front(); if (krg[i]> 0.0) {
for (std::vector<double>::size_type i=1; i<sg.size(); ++i) { sgcr_ = sg[i-1];
if (krg[i]> 0.0) { krorg_ = krog[i-1];
sgcr_ = sg[i-1]; break;
krorg_ = krog[i-1]; }
break; }
} for (std::vector<double>::size_type i=sg.size()-1; i>=1; --i) {
} if (krog[i-1]> 0.0) {
for (std::vector<double>::size_type i=sg.size()-1; i>=1; --i) { sogcr_ = 1.0 - sg[i];
if (krog[i-1]> 0.0) { krgr_ = krg[i];
sogcr_ = 1.0 - sg[i]; break;
krgr_ = krg[i]; }
break; }
} pcgmax_ = pcog.back();
}
pcgmax_ = pcog.back(); }
} if (phase_usage.phase_used[Vapour] && phase_usage.phase_used[Aqua]) {
sowcr_ -= smin_[phase_usage.phase_pos[Vapour]];
if (phase_usage.phase_used[Vapour] && phase_usage.phase_used[Aqua]) { sogcr_ -= smin_[phase_usage.phase_pos[Aqua]];
sowcr_ -= smin_[phase_usage.phase_pos[Vapour]]; smin_[phase_usage.phase_pos[Liquid]] = 0.0;
sogcr_ -= smin_[phase_usage.phase_pos[Aqua]]; smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]]
smin_[phase_usage.phase_pos[Liquid]] = 0.0; - smin_[phase_usage.phase_pos[Vapour]]; // First entry in SGOF-table supposed to be zero anyway ...
smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]] } else if (phase_usage.phase_used[Aqua]) {
- smin_[phase_usage.phase_pos[Vapour]]; // First entry in SGOF-table supposed to be zero anyway ... smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Aqua]];
} else if (phase_usage.phase_used[Aqua]) { smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]];
smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Aqua]]; } else if (phase_usage.phase_used[Vapour]) {
smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]]; smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Vapour]];
} else if (phase_usage.phase_used[Vapour]) { smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Vapour]];
smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Vapour]]; }
smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Vapour]]; }
}
} template <class TableType>
void SatFuncBase<TableType>::updateSatHyst(const double* s,
template <class TableType> const EPSTransforms* epst,
void SatFuncBase<TableType>::updateSatHyst(const double* s, const EPSTransforms* epst_hyst,
const EPSTransforms* epst, SatHyst* sat_hyst) const
const EPSTransforms* epst_hyst, {
SatHyst* sat_hyst) const if (phase_usage.phase_used[Aqua] && phase_usage.phase_used[Vapour]) { //Water/Oil/Gas
{ int opos = phase_usage.phase_pos[BlackoilPhases::Liquid];
if (phase_usage.phase_used[Aqua] && phase_usage.phase_used[Vapour]) { //Water/Oil/Gas int gpos = phase_usage.phase_pos[BlackoilPhases::Vapour];
int opos = phase_usage.phase_pos[BlackoilPhases::Liquid]; int wpos = this->phase_usage.phase_pos[BlackoilPhases::Aqua];
int gpos = phase_usage.phase_pos[BlackoilPhases::Vapour]; if (s[opos] > sat_hyst->sow_hyst)
int wpos = this->phase_usage.phase_pos[BlackoilPhases::Aqua]; {
if (s[opos] > sat_hyst->sow_hyst) sat_hyst->sow_hyst = s[opos];
{ double _sow_hyst = epst->watoil.scaleSat(sat_hyst->sow_hyst, 1.0-swcr_-smin_[gpos], sowcr_, 1.0-smin_[wpos]-smin_[gpos]);
sat_hyst->sow_hyst = s[opos]; double sow_hyst_shifted = epst_hyst->watoil.scaleSatInv(_sow_hyst, 1.0-swcr_-smin_[gpos], sowcr_, 1.0-smin_[wpos]-smin_[gpos]);
double _sow_hyst = epst->watoil.scaleSat(sat_hyst->sow_hyst, 1.0-swcr_-smin_[gpos], sowcr_, 1.0-smin_[wpos]-smin_[gpos]); sat_hyst->sow_shift = sow_hyst_shifted - sat_hyst->sow_hyst;
double sow_hyst_shifted = epst_hyst->watoil.scaleSatInv(_sow_hyst, 1.0-swcr_-smin_[gpos], sowcr_, 1.0-smin_[wpos]-smin_[gpos]); }
sat_hyst->sow_shift = sow_hyst_shifted - sat_hyst->sow_hyst; if (s[gpos] > sat_hyst->sg_hyst)
} {
if (s[gpos] > sat_hyst->sg_hyst) sat_hyst->sg_hyst = s[gpos];
{ double _sg_hyst = epst->gas.scaleSat(sat_hyst->sg_hyst, 1.0-sogcr_-smin_[wpos], sgcr_, smax_[gpos]);
sat_hyst->sg_hyst = s[gpos]; double sg_hyst_shifted = epst_hyst->gas.scaleSatInv(_sg_hyst, 1.0-sogcr_-smin_[wpos], sgcr_, smax_[gpos]);
double _sg_hyst = epst->gas.scaleSat(sat_hyst->sg_hyst, 1.0-sogcr_-smin_[wpos], sgcr_, smax_[gpos]); sat_hyst->sg_shift = sg_hyst_shifted - sat_hyst->sg_hyst;
double sg_hyst_shifted = epst_hyst->gas.scaleSatInv(_sg_hyst, 1.0-sogcr_-smin_[wpos], sgcr_, smax_[gpos]); }
sat_hyst->sg_shift = sg_hyst_shifted - sat_hyst->sg_hyst; } else if (phase_usage.phase_used[Aqua]) { //Water/oil
} int opos = phase_usage.phase_pos[BlackoilPhases::Liquid];
} else if (phase_usage.phase_used[Aqua]) { //Water/oil int wpos = this->phase_usage.phase_pos[BlackoilPhases::Aqua];
int opos = phase_usage.phase_pos[BlackoilPhases::Liquid]; if (s[opos] > sat_hyst->sow_hyst)
int wpos = this->phase_usage.phase_pos[BlackoilPhases::Aqua]; {
if (s[opos] > sat_hyst->sow_hyst) sat_hyst->sow_hyst = s[opos];
{ double _sow_hyst = epst->watoil.scaleSat(sat_hyst->sow_hyst, 1.0-swcr_, sowcr_, 1.0-smin_[wpos]);
sat_hyst->sow_hyst = s[opos]; double sow_hyst_shifted = epst_hyst->watoil.scaleSatInv(_sow_hyst, 1.0-swcr_, sowcr_, 1.0-smin_[wpos]);
double _sow_hyst = epst->watoil.scaleSat(sat_hyst->sow_hyst, 1.0-swcr_, sowcr_, 1.0-smin_[wpos]); sat_hyst->sow_shift = sow_hyst_shifted - sat_hyst->sow_hyst;
double sow_hyst_shifted = epst_hyst->watoil.scaleSatInv(_sow_hyst, 1.0-swcr_, sowcr_, 1.0-smin_[wpos]); }
sat_hyst->sow_shift = sow_hyst_shifted - sat_hyst->sow_hyst; } else if (phase_usage.phase_used[Vapour]) {//Gas/Oil
} int gpos = phase_usage.phase_pos[BlackoilPhases::Vapour];
} else if (phase_usage.phase_used[Vapour]) {//Gas/Oil if (s[gpos] > sat_hyst->sg_hyst)
int gpos = phase_usage.phase_pos[BlackoilPhases::Vapour]; {
if (s[gpos] > sat_hyst->sg_hyst) sat_hyst->sg_hyst = s[gpos];
{ double _sg_hyst = epst->gas.scaleSat(sat_hyst->sg_hyst, 1.0-sogcr_, sgcr_, smax_[gpos]);
sat_hyst->sg_hyst = s[gpos]; double sg_hyst_shifted = epst_hyst->gas.scaleSatInv(_sg_hyst, 1.0-sogcr_, sgcr_, smax_[gpos]);
double _sg_hyst = epst->gas.scaleSat(sat_hyst->sg_hyst, 1.0-sogcr_, sgcr_, smax_[gpos]); sat_hyst->sg_shift = sg_hyst_shifted - sat_hyst->sg_hyst;
double sg_hyst_shifted = epst_hyst->gas.scaleSatInv(_sg_hyst, 1.0-sogcr_, sgcr_, smax_[gpos]); }
sat_hyst->sg_shift = sg_hyst_shifted - sat_hyst->sg_hyst; }
} }
}
} template <class TableType>
void SatFuncBase<TableType>::extendTable(const std::vector<double>& xv,
template <class TableType> std::vector<double>& xv_ex,
void SatFuncBase<TableType>::extendTable(const std::vector<double>& xv, double pm) const
std::vector<double>& xv_ex, {
double pm) const int n = xv.size();
{ xv_ex[0] = xv[0]-pm;
int n = xv.size(); xv_ex[n+1] = xv[n-1]+pm;
xv_ex[0] = xv[0]-pm; for (int i=0; i<n; i++)
xv_ex[n+1] = xv[n-1]+pm; {
for (int i=0; i<n; i++) xv_ex[i+1] = xv[i];
{ }
xv_ex[i+1] = xv[i]; }
}
} } // namespace Opm
#endif // SATFUNCBASE_HPP
} // namespace Opm
#endif // SATFUNCBASE_HPP

View File

@ -161,18 +161,21 @@ namespace Opm
const Funcs& funcForCell(const int cell) const; const Funcs& funcForCell(const int cell) const;
template<class T> template<class T>
void initEPS(Opm::DeckConstPtr deck, void initEPS(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int number_of_cells, int number_of_cells,
const int* global_cell, const int* global_cell,
const T& begin_cell_centroids, const T& begin_cell_centroids,
int dimensions); int dimensions);
template<class T> template<class T>
void initEPSHyst(Opm::DeckConstPtr deck, void initEPSHyst(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int number_of_cells, int number_of_cells,
const int* global_cell, const int* global_cell,
const T& begin_cell_centroids, const T& begin_cell_centroids,
int dimensions); int dimensions);
template<class T> template<class T>
void initEPSKey(Opm::DeckConstPtr deck, void initEPSKey(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int number_of_cells, int number_of_cells,
const int* global_cell, const int* global_cell,
const T& begin_cell_centroids, const T& begin_cell_centroids,

View File

@ -29,8 +29,6 @@
#include <opm/parser/eclipse/Utility/EndscaleWrapper.hpp> #include <opm/parser/eclipse/Utility/EndscaleWrapper.hpp>
#include <opm/parser/eclipse/Utility/ScalecrsWrapper.hpp> #include <opm/parser/eclipse/Utility/ScalecrsWrapper.hpp>
#include <opm/parser/eclipse/Utility/EnptvdTable.hpp>
#include <opm/parser/eclipse/Utility/EnkrvdTable.hpp>
#include <iostream> #include <iostream>
@ -63,7 +61,7 @@ namespace Opm
template <class SatFuncSet> template <class SatFuncSet>
template<class T> template<class T>
void SaturationPropsFromDeck<SatFuncSet>::init(Opm::DeckConstPtr deck, void SaturationPropsFromDeck<SatFuncSet>::init(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr /*eclState*/, Opm::EclipseStateConstPtr eclState,
int number_of_cells, int number_of_cells,
const int* global_cell, const int* global_cell,
const T& begin_cell_centroids, const T& begin_cell_centroids,
@ -130,7 +128,7 @@ namespace Opm
// Initialize tables. // Initialize tables.
satfuncset_.resize(num_tables); satfuncset_.resize(num_tables);
for (int table = 0; table < num_tables; ++table) { for (int table = 0; table < num_tables; ++table) {
satfuncset_[table].init(deck, table, phase_usage_, samples); satfuncset_[table].init(eclState, table, phase_usage_, samples);
} }
// Check EHYSTR status // Check EHYSTR status
@ -192,7 +190,7 @@ namespace Opm
// TODO: ENPTVD/ENKRVD: Too few tables gives a cryptical message from parser, // TODO: ENPTVD/ENKRVD: Too few tables gives a cryptical message from parser,
// superfluous tables are ignored by the parser without any warning ... // superfluous tables are ignored by the parser without any warning ...
initEPS(deck, number_of_cells, global_cell, begin_cell_centroids, initEPS(deck, eclState, number_of_cells, global_cell, begin_cell_centroids,
dimensions); dimensions);
if (do_hyst_) { if (do_hyst_) {
@ -233,7 +231,7 @@ namespace Opm
// to be a scaled version of the drainage curve (confer Norne model). // to be a scaled version of the drainage curve (confer Norne model).
} }
initEPSHyst(deck, number_of_cells, global_cell, begin_cell_centroids, initEPSHyst(deck, eclState, number_of_cells, global_cell, begin_cell_centroids,
dimensions); dimensions);
} }
} }
@ -460,6 +458,7 @@ namespace Opm
template <class SatFuncSet> template <class SatFuncSet>
template<class T> template<class T>
void SaturationPropsFromDeck<SatFuncSet>::initEPS(Opm::DeckConstPtr deck, void SaturationPropsFromDeck<SatFuncSet>::initEPS(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int number_of_cells, int number_of_cells,
const int* global_cell, const int* global_cell,
const T& begin_cell_centroid, const T& begin_cell_centroid,
@ -470,39 +469,39 @@ namespace Opm
std::vector<double> pcw, pcg; std::vector<double> pcw, pcg;
const std::vector<double> dummy; const std::vector<double> dummy;
// Initialize saturation scaling parameter // Initialize saturation scaling parameter
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SWL"), swl); std::string("SWL"), swl);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SWU"), swu); std::string("SWU"), swu);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SWCR"), swcr); std::string("SWCR"), swcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SGL"), sgl); std::string("SGL"), sgl);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SGU"), sgu); std::string("SGU"), sgu);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SGCR"), sgcr); std::string("SGCR"), sgcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SOWCR"), sowcr); std::string("SOWCR"), sowcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("SOGCR"), sogcr); std::string("SOGCR"), sogcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("KRW"), krw); std::string("KRW"), krw);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("KRG"), krg); std::string("KRG"), krg);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("KRO"), kro); std::string("KRO"), kro);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("KRWR"), krwr); std::string("KRWR"), krwr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("KRGR"), krgr); std::string("KRGR"), krgr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("KRORW"), krorw); std::string("KRORW"), krorw);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("KRORG"), krorg); std::string("KRORG"), krorg);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("PCW"), pcw); std::string("PCW"), pcw);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("PCG"), pcg); std::string("PCG"), pcg);
eps_transf_.resize(number_of_cells); eps_transf_.resize(number_of_cells);
@ -613,6 +612,7 @@ namespace Opm
template <class SatFuncSet> template <class SatFuncSet>
template<class T> template<class T>
void SaturationPropsFromDeck<SatFuncSet>::initEPSHyst(Opm::DeckConstPtr deck, void SaturationPropsFromDeck<SatFuncSet>::initEPSHyst(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int number_of_cells, int number_of_cells,
const int* global_cell, const int* global_cell,
const T& begin_cell_centroid, const T& begin_cell_centroid,
@ -623,39 +623,39 @@ namespace Opm
std::vector<double> ipcw, ipcg; std::vector<double> ipcw, ipcg;
const std::vector<double> dummy; const std::vector<double> dummy;
// Initialize hysteresis saturation scaling parameters // Initialize hysteresis saturation scaling parameters
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISWL"), iswl); std::string("ISWL"), iswl);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISWU"), iswu); std::string("ISWU"), iswu);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISWCR"), iswcr); std::string("ISWCR"), iswcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISGL"), isgl); std::string("ISGL"), isgl);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISGU"), isgu); std::string("ISGU"), isgu);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISGCR"), isgcr); std::string("ISGCR"), isgcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISOWCR"), isowcr); std::string("ISOWCR"), isowcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("ISOGCR"), isogcr); std::string("ISOGCR"), isogcr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IKRW"), ikrw); std::string("IKRW"), ikrw);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IKRG"), ikrg); std::string("IKRG"), ikrg);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IKRO"), ikro); std::string("IKRO"), ikro);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IKRWR"), ikrwr); std::string("IKRWR"), ikrwr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IKRGR"), ikrgr); std::string("IKRGR"), ikrgr);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IKRORW"), ikrorw); std::string("IKRORW"), ikrorw);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IKRORG"), ikrorg); std::string("IKRORG"), ikrorg);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IPCW"), ipcw); std::string("IPCW"), ipcw);
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions, initEPSKey(deck, eclipseState, number_of_cells, global_cell, begin_cell_centroid, dimensions,
std::string("IPCG"), ipcg); std::string("IPCG"), ipcg);
eps_transf_hyst_.resize(number_of_cells); eps_transf_hyst_.resize(number_of_cells);
@ -767,6 +767,7 @@ namespace Opm
template <class SatFuncSet> template <class SatFuncSet>
template<class T> template<class T>
void SaturationPropsFromDeck<SatFuncSet>::initEPSKey(Opm::DeckConstPtr deck, void SaturationPropsFromDeck<SatFuncSet>::initEPSKey(Opm::DeckConstPtr deck,
Opm::EclipseStateConstPtr eclipseState,
int number_of_cells, int number_of_cells,
const int* global_cell, const int* global_cell,
const T& begin_cell_centroid, const T& begin_cell_centroid,
@ -849,14 +850,15 @@ namespace Opm
OPM_THROW(std::runtime_error, " -- unknown keyword: '" << keyword << "'"); OPM_THROW(std::runtime_error, " -- unknown keyword: '" << keyword << "'");
} }
if (!useKeyword && itab > 0) { if (!useKeyword && itab > 0) {
int num_tables = deck->getKeyword("ENPTVD")->size(); const auto& enptvdTables = eclipseState->getEnptvdTables();
int num_tables = enptvdTables.size();
param_col.resize(num_tables); param_col.resize(num_tables);
depth_col.resize(num_tables); depth_col.resize(num_tables);
col_names.resize(9); col_names.resize(9);
for (int table_num=0; table_num<num_tables; ++table_num) { for (int table_num=0; table_num<num_tables; ++table_num) {
Opm::SingleRecordTable enptvd(deck->getKeyword("ENPTVD"), col_names, table_num); const auto& enptvdTable = enptvdTables[table_num];
depth_col[table_num] = enptvd.getColumn(0); // depth depth_col[table_num] = enptvdTable.getDepthColumn();
param_col[table_num] = enptvd.getColumn(itab); // itab=[1-8]: swl swcr swu sgl sgcr sgu sowcr sogcr param_col[table_num] = enptvdTable.getColumn(itab); // itab=[1-8]: swl swcr swu sgl sgcr sgu sowcr sogcr
} }
} }
} else if ((keyword[0] == 'K' && (useKeyword || hasENKRVD)) || (keyword[1] == 'K' && useKeyword) ) { } else if ((keyword[0] == 'K' && (useKeyword || hasENKRVD)) || (keyword[1] == 'K' && useKeyword) ) {
@ -913,14 +915,15 @@ namespace Opm
OPM_THROW(std::runtime_error, " -- unknown keyword: '" << keyword << "'"); OPM_THROW(std::runtime_error, " -- unknown keyword: '" << keyword << "'");
} }
if (!useKeyword && itab > 0) { if (!useKeyword && itab > 0) {
int num_tables = deck->getKeyword("ENKRVD")->size(); const auto& enkrvdTables = eclipseState->getEnkrvdTables();
int num_tables = enkrvdTables.size();
param_col.resize(num_tables); param_col.resize(num_tables);
depth_col.resize(num_tables); depth_col.resize(num_tables);
col_names.resize(8); col_names.resize(8);
for (int table_num=0; table_num<num_tables; ++table_num) { for (int table_num=0; table_num<num_tables; ++table_num) {
Opm::SingleRecordTable enkrvd(deck->getKeyword("ENKRVD"), col_names, table_num); const auto &enkrvdTable = enkrvdTables[table_num];
depth_col[table_num] = enkrvd.getColumn(0); // depth depth_col[table_num] = enkrvdTable.getDepthColumn();
param_col[table_num] = enkrvd.getColumn(itab); // itab=[1-7]: krw krg kro krwr krgr krorw krorg param_col[table_num] = enkrvdTable.getColumn(itab); // itab=[1-7]: krw krg kro krwr krgr krorw krorg
} }
} }
} else if (useKeyword && (keyword[0] == 'P' || keyword[1] == 'P') ) { } else if (useKeyword && (keyword[0] == 'P' || keyword[1] == 'P') ) {

View File

@ -27,7 +27,6 @@
#include <opm/core/utility/RegionMapping.hpp> #include <opm/core/utility/RegionMapping.hpp>
#include <opm/core/utility/Units.hpp> #include <opm/core/utility/Units.hpp>
#include <opm/parser/eclipse/Utility/EquilWrapper.hpp> #include <opm/parser/eclipse/Utility/EquilWrapper.hpp>
#include <opm/parser/eclipse/Utility/SingleRecordTable.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <array> #include <array>
@ -279,15 +278,15 @@ namespace Opm
// Create Rs functions. // Create Rs functions.
rs_func_.reserve(rec.size()); rs_func_.reserve(rec.size());
if (deck->hasKeyword("DISGAS")) { if (deck->hasKeyword("DISGAS")) {
const std::vector<RsvdTable>& rsvdTables = eclipseState->getRsvdTables();
for (size_t i = 0; i < rec.size(); ++i) { for (size_t i = 0; i < rec.size(); ++i) {
const int cell = *(eqlmap.cells(i).begin()); const int cell = *(eqlmap.cells(i).begin());
if (rec[i].live_oil_table_index > 0) { if (rec[i].live_oil_table_index > 0) {
if (deck->hasKeyword("RSVD") && if (rsvdTables.size() > 0 && size_t(rec[i].live_oil_table_index) <= rsvdTables.size()) {
size_t(rec[i].live_oil_table_index) <= deck->getKeyword("RSVD")->size()) { rs_func_.push_back(std::make_shared<Miscibility::RsVD>(props,
Opm::SingleRecordTable rsvd(deck->getKeyword("RSVD"),std::vector<std::string>{"vd", "rs"},rec[i].live_oil_table_index-1); cell,
std::vector<double> vd(rsvd.getColumn("vd")); rsvdTables[i].getDepthColumn(),
std::vector<double> rs(rsvd.getColumn("rs")); rsvdTables[i].getRsColumn()));
rs_func_.push_back(std::make_shared<Miscibility::RsVD>(props, cell, vd, rs));
} else { } else {
OPM_THROW(std::runtime_error, "Cannot initialise: RSVD table " << (rec[i].live_oil_table_index) << " not available."); OPM_THROW(std::runtime_error, "Cannot initialise: RSVD table " << (rec[i].live_oil_table_index) << " not available.");
} }
@ -310,15 +309,15 @@ namespace Opm
rv_func_.reserve(rec.size()); rv_func_.reserve(rec.size());
if (deck->hasKeyword("VAPOIL")) { if (deck->hasKeyword("VAPOIL")) {
const std::vector<RvvdTable>& rvvdTables = eclipseState->getRvvdTables();
for (size_t i = 0; i < rec.size(); ++i) { for (size_t i = 0; i < rec.size(); ++i) {
const int cell = *(eqlmap.cells(i).begin()); const int cell = *(eqlmap.cells(i).begin());
if (rec[i].wet_gas_table_index > 0) { if (rec[i].wet_gas_table_index > 0) {
if (deck->hasKeyword("RVVD") && if (rvvdTables.size() > 0 && size_t(rec[i].wet_gas_table_index) <= rvvdTables.size()) {
size_t(rec[i].wet_gas_table_index) <= deck->getKeyword("RVVD")->size()) { rv_func_.push_back(std::make_shared<Miscibility::RvVD>(props,
Opm::SingleRecordTable rvvd(deck->getKeyword("RVVD"),std::vector<std::string>{"vd", "rv"},rec[i].wet_gas_table_index-1); cell,
std::vector<double> vd(rvvd.getColumn("vd")); rvvdTables[i].getDepthColumn(),
std::vector<double> rv(rvvd.getColumn("rv")); rvvdTables[i].getRvColumn()));
rv_func_.push_back(std::make_shared<Miscibility::RvVD>(props, cell, vd, rv));
} else { } else {
OPM_THROW(std::runtime_error, "Cannot initialise: RVVD table " << (rec[i].wet_gas_table_index) << " not available."); OPM_THROW(std::runtime_error, "Cannot initialise: RVVD table " << (rec[i].wet_gas_table_index) << " not available.");
} }

View File

@ -1,20 +1,25 @@
RUNSPEC
TABDIMS TABDIMS
-- use the defaults of TABDIMS but the keyword must be present in the deck -- use the defaults of TABDIMS but the keyword must be present in the deck
-- for it to be usable -- for it to be usable
/ /
DIMENS
3 3 3 /
OIL OIL
GAS GAS
WATER WATER
FIELD FIELD
GRID
-- tests for the PVT functions need a grid because the OPM-API for the -- tests for the PVT functions need a grid because the OPM-API for the
-- PVT functions assumes the presence of compressed grid cells, -- PVT functions assumes the presence of compressed grid cells,
-- i.e. we need to be able to map from compressed to logical cartesian -- i.e. we need to be able to map from compressed to logical cartesian
-- cell indices to find out the PVT region of a cell -- cell indices to find out the PVT region of a cell
DIMENS
3 3 3 /
DXV DXV
1 2 3 / 1 2 3 /
DYV DYV
@ -22,6 +27,11 @@ DYV
DZV DZV
1 2 3 / 1 2 3 /
TOPS
9*123.456 /
PROPS
PVTO PVTO
-- Rs Pbub Bo Vo -- Rs Pbub Bo Vo
.0 14.7 1.0000 1.20 / .0 14.7 1.0000 1.20 /

View File

@ -11,13 +11,9 @@
#include <opm/core/utility/Units.hpp> #include <opm/core/utility/Units.hpp>
#include <opm/core/utility/ErrorMacros.hpp> #include <opm/core/utility/ErrorMacros.hpp>
#include <opm/parser/eclipse/Utility/PvtoTable.hpp>
#include <opm/parser/eclipse/Utility/PvtgTable.hpp>
#include <opm/parser/eclipse/Utility/PvtwTable.hpp>
#include <opm/parser/eclipse/Utility/PvdoTable.hpp>
#include <opm/parser/eclipse/Utility/PvcdoTable.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp> #include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#if HAVE_DYNAMIC_BOOST_TEST #if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK #define BOOST_TEST_DYN_LINK
@ -36,7 +32,7 @@ using namespace Opm;
using namespace std; using namespace std;
std::vector<std::shared_ptr<PvtInterface> > getProps(Opm::DeckConstPtr deck, PhaseUsage phase_usage_){ std::vector<std::shared_ptr<PvtInterface> > getProps(Opm::DeckConstPtr deck, Opm::EclipseStateConstPtr eclipseState, PhaseUsage phase_usage_){
enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 }; enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 };
int samples = 0; int samples = 0;
@ -59,19 +55,20 @@ std::vector<std::shared_ptr<PvtInterface> > getProps(Opm::DeckConstPtr deck, Pha
// Oil PVT // Oil PVT
if (phase_usage_.phase_used[Liquid]) { if (phase_usage_.phase_used[Liquid]) {
if (deck->hasKeyword("PVDO")) { const auto& pvdoTables = eclipseState->getPvdoTables();
Opm::DeckKeywordConstPtr pvdoKeyword(deck->getKeyword("PVDO")); const auto& pvtoTables = eclipseState->getPvtoTables();
if (!pvdoTables.empty()) {
if (samples > 0) { if (samples > 0) {
std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline); std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline);
splinePvt->initFromOil(pvdoKeyword, samples); splinePvt->initFromOil(pvdoTables, samples);
props_[phase_usage_.phase_pos[Liquid]] = splinePvt; props_[phase_usage_.phase_pos[Liquid]] = splinePvt;
} else { } else {
std::shared_ptr<PvtDead> deadPvt(new PvtDead); std::shared_ptr<PvtDead> deadPvt(new PvtDead);
deadPvt->initFromOil(pvdoKeyword); deadPvt->initFromOil(pvdoTables);
props_[phase_usage_.phase_pos[Liquid]] = deadPvt; props_[phase_usage_.phase_pos[Liquid]] = deadPvt;
} }
} else if (deck->hasKeyword("PVTO")) { } else if (!pvtoTables.empty()) {
props_[phase_usage_.phase_pos[Liquid]].reset(new PvtLiveOil(deck->getKeyword("PVTO"))); props_[phase_usage_.phase_pos[Liquid]].reset(new PvtLiveOil(pvtoTables));
} else if (deck->hasKeyword("PVCDO")) { } else if (deck->hasKeyword("PVCDO")) {
std::shared_ptr<PvtConstCompr> pvcdo(new PvtConstCompr); std::shared_ptr<PvtConstCompr> pvcdo(new PvtConstCompr);
pvcdo->initFromOil(deck->getKeyword("PVCDO")); pvcdo->initFromOil(deck->getKeyword("PVCDO"));
@ -83,19 +80,20 @@ std::vector<std::shared_ptr<PvtInterface> > getProps(Opm::DeckConstPtr deck, Pha
} }
// Gas PVT // Gas PVT
if (phase_usage_.phase_used[Vapour]) { if (phase_usage_.phase_used[Vapour]) {
if (deck->hasKeyword("PVDG")) { const auto& pvdgTables = eclipseState->getPvdgTables();
Opm::DeckKeywordConstPtr pvdgKeyword(deck->getKeyword("PVDG")); const auto& pvtgTables = eclipseState->getPvtgTables();
if (!pvdgTables.empty()) {
if (samples > 0) { if (samples > 0) {
std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline); std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline);
splinePvt->initFromGas(pvdgKeyword, samples); splinePvt->initFromGas(pvdgTables, samples);
props_[phase_usage_.phase_pos[Vapour]] = splinePvt; props_[phase_usage_.phase_pos[Vapour]] = splinePvt;
} else { } else {
std::shared_ptr<PvtDead> deadPvt(new PvtDead); std::shared_ptr<PvtDead> deadPvt(new PvtDead);
deadPvt->initFromGas(pvdgKeyword); deadPvt->initFromGas(pvdgTables);
props_[phase_usage_.phase_pos[Vapour]] = deadPvt; props_[phase_usage_.phase_pos[Vapour]] = deadPvt;
} }
} else if (deck->hasKeyword("PVTG")) { } else if (!pvtgTables.empty()) {
props_[phase_usage_.phase_pos[Vapour]].reset(new PvtLiveGas(deck->getKeyword("PVTG"))); props_[phase_usage_.phase_pos[Vapour]].reset(new PvtLiveGas(pvtgTables));
} else { } else {
OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n"); OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n");
} }
@ -236,12 +234,11 @@ BOOST_AUTO_TEST_CASE(test_liveoil)
cout << "Reading deck: " << filename << endl; cout << "Reading deck: " << filename << endl;
Opm::ParserPtr parser(new Opm::Parser()); Opm::ParserPtr parser(new Opm::Parser());
Opm::DeckConstPtr deck(parser->parseFile(filename)); Opm::DeckConstPtr deck(parser->parseFile(filename));
Opm::EclipseStateConstPtr eclipseState(new EclipseState(deck));
// setup pvt interface // setup pvt interface
PhaseUsage phase_usage_ = phaseUsageFromDeck(deck); PhaseUsage phase_usage_ = phaseUsageFromDeck(deck);
std::vector<std::shared_ptr<PvtInterface> > props_ = getProps(deck,phase_usage_); std::vector<std::shared_ptr<PvtInterface> > props_ = getProps(deck, eclipseState, phase_usage_);
// setup a test case. We will check 6 [p,r] pairs and compare them to both the [p,z] interface and a finite difference // setup a test case. We will check 6 [p,r] pairs and compare them to both the [p,z] interface and a finite difference
@ -314,10 +311,11 @@ BOOST_AUTO_TEST_CASE(test_wetgas)
cout << "Reading deck: " << filename << endl; cout << "Reading deck: " << filename << endl;
Opm::ParserPtr parser(new Opm::Parser()); Opm::ParserPtr parser(new Opm::Parser());
Opm::DeckConstPtr deck(parser->parseFile(filename)); Opm::DeckConstPtr deck(parser->parseFile(filename));
Opm::EclipseStateConstPtr eclipseState(new EclipseState(deck));
// setup pvt interface // setup pvt interface
PhaseUsage phase_usage_ = phaseUsageFromDeck(deck); PhaseUsage phase_usage_ = phaseUsageFromDeck(deck);
std::vector<std::shared_ptr<PvtInterface> > props_ = getProps(deck,phase_usage_); std::vector<std::shared_ptr<PvtInterface> > props_ = getProps(deck,eclipseState,phase_usage_);
// setup a test case. We will check 6 [p,r] pairs and compare them to both the [p,z] interface and a finite difference // setup a test case. We will check 6 [p,r] pairs and compare them to both the [p,z] interface and a finite difference

View File

@ -1,20 +1,25 @@
RUNSPEC
TABDIMS TABDIMS
-- use the defaults of TABDIMS but the keyword must be present in the deck -- use the defaults of TABDIMS but the keyword must be present in the deck
-- for it to be usable -- for it to be usable
/ /
DIMENS
3 3 3 /
WATER WATER
OIL OIL
GAS GAS
FIELD FIELD
GRID
-- tests for the PVT functions need a grid because the OPM-API for the -- tests for the PVT functions need a grid because the OPM-API for the
-- PVT functions assumes the presence of compressed grid cells, -- PVT functions assumes the presence of compressed grid cells,
-- i.e. we need to be able to map from compressed to logical cartesian -- i.e. we need to be able to map from compressed to logical cartesian
-- cell indices to find out the PVT region of a cell -- cell indices to find out the PVT region of a cell
DIMENS
3 3 3 /
DXV DXV
1 2 3 / 1 2 3 /
DYV DYV
@ -22,6 +27,11 @@ DYV
DZV DZV
1 2 3 / 1 2 3 /
TOPS
9*123.456 /
PROPS
-- PVT PROPERTIES OF DRY GAS (NO VAPOURISED OIL) -- PVT PROPERTIES OF DRY GAS (NO VAPOURISED OIL)
-- FROM SPE3 Blackoil Kleppe -- FROM SPE3 Blackoil Kleppe
-- --