mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-27 09:40:59 -06:00
Merge pull request #3569 from totto82/operInj
check operability injectors
This commit is contained in:
commit
d925e74b76
@ -316,10 +316,10 @@ namespace Opm
|
||||
double maxPerfPress(const Simulator& ebos_simulator) const;
|
||||
|
||||
// check whether the well is operable under BHP limit with current reservoir condition
|
||||
virtual void checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
|
||||
virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
|
||||
|
||||
// check whether the well is operable under THP limit with current reservoir condition
|
||||
virtual void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
|
||||
virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
|
||||
|
||||
// updating the inflow based on the current reservoir condition
|
||||
virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const override;
|
||||
|
@ -1128,7 +1128,7 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
checkOperabilityUnderBHPLimitProducer(const WellState& /*well_state*/, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
|
||||
checkOperabilityUnderBHPLimit(const WellState& /*well_state*/, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
|
||||
{
|
||||
const auto& summaryState = ebos_simulator.vanguard().summaryState();
|
||||
const double bhp_limit = Base::mostStrictBhpFromBhpLimits(summaryState);
|
||||
@ -1139,11 +1139,11 @@ namespace Opm
|
||||
// if the BHP limit is not defaulted or the well does not have a THP limit
|
||||
// we need to check the BHP limit
|
||||
|
||||
double temp = 0;
|
||||
double ipr_rate = 0;
|
||||
for (int p = 0; p < this->number_of_phases_; ++p) {
|
||||
temp += this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
|
||||
ipr_rate += this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
|
||||
}
|
||||
if (temp < 0.) {
|
||||
if ( (this->isProducer() && ipr_rate < 0.) || (this->isInjector() && ipr_rate > 0.) ) {
|
||||
this->operability_status_.operable_under_only_bhp_limit = false;
|
||||
}
|
||||
|
||||
@ -1156,10 +1156,8 @@ namespace Opm
|
||||
computeWellRatesWithBhp(ebos_simulator, bhp_limit, well_rates_bhp_limit, deferred_logger);
|
||||
|
||||
const double thp = this->calculateThpFromBhp(well_rates_bhp_limit, bhp_limit, getRefDensity(), deferred_logger);
|
||||
|
||||
const double thp_limit = this->getTHPConstraint(summaryState);
|
||||
|
||||
if (thp < thp_limit) {
|
||||
if ( (this->isProducer() && thp < thp_limit) || (this->isInjector() && thp > thp_limit) ) {
|
||||
this->operability_status_.obey_thp_limit_under_bhp_limit = false;
|
||||
}
|
||||
}
|
||||
@ -1185,12 +1183,6 @@ namespace Opm
|
||||
{
|
||||
// TODO: not handling solvent related here for now
|
||||
|
||||
// TODO: it only handles the producers for now
|
||||
// the formular for the injectors are not formulated yet
|
||||
if (this->isInjector()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize all the values to be zero to begin with
|
||||
std::fill(this->ipr_a_.begin(), this->ipr_a_.end(), 0.);
|
||||
std::fill(this->ipr_b_.begin(), this->ipr_b_.end(), 0.);
|
||||
@ -1234,12 +1226,10 @@ namespace Opm
|
||||
const double h_perf = cell_perf_press_diff + perf_seg_press_diff + seg_bhp_press_diff;
|
||||
const double pressure_diff = pressure_cell - h_perf;
|
||||
|
||||
// Let us add a check, since the pressure is calculated based on zero value BHP
|
||||
// it should not be negative anyway. If it is negative, we might need to re-formulate
|
||||
// to taking into consideration the crossflow here.
|
||||
if (pressure_diff <= 0.) {
|
||||
deferred_logger.warning("NON_POSITIVE_DRAWDOWN_IPR",
|
||||
"non-positive drawdown found when updateIPR for well " + this->name());
|
||||
// do not take into consideration the crossflow here.
|
||||
if ( (this->isProducer() && pressure_diff < 0.) || (this->isInjector() && pressure_diff > 0.) ) {
|
||||
deferred_logger.debug("CROSSFLOW_IPR",
|
||||
"cross flow found when updateIPR for well " + this->name());
|
||||
}
|
||||
|
||||
// the well index associated with the connection
|
||||
@ -1288,10 +1278,11 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& /*well_state*/, DeferredLogger& deferred_logger)
|
||||
checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& /*well_state*/, DeferredLogger& deferred_logger)
|
||||
{
|
||||
const auto& summaryState = ebos_simulator.vanguard().summaryState();
|
||||
const auto obtain_bhp = computeBhpAtThpLimitProd(ebos_simulator, summaryState, deferred_logger);
|
||||
const auto obtain_bhp = this->isProducer() ? computeBhpAtThpLimitProd(ebos_simulator, summaryState, deferred_logger)
|
||||
: computeBhpAtThpLimitInj(ebos_simulator, summaryState, deferred_logger);
|
||||
|
||||
if (obtain_bhp) {
|
||||
this->operability_status_.can_obtain_bhp_with_thp_limit = true;
|
||||
@ -1300,13 +1291,20 @@ namespace Opm
|
||||
this->operability_status_.obey_bhp_limit_with_thp_limit = (*obtain_bhp >= bhp_limit);
|
||||
|
||||
const double thp_limit = this->getTHPConstraint(summaryState);
|
||||
if (*obtain_bhp < thp_limit) {
|
||||
if (this->isProducer() && *obtain_bhp < thp_limit) {
|
||||
const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
|
||||
+ " bars is SMALLER than thp limit "
|
||||
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
|
||||
+ " bars as a producer for well " + this->name();
|
||||
deferred_logger.debug(msg);
|
||||
}
|
||||
else if (this->isInjector() && *obtain_bhp > thp_limit) {
|
||||
const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
|
||||
+ " bars is LARGER than thp limit "
|
||||
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
|
||||
+ " bars as a injector for well " + this->name();
|
||||
deferred_logger.debug(msg);
|
||||
}
|
||||
} else {
|
||||
// Shutting wells that can not find bhp value from thp
|
||||
// when under THP control
|
||||
|
@ -394,10 +394,10 @@ namespace Opm
|
||||
DeferredLogger& deferred_logger) const;
|
||||
|
||||
// check whether the well is operable under BHP limit with current reservoir condition
|
||||
virtual void checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
|
||||
virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
|
||||
|
||||
// check whether the well is operable under THP limit with current reservoir condition
|
||||
virtual void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
|
||||
virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
|
||||
|
||||
// updating the inflow based on the current reservoir condition
|
||||
virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const override;
|
||||
|
@ -952,12 +952,6 @@ namespace Opm
|
||||
{
|
||||
// TODO: not handling solvent related here for now
|
||||
|
||||
// TODO: it only handles the producers for now
|
||||
// the formular for the injectors are not formulated yet
|
||||
if (this->isInjector()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize all the values to be zero to begin with
|
||||
std::fill(this->ipr_a_.begin(), this->ipr_a_.end(), 0.);
|
||||
std::fill(this->ipr_b_.begin(), this->ipr_b_.end(), 0.);
|
||||
@ -990,9 +984,9 @@ namespace Opm
|
||||
// Let us add a check, since the pressure is calculated based on zero value BHP
|
||||
// it should not be negative anyway. If it is negative, we might need to re-formulate
|
||||
// to taking into consideration the crossflow here.
|
||||
if (pressure_diff <= 0.) {
|
||||
deferred_logger.warning("NON_POSITIVE_DRAWDOWN_IPR",
|
||||
"non-positive drawdown found when updateIPR for well " + name());
|
||||
if ( (this->isProducer() && pressure_diff < 0.) || (this->isInjector() && pressure_diff > 0.) ) {
|
||||
deferred_logger.debug("CROSSFLOW_IPR",
|
||||
"cross flow found when updateIPR for well " + name());
|
||||
}
|
||||
|
||||
// the well index associated with the connection
|
||||
@ -1043,7 +1037,7 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
StandardWell<TypeTag>::
|
||||
checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
|
||||
checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
|
||||
{
|
||||
const auto& summaryState = ebos_simulator.vanguard().summaryState();
|
||||
const double bhp_limit = this->mostStrictBhpFromBhpLimits(summaryState);
|
||||
@ -1055,8 +1049,8 @@ namespace Opm
|
||||
// we need to check the BHP limit
|
||||
|
||||
for (int p = 0; p < this->number_of_phases_; ++p) {
|
||||
const double temp = this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
|
||||
if (temp < 0.) {
|
||||
const double ipr_rate = this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
|
||||
if ( (this->isProducer() && ipr_rate < 0.) || (this->isInjector() && ipr_rate > 0.) ) {
|
||||
this->operability_status_.operable_under_only_bhp_limit = false;
|
||||
break;
|
||||
}
|
||||
@ -1072,8 +1066,7 @@ namespace Opm
|
||||
|
||||
const double thp = this->calculateThpFromBhp(well_state, well_rates_bhp_limit, bhp_limit, deferred_logger);
|
||||
const double thp_limit = this->getTHPConstraint(summaryState);
|
||||
|
||||
if (thp < thp_limit) {
|
||||
if ( (this->isProducer() && thp < thp_limit) || (this->isInjector() && thp > thp_limit) ) {
|
||||
this->operability_status_.obey_thp_limit_under_bhp_limit = false;
|
||||
}
|
||||
}
|
||||
@ -1097,10 +1090,11 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
StandardWell<TypeTag>::
|
||||
checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger)
|
||||
checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger)
|
||||
{
|
||||
const auto& summaryState = ebos_simulator.vanguard().summaryState();
|
||||
const auto obtain_bhp = computeBhpAtThpLimitProd(well_state, ebos_simulator, summaryState, deferred_logger);
|
||||
const auto obtain_bhp = this->isProducer() ? computeBhpAtThpLimitProd(well_state, ebos_simulator, summaryState, deferred_logger)
|
||||
: computeBhpAtThpLimitInj(ebos_simulator, summaryState, deferred_logger);
|
||||
|
||||
if (obtain_bhp) {
|
||||
this->operability_status_.can_obtain_bhp_with_thp_limit = true;
|
||||
@ -1109,13 +1103,20 @@ namespace Opm
|
||||
this->operability_status_.obey_bhp_limit_with_thp_limit = (*obtain_bhp >= bhp_limit);
|
||||
|
||||
const double thp_limit = this->getTHPConstraint(summaryState);
|
||||
if (*obtain_bhp < thp_limit) {
|
||||
if (this->isProducer() && *obtain_bhp < thp_limit) {
|
||||
const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
|
||||
+ " bars is SMALLER than thp limit "
|
||||
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
|
||||
+ " bars as a producer for well " + name();
|
||||
deferred_logger.debug(msg);
|
||||
}
|
||||
else if (this->isInjector() && *obtain_bhp > thp_limit) {
|
||||
const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
|
||||
+ " bars is LARGER than thp limit "
|
||||
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
|
||||
+ " bars as a injector for well " + name();
|
||||
deferred_logger.debug(msg);
|
||||
}
|
||||
} else {
|
||||
this->operability_status_.can_obtain_bhp_with_thp_limit = false;
|
||||
this->operability_status_.obey_bhp_limit_with_thp_limit = false;
|
||||
|
@ -299,10 +299,10 @@ protected:
|
||||
std::vector<double> initialWellRateFractions(const Simulator& ebosSimulator, const WellState& well_state) const;
|
||||
|
||||
// check whether the well is operable under BHP limit with current reservoir condition
|
||||
virtual void checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) =0;
|
||||
virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) =0;
|
||||
|
||||
// check whether the well is operable under THP limit with current reservoir condition
|
||||
virtual void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) =0;
|
||||
virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) =0;
|
||||
|
||||
virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const=0;
|
||||
|
||||
|
@ -812,11 +812,6 @@ updateWellTestState(const SingleWellState& ws,
|
||||
DeferredLogger& deferred_logger) const
|
||||
{
|
||||
|
||||
// currently, we only updateWellTestState for producers
|
||||
if (this->isInjector()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Based on current understanding, only under prediction mode, we need to shut well due to various
|
||||
// reasons or limits. With more knowlage or testing cases later, this might need to be corrected.
|
||||
if (!underPredictionMode() ) {
|
||||
@ -897,7 +892,6 @@ checkMaxRatioLimitWell(const SingleWellState& ws,
|
||||
}
|
||||
|
||||
const double well_ratio = ratioFunc(well_rates, phaseUsage());
|
||||
|
||||
return (well_ratio > max_ratio_limit);
|
||||
}
|
||||
|
||||
|
@ -551,11 +551,6 @@ namespace Opm
|
||||
return;
|
||||
}
|
||||
|
||||
// focusing on PRODUCER for now
|
||||
if (this->isInjector()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->underPredictionMode() ) {
|
||||
return;
|
||||
}
|
||||
@ -575,7 +570,7 @@ namespace Opm
|
||||
{
|
||||
bool shut_unsolvable_wells = param_.shut_unsolvable_wells_;
|
||||
// the well operability system currently works only for producers in prediction mode
|
||||
return shut_unsolvable_wells && !this->isInjector() && this->underPredictionMode();
|
||||
return shut_unsolvable_wells && this->underPredictionMode();
|
||||
}
|
||||
|
||||
|
||||
@ -591,16 +586,20 @@ namespace Opm
|
||||
{
|
||||
this->operability_status_.resetOperability();
|
||||
|
||||
auto current_control = well_state.well(this->index_of_well_).production_cmode;
|
||||
bool thp_controled = this->isInjector() ? well_state.well(this->index_of_well_).injection_cmode == Well::InjectorCMode::THP:
|
||||
well_state.well(this->index_of_well_).production_cmode == Well::ProducerCMode::THP;
|
||||
bool bhp_controled = this->isInjector() ? well_state.well(this->index_of_well_).injection_cmode == Well::InjectorCMode::BHP:
|
||||
well_state.well(this->index_of_well_).production_cmode == Well::ProducerCMode::BHP;
|
||||
|
||||
// Operability checking is not free
|
||||
// Only check wells under BHP and THP control
|
||||
if(current_control == Well::ProducerCMode::BHP || current_control == Well::ProducerCMode::THP) {
|
||||
if(bhp_controled || thp_controled) {
|
||||
updateIPR(ebos_simulator, deferred_logger);
|
||||
checkOperabilityUnderBHPLimitProducer(well_state, ebos_simulator, deferred_logger);
|
||||
checkOperabilityUnderBHPLimit(well_state, ebos_simulator, deferred_logger);
|
||||
}
|
||||
// we do some extra checking for wells under THP control.
|
||||
if (current_control == Well::ProducerCMode::THP) {
|
||||
checkOperabilityUnderTHPLimitProducer(ebos_simulator, well_state, deferred_logger);
|
||||
if (thp_controled) {
|
||||
checkOperabilityUnderTHPLimit(ebos_simulator, well_state, deferred_logger);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user