47class GasLiftSingleWellGeneric :
public GasLiftCommon<Scalar, IndexTraits>
50 static constexpr int Water = IndexTraits::waterPhaseIdx;
51 static constexpr int Oil = IndexTraits::oilPhaseIdx;
52 static constexpr int Gas = IndexTraits::gasPhaseIdx;
53 static constexpr int NUM_PHASES = 3;
54 static constexpr Scalar ALQ_EPSILON = 1e-8;
57 using GLiftSyncGroups = std::set<int>;
58 using Rate =
typename GasLiftGroupInfo<Scalar, IndexTraits>::Rate;
59 using MessageType =
typename GasLiftCommon<Scalar, IndexTraits>::MessageType;
64 GradInfo(Scalar grad_,
69 Scalar new_water_rate_,
70 bool water_is_limited_,
74 , new_oil_rate{new_oil_rate_}
75 , oil_is_limited{oil_is_limited_}
76 , new_gas_rate{new_gas_rate_}
77 , gas_is_limited{gas_is_limited_}
78 , new_water_rate{new_water_rate_}
79 , water_is_limited{water_is_limited_}
81 , alq_is_limited{alq_is_limited_}
89 Scalar new_water_rate;
90 bool water_is_limited;
95 const std::string& name()
const {
return well_name_; }
97 std::optional<GradInfo> calcIncOrDecGradient(Scalar oil_rate,
101 const std::string& gr_name_dont_limit,
103 bool debug_output =
true)
const;
105 std::unique_ptr<GasLiftWellState<Scalar>> runOptimize(
const int iteration_idx);
107 std::pair<Scalar, bool> wellTestALQ();
115 const Well& ecl_well,
116 const SummaryState& summary_state,
118 const Schedule& schedule,
119 const int report_step_idx,
120 GLiftSyncGroups& sync_groups,
121 const Parallel::Communication& comm,
127 BasicRates(
const BasicRates& rates) :
131 bhp_is_limited{rates.bhp_is_limited}
134 BasicRates(Scalar oil_,
137 bool bhp_is_limited_)
141 , bhp_is_limited{bhp_is_limited_}
144 BasicRates& operator=(
const BasicRates& rates)
149 bhp_is_limited = rates.bhp_is_limited;
158 Scalar operator[](Rate rate_type)
const
168 return this->oil + this->water;
170 throw std::runtime_error(
"This should not happen");
174 Scalar oil, gas, water;
178 struct LimitedRates :
public BasicRates
180 enum class LimitType {well, group, none};
181 LimitedRates(Scalar oil_,
184 bool oil_is_limited_,
185 bool gas_is_limited_,
186 bool water_is_limited_,
187 bool bhp_is_limited_,
188 std::optional<Rate> oil_limiting_target_,
189 std ::optional<Rate> water_limiting_target_)
190 : BasicRates(oil_, gas_, water_, bhp_is_limited_)
191 , oil_is_limited{oil_is_limited_}
192 , gas_is_limited{gas_is_limited_}
193 , water_is_limited{water_is_limited_}
194 , oil_limiting_target{oil_limiting_target_}
195 , water_limiting_target{water_limiting_target_}
197 set_initial_limit_type_();
200 LimitedRates(
const BasicRates& rates,
201 bool oil_is_limited_,
202 bool gas_is_limited_,
203 bool water_is_limited_)
205 , oil_is_limited{oil_is_limited_}
206 , gas_is_limited{gas_is_limited_}
207 , water_is_limited{water_is_limited_}
209 set_initial_limit_type_();
214 return oil_is_limited || gas_is_limited || water_is_limited;
219 LimitType limit_type;
222 bool water_is_limited;
223 std::optional<Rate> oil_limiting_target;
224 std::optional<Rate> water_limiting_target;
227 void set_initial_limit_type_()
229 limit_type = limited() ? LimitType::well : LimitType::none;
235 OptimizeState( GasLiftSingleWellGeneric& parent_,
bool increase_ )
237 , increase{increase_}
239 , stop_iteration{
false}
243 GasLiftSingleWellGeneric& parent;
249 std::pair<std::optional<Scalar>,
bool> addOrSubtractAlqIncrement(Scalar alq);
250 Scalar calcEcoGradient(Scalar oil_rate,
253 Scalar new_gas_rate);
255 bool checkAlqOutsideLimits(Scalar alq, Scalar oil_rate);
256 bool checkEcoGradient(Scalar gradient);
257 bool checkOilRateExceedsTarget(Scalar oil_rate);
258 bool checkRatesViolated(
const LimitedRates& rates)
const;
260 void debugShowIterationInfo(Scalar alq);
262 Scalar getBhpWithLimit();
264 void warn_(
const std::string& msg) { parent.displayWarning_(msg); }
267 bool checkGroupALQrateExceeded(Scalar delta_alq,
268 const std::string& gr_name_dont_limit =
"")
const;
269 bool checkGroupTotalRateExceeded(Scalar delta_alq,
270 Scalar delta_gas_rate)
const;
272 std::pair<std::optional<Scalar>,
bool>
273 addOrSubtractAlqIncrement_(Scalar alq,
bool increase)
const;
275 Scalar calcEcoGradient_(Scalar oil_rate, Scalar new_oil_rate,
276 Scalar gas_rate, Scalar new_gas_rate,
bool increase)
const;
278 bool checkALQequal_(Scalar alq1, Scalar alq2)
const;
280 bool checkGroupTargetsViolated(
const BasicRates& rates,
282 bool checkInitialALQmodified_(Scalar alq, Scalar initial_alq)
const;
284 virtual bool checkThpControl_()
const = 0;
285 virtual std::optional<Scalar > computeBhpAtThpLimit_(Scalar alq,
286 bool debug_output =
true)
const = 0;
288 std::pair<std::optional<Scalar>,Scalar>
289 computeConvergedBhpAtThpLimitByMaybeIncreasingALQ_()
const;
291 std::pair<std::optional<BasicRates>,Scalar>
292 computeInitialWellRates_()
const;
294 std::optional<LimitedRates>
295 computeLimitedWellRatesWithALQ_(Scalar alq)
const;
297 virtual BasicRates computeWellRates_(Scalar bhp,
299 bool debug_output =
true)
const = 0;
301 std::optional<BasicRates> computeWellRatesWithALQ_(Scalar alq)
const;
303 void debugCheckNegativeGradient_(Scalar grad, Scalar alq, Scalar new_alq,
304 Scalar oil_rate, Scalar new_oil_rate,
305 Scalar gas_rate, Scalar new_gas_rate,
306 bool increase)
const;
308 void debugPrintWellStateRates()
const;
309 void debugShowAlqIncreaseDecreaseCounts_();
310 void debugShowBhpAlqTable_();
311 void debugShowLimitingTargets_(
const LimitedRates& rates)
const;
312 void debugShowProducerControlMode()
const;
313 void debugShowStartIteration_(Scalar alq,
bool increase, Scalar oil_rate);
314 void debugShowTargets_();
315 void displayDebugMessage_(
const std::string& msg)
const override;
316 void displayWarning_(
const std::string& warning);
318 std::pair<Scalar, bool> getBhpWithLimit_(Scalar bhp)
const;
319 std::pair<Scalar, bool> getGasRateWithLimit_(
const BasicRates& rates)
const;
320 std::pair<Scalar, bool> getGasRateWithGroupLimit_(Scalar new_gas_rate,
322 const std::string& gr_name_dont_limit)
const;
324 std::pair<std::optional<LimitedRates>,Scalar >
325 getInitialRatesWithLimit_()
const;
329 std::tuple<Scalar,Scalar,bool,bool>
330 getLiquidRateWithGroupLimit_(
const Scalar new_oil_rate,
331 const Scalar oil_rate,
332 const Scalar new_water_rate,
333 const Scalar water_rate,
334 const std::string& gr_name_dont_limit)
const;
336 std::pair<Scalar, bool>
337 getOilRateWithGroupLimit_(Scalar new_oil_rate,
339 const std::string& gr_name_dont_limit)
const;
341 std::pair<Scalar, bool> getOilRateWithLimit_(
const BasicRates& rates)
const;
343 std::pair<Scalar, std::optional<Rate>>
344 getOilRateWithLimit2_(
const BasicRates& rates)
const;
346 Scalar getProductionTarget_(Rate rate)
const;
347 Scalar getRate_(Rate rate_type,
const BasicRates& rates)
const;
349 std::pair<Scalar, std::optional<Rate>>
350 getRateWithLimit_(Rate rate_type,
const BasicRates& rates)
const;
352 std::tuple<Scalar, const std::string*, Scalar>
353 getRateWithGroupLimit_(Rate rate_type,
354 const Scalar new_rate,
355 const Scalar old_rate,
356 const std::string& gr_name_dont_limit)
const;
358 std::pair<Scalar, bool>
359 getWaterRateWithGroupLimit_(Scalar new_water_rate,
361 const std::string& gr_name_dont_limit)
const;
363 std::pair<Scalar, bool> getWaterRateWithLimit_(
const BasicRates& rates)
const;
365 std::pair<Scalar, std::optional<Rate>>
366 getWaterRateWithLimit2_(
const BasicRates& rates)
const;
369 bool hasProductionControl_(Rate rate)
const;
371 std::pair<LimitedRates, Scalar>
372 increaseALQtoPositiveOilRate_(Scalar alq,
375 std::pair<LimitedRates, Scalar>
376 increaseALQtoMinALQ_(Scalar alq,
379 void logSuccess_(Scalar alq,
380 const int iteration_idx);
382 std::pair<LimitedRates, Scalar>
383 maybeAdjustALQbeforeOptimizeLoop_(
const LimitedRates& rates,
385 bool increase)
const;
387 std::pair<LimitedRates, Scalar>
388 reduceALQtoGroupAlqLimits_(Scalar alq,
391 std::pair<LimitedRates, Scalar>
392 reduceALQtoGroupTarget(Scalar alq,
395 std::pair<LimitedRates, Scalar>
396 reduceALQtoWellTarget_(Scalar alq,
399 std::unique_ptr<GasLiftWellState<Scalar>> runOptimize1_();
400 std::unique_ptr<GasLiftWellState<Scalar>> runOptimize2_();
401 std::unique_ptr<GasLiftWellState<Scalar>> runOptimizeLoop_(
bool increase);
403 void setAlqMinRate_(
const GasLiftWell& well);
404 std::unique_ptr<GasLiftWellState<Scalar>> tryIncreaseLiftGas_();
405 std::unique_ptr<GasLiftWellState<Scalar>> tryDecreaseLiftGas_();
409 Scalar delta_alq)
const;
412 updateRatesToGroupLimits_(
const BasicRates& old_rates,
414 const std::string& gr_name =
"")
const;
416 void updateWellStateAlqFixedValue_(
const GasLiftWell& well);
417 bool useFixedAlq_(
const GasLiftWell& well);
419 void debugInfoGroupRatesExceedTarget(Rate rate_type,
420 const std::string& gr_name,
422 Scalar target)
const;
423 void warnMaxIterationsExceeded_();
425 const Well& ecl_well_;
426 const SummaryState& summary_state_;
428 GLiftSyncGroups& sync_groups_;
429 const WellProductionControls controls_;
446 std::string well_name_;
448 const GasLiftWell* gl_well_;
451 bool debug_limit_increase_decrease_;
452 bool debug_abort_if_decrease_and_oil_is_limited_ =
false;
453 bool debug_abort_if_increase_and_gas_is_limited_ =
false;