Extract group state and create WGState to manage well & group state

This commit is contained in:
Joakim Hove 2021-04-22 17:31:21 +02:00
parent 42a6505cf1
commit e1d117c59f
19 changed files with 406 additions and 337 deletions

View File

@ -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

View File

@ -34,6 +34,7 @@
#include <opm/models/utils/alignedallocator.hh>
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
#include <opm/simulators/wells/WGState.hpp>
#include <opm/material/fluidstates/CompositionalFluidState.hpp>
#include <opm/material/densead/Evaluation.hpp>
#include <opm/material/densead/Math.hpp>
@ -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");
}

View File

@ -1414,7 +1414,7 @@ public:
the next timestep we must commit it.
*/
if (commit_wellstate)
this->wellModel_.commitWellState();
this->wellModel_.commitWGState();
}

View File

@ -37,6 +37,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
#include <opm/simulators/wells/WGState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
@ -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

View File

@ -59,6 +59,7 @@
#include <opm/simulators/wells/VFPInjProperties.hpp>
#include <opm/simulators/wells/VFPProdProperties.hpp>
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
#include <opm/simulators/wells/WGState.hpp>
#include <opm/simulators/wells/RateConverter.hpp>
#include <opm/simulators/wells/WellInterface.hpp>
#include <opm/simulators/wells/StandardWell.hpp>
@ -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<std::string>& switched_groups);
void checkGroupHigherConstraints(const Group& group, Opm::DeferredLogger& deferred_logger, std::set<std::string>& 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_;
};

View File

@ -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<double> 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<TypeTag>::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<TypeTag>::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<double> 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<double> 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<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
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<TypeTag>::
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<TypeTag>::
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<bool, double> 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<bool, double> 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);

View File

@ -25,6 +25,7 @@
#include <opm/core/props/BlackoilPhases.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
namespace Opm {
@ -163,7 +164,7 @@ private:
std::map<std::string, double> m_grat_sales_target;
std::map<std::pair<Opm::Phase, std::string>, Group::InjectionCMode> injection_controls;
std::map<std::pair<Phase, std::string>, Group::InjectionCMode> injection_controls;
};
}

View File

@ -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;

View File

@ -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<TypeTag>::
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);

View File

@ -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,

View File

@ -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 <typename TypeTag>
void
StandardWell<TypeTag>::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);

View File

@ -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<double>& group_injection_reductions
= well_state_.currentInjectionGroupReductionRates(group_name_);
double voidage_rate
= well_state_.currentInjectionVREPRates(ctrl.voidage_group) * ctrl.target_void_fraction;
const std::vector<double>& 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_;

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <opm/core/props/BlackoilPhases.hpp>
#include <opm/simulators/wells/WGState.hpp>
namespace Opm {
WGState::WGState(const PhaseUsage& pu) :
well_state(pu),
group_state(pu.num_phases)
{}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_WGSTATE_HEADER_INCLUDED
#define OPM_WGSTATE_HEADER_INCLUDED
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
#include <opm/simulators/wells/GroupState.hpp>
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

View File

@ -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<double>& injRES = wellState.currentInjectionGroupReservoirRates(group.name());
guideRateValue = group_state.injection_vrep_rate(group.name());
const std::vector<double>& 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<double>& 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<double> 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<double> 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<double> 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<std::string, double>
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<std::string, std::vector<double>> 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<double>& groupTargetReductions
= wellState.currentProductionGroupReductionRates(group_name);
const std::vector<double>& 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<double>& groupTargetReductions
= wellState.currentInjectionGroupReductionRates(group_name);
const std::vector<double>& 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]);

View File

@ -28,6 +28,7 @@
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/simulators/wells/VFPProdProperties.hpp>
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <algorithm>
#include <cassert>
@ -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<double>& groupTargetReduction);
template <class Comm>
@ -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<double>& 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<std::string, double>
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,

View File

@ -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<bool>& 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<bool, double> 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<bool, double> 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 <class EvalWell>
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 <class EvalWell>
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 <class EvalWell, class BhpFromThpFunc>
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 <class EvalWell, class BhpFromThpFunc>
void assembleControlEqProd(const WellState& well_state,
const GroupState& group_state,
const Opm::Schedule& schedule,
const SummaryState& summaryState,
const Well::ProductionControls& controls,

View File

@ -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<TypeTag>::
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<typename TypeTag>
void
WellInterface<TypeTag>::
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<TypeTag>::
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<TypeTag>::
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 <typename TypeTag>
bool
WellInterface<TypeTag>::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 <typename TypeTag>
bool
WellInterface<TypeTag>::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<bool, double> 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<bool, double> 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<bool, double>
WellInterface<TypeTag>::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<bool, double>
WellInterface<TypeTag>::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 <class EvalWell, class BhpFromThpFunc>
void
WellInterface<TypeTag>::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 <class EvalWell, class BhpFromThpFunc>
void
WellInterface<TypeTag>::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<TypeTag>::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<double>& groupTargetReductions = well_state.currentInjectionGroupReductionRates(group_name);
const std::vector<double>& groupTargetReductions = group_state.injection_reduction_rates(group_name);
return tcalc.calcModeRateFromRates(groupTargetReductions);
};
@ -2265,6 +2281,7 @@ namespace Opm
void
WellInterface<TypeTag>::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<double>& groupTargetReductions = well_state.currentProductionGroupReductionRates(group_name);
const std::vector<double>& groupTargetReductions = group_state.production_reduction_rates(group_name);
return tcalc.calcModeRateFromRates(groupTargetReductions);
};

View File

@ -22,7 +22,6 @@
#define OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <opm/core/props/BlackoilPhases.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
@ -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<Well::ProducerCMode>& currentProductionControls() { return current_production_controls_; }
const std::vector<Well::ProducerCMode>& 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<double>& 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<double>& rates ) {
this->group_state.update_production_rates(groupName, rates);
}
const std::vector<double>& 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<double>& target ) {
this->group_state.update_production_reduction_rates(groupName, target);
}
const std::vector<double>& currentProductionGroupReductionRates(const std::string& groupName) const {
return this->group_state.production_reduction_rates(groupName);
}
void setCurrentInjectionGroupReductionRates(const std::string& groupName, const std::vector<double>& target ) {
this->group_state.update_injection_reduction_rates(groupName, target);
}
const std::vector<double>& currentInjectionGroupReductionRates(const std::string& groupName) const {
return this->group_state.injection_reduction_rates(groupName);
}
void setCurrentInjectionGroupReservoirRates(const std::string& groupName, const std::vector<double>& target ) {
this->group_state.update_injection_reservoir_rates(groupName, target);
}
const std::vector<double>& 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<double>& target ) {
this->group_state.update_injection_rein_rates(groupName, target);
}
const std::vector<double>& 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<double>& pot ) {
this->group_state.update_injection_potentials(groupName, pot);
}
const std::vector<double>& 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<class Comm>
@ -1299,6 +1199,7 @@ namespace Opm
return it->first;
}
private:
std::vector<double> perfphaserates_;
std::vector<bool> is_producer_; // Size equal to number of local wells.
@ -1316,8 +1217,6 @@ namespace Opm
std::map<std::string, int> wellNameToGlobalIdx_;
std::map<std::string, std::pair<bool, std::vector<double>>> well_rates;
GroupState group_state;
std::map<std::string, double> current_alq_;
std::map<std::string, double> default_alq_;
std::map<std::string, int> alq_increase_count_;