From e1d117c59f131f5b4d8d17ae5841db6688b7ce8c Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 22 Apr 2021 17:31:21 +0200 Subject: [PATCH] Extract group state and create WGState to manage well & group state --- CMakeLists_files.cmake | 2 + ebos/eclpeacemanwell.hh | 9 +- ebos/eclproblem.hh | 2 +- ebos/eclwellmanager.hh | 15 +- opm/simulators/wells/BlackoilWellModel.hpp | 47 +++--- .../wells/BlackoilWellModel_impl.hpp | 145 +++++++++--------- opm/simulators/wells/GroupState.hpp | 3 +- opm/simulators/wells/MultisegmentWell.hpp | 14 +- .../wells/MultisegmentWell_impl.hpp | 19 ++- opm/simulators/wells/StandardWell.hpp | 5 + opm/simulators/wells/StandardWell_impl.hpp | 22 ++- opm/simulators/wells/TargetCalculator.hpp | 13 +- opm/simulators/wells/WGState.cpp | 30 ++++ opm/simulators/wells/WGState.hpp | 43 ++++++ opm/simulators/wells/WellGroupHelpers.cpp | 136 ++++++++-------- opm/simulators/wells/WellGroupHelpers.hpp | 34 ++-- opm/simulators/wells/WellInterface.hpp | 24 ++- opm/simulators/wells/WellInterface_impl.hpp | 71 +++++---- .../wells/WellStateFullyImplicitBlackoil.hpp | 109 +------------ 19 files changed, 406 insertions(+), 337 deletions(-) create mode 100644 opm/simulators/wells/WGState.cpp create mode 100644 opm/simulators/wells/WGState.hpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 6b10c1d57..8d52a9465 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -41,6 +41,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/utils/gatherDeferredLogger.cpp opm/simulators/utils/ParallelRestart.cpp opm/simulators/wells/GroupState.cpp + opm/simulators/wells/WGState.cpp opm/simulators/wells/ParallelWellInfo.cpp opm/simulators/wells/VFPProdProperties.cpp opm/simulators/wells/VFPInjProperties.cpp @@ -256,6 +257,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/wells/WellConnectionAuxiliaryModule.hpp opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp opm/simulators/wells/GroupState.hpp + opm/simulators/wells/WGState.hpp opm/simulators/wells/VFPProperties.hpp opm/simulators/wells/VFPHelpers.hpp opm/simulators/wells/VFPInjProperties.hpp diff --git a/ebos/eclpeacemanwell.hh b/ebos/eclpeacemanwell.hh index 7248eb356..d4356f1e2 100644 --- a/ebos/eclpeacemanwell.hh +++ b/ebos/eclpeacemanwell.hh @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -1422,22 +1423,22 @@ protected: throw std::logic_error("wellState() method not implemented for class eclpeacemanwell"); } - void commitWellState() + void commitWGState() { throw std::logic_error("commitWellState() method not implemented for class eclpeacemanwell"); } - void commitWellState(WellStateFullyImplicitBlackoil well_state) + void commitWGState(WGState wgstate) { throw std::logic_error("commitWellState() method not implemented for class eclpeacemanwell"); } - void resetWellState() + void resetWGState() { throw std::logic_error("resetWellState() method not implemented for class eclpeacemanwell"); } - void updateNupcolWellState() + void updateNupcolWGState() { throw std::logic_error("updateNupcolWellState() method not implemented for class eclpeacemanwell"); } diff --git a/ebos/eclproblem.hh b/ebos/eclproblem.hh index 72ef82397..8a76218b6 100644 --- a/ebos/eclproblem.hh +++ b/ebos/eclproblem.hh @@ -1414,7 +1414,7 @@ public: the next timestep we must commit it. */ if (commit_wellstate) - this->wellModel_.commitWellState(); + this->wellModel_.commitWGState(); } diff --git a/ebos/eclwellmanager.hh b/ebos/eclwellmanager.hh index e02ba2547..86e8be0f7 100644 --- a/ebos/eclwellmanager.hh +++ b/ebos/eclwellmanager.hh @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -631,24 +632,24 @@ public: throw std::logic_error("wellState() method not implemented for class eclwellmanager"); } - void commitWellState() + void commitWGState() { throw std::logic_error("commitWellState() method not implemented for class eclwellmanager"); } - void commitWellState(WellStateFullyImplicitBlackoil well_state) + void commitWGState(WGState) { - throw std::logic_error("commitWellState() method not implemented for class eclwellmanager"); + throw std::logic_error("commitWGState() method not implemented for class eclwellmanager"); } - void resetWellState() + void resetWGState() { - throw std::logic_error("resetWellState() method not implemented for class eclwellmanager"); + throw std::logic_error("resetWGState() method not implemented for class eclwellmanager"); } - void updateNupcolWellState() + void updateNupcolWGState() { - throw std::logic_error("updateNupcolWellState() method not implemented for class eclwellmanager"); + throw std::logic_error("updateNupcolWGState() method not implemented for class eclwellmanager"); } void diff --git a/opm/simulators/wells/BlackoilWellModel.hpp b/opm/simulators/wells/BlackoilWellModel.hpp index 21321213b..a6fca2bfd 100644 --- a/opm/simulators/wells/BlackoilWellModel.hpp +++ b/opm/simulators/wells/BlackoilWellModel.hpp @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -254,7 +255,7 @@ namespace Opm { */ const WellStateFullyImplicitBlackoil& wellState() const { - return this->active_well_state_; + return this->active_wgstate_.well_state; } /* @@ -262,7 +263,7 @@ namespace Opm { */ WellStateFullyImplicitBlackoil& wellState() { - return this->active_well_state_; + return this->active_wgstate_.well_state; } /* @@ -274,16 +275,20 @@ namespace Opm { */ const WellStateFullyImplicitBlackoil& prevWellState() const { - return this->last_valid_well_state_; + return this->last_valid_wgstate_.well_state; } + const WGState& prevWGState() const + { + return this->last_valid_wgstate_; + } /* Will return the currently active nupcolWellState; must initialize the internal nupcol wellstate with initNupcolWellState() first. */ const WellStateFullyImplicitBlackoil& nupcolWellState() const { - return this->nupcol_well_state_; + return this->nupcol_wgstate_.well_state; } /* @@ -292,9 +297,9 @@ namespace Opm { with storeWellState() can then subsequently be recovered with the resetWellState() method. */ - void commitWellState() + void commitWGState() { - this->last_valid_well_state_ = this->active_well_state_; + this->last_valid_wgstate_ = this->active_wgstate_; } /* @@ -302,9 +307,9 @@ namespace Opm { last_valid_well_state_ member, that state can then be recovered with a subsequent call to resetWellState(). */ - void commitWellState(WellStateFullyImplicitBlackoil well_state) + void commitWGState(WGState wgstate) { - this->last_valid_well_state_ = std::move(well_state); + this->last_valid_wgstate_ = std::move(wgstate); } /* @@ -312,9 +317,9 @@ namespace Opm { was stored in the last_valid_well_state_ member. This function works in pair with commitWellState() which should be called first. */ - void resetWellState() + void resetWGState() { - this->active_well_state_ = this->last_valid_well_state_; + this->active_wgstate_ = this->last_valid_wgstate_; } /* @@ -322,9 +327,14 @@ namespace Opm { member. This can then be subsequently retrieved with accessor nupcolWellState(). */ - void updateNupcolWellState() + void updateNupcolWGState() { - this->nupcol_well_state_ = this->active_well_state_; + this->nupcol_wgstate_ = this->active_wgstate_; + } + + const GroupState& groupState() const + { + return this->active_wgstate_.group_state; } Opm::data::Wells wellData() const @@ -397,7 +407,6 @@ namespace Opm { void initPrimaryVariablesEvaluation() const; void updateWellControls(Opm::DeferredLogger& deferred_logger, const bool checkGroupControls); WellInterfacePtr getWell(const std::string& well_name) const; - protected: Simulator& ebosSimulator_; @@ -577,7 +586,7 @@ namespace Opm { const data::GroupAndNetworkValues& grpNwrkValues, const PhaseUsage& phases, const bool handle_ms_well, - WellStateFullyImplicitBlackoil& state ) const; + WellStateFullyImplicitBlackoil& state ); // whether there exists any multisegment well open on this process bool anyMSWellOpenLocal() const; @@ -589,7 +598,7 @@ namespace Opm { bool checkGroupConstraints(const Group& group, Opm::DeferredLogger& deferred_logger) const; Group::ProductionCMode checkGroupProductionConstraints(const Group& group, Opm::DeferredLogger& deferred_logger) const; Group::InjectionCMode checkGroupInjectionConstraints(const Group& group, const Phase& phase) const; - void checkGconsaleLimits(const Group& group, WellState& well_state, Opm::DeferredLogger& deferred_logger ) const; + void checkGconsaleLimits(const Group& group, WellState& well_state, Opm::DeferredLogger& deferred_logger ); void updateGroupHigherControls(Opm::DeferredLogger& deferred_logger, std::set& switched_groups); void checkGroupHigherConstraints(const Group& group, Opm::DeferredLogger& deferred_logger, std::set& switched_groups); @@ -632,6 +641,7 @@ namespace Opm { void computeWellTemperature(); private: + GroupState& groupState() { return this->active_wgstate_.group_state; } BlackoilWellModel(Simulator& ebosSimulator, const PhaseUsage& pu); /* The various wellState members should be accessed and modified @@ -639,9 +649,10 @@ namespace Opm { commitWellState(), resetWellState(), nupcolWellState() and updateNupcolWellState(). */ - WellState active_well_state_; - WellState last_valid_well_state_; - WellState nupcol_well_state_; + WGState active_wgstate_; + WGState last_valid_wgstate_; + WGState nupcol_wgstate_; + }; diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index f0c913966..e5e28ccda 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -35,9 +35,9 @@ namespace Opm { BlackoilWellModel(Simulator& ebosSimulator, const PhaseUsage& phase_usage) : ebosSimulator_(ebosSimulator), phase_usage_(phase_usage), - active_well_state_(phase_usage), - last_valid_well_state_(phase_usage), - nupcol_well_state_(phase_usage) + active_wgstate_(phase_usage), + last_valid_wgstate_(phase_usage), + nupcol_wgstate_(phase_usage) { terminal_output_ = false; if (ebosSimulator.gridView().comm().rank() == 0) @@ -279,7 +279,7 @@ namespace Opm { } const Group& fieldGroup = schedule().getGroup("FIELD", timeStepIdx); - WellGroupHelpers::setCmodeGroup(fieldGroup, schedule(), summaryState, timeStepIdx, this->wellState()); + WellGroupHelpers::setCmodeGroup(fieldGroup, schedule(), summaryState, timeStepIdx, this->wellState(), this->groupState()); // Compute reservoir volumes for RESV controls. rateConverter_.reset(new RateConverterType (phase_usage_, @@ -297,7 +297,7 @@ namespace Opm { } // Store the current well state, to be able to recover in the case of failed iterations - this->commitWellState(); + this->commitWGState(); } @@ -312,7 +312,7 @@ namespace Opm { Opm::DeferredLogger local_deferredLogger; - this->resetWellState(); + this->resetWGState(); updateAndCommunicateGroupData(); this->wellState().gliftTimeStepInit(); const int reportStepIdx = ebosSimulator_.episodeIndex(); @@ -400,8 +400,8 @@ namespace Opm { const auto& summaryState = ebosSimulator_.vanguard().summaryState(); std::vector pot(numPhases(), 0.0); const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx); - WellGroupHelpers::updateGuideRateForProductionGroups(fieldGroup, schedule(), phase_usage_, reportStepIdx, simulationTime, this->wellState(), comm, guideRate_.get(), pot); - WellGroupHelpers::updateGuideRatesForInjectionGroups(fieldGroup, schedule(), summaryState, phase_usage_, reportStepIdx, this->wellState(), guideRate_.get(), local_deferredLogger); + WellGroupHelpers::updateGuideRateForProductionGroups(fieldGroup, schedule(), phase_usage_, reportStepIdx, simulationTime, this->wellState(), this->groupState(), comm, guideRate_.get(), pot); + WellGroupHelpers::updateGuideRatesForInjectionGroups(fieldGroup, schedule(), summaryState, phase_usage_, reportStepIdx, this->wellState(), this->groupState(), guideRate_.get(), local_deferredLogger); WellGroupHelpers::updateGuideRatesForWells(schedule(), phase_usage_, reportStepIdx, simulationTime, this->wellState(), comm, guideRate_.get()); try { @@ -417,7 +417,7 @@ namespace Opm { if (event) { try { well->calculateExplicitQuantities(ebosSimulator_, this->wellState(), local_deferredLogger); - well->solveWellEquation(ebosSimulator_, this->wellState(), local_deferredLogger); + well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), local_deferredLogger); } catch (const std::exception& e) { const std::string msg = "Compute initial well solution for new well " + well->name() + " failed. Continue with zero initial rates"; local_deferredLogger.warning("WELL_INITIAL_SOLVE_FAILED", msg); @@ -491,7 +491,7 @@ namespace Opm { const WellTestConfig::Reason testing_reason = testWell.second; well->wellTesting(ebosSimulator_, simulationTime, timeStepIdx, - testing_reason, this->wellState(), wellTestState_, deferred_logger); + testing_reason, this->wellState(), this->groupState(), wellTestState_, deferred_logger); } } } @@ -566,7 +566,7 @@ namespace Opm { this->calculateProductivityIndexValues(local_deferredLogger); - this->commitWellState(); + this->commitWGState(); Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger); if (terminal_output_) { @@ -641,7 +641,7 @@ namespace Opm { loadRestartData(restartValues.wells, restartValues.grp_nwrk, phaseUsage, handle_ms_well, this->wellState()); } - this->commitWellState(); + this->commitWGState(); initial_step_ = false; } @@ -1028,7 +1028,7 @@ namespace Opm { if (param_.solve_welleq_initially_ && iterationIdx == 0) { for (auto& well : well_container_) { - well->solveWellEquation(ebosSimulator_, this->wellState(), local_deferredLogger); + well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), local_deferredLogger); } updateWellControls(local_deferredLogger, /* check group controls */ false); } @@ -1114,7 +1114,7 @@ namespace Opm { assembleWellEq(const double dt, Opm::DeferredLogger& deferred_logger) { for (auto& well : well_container_) { - well->assembleWellEq(ebosSimulator_, dt, this->wellState(), deferred_logger); + well->assembleWellEq(ebosSimulator_, dt, this->wellState(), this->groupState(), deferred_logger); } } @@ -1387,7 +1387,7 @@ namespace Opm { // Check wells' group constraints and communicate. for (const auto& well : well_container_) { const auto mode = WellInterface::IndividualOrGroup::Group; - const bool changed = well->updateWellControl(ebosSimulator_, mode, this->wellState(), deferred_logger); + const bool changed = well->updateWellControl(ebosSimulator_, mode, this->wellState(), this->groupState(), deferred_logger); if (changed) { switched_wells.insert(well->name()); } @@ -1401,7 +1401,7 @@ namespace Opm { continue; } const auto mode = WellInterface::IndividualOrGroup::Individual; - well->updateWellControl(ebosSimulator_, mode, this->wellState(), deferred_logger); + well->updateWellControl(ebosSimulator_, mode, this->wellState(), this->groupState(), deferred_logger); } updateAndCommunicateGroupData(); @@ -1421,8 +1421,7 @@ namespace Opm { if (!network.active()) { return; } - node_pressures_ = WellGroupHelpers::computeNetworkPressures( - network, this->wellState(), *(vfp_properties_->getProd()), schedule(), reportStepIdx); + node_pressures_ = WellGroupHelpers::computeNetworkPressures(network, this->wellState(), this->groupState(), *(vfp_properties_->getProd()), schedule(), reportStepIdx); // Set the thp limits of wells for (auto& well : well_container_) { @@ -1459,7 +1458,7 @@ namespace Opm { this->wellState().updateGlobalIsGrup(schedule(), reportStepIdx, comm); if (iterationIdx < nupcol) { - this->updateNupcolWellState(); + this->updateNupcolWGState(); } auto& well_state = this->wellState(); @@ -1468,15 +1467,15 @@ namespace Opm { // the group target reduction rates needs to be update since wells may have swicthed to/from GRUP control // Currently the group target reduction does not honor NUPCOL. TODO: is that true? std::vector groupTargetReduction(numPhases(), 0.0); - WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, phase_usage_, *guideRate_, well_state_nupcol, well_state, groupTargetReduction); + WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, phase_usage_, *guideRate_, well_state_nupcol, well_state, this->groupState(), groupTargetReduction); std::vector groupTargetReductionInj(numPhases(), 0.0); - WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, phase_usage_, *guideRate_, well_state_nupcol, well_state, groupTargetReductionInj); + WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, phase_usage_, *guideRate_, well_state_nupcol, well_state, this->groupState(), groupTargetReductionInj); - WellGroupHelpers::updateREINForGroups(fieldGroup, schedule(), reportStepIdx, phase_usage_, summaryState, well_state_nupcol, well_state); - WellGroupHelpers::updateVREPForGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state); + WellGroupHelpers::updateREINForGroups(fieldGroup, schedule(), reportStepIdx, phase_usage_, summaryState, well_state_nupcol, well_state, this->groupState()); + WellGroupHelpers::updateVREPForGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state, this->groupState()); - WellGroupHelpers::updateReservoirRatesInjectionGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state); - WellGroupHelpers::updateGroupProductionRates(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state); + WellGroupHelpers::updateReservoirRatesInjectionGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state, this->groupState()); + WellGroupHelpers::updateGroupProductionRates(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state, this->groupState()); // We use the rates from the privious time-step to reduce oscilations WellGroupHelpers::updateWellRates(fieldGroup, schedule(), reportStepIdx, this->prevWellState(), well_state); @@ -1491,7 +1490,7 @@ namespace Opm { } well_state.communicateGroupRates(comm); - + this->groupState().communicate_rates(comm); // compute wsolvent fraction for REIN wells updateWsolvent(fieldGroup, schedule(), reportStepIdx, well_state_nupcol); @@ -1877,7 +1876,7 @@ namespace Opm { const data::GroupAndNetworkValues& grpNwrkValues, const PhaseUsage& phases, const bool handle_ms_well, - WellStateFullyImplicitBlackoil& state) const + WellStateFullyImplicitBlackoil& well_state) { using GPMode = Group::ProductionCMode; using GIMode = Group::InjectionCMode; @@ -1898,28 +1897,28 @@ namespace Opm { phs.at( phases.phase_pos[BlackoilPhases::Vapour] ) = rt::gas; } - for( const auto& wm : state.wellMap() ) { + for( const auto& wm : well_state.wellMap() ) { const auto well_index = wm.second[ 0 ]; const auto& rst_well = rst_wells.at( wm.first ); - state.bhp()[ well_index ] = rst_well.bhp; - state.temperature()[ well_index ] = rst_well.temperature; + well_state.bhp()[ well_index ] = rst_well.bhp; + well_state.temperature()[ well_index ] = rst_well.temperature; if (rst_well.current_control.isProducer) { - state.currentProductionControls()[ well_index ] = rst_well.current_control.prod; + well_state.currentProductionControls()[ well_index ] = rst_well.current_control.prod; } else { - state.currentInjectionControls()[ well_index ] = rst_well.current_control.inj; + well_state.currentInjectionControls()[ well_index ] = rst_well.current_control.inj; } const auto wellrate_index = well_index * np; for( size_t i = 0; i < phs.size(); ++i ) { assert( rst_well.rates.has( phs[ i ] ) ); - state.wellRates()[ wellrate_index + i ] = rst_well.rates.get( phs[ i ] ); + well_state.wellRates()[ wellrate_index + i ] = rst_well.rates.get( phs[ i ] ); } - auto * perf_pressure = state.perfPress().data() + wm.second[1]; - auto * perf_rates = state.perfRates().data() + wm.second[1]; - auto * perf_phase_rates = state.perfPhaseRates().data() + wm.second[1]*np; + auto * perf_pressure = well_state.perfPress().data() + wm.second[1]; + auto * perf_rates = well_state.perfRates().data() + wm.second[1]; + auto * perf_phase_rates = well_state.perfPhaseRates().data() + wm.second[1]*np; const auto& perf_data = this->well_perf_data_[well_index]; for (std::size_t perf_index = 0; perf_index < perf_data.size(); perf_index++) { @@ -1938,7 +1937,7 @@ namespace Opm { const WellSegments& segment_set = well_ecl.getSegments(); - const int top_segment_index = state.topSegmentIndex(well_index); + const int top_segment_index = well_state.topSegmentIndex(well_index); const auto& segments = rst_well.segments; // \Note: eventually we need to hanlde the situations that some segments are shut @@ -1949,11 +1948,11 @@ namespace Opm { // recovering segment rates and pressure from the restart values const auto pres_idx = Opm::data::SegmentPressures::Value::Pressure; - state.segPress()[top_segment_index + segment_index] = segment.second.pressures[pres_idx]; + well_state.segPress()[top_segment_index + segment_index] = segment.second.pressures[pres_idx]; const auto& segment_rates = segment.second.rates; for (int p = 0; p < np; ++p) { - state.segRates()[(top_segment_index + segment_index) * np + p] = segment_rates.get(phs[p]); + well_state.segRates()[(top_segment_index + segment_index) * np + p] = segment_rates.get(phs[p]); } } } @@ -1965,15 +1964,15 @@ namespace Opm { const auto cwi = value.currentControl.currentWaterInjectionConstraint; if (cpc != GPMode::NONE) { - state.setCurrentProductionGroupControl(group, cpc); + this->groupState().production_control(group, cpc); } if (cgi != GIMode::NONE) { - state.setCurrentInjectionGroupControl(Phase::GAS, group, cgi); + this->groupState().injection_control(group, Phase::GAS, cgi); } if (cwi != GIMode::NONE) { - state.setCurrentInjectionGroupControl(Phase::WATER, group, cwi); + this->groupState().injection_control(group, Phase::WATER, cwi); } } } @@ -2143,7 +2142,7 @@ namespace Opm { const auto& well_state = this->wellState(); const auto controls = group.productionControls(summaryState); - const Group::ProductionCMode& currentControl = well_state.currentProductionGroupControl(group.name()); + const Group::ProductionCMode& currentControl = this->groupState().production_control(group.name()); if (group.has_control(Group::ProductionCMode::ORAT)) { @@ -2259,7 +2258,7 @@ namespace Opm { OPM_THROW(std::runtime_error, "Unknown phase" ); const auto& controls = group.injectionControls(phase, summaryState); - const Group::InjectionCMode& currentControl = well_state.currentInjectionGroupControl(phase, group.name()); + auto currentControl = this->groupState().injection_control(group.name(), phase); if (controls.has_control(Group::InjectionCMode::RATE)) { @@ -2344,7 +2343,7 @@ namespace Opm { template void BlackoilWellModel:: - checkGconsaleLimits(const Group& group, WellState& well_state, Opm::DeferredLogger& deferred_logger) const + checkGconsaleLimits(const Group& group, WellState& well_state, Opm::DeferredLogger& deferred_logger) { const int reportStepIdx = ebosSimulator_.episodeIndex(); // call recursively down the group hiearchy @@ -2367,7 +2366,7 @@ namespace Opm { const auto& comm = ebosSimulator_.vanguard().grid().comm(); const auto& gconsale = schedule()[reportStepIdx].gconsale().get(group.name(), summaryState); - const Group::ProductionCMode& oldProductionControl = well_state.currentProductionGroupControl(group.name()); + const Group::ProductionCMode& oldProductionControl = this->groupState().production_control(group.name()); int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour]; @@ -2425,11 +2424,11 @@ namespace Opm { break; } case GConSale::MaxProcedure::RATE: { - well_state.setCurrentProductionGroupControl(group.name(), Group::ProductionCMode::GRAT); - ss << "Maximum GCONSALE limit violated for " << group.name() << ". The group is switched from "; - ss << Group::ProductionCMode2String(oldProductionControl) << " to " << Group::ProductionCMode2String(Group::ProductionCMode::GRAT); - ss << " and limited by the maximum sales rate after consumption and import are considered" ; - well_state.setCurrentGroupGratTargetFromSales(group.name(), production_target); + this->groupState().production_control(group.name(), Group::ProductionCMode::GRAT); + ss << "Maximum GCONSALE limit violated for " << group.name() << ". The group is switched from "; + ss << Group::ProductionCMode2String(oldProductionControl) << " to " << Group::ProductionCMode2String(Group::ProductionCMode::GRAT); + ss << " and limited by the maximum sales rate after consumption and import are considered" ; + this->groupState().update_grat_sales_target(group.name(), production_target); break; } default: @@ -2437,11 +2436,11 @@ namespace Opm { } } if (sales_rate < gconsale.min_sales_rate) { - const Group::ProductionCMode& currentProductionControl = well_state.currentProductionGroupControl(group.name()); + const Group::ProductionCMode& currentProductionControl = this->groupState().production_control(group.name()); if ( currentProductionControl == Group::ProductionCMode::GRAT ) { ss << "Group " + group.name() + " has sale rate less then minimum permitted value and is under GRAT control. \n"; ss << "The GRAT is increased to meet the sales minimum rate. \n"; - well_state.setCurrentGroupGratTargetFromSales(group.name(), production_target); + this->groupState().update_grat_sales_target(group.name(), production_target); //} else if () {//TODO add action for WGASPROD //} else if () {//TODO add action for drilling queue } else { @@ -2466,8 +2465,7 @@ namespace Opm { BlackoilWellModel:: actionOnBrokenConstraints(const Group& group, const Group::ExceedAction& exceed_action, const Group::ProductionCMode& newControl, Opm::DeferredLogger& deferred_logger) { - auto& well_state = this->wellState(); - const Group::ProductionCMode oldControl = well_state.currentProductionGroupControl(group.name()); + const Group::ProductionCMode oldControl = this->groupState().production_control(group.name()); std::ostringstream ss; @@ -2496,7 +2494,7 @@ namespace Opm { } case Group::ExceedAction::RATE: { if (oldControl != newControl) { - well_state.setCurrentProductionGroupControl(group.name(), newControl); + this->groupState().production_control(group.name(), newControl); ss << "Switching production control mode for group "<< group.name() << " from " << Group::ProductionCMode2String(oldControl) << " to " << Group::ProductionCMode2String(newControl); @@ -2519,8 +2517,7 @@ namespace Opm { void BlackoilWellModel:: actionOnBrokenConstraints(const Group& group, const Group::InjectionCMode& newControl, const Phase& controlPhase, Opm::DeferredLogger& deferred_logger) { - auto& well_state = this->wellState(); - const Group::InjectionCMode oldControl = well_state.currentInjectionGroupControl(controlPhase, group.name()); + auto oldControl = this->groupState().injection_control(group.name(), controlPhase); std::ostringstream ss; if (oldControl != newControl) { @@ -2528,7 +2525,7 @@ namespace Opm { ss << "Switching injection control mode for group "<< group.name() << " from " << Group::InjectionCMode2String(oldControl) << " to " << Group::InjectionCMode2String(newControl); - well_state.setCurrentInjectionGroupControl(controlPhase, group.name(), newControl); + this->groupState().injection_control(group.name(), controlPhase, newControl); } auto cc = Dune::MPIHelper::getCollectiveCommunication(); if (!ss.str().empty() && cc.rank() == 0) @@ -2601,7 +2598,7 @@ namespace Opm { const Phase all[] = { Phase::WATER, Phase::OIL, Phase::GAS }; for (Phase phase : all) { // Check higher up only if under individual (not FLD) control. - const Group::InjectionCMode& currentControl = this->wellState().currentInjectionGroupControl(phase, group.name()); + auto currentControl = this->groupState().injection_control(group.name(), phase); if (currentControl != Group::InjectionCMode::FLD && group.injectionGroupControlAvailable(phase)) { const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx); const std::pair changed = WellGroupHelpers::checkGroupConstraintsInj( @@ -2609,6 +2606,7 @@ namespace Opm { group.parent(), parentGroup, this->wellState(), + this->groupState(), reportStepIdx, guideRate_.get(), rates.data(), @@ -2635,7 +2633,7 @@ namespace Opm { rates[phasePos] = -comm.sum(local_current_rate); } // Check higher up only if under individual (not FLD) control. - const Group::ProductionCMode& currentControl = this->wellState().currentProductionGroupControl(group.name()); + const Group::ProductionCMode& currentControl = this->groupState().production_control(group.name()); if (currentControl != Group::ProductionCMode::FLD && group.productionGroupControlAvailable()) { const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx); const std::pair changed = WellGroupHelpers::checkGroupConstraintsProd( @@ -2643,6 +2641,7 @@ namespace Opm { group.parent(), parentGroup, this->wellState(), + this->groupState(), reportStepIdx, guideRate_.get(), rates.data(), @@ -2825,8 +2824,8 @@ namespace Opm { // Minimal well setup to compute PI/II values { - auto saved_previous_well_state = this->prevWellState(); - this->commitWellState(); + auto saved_previous_wgstate = this->prevWGState(); + this->commitWGState(); well_container_ = createWellContainer(timeStepIdx); for (auto& well : well_container_) { @@ -2839,7 +2838,7 @@ namespace Opm { } this->calculateProductivityIndexValues(local_deferredLogger); - this->commitWellState(std::move(saved_previous_well_state)); + this->commitWGState(std::move(saved_previous_wgstate)); } const auto nw = this->numLocalWells(); @@ -2882,7 +2881,7 @@ namespace Opm { if (group.isProductionGroup()) return; - const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(Phase::GAS, group.name()); + auto currentGroupControl = this->groupState().injection_control(group.name(), Phase::GAS); if( currentGroupControl == Group::InjectionCMode::REIN ) { int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour]; const auto& summaryState = ebosSimulator_.vanguard().summaryState(); @@ -3117,19 +3116,19 @@ namespace Opm { cgc.currentWaterInjectionConstraint = ::Opm::Group::InjectionCMode::NONE; - if (this->wellState().hasProductionGroupControl(gname)) { - cgc.currentProdConstraint = this->wellState().currentProductionGroupControl(gname); + if (this->groupState().has_production_control(gname)) { + cgc.currentProdConstraint = this->groupState().production_control(gname); } if ((grup_type == ::Opm::Group::GroupType::INJECTION) || (grup_type == ::Opm::Group::GroupType::MIXED)) { - if (this->wellState().hasInjectionGroupControl(::Opm::Phase::WATER, gname)) { - cgc.currentWaterInjectionConstraint = this->wellState().currentInjectionGroupControl(::Opm::Phase::WATER, gname); + if (this->groupState().has_injection_control(gname, ::Opm::Phase::WATER)) { + cgc.currentWaterInjectionConstraint = this->groupState().injection_control(gname, Phase::WATER); } - if (this->wellState().hasInjectionGroupControl(::Opm::Phase::GAS, gname)) { - cgc.currentGasInjectionConstraint = this->wellState().currentInjectionGroupControl(::Opm::Phase::GAS, gname); + if (this->groupState().has_injection_control(gname, ::Opm::Phase::GAS)) { + cgc.currentGasInjectionConstraint = this->groupState().injection_control(gname, Phase::GAS); } } } @@ -3195,7 +3194,7 @@ namespace Opm { const auto& gname = group.name(); - if ( ! this->wellState().hasProductionGroupRates(gname)) { + if ( ! this->groupState().has_production_rates(gname)) { // No flow rates for production group 'gname' -- might be before group comes // online (e.g., for the initial condition before simulation // starts). @@ -3207,7 +3206,7 @@ namespace Opm { return grval; } - const auto qs = WellGroupHelpers::getProductionGroupRateVector(this->wellState(), this->phase_usage_, gname); + const auto qs = WellGroupHelpers::getProductionGroupRateVector(this->groupState(), this->phase_usage_, gname); const auto is_inj = false; // This procedure only applies to G*PGR. this->getGuideRateValues(qs, is_inj, gname, grval); diff --git a/opm/simulators/wells/GroupState.hpp b/opm/simulators/wells/GroupState.hpp index 4647ba007..3ed810852 100644 --- a/opm/simulators/wells/GroupState.hpp +++ b/opm/simulators/wells/GroupState.hpp @@ -25,6 +25,7 @@ #include #include +#include namespace Opm { @@ -163,7 +164,7 @@ private: std::map m_grat_sales_target; - std::map, Group::InjectionCMode> injection_controls; + std::map, Group::InjectionCMode> injection_controls; }; } diff --git a/opm/simulators/wells/MultisegmentWell.hpp b/opm/simulators/wells/MultisegmentWell.hpp index f7e9da9c2..2fa787711 100644 --- a/opm/simulators/wells/MultisegmentWell.hpp +++ b/opm/simulators/wells/MultisegmentWell.hpp @@ -138,6 +138,7 @@ namespace Opm virtual void assembleWellEq(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) override; /// updating the well state based the current control mode @@ -420,6 +421,7 @@ namespace Opm Opm::DeferredLogger& deferred_logger) const; void assembleControlEq(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const Well::InjectionControls& inj_controls, @@ -453,14 +455,16 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) override; virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator, - const double dt, - const Well::InjectionControls& inj_controls, - const Well::ProductionControls& prod_controls, - WellState& well_state, - Opm::DeferredLogger& deferred_logger) override; + const double dt, + const Well::InjectionControls& inj_controls, + const Well::ProductionControls& prod_controls, + WellState& well_state, + const GroupState& group_state, + Opm::DeferredLogger& deferred_logger) override; virtual void updateWaterThroughput(const double dt, WellState& well_state) const override; diff --git a/opm/simulators/wells/MultisegmentWell_impl.hpp b/opm/simulators/wells/MultisegmentWell_impl.hpp index 2fdd0bfad..c2a198a0a 100644 --- a/opm/simulators/wells/MultisegmentWell_impl.hpp +++ b/opm/simulators/wells/MultisegmentWell_impl.hpp @@ -263,6 +263,7 @@ namespace Opm assembleWellEq(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { @@ -270,13 +271,13 @@ namespace Opm const bool use_inner_iterations = param_.use_inner_iterations_ms_wells_; if (use_inner_iterations) { - this->iterateWellEquations(ebosSimulator, dt, well_state, deferred_logger); + this->iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger); } const auto& summary_state = ebosSimulator.vanguard().summaryState(); const auto inj_controls = well_ecl_.isInjector() ? well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0); const auto prod_controls = well_ecl_.isProducer() ? well_ecl_.productionControls(summary_state) : Well::ProductionControls(0); - assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, deferred_logger); + assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); } @@ -861,6 +862,7 @@ namespace Opm // store a copy of the well state, we don't want to update the real well state WellState well_state_copy = ebosSimulator.problem().wellModel().wellState(); + const auto& group_state = ebosSimulator.problem().wellModel().groupState(); // Get the current controls. const auto& summary_state = ebosSimulator.vanguard().summaryState(); @@ -894,7 +896,7 @@ namespace Opm well_copy.calculateExplicitQuantities(ebosSimulator, well_state_copy, deferred_logger); const double dt = ebosSimulator.timeStepSize(); // iterate to get a solution at the given bhp. - well_copy.iterateWellEqWithControl(ebosSimulator, dt, inj_controls, prod_controls, well_state_copy, + well_copy.iterateWellEqWithControl(ebosSimulator, dt, inj_controls, prod_controls, well_state_copy, group_state, deferred_logger); // compute the potential and store in the flux vector. @@ -2000,6 +2002,7 @@ namespace Opm void MultisegmentWell:: assembleControlEq(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const Well::InjectionControls& inj_controls, @@ -2058,7 +2061,7 @@ namespace Opm return calculateBhpFromThp(rates, well, summaryState, deferred_logger); }; // Call generic implementation. - Base::assembleControlEqInj(well_state, schedule, summaryState, inj_controls, getBhp(), injection_rate, bhp_from_thp, control_eq, deferred_logger); + Base::assembleControlEqInj(well_state, group_state, schedule, summaryState, inj_controls, getBhp(), injection_rate, bhp_from_thp, control_eq, deferred_logger); } else { // Find rates. const auto rates = getRates(); @@ -2067,7 +2070,7 @@ namespace Opm return calculateBhpFromThp(rates, well, summaryState, deferred_logger); }; // Call generic implementation. - Base::assembleControlEqProd(well_state, schedule, summaryState, prod_controls, getBhp(), rates, bhp_from_thp, control_eq, deferred_logger); + Base::assembleControlEqProd(well_state, group_state, schedule, summaryState, prod_controls, getBhp(), rates, bhp_from_thp, control_eq, deferred_logger); } // using control_eq to update the matrix and residuals @@ -2708,6 +2711,7 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { if (!this->isOperable() && !this->wellIsStopped()) return true; @@ -2726,7 +2730,7 @@ namespace Opm bool relax_convergence = false; for (; it < max_iter_number; ++it, ++debug_cost_counter_) { - assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, deferred_logger); + assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); const BVectorWell dx_well = mswellhelpers::applyUMFPack(duneD_, duneDSolver_, resWell_); @@ -2826,6 +2830,7 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { @@ -2979,7 +2984,7 @@ namespace Opm if (seg == 0) { // top segment, pressure equation is the control equation const auto& summaryState = ebosSimulator.vanguard().summaryState(); const Opm::Schedule& schedule = ebosSimulator.vanguard().schedule(); - assembleControlEq(well_state, schedule, summaryState, inj_controls, prod_controls, deferred_logger); + assembleControlEq(well_state, group_state, schedule, summaryState, inj_controls, prod_controls, deferred_logger); } else { const UnitSystem& unit_system = ebosSimulator.vanguard().eclState().getDeckUnitSystem(); assemblePressureEq(seg, unit_system, well_state, deferred_logger); diff --git a/opm/simulators/wells/StandardWell.hpp b/opm/simulators/wells/StandardWell.hpp index 61a2689c3..9ed49f958 100644 --- a/opm/simulators/wells/StandardWell.hpp +++ b/opm/simulators/wells/StandardWell.hpp @@ -184,6 +184,7 @@ namespace Opm virtual void assembleWellEq(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) override; virtual void updateWellStateWithTarget(const Simulator& ebos_simulator, @@ -242,6 +243,7 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) override; /// \brief Wether the Jacobian will also have well contributions in it. @@ -518,6 +520,7 @@ namespace Opm double getALQ(const WellState& well_state) const; void assembleControlEq(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, Opm::DeferredLogger& deferred_logger); @@ -531,11 +534,13 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) override; void assembleWellEqWithoutIterationImpl(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger); void calculateSinglePerf(const Simulator& ebosSimulator, diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index fc1bf6dbb..0503f3b2b 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -544,20 +544,21 @@ namespace Opm assembleWellEq(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { checkWellOperability(ebosSimulator, well_state, deferred_logger); const bool use_inner_iterations = param_.use_inner_iterations_wells_; if (use_inner_iterations) { - this->iterateWellEquations(ebosSimulator, dt, well_state, deferred_logger); + this->iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger); } // TODO: inj_controls and prod_controls are not used in the following function for now const auto& summary_state = ebosSimulator.vanguard().summaryState(); const auto inj_controls = well_ecl_.isInjector() ? well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0); const auto prod_controls = well_ecl_.isProducer() ? well_ecl_.productionControls(summary_state) : Well::ProductionControls(0); - assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, deferred_logger); + assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); } @@ -571,6 +572,7 @@ namespace Opm const Well::InjectionControls& /*inj_controls*/, const Well::ProductionControls& /*prod_controls*/, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { // TODO: only_wells should be put back to save some computation @@ -583,7 +585,7 @@ namespace Opm invDuneD_ = 0.0; resWell_ = 0.0; - assembleWellEqWithoutIterationImpl(ebosSimulator, dt, well_state, deferred_logger); + assembleWellEqWithoutIterationImpl(ebosSimulator, dt, well_state, group_state, deferred_logger); } @@ -595,6 +597,7 @@ namespace Opm assembleWellEqWithoutIterationImpl(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { @@ -678,7 +681,7 @@ namespace Opm const auto& summaryState = ebosSimulator.vanguard().summaryState(); const Opm::Schedule& schedule = ebosSimulator.vanguard().schedule(); - assembleControlEq(well_state, schedule, summaryState, deferred_logger); + assembleControlEq(well_state, group_state, schedule, summaryState, deferred_logger); // do the local inversion of D. @@ -869,6 +872,7 @@ namespace Opm template void StandardWell::assembleControlEq(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, Opm::DeferredLogger& deferred_logger) @@ -903,7 +907,7 @@ namespace Opm }; // Call generic implementation. const auto& inj_controls = well.injectionControls(summaryState); - Base::assembleControlEqInj(well_state, schedule, summaryState, inj_controls, getBhp(), injection_rate, bhp_from_thp, control_eq, deferred_logger); + Base::assembleControlEqInj(well_state, group_state, schedule, summaryState, inj_controls, getBhp(), injection_rate, bhp_from_thp, control_eq, deferred_logger); } else { // Find rates. const auto rates = getRates(); @@ -913,7 +917,7 @@ namespace Opm }; // Call generic implementation. const auto& prod_controls = well.productionControls(summaryState); - Base::assembleControlEqProd(well_state, schedule, summaryState, prod_controls, getBhp(), rates, bhp_from_thp, control_eq, deferred_logger); + Base::assembleControlEqProd(well_state, group_state, schedule, summaryState, prod_controls, getBhp(), rates, bhp_from_thp, control_eq, deferred_logger); } // using control_eq to update the matrix and residuals @@ -2601,6 +2605,7 @@ namespace Opm // create a copy of the well_state to use. If the operability checking is sucessful, we use this one // to replace the original one WellState well_state_copy = ebosSimulator.problem().wellModel().wellState(); + const auto& group_state = ebosSimulator.problem().wellModel().groupState(); // Set current control to bhp, and bhp value in state, modify bhp limit in control object. if (well_ecl_.isInjector()) { @@ -2611,7 +2616,7 @@ namespace Opm well_state_copy.bhp()[index_of_well_] = bhp; const double dt = ebosSimulator.timeStepSize(); - bool converged = this->iterateWellEquations(ebosSimulator, dt, well_state_copy, deferred_logger); + bool converged = this->iterateWellEquations(ebosSimulator, dt, well_state_copy, group_state, deferred_logger); if (!converged) { const std::string msg = " well " + name() + " did not get converged during well potential calculations " "returning zero values for the potential"; @@ -4092,13 +4097,14 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { const int max_iter = param_.max_inner_iter_wells_; int it = 0; bool converged; do { - assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, deferred_logger); + assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); auto report = getWellConvergence(well_state, Base::B_avg_, deferred_logger); diff --git a/opm/simulators/wells/TargetCalculator.hpp b/opm/simulators/wells/TargetCalculator.hpp index 2d13f17ba..2eabbc7c2 100644 --- a/opm/simulators/wells/TargetCalculator.hpp +++ b/opm/simulators/wells/TargetCalculator.hpp @@ -175,6 +175,7 @@ namespace WellGroupHelpers const std::string& group_name, const double sales_target, const WellStateFullyImplicitBlackoil& well_state, + const GroupState& group_state, const Phase& injection_phase, DeferredLogger& deferred_logger) : cmode_(cmode) @@ -183,6 +184,7 @@ namespace WellGroupHelpers , group_name_(group_name) , sales_target_(sales_target) , well_state_(well_state) + , group_state_(group_state) { // initialize to avoid warning pos_ = pu.phase_pos[BlackoilPhases::Aqua]; @@ -226,14 +228,12 @@ namespace WellGroupHelpers case Group::InjectionCMode::RESV: return ctrl.resv_max_rate; case Group::InjectionCMode::REIN: { - double production_rate = well_state_.currentInjectionREINRates(ctrl.reinj_group)[pos_]; + double production_rate = this->group_state_.injection_rein_rates(ctrl.reinj_group)[pos_]; return ctrl.target_reinj_fraction * production_rate; } case Group::InjectionCMode::VREP: { - const std::vector& group_injection_reductions - = well_state_.currentInjectionGroupReductionRates(group_name_); - double voidage_rate - = well_state_.currentInjectionVREPRates(ctrl.voidage_group) * ctrl.target_void_fraction; + const std::vector& group_injection_reductions = this->group_state_.injection_reduction_rates(this->group_name_); + double voidage_rate = group_state_.injection_vrep_rate(ctrl.voidage_group) * ctrl.target_void_fraction; double inj_reduction = 0.0; if (ctrl.phase != Phase::WATER) inj_reduction += group_injection_reductions[pu_.phase_pos[BlackoilPhases::Aqua]] @@ -251,7 +251,7 @@ namespace WellGroupHelpers assert(pos_ == pu_.phase_pos[BlackoilPhases::Vapour]); // Gas injection rate = Total gas production rate + gas import rate - gas consumption rate - sales rate; // Gas import and consumption is already included in the REIN rates - double inj_rate = well_state_.currentInjectionREINRates(group_name_)[pos_]; + double inj_rate = group_state_.injection_rein_rates(this->group_name_)[pos_]; inj_rate -= sales_target_; return inj_rate; } @@ -283,6 +283,7 @@ namespace WellGroupHelpers const std::string& group_name_; double sales_target_; const WellStateFullyImplicitBlackoil& well_state_; + const GroupState& group_state_; int pos_; GuideRateModel::Target target_; diff --git a/opm/simulators/wells/WGState.cpp b/opm/simulators/wells/WGState.cpp new file mode 100644 index 000000000..899a4e699 --- /dev/null +++ b/opm/simulators/wells/WGState.cpp @@ -0,0 +1,30 @@ +/* + Copyright 2021 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 . +*/ + +#include +#include + +namespace Opm { + +WGState::WGState(const PhaseUsage& pu) : + well_state(pu), + group_state(pu.num_phases) +{} + +} diff --git a/opm/simulators/wells/WGState.hpp b/opm/simulators/wells/WGState.hpp new file mode 100644 index 000000000..d0cd41412 --- /dev/null +++ b/opm/simulators/wells/WGState.hpp @@ -0,0 +1,43 @@ +/* + Copyright 2021 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 . +*/ + +#ifndef OPM_WGSTATE_HEADER_INCLUDED +#define OPM_WGSTATE_HEADER_INCLUDED + +#include +#include + +namespace Opm { + +/* + Microscopic class to handle a pair of well and group state. +*/ + +class PhaseUsage; + +struct WGState { + WGState(const PhaseUsage& pu); + + WellStateFullyImplicitBlackoil well_state; + GroupState group_state; +}; + +} + +#endif diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index 5120a89c7..12cba2d6e 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -61,23 +61,23 @@ namespace WellGroupHelpers const Schedule& schedule, const SummaryState& summaryState, const int reportStepIdx, - WellStateFullyImplicitBlackoil& wellState) + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state) { for (const std::string& groupName : group.groups()) { - setCmodeGroup( - schedule.getGroup(groupName, reportStepIdx), schedule, summaryState, reportStepIdx, wellState); + setCmodeGroup(schedule.getGroup(groupName, reportStepIdx), schedule, summaryState, reportStepIdx, wellState, group_state); } // use NONE as default control const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS}; for (Phase phase : all) { - if (!wellState.hasInjectionGroupControl(phase, group.name())) { - wellState.setCurrentInjectionGroupControl(phase, group.name(), Group::InjectionCMode::NONE); + if (!group_state.has_injection_control(group.name(), phase)) { + group_state.injection_control(group.name(), phase, Group::InjectionCMode::NONE); } } - if (!wellState.hasProductionGroupControl(group.name())) { - wellState.setCurrentProductionGroupControl(group.name(), Group::ProductionCMode::NONE); + if (!group_state.has_production_control(group.name())) { + group_state.production_control(group.name(), Group::ProductionCMode::NONE); } const auto& events = schedule[reportStepIdx].wellgroup_events(); @@ -89,18 +89,18 @@ namespace WellGroupHelpers continue; const auto& controls = group.injectionControls(phase, summaryState); - wellState.setCurrentInjectionGroupControl(phase, group.name(), controls.cmode); + group_state.injection_control(group.name(), phase, controls.cmode); } } if (group.isProductionGroup() && events.hasEvent(group.name(), ScheduleEvents::GROUP_PRODUCTION_UPDATE)) { const auto controls = group.productionControls(summaryState); - wellState.setCurrentProductionGroupControl(group.name(), controls.cmode); + group_state.production_control(group.name(), controls.cmode); } if (schedule[reportStepIdx].gconsale().has(group.name())) { - wellState.setCurrentInjectionGroupControl(Phase::GAS, group.name(), Group::InjectionCMode::SALE); + group_state.injection_control(group.name(), Phase::GAS, Group::InjectionCMode::SALE); } } @@ -232,13 +232,13 @@ namespace WellGroupHelpers const Opm::PhaseUsage& pu, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, GuideRate* guideRate, Opm::DeferredLogger& deferred_logger) { for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - updateGuideRatesForInjectionGroups( - groupTmp, schedule, summaryState, pu, reportStepIdx, wellState, guideRate, deferred_logger); + updateGuideRatesForInjectionGroups(groupTmp, schedule, summaryState, pu, reportStepIdx, wellState, group_state, guideRate, deferred_logger); } const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS}; for (Phase phase : all) { @@ -253,13 +253,13 @@ namespace WellGroupHelpers break; case Group::GuideRateInjTarget::VOID: { - guideRateValue = wellState.currentInjectionVREPRates(group.name()); + guideRateValue = group_state.injection_vrep_rate(group.name()); break; } case Group::GuideRateInjTarget::NETV: { - guideRateValue = wellState.currentInjectionVREPRates(group.name()); - const std::vector& injRES = wellState.currentInjectionGroupReservoirRates(group.name()); + guideRateValue = group_state.injection_vrep_rate(group.name()); + const std::vector& injRES = group_state.injection_reservoir_rates(group.name()); if (phase != Phase::OIL && pu.phase_used[BlackoilPhases::Liquid]) guideRateValue -= injRES[pu.phase_pos[BlackoilPhases::Liquid]]; if (phase != Phase::GAS && pu.phase_used[BlackoilPhases::Vapour]) @@ -291,6 +291,7 @@ namespace WellGroupHelpers const GuideRate& guide_rate, const WellStateFullyImplicitBlackoil& wellStateNupcol, WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state, std::vector& groupTargetReduction) { const int np = wellState.numPhases(); @@ -305,6 +306,7 @@ namespace WellGroupHelpers guide_rate, wellStateNupcol, wellState, + group_state, subGroupTargetReduction); // accumulate group contribution from sub group @@ -312,7 +314,7 @@ namespace WellGroupHelpers const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS}; for (Phase phase : all) { const Group::InjectionCMode& currentGroupControl - = wellState.currentInjectionGroupControl(phase, subGroupName); + = group_state.injection_control(subGroup.name(), phase); int phasePos; if (phase == Phase::GAS && pu.phase_used[BlackoilPhases::Vapour]) phasePos = pu.phase_pos[BlackoilPhases::Vapour]; @@ -333,12 +335,11 @@ namespace WellGroupHelpers } } } else { - const Group::ProductionCMode& currentGroupControl - = wellState.currentProductionGroupControl(subGroupName); + const Group::ProductionCMode& currentGroupControl = group_state.production_control(subGroupName); const bool individual_control = (currentGroupControl != Group::ProductionCMode::FLD && currentGroupControl != Group::ProductionCMode::NONE); const int num_group_controlled_wells - = groupControlledWells(schedule, wellStateNupcol, reportStepIdx, subGroupName, "", !isInjector, /*injectionPhaseNotUsed*/Phase::OIL); + = groupControlledWells(schedule, wellStateNupcol, group_state, reportStepIdx, subGroupName, "", !isInjector, /*injectionPhaseNotUsed*/Phase::OIL); if (individual_control || num_group_controlled_wells == 0) { for (int phase = 0; phase < np; phase++) { groupTargetReduction[phase] @@ -400,9 +401,9 @@ namespace WellGroupHelpers elem *= groupEfficiency; } if (isInjector) - wellState.setCurrentInjectionGroupReductionRates(group.name(), groupTargetReduction); + group_state.update_injection_reduction_rates(group.name(), groupTargetReduction); else - wellState.setCurrentProductionGroupReductionRates(group.name(), groupTargetReduction); + group_state.update_production_reduction_rates(group.name(), groupTargetReduction); } @@ -410,11 +411,12 @@ namespace WellGroupHelpers const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState) + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state) { for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - updateVREPForGroups(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState); + updateVREPForGroups(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState, group_state); } const int np = wellState.numPhases(); double resv = 0.0; @@ -427,18 +429,19 @@ namespace WellGroupHelpers phase, /*isInjector*/ false); } - wellState.setCurrentInjectionVREPRates(group.name(), resv); + group_state.update_injection_vrep_rate(group.name(), resv); } void updateReservoirRatesInjectionGroups(const Group& group, const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState) + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state) { for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - updateReservoirRatesInjectionGroups(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState); + updateReservoirRatesInjectionGroups(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState, group_state); } const int np = wellState.numPhases(); std::vector resv(np, 0.0); @@ -451,7 +454,7 @@ namespace WellGroupHelpers phase, /*isInjector*/ true); } - wellState.setCurrentInjectionGroupReservoirRates(group.name(), resv); + group_state.update_injection_reservoir_rates(group.name(), resv); } void updateWellRates(const Group& group, @@ -489,11 +492,12 @@ namespace WellGroupHelpers const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState) + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state) { for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - updateGroupProductionRates(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState); + updateGroupProductionRates(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState, group_state); } const int np = wellState.numPhases(); std::vector rates(np, 0.0); @@ -501,7 +505,7 @@ namespace WellGroupHelpers rates[phase] = sumWellPhaseRates( wellStateNupcol.wellRates(), group, schedule, wellState, reportStepIdx, phase, /*isInjector*/ false); } - wellState.setCurrentProductionGroupRates(group.name(), rates); + group_state.update_production_rates(group.name(), rates); } @@ -511,12 +515,13 @@ namespace WellGroupHelpers const PhaseUsage& pu, const SummaryState& st, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState) + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state) { const int np = wellState.numPhases(); for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - updateREINForGroups(groupTmp, schedule, reportStepIdx, pu, st, wellStateNupcol, wellState); + updateREINForGroups(groupTmp, schedule, reportStepIdx, pu, st, wellStateNupcol, wellState, group_state); } std::vector rein(np, 0.0); @@ -534,7 +539,7 @@ namespace WellGroupHelpers } } - wellState.setCurrentInjectionREINRates(group.name(), rein); + group_state.update_injection_rein_rates(group.name(), rein); } @@ -543,6 +548,7 @@ namespace WellGroupHelpers std::map computeNetworkPressures(const Opm::Network::ExtNetwork& network, const WellStateFullyImplicitBlackoil& well_state, + const GroupState& group_state, const VFPProdProperties& vfp_prod_props, const Schedule& schedule, const int report_time_step) @@ -580,7 +586,7 @@ namespace WellGroupHelpers // from the corresponding groups. std::map> node_inflows; for (const auto& node : leaf_nodes) { - node_inflows[node] = well_state.currentProductionGroupRates(node); + node_inflows[node] = group_state.production_rates(node); // Add the ALQ amounts to the gas rates if requested. if (network.node(node).add_gas_lift_gas()) { const auto& group = schedule.getGroup(node, report_time_step); @@ -667,14 +673,15 @@ namespace WellGroupHelpers } GuideRate::RateVector - getProductionGroupRateVector(const WellStateFullyImplicitBlackoil& well_state, const PhaseUsage& pu, const std::string& group_name) + getProductionGroupRateVector(const GroupState& group_state, const PhaseUsage& pu, const std::string& group_name) { - return getGuideRateVector(well_state.currentProductionGroupRates(group_name), pu); + return getGuideRateVector(group_state.production_rates(group_name), pu); } double getGuideRate(const std::string& name, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const GuideRateModel::Target target, @@ -685,18 +692,18 @@ namespace WellGroupHelpers } if (guideRate->has(name)) { - return guideRate->get(name, target, getProductionGroupRateVector(wellState, pu, name)); + return guideRate->get(name, target, getProductionGroupRateVector(group_state, pu, name)); } double totalGuideRate = 0.0; const Group& group = schedule.getGroup(name, reportStepIdx); for (const std::string& groupName : group.groups()) { - const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName); + const Group::ProductionCMode& currentGroupControl = group_state.production_control(groupName); if (currentGroupControl == Group::ProductionCMode::FLD || currentGroupControl == Group::ProductionCMode::NONE) { // accumulate from sub wells/groups - totalGuideRate += getGuideRate(groupName, schedule, wellState, reportStepIdx, guideRate, target, pu); + totalGuideRate += getGuideRate(groupName, schedule, wellState, group_state, reportStepIdx, guideRate, target, pu); } } @@ -722,6 +729,7 @@ namespace WellGroupHelpers double getGuideRateInj(const std::string& name, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const GuideRateModel::Target target, @@ -741,12 +749,11 @@ namespace WellGroupHelpers for (const std::string& groupName : group.groups()) { const Group::InjectionCMode& currentGroupControl - = wellState.currentInjectionGroupControl(injectionPhase, groupName); + = group_state.injection_control(groupName, injectionPhase); if (currentGroupControl == Group::InjectionCMode::FLD || currentGroupControl == Group::InjectionCMode::NONE) { // accumulate from sub wells/groups - totalGuideRate += getGuideRateInj( - groupName, schedule, wellState, reportStepIdx, guideRate, target, injectionPhase, pu); + totalGuideRate += getGuideRateInj(groupName, schedule, wellState, group_state, reportStepIdx, guideRate, target, injectionPhase, pu); } } @@ -772,6 +779,7 @@ namespace WellGroupHelpers int groupControlledWells(const Schedule& schedule, const WellStateFullyImplicitBlackoil& well_state, + const GroupState& group_state, const int report_step, const std::string& group_name, const std::string& always_included_child, @@ -784,16 +792,16 @@ namespace WellGroupHelpers bool included = (child_group == always_included_child); if (is_production_group) { - const auto ctrl = well_state.currentProductionGroupControl(child_group); + const auto ctrl = group_state.production_control(child_group); included = included || (ctrl == Group::ProductionCMode::FLD) || (ctrl == Group::ProductionCMode::NONE); } else { - const auto ctrl = well_state.currentInjectionGroupControl(injection_phase, child_group); + const auto ctrl = group_state.injection_control(child_group, injection_phase); included = included || (ctrl == Group::InjectionCMode::FLD) || (ctrl == Group::InjectionCMode::NONE); } if (included) { num_wells - += groupControlledWells(schedule, well_state, report_step, child_group, always_included_child, is_production_group, injection_phase); + += groupControlledWells(schedule, well_state, group_state, report_step, child_group, always_included_child, is_production_group, injection_phase); } } for (const std::string& child_well : group.wells()) { @@ -813,6 +821,7 @@ namespace WellGroupHelpers FractionCalculator::FractionCalculator(const Schedule& schedule, const SummaryState& summary_state, const WellStateFullyImplicitBlackoil& well_state, + const GroupState& group_state, const int report_step, const GuideRate* guide_rate, const GuideRateModel::Target target, @@ -822,6 +831,7 @@ namespace WellGroupHelpers : schedule_(schedule) , summary_state_(summary_state) , well_state_(well_state) + , group_state_(group_state) , report_step_(report_step) , guide_rate_(guide_rate) , target_(target) @@ -865,10 +875,10 @@ namespace WellGroupHelpers for (const std::string& child_group : group.groups()) { bool included = (child_group == always_included_child); if (is_producer_) { - const auto ctrl = well_state_.currentProductionGroupControl(child_group); + const auto ctrl = this->group_state_.production_control(child_group); included = included || (ctrl == Group::ProductionCMode::FLD) || (ctrl == Group::ProductionCMode::NONE); } else { - const auto ctrl = well_state_.currentInjectionGroupControl(injection_phase_, child_group); + const auto ctrl = this->group_state_.injection_control(child_group, this->injection_phase_); included = included || (ctrl == Group::InjectionCMode::FLD) || (ctrl == Group::InjectionCMode::NONE); } if (included) { @@ -915,13 +925,13 @@ namespace WellGroupHelpers const std::string& always_included_child) { return ::Opm::WellGroupHelpers::groupControlledWells( - schedule_, well_state_, report_step_, group_name, always_included_child, is_producer_, injection_phase_); + schedule_, well_state_, this->group_state_, report_step_, group_name, always_included_child, is_producer_, injection_phase_); } GuideRate::RateVector FractionCalculator::getGroupRateVector(const std::string& group_name) { assert(is_producer_); - return getProductionGroupRateVector(this->well_state_, this->pu_, group_name); + return getProductionGroupRateVector(this->group_state_, this->pu_, group_name); } @@ -958,6 +968,7 @@ namespace WellGroupHelpers const std::string& parent, const Group& group, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const double* rates, @@ -976,7 +987,7 @@ namespace WellGroupHelpers // part of. Later it is the accumulated factor including the group efficiency factor // of the child of group. - const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(group.name()); + const Group::ProductionCMode& currentGroupControl = group_state.production_control(group.name()); if (currentGroupControl == Group::ProductionCMode::FLD || currentGroupControl == Group::ProductionCMode::NONE) { // Return if we are not available for parent group. @@ -989,6 +1000,7 @@ namespace WellGroupHelpers parent, parentGroup, wellState, + group_state, reportStepIdx, guideRate, rates, @@ -1012,17 +1024,16 @@ namespace WellGroupHelpers // gconsale may adjust the grat target. // the adjusted rates is send to the targetCalculator double gratTargetFromSales = 0.0; - if (wellState.hasGroupGratTargetFromSales(group.name())) - gratTargetFromSales = wellState.currentGroupGratTargetFromSales(group.name()); + if (group_state.has_grat_sales_target(group.name())) + gratTargetFromSales = group_state.grat_sales_target(group.name()); TargetCalculator tcalc(currentGroupControl, pu, resv_coeff, gratTargetFromSales); - FractionCalculator fcalc(schedule, summaryState, wellState, reportStepIdx, guideRate, tcalc.guideTargetMode(), pu, true, Phase::OIL); + FractionCalculator fcalc(schedule, summaryState, wellState, group_state, reportStepIdx, guideRate, tcalc.guideTargetMode(), pu, true, Phase::OIL); auto localFraction = [&](const std::string& child) { return fcalc.localFraction(child, name); }; auto localReduction = [&](const std::string& group_name) { - const std::vector& groupTargetReductions - = wellState.currentProductionGroupReductionRates(group_name); + const std::vector& groupTargetReductions = group_state.production_reduction_rates(group_name); return tcalc.calcModeRateFromRates(groupTargetReductions); }; @@ -1063,7 +1074,7 @@ namespace WellGroupHelpers // the current well to be always included, because we // want to know the situation that applied to the // calculation of reductions. - const int num_gr_ctrl = groupControlledWells(schedule, wellState, reportStepIdx, chain[ii + 1], "", /*is_producer*/true, /*injectionPhaseNotUsed*/Phase::OIL); + const int num_gr_ctrl = groupControlledWells(schedule, wellState, group_state, reportStepIdx, chain[ii + 1], "", /*is_producer*/true, /*injectionPhaseNotUsed*/Phase::OIL); if (num_gr_ctrl == 0) { if (guideRate->has(chain[ii + 1])) { target += localReduction(chain[ii + 1]); @@ -1081,6 +1092,7 @@ namespace WellGroupHelpers const std::string& parent, const Group& group, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const double* rates, @@ -1100,7 +1112,7 @@ namespace WellGroupHelpers // part of. Later it is the accumulated factor including the group efficiency factor // of the child of group. - const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(injectionPhase, group.name()); + auto currentGroupControl = group_state.injection_control(group.name(), injectionPhase); if (currentGroupControl == Group::InjectionCMode::FLD || currentGroupControl == Group::InjectionCMode::NONE) { // Return if we are not available for parent group. @@ -1113,6 +1125,7 @@ namespace WellGroupHelpers parent, parentGroup, wellState, + group_state, reportStepIdx, guideRate, rates, @@ -1138,14 +1151,13 @@ namespace WellGroupHelpers const auto& gconsale = schedule[reportStepIdx].gconsale().get(group.name(), summaryState); sales_target = gconsale.sales_target; } - InjectionTargetCalculator tcalc(currentGroupControl, pu, resv_coeff, group.name(), sales_target, wellState, injectionPhase, deferred_logger); - FractionCalculator fcalc(schedule, summaryState, wellState, reportStepIdx, guideRate, tcalc.guideTargetMode(), pu, false, injectionPhase); + InjectionTargetCalculator tcalc(currentGroupControl, pu, resv_coeff, group.name(), sales_target, wellState, group_state, injectionPhase, deferred_logger); + FractionCalculator fcalc(schedule, summaryState, wellState, group_state, reportStepIdx, guideRate, tcalc.guideTargetMode(), pu, false, injectionPhase); auto localFraction = [&](const std::string& child) { return fcalc.localFraction(child, name); }; auto localReduction = [&](const std::string& group_name) { - const std::vector& groupTargetReductions - = wellState.currentInjectionGroupReductionRates(group_name); + const std::vector& groupTargetReductions = group_state.injection_reduction_rates(group_name); return tcalc.calcModeRateFromRates(groupTargetReductions); }; @@ -1186,7 +1198,7 @@ namespace WellGroupHelpers // the current well to be always included, because we // want to know the situation that applied to the // calculation of reductions. - const int num_gr_ctrl = groupControlledWells(schedule, wellState, reportStepIdx, chain[ii + 1], "", /*is_producer*/false, injectionPhase); + const int num_gr_ctrl = groupControlledWells(schedule, wellState, group_state, reportStepIdx, chain[ii + 1], "", /*is_producer*/false, injectionPhase); if (num_gr_ctrl == 0) { if (guideRate->has(chain[ii + 1], injectionPhase)) { target += localReduction(chain[ii + 1]); diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index fdaa68a29..b10e04334 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -49,7 +50,8 @@ namespace WellGroupHelpers const Schedule& schedule, const SummaryState& summaryState, const int reportStepIdx, - WellStateFullyImplicitBlackoil& wellState); + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state); void accumulateGroupEfficiencyFactor(const Group& group, const Schedule& schedule, @@ -92,6 +94,7 @@ namespace WellGroupHelpers const GuideRate& guide_rate, const WellStateFullyImplicitBlackoil& wellStateNupcol, WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state, std::vector& groupTargetReduction); template @@ -101,6 +104,7 @@ namespace WellGroupHelpers const int reportStepIdx, const double& simTime, WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const Comm& comm, GuideRate* guideRate, std::vector& pot) @@ -111,11 +115,10 @@ namespace WellGroupHelpers const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); // Note that group effiency factors for groupTmp are applied in updateGuideRateForGroups - updateGuideRateForProductionGroups( - groupTmp, schedule, pu, reportStepIdx, simTime, wellState, comm, guideRate, thisPot); + updateGuideRateForProductionGroups(groupTmp, schedule, pu, reportStepIdx, simTime, wellState, group_state, comm, guideRate, thisPot); // accumulate group contribution from sub group unconditionally - const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName); + const auto currentGroupControl = group_state.production_control(groupName); if (currentGroupControl != Group::ProductionCMode::FLD && currentGroupControl != Group::ProductionCMode::NONE) { continue; @@ -223,6 +226,7 @@ namespace WellGroupHelpers const Opm::PhaseUsage& pu, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, GuideRate* guideRate, Opm::DeferredLogger& deferred_logger); @@ -230,13 +234,15 @@ namespace WellGroupHelpers const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState); + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state); void updateReservoirRatesInjectionGroups(const Group& group, const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState); + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state); void updateWellRates(const Group& group, const Schedule& schedule, @@ -248,7 +254,8 @@ namespace WellGroupHelpers const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState); + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state); void updateREINForGroups(const Group& group, const Schedule& schedule, @@ -256,11 +263,13 @@ namespace WellGroupHelpers const PhaseUsage& pu, const SummaryState& st, const WellStateFullyImplicitBlackoil& wellStateNupcol, - WellStateFullyImplicitBlackoil& wellState); + WellStateFullyImplicitBlackoil& wellState, + GroupState& group_state); std::map computeNetworkPressures(const Opm::Network::ExtNetwork& network, const WellStateFullyImplicitBlackoil& well_state, + const GroupState& group_state, const VFPProdProperties& vfp_prod_props, const Schedule& schedule, const int report_time_step); @@ -269,11 +278,12 @@ namespace WellGroupHelpers getWellRateVector(const WellStateFullyImplicitBlackoil& well_state, const PhaseUsage& pu, const std::string& name); GuideRate::RateVector - getProductionGroupRateVector(const WellStateFullyImplicitBlackoil& well_state, const PhaseUsage& pu, const std::string& group_name); + getProductionGroupRateVector(const GroupState& group_state, const PhaseUsage& pu, const std::string& group_name); double getGuideRate(const std::string& name, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const GuideRateModel::Target target, @@ -283,6 +293,7 @@ namespace WellGroupHelpers double getGuideRateInj(const std::string& name, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const GuideRateModel::Target target, @@ -291,6 +302,7 @@ namespace WellGroupHelpers int groupControlledWells(const Schedule& schedule, const WellStateFullyImplicitBlackoil& well_state, + const GroupState& group_state, const int report_step, const std::string& group_name, const std::string& always_included_child, @@ -304,6 +316,7 @@ namespace WellGroupHelpers FractionCalculator(const Schedule& schedule, const SummaryState& summary_state, const WellStateFullyImplicitBlackoil& well_state, + const GroupState& group_state, const int report_step, const GuideRate* guide_rate, const GuideRateModel::Target target, @@ -322,6 +335,7 @@ namespace WellGroupHelpers const Schedule& schedule_; const SummaryState& summary_state_; const WellStateFullyImplicitBlackoil& well_state_; + const GroupState& group_state_; int report_step_; const GuideRate* guide_rate_; GuideRateModel::Target target_; @@ -335,6 +349,7 @@ namespace WellGroupHelpers const std::string& parent, const Group& group, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const double* rates, @@ -363,6 +378,7 @@ namespace WellGroupHelpers const std::string& parent, const Group& group, const WellStateFullyImplicitBlackoil& wellState, + const GroupState& group_state, const int reportStepIdx, const GuideRate* guideRate, const double* rates, diff --git a/opm/simulators/wells/WellInterface.hpp b/opm/simulators/wells/WellInterface.hpp index 881e46902..3c3f8d0f7 100644 --- a/opm/simulators/wells/WellInterface.hpp +++ b/opm/simulators/wells/WellInterface.hpp @@ -185,6 +185,7 @@ namespace Opm virtual void assembleWellEq(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger ) = 0; @@ -233,6 +234,7 @@ namespace Opm bool updateWellControl(const Simulator& ebos_simulator, const IndividualOrGroup iog, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) /* const */; virtual void updatePrimaryVariables(const WellState& well_state, Opm::DeferredLogger& deferred_logger) const = 0; @@ -283,7 +285,7 @@ namespace Opm void wellTesting(const Simulator& simulator, const double simulation_time, const int report_step, const WellTestConfig::Reason testing_reason, - /* const */ WellState& well_state, WellTestState& welltest_state, + /* const */ WellState& well_state, const GroupState& group_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger); void updatePerforatedCell(std::vector& is_cell_perforated); @@ -339,6 +341,7 @@ namespace Opm void solveWellEquation(const Simulator& ebosSimulator, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger); const PhaseUsage& phaseUsage() const; @@ -528,12 +531,14 @@ namespace Opm void wellTestingEconomic(const Simulator& simulator, - const double simulation_time, const WellState& well_state, + const double simulation_time, const WellState& well_state, const GroupState& group_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger); void wellTestingPhysical(const Simulator& simulator, const double simulation_time, const int report_step, - WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger); + WellState& well_state, + const GroupState& group_state, + WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger); virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator, @@ -541,6 +546,7 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) = 0; // iterate well equations with the specified control until converged @@ -549,11 +555,13 @@ namespace Opm const Well::InjectionControls& inj_controls, const Well::ProductionControls& prod_controls, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) = 0; bool iterateWellEquations(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger); void updateWellTestStateEconomic(const WellState& well_state, @@ -568,12 +576,13 @@ namespace Opm WellTestState& well_test_state, Opm::DeferredLogger& deferred_logger) const; - void solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, + void solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, const GroupState& group_state, Opm::DeferredLogger& deferred_logger); void initCompletions(); bool checkConstraints(WellState& well_state, + const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, DeferredLogger& deferred_logger) const; @@ -582,12 +591,14 @@ namespace Opm const SummaryState& summaryState) const; bool checkGroupConstraints(WellState& well_state, + const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, DeferredLogger& deferred_logger) const; std::pair checkGroupConstraintsProd(const Group& group, const WellState& well_state, + const GroupState& group_state, const double efficiencyFactor, const Schedule& schedule, const SummaryState& summaryState, @@ -595,6 +606,7 @@ namespace Opm std::pair checkGroupConstraintsInj(const Group& group, const WellState& well_state, + const GroupState& group_state, const double efficiencyFactor, const Schedule& schedule, const SummaryState& summaryState, @@ -603,6 +615,7 @@ namespace Opm template void getGroupInjectionControl(const Group& group, const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const InjectorType& injectorType, @@ -615,6 +628,7 @@ namespace Opm template void getGroupProductionControl(const Group& group, const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const EvalWell& bhp, @@ -624,6 +638,7 @@ namespace Opm template void assembleControlEqInj(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const Well::InjectionControls& controls, @@ -635,6 +650,7 @@ namespace Opm template void assembleControlEqProd(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const Well::ProductionControls& controls, diff --git a/opm/simulators/wells/WellInterface_impl.hpp b/opm/simulators/wells/WellInterface_impl.hpp index b9b70001e..f326c9fba 100644 --- a/opm/simulators/wells/WellInterface_impl.hpp +++ b/opm/simulators/wells/WellInterface_impl.hpp @@ -514,6 +514,7 @@ namespace Opm updateWellControl(const Simulator& ebos_simulator, const IndividualOrGroup iog, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) /* const */ { if (this->wellIsStopped()) { @@ -534,10 +535,10 @@ namespace Opm if (iog == IndividualOrGroup::Individual) { changed = checkIndividualConstraints(well_state, summaryState); } else if (iog == IndividualOrGroup::Group) { - changed = checkGroupConstraints(well_state, schedule, summaryState, deferred_logger); + changed = checkGroupConstraints(well_state, group_state, schedule, summaryState, deferred_logger); } else { assert(iog == IndividualOrGroup::Both); - changed = checkConstraints(well_state, schedule, summaryState, deferred_logger); + changed = checkConstraints(well_state, group_state, schedule, summaryState, deferred_logger); } auto cc = Dune::MPIHelper::getCollectiveCommunication(); @@ -1113,17 +1114,18 @@ namespace Opm const double simulation_time, const int report_step, const WellTestConfig::Reason testing_reason, /* const */ WellState& well_state, + const GroupState& group_state, WellTestState& well_test_state, Opm::DeferredLogger& deferred_logger) { if (testing_reason == WellTestConfig::Reason::PHYSICAL) { wellTestingPhysical(simulator, simulation_time, report_step, - well_state, well_test_state, deferred_logger); + well_state, group_state, well_test_state, deferred_logger); } if (testing_reason == WellTestConfig::Reason::ECONOMIC) { wellTestingEconomic(simulator, simulation_time, - well_state, well_test_state, deferred_logger); + well_state, group_state, well_test_state, deferred_logger); } } @@ -1135,7 +1137,7 @@ namespace Opm void WellInterface:: wellTestingEconomic(const Simulator& simulator, - const double simulation_time, const WellState& well_state, + const double simulation_time, const WellState& well_state, const GroupState& group_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger) { deferred_logger.info(" well " + name() + " is being tested for economic limits"); @@ -1155,7 +1157,7 @@ namespace Opm // untill the number of closed completions do not increase anymore. while (testWell) { const size_t original_number_closed_completions = welltest_state_temp.sizeCompletions(); - solveWellForTesting(simulator, well_state_copy, deferred_logger); + solveWellForTesting(simulator, well_state_copy, group_state, deferred_logger); updateWellTestState(well_state_copy, simulation_time, /*writeMessageToOPMLog=*/ false, welltest_state_temp, deferred_logger); closeCompletions(welltest_state_temp); @@ -1299,13 +1301,14 @@ namespace Opm iterateWellEquations(const Simulator& ebosSimulator, const double dt, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { const auto& summary_state = ebosSimulator.vanguard().summaryState(); const auto inj_controls = well_ecl_.isInjector() ? well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0); const auto prod_controls = well_ecl_.isProducer() ? well_ecl_.productionControls(summary_state) : Well::ProductionControls(0); - return this->iterateWellEqWithControl(ebosSimulator, dt, inj_controls, prod_controls, well_state, deferred_logger); + return this->iterateWellEqWithControl(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); } @@ -1352,13 +1355,13 @@ namespace Opm template void WellInterface:: - solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, + solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { // keep a copy of the original well state const WellState well_state0 = well_state; const double dt = ebosSimulator.timeStepSize(); - const bool converged = iterateWellEquations(ebosSimulator, dt, well_state, deferred_logger); + const bool converged = iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger); if (converged) { deferred_logger.debug("WellTest: Well equation for well " + name() + " converged"); } else { @@ -1374,6 +1377,7 @@ namespace Opm WellInterface:: solveWellEquation(const Simulator& ebosSimulator, WellState& well_state, + const GroupState& group_state, Opm::DeferredLogger& deferred_logger) { if (!this->isOperable()) @@ -1382,7 +1386,7 @@ namespace Opm // keep a copy of the original well state const WellState well_state0 = well_state; const double dt = ebosSimulator.timeStepSize(); - const bool converged = iterateWellEquations(ebosSimulator, dt, well_state, deferred_logger); + const bool converged = iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger); if (converged) { deferred_logger.debug("Compute initial well solution for well " + name() + ". Converged"); } else { @@ -1427,7 +1431,9 @@ namespace Opm WellInterface:: wellTestingPhysical(const Simulator& ebos_simulator, const double /* simulation_time */, const int /* report_step */, - WellState& well_state, WellTestState& welltest_state, + WellState& well_state, + const GroupState& group_state, + WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger) { deferred_logger.info(" well " + name() + " is being tested for physical limits"); @@ -1462,7 +1468,7 @@ namespace Opm calculateExplicitQuantities(ebos_simulator, well_state_copy, deferred_logger); const double dt = ebos_simulator.timeStepSize(); - const bool converged = this->iterateWellEquations(ebos_simulator, dt, well_state_copy, deferred_logger); + const bool converged = this->iterateWellEquations(ebos_simulator, dt, well_state_copy, group_state, deferred_logger); if (!converged) { const std::string msg = " well " + name() + " did not get converged during well testing for physical reason"; @@ -1574,6 +1580,7 @@ namespace Opm template bool WellInterface::checkConstraints(WellState& well_state, + const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, DeferredLogger& deferred_logger) const @@ -1582,7 +1589,7 @@ namespace Opm if (ind_broken) { return true; } else { - return checkGroupConstraints(well_state, schedule, summaryState, deferred_logger); + return checkGroupConstraints(well_state, group_state, schedule, summaryState, deferred_logger); } } @@ -1788,6 +1795,7 @@ namespace Opm template bool WellInterface::checkGroupConstraints(WellState& well_state, + const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, DeferredLogger& deferred_logger) const @@ -1808,7 +1816,7 @@ namespace Opm const auto& group = schedule.getGroup( well.groupName(), current_step_ ); const double efficiencyFactor = well.getEfficiencyFactor(); const std::pair group_constraint = checkGroupConstraintsInj( - group, well_state, efficiencyFactor, schedule, summaryState, deferred_logger); + group, well_state, group_state, efficiencyFactor, schedule, summaryState, deferred_logger); // If a group constraint was broken, we set the current well control to // be GRUP. if (group_constraint.first) { @@ -1835,7 +1843,7 @@ namespace Opm const auto& group = schedule.getGroup( well.groupName(), current_step_ ); const double efficiencyFactor = well.getEfficiencyFactor(); const std::pair group_constraint = checkGroupConstraintsProd( - group, well_state, efficiencyFactor, schedule, summaryState, deferred_logger); + group, well_state, group_state, efficiencyFactor, schedule, summaryState, deferred_logger); // If a group constraint was broken, we set the current well control to // be GRUP. if (group_constraint.first) { @@ -1860,6 +1868,7 @@ namespace Opm std::pair WellInterface::checkGroupConstraintsInj(const Group& group, const WellState& well_state, + const GroupState& group_state, const double efficiencyFactor, const Schedule& schedule, const SummaryState& summaryState, @@ -1898,6 +1907,7 @@ namespace Opm well_ecl_.groupName(), group, well_state, + group_state, current_step_, guide_rate_, well_state.wellRates().data() + index_of_well_ * phaseUsage().num_phases, @@ -1918,6 +1928,7 @@ namespace Opm std::pair WellInterface::checkGroupConstraintsProd(const Group& group, const WellState& well_state, + const GroupState& group_state, const double efficiencyFactor, const Schedule& schedule, const SummaryState& summaryState, @@ -1931,6 +1942,7 @@ namespace Opm well_ecl_.groupName(), group, well_state, + group_state, current_step_, guide_rate_, well_state.wellRates().data() + index_of_well_ * phaseUsage().num_phases, @@ -1950,6 +1962,7 @@ namespace Opm template void WellInterface::assembleControlEqInj(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const Well::InjectionControls& controls, @@ -2008,6 +2021,7 @@ namespace Opm const auto& group = schedule.getGroup(well_ecl_.groupName(), current_step_); getGroupInjectionControl(group, well_state, + group_state, schedule, summaryState, injectorType, @@ -2031,6 +2045,7 @@ namespace Opm template void WellInterface::assembleControlEqProd(const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const Well::ProductionControls& controls, @@ -2127,7 +2142,7 @@ namespace Opm active_rates[pu.phase_pos[canonical_phase]] = rates[canonical_phase]; } } - getGroupProductionControl(group, well_state, schedule, summaryState, bhp, active_rates, control_eq, efficiencyFactor); + getGroupProductionControl(group, well_state, group_state, schedule, summaryState, bhp, active_rates, control_eq, efficiencyFactor); break; } case Well::ProducerCMode::CMODE_UNDEFINED: { @@ -2146,6 +2161,7 @@ namespace Opm void WellInterface::getGroupInjectionControl(const Group& group, const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const InjectorType& injectorType, @@ -2179,7 +2195,7 @@ namespace Opm assert(false); } - const Group::InjectionCMode& currentGroupControl = well_state.currentInjectionGroupControl(injectionPhase, group.name()); + auto currentGroupControl = group_state.injection_control(group.name(), injectionPhase); if (currentGroupControl == Group::InjectionCMode::FLD || currentGroupControl == Group::InjectionCMode::NONE) { if (!group.injectionGroupControlAvailable(injectionPhase)) { @@ -2198,7 +2214,7 @@ namespace Opm // Inject share of parents control const auto& parent = schedule.getGroup( group.parent(), current_step_ ); efficiencyFactor *= group.getGroupEfficiencyFactor(); - getGroupInjectionControl(parent, well_state, schedule, summaryState, injectorType, bhp, injection_rate, control_eq, efficiencyFactor, deferred_logger); + getGroupInjectionControl(parent, well_state, group_state, schedule, summaryState, injectorType, bhp, injection_rate, control_eq, efficiencyFactor, deferred_logger); return; } } @@ -2226,15 +2242,15 @@ namespace Opm const auto& gconsale = schedule[current_step_].gconsale().get(group.name(), summaryState); sales_target = gconsale.sales_target; } - WellGroupHelpers::InjectionTargetCalculator tcalc(currentGroupControl, pu, resv_coeff, group.name(), sales_target, well_state, injectionPhase, deferred_logger); - WellGroupHelpers::FractionCalculator fcalc(schedule, summaryState, well_state, current_step_, guide_rate_, tcalc.guideTargetMode(), pu, false, injectionPhase); + WellGroupHelpers::InjectionTargetCalculator tcalc(currentGroupControl, pu, resv_coeff, group.name(), sales_target, well_state, group_state, injectionPhase, deferred_logger); + WellGroupHelpers::FractionCalculator fcalc(schedule, summaryState, well_state, group_state, current_step_, guide_rate_, tcalc.guideTargetMode(), pu, false, injectionPhase); auto localFraction = [&](const std::string& child) { return fcalc.localFraction(child, ""); }; auto localReduction = [&](const std::string& group_name) { - const std::vector& groupTargetReductions = well_state.currentInjectionGroupReductionRates(group_name); + const std::vector& groupTargetReductions = group_state.injection_reduction_rates(group_name); return tcalc.calcModeRateFromRates(groupTargetReductions); }; @@ -2265,6 +2281,7 @@ namespace Opm void WellInterface::getGroupProductionControl(const Group& group, const WellState& well_state, + const GroupState& group_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const EvalWell& bhp, @@ -2272,7 +2289,7 @@ namespace Opm EvalWell& control_eq, double efficiencyFactor) { - const Group::ProductionCMode& currentGroupControl = well_state.currentProductionGroupControl(group.name()); + const Group::ProductionCMode& currentGroupControl = group_state.production_control(group.name()); if (currentGroupControl == Group::ProductionCMode::FLD || currentGroupControl == Group::ProductionCMode::NONE) { if (!group.productionGroupControlAvailable()) { @@ -2291,7 +2308,7 @@ namespace Opm // Produce share of parents control const auto& parent = schedule.getGroup( group.parent(), current_step_ ); efficiencyFactor *= group.getGroupEfficiencyFactor(); - getGroupProductionControl(parent, well_state, schedule, summaryState, bhp, rates, control_eq, efficiencyFactor); + getGroupProductionControl(parent, well_state, group_state, schedule, summaryState, bhp, rates, control_eq, efficiencyFactor); return; } } @@ -2317,18 +2334,18 @@ namespace Opm // gconsale may adjust the grat target. // the adjusted rates is send to the targetCalculator double gratTargetFromSales = 0.0; - if (well_state.hasGroupGratTargetFromSales(group.name())) - gratTargetFromSales = well_state.currentGroupGratTargetFromSales(group.name()); + if (group_state.has_grat_sales_target(group.name())) + gratTargetFromSales = group_state.grat_sales_target(group.name()); WellGroupHelpers::TargetCalculator tcalc(currentGroupControl, pu, resv_coeff, gratTargetFromSales); - WellGroupHelpers::FractionCalculator fcalc(schedule, summaryState, well_state, current_step_, guide_rate_, tcalc.guideTargetMode(), pu, true, Phase::OIL); + WellGroupHelpers::FractionCalculator fcalc(schedule, summaryState, well_state, group_state, current_step_, guide_rate_, tcalc.guideTargetMode(), pu, true, Phase::OIL); auto localFraction = [&](const std::string& child) { return fcalc.localFraction(child, ""); }; auto localReduction = [&](const std::string& group_name) { - const std::vector& groupTargetReductions = well_state.currentProductionGroupReductionRates(group_name); + const std::vector& groupTargetReductions = group_state.production_reduction_rates(group_name); return tcalc.calcModeRateFromRates(groupTargetReductions); }; diff --git a/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp b/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp index ed86d2e75..1e37d7841 100644 --- a/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp +++ b/opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp @@ -22,7 +22,6 @@ #define OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED #include -#include #include #include @@ -70,9 +69,9 @@ namespace Opm using BaseType :: updateStatus; explicit WellStateFullyImplicitBlackoil(const PhaseUsage& pu) : - WellState(pu), - group_state(pu.num_phases) - {} + WellState(pu) + { + } /// Allocate and initialize if wells is non-null. Also tries @@ -412,32 +411,6 @@ namespace Opm std::vector& currentProductionControls() { return current_production_controls_; } const std::vector& currentProductionControls() const { return current_production_controls_; } - bool hasProductionGroupControl(const std::string& groupName) const { - return this->group_state.has_production_control(groupName); - } - - bool hasInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName) const { - return this->group_state.has_injection_control(groupName, phase); - } - - /// One current control per group. - void setCurrentProductionGroupControl(const std::string& groupName, const Group::ProductionCMode& groupControl ) { - this->group_state.production_control(groupName, groupControl); - } - - Group::ProductionCMode currentProductionGroupControl(const std::string& groupName) const { - return this->group_state.production_control(groupName); - } - - /// One current control per group. - void setCurrentInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName, const Group::InjectionCMode& groupControl ) { - this->group_state.injection_control(groupName, phase, groupControl); - } - - Group::InjectionCMode currentInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName) const { - return this->group_state.injection_control(groupName, phase); - } - void setCurrentWellRates(const std::string& wellName, const std::vector& rates ) { well_rates[wellName].second = rates; } @@ -455,78 +428,7 @@ namespace Opm return this->well_rates.find(wellName) != this->well_rates.end(); } - void setCurrentProductionGroupRates(const std::string& groupName, const std::vector& rates ) { - this->group_state.update_production_rates(groupName, rates); - } - const std::vector& currentProductionGroupRates(const std::string& groupName) const { - return this->group_state.production_rates(groupName); - } - - bool hasProductionGroupRates(const std::string& groupName) const { - return this->group_state.has_production_rates(groupName); - } - - - void setCurrentProductionGroupReductionRates(const std::string& groupName, const std::vector& target ) { - this->group_state.update_production_reduction_rates(groupName, target); - } - - const std::vector& currentProductionGroupReductionRates(const std::string& groupName) const { - return this->group_state.production_reduction_rates(groupName); - } - - void setCurrentInjectionGroupReductionRates(const std::string& groupName, const std::vector& target ) { - this->group_state.update_injection_reduction_rates(groupName, target); - } - - const std::vector& currentInjectionGroupReductionRates(const std::string& groupName) const { - return this->group_state.injection_reduction_rates(groupName); - } - - void setCurrentInjectionGroupReservoirRates(const std::string& groupName, const std::vector& target ) { - this->group_state.update_injection_reservoir_rates(groupName, target); - } - - const std::vector& currentInjectionGroupReservoirRates(const std::string& groupName) const { - return this->group_state.injection_reservoir_rates(groupName); - } - - void setCurrentInjectionVREPRates(const std::string& groupName, const double& target ) { - this->group_state.update_injection_vrep_rate(groupName, target); - } - - double currentInjectionVREPRates(const std::string& groupName) const { - return this->group_state.injection_vrep_rate(groupName); - } - - void setCurrentInjectionREINRates(const std::string& groupName, const std::vector& target ) { - this->group_state.update_injection_rein_rates(groupName, target); - } - - const std::vector& currentInjectionREINRates(const std::string& groupName) const { - return this->group_state.injection_rein_rates(groupName); - } - - void setCurrentGroupGratTargetFromSales(const std::string& groupName, const double& target ) { - this->group_state.update_grat_sales_target(groupName, target); - } - - bool hasGroupGratTargetFromSales(const std::string& groupName) const { - return this->group_state.has_grat_sales_target(groupName); - } - - double currentGroupGratTargetFromSales(const std::string& groupName) const { - return this->group_state.grat_sales_target(groupName); - } - - void setCurrentGroupInjectionPotentials(const std::string& groupName, const std::vector& pot ) { - this->group_state.update_injection_potentials(groupName, pot); - } - - const std::vector& currentGroupInjectionPotentials(const std::string& groupName) const { - return this->group_state.injection_potentials(groupName); - } data::Wells report(const int* globalCellIdxMap, @@ -1145,8 +1047,6 @@ namespace Opm x.second = data[pos++]; } assert(pos == sz); - - this->group_state.communicate_rates(comm); } template @@ -1299,6 +1199,7 @@ namespace Opm return it->first; } + private: std::vector perfphaserates_; std::vector is_producer_; // Size equal to number of local wells. @@ -1316,8 +1217,6 @@ namespace Opm std::map wellNameToGlobalIdx_; std::map>> well_rates; - GroupState group_state; - std::map current_alq_; std::map default_alq_; std::map alq_increase_count_;