Make Structure for Per-Group Summary Data from Simulator

This commit adds a level of indirection to the current per-group
summary quantities that is directly assigned by the simulator.  In
particular, introduce a new structure named

    GroupData

that contains a 'GroupConstraints' object and make the per-group
values into 'map<string, GroupData>' rather than the current
'map<string, GroupConstraints>'.  This is in preparation of adding
support for reporting group-level production/injection guiderates
(Gx[IP]GR) to the summary file.

Update tests and APIs accordingly.
This commit is contained in:
Bård Skaflestad
2020-07-02 10:57:46 +02:00
parent c7b93797b6
commit 68b4f38464
6 changed files with 92 additions and 67 deletions
+1 -1
View File
@@ -106,7 +106,7 @@ void msim::run_step(const Schedule& schedule, Action::State& action_state, Summa
this->simulate(schedule, st, sol, well_data, report_step, seconds_elapsed, time_step);
Opm::data::Group group_data;
Opm::data::GroupValues group_data;
seconds_elapsed += time_step;
+48 -30
View File
@@ -20,63 +20,79 @@
#ifndef OPM_OUTPUT_GROUPS_HPP
#define OPM_OUTPUT_GROUPS_HPP
#include <algorithm>
#include <cstddef>
#include <initializer_list>
#include <map>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
namespace Opm {
namespace Opm { namespace data {
namespace data {
struct currentGroupConstraints {
struct GroupConstraints {
Opm::Group::ProductionCMode currentProdConstraint;
Opm::Group::InjectionCMode currentGasInjectionConstraint;
Opm::Group::InjectionCMode currentWaterInjectionConstraint;
template <class MessageBufferType>
void write(MessageBufferType& buffer) const;
template <class MessageBufferType>
void read(MessageBufferType& buffer);
inline currentGroupConstraints& set( Opm::Group::ProductionCMode cpc,
Opm::Group::InjectionCMode cgic,
Opm::Group::InjectionCMode cwic);
inline GroupConstraints& set(Opm::Group::ProductionCMode cpc,
Opm::Group::InjectionCMode cgic,
Opm::Group::InjectionCMode cwic);
};
class Group : public std::map<std::string, Opm::data::currentGroupConstraints> {
public:
struct GroupData {
GroupConstraints currentControl;
template <class MessageBufferType>
void write(MessageBufferType& buffer) const {
void write(MessageBufferType& buffer) const
{
this->currentControl.write(buffer);
}
template <class MessageBufferType>
void read(MessageBufferType& buffer)
{
this->currentControl.read(buffer);
}
};
class GroupValues : public std::map<std::string, GroupData> {
public:
template <class MessageBufferType>
void write(MessageBufferType& buffer) const
{
unsigned int size = this->size();
buffer.write(size);
for (const auto& witr : *this) {
const std::string& name = witr.first;
buffer.write(name);
const auto& pi_constr = witr.second;
pi_constr.write(buffer);
for (const auto& [gname, gdata] : *this) {
buffer.write(gname);
gdata .write(buffer);
}
}
template <class MessageBufferType>
void read(MessageBufferType& buffer) {
unsigned int size;
void read(MessageBufferType& buffer)
{
unsigned int size;
buffer.read(size);
for (size_t i = 0; i < size; ++i) {
std::string name;
buffer.read(name);
currentGroupConstraints cgc;
cgc.read(buffer);
this->emplace(name, cgc);
auto gdata = GroupData{};
gdata.read(buffer);
this->emplace(name, gdata);
}
}
};
@@ -84,26 +100,28 @@ namespace Opm {
/* IMPLEMENTATIONS */
template <class MessageBufferType>
void currentGroupConstraints::write(MessageBufferType& buffer) const {
void GroupConstraints::write(MessageBufferType& buffer) const {
buffer.write(this->currentProdConstraint);
buffer.write(this->currentGasInjectionConstraint);
buffer.write(this->currentWaterInjectionConstraint);
}
template <class MessageBufferType>
void currentGroupConstraints::read(MessageBufferType& buffer) {
void GroupConstraints::read(MessageBufferType& buffer) {
buffer.read(this->currentProdConstraint);
buffer.read(this->currentGasInjectionConstraint);
buffer.read(this->currentWaterInjectionConstraint);
}
inline currentGroupConstraints& currentGroupConstraints::set( Opm::Group::ProductionCMode cpc,
Opm::Group::InjectionCMode cgic,
Opm::Group::InjectionCMode cwic) {
inline GroupConstraints&
GroupConstraints::set(Opm::Group::ProductionCMode cpc,
Opm::Group::InjectionCMode cgic,
Opm::Group::InjectionCMode cwic)
{
this->currentGasInjectionConstraint = cgic;
this->currentWaterInjectionConstraint = cwic;
this->currentProdConstraint = cpc;
return *this;
}
+2 -2
View File
@@ -38,7 +38,7 @@ namespace Opm {
namespace Opm { namespace data {
class WellRates;
class Group;
class GroupValues;
}} // namespace Opm::data
namespace Opm { namespace out {
@@ -65,7 +65,7 @@ public:
const EclipseState& es,
const Schedule& schedule,
const data::WellRates& well_solution,
const data::Group& group_solution,
const data::GroupValues& group_solution,
const GlobalProcessParameters& single_values,
const RegionParameters& region_values = {},
const BlockValues& block_values = {}) const;
+16 -15
View File
@@ -42,8 +42,9 @@
#include <opm/io/eclipse/EclOutput.hpp>
#include <opm/io/eclipse/OutputStream.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/output/data/Groups.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/output/eclipse/RegionCache.hpp>
#include <algorithm>
@@ -379,7 +380,7 @@ struct fn_args {
int num;
const Opm::SummaryState& st;
const Opm::data::Wells& wells;
const Opm::data::Group& group;
const Opm::data::GroupValues& groups;
const Opm::out::RegionCache& regionCache;
const Opm::EclipseGrid& grid;
const std::vector< std::pair< std::string, double > > eff_factors;
@@ -749,9 +750,9 @@ inline quantity group_control( const fn_args& args ) {
// production control
if (Producer) {
const auto it_g = args.group.find(g_name);
if (it_g != args.group.end()) {
const auto& value = it_g->second.currentProdConstraint;
auto it_g = args.groups.find(g_name);
if (it_g != args.groups.end()) {
const auto& value = it_g->second.currentControl.currentProdConstraint;
auto it_c = pCModeToPCntlMode.find(value);
if (it_c == pCModeToPCntlMode.end()) {
std::stringstream str;
@@ -763,9 +764,9 @@ inline quantity group_control( const fn_args& args ) {
}
// water injection control
else if (waterInjector){
const auto it_g = args.group.find(g_name);
if (it_g != args.group.end()) {
const auto& value = it_g->second.currentWaterInjectionConstraint;
auto it_g = args.groups.find(g_name);
if (it_g != args.groups.end()) {
const auto& value = it_g->second.currentControl.currentWaterInjectionConstraint;
auto it_c = iCModeToICntlMode.find(value);
if (it_c == iCModeToICntlMode.end()) {
std::stringstream str;
@@ -778,9 +779,9 @@ inline quantity group_control( const fn_args& args ) {
// gas injection control
else if (gasInjector){
const auto it_g = args.group.find(g_name);
if (it_g != args.group.end()) {
const auto& value = it_g->second.currentGasInjectionConstraint;
auto it_g = args.groups.find(g_name);
if (it_g != args.groups.end()) {
const auto& value = it_g->second.currentControl.currentGasInjectionConstraint;
auto it_c = iCModeToICntlMode.find(value);
if (it_c == iCModeToICntlMode.end()) {
std::stringstream str;
@@ -1493,7 +1494,7 @@ namespace Evaluator {
struct SimulatorResults
{
const Opm::data::WellRates& wellSol;
const Opm::data::Group& groupSol;
const Opm::data::GroupValues& groupSol;
const std::map<std::string, double>& single;
const std::map<std::string, std::vector<double>>& region;
const std::map<std::pair<std::string, int>, double>& block;
@@ -2229,7 +2230,7 @@ public:
const int sim_step,
const double duration,
const data::WellRates& well_solution,
const data::Group& group_solution,
const data::GroupValues& group_solution,
const GlobalProcessParameters& single_values,
const RegionParameters& region_values,
const BlockValues& block_values,
@@ -2331,7 +2332,7 @@ eval(const EclipseState& es,
const int sim_step,
const double duration,
const data::WellRates& well_solution,
const data::Group& group_solution,
const data::GroupValues& group_solution,
const GlobalProcessParameters& single_values,
const RegionParameters& region_values,
const BlockValues& block_values,
@@ -2632,7 +2633,7 @@ void Summary::eval(SummaryState& st,
const EclipseState& es,
const Schedule& schedule,
const data::WellRates& well_solution,
const data::Group& group_solution,
const data::GroupValues& group_solution,
const GlobalProcessParameters& single_values,
const RegionParameters& region_values,
const BlockValues& block_values) const
+9 -9
View File
@@ -31,8 +31,8 @@
#include <cctype>
#include <ctime>
#include <opm/output/data/Wells.hpp>
#include <opm/output/data/Groups.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/output/eclipse/Summary.hpp>
#include <opm/parser/eclipse/Python/Python.hpp>
@@ -294,22 +294,22 @@ static data::Wells result_wells(const bool w3_injector = true) {
return wellrates;
}
static data::Group result_groups() {
static data::GroupValues result_groups() {
data::Group groups;
data::currentGroupConstraints cgc_group;
data::GroupValues groups;
data::GroupConstraints cgc_group;
cgc_group.set(p_cmode::NONE, i_cmode::VREP, i_cmode::RATE);
groups.emplace("G_1", cgc_group);
groups["G_1"].currentControl = cgc_group;
cgc_group.set(p_cmode::ORAT, i_cmode::RESV, i_cmode::FLD);
groups.emplace("G_2", cgc_group);
groups["G_2"].currentControl = cgc_group;
cgc_group.set(p_cmode::GRAT, i_cmode::REIN, i_cmode::VREP);
groups.emplace("G_3", cgc_group);
groups["G_3"].currentControl = cgc_group;
cgc_group.set(p_cmode::NONE, i_cmode::NONE, i_cmode::NONE);
groups.emplace("FIELD", cgc_group);
groups["FIELD"].currentControl = cgc_group;
return groups;
@@ -394,7 +394,7 @@ struct setup {
Schedule schedule;
SummaryConfig config;
data::Wells wells;
data::Group groups;
data::GroupValues groups;
std::string name;
WorkArea ta;
+16 -10
View File
@@ -23,13 +23,17 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cctype>
#include <chrono>
#include <cstddef>
#include <ctime>
#include <exception>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <cctype>
#include <ctime>
#include <utility>
#include <opm/output/data/Wells.hpp>
#include <opm/output/data/Groups.hpp>
@@ -187,21 +191,21 @@ static data::Wells result_wells() {
}
static data::Group result_groups() {
data::Group groups;
data::currentGroupConstraints cgc_group;
static data::GroupValues result_groups() {
data::GroupValues groups;
data::GroupConstraints cgc_group;
cgc_group.set(p_cmode::NONE, i_cmode::VREP, i_cmode::RATE);
groups.emplace("TEST", cgc_group);
groups["TEST"].currentControl = cgc_group;
cgc_group.set(p_cmode::ORAT, i_cmode::RESV, i_cmode::REIN);
groups.emplace("LOWER", cgc_group);
groups["LOWER"].currentControl = cgc_group;
cgc_group.set(p_cmode::GRAT, i_cmode::REIN, i_cmode::VREP);
groups.emplace("UPPER", cgc_group);
groups["UPPER"].currentControl = cgc_group;
cgc_group.set(p_cmode::NONE, i_cmode::NONE, i_cmode::NONE);
groups.emplace("FIELD", cgc_group);
groups["FIELD"].currentControl = cgc_group;
return groups;
}
@@ -215,7 +219,7 @@ struct setup {
Schedule schedule;
SummaryConfig config;
data::Wells wells;
data::Group groups;
data::GroupValues groups;
std::string name;
WorkArea ta;
@@ -236,6 +240,8 @@ struct setup {
};
} // Anonymous namespace
// =====================================================================
BOOST_AUTO_TEST_SUITE(Summary)
/*
* Tests works by reading the Deck, write the summary output, then immediately