Merge pull request #6051 from totto82/use_status_ws

Check status from wellstate not the well object from Schedule
This commit is contained in:
Kai Bao authored and GitHub committed 2025-08-19 11:16:13 +02:00
commit 5e65e7ac84
6 files changed
+66 -44

No files matched your search

@@ -1129,25 +1129,16 @@ assignDynamicWellStatus(data::Wells& wsrpt,
const int reportStepIndex) const
{
this->loopOwnedWells([this, reportStepIndex, &wsrpt]
(const auto wellID, const Well& well)
(const auto wellID,
const Well& well)
{
auto& xwel = wsrpt[well.name()]; // data::Wells is a std::map<>
xwel.dynamicStatus = this->wellState().well(well.name()).status;
xwel.dynamicStatus = this->schedule()[reportStepIndex]
.wells(well.name()).getStatus();
if ((xwel.dynamicStatus == Well::Status::OPEN) &&
this->wellTestState().well_is_closed(well.name()) &&
!this->wasDynamicallyShutThisTimeStep(wellID))
{
// Well is supposed to be flowing according to the run
// specification (Schedule object), but it is not operable or
// cannot meet its economic limits (well testing).
//
// Assign status based on the well's defined automatic shut-in
// procedure.
xwel.dynamicStatus = well.getAutomaticShutIn()
? Well::Status::SHUT : Well::Status::STOP;
// Well was shut this time step we keep it open one last time
// for output
if (wasDynamicallyShutThisTimeStep(wellID)) {
xwel.dynamicStatus = Well::Status::OPEN;
}
});
}
+3 -2
View File
@@ -752,8 +752,6 @@ updateProductionGroupPotentialFromSubGroups(const Group& group, std::vector<Scal
if (well_tmp.isInjector())
continue;
if (well_tmp.getStatus() == Well::Status::SHUT)
continue;
const auto& well_index = this->well_state_.index(well_name);
if (!well_index.has_value()) // the well is not found
continue;
@@ -764,6 +762,9 @@ updateProductionGroupPotentialFromSubGroups(const Group& group, std::vector<Scal
}
const auto& ws = this->well_state_.well(well_index.value());
if (ws.status == Well::Status::SHUT)
continue;
for (int phase = 0; phase < this->num_phases_; phase++) {
pot[phase] += wefac * ws.well_potentials[phase];
}
@@ -1638,9 +1638,8 @@ namespace Opm
// if we fail to solve eqs, we reset status/operability before leaving
const auto well_status_orig = this->wellStatus_;
const auto operability_orig = this->operability_status_;
// don't allow opening wells that are stopped from schedule or has a stopped well state
const bool allow_open = this->well_ecl_.getStatus() == WellStatus::OPEN &&
well_state.well(this->index_of_well_).status == WellStatus::OPEN;
// don't allow opening wells that has a stopped well status
const bool allow_open = well_state.well(this->index_of_well_).status == WellStatus::OPEN;
// don't allow switcing for wells under zero rate target or requested fixed status and control
const bool allow_switching = !this->wellUnderZeroRateTarget(simulator, well_state, deferred_logger) &&
(!fixed_control || !fixed_status) && allow_open;
+2 -3
View File
@@ -2392,9 +2392,8 @@ namespace Opm
const auto operability_orig = this->operability_status_;
auto well_status_cur = well_status_orig;
int status_switch_count = 0;
// don't allow opening wells that are stopped from schedule or has a stopped well state
const bool allow_open = this->well_ecl_.getStatus() == WellStatus::OPEN &&
well_state.well(this->index_of_well_).status == WellStatus::OPEN;
// don't allow opening wells that has a stopped well status
const bool allow_open = well_state.well(this->index_of_well_).status == WellStatus::OPEN;
// don't allow switcing for wells under zero rate target or requested fixed status and control
const bool allow_switching =
!this->wellUnderZeroRateTarget(simulator, well_state, deferred_logger) &&
+49 -18
View File
@@ -115,7 +115,7 @@ namespace Opm {
}
for (const std::string& wellName : group.wells()) {
const auto& well_index = wellState.index(wellName);
const auto well_index = wellState.index(wellName);
if (!well_index.has_value())
continue;
@@ -129,11 +129,11 @@ namespace Opm {
if ((wellEcl.isProducer() && injector) || (wellEcl.isInjector() && !injector))
continue;
if (wellEcl.getStatus() == Opm::Well::Status::SHUT)
const auto& ws = wellState.well(well_index.value());
if (ws.status == Opm::Well::Status::SHUT)
continue;
const Scalar factor = wellEcl.getEfficiencyFactor(network) * wellState[wellEcl.name()].efficiency_scaling_factor;
const auto& ws = wellState.well(well_index.value());
if (res_rates) {
const auto& well_rates = ws.reservoir_rates;
if (injector)
@@ -300,7 +300,7 @@ sumSolventRates(const Group& group,
}
for (const std::string& wellName : group.wells()) {
const auto& well_index = wellState.index(wellName);
const auto well_index = wellState.index(wellName);
if (!well_index.has_value())
continue;
@@ -314,10 +314,11 @@ sumSolventRates(const Group& group,
if ((wellEcl.isProducer() && injector) || (wellEcl.isInjector() && !injector))
continue;
if (wellEcl.getStatus() == Well::Status::SHUT)
const auto& ws = wellState.well(well_index.value());
if (ws.status == Well::Status::SHUT)
continue;
const auto& ws = wellState.well(well_index.value());
const Scalar factor = wellEcl.getEfficiencyFactor() *
wellState[wellEcl.name()].efficiency_scaling_factor;
if (injector)
@@ -450,18 +451,23 @@ updateGroupTargetReduction(const Group& group,
if (wellTmp.isInjector() && !isInjector)
continue;
if (wellTmp.getStatus() == Well::Status::SHUT)
const auto well_index = wellState.index(wellName);
if (!well_index.has_value())
continue;
const auto& well_index = wellState.index(wellName);
if (!well_index.has_value())
if (! wellState.wellIsOwned(well_index.value(), wellName) ) // Only sum once
{
continue;
}
const auto& ws = wellState.well(well_index.value());
if (ws.status == Well::Status::SHUT)
continue;
const Scalar efficiency = wellTmp.getEfficiencyFactor() *
wellState[wellTmp.name()].efficiency_scaling_factor;
// add contribution from wells not under group control
const auto& ws = wellState.well(well_index.value());
if (isInjector) {
if (ws.injection_cmode != Well::InjectorCMode::GRUP)
for (int phase = 0; phase < np; phase++) {
@@ -525,15 +531,20 @@ updateWellRatesFromGroupTargetScale(const Scalar scale,
if (wellTmp.isInjector() && !isInjector)
continue;
if (wellTmp.getStatus() == Well::Status::SHUT)
continue;
const auto& well_index = wellState.index(wellName);
const auto well_index = wellState.index(wellName);
if (!well_index.has_value())
continue;
// scale rates
if (! wellState.wellIsOwned(well_index.value(), wellName) ) // Only sum once
{
continue;
}
auto& ws = wellState.well(well_index.value());
if (ws.status == Well::Status::SHUT)
continue;
// scale rates
if (isInjector) {
if (ws.injection_cmode == Well::InjectorCMode::GRUP)
for (int phase = 0; phase < np; phase++) {
@@ -648,7 +659,7 @@ updateWellRates(const Group& group,
const int np = wellState.numPhases();
for (const std::string& wellName : group.wells()) {
std::vector<Scalar> rates(np, 0.0);
const auto& well_index = wellState.index(wellName);
const auto well_index = wellState.index(wellName);
if (well_index.has_value()) { // the well is found on this node
const auto& wellTmp = schedule.getWell(wellName, reportStepIdx);
int sign = 1;
@@ -1059,7 +1070,17 @@ getGuideRate(const std::string& name,
if (wellTmp.isInjector())
continue;
if (wellTmp.getStatus() == Well::Status::SHUT)
const auto well_index = wellState.index(wellName);
if (!well_index.has_value())
continue;
if (! wellState.wellIsOwned(well_index.value(), wellName) ) // Only sum once
{
continue;
}
const auto& ws = wellState.well(well_index.value());
if (ws.status == Well::Status::SHUT)
continue;
// Only count wells under group control or the ru
@@ -1113,7 +1134,17 @@ getGuideRateInj(const std::string& name,
if (!wellTmp.isInjector())
continue;
if (wellTmp.getStatus() == Well::Status::SHUT)
const auto well_index = wellState.index(wellName);
if (!well_index.has_value())
continue;
if (! wellState.wellIsOwned(well_index.value(), wellName) ) // Only sum once
{
continue;
}
const auto& ws = wellState.well(well_index.value());
if (ws.status == Well::Status::SHUT)
continue;
// Only count wells under group control or the ru
+3 -2
View File
@@ -292,7 +292,8 @@ namespace Opm
from = WellProducerCMode2String(ws.production_cmode);
}
const bool oscillating = std::count(this->well_control_log_.begin(), this->well_control_log_.end(), from) >= this->param_.max_number_of_well_switches_;
if (oscillating || this->wellUnderZeroRateTarget(simulator, well_state, deferred_logger) || !(this->well_ecl_.getStatus() == WellStatus::OPEN)) {
if (oscillating || this->wellUnderZeroRateTarget(simulator, well_state, deferred_logger) || !(well_state.well(this->index_of_well_).status == WellStatus::OPEN)) {
return false;
}
@@ -519,7 +520,7 @@ namespace Opm
if (!this->param_.local_well_solver_control_switching_){
converged = this->iterateWellEqWithControl(simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
} else {
if (this->param_.use_implicit_ipr_ && this->well_ecl_.isProducer() && (this->well_ecl_.getStatus() == WellStatus::OPEN)) {
if (this->param_.use_implicit_ipr_ && this->well_ecl_.isProducer() && (well_state.well(this->index_of_well_).status == WellStatus::OPEN)) {
converged = solveWellWithOperabilityCheck(simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
} else {
converged = this->iterateWellEqWithSwitching(simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);