not applying WECON RATE limit

when the well is under zero group target.
This commit is contained in:
Kai Bao 2024-06-12 13:17:54 +02:00
parent 54d303ae5d
commit 6ac7f8fdaf
9 changed files with 58 additions and 19 deletions

View File

@ -2211,7 +2211,8 @@ namespace Opm {
const auto& wname = well->name(); const auto& wname = well->name();
const auto wasClosed = wellTestState.well_is_closed(wname); const auto wasClosed = wellTestState.well_is_closed(wname);
well->checkWellOperability(simulator_, this->wellState(), local_deferredLogger); well->checkWellOperability(simulator_, this->wellState(), local_deferredLogger);
well->updateWellTestState(this->wellState().well(wname), simulationTime, /*writeMessageToOPMLog=*/ true, wellTestState, local_deferredLogger); const bool under_zero_target = well->wellUnderZeroGroupRateTarget(this->simulator_, this->wellState(), local_deferredLogger);
well->updateWellTestState(this->wellState().well(wname), simulationTime, /*writeMessageToOPMLog=*/ true, under_zero_target, wellTestState, local_deferredLogger);
if (!wasClosed && wellTestState.well_is_closed(wname)) { if (!wasClosed && wellTestState.well_is_closed(wname)) {
this->closed_this_step_.insert(wname); this->closed_this_step_.insert(wname);

View File

@ -229,6 +229,11 @@ public:
const WellState<Scalar>& well_state, const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
bool wellUnderZeroGroupRateTarget(const Simulator& simulator,
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger,
std::optional<bool> group_control = std::nullopt) const;
bool stoppedOrZeroRateTarget(const Simulator& simulator, bool stoppedOrZeroRateTarget(const Simulator& simulator,
const WellState<Scalar>& well_state, const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;

View File

@ -308,11 +308,11 @@ getGroupProductionTargetRate(const Group& group,
template<typename FluidSystem> template<typename FluidSystem>
bool bool
WellInterfaceFluidSystem<FluidSystem>:: WellInterfaceFluidSystem<FluidSystem>::
wellUnderZeroRateTargetGroup(const SummaryState& summary_state, zeroGroupRateTarget(const SummaryState& summary_state,
const Schedule& schedule, const Schedule& schedule,
const WellState<Scalar>& well_state, const WellState<Scalar>& well_state,
const GroupState<Scalar>& group_state, const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
const auto& well = this->well_ecl_; const auto& well = this->well_ecl_;
const auto& group = schedule.getGroup(well.groupName(), this->currentStep()); const auto& group = schedule.getGroup(well.groupName(), this->currentStep());

View File

@ -117,11 +117,11 @@ protected:
Scalar efficiencyFactor, Scalar efficiencyFactor,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
bool wellUnderZeroRateTargetGroup(const SummaryState& summary_state, bool zeroGroupRateTarget(const SummaryState& summary_state,
const Schedule& schedule, const Schedule& schedule,
const WellState<Scalar>& well_state, const WellState<Scalar>& well_state,
const GroupState<Scalar>& group_state, const GroupState<Scalar>& group_state,
DeferredLogger& deferredLogger) const; DeferredLogger& deferredLogger) const;
// For the conversion between the surface volume rate and reservoir voidage rate // For the conversion between the surface volume rate and reservoir voidage rate
const RateConverterType& rateConverter_; const RateConverterType& rateConverter_;

View File

@ -298,12 +298,14 @@ void WellInterfaceGeneric<Scalar>::
updateWellTestState(const SingleWellState<Scalar>& ws, updateWellTestState(const SingleWellState<Scalar>& ws,
const double& simulationTime, const double& simulationTime,
const bool& writeMessageToOPMLog, const bool& writeMessageToOPMLog,
const bool zero_group_target,
WellTestState& wellTestState, WellTestState& wellTestState,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
// updating well test state based on Economic limits for operable wells // updating well test state based on Economic limits for operable wells
if (this->isOperableAndSolvable()) { if (this->isOperableAndSolvable()) {
WellTest(*this).updateWellTestStateEconomic(ws, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); WellTest(*this).updateWellTestStateEconomic(ws, simulationTime, writeMessageToOPMLog, wellTestState,
zero_group_target, deferred_logger);
} else { } else {
// updating well test state based on physical (THP/BHP) limits. // updating well test state based on physical (THP/BHP) limits.
WellTest(*this).updateWellTestStatePhysical(simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); WellTest(*this).updateWellTestStatePhysical(simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger);
@ -620,6 +622,16 @@ wellUnderZeroRateTargetIndividual(const SummaryState& summary_state,
} }
} }
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
wellUnderGroupControl(const SingleWellState<Scalar>& ws) const
{
// Check if well is under group control
const bool isGroupControlled = (this->isInjector() && ws.injection_cmode == Well::InjectorCMode::GRUP) ||
(this->isProducer() && ws.production_cmode == Well::ProducerCMode::GRUP);
return isGroupControlled;
}
template<class Scalar> template<class Scalar>
void WellInterfaceGeneric<Scalar>::resetWellOperability() void WellInterfaceGeneric<Scalar>::resetWellOperability()
{ {

View File

@ -168,6 +168,7 @@ public:
void updateWellTestState(const SingleWellState<Scalar>& ws, void updateWellTestState(const SingleWellState<Scalar>& ws,
const double& simulationTime, const double& simulationTime,
const bool& writeMessageToOPMLog, const bool& writeMessageToOPMLog,
const bool zero_group_target,
WellTestState& wellTestState, WellTestState& wellTestState,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
@ -200,6 +201,8 @@ protected:
bool wellUnderZeroRateTargetIndividual(const SummaryState& summary_state, bool wellUnderZeroRateTargetIndividual(const SummaryState& summary_state,
const WellState<Scalar>& well_state) const; const WellState<Scalar>& well_state) const;
bool wellUnderGroupControl(const SingleWellState<Scalar>& ws) const;
std::pair<bool,bool> std::pair<bool,bool>
computeWellPotentials(std::vector<Scalar>& well_potentials, computeWellPotentials(std::vector<Scalar>& well_potentials,
const WellState<Scalar>& well_state); const WellState<Scalar>& well_state);

View File

@ -431,9 +431,11 @@ namespace Opm
for (int p = 0; p < np; ++p) { for (int p = 0; p < np; ++p) {
ws.well_potentials[p] = std::max(Scalar{0.0}, potentials[p]); ws.well_potentials[p] = std::max(Scalar{0.0}, potentials[p]);
} }
const bool under_zero_target = this->wellUnderZeroGroupRateTarget(simulator, well_state_copy, deferred_logger);
this->updateWellTestState(well_state_copy.well(this->indexOfWell()), this->updateWellTestState(well_state_copy.well(this->indexOfWell()),
simulation_time, simulation_time,
/*writeMessageToOPMLog=*/ false, /*writeMessageToOPMLog=*/ false,
under_zero_target,
welltest_state_temp, welltest_state_temp,
deferred_logger); deferred_logger);
this->closeCompletions(welltest_state_temp); this->closeCompletions(welltest_state_temp);
@ -1440,19 +1442,32 @@ namespace Opm
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
// Check if well is under zero rate control, either directly or from group // Check if well is under zero rate control, either directly or from group
const auto& ws = well_state.well(this->index_of_well_); const bool isGroupControlled = this->wellUnderGroupControl(well_state.well(this->index_of_well_));
const bool isGroupControlled = (this->isInjector() && ws.injection_cmode == Well::InjectorCMode::GRUP) ||
(this->isProducer() && ws.production_cmode == Well::ProducerCMode::GRUP);
if (!isGroupControlled) { if (!isGroupControlled) {
// well is not under group control, check "individual" version // well is not under group control, check "individual" version
const auto& summaryState = simulator.vanguard().summaryState(); const auto& summaryState = simulator.vanguard().summaryState();
return this->wellUnderZeroRateTargetIndividual(summaryState, well_state); return this->wellUnderZeroRateTargetIndividual(summaryState, well_state);
} else { } else {
return this->wellUnderZeroGroupRateTarget(simulator, well_state, deferred_logger, isGroupControlled);
}
}
template <typename TypeTag>
bool
WellInterface<TypeTag>::wellUnderZeroGroupRateTarget(const Simulator& simulator,
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger,
const std::optional<bool> group_control) const
{
// Check if well is under zero rate target from group
const bool isGroupControlled = group_control.value_or(this->wellUnderGroupControl(well_state.well(this->index_of_well_)));
if (isGroupControlled) {
const auto& summaryState = simulator.vanguard().summaryState(); const auto& summaryState = simulator.vanguard().summaryState();
const auto& group_state = simulator.problem().wellModel().groupState(); const auto& group_state = simulator.problem().wellModel().groupState();
const auto& schedule = simulator.vanguard().schedule(); const auto& schedule = simulator.vanguard().schedule();
return this->wellUnderZeroRateTargetGroup(summaryState, schedule, well_state, group_state, deferred_logger); return this->zeroGroupRateTarget(summaryState, schedule, well_state, group_state, deferred_logger);
} }
return false;
} }
template<typename TypeTag> template<typename TypeTag>

View File

@ -310,6 +310,7 @@ updateWellTestStateEconomic(const SingleWellState<Scalar>& ws,
const double simulation_time, const double simulation_time,
const bool write_message_to_opmlog, const bool write_message_to_opmlog,
WellTestState& well_test_state, WellTestState& well_test_state,
const bool zero_group_target,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
if (well_.wellIsStopped()) if (well_.wellIsStopped())
@ -346,9 +347,10 @@ updateWellTestStateEconomic(const SingleWellState<Scalar>& ws,
deferred_logger); deferred_logger);
} }
else { else {
rate_limit_violated = this->checkRateEconLimits(econ_production_limits, if (!zero_group_target) {
ws.surface_rates, rate_limit_violated
deferred_logger); = this->checkRateEconLimits(econ_production_limits, ws.surface_rates, deferred_logger);
}
} }
} }

View File

@ -48,6 +48,7 @@ public:
const double simulation_time, const double simulation_time,
const bool write_message_to_opmlog, const bool write_message_to_opmlog,
WellTestState& well_test_state, WellTestState& well_test_state,
bool zero_group_target,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
void updateWellTestStatePhysical(const double simulation_time, void updateWellTestStatePhysical(const double simulation_time,