20#ifndef OPM_GASLIFT_SINGLE_WELL_IMPL_HEADER_INCLUDED
21#define OPM_GASLIFT_SINGLE_WELL_IMPL_HEADER_INCLUDED
24#ifndef OPM_GASLIFT_SINGLE_WELL_HEADER_INCLUDED
26#include <opm/simulators/wells/GasLiftSingleWell.hpp>
29#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
30#include <opm/input/eclipse/Schedule/Well/Well.hpp>
35#include <fmt/format.h>
39template<
typename TypeTag>
40GasLiftSingleWell<TypeTag>::
42 const Simulator& simulator,
49 const Parallel::Communication& comm,
60 simulator.vanguard().schedule(),
61 simulator.episodeIndex(),
65 , simulator_{simulator}
68 const auto& gl_well = *this->gl_well_;
69 if (this->useFixedAlq_(gl_well)) {
70 this->updateWellStateAlqFixedValue_(gl_well);
71 this->optimize_ =
false;
74 setAlqMaxRate_(gl_well);
75 this->optimize_ =
true;
78 setupPhaseVariables_();
83 this->orig_alq_ = this->well_state_.getALQ(this->well_name_);
84 if (this->optimize_) {
85 this->setAlqMinRate_(gl_well);
89 this->alpha_w_ = gl_well.weight_factor();
90 if (this->alpha_w_ <= 0 ) {
91 this->displayWarning_(
"Nonpositive value for alpha_w ignored");
101 this->alpha_g_ = gl_well.inc_weight_factor();
105 this->max_iterations_ = 1000;
113template<
typename TypeTag>
114typename GasLiftSingleWell<TypeTag>::BasicRates
115GasLiftSingleWell<TypeTag>::
116computeWellRates_(Scalar bhp,
bool bhp_is_limited,
bool debug_output )
const
118 std::vector<Scalar> potentials(this->NUM_PHASES, 0.0);
119 this->well_.computeWellRatesWithBhp(this->simulator_,
122 this->deferred_logger_);
124 const std::string msg = fmt::format(
"computed well potentials given bhp {}, "
125 "oil: {}, gas: {}, water: {}", bhp,
126 -potentials[this->oil_pos_], -potentials[this->gas_pos_],
127 -potentials[this->water_pos_]);
128 this->displayDebugMessage_(msg);
131 for (
auto& potential : potentials) {
132 potential = std::min(Scalar{0.0}, potential);
134 return {-potentials[this->oil_pos_],
135 -potentials[this->gas_pos_],
136 -potentials[this->water_pos_],
141template<
typename TypeTag>
142std::optional<typename GasLiftSingleWell<TypeTag>::Scalar>
143GasLiftSingleWell<TypeTag>::
144computeBhpAtThpLimit_(Scalar alq,
bool debug_output)
const
147 auto bhp_at_thp_limit = this->well_.computeBhpAtThpLimitProdWithAlq(
149 this->summary_state_,
151 this->deferred_logger_,
153 if (bhp_at_thp_limit) {
154 if (*bhp_at_thp_limit < this->controls_.bhp_limit) {
155 if (debug_output && this->debug) {
156 const std::string msg = fmt::format(
157 "Computed bhp ({}) from thp limit is below bhp limit ({}), (ALQ = {})."
158 " Using bhp limit instead",
159 *bhp_at_thp_limit, this->controls_.bhp_limit, alq
161 this->displayDebugMessage_(msg);
163 bhp_at_thp_limit = this->controls_.bhp_limit;
168 const std::string msg = fmt::format(
169 "Failed in getting converged bhp potential from thp limit (ALQ = {})", alq);
170 this->displayDebugMessage_(msg);
172 return bhp_at_thp_limit;
175template<
typename TypeTag>
177GasLiftSingleWell<TypeTag>::
178setupPhaseVariables_()
180 const auto& pu = this->phase_usage_;
182 bool num_phases_ok = (pu.num_phases == 3);
184 if (pu.num_phases == 2) {
195 if ( pu.phase_used[BlackoilPhases::Aqua] == 1
196 && pu.phase_used[BlackoilPhases::Liquid] == 1
197 && pu.phase_used[BlackoilPhases::Vapour] == 0)
200 num_phases_ok =
true;
204 throw std::logic_error(
"Two-phase gas lift optimization only supported"
205 " for oil and water");
208 assert(num_phases_ok);
209 this->oil_pos_ = pu.phase_pos[this->Oil];
210 this->gas_pos_ = pu.phase_pos[this->Gas];
211 this->water_pos_ = pu.phase_pos[this->Water];
214template<
typename TypeTag>
216GasLiftSingleWell<TypeTag>::
217setAlqMaxRate_(
const GasLiftWell& well)
219 const auto& max_alq_optional = well.max_rate();
220 if (max_alq_optional) {
223 this->max_alq_ = *max_alq_optional;
229 const auto& table = well_.vfpProperties()->getProd()->getTable(
230 this->controls_.vfp_table_number);
231 const auto& alq_values = table.getALQAxis();
234 this->max_alq_ = alq_values.back();
238template<
typename TypeTag>
240GasLiftSingleWell<TypeTag>::
241checkThpControl_()
const
243 const int well_index = this->well_state_.index(this->well_name_).value();
244 const Well::ProducerCMode& control_mode =
245 this->well_state_.well(well_index).production_cmode;
246 bool thp_control = control_mode == Well::ProducerCMode::THP;
247 const auto& well = getWell();
248 thp_control = thp_control || well.thpLimitViolatedButNotSwitched();
251 this->displayDebugMessage_(
"Well is not under THP control, skipping iteration..");
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilboundaryratevector.hh:37
PhaseUsage phaseUsage(const Phases &phases)
Determine the active phases.
Definition phaseUsageFromDeck.cpp:37
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:242