Merge pull request #1193 from stefoss23/gconsale

Adding keyword GCONSALE to Schedule.
This commit is contained in:
Joakim Hove 2019-11-04 15:02:19 +01:00 committed by GitHub
commit 8c6768cc89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 201 additions and 1 deletions

View File

@ -99,6 +99,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
@ -620,6 +621,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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef GCONSALE_H
#define GCONSALE_H
#include <map>
#include <string>
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& 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:
std::map<std::string, GCONSALEGroup> groups;
};
}
#endif

View File

@ -31,6 +31,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group2.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp>
#include <opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp>
@ -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<std::shared_ptr<UDQConfig>> udq_config;
DynamicState<std::shared_ptr<UDQActive>> udq_active;
DynamicState<std::shared_ptr<GuideRateConfig>> guide_rate_config;
DynamicState<std::shared_ptr<GConSale>> gconsale;
DynamicState<Well2::ProducerCMode> global_whistctl_mode;
DynamicState<std::shared_ptr<Action::Actions>> 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);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp>
namespace Opm {
GConSale::GConSale() {
}
bool GConSale::has(const std::string& name) const {
return (groups.find(name) != groups.end());
}
const GConSale::GCONSALEGroup& GConSale::get(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(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();
}
}

View File

@ -119,6 +119,7 @@ namespace {
m_messageLimits( this->m_timeMap ),
m_runspec( runspec ),
wtest_config(this->m_timeMap, std::make_shared<WellTestConfig>() ),
gconsale(this->m_timeMap, std::make_shared<GConSale>() ),
wlist_manager( this->m_timeMap, std::make_shared<WListManager>()),
udq_config(this->m_timeMap, std::make_shared<UDQConfig>(deck)),
udq_active(this->m_timeMap, std::make_shared<UDQActive>()),
@ -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);
@ -1603,6 +1607,24 @@ namespace {
}
}
void Schedule::handleGCONSALE( const DeckKeyword& keyword, size_t currentStep) {
const auto& current = *this->gconsale.get(currentStep);
std::shared_ptr<GConSale> 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<UDAValue>(0);
auto max_rate = record.getItem("MAX_SALES_RATE").get<UDAValue>(0);
auto min_rate = record.getItem("MIN_SALES_RATE").get<UDAValue>(0);
std::cout << "SALES TARGET = " << sales_target.get<double>() << std::endl;
std::string procedure = record.getItem("MAX_PROC").getTrimmedString(0);
new_gconsale->add(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);
@ -2576,6 +2598,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;

View File

@ -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"}
]}

View File

@ -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.get("G1");
BOOST_CHECK_EQUAL(group.sales_target.get<double>(), 50000 * metric_to_si);
BOOST_CHECK_EQUAL(group.max_sales_rate.get<double>(), 55000 * metric_to_si);
BOOST_CHECK_EQUAL(group.min_sales_rate.get<double>(), 45000 * metric_to_si);
BOOST_CHECK(group.max_proc == GConSale::MaxProcedure::WELL);
}