Merge pull request #1609 from wito/new-summarynode

New SummaryNode implementation
This commit is contained in:
Bård Skaflestad
2020-03-26 11:34:21 +01:00
committed by GitHub
9 changed files with 392 additions and 192 deletions

View File

@@ -0,0 +1,113 @@
/*
Copyright 2020 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <numeric>
#include <regex>
#include <string>
#include <unordered_set>
#include <vector>
#include <opm/io/eclipse/SummaryNode.hpp>
namespace {
constexpr bool use_number(Opm::EclIO::SummaryNode::Category category) {
switch (category) {
case Opm::EclIO::SummaryNode::Category::Block: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Connection: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Region: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Segment:
return true;
case Opm::EclIO::SummaryNode::Category::Field: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Group: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Miscellaneous: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Well:
return false;
}
}
constexpr bool use_name(Opm::EclIO::SummaryNode::Category category) {
switch (category) {
case Opm::EclIO::SummaryNode::Category::Connection: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Group: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Segment: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Well:
return true;
case Opm::EclIO::SummaryNode::Category::Block: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Field: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Miscellaneous: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Region:
return false;
}
}
};
std::string Opm::EclIO::SummaryNode::unique_key() const {
std::vector<std::string> key_parts { keyword } ;
if (use_name(category))
key_parts.emplace_back(wgname);
if (use_number(category))
key_parts.emplace_back(std::to_string(number));
auto compose_key = [](std::string& key, const std::string& key_part) -> std::string {
constexpr auto delimiter { ':' } ;
return key.empty() ? key_part : key + delimiter + key_part;
};
return std::accumulate(std::begin(key_parts), std::end(key_parts), std::string(), compose_key);
}
bool Opm::EclIO::SummaryNode::is_user_defined() const {
static const std::unordered_set<std::string> udq_blacklist {
"AUTOCOAR",
"AUTOREF",
"FULLIMP",
"GUIDECAL",
"GUIDERAT",
"GUPFREQ",
"RUNSPEC",
"RUNSUM",
"SUMMARY",
"SUMTHIN",
"SURF",
"SURFACT",
"SURFACTW",
"SURFADDW",
"SURFADS",
"SURFCAPD",
"SURFESAL",
"SURFNUM",
"SURFOPTS",
"SURFROCK",
"SURFST",
"SURFSTES",
"SURFVISC",
"SURFWNUM",
} ;
static const std::regex user_defined_regex { "[ABCFGRSW]U[A-Z]+" } ;
const bool matched { std::regex_match(keyword, user_defined_regex) } ;
const bool blacklisted { udq_blacklist.find(keyword) != udq_blacklist.end() } ;
return matched && !blacklisted;
}

View File

@@ -59,6 +59,7 @@
#include <iterator>
#include <memory>
#include <numeric>
#include <regex>
#include <stdexcept>
#include <string>
#include <unordered_map>
@@ -69,7 +70,7 @@ namespace {
struct ParamCTorArgs
{
std::string kw;
Opm::SummaryConfigNode::Type type;
Opm::EclIO::SummaryNode::Type type;
};
using p_cmode = Opm::Group::ProductionCMode;
@@ -99,7 +100,7 @@ namespace {
std::vector<ParamCTorArgs> requiredRestartVectors()
{
using Type = ::Opm::SummaryConfigNode::Type;
using Type = ::Opm::EclIO::SummaryNode::Type;
return {
// Production
@@ -135,105 +136,86 @@ namespace {
};
}
std::vector<Opm::SummaryConfigNode>
std::vector<Opm::EclIO::SummaryNode>
requiredRestartVectors(const ::Opm::Schedule& sched)
{
auto entities = std::vector<Opm::SummaryConfigNode>{};
using SN = ::Opm::SummaryConfigNode;
const auto& vectors = requiredRestartVectors();
const std::vector<ParamCTorArgs> extra_well_vectors {
{ "WBHP", Opm::EclIO::SummaryNode::Type::Pressure },
{ "WGVIR", Opm::EclIO::SummaryNode::Type::Rate },
{ "WWVIR", Opm::EclIO::SummaryNode::Type::Rate },
};
const std::vector<ParamCTorArgs> extra_group_vectors {
{ "GMCTG", Opm::EclIO::SummaryNode::Type::Mode },
{ "GMCTP", Opm::EclIO::SummaryNode::Type::Mode },
{ "GMCTW", Opm::EclIO::SummaryNode::Type::Mode },
};
const std::vector<ParamCTorArgs> extra_field_vectors {
{ "FMCTG", Opm::EclIO::SummaryNode::Type::Mode },
{ "FMCTP", Opm::EclIO::SummaryNode::Type::Mode },
{ "FMCTW", Opm::EclIO::SummaryNode::Type::Mode },
};
std::vector<Opm::EclIO::SummaryNode> entities {} ;
auto makeEntities = [&vectors, &entities]
(const char kwpref,
const SN::Category cat,
const Opm::EclIO::SummaryNode::Category cat,
const std::string& name) -> void
{
for (const auto& vector : vectors) {
entities.emplace_back(kwpref + vector.kw, cat, ::Opm::Location());
entities.push_back({kwpref + vector.kw, cat, vector.type, name, Opm::EclIO::SummaryNode::default_number });
}
};
entities.back().namedEntity(name)
.parameterType(vector.type);
auto makeExtraEntities = [&entities]
(const std::vector<ParamCTorArgs>& extra_vectors,
const Opm::EclIO::SummaryNode::Category category,
const std::string& wgname) -> void
{
for (const auto &extra_vector : extra_vectors) {
entities.push_back({ extra_vector.kw, category, extra_vector.type, wgname, Opm::EclIO::SummaryNode::default_number });
}
};
for (const auto& well_name : sched.wellNames()) {
makeEntities('W', SN::Category::Well, well_name);
entities.emplace_back("WBHP", SN::Category::Well, ::Opm::Location());
entities.back().namedEntity(well_name)
.parameterType(SN::Type::Pressure);
entities.emplace_back("WGVIR", SN::Category::Well, ::Opm::Location());
entities.back().namedEntity(well_name)
.parameterType(SN::Type::Rate);
entities.emplace_back("WWVIR", SN::Category::Well, ::Opm::Location());
entities.back().namedEntity(well_name)
.parameterType(SN::Type::Rate);
makeEntities('W', Opm::EclIO::SummaryNode::Category::Well, well_name);
makeExtraEntities(extra_well_vectors, Opm::EclIO::SummaryNode::Category::Well, well_name);
}
for (const auto& grp_name : sched.groupNames()) {
if (grp_name != "FIELD") {
makeEntities('G', SN::Category::Group, grp_name);
entities.emplace_back("GMCTP", SN::Category::Group, ::Opm::Location());
entities.back().namedEntity(grp_name)
.parameterType(SN::Type::Mode);
entities.emplace_back("GMCTW", SN::Category::Group, ::Opm::Location());
entities.back().namedEntity(grp_name)
.parameterType(SN::Type::Mode);
entities.emplace_back("GMCTG", SN::Category::Group, ::Opm::Location());
entities.back().namedEntity(grp_name)
.parameterType(SN::Type::Mode);
makeEntities('G', Opm::EclIO::SummaryNode::Category::Group, grp_name);
makeExtraEntities(extra_group_vectors, Opm::EclIO::SummaryNode::Category::Group, grp_name);
}
}
makeEntities('F', SN::Category::Field, "FIELD");
entities.emplace_back("FMCTP", SN::Category::Field, ::Opm::Location());
entities.back().namedEntity("FIELD")
.parameterType(SN::Type::Mode);
entities.emplace_back("FMCTW", SN::Category::Field, ::Opm::Location());
entities.back().namedEntity("FIELD")
.parameterType(SN::Type::Mode);
entities.emplace_back("FMCTG", SN::Category::Field, ::Opm::Location());
entities.back().namedEntity("FIELD")
.parameterType(SN::Type::Mode);
makeEntities('F', Opm::EclIO::SummaryNode::Category::Field, "FIELD");
makeExtraEntities(extra_field_vectors, Opm::EclIO::SummaryNode::Category::Field, "FIELD");
return entities;
}
std::vector<Opm::SummaryConfigNode>
std::vector<Opm::EclIO::SummaryNode>
requiredSegmentVectors(const ::Opm::Schedule& sched)
{
using SN = Opm::SummaryConfigNode;
auto ret = std::vector<SN>{};
std::vector<Opm::EclIO::SummaryNode> ret {};
auto sofr = SN{ "SOFR", SN::Category::Segment, ::Opm::Location() }
.parameterType(SN::Type::Rate);
auto sgfr = SN{ "SGFR", SN::Category::Segment, ::Opm::Location() }
.parameterType(SN::Type::Rate);
auto swfr = SN{ "SWFR", SN::Category::Segment, ::Opm::Location() }
.parameterType(SN::Type::Rate);
auto spr = SN{ "SPR", SN::Category::Segment, ::Opm::Location() }
.parameterType(SN::Type::Pressure);
constexpr Opm::EclIO::SummaryNode::Category category { Opm::EclIO::SummaryNode::Category::Segment };
const std::vector<std::pair<std::string,Opm::EclIO::SummaryNode::Type>> requiredVectors {
{ "SOFR", Opm::EclIO::SummaryNode::Type::Rate },
{ "SGFR", Opm::EclIO::SummaryNode::Type::Rate },
{ "SWFR", Opm::EclIO::SummaryNode::Type::Rate },
{ "SPR", Opm::EclIO::SummaryNode::Type::Pressure },
};
auto makeVectors =
[&](const std::string& well,
const int segNumber) -> void
{
ret.push_back(sofr.namedEntity(well).number(segNumber));
ret.push_back(sgfr.namedEntity(well).number(segNumber));
ret.push_back(swfr.namedEntity(well).number(segNumber));
ret.push_back(spr .namedEntity(well).number(segNumber));
for (const auto &requiredVector : requiredVectors) {
ret.push_back({requiredVector.first, category, requiredVector.second, well, segNumber});
}
};
for (const auto& wname : sched.wellNames()) {
@@ -1296,40 +1278,39 @@ static const std::unordered_map< std::string, Opm::UnitSystem::measure> block_un
};
inline std::vector<Opm::Well> find_wells( const Opm::Schedule& schedule,
const Opm::SummaryConfigNode& node,
const Opm::EclIO::SummaryNode& node,
const int sim_step,
const Opm::out::RegionCache& regionCache ) {
const auto cat = node.category;
const auto cat = node.category();
switch (cat) {
case Opm::EclIO::SummaryNode::Category::Well: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Connection: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Segment: {
const auto& name = node.wgname;
if ((cat == Opm::SummaryConfigNode::Category::Well) ||
(cat == Opm::SummaryConfigNode::Category::Connection) ||
(cat == Opm::SummaryConfigNode::Category::Segment))
{
const auto& name = node.namedEntity();
if (schedule.hasWell(name, sim_step)) {
const auto& well = schedule.getWell( name, sim_step );
return { well };
} else
if (schedule.hasWell(node.wgname, sim_step)) {
return { schedule.getWell( name, sim_step ) };
} else {
return {};
}
}
if( cat == Opm::SummaryConfigNode::Category::Group ) {
const auto& name = node.namedEntity();
case Opm::EclIO::SummaryNode::Category::Group: {
const auto& name = node.wgname;
if( !schedule.hasGroup( name ) ) return {};
return schedule.getChildWells2( name, sim_step);
}
if( cat == Opm::SummaryConfigNode::Category::Field )
case Opm::EclIO::SummaryNode::Category::Field:
return schedule.getWells(sim_step);
if( cat == Opm::SummaryConfigNode::Category::Region ) {
case Opm::EclIO::SummaryNode::Category::Region: {
std::vector<Opm::Well> wells;
const auto region = node.number();
const auto region = node.number;
for ( const auto& connection : regionCache.connections( region ) ){
const auto& w_name = connection.first;
@@ -1347,39 +1328,28 @@ inline std::vector<Opm::Well> find_wells( const Opm::Schedule& schedule,
return wells;
}
return {};
case Opm::EclIO::SummaryNode::Category::Block:
case Opm::EclIO::SummaryNode::Category::Miscellaneous:
return {};
}
}
bool need_wells(const Opm::EclIO::SummaryNode& node) {
static const std::regex region_keyword_regex { "R[OGW][IP][RT]" };
bool need_wells(Opm::SummaryConfigNode::Category cat, const std::string& keyword) {
static const std::set<std::string> region_keywords{"ROIR", "RGIR", "RWIR", "ROPR", "RGPR", "RWPR", "ROIT", "RWIT", "RGIT", "ROPT", "RGPT", "RWPT"};
if (cat == Opm::SummaryConfigNode::Category::Well)
return true;
if (cat == Opm::SummaryConfigNode::Category::Group)
return true;
if (cat == Opm::SummaryConfigNode::Category::Field)
return true;
if (cat == Opm::SummaryConfigNode::Category::Connection)
return true;
if (cat == Opm::SummaryConfigNode::Category::Segment)
return true;
/*
Some of the region keywords are based on summing over all the connections
which fall in the region; i.e. RGIR is the total gas injection rate in the
region and consequently the list of defined wells is required, other
region keywords like 'ROIP' do not require well information.
*/
if (cat == Opm::SummaryConfigNode::Category::Region) {
if (region_keywords.count(keyword) > 0)
return true;
switch (node.category) {
case Opm::EclIO::SummaryNode::Category::Connection: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Field: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Group: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Segment: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Well:
return true;
case Opm::EclIO::SummaryNode::Category::Region:
return std::regex_match(node.keyword, region_keyword_regex);
case Opm::EclIO::SummaryNode::Category::Miscellaneous: [[fallthrough]];
case Opm::EclIO::SummaryNode::Category::Block:
return false;
}
return false;
}
void eval_udq(const Opm::Schedule& schedule, std::size_t sim_step, Opm::SummaryState& st)
@@ -1440,16 +1410,16 @@ void eval_udq(const Opm::Schedule& schedule, std::size_t sim_step, Opm::SummaryS
}
}
void updateValue(const Opm::SummaryConfigNode& node, const double value, Opm::SummaryState& st)
void updateValue(const Opm::EclIO::SummaryNode& node, const double value, Opm::SummaryState& st)
{
if (node.category() == Opm::SummaryConfigNode::Category::Well)
st.update_well_var(node.namedEntity(), node.keyword(), value);
if (node.category == Opm::EclIO::SummaryNode::Category::Well)
st.update_well_var(node.wgname, node.keyword, value);
else if (node.category() == Opm::SummaryConfigNode::Category::Group)
st.update_group_var(node.namedEntity(), node.keyword(), value);
else if (node.category == Opm::EclIO::SummaryNode::Category::Group)
st.update_group_var(node.wgname, node.keyword, value);
else
st.update(node.uniqueNodeKey(), value);
st.update(node.unique_key(), value);
}
/*
@@ -1475,31 +1445,27 @@ struct EfficiencyFactor
FacColl factors{};
void setFactors(const Opm::SummaryConfigNode& node,
void setFactors(const Opm::EclIO::SummaryNode& node,
const Opm::Schedule& schedule,
const std::vector<Opm::Well>& schedule_wells,
const int sim_step);
};
void EfficiencyFactor::setFactors(const Opm::SummaryConfigNode& node,
void EfficiencyFactor::setFactors(const Opm::EclIO::SummaryNode& node,
const Opm::Schedule& schedule,
const std::vector<Opm::Well>& schedule_wells,
const std::vector<Opm::Well>& schedule_wells,
const int sim_step)
{
this->factors.clear();
if (schedule_wells.empty()) { return; }
const bool is_field { node.category == Opm::EclIO::SummaryNode::Category::Field } ;
const bool is_group { node.category == Opm::EclIO::SummaryNode::Category::Group } ;
const bool is_region { node.category == Opm::EclIO::SummaryNode::Category::Region } ;
const bool is_rate { node.type != Opm::EclIO::SummaryNode::Type::Total } ;
const auto cat = node.category();
if( cat != Opm::SummaryConfigNode::Category::Group
&& cat != Opm::SummaryConfigNode::Category::Field
&& cat != Opm::SummaryConfigNode::Category::Region
&& (node.type() != Opm::SummaryConfigNode::Type::Total))
if (!is_field && !is_group && !is_region && is_rate)
return;
const bool is_group = (cat == Opm::SummaryConfigNode::Category::Group);
const bool is_rate = (node.type() != Opm::SummaryConfigNode::Type::Total);
for( const auto& well : schedule_wells ) {
if (!well.hasBeenDefined(sim_step))
continue;
@@ -1507,16 +1473,18 @@ void EfficiencyFactor::setFactors(const Opm::SummaryConfigNode& node,
double eff_factor = well.getEfficiencyFactor();
const auto* group_ptr = std::addressof(schedule.getGroup(well.groupName(), sim_step));
while(true){
if(( is_group
&& is_rate
&& group_ptr->name() == node.namedEntity() ))
while (group_ptr) {
if (is_group && is_rate && group_ptr->name() == node.wgname )
break;
eff_factor *= group_ptr->getGroupEfficiencyFactor();
if (group_ptr->name() == "FIELD")
break;
group_ptr = std::addressof( schedule.getGroup( group_ptr->parent(), sim_step ) );
const auto parent_group = group_ptr->flow_group();
if (parent_group)
group_ptr = std::addressof(schedule.getGroup( parent_group.value(), sim_step ));
else
group_ptr = nullptr;
}
this->factors.emplace_back( well.name(), eff_factor );
@@ -1556,7 +1524,7 @@ namespace Evaluator {
class FunctionRelation : public Base
{
public:
explicit FunctionRelation(Opm::SummaryConfigNode node, ofun fcn)
explicit FunctionRelation(Opm::EclIO::SummaryNode node, ofun fcn)
: node_(std::move(node))
, fcn_ (std::move(fcn))
{}
@@ -1568,7 +1536,7 @@ namespace Evaluator {
Opm::SummaryState& st) const override
{
const auto get_wells =
need_wells(this->node_.category(), this->node_.keyword());
need_wells(node_);
const auto wells = get_wells
? find_wells(input.sched, this->node_,
@@ -1580,14 +1548,14 @@ namespace Evaluator {
// wells apply at this sim_step. Nothing to do.
return;
std::string group_name = this->node_.category() == Opm::SummaryConfigNode::Category::Group ? this->node_.namedEntity() : "";
std::string group_name = this->node_.category == Opm::EclIO::SummaryNode::Category::Group ? this->node_.wgname : "";
EfficiencyFactor efac{};
efac.setFactors(this->node_, input.sched, wells, sim_step);
const fn_args args {
wells, group_name, stepSize, static_cast<int>(sim_step),
std::max(0, this->node_.number()),
std::max(0, this->node_.number),
st, simRes.wellSol, simRes.groupSol, input.reg, input.grid,
std::move(efac.factors)
};
@@ -1599,14 +1567,14 @@ namespace Evaluator {
}
private:
Opm::SummaryConfigNode node_;
Opm::EclIO::SummaryNode node_;
ofun fcn_;
};
class BlockValue : public Base
{
public:
explicit BlockValue(Opm::SummaryConfigNode node,
explicit BlockValue(Opm::EclIO::SummaryNode node,
const Opm::UnitSystem::measure m)
: node_(std::move(node))
, m_ (m)
@@ -1628,19 +1596,19 @@ namespace Evaluator {
}
private:
Opm::SummaryConfigNode node_;
Opm::EclIO::SummaryNode node_;
Opm::UnitSystem::measure m_;
Opm::out::Summary::BlockValues::key_type lookupKey() const
{
return { this->node_.keyword(), this->node_.number() };
return { this->node_.keyword, this->node_.number };
}
};
class RegionValue : public Base
{
public:
explicit RegionValue(Opm::SummaryConfigNode node,
explicit RegionValue(Opm::EclIO::SummaryNode node,
const Opm::UnitSystem::measure m)
: node_(std::move(node))
, m_ (m)
@@ -1652,10 +1620,10 @@ namespace Evaluator {
const SimulatorResults& simRes,
Opm::SummaryState& st) const override
{
if (this->node_.number() < 0)
if (this->node_.number < 0)
return;
auto xPos = simRes.region.find(this->node_.keyword());
auto xPos = simRes.region.find(this->node_.keyword);
if (xPos == simRes.region.end())
return;
@@ -1670,19 +1638,19 @@ namespace Evaluator {
}
private:
Opm::SummaryConfigNode node_;
Opm::EclIO::SummaryNode node_;
Opm::UnitSystem::measure m_;
std::vector<double>::size_type index() const
{
return this->node_.number() - 1;
return this->node_.number - 1;
}
};
class GlobalProcessValue : public Base
{
public:
explicit GlobalProcessValue(Opm::SummaryConfigNode node,
explicit GlobalProcessValue(Opm::EclIO::SummaryNode node,
const Opm::UnitSystem::measure m)
: node_(std::move(node))
, m_ (m)
@@ -1694,7 +1662,7 @@ namespace Evaluator {
const SimulatorResults& simRes,
Opm::SummaryState& st) const override
{
auto xPos = simRes.single.find(this->node_.keyword());
auto xPos = simRes.single.find(this->node_.keyword);
if (xPos == simRes.single.end())
return;
@@ -1705,7 +1673,7 @@ namespace Evaluator {
}
private:
Opm::SummaryConfigNode node_;
Opm::EclIO::SummaryNode node_;
Opm::UnitSystem::measure m_;
};
@@ -1795,7 +1763,7 @@ namespace Evaluator {
Factory& operator=(const Factory&) = delete;
Factory& operator=(Factory&&) = delete;
Descriptor create(const Opm::SummaryConfigNode&);
Descriptor create(const Opm::EclIO::SummaryNode&);
private:
const Opm::EclipseState& es_;
@@ -1803,7 +1771,7 @@ namespace Evaluator {
const Opm::SummaryState& st_;
const Opm::UDQConfig& udq_;
const Opm::SummaryConfigNode* node_;
const Opm::EclIO::SummaryNode* node_;
Opm::UnitSystem::measure paramUnit_;
ofun paramFunction_;
@@ -1826,7 +1794,7 @@ namespace Evaluator {
std::string userDefinedUnit() const;
};
Factory::Descriptor Factory::create(const Opm::SummaryConfigNode& node)
Factory::Descriptor Factory::create(const Opm::EclIO::SummaryNode& node)
{
this->node_ = &node;
@@ -1910,18 +1878,18 @@ namespace Evaluator {
{
auto desc = Descriptor{};
desc.uniquekey = this->node_->uniqueNodeKey();
desc.uniquekey = this->node_->unique_key();
return desc;
}
bool Factory::isBlockValue()
{
auto pos = block_units.find(this->node_->keyword());
auto pos = block_units.find(this->node_->keyword);
if (pos == block_units.end())
return false;
if (! this->grid_.cellActive(this->node_->number() - 1))
if (! this->grid_.cellActive(this->node_->number - 1))
// 'node_' is a block value, but it is configured in a
// deactivated cell. Don't create an evaluation function.
return false;
@@ -1934,7 +1902,7 @@ namespace Evaluator {
bool Factory::isRegionValue()
{
auto pos = region_units.find(this->node_->keyword());
auto pos = region_units.find(this->node_->keyword);
if (pos == region_units.end())
return false;
@@ -1946,7 +1914,7 @@ namespace Evaluator {
bool Factory::isGlobalProcessValue()
{
auto pos = single_values_units.find(this->node_->keyword());
auto pos = single_values_units.find(this->node_->keyword);
if (pos == single_values_units.end())
return false;
@@ -1958,7 +1926,7 @@ namespace Evaluator {
bool Factory::isFunctionRelation()
{
auto pos = funs.find(this->node_->keyword());
auto pos = funs.find(this->node_->keyword);
if (pos == funs.end())
return false;
@@ -1970,7 +1938,7 @@ namespace Evaluator {
bool Factory::isUserDefined()
{
return this->node_->isUserDefined();
return this->node_->is_user_defined();
}
std::string Factory::functionUnitString() const
@@ -1978,7 +1946,7 @@ namespace Evaluator {
const auto reg = Opm::out::RegionCache{};
const fn_args args {
{}, "", 0.0, 0, std::max(0, this->node_->number()),
{}, "", 0.0, 0, std::max(0, this->node_->number),
this->st_, {}, {}, reg, this->grid_,
{}
};
@@ -1995,7 +1963,7 @@ namespace Evaluator {
std::string Factory::userDefinedUnit() const
{
const auto& kw = this->node_->keyword();
const auto& kw = this->node_->keyword;
return this->udq_.has_unit(kw)
? this->udq_.unit(kw) : "?????";
@@ -2459,13 +2427,13 @@ Opm::out::Summary::SummaryImplementation::
configureRequiredRestartParameters(const SummaryConfig& sumcfg,
const Schedule& sched)
{
auto makeEvaluator = [&sumcfg, this](const SummaryConfigNode& node) -> void
auto makeEvaluator = [&sumcfg, this](const Opm::EclIO::SummaryNode& node) -> void
{
if (sumcfg.hasSummaryKey(node.uniqueNodeKey()))
if (sumcfg.hasSummaryKey(node.unique_key()))
// Handler already exists. Don't add second evaluation.
return;
auto fcnPos = funs.find(node.keyword());
auto fcnPos = funs.find(node.keyword);
assert ((fcnPos != funs.end()) &&
"Internal error creating required restart vectors");

View File

@@ -360,12 +360,18 @@ const std::string& Group::parent() const {
return this->parent_group;
}
const std::string& Group::control_group() const {
return this->parent();
std::optional<std::string> Group::control_group() const {
if (m_name == "FIELD")
return std::nullopt;
else
return this->parent();
}
const std::string& Group::flow_group() const {
return this->parent();
std::optional<std::string> Group::flow_group() const {
if (m_name == "FIELD")
return std::nullopt;
else
return this->parent();
}
const Phase& Group::topup_phase() const {