Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OPERATE for FieldData with global storage. #4237

Merged
merged 3 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions opm/input/eclipse/EclipseState/Grid/FieldProps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,25 @@ void max_value(const KeywordLocation& loc,
}
}


template<typename T>
void update_global_from_local(Fieldprops::FieldData<T>& data,
const std::vector<Box::cell_index>& index_list)
{
if(data.global_data)
{
auto& to = *data.global_data;
auto to_st = *data.global_value_status;
const auto& from = data.data;
const auto& from_st = data.value_status;

for (const auto& cell_index : index_list) {
to[cell_index.global_index] = from[cell_index.active_index];
to_st[cell_index.global_index] = from_st[cell_index.active_index];
}
}
}

template <typename T>
void apply(const Fieldprops::ScalarOperation op,
const KeywordLocation& loc,
Expand Down Expand Up @@ -1322,15 +1341,9 @@ template <typename T>
void FieldProps::operate(const DeckRecord& record,
Fieldprops::FieldData<T>& target_data,
const Fieldprops::FieldData<T>& src_data,
const std::vector<Box::cell_index>& index_list)
const std::vector<Box::cell_index>& index_list,
const bool global)
{
if (target_data.global_data) {
throw std::logic_error {
"The OPERATE and OPERATER keywords are not "
"supported for keywords with global storage"
};
}

const auto target_array = record.getItem("TARGET_ARRAY").getTrimmedString(0);
if (this->tran.find(target_array) != this->tran.end()) {
throw std::logic_error {
Expand All @@ -1346,13 +1359,19 @@ void FieldProps::operate(const DeckRecord& record,
const auto beta = this->get_beta(func_name, target_array, record.getItem("PARAM2").get<double>(0));
const auto func = Operate::get(func_name, alpha, beta);

auto& to_data = global? *target_data.global_data : target_data.data;
auto& to_status = global? *target_data.global_value_status : target_data.value_status;
const auto& from_data = global? *src_data.global_data : src_data.data;
auto& from_status = global? *src_data.global_value_status : src_data.value_status;

for (const auto& cell_index : index_list) {
// This is the global index if global is true and global storage is used.
const auto ix = cell_index.active_index;

if (value::has_value(src_data.value_status[ix])) {
if (!check_target || value::has_value(target_data.value_status[ix])) {
target_data.data[ix] = func(target_data.data[ix], src_data.data[ix]);
target_data.value_status[ix] =src_data.value_status[ix];
if (value::has_value(from_status[ix])) {
if (!check_target || value::has_value(to_status[ix])) {
to_data[ix] = func(to_data[ix], from_data[ix]);
to_status[ix] = from_status[ix];
}
else {
throw std::invalid_argument {
Expand Down Expand Up @@ -1417,6 +1436,10 @@ void FieldProps::handle_operateR(const DeckKeyword& keyword)

const auto& src_data = this->init_get<double>(src_kw);
FieldProps::operate(record, field_data, src_data, index_list);

// For now regions do not 100% support global storage.
// Make sure that the global storage at least reflects the local one.
update_global_from_local(field_data, index_list);
}
}

Expand Down Expand Up @@ -1524,6 +1547,18 @@ void FieldProps::handle_OPERATE(const DeckKeyword& keyword, Box box)
const auto& src_data = this->init_get<double>(src_kw);

FieldProps::operate(record, field_data, src_data, box.index_list());

if (field_data.global_data)
{
if (!src_data.global_data) {
throw std::logic_error {
"The OPERATE and OPERATER keywords are only "
"supported between keywords with same storage"
};
}

FieldProps::operate(record, field_data, src_data, box.global_index_list(), true);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion opm/input/eclipse/EclipseState/Grid/FieldProps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,8 @@ class FieldProps {
void operate(const DeckRecord& record,
Fieldprops::FieldData<T>& target_data,
const Fieldprops::FieldData<T>& src_data,
const std::vector<Box::cell_index>& index_list);
const std::vector<Box::cell_index>& index_list,
const bool global = false);

template <typename T>
Fieldprops::FieldData<T>&
Expand Down
11 changes: 10 additions & 1 deletion tests/parser/FieldPropsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -822,13 +822,18 @@ PERMX
PERMY
6*1000/

MULTZ
6*1.0/

OPERATE
PERMX 1 3 1 1 1 1 'MINLIM' PERMX 2 /
PERMX 1 3 2 2 1 1 'MINLIM' PERMX 4 /
PERMY 1 3 1 1 1 1 'MAXLIM' PERMY 100 /
PERMY 1 3 2 2 1 1 'MAXLIM' PERMY 200 /
PERMZ 1 3 1 1 1 1 'MULTA' PERMY 2 1000 /
PERMZ 1 3 2 2 1 1 'MULTA' PERMX 3 300 /
MULTZ 1 3 1 1 1 1 'MAXLIM' MULTZ 0.50 /
MULTZ 1 3 2 2 1 1 'MAXLIM' MULTZ 0.75 /
/


Expand Down Expand Up @@ -858,6 +863,10 @@ OPERATE
BOOST_CHECK_CLOSE(permz[i] , 2*permy[i] + to_si(1000), 1e-13);
BOOST_CHECK_CLOSE(permz[i+3], 3*permx[i+3] + to_si(300), 1e-13);
}

const auto& multz = fpm.get_double("MULTZ");
BOOST_CHECK_EQUAL(multz[0], 0.5);
BOOST_CHECK_EQUAL(multz[3], 0.75);
}

BOOST_AUTO_TEST_CASE(EPS_Props_Inconsistent) {
Expand Down Expand Up @@ -2276,7 +2285,7 @@ MULTZ
27*1.0 /

OPERATE
MULTZ 1 3 1 1 1 1 'MAXLIM' MULTZ 0.50 /
MULTZ 1 3 1 1 1 1 'MAXLIM' MULTX 0.50 /
/

)" };
Expand Down