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:
+1
-1
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user