Merge pull request #2900 from joakim-hove/handlercontext-refactor

Refactor Schedule handlerContext usage
This commit is contained in:
Joakim Hove 2021-12-13 18:18:00 +01:00 committed by GitHub
commit fb1e9d5d7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 380 additions and 428 deletions

View File

@ -52,6 +52,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/RPTConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/SimulatorUpdate.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Python/Python.hpp>
@ -266,8 +267,6 @@ namespace Opm
GTNode groupTree(const std::string& root_node, std::size_t report_step) const;
const Group& getGroup(const std::string& groupName, std::size_t timeStep) const;
void invalidNamePattern (const std::string& namePattern, std::size_t report_step, const ParseContext& parseContext, ErrorGuard& errors, const DeckKeyword& keyword) const;
std::optional<std::size_t> first_RFT() const;
/*
Will remove all completions which are connected to cell which is not
@ -475,6 +474,47 @@ namespace Opm
void dump_deck(std::ostream& os) const;
private:
struct HandlerContext {
const ScheduleBlock& block;
const DeckKeyword& keyword;
const std::size_t currentStep;
const std::vector<std::string>& matching_wells;
const bool actionx_mode;
const ParseContext& parseContext;
ErrorGuard& errors;
SimulatorUpdate * sim_update;
const std::unordered_map<std::string, double> * target_wellpi;
const ScheduleGrid& grid;
HandlerContext(const ScheduleBlock& block_,
const DeckKeyword& keyword_,
const ScheduleGrid& grid_,
const std::size_t currentStep_,
const std::vector<std::string>& matching_wells_,
bool actionx_mode_,
const ParseContext& parseContext_,
ErrorGuard& errors_,
SimulatorUpdate * sim_update_,
const std::unordered_map<std::string, double> * target_wellpi_)
: block(block_)
, keyword(keyword_)
, currentStep(currentStep_)
, matching_wells(matching_wells_)
, actionx_mode(actionx_mode_)
, parseContext(parseContext_)
, errors(errors_)
, sim_update(sim_update_)
, target_wellpi(target_wellpi_)
, grid(grid_)
{}
void affected_well(const std::string& well_name) {
if (this->sim_update)
this->sim_update->affected_wells.insert(well_name);
}
};
ScheduleStatic m_static;
ScheduleDeck m_sched_deck;
std::optional<int> exit_status;
@ -533,48 +573,15 @@ namespace Opm
const std::unordered_map<std::string, double> * target_wellpi);
void prefetch_cell_properties(const ScheduleGrid& grid, const DeckKeyword& keyword);
std::vector<std::string> wellNames(const std::string& pattern, const HandlerContext& context);
std::vector<std::string> wellNames(const std::string& pattern, std::size_t timeStep, const std::vector<std::string>& matching_wells, InputError::Action error_action, ErrorGuard& errors, const KeywordLocation& location) const;
void invalidNamePattern( const std::string& namePattern, const HandlerContext& context) const;
static std::string formatDate(std::time_t t);
std::string simulationDays(std::size_t currentStep) const;
bool must_write_rst_file(std::size_t report_step) const;
void applyEXIT(const DeckKeyword&, std::size_t currentStep);
void applyWELOPEN(const DeckKeyword&, std::size_t currentStep, const ParseContext&, ErrorGuard&, const std::vector<std::string>& matching_wells = {}, SimulatorUpdate * sim_update = nullptr);
struct HandlerContext {
const ScheduleBlock& block;
const DeckKeyword& keyword;
const std::size_t currentStep;
const std::vector<std::string>& matching_wells;
const bool actionx_mode;
SimulatorUpdate * sim_update;
const std::unordered_map<std::string, double> * target_wellpi;
const ScheduleGrid& grid;
HandlerContext(const ScheduleBlock& block_,
const DeckKeyword& keyword_,
const ScheduleGrid& grid_,
const std::size_t currentStep_,
const std::vector<std::string>& matching_wells_,
bool actionx_mode_,
SimulatorUpdate * sim_update_,
const std::unordered_map<std::string, double> * target_wellpi_)
: block(block_)
, keyword(keyword_)
, currentStep(currentStep_)
, matching_wells(matching_wells_)
, actionx_mode(actionx_mode_)
, sim_update(sim_update_)
, target_wellpi(target_wellpi_)
, grid(grid_)
{}
void affected_well(const std::string& well_name) {
if (this->sim_update)
this->sim_update->affected_wells.insert(well_name);
}
};
/**
* Handles a "normal" keyword. A normal keyword is one that can be handled by a function with the standard set of arguments (the ones that are passed to this function).
@ -591,95 +598,92 @@ namespace Opm
*
* @return `true` if the keyword was handled
*/
bool handleNormalKeyword(HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors);
bool handleNormalKeyword(HandlerContext& handlerContext);
// Keyword Handlers
void handlePYACTION(const DeckKeyword&);
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, const std::vector<std::string>& matching_wells = {});
void handleWELPIRuntime(HandlerContext&);
// Normal keyword handlers -- in KeywordHandlers.cpp
void handleBRANPROP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPDAT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPLUMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPORD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPSEGS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDTCON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDTR (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRVDT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRVDTR (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleEXIT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONINJE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONSALE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONSUMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGEFAC (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGEOKeyword(HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGPMAINT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGRUPNET (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGRUPTREE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGUIDERAT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleLINCOM (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMESSAGES (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMXUNSUPP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNETBALAN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNEXTSTEP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNODEPROP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNUPCOL (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLY (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLYO (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTRST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTSCHED (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleTUNING (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleSAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleSUMTHIN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleUDQ (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVAPPARS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVFPINJ (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVFPPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONHIST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONINJE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONINJH (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWECON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWEFAC (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELOPEN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELPI (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELSEGS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELSPECS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELTARG (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWFOAM (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWGRUPCON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWHISTCTL (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWINJTEMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWLIST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWMICP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPAVEDEP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWWPAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPIMULT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPMITAB (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPOLYMER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWRFT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWRFTPLT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSALT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGITER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGSICD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGAICD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGVALV (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSKPTAB (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSOLVENT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTEMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTEST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTMULT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTRACER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleBRANPROP (HandlerContext&);
void handleCOMPDAT (HandlerContext&);
void handleCOMPLUMP (HandlerContext&);
void handleCOMPORD (HandlerContext&);
void handleCOMPSEGS (HandlerContext&);
void handleDRSDT (HandlerContext&);
void handleDRSDTCON (HandlerContext&);
void handleDRSDTR (HandlerContext&);
void handleDRVDT (HandlerContext&);
void handleDRVDTR (HandlerContext&);
void handleEXIT (HandlerContext&);
void handleGCONINJE (HandlerContext&);
void handleGCONPROD (HandlerContext&);
void handleGCONSALE (HandlerContext&);
void handleGCONSUMP (HandlerContext&);
void handleGEFAC (HandlerContext&);
void handleGEOKeyword(HandlerContext&);
void handleGLIFTOPT (HandlerContext&);
void handleGPMAINT (HandlerContext&);
void handleGRUPNET (HandlerContext&);
void handleGRUPTREE (HandlerContext&);
void handleGUIDERAT (HandlerContext&);
void handleLIFTOPT (HandlerContext&);
void handleLINCOM (HandlerContext&);
void handleMESSAGES (HandlerContext&);
void handleMXUNSUPP (HandlerContext&);
void handleNETBALAN (HandlerContext&);
void handleNEXTSTEP (HandlerContext&);
void handleNODEPROP (HandlerContext&);
void handleNUPCOL (HandlerContext&);
void handleRPTONLY (HandlerContext&);
void handleRPTONLYO (HandlerContext&);
void handleRPTRST (HandlerContext&);
void handleRPTSCHED (HandlerContext&);
void handleTUNING (HandlerContext&);
void handleSAVE (HandlerContext&);
void handleSUMTHIN (HandlerContext&);
void handleUDQ (HandlerContext&);
void handleVAPPARS (HandlerContext&);
void handleVFPINJ (HandlerContext&);
void handleVFPPROD (HandlerContext&);
void handleWCONHIST (HandlerContext&);
void handleWCONINJE (HandlerContext&);
void handleWCONINJH (HandlerContext&);
void handleWCONPROD (HandlerContext&);
void handleWECON (HandlerContext&);
void handleWEFAC (HandlerContext&);
void handleWELOPEN (HandlerContext&);
void handleWELPI (HandlerContext&);
void handleWELSEGS (HandlerContext&);
void handleWELSPECS (HandlerContext&);
void handleWELTARG (HandlerContext&);
void handleWFOAM (HandlerContext&);
void handleWGRUPCON (HandlerContext&);
void handleWHISTCTL (HandlerContext&);
void handleWINJTEMP (HandlerContext&);
void handleWLIFTOPT (HandlerContext&);
void handleWLIST (HandlerContext&);
void handleWMICP (HandlerContext&);
void handleWPAVE (HandlerContext&);
void handleWPAVEDEP (HandlerContext&);
void handleWWPAVE (HandlerContext&);
void handleWPIMULT (HandlerContext&);
void handleWPMITAB (HandlerContext&);
void handleWPOLYMER (HandlerContext&);
void handleWRFT (HandlerContext&);
void handleWRFTPLT (HandlerContext&);
void handleWSALT (HandlerContext&);
void handleWSEGITER (HandlerContext&);
void handleWSEGSICD (HandlerContext&);
void handleWSEGAICD (HandlerContext&);
void handleWSEGVALV (HandlerContext&);
void handleWSKPTAB (HandlerContext&);
void handleWSOLVENT (HandlerContext&);
void handleWTEMP (HandlerContext&);
void handleWTEST (HandlerContext&);
void handleWTMULT (HandlerContext&);
void handleWTRACER (HandlerContext&);
};
}

View File

@ -319,12 +319,12 @@ Schedule::Schedule(const Deck& deck, const EclipseState& es, const std::optional
};
HandlerContext handlerContext { block, keyword, grid, currentStep, matching_wells, actionx_mode, sim_update, target_wellpi};
HandlerContext handlerContext { block, keyword, grid, currentStep, matching_wells, actionx_mode, parseContext, errors, sim_update, target_wellpi};
/*
The grid and fieldProps members create problems for reiterating the
Schedule section. We therefor single them out very clearly here.
*/
if (handleNormalKeyword(handlerContext, parseContext, errors))
if (handleNormalKeyword(handlerContext))
return;
if (keyword.is<ParserKeywords::PYACTION>())
@ -679,83 +679,6 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e
void Schedule::applyWELOPEN(const DeckKeyword& keyword,
std::size_t currentStep,
const ParseContext& parseContext,
ErrorGuard& errors,
const std::vector<std::string>& matching_wells,
SimulatorUpdate * sim_update) {
auto conn_defaulted = []( const DeckRecord& rec ) {
auto defaulted = []( const DeckItem& item ) {
return item.defaultApplied( 0 );
};
return std::all_of( rec.begin() + 2, rec.end(), defaulted );
};
constexpr auto open = Well::Status::OPEN;
for (const auto& record : keyword) {
const auto& wellNamePattern = record.getItem( "WELL" ).getTrimmedString(0);
const auto& status_str = record.getItem( "STATUS" ).getTrimmedString( 0 );
const auto well_names = this->wellNames(wellNamePattern, currentStep, matching_wells);
if (well_names.empty())
invalidNamePattern( wellNamePattern, currentStep, parseContext, errors, keyword);
/* if all records are defaulted or just the status is set, only
* well status is updated
*/
if (conn_defaulted( record )) {
const auto well_status = Well::StatusFromString( status_str );
for (const auto& wname : well_names) {
{
const auto& well = this->getWell(wname, currentStep);
if( well_status == open && !well.canOpen() ) {
auto elapsed = this->snapshots[currentStep].start_time() - this->snapshots[0].start_time();
auto days = std::chrono::duration_cast<std::chrono::hours>(elapsed).count() / 24;
std::string msg = "Well " + wname
+ " where crossflow is banned has zero total rate."
+ " This well is prevented from opening at "
+ std::to_string( days ) + " days";
OpmLog::note(msg);
} else {
this->updateWellStatus( wname, currentStep, well_status);
if (sim_update)
sim_update->affected_wells.insert(wname);
}
}
}
continue;
}
/*
Some of the connection information has been entered, in this case
we *only* update the status of the connections, and not the well
itself. Unless all connections are shut - then the well is also
shut.
*/
for (const auto& wname : well_names) {
{
auto well = this->snapshots[currentStep].wells.get(wname);
this->snapshots[currentStep].wells.update( std::move(well) );
}
const auto connection_status = Connection::StateFromString( status_str );
{
auto well = this->snapshots[currentStep].wells.get(wname);
well.handleWELOPENConnections(record, connection_status);
this->snapshots[currentStep].wells.update( std::move(well) );
}
if (sim_update)
sim_update->affected_wells.insert(wname);
this->snapshots.back().events().addEvent( ScheduleEvents::COMPLETION_CHANGE);
}
}
}
std::optional<std::size_t> Schedule::first_RFT() const {
for (std::size_t report_step = 0; report_step < this->snapshots.size(); report_step++) {
@ -765,10 +688,9 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e
return {};
}
void Schedule::invalidNamePattern( const std::string& namePattern, std::size_t, const ParseContext& parseContext, ErrorGuard& errors, const DeckKeyword& keyword ) const {
void Schedule::invalidNamePattern( const std::string& namePattern, const HandlerContext& context) const {
std::string msg_fmt = fmt::format("No wells/groups match the pattern: \'{}\'", namePattern);
parseContext.handleError( ParseContext::SCHEDULE_INVALID_NAME, msg_fmt, keyword.location(), errors );
context.parseContext.handleError(ParseContext::SCHEDULE_INVALID_NAME, msg_fmt, context.keyword.location(), context.errors);
}
GTNode Schedule::groupTree(const std::string& root_node, std::size_t report_step, std::size_t level, const std::optional<std::string>& parent_name) const {
@ -1060,6 +982,17 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e
}
std::vector<std::string> Schedule::wellNames(const std::string& pattern, const HandlerContext& context) {
std::vector<std::string> valid_names;
const auto& report_step = context.currentStep;
auto names = this->wellNames(pattern, report_step, context.matching_wells);
if (names.empty())
this->invalidNamePattern(pattern, context);
return names;
}
WellMatcher Schedule::wellMatcher(std::size_t report_step) const {
const ScheduleState * sched_state;