22#define OPM_BLACKOILWELLMODEL_GASLIFT_IMPL_HEADER_INCLUDED
23#define OPM_BLACKOILWELLMODEL_GASLIFT_IMPL_HEADER_INCLUDED
26#ifndef OPM_BLACKOILWELLMODEL_GASLIFT_HEADER_INCLUDED
30#include <opm/common/TimingMacros.hpp>
40template<
typename TypeTag>
44 const std::vector<WellInterfacePtr>& well_container,
45 const std::map<std::string, Scalar>& node_pressures,
46 const bool updatePotentials,
52 const auto& glo = simulator.vanguard().schedule().glo(simulator.episodeIndex());
56 bool do_glift_optimization =
false;
57 int num_wells_changed = 0;
58 const double simulation_time = simulator.time();
59 const Scalar min_wait = glo.min_wait();
64 if (simulation_time == this->last_glift_opt_time_ ||
65 simulation_time >= (this->last_glift_opt_time_ + min_wait))
67 do_glift_optimization =
true;
68 this->last_glift_opt_time_ = simulation_time;
72 if (updatePotentials) {
73 updateWellPotentials(simulator, well_container, node_pressures, wellState, deferred_logger);
76 if (do_glift_optimization) {
88 initGliftEclWellMap(well_container, ecl_well_map);
91 simulator.vanguard().schedule(),
92 simulator.vanguard().summaryState(),
93 simulator.episodeIndex(),
94 simulator.model().newtonMethod().numIterations(),
98 simulator.vanguard().grid().comm(),
101 group_info.initialize();
103 gasLiftOptimizationStage1(simulator,
113 this->gasLiftOptimizationStage2(simulator.vanguard().gridView().comm(),
114 simulator.vanguard().schedule(),
115 simulator.vanguard().summaryState(),
122 simulator.episodeIndex(),
125 if constexpr (glift_debug) {
126 std::vector<WellInterfaceGeneric<Scalar, IndexTraits>*> wc;
127 wc.reserve(well_container.size());
128 std::ranges::transform(well_container, std::back_inserter(wc),
131 this->gliftDebugShowALQ(wc,
135 num_wells_changed = glift_wells.size();
137 num_wells_changed = simulator.vanguard().gridView().comm().sum(num_wells_changed);
138 return num_wells_changed > 0;
141template<
typename TypeTag>
145 const std::vector<WellInterfacePtr>& well_container,
146 WellStateType& wellState,
148 GLiftProdWells& prod_wells,
149 GLiftOptWells &glift_wells,
151 GLiftWellStateMap& state_map,
155 auto comm = simulator.
vanguard().grid().comm();
156 int num_procs = comm.size();
182 for (
int i = 0; i< num_procs; i++) {
183 int num_rates_to_sync = 0;
184 GLiftSyncGroups groups_to_sync;
185 if (comm.rank() == i) {
187 for (
const auto& well : well_container) {
189 if (group_info.
hasWell(well->name())) {
190 gasLiftOptimizationStage1SingleWell(well.get(),
202 num_rates_to_sync = groups_to_sync.size();
205 OPM_TIMEBLOCK(WaitForGasLiftSyncGroups);
206 num_rates_to_sync = comm.sum(num_rates_to_sync);
208 if (num_rates_to_sync > 0) {
209 OPM_TIMEBLOCK(GasLiftSyncGroups);
210 std::vector<int> group_indexes;
211 group_indexes.reserve(num_rates_to_sync);
212 std::vector<Scalar> group_alq_rates;
213 group_alq_rates.reserve(num_rates_to_sync);
214 std::vector<Scalar> group_oil_rates;
215 group_oil_rates.reserve(num_rates_to_sync);
216 std::vector<Scalar> group_gas_rates;
217 group_gas_rates.reserve(num_rates_to_sync);
218 std::vector<Scalar> group_water_rates;
219 group_water_rates.reserve(num_rates_to_sync);
220 if (comm.rank() == i) {
221 for (
auto idx : groups_to_sync) {
222 auto [oil_rate, gas_rate, water_rate, alq] = group_info.
getRates(idx);
223 group_indexes.push_back(idx);
224 group_oil_rates.push_back(oil_rate);
225 group_gas_rates.push_back(gas_rate);
226 group_water_rates.push_back(water_rate);
227 group_alq_rates.push_back(alq);
230 group_indexes.resize(num_rates_to_sync);
231 group_oil_rates.resize(num_rates_to_sync);
232 group_gas_rates.resize(num_rates_to_sync);
233 group_water_rates.resize(num_rates_to_sync);
234 group_alq_rates.resize(num_rates_to_sync);
237 Parallel::MpiSerializer ser(comm);
238 ser.broadcast(Parallel::RootRank{i}, group_indexes, group_oil_rates,
239 group_gas_rates, group_water_rates, group_alq_rates);
241 if (comm.rank() != i) {
242 for (
int j = 0; j < num_rates_to_sync; ++j) {
246 group_water_rates[j],
257template<
typename TypeTag>
259BlackoilWellModelGasLift<TypeTag>::
260gasLiftOptimizationStage1SingleWell(WellInterface<TypeTag>* well,
261 const Simulator& simulator,
262 WellStateType& wellState,
263 GroupState<Scalar>& groupState,
264 GLiftProdWells& prod_wells,
265 GLiftOptWells& glift_wells,
266 GasLiftGroupInfo<Scalar, IndexTraits>& group_info,
267 GLiftWellStateMap& state_map,
268 GLiftSyncGroups& sync_groups,
269 DeferredLogger& deferred_logger)
272 const auto& summary_state = simulator.vanguard().summaryState();
273 auto glift = std::make_unique<GasLiftSingleWell<TypeTag>>(*well,
281 simulator.vanguard().gridView().comm(),
283 auto state = glift->runOptimize(simulator.model().newtonMethod().numIterations());
285 state_map.emplace(well->name(), std::move(state));
286 glift_wells.emplace(well->name(), std::move(glift));
289 prod_wells.insert({well->name(), well});
292template<
typename TypeTag>
298 for (
const auto& well : well_container) {
299 ecl_well_map.try_emplace(well->name(), &well->wellEcl(), well->indexOfWell());
303template<
typename TypeTag>
307 const std::vector<WellInterfacePtr>& well_container,
308 const std::map<std::string, Scalar>& node_pressures,
309 WellStateType& wellState,
312 auto well_state_copy = wellState;
313 const int np = wellState.numPhases();
316 for (
const auto& well : well_container) {
317 if (well->isInjector() || !well->wellEcl().predictionMode())
320 const auto it = node_pressures.find(well->wellEcl().groupName());
321 if (it != node_pressures.end()) {
322 std::string cur_exc_msg;
325 std::vector<Scalar> potentials;
326 const auto& groupStateHelper = simulator.
problem().wellModel().groupStateHelper();
327 well->computeWellPotentials(simulator, well_state_copy, groupStateHelper, potentials);
328 auto& ws = wellState.well(well->indexOfWell());
329 for (
int p = 0; p < np; ++p) {
331 ws.well_potentials[p] = std::max(Scalar{0.0}, potentials[p]);
337 exc_msg += fmt::format(
"\nFor well {}: {}", well->name(), cur_exc_msg);
339 exc_type = std::max(exc_type, cur_exc_type);
343 const std::string msg =
"Updating well potentials after network balancing failed. Continue with current potentials";
344 deferred_logger.
warning(
"WELL_POT_SOLVE_AFTER_NETWORK_FAILED", msg + exc_msg);
#define OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, obptc_exc_msg)
Inserts catch classes for the parallel try-catch.
Definition: DeferredLoggingErrorHelpers.hpp:166
Class for handling the gaslift in the blackoil well model.
Definition: BlackoilWellModelGasLift.hpp:96
GetPropType< TypeTag, Properties::Simulator > Simulator
Definition: BlackoilWellModelGasLift.hpp:108
bool maybeDoGasLiftOptimize(const Simulator &simulator, const std::vector< WellInterfacePtr > &well_container, const std::map< std::string, Scalar > &node_pressures, const bool updatePotentials, WellStateType &wellState, GroupState< Scalar > &groupState, DeferredLogger &deferred_logger)
Definition: BlackoilWellModelGasLift_impl.hpp:43
static void initGliftEclWellMap(const std::vector< WellInterfacePtr > &well_container, GLiftEclWells &ecl_well_map)
Definition: BlackoilWellModelGasLift_impl.hpp:295
typename Base::GLiftWellStateMap GLiftWellStateMap
Definition: BlackoilWellModelGasLift.hpp:107
typename Base::GLiftOptWells GLiftOptWells
Definition: BlackoilWellModelGasLift.hpp:104
typename GasLiftGroupInfo< Scalar, IndexTraits >::GLiftEclWells GLiftEclWells
Definition: BlackoilWellModelGasLift.hpp:103
typename Base::GLiftProdWells GLiftProdWells
Definition: BlackoilWellModelGasLift.hpp:105
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: BlackoilWellModelGasLift.hpp:98
Definition: DeferredLogger.hpp:57
void warning(const std::string &tag, const std::string &message)
Definition: GasLiftGroupInfo.hpp:46
bool hasWell(const std::string &well_name)
std::tuple< Scalar, Scalar, Scalar, Scalar > getRates(const int group_idx) const
void updateRate(int idx, Scalar oil_rate, Scalar gas_rate, Scalar water_rate, Scalar alq)
Definition: GroupState.hpp:41
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:84
Vanguard & vanguard()
Return a reference to the grid manager of simulation.
Definition: simulator.hh:234
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:265
Definition: WellInterfaceGeneric.hpp:53
Definition: WellState.hpp:66
@ NONE
Definition: DeferredLogger.hpp:46
Definition: blackoilbioeffectsmodules.hh:43