opm-common/tests/parser/PvtxTableTests.cpp

226 lines
7.6 KiB
C++
Raw Normal View History

/*
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/>.
*/
2015-12-21 08:10:31 -06:00
#define BOOST_TEST_MODULE PvtxTableTests
#include <boost/test/unit_test.hpp>
#include <boost/version.hpp>
#include <opm/input/eclipse/Parser/ParserKeywords/P.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Units/UnitSystem.hpp>
// generic table classes
#include <opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/PvtxTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
// keyword specific table classes
//#include <opm/input/eclipse/EclipseState/Tables/PvtoTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SwofTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SgofTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/PlyadsTable.hpp>
#include <opm/input/eclipse/Schedule/VFPProdTable.hpp>
#include <opm/input/eclipse/Schedule/VFPInjTable.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <filesystem>
#include <stdexcept>
#include <iostream>
using namespace Opm;
Redesign cmake Tune the makefile according to new principles, which adds a few bells and whistles and for clarity. Synopsis: * The dependency on opm-common is completely gone. This is reflected in travis and appveyor as well. No non-kitware cmake modules are used. * Directories are flattened, quite a bit - source code is located in the lib/ directory if it belongs to opm-parser, and external/ if third party. * The sibling build feature is implemented through cmake's export(PACKAGE) rather than implicitly looking through source files. * Targets explicitly set required public and private include directories, compile options and definitions, which cmake will handle and propagate * opm-parser-config.cmake for downstream users is now provided. * Dependencies are set up using targets. In the future, when cmake 3.x+ can be used, these should be either targets from newer Find modules, or interface libraries. * Fewer system specific assumptions are coded in, instead we assume cmake or users set up system specific details. * All module wide configuration and looking up libraries is handled in the root makefile - all sub directories only set up libraries and compile options for the module in question. * Targets are defined and links handled transitively because cmake now is told about them. ${module_LIBRARIES} variables are gone. This is largely guided by the principles outlined in https://rix0r.nl/blog/2015/08/13/cmake-guide/ Most source files are just moved - if they have some content change then it's nothing more than include fixes or similar in order to make them compile.
2017-05-23 05:03:08 -05:00
inline std::string prefix() {
#if BOOST_VERSION / 100000 == 1 && BOOST_VERSION / 100 % 1000 < 71
return boost::unit_test::framework::master_test_suite().argv[2];
#else
Redesign cmake Tune the makefile according to new principles, which adds a few bells and whistles and for clarity. Synopsis: * The dependency on opm-common is completely gone. This is reflected in travis and appveyor as well. No non-kitware cmake modules are used. * Directories are flattened, quite a bit - source code is located in the lib/ directory if it belongs to opm-parser, and external/ if third party. * The sibling build feature is implemented through cmake's export(PACKAGE) rather than implicitly looking through source files. * Targets explicitly set required public and private include directories, compile options and definitions, which cmake will handle and propagate * opm-parser-config.cmake for downstream users is now provided. * Dependencies are set up using targets. In the future, when cmake 3.x+ can be used, these should be either targets from newer Find modules, or interface libraries. * Fewer system specific assumptions are coded in, instead we assume cmake or users set up system specific details. * All module wide configuration and looking up libraries is handled in the root makefile - all sub directories only set up libraries and compile options for the module in question. * Targets are defined and links handled transitively because cmake now is told about them. ${module_LIBRARIES} variables are gone. This is largely guided by the principles outlined in https://rix0r.nl/blog/2015/08/13/cmake-guide/ Most source files are just moved - if they have some content change then it's nothing more than include fixes or similar in order to make them compile.
2017-05-23 05:03:08 -05:00
return boost::unit_test::framework::master_test_suite().argv[1];
#endif
Redesign cmake Tune the makefile according to new principles, which adds a few bells and whistles and for clarity. Synopsis: * The dependency on opm-common is completely gone. This is reflected in travis and appveyor as well. No non-kitware cmake modules are used. * Directories are flattened, quite a bit - source code is located in the lib/ directory if it belongs to opm-parser, and external/ if third party. * The sibling build feature is implemented through cmake's export(PACKAGE) rather than implicitly looking through source files. * Targets explicitly set required public and private include directories, compile options and definitions, which cmake will handle and propagate * opm-parser-config.cmake for downstream users is now provided. * Dependencies are set up using targets. In the future, when cmake 3.x+ can be used, these should be either targets from newer Find modules, or interface libraries. * Fewer system specific assumptions are coded in, instead we assume cmake or users set up system specific details. * All module wide configuration and looking up libraries is handled in the root makefile - all sub directories only set up libraries and compile options for the module in question. * Targets are defined and links handled transitively because cmake now is told about them. ${module_LIBRARIES} variables are gone. This is largely guided by the principles outlined in https://rix0r.nl/blog/2015/08/13/cmake-guide/ Most source files are just moved - if they have some content change then it's nothing more than include fixes or similar in order to make them compile.
2017-05-23 05:03:08 -05:00
}
2015-12-21 08:10:31 -06:00
BOOST_AUTO_TEST_CASE( PvtxNumTables1 ) {
Parser parser;
std::filesystem::path deckFile(prefix() + "TABLES/PVTX1.DATA");
auto deck = parser.parseFile(deckFile.string());
BOOST_CHECK_EQUAL( PvtxTable::numTables( deck.get<ParserKeywords::PVTO>().back()) , 1);
auto ranges = PvtxTable::recordRanges( deck.get<ParserKeywords::PVTO>().back() );
auto range = ranges[0];
BOOST_CHECK_EQUAL( range.first , 0 );
BOOST_CHECK_EQUAL( range.second , 2 );
}
2015-12-21 08:10:31 -06:00
BOOST_AUTO_TEST_CASE( PvtxNumTables2 ) {
Parser parser;
std::filesystem::path deckFile(prefix() + "TABLES/PVTO2.DATA");
auto deck = parser.parseFile(deckFile.string());
BOOST_CHECK_EQUAL( PvtxTable::numTables( deck.get<ParserKeywords::PVTO>().back()) , 3);
auto ranges = PvtxTable::recordRanges( deck.get<ParserKeywords::PVTO>().back() );
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 );
}
2015-12-21 08:10:31 -06:00
BOOST_AUTO_TEST_CASE( PvtxNumTables3 ) {
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::Parser parser;
auto deck = parser.parseString(deckData);
auto ranges = PvtxTable::recordRanges( deck.get<ParserKeywords::PVTO>().back() );
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 );
}
2015-12-21 08:10:31 -06:00
BOOST_AUTO_TEST_CASE( PVTOSaturatedTable ) {
Parser parser;
std::filesystem::path deckFile(prefix() + "TABLES/PVTX1.DATA");
auto deck = parser.parseFile(deckFile.string());
Opm::TableManager tables(deck);
2015-12-21 08:10:31 -06:00
const auto& pvtoTables = tables.getPvtoTables( );
const auto& pvtoTable = pvtoTables[0];
const auto& saturatedTable = pvtoTable.getSaturatedTable( );
BOOST_CHECK_EQUAL( saturatedTable.numColumns( ) , 4 );
BOOST_CHECK_EQUAL( saturatedTable.numRows( ) , 2 );
BOOST_CHECK_EQUAL( saturatedTable.get(0 , 0) , 20.59 );
BOOST_CHECK_EQUAL( saturatedTable.get(0 , 1) , 28.19 );
{
int num = 0;
UnitSystem units( UnitSystem::UnitType::UNIT_TYPE_METRIC );
for (const auto& table : pvtoTable) {
if (num == 0) {
{
const auto& col = table.getColumn(0);
BOOST_CHECK_EQUAL( col.size() , 5 );
BOOST_CHECK_CLOSE( col[0] , units.to_si( UnitSystem::measure::pressure , 50 ) , 1e-3);
BOOST_CHECK_CLOSE( col[4] , units.to_si( UnitSystem::measure::pressure , 150) , 1e-3);
}
{
const auto& col = table.getColumn(2);
BOOST_CHECK_CLOSE( col[0] , units.to_si( UnitSystem::measure::viscosity , 1.180) , 1e-3);
BOOST_CHECK_CLOSE( col[4] , units.to_si( UnitSystem::measure::viscosity , 1.453) , 1e-3);
}
}
if (num == 1) {
const auto& col = table.getColumn(0);
BOOST_CHECK_EQUAL( col.size() , 5 );
BOOST_CHECK_CLOSE( col[0] , units.to_si( UnitSystem::measure::pressure , 70 ), 1e-3);
BOOST_CHECK_CLOSE( col[4] , units.to_si( UnitSystem::measure::pressure , 170 ), 1e-3);
}
num++;
}
BOOST_CHECK_EQUAL( num , pvtoTable.size() );
}
2015-12-21 08:10:31 -06:00
}
BOOST_AUTO_TEST_CASE( PVTGSaturatedTable ) {
Parser parser;
std::filesystem::path deckFile(prefix() + "TABLES/PVTX1.DATA");
auto deck = parser.parseFile(deckFile.string());
Opm::TableManager tables(deck);
2015-12-21 08:10:31 -06:00
const auto& pvtgTables = tables.getPvtgTables( );
const auto& pvtgTable = pvtgTables[0];
const auto& saturatedTable = pvtgTable.getSaturatedTable( );
BOOST_CHECK_EQUAL( saturatedTable.numColumns( ) , 4 );
BOOST_CHECK_EQUAL( saturatedTable.numRows( ) , 2 );
BOOST_CHECK_EQUAL( saturatedTable.get(1 , 0) , 0.00002448 );
BOOST_CHECK_EQUAL( saturatedTable.get(1 , 1) , 0.00000628 );
}
BOOST_AUTO_TEST_CASE( PVTWTable ) {
const std::string input = R"(
RUNSPEC
DIMENS
10 10 10 /
TABDIMS
1 2 /
PROPS
PVTW
3600.0000 1.00341 3.00E-06 0.52341 0.00E-01 /
3900 1 2.67E-06 0.56341 1.20E-07 /
)";
auto deck = Parser().parseString( input );
TableManager tables( deck );
const auto& pvtw = tables.getPvtwTable();
const auto& rec1 = pvtw[0];
const auto& rec2 = pvtw.at(1);
BOOST_CHECK_THROW( pvtw.at(2), std::out_of_range );
BOOST_CHECK_CLOSE( 3600.00, rec1.reference_pressure / 1e5, 1e-5 );
BOOST_CHECK_CLOSE( 1.00341, rec1.volume_factor, 1e-5 );
BOOST_CHECK_CLOSE( 3.0e-06, rec1.compressibility * 1e5, 1e-5 );
BOOST_CHECK_CLOSE( 0.52341, rec1.viscosity * 1e3, 1e-5 );
BOOST_CHECK_CLOSE( 0.0e-01, rec1.viscosibility * 1e5, 1e-5 );
BOOST_CHECK_CLOSE( 3900, rec2.reference_pressure / 1e5, 1e-5 );
BOOST_CHECK_CLOSE( 1.0, rec2.volume_factor, 1e-5 );
BOOST_CHECK_CLOSE( 2.67e-06, rec2.compressibility * 1e5, 1e-5 );
BOOST_CHECK_CLOSE( 0.56341, rec2.viscosity * 1e3, 1e-5 );
BOOST_CHECK_CLOSE( 1.20e-07, rec2.viscosibility * 1e5, 1e-5 );
}