Merge pull request #1152 from joakim-hove/deckkeyword-unit

Deckkeyword unit
This commit is contained in:
Joakim Hove
2019-10-24 08:43:18 +02:00
committed by GitHub
7 changed files with 135 additions and 84 deletions

View File

@@ -42,7 +42,7 @@ namespace Opm {
explicit DeckKeyword(const ParserKeyword& parserKeyword);
DeckKeyword(const ParserKeyword& parserKeyword, const Location& location, const std::string& keywordName);
DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<std::vector<DeckValue>>& record_list);
DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<std::vector<DeckValue>>& record_list, UnitSystem& system_active, UnitSystem& system_default);
DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<int>& data);
DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<double>& data);

View File

@@ -1,5 +1,7 @@
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckValue.hpp>
@@ -20,6 +22,9 @@ namespace {
const DeckRecord& (DeckKeyword::*getRecord)(size_t index) const = &DeckKeyword::getRecord;
const DeckItem& getItem(const DeckRecord& record, size_t index) {
return record.getItem(index);
}
py::list item_to_pylist( const DeckItem& item )
{
@@ -29,7 +34,7 @@ py::list item_to_pylist( const DeckItem& item )
return iterable_to_pylist( item.getData< int >() );
break;
case type_tag::fdouble:
return iterable_to_pylist( item.getData< double >() );
throw py::type_error("Double list access must be specified by either 'get_raw_data_list' or 'get_SI_data_list'.");
break;
case type_tag::string:
return iterable_to_pylist( item.getData< std::string >() );
@@ -40,24 +45,15 @@ py::list item_to_pylist( const DeckItem& item )
}
}
struct DeckRecordIterator
{
DeckRecordIterator(const DeckRecord* record) {
this->record = record;
this->it = this->record->begin();
}
const DeckRecord* record;
DeckRecord::const_iterator it;
py::list raw_data_to_pylist( const DeckItem& item) {
return iterable_to_pylist( item.getData<double>() );
}
py::list next() {
if (it == record->end()) {
PyErr_SetString(PyExc_StopIteration, "At end.");
throw py::error_already_set();
}
return item_to_pylist(*(it++));
}
};
py::list SI_data_to_pylist( const DeckItem& item) {
return iterable_to_pylist( item.getSIDoubleData() );
}
bool is_int(const std::string& s)
@@ -107,7 +103,7 @@ void python::common::export_DeckKeyword(py::module& module) {
py::class_< DeckKeyword >( module, "DeckKeyword")
.def(py::init<const ParserKeyword& >())
.def(py::init([](const ParserKeyword& parser_keyword, py::list record_list) {
.def(py::init([](const ParserKeyword& parser_keyword, py::list record_list, UnitSystem& active_system, UnitSystem& default_system) {
std::vector< std::vector<DeckValue> > value_record_list;
@@ -143,7 +139,7 @@ void python::common::export_DeckKeyword(py::module& module) {
}
value_record_list.push_back( value_record );
}
return DeckKeyword(parser_keyword, value_record_list);
return DeckKeyword(parser_keyword, value_record_list, active_system, default_system);
} ) )
.def( "__repr__", &DeckKeyword::name )
@@ -157,22 +153,22 @@ void python::common::export_DeckKeyword(py::module& module) {
py::class_< DeckRecord >( module, "DeckRecord")
.def( "__repr__", &str<DeckRecord> )
.def( "__iter__", +[](const DeckRecord& record){
return DeckRecordIterator(&record);
})
.def( "__getitem__", +[](const DeckRecord& record, size_t index){
return item_to_pylist( record.getItem(index) );
})
.def( "__getitem__", +[](const DeckRecord& record, const std::string& name){
return item_to_pylist( record.getItem(name) );
})
.def( "__iter__", +[] (const DeckRecord& record) { return py::make_iterator(record.begin(), record.end()); }, py::keep_alive<0,1>())
.def( "__getitem__", &getItem, ref_internal)
.def( "__len__", &DeckRecord::size )
;
py::class_< DeckRecordIterator >( module, "DeckRecordIterator")
.def( "__next__", &DeckRecordIterator::next )
.def( "next", &DeckRecordIterator::next )
py::class_< DeckItem >(module, "DeckItem")
.def( "__len__", &DeckItem::size )
.def("get_str", &DeckItem::get<std::string>)
.def("get_int", &DeckItem::get<int>)
.def("get_raw", &DeckItem::get<double>)
.def("get_SI", &DeckItem::getSIDouble)
.def("get_data_list", &item_to_pylist)
.def("get_raw_data_list", &raw_data_to_pylist)
.def("get_SI_data_list", &SI_data_to_pylist)
;
}

View File

@@ -39,9 +39,9 @@ inv_ecl_month = {1 : "JAN",
12 : "DEC"}
def _make_datetime(dates_record):
day = dates_record[0][0]
month = dates_record[1][0]
year = dates_record[2][0]
day = dates_record[0].get_int(0)
month = dates_record[1].get_str(0)
year = dates_record[2].get_int(0)
return datetime.datetime(year, ecl_month[month], day)

View File

@@ -66,7 +66,7 @@ FIPNUM
self.assertIn('FIPNUM', self.deck)
self.assertEqual(len(self.deck['FIPNUM']), 1)
self.assertEqual(len(self.deck['FIPNUM'][0]), 1)
self.assertEqual(len(self.deck['FIPNUM'][0][0]), 4)
self.assertEqual(len(self.deck['FIPNUM'][0][0].get_data_list()), 4)
if __name__ == "__main__":

View File

@@ -6,9 +6,33 @@ from opm.io.parser import Parser
from opm.io.parser import ParseContext
from opm.io.deck import DeckKeyword
unit_foot = 0.3048 #meters
class TestParser(unittest.TestCase):
REGIONDATA = """
START -- 0
10 MAI 2007 /
RUNSPEC
FIELD
DIMENS
2 2 1 /
GRID
DX
4*0.25 /
DY
4*0.25 /
DZ
4*0.25 /
TOPS
4*0.25 /
REGIONS
OPERNUM
3 3 1 2 /
FIPNUM
1 1 2 3 /
"""
def setUp(self):
self.spe3fn = 'tests/spe3/SPE3CASE1.DATA'
self.norne_fname = os.path.abspath('examples/data/norne/NORNE_ATW2013.DATA')
@@ -30,6 +54,11 @@ class TestParser(unittest.TestCase):
def test_create_deck_kw(self):
parser = Parser()
deck = parser.parse_string(self.REGIONDATA)
active_unit_system = deck.active_unit_system()
default_unit_system = deck.default_unit_system()
self.assertEqual(active_unit_system.name, "Field")
with self.assertRaises(ValueError):
kw = parser["NOT_A_VALID_KEYWORD"]
@@ -39,53 +68,63 @@ class TestParser(unittest.TestCase):
dkw_field = DeckKeyword(field)
assert(dkw_field.name == "FIELD")
DeckKeyword(parser["AQUCWFAC"], [[]])
DeckKeyword(parser["AQUCWFAC"], [[]], active_unit_system, default_unit_system)
with self.assertRaises(TypeError):
dkw_wrong = DeckKeyword(parser["AQUCWFAC"], [22.2, 0.25])
dkw_wrong = DeckKeyword(parser["AQUCWFAC"], [22.2, 0.25], active_unit_system, default_unit_system)
dkw_aqannc = DeckKeyword(parser["AQANNC"], [[12, 1, 2, 3, 0.89], [13, 4, 5, 6, 0.625]])
dkw_aqannc = DeckKeyword(parser["AQANNC"], [[12, 1, 2, 3, 0.89], [13, 4, 5, 6, 0.625]], active_unit_system, default_unit_system)
assert( len(dkw_aqannc[0]) == 5 )
assert( dkw_aqannc[0][2][0] == 2 )
assert( dkw_aqannc[1][1][0] == 4 )
assert( dkw_aqannc[1][4][0] == 0.625 )
assert( dkw_aqannc[0][2].get_int(0) == 2 )
assert( dkw_aqannc[1][1].get_int(0) == 4 )
with self.assertRaises(ValueError):
value = dkw_aqannc[1][1].get_raw(0)
with self.assertRaises(ValueError):
value = dkw_aqannc[1][1].get_SI(0)
assert( dkw_aqannc[1][4].get_raw(0) == 0.625 )
self.assertAlmostEqual( dkw_aqannc[1][4].get_SI(0), 0.625 * unit_foot**2 )
assert( dkw_aqannc[1][4].get_raw_data_list() == [0.625] )
self.assertAlmostEqual( dkw_aqannc[1][4].get_SI_data_list()[0], 0.625 * unit_foot**2 )
with self.assertRaises(ValueError):
value = dkw_aqannc[1][4].get_int(0)
dkw_aqantrc = DeckKeyword(parser["AQANTRC"], [[12, "ABC", 8]])
assert( dkw_aqantrc[0][1][0] == "ABC" )
assert( dkw_aqantrc[0][2][0] == 8.0 )
dkw_aqantrc = DeckKeyword(parser["AQANTRC"], [[12, "ABC", 8]], active_unit_system, default_unit_system)
assert( dkw_aqantrc[0][1].get_str(0) == "ABC" )
assert( dkw_aqantrc[0][2].get_raw(0) == 8.0 )
dkw1 = DeckKeyword(parser["AQUCWFAC"], [["*", 0.25]])
assert( dkw1[0][0][0] == 0.0 )
assert( dkw1[0][1][0] == 0.25 )
dkw1 = DeckKeyword(parser["AQUCWFAC"], [["*", 0.25]], active_unit_system, default_unit_system)
assert( dkw1[0][0].get_raw(0) == 0.0 )
assert( dkw1[0][1].get_raw(0) == 0.25 )
dkw2 = DeckKeyword(parser["AQUCWFAC"], [[0.25, "*"]])
assert( dkw2[0][0][0] == 0.25 )
assert( dkw2[0][1][0] == 1.0 )
dkw2 = DeckKeyword(parser["AQUCWFAC"], [[0.25, "*"]], active_unit_system, default_unit_system)
assert( dkw2[0][0].get_raw(0) == 0.25 )
assert( dkw2[0][1].get_raw(0) == 1.0 )
dkw3 = DeckKeyword(parser["AQUCWFAC"], [[0.50]])
assert( dkw3[0][0][0] == 0.50 )
assert( dkw3[0][1][0] == 1.0 )
dkw3 = DeckKeyword(parser["AQUCWFAC"], [[0.50]], active_unit_system, default_unit_system)
assert( dkw3[0][0].get_raw(0) == 0.50 )
assert( dkw3[0][1].get_raw(0) == 1.0 )
dkw4 = DeckKeyword(parser["CBMOPTS"], [["3*", "A", "B", "C", "2*", 0.375]])
assert( dkw4[0][0][0] == "TIMEDEP" )
assert( dkw4[0][2][0] == "NOKRMIX" )
assert( dkw4[0][3][0] == "A" )
assert( dkw4[0][6][0] == "PMPVK" )
assert( dkw4[0][8][0] == 0.375 )
dkw4 = DeckKeyword(parser["CBMOPTS"], [["3*", "A", "B", "C", "2*", 0.375]], active_unit_system, default_unit_system)
assert( dkw4[0][0].get_str(0) == "TIMEDEP" )
assert( dkw4[0][2].get_str(0) == "NOKRMIX" )
assert( dkw4[0][3].get_str(0) == "A" )
assert( dkw4[0][6].get_str(0) == "PMPVK" )
assert( dkw4[0][8].get_raw(0) == 0.375 )
with self.assertRaises(TypeError):
dkw4[0][8].get_data_list()
with self.assertRaises(TypeError):
DeckKeyword(parser["CBMOPTS"], [["3*", "A", "B", "C", "R2*", 0.77]])
DeckKeyword(parser["CBMOPTS"], [["3*", "A", "B", "C", "R2*", 0.77]], active_unit_system, default_unit_system)
with self.assertRaises(TypeError):
DeckKeyword(parser["CBMOPTS"], [["3*", "A", "B", "C", "2.2*", 0.77]])
DeckKeyword(parser["CBMOPTS"], [["3*", "A", "B", "C", "2.2*", 0.77]], active_unit_system, default_unit_system)
dkw5 = DeckKeyword(parser["AQUCWFAC"], [["2*5.5"]])
assert( dkw5[0][0][0] == 5.5 )
assert( dkw5[0][1][0] == 5.5 )
dkw5 = DeckKeyword(parser["AQUCWFAC"], [["2*5.5"]], active_unit_system, default_unit_system)
assert( dkw5[0][0].get_raw(0) == 5.5 )
assert( dkw5[0][1].get_raw(0) == 5.5 )
with self.assertRaises(ValueError):
raise DeckKeyword(parser["AQANTRC"], [["1*2.2", "ABC", 8]])
raise DeckKeyword(parser["AQANTRC"], [["1*2.2", "ABC", 8]], active_unit_system, default_unit_system)
if __name__ == "__main__":

View File

@@ -68,7 +68,7 @@ namespace Opm {
}
DeckKeyword::DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<std::vector<DeckValue>>& record_list) :
DeckKeyword::DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<std::vector<DeckValue>>& record_list, UnitSystem& system_active, UnitSystem& system_default) :
DeckKeyword(parserKeyword)
{
if (parserKeyword.hasFixedSize() && (record_list.size() != parserKeyword.getFixedSize()))
@@ -94,12 +94,14 @@ namespace Opm {
break;
case type_tag::fdouble:
{
// The arguments active_dim and default_dim are totally dummy,
// and just added here to get this to compile after rebase.
UnitSystem unit_system(UnitSystem::UnitType::UNIT_TYPE_METRIC);
auto active_dim = unit_system.getDimension("1");
auto default_dim = unit_system.getDimension("1");
DeckItem deck_item(parser_item.name(), double(), {active_dim}, {default_dim});
auto& dim = parser_item.dimensions();
std::vector<Dimension> active_dimensions;
std::vector<Dimension> default_dimensions;
if (dim.size() > 0) {
active_dimensions.push_back( system_active.getNewDimension(dim[0]) );
default_dimensions.push_back( system_default.getNewDimension(dim[0]) );
}
DeckItem deck_item(parser_item.name(), double(), active_dimensions, default_dimensions);
add_deckvalue<double>(std::move(deck_item), deck_record, parser_item, input_record, j);
}
break;

View File

@@ -23,11 +23,14 @@
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/B.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckValue.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@@ -36,7 +39,6 @@ using namespace Opm;
BOOST_AUTO_TEST_CASE(DeckValueTest) {
const DeckValue value0;
BOOST_CHECK(value0.is_default());
BOOST_CHECK(!value0.is_compatible<int>());
BOOST_CHECK(!value0.is_compatible<std::string>());
@@ -75,23 +77,27 @@ BOOST_AUTO_TEST_CASE(DeckValueTest) {
BOOST_AUTO_TEST_CASE(DeckKeywordConstructor) {
Parser parser;
Deck deck;
UnitSystem& unit_default = deck.getDefaultUnitSystem();
UnitSystem unit_active(UnitSystem::UnitType::UNIT_TYPE_LAB);
const ParserKeyword& big_model = parser.getKeyword("BIGMODEL");
BOOST_CHECK_THROW( DeckKeyword( big_model, {{DeckValue("WORD_A")}} ), std::invalid_argument );
BOOST_CHECK_THROW( DeckKeyword( big_model, {{DeckValue("WORD_A")}}, unit_active, unit_default ), std::invalid_argument );
const ParserKeyword& box = parser.getKeyword("BOX");
std::vector< DeckValue > record1 = {DeckValue(1), DeckValue(2), DeckValue(3), DeckValue(4), DeckValue(5), DeckValue(6)};
DeckKeyword dkw(box, {record1});
BOOST_CHECK_NO_THROW( DeckKeyword( box, {record1} ) );
BOOST_CHECK_THROW( DeckKeyword( box, {{ record1, record1 }}), std::invalid_argument );
DeckKeyword dkw(box, {record1}, unit_active, unit_default);
BOOST_CHECK_NO_THROW( DeckKeyword( box, {record1}, unit_active, unit_default ) );
BOOST_CHECK_THROW( DeckKeyword( box, {{ record1, record1 }}, unit_default, unit_active), std::invalid_argument );
const ParserKeyword& addreg = parser.getKeyword("ADDREG");
BOOST_CHECK_NO_THROW( DeckKeyword( addreg, {{ DeckValue("WORD_A") }} ) );
BOOST_CHECK_THROW( DeckKeyword( addreg, {{DeckValue("WORD_A"), DeckValue(77), DeckValue(16.25), DeckValue("WORD_B")}} ) , std::invalid_argument);
BOOST_CHECK_NO_THROW( DeckKeyword( addreg, {{ DeckValue("WORD_A") }}, unit_active, unit_default ) );
BOOST_CHECK_THROW( DeckKeyword( addreg, {{DeckValue("WORD_A"), DeckValue(77), DeckValue(16.25), DeckValue("WORD_B")}}, unit_default, unit_active ) , std::invalid_argument);
std::vector< DeckValue > record = {DeckValue("WORD_A"), DeckValue(16.25), DeckValue(77), DeckValue("WORD_B")};
DeckKeyword deck_kw(addreg, {record});
DeckKeyword deck_kw(addreg, {record}, unit_active, unit_default);
BOOST_CHECK_EQUAL( deck_kw.size(), 1 );
@@ -110,7 +116,7 @@ BOOST_AUTO_TEST_CASE(DeckKeywordConstructor) {
//checking default values:
record = {DeckValue("WORD_A"), DeckValue(), DeckValue(77)};
DeckKeyword deck_kw1(addreg, {record});
DeckKeyword deck_kw1(addreg, {record}, unit_active, unit_default);
const DeckRecord& deck_record1 = deck_kw1.getRecord(0);
const auto& shift1 = deck_record1.getItem( 1 );
@@ -119,7 +125,15 @@ BOOST_AUTO_TEST_CASE(DeckKeywordConstructor) {
BOOST_CHECK_EQUAL( name1.get<std::string>(0), "M" );
//check that int can substitute double
BOOST_CHECK_NO_THROW( DeckKeyword(addreg, {{DeckValue("WORD_A"), DeckValue(5), DeckValue(77)}} ) );
BOOST_CHECK_NO_THROW( DeckKeyword(addreg, {{DeckValue("WORD_A"), DeckValue(5), DeckValue(77)}}, unit_active, unit_default ) );
//Check correct SI conversion
const ParserKeyword& delayact = parser.getKeyword("DELAYACT");
DeckKeyword delayact_kw( delayact, {{DeckValue("ABC"), DeckValue("DEF"), DeckValue(1.0), DeckValue(8)}}, unit_active, unit_default );
const auto& deck_record2 = delayact_kw.getRecord(0);
const auto& delay = deck_record2.getItem( 2 );
BOOST_CHECK_EQUAL( delay.get<double>(0), 1.0 );
BOOST_CHECK_EQUAL( delay.getSIDouble(0), 3600.0 );
}