Add support for UDA values in DeckKeyword constructor.

Add support for UDA values items when constructing DeckKeywords from
DeckValues. This is needed when constructing DeckKeywords
from Python. For example WCONPROD has UDA value argument for the oil
rate.
This commit is contained in:
Håkon Hægland
2021-11-08 09:58:22 +01:00
parent 0595aa8fea
commit 702c4d46af
4 changed files with 98 additions and 39 deletions

View File

@@ -23,6 +23,7 @@
#include <string>
#include <opm/parser/eclipse/Utility/Typetools.hpp>
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
namespace Opm {
@@ -33,7 +34,8 @@ class DeckValue {
explicit DeckValue(int);
explicit DeckValue(double);
explicit DeckValue(const std::string&);
explicit DeckValue(const UDAValue&);
bool is_default() const;
template<typename T>
@@ -48,7 +50,8 @@ class DeckValue {
type_tag value_enum;
int int_value;
double double_value;
std::string string_value;
std::string string_value;
UDAValue uda_value;
};

View File

@@ -62,7 +62,11 @@ bool is_int(const std::string& s)
}
void push_string_as_deck_value(std::vector<DeckValue>& record, const std::string str) {
void push_string_as_deck_value(
const ParserItem& parser_item,
std::vector<DeckValue>& record,
const std::string str)
{
std::size_t star_pos = str.find('*');
if (star_pos != std::string::npos) {
@@ -79,12 +83,24 @@ void push_string_as_deck_value(std::vector<DeckValue>& record, const std::string
std::string value_str = str.substr(star_pos + 1, str.length());
DeckValue value;
if (value_str.length() > 0) {
if (is_int(value_str))
value = DeckValue( stoi(value_str) );
else
value = DeckValue( stod(value_str) );
if (parser_item.dataType() == type_tag::uda) {
if (value_str.length() > 0) {
if (is_int(value_str))
value = DeckValue( UDAValue(stoi(value_str)) );
else
value = DeckValue( UDAValue(stod(value_str)) );
}
else {
value = DeckValue( UDAValue( parser_item.getDefault<UDAValue>() ) );
}
}
else {
if (value_str.length() > 0) {
if (is_int(value_str))
value = DeckValue( stoi(value_str) );
else
value = DeckValue( stod(value_str) );
}
}
for (int i = 0; i < multiplier; i++)
@@ -96,7 +112,6 @@ void push_string_as_deck_value(std::vector<DeckValue>& record, const std::string
}
py::array_t<int> get_int_array(const DeckKeyword& kw) {
return convert::numpy_array( kw.getIntData() );
}
@@ -140,35 +155,47 @@ void python::common::export_DeckKeyword(py::module& module) {
.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;
int i = 0;
for (py::handle record_obj : record_list) {
py::list record = record_obj.cast<py::list>();
std::vector<DeckValue> value_record;
const ParserRecord& parser_record = parser_keyword.getRecord(i++);
int j = 0;
for (const py::handle& value_obj : record) {
const ParserItem& parser_item = parser_record.get(j++);
try {
int val_int = value_obj.cast<int>();
if (parser_item.dataType() == type_tag::uda) {
value_record.push_back( DeckValue(UDAValue(val_int)) );
}
else {
value_record.push_back( DeckValue( val_int) );
}
continue;
}
catch (const std::exception& e_int) {}
try {
int val_int = value_obj.cast<int>();
value_record.push_back( DeckValue(val_int) );
continue;
}
catch (const std::exception& e_int) {}
try {
double val_double = value_obj.cast<double>();
if (parser_item.dataType() == type_tag::uda) {
value_record.push_back( DeckValue(UDAValue(val_double)));
}
else {
value_record.push_back( DeckValue(val_double) );
}
continue;
}
catch (const std::exception& e_double) {}
try {
double val_double = value_obj.cast<double>();
value_record.push_back( DeckValue(val_double) );
continue;
}
catch (const std::exception& e_double) {}
try {
std::string val_string = value_obj.cast<std::string>();
push_string_as_deck_value(
parser_item, value_record, val_string);
continue;
}
catch (const std::exception& e_string) {}
try {
std::string val_string = value_obj.cast<std::string>();
push_string_as_deck_value(value_record, val_string);
continue;
}
catch (const std::exception& e_string) {}
throw py::type_error("DeckKeyword: tried to add unknown type to record.");
throw py::type_error("DeckKeyword: tried to add unknown type to record.");
}
value_record_list.push_back( value_record );

View File

@@ -128,7 +128,23 @@ namespace Opm {
add_deckvalue<std::string>(std::move(deck_item), deck_record, parser_item, input_record, j);
}
break;
case type_tag::uda:
{
auto& dimensions = parser_item.dimensions();
std::vector<Dimension> active_dimensions;
std::vector<Dimension> default_dimensions;
for (const auto& dim_string : dimensions) {
active_dimensions.push_back(
system_active.parse(dim_string));
default_dimensions.push_back(
system_default.parse(dim_string));
}
DeckItem deck_item(parser_item.name(), UDAValue(),
active_dimensions, default_dimensions);
add_deckvalue<UDAValue>(std::move(deck_item),
deck_record, parser_item, input_record, j);
}
break;
default: throw std::invalid_argument("For input to DeckKeyword '" + name() + ": unsupported type. (only support for string, double and int.)");
}
}
@@ -136,11 +152,8 @@ namespace Opm {
this->addRecord( std::move(deck_record) );
}
}
DeckKeyword::DeckKeyword(const ParserKeyword& parserKeyword, const std::vector<int>& data) :
DeckKeyword(parserKeyword)
{

View File

@@ -47,6 +47,12 @@ DeckValue::DeckValue(const std::string& value):
string_value(value)
{}
DeckValue::DeckValue(const UDAValue& value):
default_value(false),
value_enum(type_tag::uda),
uda_value(value)
{}
bool DeckValue::is_default() const {
return default_value;
}
@@ -66,7 +72,7 @@ double DeckValue::get() const {
if (value_enum == type_tag::integer)
return this->int_value;
throw std::invalid_argument("DeckValue does not hold a double value");
}
@@ -78,6 +84,14 @@ std::string DeckValue::get() const {
throw std::invalid_argument("DeckValue does not hold a string value");
}
template<>
UDAValue DeckValue::get() const {
if (value_enum == type_tag::uda)
return this->uda_value;
throw std::invalid_argument("DeckValue does not hold an UDAValue");
}
template<>
bool DeckValue::is_compatible<int>() const {
return (value_enum == type_tag::integer);
@@ -88,12 +102,14 @@ bool DeckValue::is_compatible<double>() const {
return (value_enum == type_tag::fdouble || value_enum == type_tag::integer);
}
template<>
bool DeckValue::is_compatible<std::string>() const {
return (value_enum == type_tag::string);
}
template<>
bool DeckValue::is_compatible<UDAValue>() const {
return (value_enum == type_tag::uda);
}
}