From d2dce884113b8de4fbfc76e0482c624dc5b22777 Mon Sep 17 00:00:00 2001 From: Steinar Foss Date: Thu, 31 Oct 2019 15:18:42 +0100 Subject: [PATCH 1/3] Adding keyword GCONSALE to Schedule. added files GConSale cpp/hpp. Schedule: adde GConSale as DynamicState. Shcedule: added function gConSale. added function handleGCONSALE. GConsale: added substruct GCONSALEGroup. GConSale: empty records added. GConSale: all values set to zero. GCONSALE: values stored as UDA. GConSale: UDAValues to SI. GConSale: max_proc parsed. --- CMakeLists_files.cmake | 1 + .../EclipseState/Schedule/Group/GConSale.hpp | 57 +++++++++++++++ .../EclipseState/Schedule/Schedule.hpp | 4 ++ .../EclipseState/Schedule/Group/GConSale.cpp | 71 +++++++++++++++++++ .../EclipseState/Schedule/Schedule.cpp | 27 +++++++ .../share/keywords/000_Eclipse100/G/GCONSALE | 2 +- tests/parser/GroupTests.cpp | 39 ++++++++++ 7 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp create mode 100644 src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 900eb8dbb..0caffb40b 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -97,6 +97,7 @@ if(ENABLE_ECL_INPUT) src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.cpp src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp + src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp src/opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.cpp src/opm/parser/eclipse/EclipseState/Schedule/Well/injection.cpp src/opm/parser/eclipse/EclipseState/Schedule/MessageLimits.cpp diff --git a/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp b/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp new file mode 100644 index 000000000..d2bd73f2c --- /dev/null +++ b/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp @@ -0,0 +1,57 @@ +/* + Copyright 2019 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 . +*/ + +#ifndef GCONSALE_H +#define GCONSALE_H + +#include +#include + +namespace Opm { + + class GConSale { + public: + + enum class MaxProcedure { + NONE, CON, CON_P, WELL, PLUG, RATE, MAXR, END + }; + + struct GCONSALEGroup { + UDAValue sales_target; + UDAValue max_sales_rate; + UDAValue min_sales_rate; + MaxProcedure max_proc; + }; + + GConSale(); + + bool has(const std::string& name) const; + const GCONSALEGroup& getGroup(const std::string& name) const; + MaxProcedure stringToProcedure(const std::string& procedure); + void add_group(const std::string& name, const UDAValue& sales_target, const UDAValue& max_rate, const UDAValue& min_rate, const std::string& procedure); + size_t size() const; + + private: + std::map groups; + }; + +} + + +#endif diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index 4a4f2434f..c17e9c873 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,7 @@ namespace Opm const UDQActive& udqActive(size_t timeStep) const; const WellTestConfig& wtestConfig(size_t timestep) const; + const GConSale& gConSale(size_t timestep) const; const WListManager& getWListManager(size_t timeStep) const; const UDQConfig& getUDQConfig(size_t timeStep) const; const Action::Actions& actions(std::size_t timeStep) const; @@ -234,6 +236,7 @@ namespace Opm DynamicState> udq_config; DynamicState> udq_active; DynamicState> guide_rate_config; + DynamicState> gconsale; DynamicState global_whistctl_mode; DynamicState> m_actions; RFTConfig rft_config; @@ -281,6 +284,7 @@ namespace Opm void handleGCONINJE( const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors); void handleGCONPROD( const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors); void handleGEFAC( const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors); + void handleGCONSALE( const DeckKeyword& keyword, size_t currentStep); void handleGUIDERAT( const DeckKeyword& keyword, size_t currentStep); void handleLINCOM( const DeckKeyword& keyword, size_t currentStep); void handleWEFAC( const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp new file mode 100644 index 000000000..918ed48c9 --- /dev/null +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp @@ -0,0 +1,71 @@ +/* + Copyright 2019 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 . +*/ + +#include + +#include + +namespace Opm { + +GConSale::GConSale() { +} + +bool GConSale::has(const std::string& name) const { + return (groups.find(name) != groups.end()); +} + +const GConSale::GCONSALEGroup& GConSale::getGroup(const std::string& name) const { + + auto it = groups.find(name); + if (it == groups.end()) + throw std::invalid_argument("Current GConSale obj. does not contain '" + name + "'."); + else + return it->second; +} + +GConSale::MaxProcedure GConSale::stringToProcedure(const std::string& str_proc) { + + if (str_proc == "NONE") return MaxProcedure::NONE; + else if (str_proc == "CON" ) return MaxProcedure::CON; + else if (str_proc == "+CON") return MaxProcedure::CON_P; + else if (str_proc == "WELL") return MaxProcedure::WELL; + else if (str_proc == "PLUG") return MaxProcedure::PLUG; + else if (str_proc == "RATE") return MaxProcedure::RATE; + else if (str_proc == "MAXR") return MaxProcedure::MAXR; + else if (str_proc == "END" ) return MaxProcedure::END; + else + throw std::invalid_argument(str_proc + "invalid argument to GConSake::stringToProcedure"); + + return MaxProcedure::NONE; +} + +void GConSale::add_group(const std::string& name, const UDAValue& sales_target, const UDAValue& max_rate, const UDAValue& min_rate, const std::string& procedure) { + groups[name] = GCONSALEGroup(); + GConSale::GCONSALEGroup& group = groups[name]; + group.sales_target = sales_target; + group.max_sales_rate = max_rate; + group.min_sales_rate = min_rate; + group.max_proc = stringToProcedure(procedure); +} + +size_t GConSale::size() const { + return groups.size(); +} + +} diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 1152d9405..c73b1a142 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -119,6 +119,7 @@ namespace { m_messageLimits( this->m_timeMap ), m_runspec( runspec ), wtest_config(this->m_timeMap, std::make_shared() ), + gconsale(this->m_timeMap, std::make_shared() ), wlist_manager( this->m_timeMap, std::make_shared()), udq_config(this->m_timeMap, std::make_shared(deck)), udq_active(this->m_timeMap, std::make_shared()), @@ -337,6 +338,9 @@ namespace { else if (keyword.name() == "GEFAC") handleGEFAC(keyword, currentStep, parseContext, errors); + else if (keyword.name() == "GCONSALE") + handleGCONSALE(keyword, currentStep); + else if (keyword.name() == "GUIDERAT") handleGUIDERAT(keyword, currentStep); @@ -1594,6 +1598,24 @@ namespace { } } + void Schedule::handleGCONSALE( const DeckKeyword& keyword, size_t currentStep) { + const auto& current = *this->gconsale.get(currentStep); + std::shared_ptr new_gconsale(new GConSale(current)); + for( const auto& record : keyword ) { + const std::string& groupName = record.getItem("GROUP").getTrimmedString(0); + auto sales_target = record.getItem("SALES_TARGET").get(0); + auto max_rate = record.getItem("MAX_SALES_RATE").get(0); + auto min_rate = record.getItem("MIN_SALES_RATE").get(0); + std::cout << "SALES TARGET = " << sales_target.get() << std::endl; + std::string procedure = record.getItem("MAX_PROC").getTrimmedString(0); + + new_gconsale->add_group(groupName, sales_target, max_rate, min_rate, procedure); + + } + this->gconsale.update(currentStep, new_gconsale); + } + + void Schedule::handleGUIDERAT( const DeckKeyword& keyword, size_t currentStep) { const auto& record = keyword.getRecord(0); @@ -2567,6 +2589,11 @@ void Schedule::handleGRUPTREE( const DeckKeyword& keyword, size_t currentStep, c return *ptr; } + const GConSale& Schedule::gConSale(size_t timeStep) const { + const auto& ptr = this->gconsale.get(timeStep); + return *ptr; + } + const WListManager& Schedule::getWListManager(size_t timeStep) const { const auto& ptr = this->wlist_manager.get(timeStep); return *ptr; diff --git a/src/opm/parser/eclipse/share/keywords/000_Eclipse100/G/GCONSALE b/src/opm/parser/eclipse/share/keywords/000_Eclipse100/G/GCONSALE index b19054b95..c214e4251 100644 --- a/src/opm/parser/eclipse/share/keywords/000_Eclipse100/G/GCONSALE +++ b/src/opm/parser/eclipse/share/keywords/000_Eclipse100/G/GCONSALE @@ -1,7 +1,7 @@ {"name" : "GCONSALE" , "sections" : ["SCHEDULE"], "items" : [ {"name" : "GROUP" , "value_type" : "STRING" }, {"name" : "SALES_TARGET" , "value_type" : "UDA", "dimension": "GasSurfaceVolume/Time"}, - {"name" : "MAX_SALES_RATE" , "value_type" : "UDA", "dimension": "GasSurfaceVolume/Time"}, + {"name" : "MAX_SALES_RATE" , "value_type" : "UDA", "dimension": "GasSurfaceVolume/Time", "default": 1e20}, {"name" : "MIN_SALES_RATE" , "value_type" : "UDA", "dimension": "GasSurfaceVolume/Time", "default" : -1e20}, {"name" : "MAX_PROC" , "value_type" : "STRING", "default" : "NONE"} ]} diff --git a/tests/parser/GroupTests.cpp b/tests/parser/GroupTests.cpp index a9f127780..ffba4ce9e 100644 --- a/tests/parser/GroupTests.cpp +++ b/tests/parser/GroupTests.cpp @@ -378,3 +378,42 @@ BOOST_AUTO_TEST_CASE(TESTGuideRate) { GuideRate gr(schedule); } + +BOOST_AUTO_TEST_CASE(TESTGCONSALE) { + Parser parser; + std::string input = R"( + START -- 0 + 31 AUG 1993 / + SCHEDULE + + GRUPTREE + 'G1' 'FIELD' / + 'G2' 'FIELD' / + / + + GCONSALE + 'G1' 50000 55000 45000 WELL / + / + )"; + + auto deck = parser.parseString(input); + EclipseGrid grid(10,10,10); + TableManager table ( deck ); + Eclipse3DProperties eclipseProperties ( deck , table, grid); + Runspec runspec (deck ); + Schedule schedule(deck, grid, eclipseProperties, runspec); + + double metric_to_si = 1.0 / (24.0 * 3600.0); //cubic meters / day + + const auto& gconsale = schedule.gConSale(0); + BOOST_CHECK_EQUAL(gconsale.size(), 1); + BOOST_CHECK(gconsale.has("G1")); + BOOST_CHECK(!gconsale.has("G2")); + const GConSale::GCONSALEGroup& group = gconsale.getGroup("G1"); + BOOST_CHECK_EQUAL(group.sales_target.get(), 50000 * metric_to_si); + BOOST_CHECK_EQUAL(group.max_sales_rate.get(), 55000 * metric_to_si); + BOOST_CHECK_EQUAL(group.min_sales_rate.get(), 45000 * metric_to_si); + BOOST_CHECK(group.max_proc == GConSale::MaxProcedure::WELL); + + +} From ec07dca68b2bb45667022e47a35a2806f259e590 Mon Sep 17 00:00:00 2001 From: Steinar Foss Date: Mon, 4 Nov 2019 09:31:45 +0100 Subject: [PATCH 2/3] Added GConSale.hpp to CMakeLists_files.cmake. --- CMakeLists_files.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 0caffb40b..ea2c73f02 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -617,6 +617,7 @@ if(ENABLE_ECL_INPUT) opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.hpp opm/parser/eclipse/EclipseState/Schedule/Group/Group2.hpp opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp + opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp From 17d11e9a60a6c123e75494eca36915990a2699ae Mon Sep 17 00:00:00 2001 From: Steinar Foss Date: Mon, 4 Nov 2019 13:59:54 +0100 Subject: [PATCH 3/3] GConSaleGroup: MaxProcedure static, simplified get and add. --- opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp | 6 +++--- .../parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp | 4 ++-- src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp | 2 +- tests/parser/GroupTests.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp b/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp index d2bd73f2c..ca290ac09 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp @@ -42,9 +42,9 @@ namespace Opm { GConSale(); bool has(const std::string& name) const; - const GCONSALEGroup& getGroup(const std::string& name) const; - MaxProcedure stringToProcedure(const std::string& procedure); - void add_group(const std::string& name, const UDAValue& sales_target, const UDAValue& max_rate, const UDAValue& min_rate, const std::string& procedure); + const GCONSALEGroup& get(const std::string& name) const; + static MaxProcedure stringToProcedure(const std::string& procedure); + void add(const std::string& name, const UDAValue& sales_target, const UDAValue& max_rate, const UDAValue& min_rate, const std::string& procedure); size_t size() const; private: diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp index 918ed48c9..f16be4265 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp @@ -30,7 +30,7 @@ bool GConSale::has(const std::string& name) const { return (groups.find(name) != groups.end()); } -const GConSale::GCONSALEGroup& GConSale::getGroup(const std::string& name) const { +const GConSale::GCONSALEGroup& GConSale::get(const std::string& name) const { auto it = groups.find(name); if (it == groups.end()) @@ -55,7 +55,7 @@ GConSale::MaxProcedure GConSale::stringToProcedure(const std::string& str_proc) return MaxProcedure::NONE; } -void GConSale::add_group(const std::string& name, const UDAValue& sales_target, const UDAValue& max_rate, const UDAValue& min_rate, const std::string& procedure) { +void GConSale::add(const std::string& name, const UDAValue& sales_target, const UDAValue& max_rate, const UDAValue& min_rate, const std::string& procedure) { groups[name] = GCONSALEGroup(); GConSale::GCONSALEGroup& group = groups[name]; group.sales_target = sales_target; diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index c73b1a142..f58c27f6d 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -1609,7 +1609,7 @@ namespace { std::cout << "SALES TARGET = " << sales_target.get() << std::endl; std::string procedure = record.getItem("MAX_PROC").getTrimmedString(0); - new_gconsale->add_group(groupName, sales_target, max_rate, min_rate, procedure); + new_gconsale->add(groupName, sales_target, max_rate, min_rate, procedure); } this->gconsale.update(currentStep, new_gconsale); diff --git a/tests/parser/GroupTests.cpp b/tests/parser/GroupTests.cpp index ffba4ce9e..5f592f0d5 100644 --- a/tests/parser/GroupTests.cpp +++ b/tests/parser/GroupTests.cpp @@ -409,7 +409,7 @@ BOOST_AUTO_TEST_CASE(TESTGCONSALE) { BOOST_CHECK_EQUAL(gconsale.size(), 1); BOOST_CHECK(gconsale.has("G1")); BOOST_CHECK(!gconsale.has("G2")); - const GConSale::GCONSALEGroup& group = gconsale.getGroup("G1"); + const GConSale::GCONSALEGroup& group = gconsale.get("G1"); BOOST_CHECK_EQUAL(group.sales_target.get(), 50000 * metric_to_si); BOOST_CHECK_EQUAL(group.max_sales_rate.get(), 55000 * metric_to_si); BOOST_CHECK_EQUAL(group.min_sales_rate.get(), 45000 * metric_to_si);