mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #131 from andlaus/implement_multi-region_pvt_tables
implement multi-region PVT
This commit is contained in:
commit
c834177897
@ -66,9 +66,7 @@ struct HelperOps
|
|||||||
const int nc = numCells(grid);
|
const int nc = numCells(grid);
|
||||||
const int nf = numFaces(grid);
|
const int nf = numFaces(grid);
|
||||||
// Define some neighbourhood-derived helper arrays.
|
// Define some neighbourhood-derived helper arrays.
|
||||||
typedef Eigen::Array<bool, Eigen::Dynamic, 1> OneColBool;
|
|
||||||
typedef Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColInt;
|
typedef Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColInt;
|
||||||
typedef Eigen::Array<bool, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColBool;
|
|
||||||
TwoColInt nbi;
|
TwoColInt nbi;
|
||||||
extractInternalFaces(grid, internal_faces, nbi);
|
extractInternalFaces(grid, internal_faces, nbi);
|
||||||
int num_internal=internal_faces.size();
|
int num_internal=internal_faces.size();
|
||||||
|
@ -91,8 +91,10 @@ namespace Opm
|
|||||||
|
|
||||||
/// Densities of stock components at surface conditions.
|
/// Densities of stock components at surface conditions.
|
||||||
/// \return Array of 3 density values.
|
/// \return Array of 3 density values.
|
||||||
const double* BlackoilPropsAd::surfaceDensity() const
|
const double* BlackoilPropsAd::surfaceDensity(int regionIdx) const
|
||||||
{
|
{
|
||||||
|
// this class only supports a single PVT region for now...
|
||||||
|
assert(regionIdx == 0);
|
||||||
return props_.surfaceDensity();
|
return props_.surfaceDensity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ namespace Opm
|
|||||||
|
|
||||||
/// Densities of stock components at surface conditions.
|
/// Densities of stock components at surface conditions.
|
||||||
/// \return Array of 3 density values.
|
/// \return Array of 3 density values.
|
||||||
const double* surfaceDensity() const;
|
const double* surfaceDensity(int regionIdx = 0) const;
|
||||||
|
|
||||||
|
|
||||||
// ------ Viscosity ------
|
// ------ Viscosity ------
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
#include <opm/autodiff/AutoDiffHelpers.hpp>
|
#include <opm/autodiff/AutoDiffHelpers.hpp>
|
||||||
#include <opm/core/props/BlackoilPropertiesInterface.hpp>
|
#include <opm/core/props/BlackoilPropertiesInterface.hpp>
|
||||||
#include <opm/core/props/BlackoilPhases.hpp>
|
#include <opm/core/props/BlackoilPhases.hpp>
|
||||||
#include <opm/core/props/pvt/SinglePvtInterface.hpp>
|
#include <opm/core/props/pvt/PvtInterface.hpp>
|
||||||
#include <opm/core/props/pvt/SinglePvtConstCompr.hpp>
|
#include <opm/core/props/pvt/PvtConstCompr.hpp>
|
||||||
#include <opm/core/props/pvt/SinglePvtDead.hpp>
|
#include <opm/core/props/pvt/PvtDead.hpp>
|
||||||
#include <opm/core/props/pvt/SinglePvtDeadSpline.hpp>
|
#include <opm/core/props/pvt/PvtDeadSpline.hpp>
|
||||||
#include <opm/core/props/pvt/SinglePvtLiveOil.hpp>
|
#include <opm/core/props/pvt/PvtLiveOil.hpp>
|
||||||
#include <opm/core/props/pvt/SinglePvtLiveGas.hpp>
|
#include <opm/core/props/pvt/PvtLiveGas.hpp>
|
||||||
#include <opm/core/utility/ErrorMacros.hpp>
|
#include <opm/core/utility/ErrorMacros.hpp>
|
||||||
#include <opm/core/utility/Units.hpp>
|
#include <opm/core/utility/Units.hpp>
|
||||||
|
|
||||||
@ -80,79 +80,104 @@ namespace Opm
|
|||||||
int dimension,
|
int dimension,
|
||||||
const bool init_rock)
|
const bool init_rock)
|
||||||
{
|
{
|
||||||
|
// retrieve the cell specific PVT table index from the deck
|
||||||
|
// and using the grid...
|
||||||
|
extractPvtTableIndex(cellPvtRegionIdx_, deck, number_of_cells, global_cell);
|
||||||
|
|
||||||
if (init_rock){
|
if (init_rock){
|
||||||
rock_.init(deck, number_of_cells, global_cell, cart_dims);
|
rock_.init(deck, number_of_cells, global_cell, cart_dims);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int samples = 0;
|
|
||||||
const int region_number = 0;
|
|
||||||
|
|
||||||
phase_usage_ = phaseUsageFromDeck(deck);
|
phase_usage_ = phaseUsageFromDeck(deck);
|
||||||
|
|
||||||
// Surface densities. Accounting for different orders in eclipse and our code.
|
// Surface densities. Accounting for different orders in eclipse and our code.
|
||||||
if (deck->hasKeyword("DENSITY")) {
|
Opm::DeckKeywordConstPtr densityKeyword = deck->getKeyword("DENSITY");
|
||||||
const auto keyword = deck->getKeyword("DENSITY");
|
int numRegions = densityKeyword->size();
|
||||||
const auto record = keyword->getRecord(region_number);
|
|
||||||
enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 };
|
densities_.resize(numRegions);
|
||||||
|
for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
|
||||||
|
if (phase_usage_.phase_used[Liquid]) {
|
||||||
|
densities_[regionIdx][phase_usage_.phase_pos[Liquid]]
|
||||||
|
= densityKeyword->getRecord(regionIdx)->getItem("OIL")->getSIDouble(0);
|
||||||
|
}
|
||||||
if (phase_usage_.phase_used[Aqua]) {
|
if (phase_usage_.phase_used[Aqua]) {
|
||||||
densities_[phase_usage_.phase_pos[Aqua]] = record->getItem("WATER")->getSIDouble(0);
|
densities_[regionIdx][phase_usage_.phase_pos[Aqua]]
|
||||||
|
= densityKeyword->getRecord(regionIdx)->getItem("WATER")->getSIDouble(0);
|
||||||
}
|
}
|
||||||
if (phase_usage_.phase_used[Vapour]) {
|
if (phase_usage_.phase_used[Vapour]) {
|
||||||
densities_[phase_usage_.phase_pos[Vapour]] = record->getItem("GAS")->getSIDouble(0);
|
densities_[regionIdx][phase_usage_.phase_pos[Vapour]]
|
||||||
|
= densityKeyword->getRecord(regionIdx)->getItem("GAS")->getSIDouble(0);
|
||||||
}
|
}
|
||||||
if (phase_usage_.phase_used[Liquid]) {
|
|
||||||
densities_[phase_usage_.phase_pos[Liquid]] = record->getItem("OIL")->getSIDouble(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
OPM_THROW(std::runtime_error, "Input is missing DENSITY\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the properties.
|
// first, calculate the PVT table index for each compressed
|
||||||
|
// cell. This array is required to construct the PVT classes
|
||||||
|
// below.
|
||||||
|
Opm::extractPvtTableIndex(pvtTableIdx_,
|
||||||
|
deck,
|
||||||
|
number_of_cells,
|
||||||
|
global_cell);
|
||||||
|
|
||||||
|
const int numSamples = 0;
|
||||||
|
|
||||||
|
// Resize the property objects container
|
||||||
props_.resize(phase_usage_.num_phases);
|
props_.resize(phase_usage_.num_phases);
|
||||||
|
|
||||||
|
|
||||||
// Water PVT
|
// Water PVT
|
||||||
if (phase_usage_.phase_used[Aqua]) {
|
if (phase_usage_.phase_used[Aqua]) {
|
||||||
if (deck->hasKeyword("PVTW")) {
|
// if water is used, we require the presence of the "PVTW"
|
||||||
Opm::PvtwTable pvtwTable(deck->getKeyword("PVTW"), region_number);
|
// keyword for now...
|
||||||
props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(pvtwTable));
|
std::shared_ptr<PvtConstCompr> pvtw(new PvtConstCompr);
|
||||||
} else {
|
pvtw->initFromWater(deck->getKeyword("PVTW"));
|
||||||
// Eclipse 100 default.
|
|
||||||
props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(0.5*Opm::prefix::centi*Opm::unit::Poise));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
props_[phase_usage_.phase_pos[Aqua]] = pvtw;
|
||||||
|
}
|
||||||
// Oil PVT
|
// Oil PVT
|
||||||
if (phase_usage_.phase_used[Liquid]) {
|
if (phase_usage_.phase_used[Liquid]) {
|
||||||
|
// for oil, we support the "PVDO", "PVTO" and "PVCDO"
|
||||||
|
// keywords...
|
||||||
if (deck->hasKeyword("PVDO")) {
|
if (deck->hasKeyword("PVDO")) {
|
||||||
Opm::PvdoTable pvdoTable(deck->getKeyword("PVDO"), region_number);
|
Opm::DeckKeywordConstPtr pvdoKeyword = deck->getKeyword("PVDO");
|
||||||
if (samples > 0) {
|
if (numSamples > 0) {
|
||||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(pvdoTable, samples));
|
auto splinePvt = std::shared_ptr<PvtDeadSpline>(new PvtDeadSpline);
|
||||||
|
splinePvt->initFromOil(pvdoKeyword, numSamples);
|
||||||
|
props_[phase_usage_.phase_pos[Liquid]] = splinePvt;
|
||||||
} else {
|
} else {
|
||||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(pvdoTable));
|
auto deadPvt = std::shared_ptr<PvtDead>(new PvtDead);
|
||||||
|
deadPvt->initFromOil(pvdoKeyword);
|
||||||
|
props_[phase_usage_.phase_pos[Liquid]] = deadPvt;
|
||||||
}
|
}
|
||||||
}
|
} else if (deck->hasKeyword("PVTO")) {
|
||||||
else if (deck->hasKeyword("PVTO")) {
|
props_[phase_usage_.phase_pos[Liquid]].reset(new PvtLiveOil(deck->getKeyword("PVTO")));
|
||||||
Opm::PvtoTable pvtoTable(deck->getKeyword("PVTO"), /*tableIdx=*/0);
|
|
||||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(pvtoTable));
|
|
||||||
} else if (deck->hasKeyword("PVCDO")) {
|
} else if (deck->hasKeyword("PVCDO")) {
|
||||||
Opm::PvcdoTable pvdcoTable(deck->getKeyword("PVCDO"), region_number);
|
std::shared_ptr<PvtConstCompr> pvcdo(new PvtConstCompr);
|
||||||
props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtConstCompr(pvdcoTable));
|
pvcdo->initFromOil(deck->getKeyword("PVCDO"));
|
||||||
|
|
||||||
|
props_[phase_usage_.phase_pos[Liquid]] = pvcdo;
|
||||||
} else {
|
} else {
|
||||||
OPM_THROW(std::runtime_error, "Input is missing PVDO, PVTO or PVCDO\n");
|
OPM_THROW(std::runtime_error, "Input is missing PVDO, PVCDO or PVTO\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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...
|
||||||
if (deck->hasKeyword("PVDG")) {
|
if (deck->hasKeyword("PVDG")) {
|
||||||
Opm::PvdoTable pvdgTable(deck->getKeyword("PVDG"), region_number);
|
Opm::DeckKeywordConstPtr pvdgKeyword = deck->getKeyword("PVDG");
|
||||||
if (samples > 0) {
|
|
||||||
props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(pvdgTable, samples));
|
if (numSamples > 0) {
|
||||||
|
std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline);
|
||||||
|
splinePvt->initFromGas(pvdgKeyword, numSamples);
|
||||||
|
|
||||||
|
props_[phase_usage_.phase_pos[Vapour]] = splinePvt;
|
||||||
} else {
|
} else {
|
||||||
props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(pvdgTable));
|
std::shared_ptr<PvtDead> deadPvt(new PvtDead);
|
||||||
|
deadPvt->initFromGas(pvdgKeyword);
|
||||||
|
|
||||||
|
props_[phase_usage_.phase_pos[Vapour]] = deadPvt;
|
||||||
}
|
}
|
||||||
} else if (deck->hasKeyword("PVTG")) {
|
} else if (deck->hasKeyword("PVTG")) {
|
||||||
Opm::PvtgTable pvtgTable(deck->getKeyword("PVTG"), /*tableIdx=*/0);
|
props_[phase_usage_.phase_pos[Vapour]].reset(new PvtLiveGas(deck->getKeyword("PVTG")));
|
||||||
props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(pvtgTable));
|
|
||||||
} 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");
|
||||||
}
|
}
|
||||||
@ -221,9 +246,10 @@ namespace Opm
|
|||||||
|
|
||||||
/// Densities of stock components at surface conditions.
|
/// Densities of stock components at surface conditions.
|
||||||
/// \return Array of 3 density values.
|
/// \return Array of 3 density values.
|
||||||
const double* BlackoilPropsAdFromDeck::surfaceDensity() const
|
const double* BlackoilPropsAdFromDeck::surfaceDensity(const int cellIdx) const
|
||||||
{
|
{
|
||||||
return densities_;
|
int pvtRegionIdx = cellPvtRegionIdx_[cellIdx];
|
||||||
|
return &densities_[pvtRegionIdx][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -246,7 +272,7 @@ namespace Opm
|
|||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
const double* rs = 0;
|
const double* rs = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Water]]->mu(n, pw.data(), rs,
|
props_[phase_usage_.phase_pos[Water]]->mu(n, &pvtTableIdx_[0], pw.data(), rs,
|
||||||
mu.data(), dmudp.data(), dmudr.data());
|
mu.data(), dmudp.data(), dmudr.data());
|
||||||
return mu;
|
return mu;
|
||||||
}
|
}
|
||||||
@ -271,7 +297,7 @@ namespace Opm
|
|||||||
V dmudp(n);
|
V dmudp(n);
|
||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Oil]]->mu(n, po.data(), rs.data(), &cond[0],
|
props_[phase_usage_.phase_pos[Oil]]->mu(n, &pvtTableIdx_[0], po.data(), rs.data(), &cond[0],
|
||||||
mu.data(), dmudp.data(), dmudr.data());
|
mu.data(), dmudp.data(), dmudr.data());
|
||||||
return mu;
|
return mu;
|
||||||
}
|
}
|
||||||
@ -293,7 +319,7 @@ namespace Opm
|
|||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
const double* rs = 0;
|
const double* rs = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->mu(n, pg.data(), rs,
|
props_[phase_usage_.phase_pos[Gas]]->mu(n, &pvtTableIdx_[0], pg.data(), rs,
|
||||||
mu.data(), dmudp.data(), dmudr.data());
|
mu.data(), dmudp.data(), dmudr.data());
|
||||||
return mu;
|
return mu;
|
||||||
}
|
}
|
||||||
@ -316,7 +342,7 @@ namespace Opm
|
|||||||
V dmudp(n);
|
V dmudp(n);
|
||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->mu(n, pg.data(), rv.data(),&cond[0],
|
props_[phase_usage_.phase_pos[Gas]]->mu(n, &pvtTableIdx_[0], pg.data(), rv.data(),&cond[0],
|
||||||
mu.data(), dmudp.data(), dmudr.data());
|
mu.data(), dmudp.data(), dmudr.data());
|
||||||
return mu;
|
return mu;
|
||||||
}
|
}
|
||||||
@ -338,7 +364,7 @@ namespace Opm
|
|||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
const double* rs = 0;
|
const double* rs = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Water]]->mu(n, pw.value().data(), rs,
|
props_[phase_usage_.phase_pos[Water]]->mu(n, &pvtTableIdx_[0], pw.value().data(), rs,
|
||||||
mu.data(), dmudp.data(), dmudr.data());
|
mu.data(), dmudp.data(), dmudr.data());
|
||||||
ADB::M dmudp_diag = spdiag(dmudp);
|
ADB::M dmudp_diag = spdiag(dmudp);
|
||||||
const int num_blocks = pw.numBlocks();
|
const int num_blocks = pw.numBlocks();
|
||||||
@ -369,7 +395,7 @@ namespace Opm
|
|||||||
V dmudp(n);
|
V dmudp(n);
|
||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Oil]]->mu(n, po.value().data(), rs.value().data(),
|
props_[phase_usage_.phase_pos[Oil]]->mu(n, &pvtTableIdx_[0], po.value().data(), rs.value().data(),
|
||||||
&cond[0], mu.data(), dmudp.data(), dmudr.data());
|
&cond[0], mu.data(), dmudp.data(), dmudr.data());
|
||||||
|
|
||||||
ADB::M dmudp_diag = spdiag(dmudp);
|
ADB::M dmudp_diag = spdiag(dmudp);
|
||||||
@ -399,7 +425,7 @@ namespace Opm
|
|||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
const double* rv = 0;
|
const double* rv = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->mu(n, pg.value().data(), rv,
|
props_[phase_usage_.phase_pos[Gas]]->mu(n, &pvtTableIdx_[0], pg.value().data(), rv,
|
||||||
mu.data(), dmudp.data(), dmudr.data());
|
mu.data(), dmudp.data(), dmudr.data());
|
||||||
|
|
||||||
ADB::M dmudp_diag = spdiag(dmudp);
|
ADB::M dmudp_diag = spdiag(dmudp);
|
||||||
@ -431,7 +457,7 @@ namespace Opm
|
|||||||
V dmudp(n);
|
V dmudp(n);
|
||||||
V dmudr(n);
|
V dmudr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->mu(n, pg.value().data(), rv.value().data(),&cond[0],
|
props_[phase_usage_.phase_pos[Gas]]->mu(n, &pvtTableIdx_[0], pg.value().data(), rv.value().data(),&cond[0],
|
||||||
mu.data(), dmudp.data(), dmudr.data());
|
mu.data(), dmudp.data(), dmudr.data());
|
||||||
|
|
||||||
ADB::M dmudp_diag = spdiag(dmudp);
|
ADB::M dmudp_diag = spdiag(dmudp);
|
||||||
@ -480,7 +506,7 @@ namespace Opm
|
|||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
const double* rs = 0;
|
const double* rs = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Water]]->b(n, pw.data(), rs,
|
props_[phase_usage_.phase_pos[Water]]->b(n, &pvtTableIdx_[0], pw.data(), rs,
|
||||||
b.data(), dbdp.data(), dbdr.data());
|
b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
@ -507,7 +533,7 @@ namespace Opm
|
|||||||
V dbdp(n);
|
V dbdp(n);
|
||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Oil]]->b(n, po.data(), rs.data(), &cond[0],
|
props_[phase_usage_.phase_pos[Oil]]->b(n, &pvtTableIdx_[0], po.data(), rs.data(), &cond[0],
|
||||||
b.data(), dbdp.data(), dbdr.data());
|
b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
@ -531,7 +557,7 @@ namespace Opm
|
|||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
const double* rs = 0;
|
const double* rs = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->b(n, pg.data(), rs,
|
props_[phase_usage_.phase_pos[Gas]]->b(n, &pvtTableIdx_[0], pg.data(), rs,
|
||||||
b.data(), dbdp.data(), dbdr.data());
|
b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
@ -558,7 +584,7 @@ namespace Opm
|
|||||||
V dbdp(n);
|
V dbdp(n);
|
||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->b(n, pg.data(), rv.data(), &cond[0],
|
props_[phase_usage_.phase_pos[Gas]]->b(n, &pvtTableIdx_[0], pg.data(), rv.data(), &cond[0],
|
||||||
b.data(), dbdp.data(), dbdr.data());
|
b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
@ -582,7 +608,7 @@ namespace Opm
|
|||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
const double* rs = 0;
|
const double* rs = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Water]]->b(n, pw.value().data(), rs,
|
props_[phase_usage_.phase_pos[Water]]->b(n, &pvtTableIdx_[0], pw.value().data(), rs,
|
||||||
b.data(), dbdp.data(), dbdr.data());
|
b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
ADB::M dbdp_diag = spdiag(dbdp);
|
ADB::M dbdp_diag = spdiag(dbdp);
|
||||||
@ -615,7 +641,7 @@ namespace Opm
|
|||||||
V dbdp(n);
|
V dbdp(n);
|
||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Oil]]->b(n, po.value().data(), rs.value().data(),
|
props_[phase_usage_.phase_pos[Oil]]->b(n, &pvtTableIdx_[0], po.value().data(), rs.value().data(),
|
||||||
&cond[0], b.data(), dbdp.data(), dbdr.data());
|
&cond[0], b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
ADB::M dbdp_diag = spdiag(dbdp);
|
ADB::M dbdp_diag = spdiag(dbdp);
|
||||||
@ -646,7 +672,7 @@ namespace Opm
|
|||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
const double* rv = 0;
|
const double* rv = 0;
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->b(n, pg.value().data(), rv,
|
props_[phase_usage_.phase_pos[Gas]]->b(n, &pvtTableIdx_[0], pg.value().data(), rv,
|
||||||
b.data(), dbdp.data(), dbdr.data());
|
b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
ADB::M dbdp_diag = spdiag(dbdp);
|
ADB::M dbdp_diag = spdiag(dbdp);
|
||||||
@ -679,7 +705,7 @@ namespace Opm
|
|||||||
V dbdp(n);
|
V dbdp(n);
|
||||||
V dbdr(n);
|
V dbdr(n);
|
||||||
|
|
||||||
props_[phase_usage_.phase_pos[Gas]]->b(n, pg.value().data(), rv.value().data(), &cond[0],
|
props_[phase_usage_.phase_pos[Gas]]->b(n, &pvtTableIdx_[0], pg.value().data(), rv.value().data(), &cond[0],
|
||||||
b.data(), dbdp.data(), dbdr.data());
|
b.data(), dbdp.data(), dbdr.data());
|
||||||
|
|
||||||
ADB::M dbdp_diag = spdiag(dbdp);
|
ADB::M dbdp_diag = spdiag(dbdp);
|
||||||
@ -710,7 +736,7 @@ namespace Opm
|
|||||||
assert(po.size() == n);
|
assert(po.size() == n);
|
||||||
V rbub(n);
|
V rbub(n);
|
||||||
V drbubdp(n);
|
V drbubdp(n);
|
||||||
props_[Oil]->rsSat(n, po.data(), rbub.data(), drbubdp.data());
|
props_[Oil]->rsSat(n, &pvtTableIdx_[0], po.data(), rbub.data(), drbubdp.data());
|
||||||
return rbub;
|
return rbub;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,7 +754,7 @@ namespace Opm
|
|||||||
assert(po.size() == n);
|
assert(po.size() == n);
|
||||||
V rbub(n);
|
V rbub(n);
|
||||||
V drbubdp(n);
|
V drbubdp(n);
|
||||||
props_[Oil]->rsSat(n, po.value().data(), rbub.data(), drbubdp.data());
|
props_[Oil]->rsSat(n, &pvtTableIdx_[0], po.value().data(), rbub.data(), drbubdp.data());
|
||||||
ADB::M drbubdp_diag = spdiag(drbubdp);
|
ADB::M drbubdp_diag = spdiag(drbubdp);
|
||||||
const int num_blocks = po.numBlocks();
|
const int num_blocks = po.numBlocks();
|
||||||
std::vector<ADB::M> jacs(num_blocks);
|
std::vector<ADB::M> jacs(num_blocks);
|
||||||
@ -754,7 +780,7 @@ namespace Opm
|
|||||||
assert(po.size() == n);
|
assert(po.size() == n);
|
||||||
V rv(n);
|
V rv(n);
|
||||||
V drvdp(n);
|
V drvdp(n);
|
||||||
props_[Gas]->rvSat(n, po.data(), rv.data(), drvdp.data());
|
props_[Gas]->rvSat(n, &pvtTableIdx_[0], po.data(), rv.data(), drvdp.data());
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,7 +798,7 @@ namespace Opm
|
|||||||
assert(po.size() == n);
|
assert(po.size() == n);
|
||||||
V rv(n);
|
V rv(n);
|
||||||
V drvdp(n);
|
V drvdp(n);
|
||||||
props_[Gas]->rvSat(n, po.value().data(), rv.data(), drvdp.data());
|
props_[Gas]->rvSat(n, &pvtTableIdx_[0], po.value().data(), rv.data(), drvdp.data());
|
||||||
ADB::M drvdp_diag = spdiag(drvdp);
|
ADB::M drvdp_diag = spdiag(drvdp);
|
||||||
const int num_blocks = po.numBlocks();
|
const int num_blocks = po.numBlocks();
|
||||||
std::vector<ADB::M> jacs(num_blocks);
|
std::vector<ADB::M> jacs(num_blocks);
|
||||||
|
@ -23,12 +23,14 @@
|
|||||||
#include <opm/autodiff/BlackoilPropsAdInterface.hpp>
|
#include <opm/autodiff/BlackoilPropsAdInterface.hpp>
|
||||||
#include <opm/autodiff/AutoDiffBlock.hpp>
|
#include <opm/autodiff/AutoDiffBlock.hpp>
|
||||||
|
|
||||||
|
#include <opm/core/props/BlackoilPhases.hpp>
|
||||||
#include <opm/core/props/satfunc/SaturationPropsFromDeck.hpp>
|
#include <opm/core/props/satfunc/SaturationPropsFromDeck.hpp>
|
||||||
#include <opm/core/props/rock/RockFromDeck.hpp>
|
#include <opm/core/props/rock/RockFromDeck.hpp>
|
||||||
|
|
||||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#ifdef HAVE_DUNE_CORNERPOINT
|
#ifdef HAVE_DUNE_CORNERPOINT
|
||||||
#include "disable_warning_pragmas.h"
|
#include "disable_warning_pragmas.h"
|
||||||
@ -38,8 +40,7 @@
|
|||||||
|
|
||||||
namespace Opm
|
namespace Opm
|
||||||
{
|
{
|
||||||
|
class PvtInterface;
|
||||||
class SinglePvtInterface;
|
|
||||||
|
|
||||||
/// This class implements the AD-adapted fluid interface for
|
/// This class implements the AD-adapted fluid interface for
|
||||||
/// three-phase black-oil. It requires an input deck from which it
|
/// three-phase black-oil. It requires an input deck from which it
|
||||||
@ -76,6 +77,11 @@ namespace Opm
|
|||||||
/// \return N, the number of cells.
|
/// \return N, the number of cells.
|
||||||
int numCells() const;
|
int numCells() const;
|
||||||
|
|
||||||
|
/// Return an array containing the PVT table index for each
|
||||||
|
/// grid cell
|
||||||
|
virtual const int* cellPvtRegionIndex() const
|
||||||
|
{ return &cellPvtRegionIdx_[0]; }
|
||||||
|
|
||||||
/// \return Array of N porosity values.
|
/// \return Array of N porosity values.
|
||||||
const double* porosity() const;
|
const double* porosity() const;
|
||||||
|
|
||||||
@ -109,7 +115,7 @@ namespace Opm
|
|||||||
|
|
||||||
/// Densities of stock components at surface conditions.
|
/// Densities of stock components at surface conditions.
|
||||||
/// \return Array of 3 density values.
|
/// \return Array of 3 density values.
|
||||||
const double* surfaceDensity() const;
|
const double* surfaceDensity(const int cellIdx = 0) const;
|
||||||
|
|
||||||
|
|
||||||
// ------ Viscosity ------
|
// ------ Viscosity ------
|
||||||
@ -347,12 +353,27 @@ namespace Opm
|
|||||||
|
|
||||||
RockFromDeck rock_;
|
RockFromDeck rock_;
|
||||||
std::unique_ptr<SaturationPropsInterface> satprops_;
|
std::unique_ptr<SaturationPropsInterface> satprops_;
|
||||||
|
|
||||||
PhaseUsage phase_usage_;
|
PhaseUsage phase_usage_;
|
||||||
std::vector<std::shared_ptr<SinglePvtInterface> > props_;
|
|
||||||
double densities_[BlackoilPhases::MaxNumPhases];
|
// The PVT region which is to be used for each cell
|
||||||
|
std::vector<int> cellPvtRegionIdx_;
|
||||||
|
|
||||||
|
// The PVT properties. One object per PVT region and per
|
||||||
|
// active fluid phase.
|
||||||
|
std::vector<std::shared_ptr<Opm::PvtInterface> > props_;
|
||||||
|
|
||||||
|
// The index of the PVT table which ought to be used for each
|
||||||
|
// cell. Eclipse does not seem to allow specifying fluid-phase
|
||||||
|
// specific table indices, so for the sake of simplicity, we
|
||||||
|
// don't do this either. (if it turns out that Eclipes does in
|
||||||
|
// fact support it or if it by some miracle gains this feature
|
||||||
|
// in the future, this attribute needs to become a vector of
|
||||||
|
// vectors of ints.)
|
||||||
|
std::vector<int> pvtTableIdx_;
|
||||||
|
|
||||||
|
std::vector<std::array<double, BlackoilPhases::MaxNumPhases> > densities_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
#endif // OPM_BLACKOILPROPSADFROMDECK_HEADER_INCLUDED
|
#endif // OPM_BLACKOILPROPSADFROMDECK_HEADER_INCLUDED
|
||||||
|
@ -84,7 +84,7 @@ namespace Opm
|
|||||||
|
|
||||||
/// Densities of stock components at surface conditions.
|
/// Densities of stock components at surface conditions.
|
||||||
/// \return Array of 3 density values.
|
/// \return Array of 3 density values.
|
||||||
virtual const double* surfaceDensity() const = 0;
|
virtual const double* surfaceDensity(int regionIdx = 0) const = 0;
|
||||||
|
|
||||||
|
|
||||||
// ------ Viscosity ------
|
// ------ Viscosity ------
|
||||||
|
@ -233,9 +233,6 @@ void extractInternalFaces(const Dune::CpGrid& grid,
|
|||||||
Eigen::Array<int, Eigen::Dynamic, 1>& internal_faces,
|
Eigen::Array<int, Eigen::Dynamic, 1>& internal_faces,
|
||||||
Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor>& nbi)
|
Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor>& nbi)
|
||||||
{
|
{
|
||||||
typedef Eigen::Array<bool, Eigen::Dynamic, 1> OneColBool;
|
|
||||||
typedef Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColInt;
|
|
||||||
typedef Eigen::Array<bool, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColBool;
|
|
||||||
// Extracts the internal faces of the grid.
|
// Extracts the internal faces of the grid.
|
||||||
// These are stored in internal_faces.
|
// These are stored in internal_faces.
|
||||||
int nf=numFaces(grid);
|
int nf=numFaces(grid);
|
||||||
|
@ -185,7 +185,6 @@ namespace Opm
|
|||||||
// but for scalar lambda and using TPFA it holds.
|
// but for scalar lambda and using TPFA it holds.
|
||||||
const V p1 = Vec(state.pressure().data(), nc, 1);
|
const V p1 = Vec(state.pressure().data(), nc, 1);
|
||||||
const V ndp = (ops_.ngrad * p1.matrix()).array();
|
const V ndp = (ops_.ngrad * p1.matrix()).array();
|
||||||
typedef Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> DynArr;
|
|
||||||
const V z = cellCentroidsZ(grid_);
|
const V z = cellCentroidsZ(grid_);
|
||||||
const V ndz = (ops_.ngrad * z.matrix()).array();
|
const V ndz = (ops_.ngrad * z.matrix()).array();
|
||||||
assert(num_internal == ndp.size());
|
assert(num_internal == ndp.size());
|
||||||
|
Loading…
Reference in New Issue
Block a user