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

Generalise Restart Representation of UDQs #4225

Merged
merged 3 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
93 changes: 67 additions & 26 deletions opm/input/eclipse/Schedule/UDQ/UDQAssign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <opm/input/eclipse/Schedule/UDQ/UDQAssign.hpp>

#include <opm/io/eclipse/rst/udq.hpp>

#include <opm/input/eclipse/Schedule/UDQ/UDQEnums.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQSet.hpp>

Expand All @@ -36,19 +38,13 @@ namespace Opm {
void UDQAssign::AssignRecord::eval(UDQSet& values) const
{
if (this->input_selector.empty() &&
this->rst_selector.empty() &&
this->numbered_selector.empty())
{
values.assign(this->value);
}
else if (! this->input_selector.empty()) {
values.assign(this->input_selector[0], this->value);
}
else if (! this->rst_selector.empty()) {
for (const auto& wgname : this->rst_selector) {
values.assign(wgname, this->value);
}
}
else {
for (const auto& item : this->numbered_selector) {
for (const auto& number : item.numbers) {
Expand All @@ -61,12 +57,13 @@ void UDQAssign::AssignRecord::eval(UDQSet& values) const
bool UDQAssign::AssignRecord::operator==(const AssignRecord& data) const
{
return (this->input_selector == data.input_selector)
&& (this->rst_selector == data.rst_selector)
&& (this->numbered_selector == data.numbered_selector)
&& (this->report_step == data.report_step)
&& (this->value == data.value);
}

// ---------------------------------------------------------------------------

UDQAssign::UDQAssign(const std::string& keyword,
const std::vector<std::string>& input_selector,
const double value,
Expand All @@ -77,16 +74,6 @@ UDQAssign::UDQAssign(const std::string& keyword,
this->add_record(input_selector, value, report_step);
}

UDQAssign::UDQAssign(const std::string& keyword,
const std::unordered_set<std::string>& rst_selector,
const double value,
const std::size_t report_step)
: m_keyword (keyword)
, m_var_type(UDQ::varType(keyword))
{
this->add_record(rst_selector, value, report_step);
}

UDQAssign::UDQAssign(const std::string& keyword,
const std::vector<UDQSet::EnumeratedItems>& selector,
double value,
Expand All @@ -107,15 +94,22 @@ UDQAssign::UDQAssign(const std::string& keyword,
this->add_record(std::move(selector), value, report_step);
}

UDQAssign::UDQAssign(const std::string& keyword,
const RestartIO::RstUDQ& assignRst,
const std::size_t report_step)
: m_keyword { keyword }
, m_var_type { assignRst.category }
{
this->add_record(assignRst, report_step);
}

UDQAssign UDQAssign::serializationTestObject()
{
UDQAssign result;
result.m_keyword = "test";
result.m_var_type = UDQVarType::CONNECTION_VAR;
result.records.emplace_back(std::vector<std::string>{"test1"}, 1.0, 0);

result.records.emplace_back(std::unordered_set<std::string>{ "I-45" }, 3.1415, 3);

// Class-template argument deduction for the vector element type.
result.records.emplace_back(std::vector { UDQSet::EnumeratedItems::serializationTestObject() }, 2.71828, 42);

Expand All @@ -129,13 +123,6 @@ void UDQAssign::add_record(const std::vector<std::string>& input_selector,
this->records.emplace_back(input_selector, value, report_step);
}

void UDQAssign::add_record(const std::unordered_set<std::string>& rst_selector,
const double value,
const std::size_t report_step)
{
this->records.emplace_back(rst_selector, value, report_step);
}

void UDQAssign::add_record(const std::vector<UDQSet::EnumeratedItems>& selector,
const double value,
const std::size_t report_step)
Expand All @@ -150,6 +137,34 @@ void UDQAssign::add_record(std::vector<UDQSet::EnumeratedItems>&& selector,
this->records.emplace_back(std::move(selector), value, report_step);
}

void UDQAssign::add_record(const RestartIO::RstUDQ& assignRst,
const std::size_t report_step)
{
if (assignRst.name != this->m_keyword) {
throw std::invalid_argument {
fmt::format("ASSIGN UDQ '{}' must not attempt to include "
"information for unrelated UDQ '{}' from restart file.",
this->m_keyword, assignRst.name)
};
}

switch (assignRst.category) {
case UDQVarType::SCALAR:
case UDQVarType::FIELD_VAR:
this->add_record(assignRst.entityNames(),
assignRst.scalarValue(), report_step);
break;

case UDQVarType::WELL_VAR:
case UDQVarType::GROUP_VAR:
this->add_well_or_group_records(assignRst, report_step);
break;

default:
break;
}
}

const std::string& UDQAssign::keyword() const
{
return this->m_keyword;
Expand Down Expand Up @@ -225,4 +240,30 @@ bool UDQAssign::operator==(const UDQAssign& data) const
&& (this->records == data.records);
}

// ---------------------------------------------------------------------------
// Private member functions below separator
// ---------------------------------------------------------------------------

void UDQAssign::add_well_or_group_records(const RestartIO::RstUDQ& assignRst,
const std::size_t report_step)
{
const auto& wgnames = assignRst.entityNames();
const auto& nameIdx = assignRst.nameIndex();
const auto n = assignRst.numEntities();

// Note: We intentionally allocate a single selector string and reuse
// that for every add_record() call. The loop here guarantees that we
// handle the case of different values for well or group, albeit at the
// cost of the 'records' data member being larger than necessary if all
// entities do have the same value.
auto selector = std::vector<std::string>(1);

for (auto i = 0*n; i < n; ++i) {
for (const auto& subValuePair : assignRst[i]) {
selector.front() = wgnames[nameIdx[i]];
this->add_record(selector, subValuePair.second, report_step);
}
}
}

} // namespace Opm
Loading