Merge pull request #2077 from joakim-hove/actionx-gliftopt
Actionx gliftopt
This commit is contained in:
commit
3a1f5bd654
@ -497,6 +497,7 @@ namespace Opm
|
||||
// Keyword Handlers
|
||||
void handlePYACTION (std::shared_ptr<const Python> python, const std::string& input_path, const DeckKeyword&, std::size_t currentStep);
|
||||
void handleGCONPROD(const DeckKeyword& keyword, std::size_t current_step, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
void handleGLIFTOPT(const DeckKeyword& keyword, std::size_t report_step, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
|
||||
// Normal keyword handlers -- in KeywordHandlers.cpp
|
||||
void handleBRANPROP (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
|
@ -33,7 +33,7 @@ namespace Action {
|
||||
|
||||
|
||||
bool ActionX::valid_keyword(const std::string& keyword) {
|
||||
static std::unordered_set<std::string> actionx_allowed_list = {"EXIT", "GCONPROD", "WELSPECS","WELOPEN", "UDQ"};
|
||||
static std::unordered_set<std::string> actionx_allowed_list = {"EXIT", "GCONPROD", "GLIFTOPT", "WELSPECS","WELOPEN", "UDQ"};
|
||||
return (actionx_allowed_list.find(keyword) != actionx_allowed_list.end());
|
||||
}
|
||||
|
||||
|
@ -505,14 +505,18 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleGLIFTOPT(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard&errors) {
|
||||
auto glo = std::make_shared<GasLiftOpt>( this->glo(handlerContext.currentStep) );
|
||||
void Schedule::handleGLIFTOPT(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
|
||||
this->handleGLIFTOPT(handlerContext.keyword, handlerContext.currentStep, parseContext, errors);
|
||||
}
|
||||
|
||||
for (const auto& record : handlerContext.keyword) {
|
||||
void Schedule::handleGLIFTOPT(const DeckKeyword& keyword, std::size_t report_step, const ParseContext& parseContext, ErrorGuard&errors) {
|
||||
auto glo = std::make_shared<GasLiftOpt>( this->glo(report_step) );
|
||||
|
||||
for (const auto& record : keyword) {
|
||||
const std::string& groupNamePattern = record.getItem<ParserKeywords::GLIFTOPT::GROUP_NAME>().getTrimmedString(0);
|
||||
const auto group_names = this->groupNames(groupNamePattern);
|
||||
if (group_names.empty())
|
||||
invalidNamePattern(groupNamePattern, handlerContext.currentStep, parseContext, errors, handlerContext.keyword);
|
||||
invalidNamePattern(groupNamePattern, report_step, parseContext, errors, keyword);
|
||||
|
||||
const auto& max_gas_item = record.getItem<ParserKeywords::GLIFTOPT::MAX_LIFT_GAS_SUPPLY>();
|
||||
const double max_lift_gas_value = max_gas_item.hasValue(0)
|
||||
@ -533,7 +537,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
this->m_glo.update(handlerContext.currentStep, std::move(glo));
|
||||
this->m_glo.update(report_step, std::move(glo));
|
||||
}
|
||||
|
||||
void Schedule::handleGPMAINT(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
|
||||
|
@ -1499,6 +1499,9 @@ private:
|
||||
|
||||
if (keyword.name() == "GCONPROD")
|
||||
this->handleGCONPROD(keyword, reportStep, parseContext, errors);
|
||||
|
||||
if (keyword.name() == "GLIFTOPT")
|
||||
this->handleGLIFTOPT(keyword, reportStep, parseContext, errors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
"sections": [
|
||||
"SCHEDULE"
|
||||
],
|
||||
"requires" : ["LIFTOPT"],
|
||||
"items": [
|
||||
{
|
||||
"name": "GROUP_NAME",
|
||||
|
@ -53,6 +53,17 @@
|
||||
using namespace Opm;
|
||||
|
||||
|
||||
Schedule make_schedule(const std::string& deck_string, const ParseContext& parseContext = {}) {
|
||||
ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
auto deck = parser.parseString(deck_string);
|
||||
EclipseGrid grid1(10,10,10);
|
||||
TableManager table ( deck );
|
||||
FieldPropsManager fp( deck, Phases{true, true, true}, grid1, table);
|
||||
auto python = std::make_shared<Python>();
|
||||
Runspec runspec (deck);
|
||||
return Schedule(deck, grid1, fp, runspec, parseContext, errors, python);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Create) {
|
||||
@ -128,27 +139,15 @@ ENDACTIO
|
||||
TSTEP
|
||||
10 /
|
||||
)"};
|
||||
auto python = std::make_shared<Python>();
|
||||
Opm::Parser parser;
|
||||
auto deck1 = parser.parseString(MISSING_END);
|
||||
auto deck2 = parser.parseString(WITH_WELSPECS);
|
||||
auto deck3 = parser.parseString(WITH_GRID);
|
||||
EclipseGrid grid1(10,10,10);
|
||||
TableManager table ( deck1 );
|
||||
FieldPropsManager fp( deck1, Phases{true, true, true}, grid1, table);
|
||||
Runspec runspec (deck1);
|
||||
BOOST_CHECK_THROW(make_schedule(MISSING_END), OpmInputError);
|
||||
|
||||
// The ACTIONX keyword has no matching 'ENDACTIO' -> exception
|
||||
BOOST_CHECK_THROW(Schedule(deck1, grid1, fp, runspec, python), OpmInputError);
|
||||
|
||||
Schedule sched(deck2, grid1, fp, runspec, python);
|
||||
Schedule sched = make_schedule(WITH_WELSPECS);
|
||||
BOOST_CHECK( !sched.hasWell("W1") );
|
||||
BOOST_CHECK( sched.hasWell("W2"));
|
||||
|
||||
// The deck3 contains the 'GRID' keyword in the ACTIONX block - that is not a whitelisted keyword.
|
||||
ParseContext parseContext( {{ParseContext::ACTIONX_ILLEGAL_KEYWORD, InputError::THROW_EXCEPTION}} );
|
||||
ErrorGuard errors;
|
||||
BOOST_CHECK_THROW(Schedule(deck3, grid1, fp, runspec, parseContext, errors, python), OpmInputError);
|
||||
BOOST_CHECK_THROW( make_schedule(WITH_GRID, parseContext), OpmInputError );
|
||||
}
|
||||
|
||||
|
||||
@ -964,16 +963,8 @@ TSTEP
|
||||
)"};
|
||||
|
||||
auto unit_system = UnitSystem::newMETRIC();
|
||||
Opm::Parser parser;
|
||||
auto deck = parser.parseString(deck_string);
|
||||
EclipseGrid grid1(10,10,10);
|
||||
TableManager table ( deck );
|
||||
FieldPropsManager fp( deck, Phases{true, true, true}, grid1, table);
|
||||
auto python = std::make_shared<Python>();
|
||||
const auto st = SummaryState{ std::chrono::system_clock::now() };
|
||||
|
||||
Runspec runspec (deck);
|
||||
Schedule sched(deck, grid1, fp, runspec, python);
|
||||
Schedule sched = make_schedule(deck_string);
|
||||
const auto& action1 = sched.actions(0).get("A");
|
||||
{
|
||||
const auto& group = sched.getGroup("G1", 0);
|
||||
@ -990,3 +981,62 @@ TSTEP
|
||||
BOOST_CHECK_CLOSE( prod.oil_target , unit_system.to_si(UnitSystem::measure::liquid_surface_rate, 200), 1e-5 );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GASLIFT_OPT_DECK) {
|
||||
const auto input = R"(-- Turns on gas lift optimization
|
||||
RUNSPEC
|
||||
LIFTOPT
|
||||
/
|
||||
|
||||
SCHEDULE
|
||||
|
||||
GRUPTREE
|
||||
'PROD' 'FIELD' /
|
||||
|
||||
'M5S' 'PLAT-A' /
|
||||
'M5N' 'PLAT-A' /
|
||||
|
||||
'C1' 'M5N' /
|
||||
'F1' 'M5N' /
|
||||
'B1' 'M5S' /
|
||||
'G1' 'M5S' /
|
||||
/
|
||||
|
||||
ACTIONX
|
||||
'A' /
|
||||
WWCT 'OPX' > 0.75 AND /
|
||||
FPR < 100 /
|
||||
/
|
||||
|
||||
GLIFTOPT
|
||||
'PLAT-A' 200000 / --
|
||||
/
|
||||
|
||||
ENDACTIO
|
||||
|
||||
TSTEP
|
||||
10 /
|
||||
|
||||
|
||||
)";
|
||||
|
||||
Opm::UnitSystem unitSystem = UnitSystem( UnitSystem::UnitType::UNIT_TYPE_METRIC );
|
||||
auto sched = make_schedule(input);
|
||||
const auto& action1 = sched.actions(0).get("A");
|
||||
{
|
||||
const auto& glo = sched.glo(0);
|
||||
BOOST_CHECK(!glo.has_group("PLAT-A"));
|
||||
}
|
||||
|
||||
Action::Result action_result(true);
|
||||
sched.applyAction(0, action1, action_result);
|
||||
|
||||
{
|
||||
const auto& glo = sched.glo(0);
|
||||
BOOST_CHECK(glo.has_group("PLAT-A"));
|
||||
const auto& plat_group = glo.group("PLAT-A");
|
||||
BOOST_CHECK_EQUAL( *plat_group.max_lift_gas(), unitSystem.to_si( UnitSystem::measure::gas_surface_rate, 200000));
|
||||
BOOST_CHECK(!plat_group.max_total_gas().has_value());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user