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 wasClosed = wellTestState.well_is_closed(wname);
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)) {
this->closed_this_step_.insert(wname);

View File

@ -229,6 +229,11 @@ public:
const WellState<Scalar>& well_state,
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,
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const;

View File

@ -308,7 +308,7 @@ getGroupProductionTargetRate(const Group& group,
template<typename FluidSystem>
bool
WellInterfaceFluidSystem<FluidSystem>::
wellUnderZeroRateTargetGroup(const SummaryState& summary_state,
zeroGroupRateTarget(const SummaryState& summary_state,
const Schedule& schedule,
const WellState<Scalar>& well_state,
const GroupState<Scalar>& group_state,

View File

@ -117,7 +117,7 @@ protected:
Scalar efficiencyFactor,
DeferredLogger& deferred_logger) const;
bool wellUnderZeroRateTargetGroup(const SummaryState& summary_state,
bool zeroGroupRateTarget(const SummaryState& summary_state,
const Schedule& schedule,
const WellState<Scalar>& well_state,
const GroupState<Scalar>& group_state,

View File

@ -298,12 +298,14 @@ void WellInterfaceGeneric<Scalar>::
updateWellTestState(const SingleWellState<Scalar>& ws,
const double& simulationTime,
const bool& writeMessageToOPMLog,
const bool zero_group_target,
WellTestState& wellTestState,
DeferredLogger& deferred_logger) const
{
// updating well test state based on Economic limits for operable wells
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 {
// updating well test state based on physical (THP/BHP) limits.
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>
void WellInterfaceGeneric<Scalar>::resetWellOperability()
{

View File

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

View File

@ -431,9 +431,11 @@ namespace Opm
for (int p = 0; p < np; ++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()),
simulation_time,
/*writeMessageToOPMLog=*/ false,
under_zero_target,
welltest_state_temp,
deferred_logger);
this->closeCompletions(welltest_state_temp);
@ -1440,19 +1442,32 @@ namespace Opm
DeferredLogger& deferred_logger) const
{
// 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->isInjector() && ws.injection_cmode == Well::InjectorCMode::GRUP) ||
(this->isProducer() && ws.production_cmode == Well::ProducerCMode::GRUP);
const bool isGroupControlled = this->wellUnderGroupControl(well_state.well(this->index_of_well_));
if (!isGroupControlled) {
// well is not under group control, check "individual" version
const auto& summaryState = simulator.vanguard().summaryState();
return this->wellUnderZeroRateTargetIndividual(summaryState, well_state);
} 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& group_state = simulator.problem().wellModel().groupState();
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>

View File

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

View File

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