Changed MultiRecordTable implementation:

- Will not use any getFlatXxx() methods.

  - Will fetch item0 and items1 for reference Rs value and table data
    respectively.
This commit is contained in:
Joakim Hove
2015-09-14 16:32:10 +02:00
parent 8e649ec7e6
commit 3dd8aad70b
8 changed files with 519 additions and 117 deletions

View File

@@ -16,6 +16,7 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <opm/parser/eclipse/EclipseState/Tables/MultiRecordTable.hpp>
namespace Opm {
@@ -23,112 +24,65 @@ namespace Opm {
* \brief Returns the number of tables which can be found in a
* given keyword.
*/
size_t MultiRecordTable::numTables(Opm::DeckKeywordConstPtr keyword)
{
size_t result = 0;
// first, go to the first record of the specified table. For this,
// we need to skip the right number of empty records...
for (size_t recordIdx = 0;
recordIdx < keyword->size();
++ recordIdx)
{
if (getNumFlatItems(keyword->getRecord(recordIdx)) == 0)
// each table ends with an empty record
++ result;
}
// the last empty record of a keyword seems to go MIA for some
// strange reason...
++result;
return result;
auto ranges = recordRanges(keyword);
return ranges.size();
}
std::vector<std::pair<size_t , size_t> > MultiRecordTable::recordRanges(Opm::DeckKeywordConstPtr keyword) {
std::vector<std::pair<size_t,size_t> > ranges;
size_t startRecord = 0;
size_t recordIndex = 0;
while (recordIndex < keyword->size()) {
auto item = keyword->getRecord(recordIndex)->getItem(0);
if (item->size( ) == 0) {
ranges.push_back( std::make_pair( startRecord , recordIndex ) );
startRecord = recordIndex + 1;
}
recordIndex++;
}
ranges.push_back( std::make_pair( startRecord , recordIndex ) );
return ranges;
}
// create table from first few items of multiple records
void MultiRecordTable::init(Opm::DeckKeywordConstPtr keyword,
const std::vector<std::string> &columnNames,
size_t tableIdx,
size_t firstEntityOffset)
size_t tableIdx)
{
auto ranges = recordRanges(keyword);
if (tableIdx >= ranges.size())
throw std::invalid_argument("Asked for table: " + std::to_string( tableIdx ) + " in keyword + " + keyword->name() + " which only has " + std::to_string( ranges.size() ) + " tables");
createColumns(columnNames);
m_recordRange = ranges[ tableIdx ];
for (size_t rowIdx = m_recordRange.first; rowIdx < m_recordRange.second; rowIdx++) {
Opm::DeckRecordConstPtr deckRecord = keyword->getRecord(rowIdx);
Opm::DeckItemConstPtr indexItem = deckRecord->getItem(0);
Opm::DeckItemConstPtr dataItem = deckRecord->getItem(1);
// first, go to the first record of the specified table. For this,
// we need to skip the right number of empty records...
size_t curTableIdx = 0;
for (m_firstRecordIdx = 0;
curTableIdx < tableIdx;
++ m_firstRecordIdx)
{
if (getNumFlatItems(keyword->getRecord(m_firstRecordIdx)) == 0)
// next table starts with an empty record
++ curTableIdx;
}
if (curTableIdx != tableIdx) {
throw std::runtime_error("keyword does not specify enough tables");
}
// find the number of records in the table
for (m_numRecords = 0;
m_firstRecordIdx + m_numRecords < keyword->size()
&& getNumFlatItems(keyword->getRecord(m_firstRecordIdx + m_numRecords)) != 0;
++ m_numRecords)
{
}
for (size_t rowIdx = m_firstRecordIdx; rowIdx < m_firstRecordIdx + m_numRecords; ++ rowIdx) {
// extract the actual data from the records of the keyword of
// the deck
Opm::DeckRecordConstPtr deckRecord =
keyword->getRecord(rowIdx);
if ( (getNumFlatItems(deckRecord) - firstEntityOffset) < numColumns())
throw std::runtime_error("Number of columns in the data file is"
"inconsistent with the ones specified");
for (size_t colIdx = 0; colIdx < numColumns(); ++colIdx) {
size_t deckItemIdx = colIdx + firstEntityOffset;
m_columns[colIdx].push_back(getFlatSiDoubleData(deckRecord, deckItemIdx));
m_valueDefaulted[colIdx].push_back(getFlatIsDefaulted(deckRecord, deckItemIdx));
m_columns[0].push_back(indexItem->getSIDouble(0));
m_valueDefaulted[0].push_back(indexItem->defaultApplied(0));
for (size_t colIdx = 1; colIdx < numColumns(); ++colIdx) {
m_columns[colIdx].push_back(dataItem->getSIDouble(colIdx - 1));
m_valueDefaulted[colIdx].push_back(dataItem->defaultApplied(colIdx - 1));
}
}
}
size_t MultiRecordTable::firstRecordIndex() const
{
return m_firstRecordIdx;
return m_recordRange.first;
}
size_t MultiRecordTable::numRecords() const
{
return m_numRecords;
return m_recordRange.second - m_recordRange.first;
}
size_t MultiRecordTable::getNumFlatItems(Opm::DeckRecordConstPtr deckRecord)
{
int result = 0;
for (unsigned i = 0; i < deckRecord->size(); ++ i) {
Opm::DeckItemConstPtr item(deckRecord->getItem(i));
if (item->size() == 0 || item->defaultApplied(0))
return result;
result += item->size();
}
return result;
}
double MultiRecordTable::getFlatSiDoubleData(Opm::DeckRecordConstPtr deckRecord, unsigned flatItemIdx) const
{
unsigned itemFirstFlatIdx = 0;
for (unsigned i = 0; i < deckRecord->size(); ++ i) {
Opm::DeckItemConstPtr item = deckRecord->getItem(i);
if (itemFirstFlatIdx + item->size() > flatItemIdx)
return item->getSIDouble(flatItemIdx - itemFirstFlatIdx);
else
itemFirstFlatIdx += item->size();
}
throw std::range_error("Tried to access out-of-range flat item");
}
}

View File

@@ -44,8 +44,7 @@ namespace Opm {
*/
void init(Opm::DeckKeywordConstPtr keyword,
const std::vector<std::string> &columnNames,
size_t tableIndex,
size_t firstEntityOffset);
size_t tableIndex);
public:
MultiRecordTable() = default;
@@ -54,9 +53,8 @@ namespace Opm {
// DO NOT TRY TO CALL THIS METHOD! it is only for the unit tests!
void initFORUNITTESTONLY(Opm::DeckKeywordConstPtr keyword,
const std::vector<std::string> &columnNames,
size_t tableIndex,
size_t firstEntityOffset)
{ init(keyword, columnNames, tableIndex, firstEntityOffset); }
size_t tableIndex)
{ init(keyword, columnNames, tableIndex); }
#endif
/*!
@@ -64,7 +62,7 @@ namespace Opm {
* given keyword.
*/
static size_t numTables(Opm::DeckKeywordConstPtr keyword);
static std::vector<std::pair<size_t , size_t> > recordRanges(Opm::DeckKeywordConstPtr keyword);
/*!
* \brief Return the index of the first record which applies
* for this table object.
@@ -78,11 +76,7 @@ namespace Opm {
size_t numRecords() const;
private:
static size_t getNumFlatItems(Opm::DeckRecordConstPtr deckRecord);
double getFlatSiDoubleData(Opm::DeckRecordConstPtr deckRecord, unsigned flatItemIdx) const;
size_t m_firstRecordIdx;
size_t m_numRecords;
std::pair<size_t, size_t> m_recordRange;
};
typedef std::shared_ptr<MultiRecordTable> MultiRecordTablePtr;

View File

@@ -40,10 +40,9 @@ namespace Opm {
*/
void init(Opm::DeckKeywordConstPtr keyword, size_t tableIdx)
{
ParentType::init(keyword,
std::vector<std::string>{"P", "RV", "BG", "MUG"},
tableIdx,
/*firstEntryOffset=*/0);
MultiRecordTable::init(keyword,
std::vector<std::string>{"P", "RV", "BG", "MUG"},
tableIdx);
MultiRecordTable::checkNonDefaultable("P");
MultiRecordTable::checkMonotonic("P", /*isAscending=*/true);
@@ -53,24 +52,24 @@ namespace Opm {
}
public:
using ParentType::numTables;
using ParentType::numRows;
using ParentType::numColumns;
using ParentType::evaluate;
using ParentType::firstRecordIndex;
using ParentType::numRecords;
using MultiRecordTable::numTables;
using MultiRecordTable::numRows;
using MultiRecordTable::numColumns;
using MultiRecordTable::evaluate;
using MultiRecordTable::firstRecordIndex;
using MultiRecordTable::numRecords;
const std::vector<double> &getPressureColumn() const
{ return ParentType::getColumn(0); }
{ return MultiRecordTable::getColumn(0); }
const std::vector<double> &getOilSolubilityColumn() const
{ return ParentType::getColumn(1); }
{ return MultiRecordTable::getColumn(1); }
const std::vector<double> &getGasFormationFactorColumn() const
{ return ParentType::getColumn(2); }
{ return MultiRecordTable::getColumn(2); }
const std::vector<double> &getGasViscosityColumn() const
{ return ParentType::getColumn(3); }
{ return MultiRecordTable::getColumn(3); }
};
}

View File

@@ -37,15 +37,13 @@ namespace Opm {
/*!
* \brief Read the per record table of the PVTO keyword and
* provide some convenience methods for it.
*
* The first value of the record (-> Rs) is skipped.
*/
void init(Opm::DeckKeywordConstPtr keyword, int tableIdx)
{
ParentType::init(keyword,
std::vector<std::string>{"RS", "P", "BO", "MU"},
tableIdx,
/*firstEntryOffset=*/0);
MultiRecordTable::init(keyword,
std::vector<std::string>{"RS", "P", "BO", "MU"},
tableIdx);
MultiRecordTable::checkNonDefaultable("RS");
MultiRecordTable::checkMonotonic("RS", /*isAscending=*/true);

View File

@@ -1,4 +1,4 @@
foreach(tapp TableManagerTests TabdimsTests)
foreach(tapp TableManagerTests TabdimsTests MultiRecordTableTests)
opm_add_test(run${tapp} SOURCES ${tapp}.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
endforeach()

View File

@@ -0,0 +1,117 @@
/*
Copyright (C) 2013 by Andreas Lauser
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_MODULE MultiRecordTableTests
#include <opm/core/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/core/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Parser/ParserKeywords.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
// generic table classes
#include <opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/MultiRecordTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/FullTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
// keyword specific table classes
#include <opm/parser/eclipse/EclipseState/Tables/PvtoTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/SwofTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/SgofTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/PlyadsTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/VFPProdTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/VFPInjTable.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <stdexcept>
#include <iostream>
using namespace Opm;
BOOST_AUTO_TEST_CASE( MultiRecordNumTables1 ) {
ParserPtr parser(new Parser());
boost::filesystem::path deckFile("testdata/integration_tests/TABLES/PVTO1.DATA");
ParseMode parseMode;
DeckPtr deck = parser->parseFile(deckFile.string(), parseMode);
BOOST_CHECK_EQUAL( MultiRecordTable::numTables( deck->getKeyword<ParserKeywords::PVTO>()) , 1);
auto ranges = MultiRecordTable::recordRanges( deck->getKeyword<ParserKeywords::PVTO>() );
auto range = ranges[0];
BOOST_CHECK_EQUAL( range.first , 0 );
BOOST_CHECK_EQUAL( range.second , 2 );
}
BOOST_AUTO_TEST_CASE( MultiRecordNumTables2 ) {
ParserPtr parser(new Parser());
boost::filesystem::path deckFile("testdata/integration_tests/TABLES/PVTO2.DATA");
ParseMode parseMode;
DeckPtr deck = parser->parseFile(deckFile.string(), parseMode);
BOOST_CHECK_EQUAL( MultiRecordTable::numTables( deck->getKeyword<ParserKeywords::PVTO>()) , 3);
auto ranges = MultiRecordTable::recordRanges( deck->getKeyword<ParserKeywords::PVTO>() );
auto range1 = ranges[0];
BOOST_CHECK_EQUAL( range1.first , 0 );
BOOST_CHECK_EQUAL( range1.second , 41 );
auto range2 = ranges[1];
BOOST_CHECK_EQUAL( range2.first , 42 );
BOOST_CHECK_EQUAL( range2.second , 43 );
auto range3 = ranges[2];
BOOST_CHECK_EQUAL( range3.first , 44 );
BOOST_CHECK_EQUAL( range3.second , 46 );
}
BOOST_AUTO_TEST_CASE( MultiRecordNumTables3 ) {
const char *deckData =
"TABDIMS\n"
"1 2 /\n"
"\n"
"PVTO\n"
" 1 2 3 4"
" 5 6 7/\n"
" 8 9 10 11 /\n"
"/\n"
"12 13 14 15\n"
" 16 17 18/\n"
"19 20 21 22/\n"
"/\n";
Opm::ParserPtr parser(new Opm::Parser);
Opm::DeckConstPtr deck(parser->parseString(deckData, Opm::ParseMode()));
auto ranges = MultiRecordTable::recordRanges( deck->getKeyword<ParserKeywords::PVTO>() );
BOOST_CHECK_EQUAL( 2 ,ranges.size() );
auto range1 = ranges[0];
BOOST_CHECK_EQUAL( range1.first , 0 );
BOOST_CHECK_EQUAL( range1.second , 2 );
auto range2 = ranges[1];
BOOST_CHECK_EQUAL( range2.first , 3 );
BOOST_CHECK_EQUAL( range2.second , 5 );
}

View File

@@ -0,0 +1,44 @@
RUNSPEC
TITLE
SIMPLE TEST
DIMENS
9 9 2 /
OIL
WATER
GAS
DISGAS
VAPOIL
METRIC
EQLDIMS
1 100 2 1 1 /
TABDIMS
1 1 33 60 16 60 /
PROPS ===============================================================
PVTO
-- RSO PRESSURE B-OIL VISCOSITY
-- (BAR) (CP)
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 /
/

View File

@@ -0,0 +1,296 @@
RUNSPEC
TITLE
SIMPLE TEST
DIMENS
9 9 2 /
OIL
WATER
GAS
DISGAS
VAPOIL
METRIC
EQLDIMS
1 100 2 1 1 /
TABDIMS
1 3 33 60 16 60 /
PROPS ===============================================================
PVTO
-- RSO PRESSURE B-OIL VISCOSITY
-- (BAR) (CP)
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 /
52.46 130.00 1.18467 0.805
155.00 1.17921 0.843
180.00 1.17413 0.882
205.00 1.16937 0.920
230.00 1.16491 0.959 /
61.13 150.00 1.20555 0.746
175.00 1.19985 0.780
200.00 1.19454 0.814
225.00 1.18958 0.849
250.00 1.18492 0.883 /
70.14 170.00 1.22704 0.698
195.00 1.22111 0.729
220.00 1.21558 0.759
245.00 1.21040 0.790
270.00 1.20555 0.821 /
79.50 190.00 1.24922 0.658
215.00 1.24305 0.686
240.00 1.23729 0.714
265.00 1.23190 0.742
290.00 1.22685 0.770 /
89.24 210.00 1.27214 0.637
235.00 1.26573 0.664
260.00 1.25974 0.693
285.00 1.25414 0.725
310.00 1.24888 0.760 /
99.39 230.00 1.29586 0.622
255.00 1.28921 0.641
280.00 1.28300 0.661
305.00 1.27718 0.680
330.00 1.27171 0.699 /
110.41 250.80 1.32148 0.610
275.80 1.31457 0.628
300.80 1.30812 0.647
325.80 1.30207 0.665
350.80 1.29638 0.682 /
120.32 268.42 1.34449 0.576
293.42 1.33735 0.593
318.42 1.33068 0.609
343.42 1.32442 0.626
368.42 1.31853 0.642 /
130.23 285.33 1.36737 0.5335
310.33 1.36001 0.5487
335.33 1.35313 0.5638
360.33 1.34667 0.5787
385.33 1.34059 0.5934 /
140.12 301.59 1.39015 0.4956
326.59 1.38257 0.5094
351.59 1.37548 0.5230
376.59 1.36882 0.5365
401.59 1.36255 0.5498 /
150.01 317.23 1.41282 0.4614
342.23 1.40503 0.4739
367.23 1.39773 0.4863
392.23 1.39088 0.4986
417.23 1.38443 0.5107 /
159.89 332.29 1.43539 0.43042
357.29 1.42739 0.44183
382.29 1.41990 0.45312
407.29 1.41286 0.46430
432.29 1.40622 0.47537 /
169.76 346.80 1.45788 0.41191
371.80 1.44967 0.42260
396.80 1.44198 0.43318
421.80 1.43475 0.44365
446.80 1.42794 0.45402 /
179.63 360.80 1.48028 0.39503
385.80 1.47187 0.40508
410.80 1.46398 0.41502
435.80 1.45657 0.42487
460.80 1.44958 0.43461 /
189.48 374.31 1.50260 0.37959
399.31 1.49399 0.38907
424.31 1.48591 0.39845
449.31 1.47832 0.40773
474.31 1.47116 0.41692 /
199.34 387.36 1.52484 0.36543
412.36 1.51603 0.37439
437.36 1.50777 0.38326
462.36 1.50000 0.39203
487.36 1.49267 0.40072 /
209.18 399.99 1.54700 0.35239
424.99 1.53800 0.36089
449.99 1.52956 0.36929
474.99 1.52161 0.37762
499.99 1.51411 0.38585 /
219.02 412.21 1.56910 0.34035
437.21 1.55991 0.34843
462.21 1.55128 0.35642
487.21 1.54316 0.36433
512.21 1.53549 0.37216 /
228.85 424.05 1.59112 0.32921
449.05 1.58174 0.33691
474.05 1.57294 0.34453
499.05 1.56464 0.35206
524.05 1.55681 0.35952 /
238.67 435.53 1.61307 0.31888
460.53 1.60351 0.32623
485.53 1.59453 0.33350
510.53 1.58606 0.34070
535.53 1.57807 0.34782 /
248.48 446.68 1.63496 0.30927
471.68 1.62522 0.31630
496.68 1.61606 0.32326
521.68 1.60743 0.33014
546.68 1.59927 0.33695 /
258.29 457.51 1.65678 0.30032
482.51 1.64686 0.30706
507.51 1.63753 0.31373
532.51 1.62873 0.32032
557.51 1.62042 0.32685 /
268.09 468.04 1.67853 0.29196
493.04 1.66843 0.29843
518.04 1.65893 0.30483
543.04 1.64997 0.31117
568.04 1.64150 0.31743 /
277.89 478.30 1.70022 0.28414
503.30 1.68994 0.29037
528.30 1.68028 0.29652
553.30 1.67116 0.30261
578.30 1.66253 0.30864 /
287.68 488.30 1.72184 0.27681
513.30 1.71139 0.28281
538.30 1.70156 0.28874
563.30 1.69228 0.29460
588.30 1.68350 0.30040 /
297.46 498.06 1.74339 0.26994
523.06 1.73277 0.27572
548.06 1.72278 0.28144
573.06 1.71334 0.28709
598.06 1.70442 0.29269 /
307.23 507.59 1.76487 0.26347
532.59 1.75409 0.26906
557.59 1.74393 0.27458
582.59 1.73434 0.28004
607.59 1.72527 0.28544 /
317.00 516.92 1.78628 0.25738
541.92 1.77533 0.26279
566.92 1.76502 0.26812
591.92 1.75528 0.27340
616.92 1.74606 0.27863 /
326.76 526.06 1.80761 0.25165
551.06 1.79651 0.25688
576.06 1.78604 0.26204
601.06 1.77615 0.26716
626.06 1.76679 0.27221 /
336.51 535.02 1.82887 0.24623
560.02 1.81761 0.25130
585.02 1.80699 0.25631
610.02 1.79696 0.26126
635.02 1.78746 0.26616 /
346.26 543.83 1.85005 0.24112
568.83 1.83864 0.24603
593.83 1.82787 0.25089
618.83 1.81770 0.25570
643.83 1.80806 0.26045 /
356.00 552.49 1.87115 0.23628
577.49 1.85959 0.24105
602.49 1.84868 0.24577
627.49 1.83836 0.25043
652.49 1.82858 0.25505 /
365.73 561.04 1.89217 0.23170
586.04 1.88046 0.23634
611.04 1.86940 0.24092
636.04 1.85895 0.24546
661.04 1.84904 0.24994 /
375.46 569.48 1.91309 0.22736
594.48 1.90124 0.23187
619.48 1.89004 0.23633
644.48 1.87946 0.24074
669.48 1.86942 0.24510 /
385.18 577.82 1.93391 0.22325
602.82 1.92192 0.22764
627.82 1.91060 0.23198
652.82 1.89988 0.23627
677.82 1.88971 0.24052 /
394.89 586.09 1.95464 0.21934
611.09 1.94252 0.22362
636.09 1.93106 0.22785
661.09 1.92021 0.23204
686.09 1.90993 0.23617 /
404.60 594.29 1.97527 0.21564
619.29 1.96301 0.21981
644.29 1.95143 0.22393
669.29 1.94046 0.22801
694.29 1.93005 0.23204 / --40
/ --41
404.60 594.29 1.97527 0.21564
619.29 1.96301 0.21981
644.29 1.95143 0.22393
669.29 1.94046 0.22801
694.29 1.93005 0.23204 / --42
/ --43
404.60 594.29 1.97527 0.21564
619.29 1.96301 0.21981
644.29 1.95143 0.22393
669.29 1.94046 0.22801
694.29 1.93005 0.23204 / --44
404.60 594.29 1.97527 0.21564
619.29 1.96301 0.21981
644.29 1.95143 0.22393
669.29 1.94046 0.22801
694.29 1.93005 0.23204 / --45
/ --46