Split Scalar Value Scattering Out to Helper Function

In preparation of adding support for segment level UDQs.  While
here, also apply const in a few places.
This commit is contained in:
Bård Skaflestad
2023-01-11 10:16:51 +01:00
parent b1f3b3b4cf
commit 9161ac9503
2 changed files with 58 additions and 40 deletions

View File

@@ -111,6 +111,10 @@ private:
std::size_t m_report_step;
UDQUpdate m_update_status;
mutable std::optional<std::string> string_data;
UDQSet scatter_scalar_value(UDQSet&& res, const UDQContext& context) const;
UDQSet scatter_scalar_well_value(const UDQContext& context, const std::optional<double>& value) const;
UDQSet scatter_scalar_group_value(const UDQContext& context, const std::optional<double>& value) const;
};
} // Namespace Opm

View File

@@ -87,7 +87,7 @@ make_tokens(const std::vector<std::string>& string_tokens)
std::size_t token_index = 0;
while (true) {
const auto& string_token = string_tokens[token_index];
auto token_type = Opm::UDQ::tokenType(string_tokens[token_index]);
const auto token_type = Opm::UDQ::tokenType(string_tokens[token_index]);
token_index += 1;
if (token_type == Opm::UDQTokenType::ecl_expr) {
@@ -203,7 +203,6 @@ UDQDefine::UDQDefine(const UDQParams& udq_params_arg,
: UDQDefine(udq_params_arg, keyword, report_step, location, deck_data, parseContext, errors)
{}
UDQDefine::UDQDefine(const UDQParams& udq_params_arg,
const std::string& keyword,
const std::size_t report_step,
@@ -295,7 +294,8 @@ UDQSet UDQDefine::eval(const UDQContext& context) const
if (!dynamic_type_check(this->var_type(), res->var_type())) {
throw std::invalid_argument {
"Invalid runtime type conversion detected when evaluating UDQ"
"Invalid runtime type conversion "
"detected when evaluating UDQ " + this->m_keyword
};
}
}
@@ -316,45 +316,10 @@ UDQSet UDQDefine::eval(const UDQContext& context) const
}
if (res->var_type() == UDQVarType::SCALAR) {
// If the right hand side evaluates to a scalar that scalar value
// should be set for all wells in the wellset:
//
// UDQ
// DEFINE WUINJ1 SUM(WOPR) * 1.25 /
// DEFINE WUINJ2 WOPR OP1 * 5.0 /
// /
//
// Both the expressions "SUM(WOPR)" and "WOPR OP1" evaluate to a
// scalar, this should then be copied all wells, so that
// WUINJ1:$WELL should evaulate to the same numerical value for all
// wells. We implement the same behavior for group sets - but there
// is lots of uncertainty regarding the semantics of group sets.
const auto& scalar_value = (*res)[0].value();
if (this->var_type() == UDQVarType::WELL_VAR) {
const std::vector<std::string> wells = context.wells();
UDQSet well_res = UDQSet::wells(this->m_keyword, wells);
for (const auto& well : wells) {
well_res.assign(well, scalar_value);
}
return well_res;
}
if (this->var_type() == UDQVarType::GROUP_VAR) {
const std::vector<std::string> groups = context.groups();
UDQSet group_res = UDQSet::groups(this->m_keyword, groups);
for (const auto& group : groups) {
group_res.assign(group, scalar_value);
}
return group_res;
}
return this->scatter_scalar_value(*std::move(res), context);
}
return *res;
return *std::move(res);
}
const KeywordLocation& UDQDefine::location() const
@@ -438,4 +403,53 @@ bool UDQDefine::operator==(const UDQDefine& data) const
;
}
UDQSet UDQDefine::scatter_scalar_value(UDQSet&& res, const UDQContext& context) const
{
// If the right hand side evaluates to a scalar that scalar value should
// be set for all elements of the UDQ set. For example, in
//
// UDQ
// DEFINE WUINJ1 SUM(WOPR) * 1.25 /
// DEFINE WUINJ2 WOPR OP1 * 5.0 /
// /
//
// both the expressions "SUM(WOPR)" and "WOPR OP1" produce scalar
// values. This scalar value must then be copied/assigned to all wells
// in order for WUINJ1:$WELL to produce the same numerical value for
// every well.
//
// We mirror this behavior for group sets, but there is lots of
// uncertainty regarding the semantics of group sets.
if (this->var_type() == UDQVarType::WELL_VAR) {
return this->scatter_scalar_well_value(context, res[0].value());
}
if (this->var_type() == UDQVarType::GROUP_VAR) {
return this->scatter_scalar_group_value(context, res[0].value());
}
return std::move(res);
}
UDQSet UDQDefine::scatter_scalar_well_value(const UDQContext& context,
const std::optional<double>& value) const
{
if (! value.has_value()) {
return UDQSet::wells(this->m_keyword, context.wells());
}
return UDQSet::wells(this->m_keyword, context.wells(), *value);
}
UDQSet UDQDefine::scatter_scalar_group_value(const UDQContext& context,
const std::optional<double>& value) const
{
if (! value.has_value()) {
return UDQSet::groups(this->m_keyword, context.groups());
}
return UDQSet::groups(this->m_keyword, context.groups(), *value);
}
} // namespace Opm