make it possible to evaluate some tables using linear interpolation

... and constant interpolation at the fringes. this kind of evaluation
in between sampling point only makes sense for tables where the first
column is strictly monotonic, though.
This commit is contained in:
Andreas Lauser
2014-09-16 17:15:29 +02:00
parent 1bbe775831
commit fd6209a34d
21 changed files with 83 additions and 2 deletions

View File

@@ -76,6 +76,10 @@ static void check_SwofTable(ParserPtr parser) {
BOOST_CHECK_EQUAL(0.0, swofTable.getKrwColumn()[0]);
BOOST_CHECK_EQUAL(1.0, swofTable.getKrowColumn()[0]);
BOOST_CHECK_EQUAL(0.0, swofTable.getPcowColumn()[0]);
BOOST_CHECK_CLOSE(0.00, swofTable.evaluate("KRW", -0.1), 1e-8);
BOOST_CHECK_CLOSE(0.05, swofTable.evaluate("KRW", 0.15), 1e-8);
BOOST_CHECK_CLOSE(1.00, swofTable.evaluate("KRW", 1.1), 1e-8);
}
BOOST_AUTO_TEST_CASE( parse_SWOF_OK ) {

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the ENKRVD keyword and provide some convenience

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the ENPTVD keyword and provide some convenience

View File

@@ -31,7 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the IMKRVD keyword and provide some convenience
* methods for it.

View File

@@ -31,7 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the IMPTVD keyword and provide some convenience
* methods for it.

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the PLYADS keyword and provide some convenience

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the PLYMAX keyword and provide some convenience

View File

@@ -32,6 +32,9 @@ namespace Opm {
using ParentType::numRows;
using ParentType::numColumns;
// since this keyword is not necessarily monotonic, it cannot be evaluated!
//using ParentType::evaluate;
/*!
* \brief Read the PLYROCK keyword and provide some convenience
* methods for it.

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the PLYVISC keyword and provide some convenience

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the PVDG keyword and provide some convenience

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the PVDO keyword and provide some convenience

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the per record table of the PVTG keyword and

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
using ParentType::firstRecordIndex;
using ParentType::numRecords;

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the per record table of the PVTO keyword and

View File

@@ -45,6 +45,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
using ParentType::firstRecordIndex;
using ParentType::numRecords;

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the ROCKTAB keyword and provide some convenience

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the SGOF keyword and provide some convenience

View File

@@ -74,6 +74,56 @@ const std::vector<double> &SingleRecordTable::getColumn(size_t colIdx) const
return m_columns[colIdx];
}
double SingleRecordTable::evaluate(const std::string& columnName, double xPos) const
{
const std::vector<double>& xColumn = getColumn(0);
const std::vector<double>& yColumn = getColumn(columnName);
bool isDescending = false;
if (xColumn.front() > xColumn.back())
isDescending = true;
// handle the constant interpolation cases
if (isDescending) {
if (xColumn.front() < xPos)
return yColumn.front();
else if (xPos < xColumn.back())
return yColumn.back();
}
else {
if (xPos < xColumn.front())
return yColumn.front();
else if (xColumn.back() < xPos)
return yColumn.back();
}
// find the interval which contains the x position using interval halfing
size_t lowIntervalIdx = 0;
size_t intervalIdx = (xColumn.size() - 1)/2;
size_t highIntervalIdx = xColumn.size()-1;
while (lowIntervalIdx + 1 < highIntervalIdx) {
if (isDescending) {
if (xColumn[intervalIdx] < xPos)
highIntervalIdx = intervalIdx;
else
lowIntervalIdx = intervalIdx;
}
else {
if (xColumn[intervalIdx] < xPos)
lowIntervalIdx = intervalIdx;
else
highIntervalIdx = intervalIdx;
}
intervalIdx = (highIntervalIdx + lowIntervalIdx)/2;
}
// use linear interpolation if the x position is in between two non-defaulted
// values, else use the non-defaulted value
double alpha = (xPos - xColumn[intervalIdx])/(xColumn[intervalIdx + 1] - xColumn[intervalIdx]);
return yColumn[intervalIdx]*(1-alpha) + yColumn[intervalIdx + 1]*alpha;
}
void SingleRecordTable::createColumns_(const std::vector<std::string> &columnNames)
{
// Allocate column names. TODO (?): move the column names into

View File

@@ -54,6 +54,13 @@ namespace Opm {
const std::vector<double> &getColumn(const std::string &name) const;
const std::vector<double> &getColumn(size_t colIdx) const;
/*!
* \brief Evaluate a column of the table at a given position.
*
* This method uses linear interpolation and always uses the first column as the
* X coordinate.
*/
double evaluate(const std::string& columnName, double xPos) const;
protected:
void createColumns_(const std::vector<std::string> &columnNames);
bool isDefaulted_(const std::string& columnName, size_t rowIdx) const

View File

@@ -31,6 +31,7 @@ namespace Opm {
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
/*!
* \brief Read the SWOF keyword and provide some convenience

View File

@@ -32,6 +32,9 @@ namespace Opm {
using ParentType::numRows;
using ParentType::numColumns;
// this table is not necessarily monotonic, so it cannot be evaluated!
//using ParentType::evaluate;
/*!
* \brief Read the TLMIXPAR keyword and provide some convenience
* methods for it.