From 064559b9e4d0edda0858a50a05df84fecd770c33 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Mon, 2 Nov 2020 16:11:35 +0100 Subject: [PATCH] Add UnitSystem member to Schedule class Mkae Section and KeywordIndex members in HandleContext optional. --- .../EclipseState/Schedule/Schedule.hpp | 31 +++++++---- .../EclipseState/Schedule/KeywordHandlers.cpp | 41 ++++++--------- .../EclipseState/Schedule/Schedule.cpp | 52 +++++++++++-------- 3 files changed, 69 insertions(+), 55 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index 4b8cf2ed0..692d4514e 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -106,7 +106,6 @@ namespace Opm class SCHEDULESection; class SummaryState; class TimeMap; - class UnitSystem; class ErrorGuard; class WListManager; class UDQConfig; @@ -334,6 +333,7 @@ namespace Opm reconstructDynMap(splitvfpprod.first, splitvfpprod.second, vfpprod_tables); reconstructDynMap(splitvfpinj.first, splitvfpinj.second, vfpinj_tables); } + unit_system.serializeOp(serializer); } private: @@ -364,13 +364,13 @@ namespace Opm RFTConfig rft_config; DynamicState m_nupcol; RestartConfig restart_config; + UnitSystem unit_system; std::optional exit_status; std::map wellgroup_events; void load_rst(const RestartIO::RstState& rst, const EclipseGrid& grid, - const FieldPropsManager& fp, - const UnitSystem& unit_system); + const FieldPropsManager& fp); void addWell(Well well, std::size_t report_step); void addWell(const std::string& wellName, const std::string& group, @@ -384,8 +384,7 @@ namespace Opm int pvt_table, Well::GasInflowEquation gas_inflow, std::size_t timeStep, - Connection::Order wellConnectionOrder, - const UnitSystem& unit_system); + Connection::Order wellConnectionOrder); DynamicState> rpt_config; void updateNetwork(std::shared_ptr network, std::size_t report_step); @@ -402,9 +401,9 @@ namespace Opm void addACTIONX(const Action::ActionX& action, std::size_t currentStep); void addGroupToGroup( const std::string& parent_group, const std::string& child_group, std::size_t timeStep); void addGroupToGroup( const std::string& parent_group, const Group& child_group, std::size_t timeStep); - void addGroup(const std::string& groupName , std::size_t timeStep, const UnitSystem& unit_system); + void addGroup(const std::string& groupName , std::size_t timeStep); void addGroup(const Group& group, std::size_t timeStep); - void addWell(const std::string& wellName, const DeckRecord& record, std::size_t timeStep, Connection::Order connection_order, const UnitSystem& unit_system); + void addWell(const std::string& wellName, const DeckRecord& record, std::size_t timeStep, Connection::Order connection_order); void checkUnhandledKeywords( const SCHEDULESection& ) const; void checkIfAllConnectionsIsShut(std::size_t currentStep); void updateUDQ(const DeckKeyword& keyword, std::size_t current_step); @@ -447,7 +446,7 @@ namespace Opm } static std::string formatDate(std::time_t t); - std::string simulationDays(const UnitSystem&, std::size_t currentStep) const; + std::string simulationDays(std::size_t currentStep) const; void applyEXIT(const DeckKeyword&, std::size_t currentStep); void applyMESSAGES(const DeckKeyword&, std::size_t currentStep); @@ -456,12 +455,24 @@ namespace Opm void applyWRFTPLT(const DeckKeyword&, std::size_t currentStep); struct HandlerContext { - const SCHEDULESection& section; const DeckKeyword& keyword; - const std::size_t keywordIndex; const std::size_t currentStep; const EclipseGrid& grid; const FieldPropsManager& fieldPropsManager; + const SCHEDULESection * section = nullptr; + std::optional keywordIndex; + + HandlerContext(const DeckKeyword& keyword_, + const std::size_t currentStep_, + const EclipseGrid& grid_, + const FieldPropsManager& fieldPropsManager_) : + keyword(keyword_), + currentStep(currentStep_), + grid(grid_), + fieldPropsManager(fieldPropsManager_) + {} + + }; /** diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp index e3b8f6c06..1babaef98 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp @@ -383,7 +383,7 @@ namespace { { auto group_ptr = std::make_shared(this->getGroup(group_name, handlerContext.currentStep)); - Group::GroupProductionProperties production(handlerContext.section.unitSystem(), group_name); + Group::GroupProductionProperties production(this->unit_system, group_name); production.gconprod_cmode = controlMode; production.active_cmode = controlMode; production.oil_target = oil_target; @@ -439,7 +439,6 @@ namespace { } void Schedule::handleGCONSALE(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) { - const auto& unit_system = handlerContext.section.unitSystem(); const auto& current = *this->gconsale.get(handlerContext.currentStep); std::shared_ptr new_gconsale(new GConSale(current)); for (const auto& record : handlerContext.keyword) { @@ -450,7 +449,7 @@ namespace { std::string procedure = record.getItem("MAX_PROC").getTrimmedString(0); auto udqconfig = this->getUDQConfig(handlerContext.currentStep).params().undefinedValue(); - new_gconsale->add(groupName, sales_target, max_rate, min_rate, procedure, udqconfig, unit_system); + new_gconsale->add(groupName, sales_target, max_rate, min_rate, procedure, udqconfig, this->unit_system); auto group_ptr = std::make_shared(this->getGroup(groupName, handlerContext.currentStep)); Group::GroupInjectionProperties injection; @@ -463,7 +462,6 @@ namespace { } void Schedule::handleGCONSUMP(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) { - const auto& unit_system = handlerContext.section.unitSystem(); const auto& current = *this->gconsump.get(handlerContext.currentStep); std::shared_ptr new_gconsump(new GConSump(current)); for (const auto& record : handlerContext.keyword) { @@ -478,7 +476,7 @@ namespace { auto udqconfig = this->getUDQConfig(handlerContext.currentStep).params().undefinedValue(); - new_gconsump->add(groupName, consumption_rate, import_rate, network_node_name, udqconfig, unit_system); + new_gconsump->add(groupName, consumption_rate, import_rate, network_node_name, udqconfig, this->unit_system); } this->gconsump.update(handlerContext.currentStep, new_gconsump); } @@ -555,12 +553,11 @@ namespace { } void Schedule::handleGRUPNET(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) { - const auto& unit_system = handlerContext.section.unitSystem(); for (const auto& record : handlerContext.keyword) { const auto& groupName = record.getItem("NAME").getTrimmedString(0); if (!hasGroup(groupName)) - addGroup(groupName , handlerContext.currentStep, unit_system); + addGroup(groupName , handlerContext.currentStep); int table = record.getItem("VFP_TABLE").get< int >(0); @@ -571,16 +568,15 @@ namespace { } void Schedule::handleGRUPTREE(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) { - const auto& unit_system = handlerContext.section.unitSystem(); for (const auto& record : handlerContext.keyword) { const std::string& childName = trim_wgname(handlerContext.keyword, record.getItem("CHILD_GROUP").get(0), parseContext, errors); const std::string& parentName = trim_wgname(handlerContext.keyword, record.getItem("PARENT_GROUP").get(0), parseContext, errors); if (!hasGroup(childName)) - addGroup(childName, handlerContext.currentStep, unit_system); + addGroup(childName, handlerContext.currentStep); if (!hasGroup(parentName)) - addGroup(parentName, handlerContext.currentStep, unit_system); + addGroup(parentName, handlerContext.currentStep); this->addGroupToGroup(parentName, childName, handlerContext.currentStep); } @@ -803,7 +799,7 @@ namespace { } void Schedule::handleVFPINJ(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) { - std::shared_ptr table = std::make_shared(handlerContext.keyword, handlerContext.section.unitSystem()); + std::shared_ptr table = std::make_shared(handlerContext.keyword, this->unit_system); int table_id = table->getTableNum(); if (vfpinj_tables.find(table_id) == vfpinj_tables.end()) { @@ -817,7 +813,7 @@ namespace { } void Schedule::handleVFPPROD(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) { - std::shared_ptr table = std::make_shared(handlerContext.keyword, handlerContext.section.unitSystem()); + std::shared_ptr table = std::make_shared(handlerContext.keyword, this->unit_system); int table_id = table->getTableNum(); if (vfpprod_tables.find(table_id) == vfpprod_tables.end()) { @@ -831,7 +827,6 @@ namespace { } void Schedule::handleWCONHIST(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) { - const auto& unit_system = handlerContext.section.unitSystem(); for (const auto& record : handlerContext.keyword) { const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0); const auto well_names = this->wellNames(wellNamePattern, handlerContext.currentStep); @@ -853,7 +848,7 @@ namespace { if (table_nr != 0) alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType(); - properties->handleWCONHIST(alq_type, unit_system, record); + properties->handleWCONHIST(alq_type, this->unit_system, record); if (switching_from_injector) { properties->resetDefaultBHPLimit(); @@ -898,7 +893,6 @@ namespace { } void Schedule::handleWCONPROD(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) { - const auto& unit_system = handlerContext.section.unitSystem(); for (const auto& record : handlerContext.keyword) { const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0); const auto well_names = this->wellNames(wellNamePattern, handlerContext.currentStep); @@ -922,7 +916,7 @@ namespace { if (table_nr != 0) alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType(); - properties->handleWCONPROD(alq_type, unit_system, well_name, record); + properties->handleWCONPROD(alq_type, this->unit_system, well_name, record); if (switching_from_injector) properties->resetDefaultBHPLimit(); @@ -1148,20 +1142,19 @@ namespace { } void Schedule::handleWELSPECS(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) { - const auto& section = handlerContext.section; - const auto& unit_system = section.unitSystem(); const auto COMPORD_in_timestep = [&]() -> const DeckKeyword* { - auto itr = section.begin() + handlerContext.keywordIndex; + const auto& section = *handlerContext.section; + auto itr = section.begin() + handlerContext.keywordIndex.value(); for( ; itr != section.end(); ++itr ) { if (itr->name() == "DATES") return nullptr; if (itr->name() == "TSTEP") return nullptr; if (itr->name() == "COMPORD") return std::addressof( *itr ); } - return nullptr; }; - const auto& keyword = section.getKeyword(handlerContext.keywordIndex); + + const auto& keyword = handlerContext.keyword; for (std::size_t recordNr = 0; recordNr < keyword.size(); recordNr++) { const auto& record = keyword.getRecord(recordNr); const std::string& wellName = trim_wgname(keyword, record.getItem().get(0), parseContext, errors); @@ -1182,7 +1175,7 @@ namespace { } if (!hasGroup(groupName)) - addGroup(groupName, handlerContext.currentStep, unit_system); + addGroup(groupName, handlerContext.currentStep); if (!hasWell(wellName)) { auto wellConnectionOrder = Connection::Order::TRACK; @@ -1200,7 +1193,7 @@ namespace { } } } - this->addWell(wellName, record, handlerContext.currentStep, wellConnectionOrder, unit_system); + this->addWell(wellName, record, handlerContext.currentStep, wellConnectionOrder); this->addWellToGroup(groupName, wellName, handlerContext.currentStep); } else { const auto headI = record.getItem().get(0) - 1; @@ -1248,7 +1241,7 @@ namespace { rates will be wrong. */ void Schedule::handleWELTARG(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) { - const double SiFactorP = handlerContext.section.unitSystem().parse("Pressure").getSIScaling(); + const double SiFactorP = this->unit_system.parse("Pressure").getSIScaling(); for (const auto& record : handlerContext.keyword) { const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0); const auto well_names = wellNames(wellNamePattern, handlerContext.currentStep); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index c5228f4f2..c15496db8 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -130,11 +130,12 @@ namespace { rft_config(this->m_timeMap), m_nupcol(this->m_timeMap, runspec.nupcol()), restart_config(m_timeMap, deck, parseContext, errors), + unit_system(deck.getActiveUnitSystem()), rpt_config(this->m_timeMap, std::make_shared()) { - addGroup( "FIELD", 0, deck.getActiveUnitSystem()); + addGroup( "FIELD", 0); if (rst) - this->load_rst(*rst, grid, fp, deck.getActiveUnitSystem()); + this->load_rst(*rst, grid, fp); /* We can have the MESSAGES keyword anywhere in the deck, we @@ -261,6 +262,7 @@ namespace { result.m_nupcol = {{1}, 1}; result.restart_config = RestartConfig::serializeObject(); result.wellgroup_events = {{"test", Events::serializeObject()}}; + result.unit_system = UnitSystem::newFIELD(); return result; } @@ -290,7 +292,18 @@ namespace { const FieldPropsManager& fp, std::vector >& rftProperties) { - const HandlerContext handlerContext { section, keyword, keywordIdx, currentStep, grid, fp }; + HandlerContext handlerContext { keyword, currentStep, grid, fp }; + + /* + The WELSPECS handler needs to look in the same report step for a + COMPORD keyword. This keyword-keyword interaction is quite ugly, so in + this case it is made very explicit - hopefully it can be refactored in + the future. + */ + if (keyword.name() == "WELSPECS") { + handlerContext.section = §ion; + handlerContext.keywordIndex = keywordIdx; + } if (handleNormalKeyword(handlerContext, parseContext, errors)) return; @@ -353,9 +366,8 @@ private: const FieldPropsManager& fp) { std::vector > rftProperties; - const auto& unit_system = section.unitSystem(); - std::string time_unit = unit_system.name(UnitSystem::measure::time); - auto convert_time = [&unit_system](double seconds) { return unit_system.from_si(UnitSystem::measure::time, seconds); }; + std::string time_unit = this->unit_system.name(UnitSystem::measure::time); + auto convert_time = [this](double seconds) { return this->unit_system.from_si(UnitSystem::measure::time, seconds); }; std::size_t keywordIdx = 0; std::string current_file; const auto& time_map = this->m_timeMap; @@ -778,8 +790,7 @@ private: void Schedule::addWell(const std::string& wellName, const DeckRecord& record, std::size_t timeStep, - Connection::Order wellConnectionOrder, - const UnitSystem& unit_system) + Connection::Order wellConnectionOrder) { // We change from eclipse's 1 - n, to a 0 - n-1 solution int headI = record.getItem("HEAD_I").get< int >(0) - 1; @@ -832,8 +843,7 @@ private: pvt_table, gas_inflow, timeStep, - wellConnectionOrder, - unit_system); + wellConnectionOrder); } void Schedule::addWell(Well well, std::size_t report_step) { @@ -861,8 +871,7 @@ private: int pvt_table, Well::GasInflowEquation gas_inflow, std::size_t timeStep, - Connection::Order wellConnectionOrder, - const UnitSystem& unit_system) { + Connection::Order wellConnectionOrder) { Well well(wellName, group, @@ -873,7 +882,7 @@ private: WellType(preferredPhase), this->global_whistctl_mode[timeStep], wellConnectionOrder, - unit_system, + this->unit_system, this->getUDQConfig(timeStep).params().undefinedValue(), drainageRadius, allowCrossFlow, @@ -1213,10 +1222,10 @@ private: } - void Schedule::addGroup(const std::string& groupName, std::size_t timeStep, const UnitSystem& unit_system) { + void Schedule::addGroup(const std::string& groupName, std::size_t timeStep) { const std::size_t insert_index = this->groups.size(); auto udq_undefined = this->getUDQConfig(timeStep).params().undefinedValue(); - auto group = Group{ groupName, insert_index, timeStep, udq_undefined, unit_system }; + auto group = Group{ groupName, insert_index, timeStep, udq_undefined, this->unit_system }; this->addGroup(group, timeStep); } @@ -1608,6 +1617,7 @@ private: rft_config == data.rft_config && this->m_nupcol == data.m_nupcol && this->restart_config == data.restart_config && + this->unit_system == data.unit_system && this->wellgroup_events == data.wellgroup_events; } @@ -1617,9 +1627,9 @@ private: return fmt::format("{:04d}-{:02d}-{:02d}" , ts.year(), ts.month(), ts.day()); } - std::string Schedule::simulationDays(const UnitSystem& unit_system, std::size_t currentStep) const { - const double sim_time { unit_system.from_si(UnitSystem::measure::time, simTime(currentStep)) } ; - return fmt::format("{} {}", sim_time, unit_system.name(UnitSystem::measure::time)); + std::string Schedule::simulationDays(std::size_t currentStep) const { + const double sim_time { this->unit_system.from_si(UnitSystem::measure::time, simTime(currentStep)) } ; + return fmt::format("{} {}", sim_time, this->unit_system.name(UnitSystem::measure::time)); } namespace { @@ -1639,13 +1649,13 @@ namespace { } } - void Schedule::load_rst(const RestartIO::RstState& rst_state, const EclipseGrid& grid, const FieldPropsManager& fp, const UnitSystem& unit_system) + void Schedule::load_rst(const RestartIO::RstState& rst_state, const EclipseGrid& grid, const FieldPropsManager& fp) { double udq_undefined = 0; const auto report_step = rst_state.header.report_step - 1; for (const auto& rst_group : rst_state.groups) { - auto group = Group{ rst_group, this->groups.size(), static_cast(report_step), udq_undefined, unit_system }; + auto group = Group{ rst_group, this->groups.size(), static_cast(report_step), udq_undefined, this->unit_system }; this->addGroup(group, report_step); if (group.isProductionGroup()) { @@ -1673,7 +1683,7 @@ namespace { } for (const auto& rst_well : rst_state.wells) { - Opm::Well well(rst_well, report_step, unit_system, udq_undefined); + Opm::Well well(rst_well, report_step, this->unit_system, udq_undefined); std::vector rst_connections; for (const auto& rst_conn : rst_well.connections)