Merge pull request #2110 from joakim-hove/actionx-welpi

Actionx welpi
This commit is contained in:
Joakim Hove 2020-11-16 18:12:53 +01:00 committed by GitHub
commit c46488236a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 16 deletions

View File

@ -503,6 +503,7 @@ namespace Opm
void handleGCONPROD(const DeckKeyword& keyword, std::size_t current_step, const ParseContext& parseContext, ErrorGuard& errors);
void handleGCONINJE(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);
void handleWELPI (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&);

View File

@ -33,7 +33,7 @@ namespace Action {
bool ActionX::valid_keyword(const std::string& keyword) {
static std::unordered_set<std::string> actionx_allowed_list = {"EXIT", "GCONINJE", "GCONPROD", "GLIFTOPT", "WELSPECS","WELOPEN", "UDQ"};
static std::unordered_set<std::string> actionx_allowed_list = {"EXIT", "GCONINJE", "GCONPROD", "GLIFTOPT", "WELSPECS","WELOPEN", "WELPI", "UDQ"};
return (actionx_allowed_list.find(keyword) != actionx_allowed_list.end());
}

View File

@ -1101,10 +1101,14 @@ namespace {
}
void Schedule::handleWELOPEN (const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
return applyWELOPEN(handlerContext.keyword, handlerContext.currentStep, parseContext, errors);
this->applyWELOPEN(handlerContext.keyword, handlerContext.currentStep, parseContext, errors);
}
void Schedule::handleWELPI(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
this->handleWELPI(handlerContext.keyword, handlerContext.currentStep, parseContext, errors);
}
void Schedule::handleWELPI(const DeckKeyword& keyword, std::size_t report_step, const ParseContext& parseContext, ErrorGuard& errors) {
// Keyword structure
//
// WELPI
@ -1118,18 +1122,18 @@ namespace {
using WELL_NAME = ParserKeywords::WELPI::WELL_NAME;
using PI = ParserKeywords::WELPI::STEADY_STATE_PRODUCTIVITY_OR_INJECTIVITY_INDEX_VALUE;
for (const auto& record : handlerContext.keyword) {
for (const auto& record : keyword) {
const auto well_names = this->wellNames(record.getItem<WELL_NAME>().getTrimmedString(0),
handlerContext.currentStep);
report_step);
if (well_names.empty())
this->invalidNamePattern(record.getItem<WELL_NAME>().getTrimmedString(0),
handlerContext.currentStep, parseContext,
errors, handlerContext.keyword);
report_step, parseContext,
errors, keyword);
const auto rawProdIndex = record.getItem<PI>().get<double>(0);
for (const auto& well_name : well_names) {
auto well2 = std::make_shared<Well>(this->getWell(well_name, handlerContext.currentStep));
auto well2 = std::make_shared<Well>(this->getWell(well_name, report_step));
// Note: Need to ensure we have an independent copy of
// well's connections because
@ -1138,13 +1142,13 @@ namespace {
auto connections = std::make_shared<WellConnections>(well2->getConnections());
well2->forceUpdateConnections(std::move(connections));
if (well2->updateWellProductivityIndex(rawProdIndex))
this->updateWell(std::move(well2), handlerContext.currentStep);
this->updateWell(std::move(well2), report_step);
this->addWellGroupEvent(well_name, ScheduleEvents::WELL_PRODUCTIVITY_INDEX, handlerContext.currentStep);
this->addWellGroupEvent(well_name, ScheduleEvents::WELL_PRODUCTIVITY_INDEX, report_step);
}
}
this->m_events.addEvent(ScheduleEvents::WELL_PRODUCTIVITY_INDEX, handlerContext.currentStep);
this->m_events.addEvent(ScheduleEvents::WELL_PRODUCTIVITY_INDEX, report_step);
}
void Schedule::handleWELSEGS(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {

View File

@ -1506,15 +1506,9 @@ private:
if (!Action::ActionX::valid_keyword(keyword.name()))
throw std::invalid_argument("The keyword: " + keyword.name() + " can not be handled in the ACTION body");
if (keyword.name() == "WELOPEN")
this->applyWELOPEN(keyword, reportStep, parseContext, errors, result.wells());
if (keyword.name() == "EXIT")
this->applyEXIT(keyword, reportStep);
if (keyword.name() == "UDQ")
this->updateUDQ(keyword, reportStep);
if (keyword.name() == "GCONINJE")
this->handleGCONINJE(keyword, reportStep, parseContext, errors);
@ -1523,6 +1517,15 @@ private:
if (keyword.name() == "GLIFTOPT")
this->handleGLIFTOPT(keyword, reportStep, parseContext, errors);
if (keyword.name() == "UDQ")
this->updateUDQ(keyword, reportStep);
if (keyword.name() == "WELOPEN")
this->applyWELOPEN(keyword, reportStep, parseContext, errors, result.wells());
if (keyword.name() == "WELPI")
this->handleWELPI(keyword, reportStep, parseContext, errors);
}
}

View File

@ -1056,3 +1056,54 @@ TSTEP
}
}
BOOST_AUTO_TEST_CASE(Action_WELPI) {
const auto deck_string = std::string{ R"(
SCHEDULE
WELSPECS
'PROD1' 'G1' 1 1 10 'OIL' /
/
COMPDAT
'PROD1' 1 1 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 /
/
ACTIONX
'A' /
WWCT 'OPX' > 0.75 AND /
FPR < 100 /
/
WELPI
'PROD1' 1000 /
/
ENDACTIO
TSTEP
10 /
)"};
const auto st = SummaryState{ std::chrono::system_clock::now() };
Schedule sched = make_schedule(deck_string);
const auto& action1 = sched.actions(0).get("A");
{
const auto& well = sched.getWell("PROD1", 0);
BOOST_CHECK_EQUAL( well.getWellPIScalingFactor(1.0), 1.0);
}
Action::Result action_result(true);
sched.applyAction(0, action1, action_result);
{
auto unit_system = UnitSystem::newMETRIC();
const auto& well = sched.getWell("PROD1", 0);
const auto PI = unit_system.to_si(UnitSystem::measure::liquid_productivity_index, 1.0);
const auto scaling = well.getWellPIScalingFactor(PI);
BOOST_CHECK_CLOSE(scaling, 1000.0, 1.0e-10);
}
}