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:
@@ -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 ) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace Opm {
|
||||
using ParentType::numTables;
|
||||
using ParentType::numRows;
|
||||
using ParentType::numColumns;
|
||||
using ParentType::evaluate;
|
||||
using ParentType::firstRecordIndex;
|
||||
using ParentType::numRecords;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace Opm {
|
||||
using ParentType::numTables;
|
||||
using ParentType::numRows;
|
||||
using ParentType::numColumns;
|
||||
using ParentType::evaluate;
|
||||
using ParentType::firstRecordIndex;
|
||||
using ParentType::numRecords;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user