Merge pull request #2133 from verveerpj/support_permr_and_permtht

Support PERMR and PERMTHT as aliases for PERMX and PERMY
This commit is contained in:
Joakim Hove 2020-11-26 19:35:46 +01:00 committed by GitHub
commit b6717fd685
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 202 additions and 7 deletions

View File

@ -55,6 +55,14 @@ static const std::set<std::string> oper_keywords = {"ADD", "EQUALS", "MAXVALUE",
static const std::set<std::string> region_oper_keywords = {"MULTIREG", "ADDREG", "EQUALREG", "OPERATER"};
static const std::set<std::string> box_keywords = {"BOX", "ENDBOX"};
std::string get_keyword_from_alias(const std::string& name) {
if (ALIAS::aliased_keywords.count(name))
return ALIAS::aliased_keywords.at(name);
return name;
}
template <>
keyword_info<double> global_kw_info(const std::string& name,
bool allow_unsupported) {
@ -487,7 +495,9 @@ bool FieldProps::supported<int>(const std::string& keyword) {
template <>
Fieldprops::FieldData<double>& FieldProps::init_get(const std::string& keyword, const Fieldprops::keywords::keyword_info<double>& kw_info) {
Fieldprops::FieldData<double>& FieldProps::init_get(const std::string& keyword_name, const Fieldprops::keywords::keyword_info<double>& kw_info) {
const std::string& keyword = Fieldprops::keywords::get_keyword_from_alias(keyword_name);
auto iter = this->double_data.find(keyword);
if (iter != this->double_data.end())
return iter->second;
@ -562,7 +572,8 @@ std::string FieldProps::region_name(const DeckItem& region_item) {
}
template <>
bool FieldProps::has<double>(const std::string& keyword) const {
bool FieldProps::has<double>(const std::string& keyword_name) const {
const std::string& keyword = Fieldprops::keywords::get_keyword_from_alias(keyword_name);
return (this->double_data.count(keyword) != 0);
}
@ -750,7 +761,7 @@ void FieldProps::operate(const DeckRecord& record, Fieldprops::FieldData<T>& tar
void FieldProps::handle_region_operation(const DeckKeyword& keyword) {
for (const auto& record : keyword) {
const std::string& target_kw = record.getItem(0).get<std::string>(0);
const std::string& target_kw = Fieldprops::keywords::get_keyword_from_alias(record.getItem(0).get<std::string>(0));
int region_value = record.getItem("REGION_NUMBER").get<int>(0);
if (this->tran.find(target_kw) != this->tran.end())
@ -799,7 +810,7 @@ void FieldProps::handle_region_operation(const DeckKeyword& keyword) {
void FieldProps::handle_OPERATE(const DeckKeyword& keyword, Box box) {
for (const auto& record : keyword) {
const std::string& target_kw = record.getItem(0).get<std::string>(0);
const std::string& target_kw = Fieldprops::keywords::get_keyword_from_alias(record.getItem(0).get<std::string>(0));
box.update(record);
auto& field_data = this->init_get<double>(target_kw);
@ -813,7 +824,7 @@ void FieldProps::handle_OPERATE(const DeckKeyword& keyword, Box box) {
void FieldProps::handle_operation(const DeckKeyword& keyword, Box box) {
std::unordered_map<std::string, std::string> tran_fields;
for (const auto& record : keyword) {
const std::string& target_kw = record.getItem(0).get<std::string>(0);
const std::string& target_kw = Fieldprops::keywords::get_keyword_from_alias(record.getItem(0).get<std::string>(0));
box.update(record);
if (FieldProps::supported<double>(target_kw) || this->tran.count(target_kw) > 0) {
@ -868,8 +879,8 @@ void FieldProps::handle_operation(const DeckKeyword& keyword, Box box) {
void FieldProps::handle_COPY(const DeckKeyword& keyword, Box box, bool region) {
for (const auto& record : keyword) {
const std::string& src_kw = record.getItem(0).get<std::string>(0);
const std::string& target_kw = record.getItem(1).get<std::string>(0);
const std::string& src_kw = Fieldprops::keywords::get_keyword_from_alias(record.getItem(0).get<std::string>(0));
const std::string& target_kw = Fieldprops::keywords::get_keyword_from_alias(record.getItem(1).get<std::string>(0));
std::vector<Box::cell_index> index_list;
if (region) {

View File

@ -99,6 +99,26 @@ inline bool isFipxxx(const std::string& keyword) {
}
/*
The aliased_keywords map defines aliases for other keywords. The FieldProps
objects will translate those keywords before further processing. The aliases
will also be exposed by the FieldPropsManager object.
However, the following methods of FieldProps do not fully support aliases:
- FieldProps::keys() does not return the aliases.
- FieldProps::erase() and FieldProps::extract() do not support aliases. Using
them with an aliased keyword will also remove the alias.
Note that the aliases are also added to GRID::double_keywords.
The PERMR and PERMTHT keywords are aliases for PERMX and PERMY, respectively.
*/
namespace ALIAS {
static const std::unordered_map<std::string, std::string> aliased_keywords = {{"PERMR", "PERMX"},
{"PERMTHT", "PERMY"}};
}
namespace GRID {
static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"MULTPV", keyword_info<double>{}.init(1.0)},
{"NTG", keyword_info<double>{}.init(1.0)},
@ -106,6 +126,8 @@ static const std::unordered_map<std::string, keyword_info<double>> double_keywor
{"PERMX", keyword_info<double>{}.unit_string("Permeability").distribute_top(true)},
{"PERMY", keyword_info<double>{}.unit_string("Permeability").distribute_top(true)},
{"PERMZ", keyword_info<double>{}.unit_string("Permeability").distribute_top(true)},
{"PERMR", keyword_info<double>{}.unit_string("Permeability").distribute_top(true)},
{"PERMTHT", keyword_info<double>{}.unit_string("Permeability").distribute_top(true)},
{"TEMPI", keyword_info<double>{}.unit_string("Temperature")},
{"THCONR", keyword_info<double>{}},
{"THCONSF", keyword_info<double>{}},

View File

@ -2341,3 +2341,165 @@ COPYREG
BOOST_CHECK_EQUAL(permx[g], permy[g]);
}
}
BOOST_AUTO_TEST_CASE(OPERATE_RADIAL_PERM) {
std::string deck_string = R"(
GRID
PORO
6*1.0 /
OPERATE
PORO 1 3 1 1 1 1 'MAXLIM' PORO 0.50 /
PORO 1 3 2 2 1 1 'MAXLIM' PORO 0.25 /
/
PERMR
6*1/
PERMTHT
6*1000/
OPERATE
PERMR 1 3 1 1 1 1 'MINLIM' PERMR 2 /
PERMR 1 3 2 2 1 1 'MINLIM' PERMR 4 /
PERMTHT 1 3 1 1 1 1 'MAXLIM' PERMTHT 100 /
PERMTHT 1 3 2 2 1 1 'MAXLIM' PERMTHT 200 /
PERMZ 1 3 1 1 1 1 'MULTA' PERMTHT 2 1000 /
PERMZ 1 3 2 2 1 1 'MULTA' PERMR 3 300 /
/
)";
UnitSystem unit_system(UnitSystem::UnitType::UNIT_TYPE_METRIC);
auto to_si = [&unit_system](double raw_value) { return unit_system.to_si(UnitSystem::measure::permeability, raw_value); };
EclipseGrid grid(3,2,1);
Deck deck = Parser{}.parseString(deck_string);
FieldPropsManager fpm(deck, Phases{true, true, true}, grid, TableManager());
const auto& poro = fpm.get_double("PORO");
BOOST_CHECK_EQUAL(poro[0], 0.50);
BOOST_CHECK_EQUAL(poro[3], 0.25);
const auto& permx = fpm.get_double("PERMX");
BOOST_CHECK_EQUAL(permx[0], to_si(2));
BOOST_CHECK_EQUAL(permx[3], to_si(4));
const auto& permy = fpm.get_double("PERMY");
BOOST_CHECK_EQUAL(permy[0], to_si(100));
BOOST_CHECK_EQUAL(permy[3], to_si(200));
const auto& permz = fpm.get_double("PERMZ");
for (std::size_t i = 0; i < 3; i++) {
BOOST_CHECK_EQUAL(permz[i] , 2*permy[i] + to_si(1000));
BOOST_CHECK_EQUAL(permz[i+3], 3*permx[i+3] + to_si(300));
}
BOOST_CHECK(permx == fpm.get_double("PERMR"));
BOOST_CHECK(permy == fpm.get_double("PERMTHT"));
}
BOOST_AUTO_TEST_CASE(REGION_OPERATION_RADIAL_PERM) {
std::string deck_string1 = R"(
GRID
PORO
200*0.15 /
PERMR
200*1 /
REGIONS
FIPNUM
200*1 /
MULTNUM
50*1 50*2 100*3 /
EDIT
MULTIREG
PERMR 1 1 M/
PERMR 2 2 M/
PERMR 3 3 M/
/
COPYREG
PERMR PERMTHT 1 M /
PERMR PERMTHT 2 M /
PERMR PERMTHT 3 M /
/
)";
UnitSystem unit_system(UnitSystem::UnitType::UNIT_TYPE_METRIC);
auto to_si = [&unit_system](double raw_value) { return unit_system.to_si(UnitSystem::measure::permeability, raw_value); };
EclipseGrid grid(10,10, 2);
Deck deck1 = Parser{}.parseString(deck_string1);
FieldPropsManager fp(deck1, Phases{true, true, true}, grid, TableManager());
const auto& permx = fp.get_double("PERMX");
const auto& permy = fp.get_double("PERMY");
const auto& multn = fp.get_int("MULTNUM");
for (std::size_t g = 0; g < 200; g++) {
BOOST_CHECK_CLOSE(to_si(multn[g]), permx[g], 1e-5);
BOOST_CHECK_EQUAL(permx[g], permy[g]);
}
BOOST_CHECK(permx == fp.get_double("PERMR"));
BOOST_CHECK(permy == fp.get_double("PERMTHT"));
}
BOOST_AUTO_TEST_CASE(REGION_OPERATION_MIXED_PERM) {
std::string deck_string1 = R"(
GRID
PORO
200*0.15 /
PERMX
200*1 /
REGIONS
FIPNUM
200*1 /
MULTNUM
50*1 50*2 100*3 /
EDIT
MULTIREG
PERMR 1 1 M/
PERMX 2 2 M/
PERMR 3 3 M/
/
COPYREG
PERMR PERMTHT 1 M /
PERMR PERMY 2 M /
PERMX PERMY 3 M /
/
)";
UnitSystem unit_system(UnitSystem::UnitType::UNIT_TYPE_METRIC);
auto to_si = [&unit_system](double raw_value) { return unit_system.to_si(UnitSystem::measure::permeability, raw_value); };
EclipseGrid grid(10,10, 2);
Deck deck1 = Parser{}.parseString(deck_string1);
FieldPropsManager fp(deck1, Phases{true, true, true}, grid, TableManager());
const auto& permx = fp.get_double("PERMX");
const auto& permy = fp.get_double("PERMY");
const auto& multn = fp.get_int("MULTNUM");
for (std::size_t g = 0; g < 200; g++) {
BOOST_CHECK_CLOSE(to_si(multn[g]), permx[g], 1e-5);
BOOST_CHECK_EQUAL(permx[g], permy[g]);
}
BOOST_CHECK(permx == fp.get_double("PERMR"));
BOOST_CHECK(permy == fp.get_double("PERMTHT"));
}