From 7fecd9f433aa5545d8f685ddee0881e2d3a1745c Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 21 Apr 2021 09:35:41 +0200 Subject: [PATCH] Create new class GroupState to maintain runtime state of groups --- CMakeLists_files.cmake | 3 + opm/simulators/wells/GroupState.cpp | 237 ++++++++++++++++++ opm/simulators/wells/GroupState.hpp | 168 +++++++++++++ .../wells/WellStateFullyImplicitBlackoil.hpp | 154 +++--------- tests/test_GroupState.cpp | 69 +++++ 5 files changed, 516 insertions(+), 115 deletions(-) create mode 100644 opm/simulators/wells/GroupState.cpp create mode 100644 opm/simulators/wells/GroupState.hpp create mode 100644 tests/test_GroupState.cpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index f3d685ff8..6b10c1d57 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -40,6 +40,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/utils/DeferredLogger.cpp opm/simulators/utils/gatherDeferredLogger.cpp opm/simulators/utils/ParallelRestart.cpp + opm/simulators/wells/GroupState.cpp opm/simulators/wells/ParallelWellInfo.cpp opm/simulators/wells/VFPProdProperties.cpp opm/simulators/wells/VFPInjProperties.cpp @@ -106,6 +107,7 @@ list (APPEND TEST_SOURCE_FILES tests/test_parallelwellinfo.cpp tests/test_glift1.cpp tests/test_keyword_validator.cpp + tests/test_GroupState.cpp ) if(MPI_FOUND) @@ -253,6 +255,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/wells/TargetCalculator.hpp opm/simulators/wells/WellConnectionAuxiliaryModule.hpp opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp + opm/simulators/wells/GroupState.hpp opm/simulators/wells/VFPProperties.hpp opm/simulators/wells/VFPHelpers.hpp opm/simulators/wells/VFPInjProperties.hpp diff --git a/opm/simulators/wells/GroupState.cpp b/opm/simulators/wells/GroupState.cpp new file mode 100644 index 000000000..87fc18951 --- /dev/null +++ b/opm/simulators/wells/GroupState.cpp @@ -0,0 +1,237 @@ +/* + Copyright 2021 Equinor + + 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 . +*/ + + + +#include + +namespace Opm { + +GroupState::GroupState(std::size_t np) : + num_phases(np) +{} + +bool GroupState::operator==(const GroupState& other) const { + return this->m_production_rates == other.m_production_rates && + this->production_controls == other.production_controls && + this->prod_red_rates == other.prod_red_rates && + this->inj_red_rates == other.inj_red_rates && + this->inj_resv_rates == other.inj_resv_rates && + this->inj_potentials == other.inj_potentials && + this->inj_rein_rates == other.inj_rein_rates && + this->inj_vrep_rate == other.inj_vrep_rate && + this->m_grat_sales_target == other.m_grat_sales_target && + this->injection_controls == other.injection_controls; +} + +//------------------------------------------------------------------------- + +bool GroupState::has_production_rates(const std::string& gname) const { + auto group_iter = this->m_production_rates.find(gname); + return (group_iter != this->m_production_rates.end()); +} + +void GroupState::update_production_rates(const std::string& gname, const std::vector& rates) { + if (rates.size() != this->num_phases) + throw std::logic_error("Wrong number of phases"); + + this->m_production_rates[gname] = rates; +} + +const std::vector& GroupState::production_rates(const std::string& gname) const { + auto group_iter = this->m_production_rates.find(gname); + if (group_iter == this->m_production_rates.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +bool GroupState::has_production_reduction_rates(const std::string& gname) const { + auto group_iter = this->prod_red_rates.find(gname); + return (group_iter != this->prod_red_rates.end()); +} + +void GroupState::update_production_reduction_rates(const std::string& gname, const std::vector& rates) { + if (rates.size() != this->num_phases) + throw std::logic_error("Wrong number of phases"); + + this->prod_red_rates[gname] = rates; +} + +const std::vector& GroupState::production_reduction_rates(const std::string& gname) const { + auto group_iter = this->prod_red_rates.find(gname); + if (group_iter == this->prod_red_rates.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +bool GroupState::has_injection_reduction_rates(const std::string& gname) const { + auto group_iter = this->inj_red_rates.find(gname); + return (group_iter != this->inj_red_rates.end()); +} + +void GroupState::update_injection_reduction_rates(const std::string& gname, const std::vector& rates) { + if (rates.size() != this->num_phases) + throw std::logic_error("Wrong number of phases"); + + this->inj_red_rates[gname] = rates; +} + +const std::vector& GroupState::injection_reduction_rates(const std::string& gname) const { + auto group_iter = this->inj_red_rates.find(gname); + if (group_iter == this->inj_red_rates.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +bool GroupState::has_injection_reservoir_rates(const std::string& gname) const { + auto group_iter = this->inj_resv_rates.find(gname); + return (group_iter != this->inj_resv_rates.end()); +} + +void GroupState::update_injection_reservoir_rates(const std::string& gname, const std::vector& rates) { + if (rates.size() != this->num_phases) + throw std::logic_error("Wrong number of phases"); + + this->inj_resv_rates[gname] = rates; +} + +const std::vector& GroupState::injection_reservoir_rates(const std::string& gname) const { + auto group_iter = this->inj_resv_rates.find(gname); + if (group_iter == this->inj_resv_rates.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +void GroupState::update_injection_rein_rates(const std::string& gname, const std::vector& rates) { + if (rates.size() != this->num_phases) + throw std::logic_error("Wrong number of phases"); + + this->inj_rein_rates[gname] = rates; +} + +const std::vector& GroupState::injection_rein_rates(const std::string& gname) const { + auto group_iter = this->inj_rein_rates.find(gname); + if (group_iter == this->inj_rein_rates.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +void GroupState::update_injection_vrep_rate(const std::string& gname, double rate) { + this->inj_vrep_rate[gname] = rate; +} + +double GroupState::injection_vrep_rate(const std::string& gname) const { + auto group_iter = this->inj_vrep_rate.find(gname); + if (group_iter == this->inj_vrep_rate.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +void GroupState::update_grat_sales_target(const std::string& gname, double target) { + this->m_grat_sales_target[gname] = target; +} + +double GroupState::grat_sales_target(const std::string& gname) const { + auto group_iter = this->m_grat_sales_target.find(gname); + if (group_iter == this->m_grat_sales_target.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +bool GroupState::has_grat_sales_target(const std::string& gname) const { + return (this->m_grat_sales_target.count(gname) > 0); +} + +//------------------------------------------------------------------------- + +void GroupState::update_injection_potentials(const std::string& gname, const std::vector& potentials) { + if (potentials.size() != this->num_phases) + throw std::logic_error("Wrong number of phases"); + + this->inj_potentials[gname] = potentials; +} + +const std::vector& GroupState::injection_potentials(const std::string& gname) const { + auto group_iter = this->inj_potentials.find(gname); + if (group_iter == this->inj_potentials.end()) + throw std::logic_error("No such group"); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +bool GroupState::has_production_control(const std::string& gname) const { + auto group_iter = this->production_controls.find(gname); + if (group_iter == this->production_controls.end()) + return false; + + return true; +} + +void GroupState::production_control(const std::string& gname, Group::ProductionCMode cmode) { + this->production_controls[gname] = cmode; +} + +Group::ProductionCMode GroupState::production_control(const std::string& gname) const { + auto group_iter = this->production_controls.find(gname); + if (group_iter == this->production_controls.end()) + throw std::logic_error("Could not find any control for production group: " + gname); + + return group_iter->second; +} + +//------------------------------------------------------------------------- + +bool GroupState::has_injection_control(const std::string& gname, Phase phase) const { + return this->injection_controls.count(std::make_pair(phase, gname)) > 0; +} + +void GroupState::injection_control(const std::string& gname, Phase phase, Group::InjectionCMode cmode) { + this->injection_controls[ std::make_pair(phase, gname) ] = cmode; +} + +Group::InjectionCMode GroupState::injection_control(const std::string& gname, Phase phase) const { + auto key = std::make_pair(phase, gname); + auto group_iter = this->injection_controls.find( key ); + if (group_iter == this->injection_controls.end()) + throw std::logic_error("Could not find ontrol for injection group: " + gname); + + return group_iter->second; +} +} diff --git a/opm/simulators/wells/GroupState.hpp b/opm/simulators/wells/GroupState.hpp new file mode 100644 index 000000000..6b2115fbc --- /dev/null +++ b/opm/simulators/wells/GroupState.hpp @@ -0,0 +1,168 @@ +/* + Copyright 2021 Equinor + + 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 . +*/ + +#ifndef OPM_GROUPSTATE_HEADER_INCLUDED +#define OPM_GROUPSTATE_HEADER_INCLUDED + +#include +#include + +#include +#include + +namespace Opm { + +class GroupState { +public: + explicit GroupState(std::size_t num_phases); + bool operator==(const GroupState& other) const; + + bool has_production_rates(const std::string& gname) const; + void update_production_rates(const std::string& gname, const std::vector& rates); + const std::vector& production_rates(const std::string& gname) const; + + bool has_production_reduction_rates(const std::string& gname) const; + void update_production_reduction_rates(const std::string& gname, const std::vector& rates); + const std::vector& production_reduction_rates(const std::string& gname) const; + + bool has_injection_reduction_rates(const std::string& gname) const; + void update_injection_reduction_rates(const std::string& gname, const std::vector& rates); + const std::vector& injection_reduction_rates(const std::string& gname) const; + + bool has_injection_reservoir_rates(const std::string& gname) const; + void update_injection_reservoir_rates(const std::string& gname, const std::vector& rates); + const std::vector& injection_reservoir_rates(const std::string& gname) const; + + void update_injection_rein_rates(const std::string& gname, const std::vector& rates); + const std::vector& injection_rein_rates(const std::string& gname) const; + + void update_injection_potentials(const std::string& gname, const std::vector& potentials); + const std::vector& injection_potentials(const std::string& gname) const; + + void update_injection_vrep_rate(const std::string& gname, double rate); + double injection_vrep_rate(const std::string& gname) const; + + void update_grat_sales_target(const std::string& gname, double target); + double grat_sales_target(const std::string& gname) const; + bool has_grat_sales_target(const std::string& gname) const; + + bool has_production_control(const std::string& gname) const; + void production_control(const std::string& gname, Group::ProductionCMode cmode); + Group::ProductionCMode production_control(const std::string& gname) const; + + bool has_injection_control(const std::string& gname, Phase phase) const; + void injection_control(const std::string& gname, Phase phase, Group::InjectionCMode cmode); + Group::InjectionCMode injection_control(const std::string& gname, Phase phase) const; + + std::size_t data_size() const; + std::size_t collect(double * data) const; + std::size_t distribute(const double * data); + + + template + void communicate_rates(const Comm& comm) + { + // Note that injection_group_vrep_rates is handled separate from + // the forAllGroupData() function, since it contains single doubles, + // not vectors. + + // Create a function that calls some function + // for all the individual data items to simplify + // the further code. + auto iterateContainer = [](auto& container, auto& func) { + for (auto& x : container) { + func(x.second); + } + }; + + + auto forAllGroupData = [&](auto& func) { + iterateContainer(m_production_rates, func); + iterateContainer(prod_red_rates, func); + iterateContainer(inj_red_rates, func); + iterateContainer(inj_resv_rates, func); + iterateContainer(inj_rein_rates, func); + }; + + // Compute the size of the data. + std::size_t sz = 0; + auto computeSize = [&sz](const auto& v) { + sz += v.size(); + }; + forAllGroupData(computeSize); + sz += this->inj_vrep_rate.size(); + + // Make a vector and collect all data into it. + std::vector data(sz); + std::size_t pos = 0; + + + + // That the collect function mutates the vector v is an artifact for + // testing. + auto collect = [&data, &pos](auto& v) { + for (auto& x : v) { + data[pos++] = x; + x = -1; + } + }; + forAllGroupData(collect); + for (const auto& x : this->inj_vrep_rate) { + data[pos++] = x.second; + } + if (pos != sz) + throw std::logic_error("Internal size mismatch when collecting groupData"); + + // Communicate it with a single sum() call. + comm.sum(data.data(), data.size()); + + // Distribute the summed vector to the data items. + pos = 0; + auto distribute = [&data, &pos](auto& v) { + for (auto& x : v) { + x = data[pos++]; + } + }; + forAllGroupData(distribute); + for (auto& x : this->inj_vrep_rate) { + x.second = data[pos++]; + } + if (pos != sz) + throw std::logic_error("Internal size mismatch when distributing groupData"); + } + +private: + std::size_t num_phases; + std::map> m_production_rates; + std::map production_controls; + std::map> prod_red_rates; + std::map> inj_red_rates; + std::map> inj_resv_rates; + std::map> inj_potentials; + std::map> inj_rein_rates; + std::map inj_vrep_rate; + std::map m_grat_sales_target; + + + std::map, Group::InjectionCMode> injection_controls; +}; + +} + +#endif diff --git a/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp b/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp index 10acb5a46..d2d1ff389 100644 --- a/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp +++ b/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp @@ -22,6 +22,7 @@ #define OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED #include +#include #include #include @@ -69,7 +70,8 @@ namespace Opm using BaseType :: updateStatus; explicit WellStateFullyImplicitBlackoil(int num_phases) : - WellState(num_phases) + WellState(num_phases), + group_state(num_phases) {} @@ -412,39 +414,29 @@ namespace Opm const std::vector& currentProductionControls() const { return current_production_controls_; } bool hasProductionGroupControl(const std::string& groupName) const { - return current_production_group_controls_.count(groupName) > 0; + return this->group_state.has_production_control(groupName); } bool hasInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName) const { - return current_injection_group_controls_.count(std::make_pair(phase, groupName)) > 0; + return this->group_state.has_injection_control(groupName, phase); } /// One current control per group. void setCurrentProductionGroupControl(const std::string& groupName, const Group::ProductionCMode& groupControl ) { - current_production_group_controls_[groupName] = groupControl; + this->group_state.production_control(groupName, groupControl); } - const Group::ProductionCMode& currentProductionGroupControl(const std::string& groupName) const { - auto it = current_production_group_controls_.find(groupName); - - if (it == current_production_group_controls_.end()) - OPM_THROW(std::logic_error, "Could not find any control for production group " << groupName); - - return it->second; + Group::ProductionCMode currentProductionGroupControl(const std::string& groupName) const { + return this->group_state.production_control(groupName); } /// One current control per group. void setCurrentInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName, const Group::InjectionCMode& groupControl ) { - current_injection_group_controls_[std::make_pair(phase, groupName)] = groupControl; + this->group_state.injection_control(groupName, phase, groupControl); } - const Group::InjectionCMode& currentInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName) const { - auto it = current_injection_group_controls_.find(std::make_pair(phase, groupName)); - - if (it == current_injection_group_controls_.end()) - OPM_THROW(std::logic_error, "Could not find any control for " << phase << " injection group " << groupName); - - return it->second; + Group::InjectionCMode currentInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName) const { + return this->group_state.injection_control(groupName, phase); } void setCurrentWellRates(const std::string& wellName, const std::vector& rates ) { @@ -465,117 +457,76 @@ namespace Opm } void setCurrentProductionGroupRates(const std::string& groupName, const std::vector& rates ) { - production_group_rates[groupName] = rates; + this->group_state.update_production_rates(groupName, rates); } const std::vector& currentProductionGroupRates(const std::string& groupName) const { - auto it = production_group_rates.find(groupName); - - if (it == production_group_rates.end()) - OPM_THROW(std::logic_error, "Could not find any rates for productino group " << groupName); - - return it->second; + return this->group_state.production_rates(groupName); } bool hasProductionGroupRates(const std::string& groupName) const { - return this->production_group_rates.find(groupName) != this->production_group_rates.end(); + return this->group_state.has_production_rates(groupName); } void setCurrentProductionGroupReductionRates(const std::string& groupName, const std::vector& target ) { - production_group_reduction_rates[groupName] = target; + this->group_state.update_production_reduction_rates(groupName, target); } const std::vector& currentProductionGroupReductionRates(const std::string& groupName) const { - auto it = production_group_reduction_rates.find(groupName); - - if (it == production_group_reduction_rates.end()) - OPM_THROW(std::logic_error, "Could not find any reduction rates for production group " << groupName); - - return it->second; + return this->group_state.production_reduction_rates(groupName); } void setCurrentInjectionGroupReductionRates(const std::string& groupName, const std::vector& target ) { - injection_group_reduction_rates[groupName] = target; + this->group_state.update_injection_reduction_rates(groupName, target); } const std::vector& currentInjectionGroupReductionRates(const std::string& groupName) const { - auto it = injection_group_reduction_rates.find(groupName); - - if (it == injection_group_reduction_rates.end()) - OPM_THROW(std::logic_error, "Could not find any reduction rates for injection group " << groupName); - - return it->second; + return this->group_state.injection_reduction_rates(groupName); } void setCurrentInjectionGroupReservoirRates(const std::string& groupName, const std::vector& target ) { - injection_group_reservoir_rates[groupName] = target; + this->group_state.update_injection_reservoir_rates(groupName, target); } const std::vector& currentInjectionGroupReservoirRates(const std::string& groupName) const { - auto it = injection_group_reservoir_rates.find(groupName); - - if (it == injection_group_reservoir_rates.end()) - OPM_THROW(std::logic_error, "Could not find any reservoir rates for injection group " << groupName); - - return it->second; + return this->group_state.injection_reservoir_rates(groupName); } void setCurrentInjectionVREPRates(const std::string& groupName, const double& target ) { - injection_group_vrep_rates[groupName] = target; + this->group_state.update_injection_vrep_rate(groupName, target); } - const double& currentInjectionVREPRates(const std::string& groupName) const { - auto it = injection_group_vrep_rates.find(groupName); - - if (it == injection_group_vrep_rates.end()) - OPM_THROW(std::logic_error, "Could not find any VREP rates for group " << groupName); - - return it->second; + double currentInjectionVREPRates(const std::string& groupName) const { + return this->group_state.injection_vrep_rate(groupName); } void setCurrentInjectionREINRates(const std::string& groupName, const std::vector& target ) { - injection_group_rein_rates[groupName] = target; + this->group_state.update_injection_rein_rates(groupName, target); } const std::vector& currentInjectionREINRates(const std::string& groupName) const { - auto it = injection_group_rein_rates.find(groupName); - - if (it == injection_group_rein_rates.end()) - OPM_THROW(std::logic_error, "Could not find any REIN rates for group " << groupName); - - return it->second; + return this->group_state.injection_rein_rates(groupName); } void setCurrentGroupGratTargetFromSales(const std::string& groupName, const double& target ) { - group_grat_target_from_sales[groupName] = target; + this->group_state.update_grat_sales_target(groupName, target); } bool hasGroupGratTargetFromSales(const std::string& groupName) const { - auto it = group_grat_target_from_sales.find(groupName); - return it != group_grat_target_from_sales.end(); + return this->group_state.has_grat_sales_target(groupName); } - const double& currentGroupGratTargetFromSales(const std::string& groupName) const { - auto it = group_grat_target_from_sales.find(groupName); - - if (it == group_grat_target_from_sales.end()) - OPM_THROW(std::logic_error, "Could not find any grat target from sales for group " << groupName); - - return it->second; + double currentGroupGratTargetFromSales(const std::string& groupName) const { + return this->group_state.grat_sales_target(groupName); } void setCurrentGroupInjectionPotentials(const std::string& groupName, const std::vector& pot ) { - injection_group_potentials[groupName] = pot; + this->group_state.update_injection_potentials(groupName, pot); } const std::vector& currentGroupInjectionPotentials(const std::string& groupName) const { - auto it = injection_group_potentials.find(groupName); - - if (it == injection_group_potentials.end()) - OPM_THROW(std::logic_error, "Could not find any potentials for group " << groupName); - - return it->second; + return this->group_state.injection_potentials(groupName); } data::Wells @@ -1141,11 +1092,6 @@ namespace Opm // Create a function that calls some function // for all the individual data items to simplify // the further code. - auto iterateContainer = [](auto& container, auto& func) { - for (auto& x : container) { - func(x.second); - } - }; auto iterateRatesContainer = [](auto& container, auto& func) { for (auto& x : container) { if (x.second.first) @@ -1163,22 +1109,13 @@ namespace Opm } }; - auto forAllGroupData = [&](auto& func) { - iterateContainer(injection_group_rein_rates, func); - iterateContainer(production_group_reduction_rates, func); - iterateContainer(injection_group_reduction_rates, func); - iterateContainer(injection_group_reservoir_rates, func); - iterateContainer(production_group_rates, func); - iterateRatesContainer(well_rates, func); - }; // Compute the size of the data. std::size_t sz = 0; auto computeSize = [&sz](const auto& v) { sz += v.size(); }; - forAllGroupData(computeSize); - sz += injection_group_vrep_rates.size(); + iterateRatesContainer(this->well_rates, computeSize); sz += current_alq_.size(); // Make a vector and collect all data into it. @@ -1189,10 +1126,7 @@ namespace Opm data[pos++] = x; } }; - forAllGroupData(collect); - for (const auto& x : injection_group_vrep_rates) { - data[pos++] = x.second; - } + iterateRatesContainer(this->well_rates, collect); for (const auto& x : current_alq_) { data[pos++] = x.second; } @@ -1208,14 +1142,13 @@ namespace Opm x = data[pos++]; } }; - forAllGroupData(distribute); - for (auto& x : injection_group_vrep_rates) { - x.second = data[pos++]; - } + iterateRatesContainer(this->well_rates, distribute); for (auto& x : current_alq_) { x.second = data[pos++]; } assert(pos == sz); + + this->group_state.communicate_rates(comm); } template @@ -1391,19 +1324,10 @@ namespace Opm std::vector globalIsInjectionGrup_; std::vector globalIsProductionGrup_; std::map wellNameToGlobalIdx_; - - std::map current_production_group_controls_; - std::map, Group::InjectionCMode> current_injection_group_controls_; - std::map>> well_rates; - std::map> production_group_rates; - std::map> production_group_reduction_rates; - std::map> injection_group_reduction_rates; - std::map> injection_group_reservoir_rates; - std::map> injection_group_potentials; - std::map injection_group_vrep_rates; - std::map> injection_group_rein_rates; - std::map group_grat_target_from_sales; + + GroupState group_state; + std::map current_alq_; std::map default_alq_; std::map alq_increase_count_; diff --git a/tests/test_GroupState.cpp b/tests/test_GroupState.cpp new file mode 100644 index 000000000..3a5d6df52 --- /dev/null +++ b/tests/test_GroupState.cpp @@ -0,0 +1,69 @@ +/* + Copyright 2021 Equinor. + + 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 . +*/ + +#include + +#include + +#define BOOST_TEST_MODULE GroupStateTest +#include + +using namespace Opm; + +class TestCommunicator { +public: + void sum(const double *, std::size_t) const {} +}; + + + +BOOST_AUTO_TEST_CASE(GroupStateCreate) { + std::size_t num_phases{3}; + GroupState gs(num_phases); + + BOOST_CHECK(!gs.has_production_rates("AGROUP")); + BOOST_CHECK_THROW( gs.update_production_rates("AGROUP", {0}), std::exception); + + std::vector rates{0,1,2}; + gs.update_production_rates("AGROUP", rates); + BOOST_CHECK(gs.has_production_rates("AGROUP")); + + BOOST_CHECK_THROW( gs.production_rates("NO_SUCH_GROUP"), std::exception ); + auto r2 = gs.production_rates("AGROUP"); + BOOST_CHECK( r2 == rates ); + + gs.update_injection_rein_rates("CGROUP", rates); + + + BOOST_CHECK(!gs.has_production_control("NO_SUCH_GROUP")); + BOOST_CHECK(!gs.has_production_control("AGROUP")); + + gs.production_control("AGROUP", Group::ProductionCMode::GRAT); + BOOST_CHECK(gs.has_production_control("AGROUP")); + BOOST_CHECK(gs.production_control("AGROUP") == Group::ProductionCMode::GRAT); + BOOST_CHECK_THROW(gs.production_control("BGROUP"), std::exception); + + + auto gs2 = gs; + BOOST_CHECK(gs2 == gs); + TestCommunicator comm; + gs.communicate_rates(comm); + BOOST_CHECK(gs2 == gs); +} +