Tables: Add Structurally Correct Oil PVT Output from PVTO
This commit expands the private member function
Tables::addOilPVTTables(const EclipseState&)
to create structurally correct TAB vector entries from the PVTO
(live oil) input table data when oil is an active phase in a
simulation run. Specifically, the main result array has the columns
[ Po, 1/Bo, 1/(Bo*mu_o), d(1/Bo)/dPo, d(1/(Bo*mu_o))/dPo ]
and the ancillary table (base pointer JBPVTO) holds the composition
nodes.
Note that while we do create structurally correct output tables, we
do not fill in undersaturated states that have been defaulted in the
input table.
The number of table rows in the main table is equal to number of PVT
regions times the number of declared composition nodes (TABDIMS item
6, NRPVT) times the number of declared pressure nodes (TABDIMS item
4, NPPVT). In other words, the main result array is expanded to
fill NPPVT rows per Rs node per PVT region. Fill value +2.0e+20.
We have verified the results with ECLIPSE 100. The ancillary table
is expanded to number of declared composition nodes for each PVT
region. Fill value +2.0e+20.
As an OPM extension, we will use the maximum number of active
pressure and composition nodes across all PVTO tables if the
declared maximum pressure nodes in TABDIMS is too small. This will
create a TAB vector representations that are not compatible with
ECLIPSE, but which will nevertheless be useful in the context of
ResInsight's flux calculation.
Add unit tests for all supported oil-related PVT tables.
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/FlatTable.hpp> // PVTW, PVCDO
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/PvdoTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/PvtoTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/SgfnTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/SgofTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/Sof2Table.hpp>
|
||||
@@ -1283,6 +1284,198 @@ namespace { namespace PVTFunc {
|
||||
});
|
||||
}
|
||||
|
||||
/// Create linearised and padded 'TAB' vector entries of normalised
|
||||
/// gas tables for all PVT function regions from PVTO (live oil with
|
||||
/// dissolved gas) keyword data.
|
||||
///
|
||||
/// \param[in] numCompNodes Number of composition nodes (sub-tables)
|
||||
/// to allocate in the output vector for each oil PVT table.
|
||||
/// Expected to be equal to the number of declared composition
|
||||
/// nodes in the simulation run's TABDIMS keyword (NRPVT, Item
|
||||
/// 6).
|
||||
///
|
||||
/// \param[in] numPressNodes Number of pressure nodes (rows per
|
||||
/// sub-table) to allocate in the output vector for each oil PVT
|
||||
/// table. Expected to be equal to the number of declared
|
||||
/// pressure nodes in the simulation run's TABDIMS keyword
|
||||
/// (NPPVT, Item 4).
|
||||
///
|
||||
/// \param[in] units Active unit system. Needed to convert SI
|
||||
/// convention pressure values (Pascal), formation volume factors
|
||||
/// (S-volume to R-volume), and viscosity values (Pa*s) to
|
||||
/// declared conventions of the run specification.
|
||||
///
|
||||
/// \param[in] pvto Collection of PVTO tables for all PVT regions.
|
||||
///
|
||||
/// \return Linearised and padded 'TAB' vector values for output gas
|
||||
/// PVT tables. A unit-converted copy of the input table \p pvto
|
||||
/// with added derivatives.
|
||||
std::vector<double>
|
||||
fromPVTO(const std::size_t numCompNodes,
|
||||
const std::size_t numPressNodes,
|
||||
const Opm::UnitSystem& units,
|
||||
const std::vector<Opm::PvtoTable>& pvto)
|
||||
{
|
||||
// Columns [ Po, 1/Bo, 1/(Bo*mu_o), derivatives ]
|
||||
const auto numTab = pvto.size();
|
||||
const auto numPrim = numCompNodes;
|
||||
const auto numRows = numPressNodes;
|
||||
const auto numDep = std::size_t{2}; // 1/Bo, 1/(Bo*mu_o)
|
||||
|
||||
// PVTO fill value = +2.0e20
|
||||
const auto fillVal = +2.0e20;
|
||||
|
||||
return createPropfuncTable(numTab, numPrim, numRows, numDep, fillVal,
|
||||
[&units, &pvto](const std::size_t tableID,
|
||||
const std::size_t primID,
|
||||
Opm::LinearisedOutputTable& linTable)
|
||||
-> std::size_t
|
||||
{
|
||||
auto numActRows = std::size_t{0};
|
||||
|
||||
if (primID >= pvto[tableID].size()) {
|
||||
// Pressure node outside current table's active set. No
|
||||
// active rows in this subtable.
|
||||
return numActRows;
|
||||
}
|
||||
|
||||
const auto& t = pvto[tableID].getUnderSaturatedTable(primID);
|
||||
|
||||
// Column 0: Po
|
||||
{
|
||||
const auto uPo = ::Opm::UnitSystem::measure::pressure;
|
||||
|
||||
const auto& Po = t.getColumn(0);
|
||||
|
||||
numActRows = Po.size();
|
||||
|
||||
std::transform(std::begin(Po), std::end(Po),
|
||||
linTable.column(tableID, primID, 0),
|
||||
[&units](const double po) -> double
|
||||
{
|
||||
return units.from_si(uPo, po);
|
||||
});
|
||||
}
|
||||
|
||||
// Column 1: 1/Bo
|
||||
{
|
||||
const auto uRecipFVF = ::Opm::UnitSystem::measure::
|
||||
oil_inverse_formation_volume_factor;
|
||||
|
||||
const auto& Bo = t.getColumn(1);
|
||||
|
||||
std::transform(std::begin(Bo), std::end(Bo),
|
||||
linTable.column(tableID, primID, 1),
|
||||
[&units](const double B) -> double
|
||||
{
|
||||
return units.from_si(uRecipFVF, 1.0 / B);
|
||||
});
|
||||
}
|
||||
|
||||
// Column 2: 1/(Bo*mu_o)
|
||||
{
|
||||
const auto uRecipFVF = ::Opm::UnitSystem::measure::
|
||||
oil_inverse_formation_volume_factor;
|
||||
|
||||
const auto uVisc = ::Opm::UnitSystem::measure::viscosity;
|
||||
|
||||
const auto& Bo = t.getColumn(1);
|
||||
const auto& mu_o = t.getColumn(2);
|
||||
|
||||
std::transform(std::begin(Bo), std::end(Bo),
|
||||
std::begin(mu_o),
|
||||
linTable.column(tableID, primID, 2),
|
||||
[&units](const double B, const double mu) -> double
|
||||
{
|
||||
return units.from_si(uRecipFVF, 1.0 / B)
|
||||
/ units.from_si(uVisc , mu);
|
||||
});
|
||||
}
|
||||
|
||||
// Inform createPropfuncTable() of number of active rows in
|
||||
// this table. Needed to compute slopes of piecewise linear
|
||||
// interpolants.
|
||||
return numActRows;
|
||||
});
|
||||
}
|
||||
|
||||
/// Create linearised and padded 'TAB' vector entries of normalised
|
||||
/// composition nodes for all PVT function regions from PVTO (live
|
||||
/// oil with dissolved gas) keyword data.
|
||||
///
|
||||
/// \param[in] numCompNodes Number of compositoin nodes to allocate
|
||||
/// in the output vector for each oil PVT table. Expected to be
|
||||
/// equal to the number of declared composition nodes in the
|
||||
/// simulation run's TABDIMS keyword (NRPVT, Item 6).
|
||||
///
|
||||
/// \param[in] units Active unit system. Needed to convert SI
|
||||
/// convention dissolved gas composition values (Sm3/Sm3) to
|
||||
/// declared conventions of the run specification.
|
||||
///
|
||||
/// \param[in] pvto Collection of PVTO tables for all PVT regions.
|
||||
///
|
||||
/// \return Linearised and padded 'TAB' vector values for output oil
|
||||
/// PVT tables. A unit-converted copy of the primary keys in
|
||||
/// input table \p pvto.
|
||||
std::vector<double>
|
||||
compositionNodes(const std::size_t numCompNodes,
|
||||
const Opm::UnitSystem& units,
|
||||
const std::vector<Opm::PvtoTable>& pvto)
|
||||
{
|
||||
// Columns [ Rs ]
|
||||
const auto numTab = pvto.size();
|
||||
|
||||
// One set of composition nodes per table.
|
||||
const auto numPrim = std::size_t{1};
|
||||
const auto numRows = numCompNodes;
|
||||
|
||||
// No dependent variables.
|
||||
const auto numDep = std::size_t{0};
|
||||
|
||||
// PVTO fill value = +2.0e20
|
||||
const auto fillVal = +2.0e20;
|
||||
|
||||
return createPropfuncTable(numTab, numPrim, numRows, numDep, fillVal,
|
||||
[&units, &pvto](const std::size_t tableID,
|
||||
const std::size_t primID,
|
||||
Opm::LinearisedOutputTable& linTable)
|
||||
-> std::size_t
|
||||
{
|
||||
const auto uRs = ::Opm::UnitSystem::measure::gas_oil_ratio;
|
||||
|
||||
const auto& t = pvto[tableID].getSaturatedTable();
|
||||
const auto& Rs = t.getColumn(0);
|
||||
|
||||
const auto numActRows = Rs.size();
|
||||
|
||||
std::transform(std::begin(Rs), std::end(Rs),
|
||||
linTable.column(tableID, primID, 0),
|
||||
[&units](const double rs) -> double
|
||||
{
|
||||
return units.from_si(uRs, rs);
|
||||
});
|
||||
|
||||
return numActRows;
|
||||
});
|
||||
}
|
||||
|
||||
/// Extract maximum effective composition nodes in PVTO table data
|
||||
///
|
||||
/// \param[in] pvto Collection of PVTO tables for all PVT regions.
|
||||
///
|
||||
/// \return Maximum number of active keys across all tables of \p
|
||||
/// pvto.
|
||||
std::size_t maxNumCompNodes(const std::vector<Opm::PvtoTable>& pvto)
|
||||
{
|
||||
if (pvto.empty()) { return 0; }
|
||||
|
||||
return std::accumulate(std::begin(pvto), std::end(pvto), std::size_t{0},
|
||||
[](const std::size_t n, const Opm::PvtoTable& t) -> std::size_t
|
||||
{
|
||||
return std::max(n, t.getSaturatedTable().numRows());
|
||||
});
|
||||
}
|
||||
|
||||
/// Extract maximum effective pressure nodes in PVDO table data
|
||||
///
|
||||
/// \param[in] pvdo Collection of PVDO tables for all PVT regions.
|
||||
@@ -1302,6 +1495,30 @@ namespace { namespace PVTFunc {
|
||||
return std::max(n, pvdo.getTable<PVDO>(table).numRows());
|
||||
});
|
||||
}
|
||||
|
||||
/// Extract maximum effective pressure nodes in PVTO table data
|
||||
///
|
||||
/// \param[in] pvto Collection of PVTO tables for all PVT regions.
|
||||
///
|
||||
/// \return Maximum number of active pressure rows across all
|
||||
/// sub-tables of \p pvto.
|
||||
std::size_t maxNumPressNodes(const std::vector<Opm::PvtoTable>& pvto)
|
||||
{
|
||||
auto max_nppvt = std::size_t{0};
|
||||
|
||||
for (const auto& table : pvto) {
|
||||
const auto max_nppvt_tab =
|
||||
std::accumulate(table.begin(), table.end(), std::size_t{0},
|
||||
[](const std::size_t n, const Opm::SimpleTable& t)
|
||||
{
|
||||
return std::max(n, t.numRows());
|
||||
});
|
||||
|
||||
max_nppvt = std::max(max_nppvt, max_nppvt_tab);
|
||||
}
|
||||
|
||||
return max_nppvt;
|
||||
}
|
||||
} // Oil
|
||||
|
||||
/// Functions to create linearised, padded, and normalised water PVT
|
||||
@@ -1771,15 +1988,39 @@ namespace Opm {
|
||||
|
||||
const auto numPressNodes = tabd.getNumPressureNodes();
|
||||
|
||||
const auto hasPVTO = !tabMgr.getPvtoTables().empty();
|
||||
const auto hasPVDO = tabMgr.hasTables("PVDO");
|
||||
const auto hasPVCDO = !tabMgr.getPvcdoTable().empty();
|
||||
|
||||
if (hasPVDO + hasPVCDO != 1) {
|
||||
// Unhandled table specification. Maybe throw here?
|
||||
if (hasPVTO + hasPVDO + hasPVCDO != 1) {
|
||||
// Inconsistent table specification. Maybe throw here?
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasPVDO) {
|
||||
if (hasPVTO) {
|
||||
// Live oil with dissolved gas.
|
||||
const auto& pvto = tabMgr.getPvtoTables();
|
||||
|
||||
const auto numCompNodes =
|
||||
std::max(tabd.getNumRSNodes(), PVTFunc::Oil::maxNumCompNodes(pvto));
|
||||
|
||||
const auto numRows =
|
||||
std::max(numPressNodes, PVTFunc::Oil::maxNumPressNodes(pvto));
|
||||
|
||||
const auto data = PVTFunc::Oil::
|
||||
fromPVTO(numCompNodes, numRows, this->units, pvto);
|
||||
|
||||
const auto rsData = PVTFunc::Oil::
|
||||
compositionNodes(numCompNodes, this->units, pvto);
|
||||
|
||||
this->addData(TABDIMS_IBPVTO_OFFSET_ITEM, data);
|
||||
this->addData(TABDIMS_JBPVTO_OFFSET_ITEM, rsData);
|
||||
|
||||
this->m_tabdims[TABDIMS_NPPVTO_ITEM] = numRows;
|
||||
this->m_tabdims[TABDIMS_NRPVTO_ITEM] = numCompNodes;
|
||||
this->m_tabdims[TABDIMS_NTPVTO_ITEM] = pvto.size();
|
||||
}
|
||||
else if (hasPVDO) {
|
||||
// Dead oil, pressure dependent compressibility.
|
||||
const auto& pvdo = tabMgr.getPvdoTables();
|
||||
|
||||
|
||||
@@ -1656,6 +1656,746 @@ END
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (Oil)
|
||||
|
||||
BOOST_AUTO_TEST_CASE (PVCDO)
|
||||
{
|
||||
const auto rspec = std::string { R"(RUNSPEC
|
||||
DIMENS
|
||||
10 10 10 /
|
||||
|
||||
TITLE
|
||||
Test PVCDO Output
|
||||
|
||||
OIL
|
||||
WATER
|
||||
|
||||
METRIC
|
||||
|
||||
TABDIMS
|
||||
-- NTSFUN NTPVT NSSFUN NPPVT NTFIP NRPVT
|
||||
1* 2 1* 4 1* 3
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto props = std::string { R"(
|
||||
PVCDO
|
||||
-- Pref Bo(Pref) Co Vo(Pref) Cv
|
||||
200 1.23 0.321e-4 0.25 0.654e-3 /
|
||||
250 0.987 1.234e-5 0.314 0.9876e-5 /
|
||||
)" };
|
||||
|
||||
const auto es = parse(rspec, props);
|
||||
|
||||
auto tables = ::Opm::Tables(es.getUnits());
|
||||
tables.addPVTTables(es);
|
||||
|
||||
const auto& tabdims = tables.tabdims();
|
||||
const auto& tab = tables.tab();
|
||||
|
||||
const auto ibpvto = tabdims[ TABDIMS_IBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto nppvto = tabdims[ TABDIMS_NPPVTO_ITEM ];
|
||||
const auto ntpvto = tabdims[ TABDIMS_NTPVTO_ITEM ];
|
||||
const auto ncol = 5;
|
||||
|
||||
// Rs table defaulted
|
||||
BOOST_CHECK_EQUAL(tabdims[TABDIMS_JBPVTO_OFFSET_ITEM], 1);
|
||||
BOOST_CHECK_EQUAL(tabdims[TABDIMS_NRPVTO_ITEM], 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(nppvto, 4);
|
||||
BOOST_CHECK_EQUAL(ntpvto, 2);
|
||||
|
||||
const auto pvcdo = std::vector<double> {
|
||||
&tab[ ibpvto ] + 0,
|
||||
&tab[ ibpvto ] + ntpvto*nppvto*ncol
|
||||
};
|
||||
|
||||
const auto expect_pvcdo = makeTable(5, {
|
||||
// Po Bo Co Vo Cv
|
||||
//
|
||||
// Table 1
|
||||
2.000000000000000e+02, 1.230000000000000e+00, 3.210000000000000e-05, 2.500000000000000e-01, 6.540000000000001e-04,
|
||||
-1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20,
|
||||
-1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20,
|
||||
-1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20,
|
||||
|
||||
// ===========================================================================================================================
|
||||
|
||||
// Table 2
|
||||
2.500000000000000e+02, 9.870000000000000e-01, 1.234000000000000e-05, 3.140000000000000e-01, 9.876000000000000e-06,
|
||||
-1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20,
|
||||
-1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20,
|
||||
-1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20, -1.000000000000000e+20,
|
||||
});
|
||||
|
||||
check_is_close(pvcdo, expect_pvcdo);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (PVDO_Regular)
|
||||
{
|
||||
const auto rspec = std::string { R"(RUNSPEC
|
||||
DIMENS
|
||||
10 10 10 /
|
||||
|
||||
TITLE
|
||||
Test PVDO Output
|
||||
|
||||
OIL
|
||||
WATER
|
||||
|
||||
FIELD
|
||||
|
||||
TABDIMS
|
||||
-- NTSFUN NTPVT NSSFUN NPPVT NTFIP NRPVT
|
||||
1* 2 1* 8 1* 1*
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto props = std::string { R"(
|
||||
PVDO
|
||||
400 1.012 1.16
|
||||
1200 1.0040 1.164
|
||||
2000 0.9960 1.167
|
||||
2800 0.9880 1.172
|
||||
3600 0.9802 1.177
|
||||
4400 0.9724 1.181
|
||||
5200 0.9646 1.185
|
||||
5600 0.9607 1.19 /
|
||||
800 1.0255 1.14
|
||||
1600 1.0172 1.14
|
||||
2400 1.0091 1.14
|
||||
3200 1.0011 1.14
|
||||
4000 0.9931 1.14
|
||||
4800 0.9852 1.14
|
||||
5600 0.9774 1.14 /
|
||||
)" };
|
||||
|
||||
const auto es = parse(rspec, props);
|
||||
|
||||
auto tables = ::Opm::Tables(es.getUnits());
|
||||
tables.addPVTTables(es);
|
||||
|
||||
const auto& tabdims = tables.tabdims();
|
||||
const auto& tab = tables.tab();
|
||||
|
||||
const auto ibpvto = tabdims[ TABDIMS_IBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto nppvto = tabdims[ TABDIMS_NPPVTO_ITEM ];
|
||||
const auto ntpvto = tabdims[ TABDIMS_NTPVTO_ITEM ];
|
||||
const auto ncol = 5;
|
||||
|
||||
// Rs table defaulted
|
||||
BOOST_CHECK_EQUAL(tabdims[TABDIMS_JBPVTO_OFFSET_ITEM], 1);
|
||||
BOOST_CHECK_EQUAL(tabdims[TABDIMS_NRPVTO_ITEM], 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(nppvto, 8);
|
||||
BOOST_CHECK_EQUAL(ntpvto, 2);
|
||||
|
||||
const auto pvdo = std::vector<double> {
|
||||
&tab[ ibpvto ] + 0,
|
||||
&tab[ ibpvto ] + ntpvto*nppvto*ncol
|
||||
};
|
||||
|
||||
const auto expect_pvdo = makeTable(5, {
|
||||
// Po 1/Bo 1/(Bo*mu_o) d(1/Bo)/dPo d(1/(Bo*mu_o))/dPo
|
||||
//
|
||||
// Table 1 (8 pressure nodes)
|
||||
4.000000000000000e+02, 9.881422924901185e-01, 8.518468038707919e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.200000000000000e+03, 9.960159362549801e-01, 8.556837940334882e-01, 9.842054706076935e-06, 4.796237703370287e-06,
|
||||
2.000000000000000e+03, 1.004016064257028e+00, 8.603393866812581e-01, 1.000016000256010e-05, 5.819490809712421e-06,
|
||||
2.800000000000000e+03, 1.012145748987854e+00, 8.636055878735959e-01, 1.016210591353262e-05, 4.082751490422227e-06,
|
||||
3.600000000000000e+03, 1.020199959192002e+00, 8.667799143517431e-01, 1.006776275518428e-05, 3.967908097683990e-06,
|
||||
4.400000000000000e+03, 1.028383381324558e+00, 8.707733965491598e-01, 1.022927766569509e-05, 4.991852746770858e-06,
|
||||
5.199999999999999e+03, 1.036699149906697e+00, 8.748516032967908e-01, 1.039471072767418e-05, 5.097758434538807e-06,
|
||||
5.599999999999999e+03, 1.040907671489539e+00, 8.747123289828058e-01, 1.052130395710449e-05, -3.481857849624292e-07,
|
||||
|
||||
// ===========================================================================================================================
|
||||
|
||||
// Table 2 (7 pressure nodes)
|
||||
8.000000000000000e+02, 9.751340809361286e-01, 8.553807727509901e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.600000000000000e+03, 9.830908375933936e-01, 8.623603838538541e-01, 9.945945821581148e-06, 8.724513878579920e-06,
|
||||
2.400000000000000e+03, 9.909820632246555e-01, 8.692825116005751e-01, 9.864032039077486e-06, 8.652659683401343e-06,
|
||||
3.200000000000000e+03, 9.989012086704624e-01, 8.762291304126864e-01, 9.898931807258565e-06, 8.683273515139035e-06,
|
||||
4.000000000000000e+03, 1.006947940791461e+00, 8.832876673609308e-01, 1.005841515124826e-05, 8.823171185305545e-06,
|
||||
4.800000000000000e+03, 1.015022330491271e+00, 8.903704653432202e-01, 1.009298712476236e-05, 8.853497477861732e-06,
|
||||
5.599999999999999e+03, 1.023122570083896e+00, 8.974759386700842e-01, 1.012529949078135e-05, 8.881841658580091e-06,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
});
|
||||
|
||||
check_is_close(pvdo, expect_pvdo);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (PVDO_Exceed_Tabdims_Limits)
|
||||
{
|
||||
// This checks that Flow's extended table allocation scheme does what
|
||||
// it's supposed to do. Normally, one would announce the maximum sizes
|
||||
// in the RUNSPEC keyword 'TABDIMS'. Note that the maximum sizes need
|
||||
// to be big enough in order to run the case in ECLIPSE. Other than
|
||||
// NTPVT, Flow does not really care about these declared maximum sizes.
|
||||
|
||||
const auto rspec = std::string { R"(RUNSPEC
|
||||
DIMENS
|
||||
10 10 10 /
|
||||
|
||||
TITLE
|
||||
Test PVDO Output
|
||||
|
||||
OIL
|
||||
WATER
|
||||
|
||||
FIELD
|
||||
|
||||
TABDIMS
|
||||
-- NTSFUN NTPVT NSSFUN NPPVT NTFIP NRPVT
|
||||
1* 2 1* 2 1* 1*
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto props = std::string { R"(
|
||||
PVDO
|
||||
400 1.012 1.16
|
||||
1200 1.0040 1.164
|
||||
2000 0.9960 1.167
|
||||
2800 0.9880 1.172
|
||||
3600 0.9802 1.177
|
||||
4000 0.9752 1.179
|
||||
4400 0.9724 1.181
|
||||
5200 0.9646 1.185
|
||||
5400 0.9630 1.187
|
||||
5600 0.9607 1.19 /
|
||||
800 1.0255 1.14
|
||||
1600 1.0172 1.14
|
||||
5600 0.9774 1.14 /
|
||||
)" };
|
||||
|
||||
const auto es = parse(rspec, props);
|
||||
|
||||
auto tables = ::Opm::Tables(es.getUnits());
|
||||
tables.addPVTTables(es);
|
||||
|
||||
const auto& tabdims = tables.tabdims();
|
||||
const auto& tab = tables.tab();
|
||||
|
||||
const auto ibpvto = tabdims[ TABDIMS_IBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto nppvto = tabdims[ TABDIMS_NPPVTO_ITEM ];
|
||||
const auto ntpvto = tabdims[ TABDIMS_NTPVTO_ITEM ];
|
||||
const auto ncol = 5;
|
||||
|
||||
// Rs table defaulted
|
||||
BOOST_CHECK_EQUAL(tabdims[TABDIMS_JBPVTO_OFFSET_ITEM], 1);
|
||||
BOOST_CHECK_EQUAL(tabdims[TABDIMS_NRPVTO_ITEM], 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(nppvto, 10); // Table 1
|
||||
BOOST_CHECK_EQUAL(ntpvto, 2);
|
||||
|
||||
// Verify declared TABDIMS from input
|
||||
{
|
||||
const auto& tabd = es.runspec().tabdims();
|
||||
|
||||
BOOST_CHECK_EQUAL(tabd.getNumPVTTables(), 2);
|
||||
BOOST_CHECK_EQUAL(tabd.getNumPressureNodes(), 2);
|
||||
}
|
||||
|
||||
const auto pvdo = std::vector<double> {
|
||||
&tab[ ibpvto ] + 0,
|
||||
&tab[ ibpvto ] + ntpvto*nppvto*ncol
|
||||
};
|
||||
|
||||
const auto expect_pvdo = makeTable(5, {
|
||||
// Po 1/Bo 1/(Bo*mu_o) d(1/Bo)/dPo d(1/(Bo*mu_o))/dPo
|
||||
//
|
||||
// Table 1 (10 pressure nodes)
|
||||
4.000000000000000e+02, 9.881422924901185e-01, 8.518468038707919e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.200000000000000e+03, 9.960159362549801e-01, 8.556837940334882e-01, 9.842054706076935e-06, 4.796237703370287e-06,
|
||||
2.000000000000000e+03, 1.004016064257028e+00, 8.603393866812581e-01, 1.000016000256010e-05, 5.819490809712421e-06,
|
||||
2.800000000000000e+03, 1.012145748987854e+00, 8.636055878735959e-01, 1.016210591353262e-05, 4.082751490422227e-06,
|
||||
3.600000000000000e+03, 1.020199959192002e+00, 8.667799143517431e-01, 1.006776275518428e-05, 3.967908097683990e-06,
|
||||
4.000000000000000e+03, 1.025430680885972e+00, 8.697461245852181e-01, 1.307680423492609e-05, 7.415525583687474e-06,
|
||||
4.400000000000000e+03, 1.028383381324558e+00, 8.707733965491598e-01, 7.381751096464098e-06, 2.568179909854249e-06,
|
||||
5.199999999999999e+03, 1.036699149906697e+00, 8.748516032967908e-01, 1.039471072767418e-05, 5.097758434538807e-06,
|
||||
5.400000000000000e+03, 1.038421599169263e+00, 8.748286429395642e-01, 8.612246312827937e-06, -1.148017861329892e-07,
|
||||
5.599999999999999e+03, 1.040907671489539e+00, 8.747123289828058e-01, 1.243036160138106e-05, -5.815697837918713e-07,
|
||||
|
||||
// ===========================================================================================================================
|
||||
|
||||
// Table 2 (3 pressure nodes)
|
||||
8.000000000000000e+02, 9.751340809361286e-01, 8.553807727509901e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.600000000000000e+03, 9.830908375933936e-01, 8.623603838538541e-01, 9.945945821581148e-06, 8.724513878579920e-06,
|
||||
5.599999999999999e+03, 1.023122570083896e+00, 8.974759386700842e-01, 1.000793312262560e-05, 8.778888704057549e-06,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
});
|
||||
|
||||
check_is_close(pvdo, expect_pvdo);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (PVTO_SPE1_USat_Defaulted)
|
||||
{
|
||||
const auto rspec = std::string { R"(RUNSPEC
|
||||
DIMENS
|
||||
10 10 10 /
|
||||
|
||||
TITLE
|
||||
Test PVTO Output
|
||||
|
||||
OIL
|
||||
WATER
|
||||
|
||||
FIELD
|
||||
|
||||
TABDIMS
|
||||
-- NTSFUN NTPVT NSSFUN NPPVT NTFIP NRPVT
|
||||
1* 2 1* 4 1* 3
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto props = std::string { R"(
|
||||
PVTO
|
||||
0.3710 1014.7 1.2950 0.8300 /
|
||||
0.9300 3014.7 1.5650 0.5940 /
|
||||
1.6180 5014.7 1.8270 0.4490
|
||||
9014.7 1.7370 0.6310 /
|
||||
/
|
||||
0.0010 14.7 1.0620 1.0400 /
|
||||
1.2700 4014.7 1.6950 0.5100
|
||||
9014.7 1.5790 0.7400 /
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto es = parse(rspec, props);
|
||||
|
||||
auto tables = ::Opm::Tables(es.getUnits());
|
||||
tables.addPVTTables(es);
|
||||
|
||||
const auto& tabdims = tables.tabdims();
|
||||
const auto& tab = tables.tab();
|
||||
|
||||
const auto ibpvto = tabdims[ TABDIMS_IBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto jbpvto = tabdims[ TABDIMS_JBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto nppvto = tabdims[ TABDIMS_NPPVTO_ITEM ];
|
||||
const auto nrpvto = tabdims[ TABDIMS_NRPVTO_ITEM ];
|
||||
const auto ntpvto = tabdims[ TABDIMS_NTPVTO_ITEM ];
|
||||
const auto ncol = 5;
|
||||
|
||||
BOOST_CHECK_EQUAL(nppvto, 4);
|
||||
BOOST_CHECK_EQUAL(nrpvto, 3);
|
||||
BOOST_CHECK_EQUAL(ntpvto, 2);
|
||||
|
||||
const auto pvto = std::vector<double> {
|
||||
&tab[ ibpvto ] + 0,
|
||||
&tab[ ibpvto ] + ntpvto*nrpvto*nppvto*ncol
|
||||
};
|
||||
|
||||
const auto rs = std::vector<double> {
|
||||
&tab[ jbpvto ] + 0,
|
||||
&tab[ jbpvto ] + ntpvto*nrpvto
|
||||
};
|
||||
|
||||
const auto expect_pvto = makeTable(5, {
|
||||
// Po 1/Bo 1/(Bo*mu_o) d(1/Bo)/dPo d(1/(Bo*mu_o))/dPo
|
||||
//
|
||||
// Table 1 (Comp 1)
|
||||
1.014700000000000e+03, 7.722007722007722e-01, 9.303623761455088e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 1 (Comp 2) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
3.014700000000000e+03, 6.389776357827476e-01, 1.075719925560181e+00, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 1 (Comp 3) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
5.014700000000000e+03, 5.473453749315819e-01, 1.219032015437822e+00, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
9.014699999999999e+03, 5.757052389176741e-01, 9.123696337839526e-01, 7.089965996523064e-06, -7.666559541346725e-05,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// ==========================================================================================================================
|
||||
|
||||
// Table 2 (Comp 1)
|
||||
1.470000000000000e+01, 9.416195856873822e-01, 9.054034477763291e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 2) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
4.014699999999999e+03, 5.899705014749262e-01, 1.156804904852797e+00, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
9.014699999999999e+03, 6.333122229259025e-01, 8.558273282782466e-01, 8.668344290195251e-06, -6.019551531491001e-05,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 3, unused) --------------------------------------------------------------------------------------------------
|
||||
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
});
|
||||
|
||||
const auto expect_rs = makeTable(1, {
|
||||
// Table 1
|
||||
0.3710, 0.9300, 1.6180,
|
||||
|
||||
// Table 2
|
||||
0.0010, 1.2700, 2.0e+20,
|
||||
});
|
||||
|
||||
check_is_close(pvto, expect_pvto);
|
||||
check_is_close(rs , expect_rs );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (PVTO_USat_Full)
|
||||
{
|
||||
const auto rspec = std::string { R"(RUNSPEC
|
||||
DIMENS
|
||||
10 10 10 /
|
||||
|
||||
TITLE
|
||||
Test PVTO Output
|
||||
|
||||
OIL
|
||||
WATER
|
||||
|
||||
METRIC
|
||||
|
||||
TABDIMS
|
||||
-- NTSFUN NTPVT NSSFUN NPPVT NTFIP NRPVT
|
||||
1* 2 1* 5 1* 4
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto props = std::string { R"(
|
||||
PVTO
|
||||
20.59 50.00 1.10615 1.180
|
||||
75.00 1.10164 1.247
|
||||
100.00 1.09744 1.315
|
||||
125.00 1.09351 1.384
|
||||
150.00 1.08984 1.453 /
|
||||
28.19 70.00 1.12522 1.066
|
||||
95.00 1.12047 1.124
|
||||
120.00 1.11604 1.182
|
||||
145.00 1.11191 1.241
|
||||
170.00 1.10804 1.300 /
|
||||
36.01 90.00 1.14458 0.964
|
||||
115.00 1.13959 1.014
|
||||
140.00 1.13494 1.064
|
||||
165.00 1.13060 1.115
|
||||
190.00 1.12653 1.166 /
|
||||
44.09 110.00 1.16437 0.880
|
||||
135.00 1.15915 0.924
|
||||
160.00 1.15428 0.968
|
||||
185.00 1.14973 1.012
|
||||
210.00 1.14547 1.056 /
|
||||
/
|
||||
32.91 80.00 1.13304 1.04537
|
||||
114.00 1.12837 1.10009
|
||||
148.00 1.12401 1.15521
|
||||
182.00 1.11994 1.21063 /
|
||||
40.99 100.00 1.15276 0.97219
|
||||
134.00 1.14786 1.02086
|
||||
168.00 1.14328 1.06983
|
||||
202.00 1.13900 1.11901 /
|
||||
49.36 120.00 1.17297 0.91124
|
||||
154.00 1.16783 0.95496
|
||||
188.00 1.16303 0.99891
|
||||
222.00 1.15854 1.04301 /
|
||||
58.04 140.00 1.19374 0.85942
|
||||
174.00 1.18836 0.89902
|
||||
208.00 1.18334 0.93878
|
||||
242.00 1.17864 0.97864 /
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto es = parse(rspec, props);
|
||||
|
||||
auto tables = ::Opm::Tables(es.getUnits());
|
||||
tables.addPVTTables(es);
|
||||
|
||||
const auto& tabdims = tables.tabdims();
|
||||
const auto& tab = tables.tab();
|
||||
|
||||
const auto ibpvto = tabdims[ TABDIMS_IBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto jbpvto = tabdims[ TABDIMS_JBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto nppvto = tabdims[ TABDIMS_NPPVTO_ITEM ];
|
||||
const auto nrpvto = tabdims[ TABDIMS_NRPVTO_ITEM ];
|
||||
const auto ntpvto = tabdims[ TABDIMS_NTPVTO_ITEM ];
|
||||
const auto ncol = 5;
|
||||
|
||||
BOOST_CHECK_EQUAL(nppvto, 5);
|
||||
BOOST_CHECK_EQUAL(nrpvto, 4);
|
||||
BOOST_CHECK_EQUAL(ntpvto, 2);
|
||||
|
||||
const auto pvto = std::vector<double> {
|
||||
&tab[ ibpvto ] + 0,
|
||||
&tab[ ibpvto ] + ntpvto*nrpvto*nppvto*ncol
|
||||
};
|
||||
|
||||
const auto rs = std::vector<double> {
|
||||
&tab[ jbpvto ] + 0,
|
||||
&tab[ jbpvto ] + ntpvto*nrpvto
|
||||
};
|
||||
|
||||
const auto expect_pvto = makeTable(5, {
|
||||
// Po 1/Bo 1/(Bo*mu_o) d(1/Bo)/dPo d(1/(Bo*mu_o))/dPo
|
||||
//
|
||||
// Table 1 (Comp 1)
|
||||
5.000000000000001e+01, 9.040365230755323e-01, 7.661326466741798e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
7.500000000000000e+01, 9.077375549181221e-01, 7.279370929575959e-01, 1.480412737035941e-04, -1.527822148663356e-03,
|
||||
1.000000000000000e+02, 9.112115468727220e-01, 6.929365375457962e-01, 1.389596781839940e-04, -1.400022216471987e-03,
|
||||
1.250000000000000e+02, 9.144863787253888e-01, 6.607560539923329e-01, 1.309932741066744e-04, -1.287219342138530e-03,
|
||||
1.500000000000000e+02, 9.175658812302724e-01, 6.314975094496025e-01, 1.231801001953415e-04, -1.170341781709219e-03,
|
||||
|
||||
// Table 1 (Comp 2) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
7.000000000000000e+01, 8.887150957146157e-01, 8.336914593945738e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
9.500000000000001e+01, 8.924826189009969e-01, 7.940236822962605e-01, 1.507009274552472e-04, -1.586711083932530e-03,
|
||||
1.200000000000000e+02, 8.960252320705352e-01, 7.580585719716880e-01, 1.417045267815320e-04, -1.438604412982900e-03,
|
||||
1.450000000000000e+02, 8.993533649306149e-01, 7.247005358022682e-01, 1.331253144031886e-04, -1.334321446776793e-03,
|
||||
1.700000000000000e+02, 9.024944947835819e-01, 6.942265344489090e-01, 1.256451941186798e-04, -1.218960054134368e-03,
|
||||
|
||||
// Table 1 (Comp 3) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
9.000000000000001e+01, 8.736829229935872e-01, 9.063100860929328e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.150000000000000e+02, 8.775085776463464e-01, 8.653930746019195e-01, 1.530261861103677e-04, -1.636680459640534e-03,
|
||||
1.400000000000000e+02, 8.811038468993955e-01, 8.281051192663491e-01, 1.438107701219638e-04, -1.491518213422816e-03,
|
||||
1.650000000000000e+02, 8.844861135680170e-01, 7.932610884018088e-01, 1.352906667448606e-04, -1.393761234581614e-03,
|
||||
1.900000000000000e+02, 8.876816418559648e-01, 7.613050101680658e-01, 1.278211315179111e-04, -1.278243129349715e-03,
|
||||
|
||||
// Table 1 (Comp 4) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.100000000000000e+02, 8.588335322964350e-01, 9.759471957914034e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.350000000000000e+02, 8.627011171979468e-01, 9.336592177466957e-01, 1.547033960604739e-04, -1.691519121788311e-03,
|
||||
1.600000000000000e+02, 8.663409224798143e-01, 8.949802918179900e-01, 1.455922112746988e-04, -1.547157037148228e-03,
|
||||
1.850000000000000e+02, 8.697694241256644e-01, 8.594559526933443e-01, 1.371400658340026e-04, -1.420973564985826e-03,
|
||||
2.100000000000000e+02, 8.730040943892027e-01, 8.267084227170479e-01, 1.293868105415319e-04, -1.309901199051855e-03,
|
||||
|
||||
// ===========================================================================================================================
|
||||
|
||||
// Table 2 (Comp 1)
|
||||
8.000000000000000e+01, 8.825813740026830e-01, 8.442765470624592e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.140000000000000e+02, 8.862341253312299e-01, 8.056014738168967e-01, 1.074338626043212e-04, -1.137502154281250e-03,
|
||||
1.480000000000000e+02, 8.896718000729531e-01, 7.701385895836714e-01, 1.011080806389172e-04, -1.043026006859568e-03,
|
||||
1.820000000000000e+02, 8.929049770523422e-01, 7.375539818543586e-01, 9.509344057026681e-05, -9.583708155680233e-04,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 2) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.000000000000000e+02, 8.674832575731288e-01, 8.922980668111468e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.340000000000000e+02, 8.711863816144825e-01, 8.533847752037326e-01, 1.089154129809896e-04, -1.144508576688653e-03,
|
||||
1.680000000000000e+02, 8.746763697431950e-01, 8.175844477563677e-01, 1.026467096680142e-04, -1.052950807275436e-03,
|
||||
2.020000000000000e+02, 8.779631255487269e-01, 7.845891685943172e-01, 9.666928839799841e-05, -9.704493871191340e-04,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 3) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.200000000000000e+02, 8.525367230193440e-01, 9.355786873044905e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.540000000000000e+02, 8.562890146682309e-01, 8.966752687738030e-01, 1.103615190849091e-04, -1.144218192079043e-03,
|
||||
1.880000000000000e+02, 8.598230484166358e-01, 8.607612782098846e-01, 1.039421690707318e-04, -1.056293840115247e-03,
|
||||
2.220000000000000e+02, 8.631553507000190e-01, 8.275619128292337e-01, 9.800889068774162e-05, -9.764519229603183e-04,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 4) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.400000000000000e+02, 8.377033524888167e-01, 9.747310424342193e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.740000000000000e+02, 8.414958430105355e-01, 9.360145970173471e-01, 1.115438388740827e-04, -1.138718982849180e-03,
|
||||
2.080000000000000e+02, 8.450656616019064e-01, 9.001743343508666e-01, 1.049946644520869e-04, -1.054125372543546e-03,
|
||||
2.420000000000000e+02, 8.484354849657233e-01, 8.669536141642721e-01, 9.911245187696645e-05, -9.770800054880735e-04,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
});
|
||||
|
||||
const auto expect_rs = makeTable(1, {
|
||||
// Table 1
|
||||
20.59, 28.19, 36.01, 44.09,
|
||||
|
||||
// Table 2
|
||||
32.91, 40.99, 49.36, 58.04,
|
||||
});
|
||||
|
||||
check_is_close(pvto, expect_pvto);
|
||||
check_is_close(rs , expect_rs );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (PVTO_Exceed_Tabdims_Limits)
|
||||
{
|
||||
// This checks that Flow's extended table allocation scheme does what
|
||||
// it's supposed to do. Normally, one would announce the maximum sizes
|
||||
// in the RUNSPEC keyword 'TABDIMS'. Note that the maximum sizes need
|
||||
// to be big enough in order to run the case in ECLIPSE. Other than
|
||||
// NTPVT, Flow does not really care about these declared maximum sizes.
|
||||
|
||||
const auto rspec = std::string { R"(RUNSPEC
|
||||
DIMENS
|
||||
10 10 10 /
|
||||
|
||||
TITLE
|
||||
Test PVTO Output
|
||||
|
||||
OIL
|
||||
WATER
|
||||
|
||||
METRIC
|
||||
|
||||
TABDIMS
|
||||
-- NTSFUN NTPVT NSSFUN NPPVT NTFIP NRPVT
|
||||
1* 2 1* 2 1* 1
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto props = std::string { R"(
|
||||
PVTO
|
||||
20.59 50.00 1.10615 1.180
|
||||
75.00 1.10164 1.247 /
|
||||
28.19 70.00 1.12522 1.066 /
|
||||
44.09 110.00 1.16437 0.880
|
||||
135.00 1.15915 0.924
|
||||
160.00 1.15428 0.968
|
||||
185.00 1.14973 1.012
|
||||
210.00 1.14547 1.056 /
|
||||
/
|
||||
32.91 80.00 1.13304 1.04537
|
||||
114.00 1.12837 1.10009 /
|
||||
40.99 100.00 1.15276 0.97219
|
||||
134.00 1.14786 1.02086
|
||||
168.00 1.14328 1.06983 /
|
||||
49.36 120.00 1.17297 0.91124
|
||||
154.00 1.16783 0.95496 /
|
||||
58.04 140.00 1.19374 0.85942
|
||||
174.00 1.18836 0.89902 /
|
||||
/
|
||||
)" };
|
||||
|
||||
const auto es = parse(rspec, props);
|
||||
|
||||
auto tables = ::Opm::Tables(es.getUnits());
|
||||
tables.addPVTTables(es);
|
||||
|
||||
const auto& tabdims = tables.tabdims();
|
||||
const auto& tab = tables.tab();
|
||||
|
||||
const auto ibpvto = tabdims[ TABDIMS_IBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto jbpvto = tabdims[ TABDIMS_JBPVTO_OFFSET_ITEM ] - 1;
|
||||
const auto nppvto = tabdims[ TABDIMS_NPPVTO_ITEM ];
|
||||
const auto nrpvto = tabdims[ TABDIMS_NRPVTO_ITEM ];
|
||||
const auto ntpvto = tabdims[ TABDIMS_NTPVTO_ITEM ];
|
||||
const auto ncol = 5;
|
||||
|
||||
// Verify declared TABDIMS from input
|
||||
{
|
||||
const auto& tabd = es.runspec().tabdims();
|
||||
|
||||
BOOST_CHECK_EQUAL(tabd.getNumPVTTables(), 2);
|
||||
BOOST_CHECK_EQUAL(tabd.getNumRSNodes(), 1);
|
||||
BOOST_CHECK_EQUAL(tabd.getNumPressureNodes(), 2);
|
||||
}
|
||||
|
||||
// Verify active TABDIMS from dynamic sizes
|
||||
BOOST_CHECK_EQUAL(nppvto, 5); // Table 1, Comp 3
|
||||
BOOST_CHECK_EQUAL(nrpvto, 4); // Table 2
|
||||
BOOST_CHECK_EQUAL(ntpvto, 2);
|
||||
|
||||
const auto pvto = std::vector<double> {
|
||||
&tab[ ibpvto ] + 0,
|
||||
&tab[ ibpvto ] + ntpvto*nrpvto*nppvto*ncol
|
||||
};
|
||||
|
||||
const auto rs = std::vector<double> {
|
||||
&tab[ jbpvto ] + 0,
|
||||
&tab[ jbpvto ] + ntpvto*nrpvto
|
||||
};
|
||||
|
||||
const auto expect_pvto = makeTable(5, {
|
||||
// Po 1/Bo 1/(Bo*mu_o) d(1/Bo)/dPo d(1/(Bo*mu_o))/dPo
|
||||
//
|
||||
// Table 1 (Comp 1)
|
||||
5.000000000000001e+01, 9.040365230755323e-01, 7.661326466741798e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
7.500000000000000e+01, 9.077375549181221e-01, 7.279370929575959e-01, 1.480412737035941e-04, -1.527822148663356e-03,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 1 (Comp 2) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
7.000000000000000e+01, 8.887150957146157e-01, 8.336914593945738e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 1 (Comp 3) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.100000000000000e+02, 8.588335322964350e-01, 9.759471957914034e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.350000000000000e+02, 8.627011171979468e-01, 9.336592177466957e-01, 1.547033960604739e-04, -1.691519121788311e-03,
|
||||
1.600000000000000e+02, 8.663409224798143e-01, 8.949802918179900e-01, 1.455922112746988e-04, -1.547157037148228e-03,
|
||||
1.850000000000000e+02, 8.697694241256644e-01, 8.594559526933443e-01, 1.371400658340026e-04, -1.420973564985826e-03,
|
||||
2.100000000000000e+02, 8.730040943892027e-01, 8.267084227170479e-01, 1.293868105415319e-04, -1.309901199051855e-03,
|
||||
|
||||
// Table 1 (Comp 4 -- unused) ------------------------------------------------------------------------------------------------
|
||||
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// ===========================================================================================================================
|
||||
|
||||
// Table 2 (Comp 1)
|
||||
8.000000000000000e+01, 8.825813740026830e-01, 8.442765470624592e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.140000000000000e+02, 8.862341253312299e-01, 8.056014738168967e-01, 1.074338626043212e-04, -1.137502154281250e-03,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 2) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.000000000000000e+02, 8.674832575731288e-01, 8.922980668111468e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.340000000000000e+02, 8.711863816144825e-01, 8.533847752037326e-01, 1.089154129809896e-04, -1.144508576688653e-03,
|
||||
1.680000000000000e+02, 8.746763697431950e-01, 8.175844477563677e-01, 1.026467096680142e-04, -1.052950807275436e-03,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 3) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.200000000000000e+02, 8.525367230193440e-01, 9.355786873044905e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.540000000000000e+02, 8.562890146682309e-01, 8.966752687738030e-01, 1.103615190849091e-04, -1.144218192079043e-03,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
|
||||
// Table 2 (Comp 4) ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
1.400000000000000e+02, 8.377033524888167e-01, 9.747310424342193e-01, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
1.740000000000000e+02, 8.414958430105355e-01, 9.360145970173471e-01, 1.115438388740827e-04, -1.138718982849180e-03,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
|
||||
});
|
||||
|
||||
const auto expect_rs = makeTable(1, {
|
||||
// Table 1
|
||||
20.59, 28.19, 44.09, +2.0e20,
|
||||
|
||||
// Table 2
|
||||
32.91, 40.99, 49.36, 58.04,
|
||||
});
|
||||
|
||||
check_is_close(pvto, expect_pvto);
|
||||
check_is_close(rs , expect_rs );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END ()
|
||||
|
||||
// =====================================================================
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (Water)
|
||||
|
||||
BOOST_AUTO_TEST_CASE (PVTW)
|
||||
|
||||
Reference in New Issue
Block a user