wells under zero injection target are also treated as stopped well

when formulating the well control equations
This commit is contained in:
Kai Bao 2023-03-28 13:14:33 +02:00
parent b4b8e7aff1
commit f4e0a996b9
10 changed files with 53 additions and 33 deletions

View File

@ -116,7 +116,7 @@ assembleControlEq(const WellState& well_state,
return rates;
};
if (well_.wellIsStopped()) {
if (well_.wellUnderZeroRateControl(summaryState, well_state)) {
control_eq = primary_variables.getWQTotal();
} else if (well_.isInjector() ) {
// Find scaling factor to get injection rate,
@ -164,9 +164,6 @@ assembleControlEq(const WellState& well_state,
bhp_from_thp,
control_eq,
deferred_logger);
} else if (wellhelpers::rateControlWithZeroTarget(well_state.well(well_.indexOfWell()).production_cmode, prod_controls)) {
// Production mode, zero target. Treat as STOP.
control_eq = primary_variables.getWQTotal();
} else {
// Find rates.
const auto rates = getRates();

View File

@ -152,7 +152,7 @@ namespace Opm
const WellState& well_state,
DeferredLogger& /* deferred_logger */)
{
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
const bool zero_rate_target = this->wellUnderZeroRateControl(summary_state, well_state);
this->primary_variables_.update(well_state, zero_rate_target);
}
@ -615,7 +615,7 @@ namespace Opm
const double dFLimit = this->param_.dwell_fraction_max_;
const double max_pressure_change = this->param_.max_pressure_change_ms_wells_;
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
const bool zero_rate_target = this->wellUnderZeroRateControl(summary_state, well_state);
this->primary_variables_.updateNewton(dwells,
relaxation_factor,
dFLimit,

View File

@ -116,7 +116,7 @@ assembleControlEq(const WellState& well_state,
return rates;
};
if (well_.wellIsStopped()) {
if (well_.wellUnderZeroRateControl(summaryState, well_state)) {
control_eq = primary_variables.eval(PrimaryVariables::WQTotal);
} else if (well_.isInjector()) {
// Find injection rate.
@ -143,9 +143,6 @@ assembleControlEq(const WellState& well_state,
bhp_from_thp,
control_eq,
deferred_logger);
} else if (wellhelpers::rateControlWithZeroTarget(well_state.well(well_.indexOfWell()).production_cmode, prod_controls)) {
// Production mode, zero target. Treat as STOP.
control_eq = primary_variables.eval(PrimaryVariables::WQTotal);
} else {
// Find rates.
const auto rates = getRates();

View File

@ -1000,7 +1000,7 @@ namespace Opm
{
if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
const bool zero_rate_target = this->wellUnderZeroRateControl(summary_state, well_state);
updatePrimaryVariablesNewton(dwells, zero_rate_target, deferred_logger);
updateWellStateFromPrimaryVariables(well_state, deferred_logger);
@ -1982,7 +1982,7 @@ namespace Opm
{
if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
const bool zero_rate_target = this->wellUnderZeroRateControl(summary_state, well_state);
this->primary_variables_.update(well_state, zero_rate_target, deferred_logger);
// other primary variables related to polymer injection

View File

@ -25,6 +25,7 @@
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/input/eclipse/Schedule/Well/WellInjectionControls.hpp>
#include <opm/input/eclipse/Schedule/Well/WellProductionControls.hpp>
#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
@ -171,8 +172,8 @@ DenseMatrix transposeDenseDynMatrix(const DenseMatrix& M)
return tmp;
}
bool rateControlWithZeroTarget(const WellProducerCMode& mode,
const WellProductionControls& controls)
bool rateControlWithZeroProdTarget(const WellProductionControls& controls,
const WellProducerCMode mode)
{
switch (mode) {
case WellProducerCMode::ORAT:
@ -198,6 +199,20 @@ bool rateControlWithZeroTarget(const WellProducerCMode& mode,
}
bool rateControlWithZeroInjTarget(const WellInjectionControls& controls,
const WellInjectorCMode mode)
{
switch (mode) {
case WellInjectorCMode::RATE:
return controls.surface_rate == 0.0;
case WellInjectorCMode::RESV:
return controls.reservoir_rate == 0.0;
default:
return false;
}
}
template class ParallelStandardWellB<double>;
template<int Dim> using Vec = Dune::BlockVector<Dune::FieldVector<double,Dim>>;

View File

@ -31,8 +31,10 @@
namespace Opm {
class ParallelWellInfo;
struct WellProductionControls;
struct WellInjectionControls;
enum class WellProducerCMode;
class WellProductionControls;
enum class WellInjectorCMode;
namespace wellhelpers {
@ -86,8 +88,12 @@ template <class DenseMatrix>
DenseMatrix transposeDenseDynMatrix(const DenseMatrix& M);
/// Helper to check whether the well is under zero production rate control
bool rateControlWithZeroTarget(const WellProducerCMode& mode,
const WellProductionControls& controls);
bool rateControlWithZeroProdTarget(const WellProductionControls& controls,
WellProducerCMode mode);
/// Helper to check whether the well is under zero injection rate control
bool rateControlWithZeroInjTarget(const WellInjectionControls& controls,
WellInjectorCMode mode);
} // namespace wellhelpers
} // namespace Opm

View File

@ -360,8 +360,6 @@ protected:
Eval getPerfCellPressure(const FluidState& fs) const;
bool wellUnderZeroProductionRateControl(const SummaryState& summary_state,
const WellState& well_state) const;
};
}

View File

@ -450,6 +450,24 @@ bool WellInterfaceGeneric::isPressureControlled(const WellState& well_state) con
}
}
bool WellInterfaceGeneric::wellUnderZeroRateControl(const SummaryState& summary_state,
const WellState& well_state) const
{
if (this->wellIsStopped()) return true;
if (this->isProducer()) { // producers
const auto prod_controls = this->well_ecl_.productionControls(summary_state);
const auto prod_mode = well_state.well(this->indexOfWell()).production_cmode;
return wellhelpers::rateControlWithZeroProdTarget(prod_controls, prod_mode);
} else { // injectors
const auto inj_controls = this->well_ecl_.injectionControls(summary_state);
const auto inj_mode = well_state.well(this->indexOfWell()).injection_cmode;
return wellhelpers::rateControlWithZeroInjTarget(inj_controls, inj_mode);
}
}
double WellInterfaceGeneric::wmicrobes_() const
{
auto injectorType = this->well_ecl_.injectorType();

View File

@ -195,6 +195,9 @@ public:
bool isPressureControlled(const WellState& well_state) const;
bool wellUnderZeroRateControl(const SummaryState& summary_state,
const WellState& well_state) const;
protected:
bool getAllowCrossFlow() const;

View File

@ -1131,18 +1131,4 @@ namespace Opm
}
}
template<typename TypeTag>
bool WellInterface<TypeTag>::wellUnderZeroProductionRateControl(const SummaryState& summary_state,
const WellState& well_state) const
{
if (this->wellIsStopped()) return true;
bool zero_rate_target = false;
if (this->well_ecl_.isProducer()) {
const auto prod_controls = this->well_ecl_.productionControls(summary_state);
zero_rate_target = wellhelpers::rateControlWithZeroTarget(well_state.well(this->index_of_well_).production_cmode, prod_controls);
}
return zero_rate_target;
}
} // namespace Opm