/* Copyright 2021 Equinor ASA. This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #ifndef OPM_GASLIFT_GROUP_INFO_HEADER_INCLUDED #define OPM_GASLIFT_GROUP_INFO_HEADER_INCLUDED #include #include #include #include #include #include #include namespace Opm { class DeferredLogger; class GasLiftOpt; class Group; template class GroupState; class Schedule; class SummaryState; class Well; template class WellState; template class GasLiftGroupInfo : public GasLiftCommon { protected: class GroupRates; // NOTE: In the Well2GroupMap below, in the std::vector value we store // pairs of group names and efficiency factors. The efficiency factors // are the product of the wells efficiency factor and all the efficiency // factors of the child groups of the group all the way down // to the well group. using Well2GroupMap = std::map>>; using GroupRateMap = std::map; using GroupIdxMap = std::map; using Communication = Dune::Communication; // TODO: same definition with WellInterface, and // WellState eventually they should go to a common header file. static const int Water = BlackoilPhases::Aqua; static const int Oil = BlackoilPhases::Liquid; static const int Gas = BlackoilPhases::Vapour; public: enum class Rate {oil, gas, water, liquid}; using GLiftEclWells = std::map>; GasLiftGroupInfo(GLiftEclWells& ecl_wells, const Schedule& schedule, const SummaryState& summary_state, const int report_step_idx, const int iteration_idx, const PhaseUsage& phase_usage, DeferredLogger& deferred_logger, WellState& well_state, const GroupState& group_state, const Parallel::Communication& comm, bool glift_debug); std::vector>& getWellGroups(const std::string& well_name); Scalar alqRate(const std::string& group_name); Scalar gasRate(const std::string& group_name) const; Scalar gasPotential(const std::string& group_name) const; Scalar waterPotential(const std::string& group_name) const; Scalar oilPotential(const std::string& group_name) const; int getGroupIdx(const std::string& group_name); Scalar getRate(Rate rate_type, const std::string& group_name) const; Scalar getPotential(Rate rate_type, const std::string& group_name) const; std::tuple getRates(const int group_idx) const; std::optional gasTarget(const std::string& group_name) const; std::optional getTarget(Rate rate_type, const std::string& group_name) const; const std::string& groupIdxToName(int group_idx) const; bool hasAnyTarget(const std::string& group_name) const; bool hasWell(const std::string& well_name); void initialize(); std::optional liquidTarget(const std::string& group_name) const; std::optional maxAlq(const std::string& group_name); std::optional maxTotalGasRate(const std::string& group_name); Scalar oilRate(const std::string& group_name) const; std::optional oilTarget(const std::string& group_name) const; static const std::string rateToString(Rate rate); Scalar waterRate(const std::string& group_name) const; std::optional waterTarget(const std::string& group_name) const; void update(const std::string& well_name, Scalar delta_oil, Scalar delta_gas, Scalar delta_water, Scalar delta_alq); void updateRate(int idx, Scalar oil_rate, Scalar gas_rate, Scalar water_rate, Scalar alq); const Well2GroupMap& wellGroupMap() { return well_group_map_; } protected: bool checkDoGasLiftOptimization_(const std::string& well_name); bool checkNewtonIterationIdxOk_(const std::string& well_name); void debugDisplayWellContribution_(const std::string& gr_name, const std::string& well_name, Scalar eff_factor, Scalar well_oil_rate, Scalar well_gas_rate, Scalar well_water_rate, Scalar well_alq, Scalar oil_rate, Scalar gas_rate, Scalar water_rate, Scalar alq) const; void debugDisplayUpdatedGroupRates(const std::string& name, Scalar oil_rate, Scalar gas_rate, Scalar water_rate, Scalar alq) const; void debugEndInitializeGroup(const std::string& name) const; void debugStartInitializeGroup(const std::string& name) const; void displayDebugMessage_(const std::string& msg) const override; void displayDebugMessage_(const std::string& msg, const std::string& well_name); std::tuple getProducerWellRates_(const Well* well, const int index); std::tuple initializeGroupRatesRecursive_(const Group &group); void initializeWell2GroupMapRecursive_(const Group& group, std::vector& group_names, std::vector& group_efficiency, Scalar cur_efficiency); void updateGroupIdxMap_(const std::string& group_name); class GroupRates { public: GroupRates(Scalar oil_rate, Scalar gas_rate, Scalar water_rate, Scalar alq, Scalar oil_potential, Scalar gas_potential, Scalar water_potential, std::optional oil_target, std::optional gas_target, std::optional water_target, std::optional liquid_target, std::optional total_gas, std::optional max_alq) : oil_rate_{oil_rate} , gas_rate_{gas_rate} , water_rate_{water_rate} , alq_{alq} , oil_potential_{oil_potential} , gas_potential_{gas_potential} , water_potential_{water_potential} , oil_target_{oil_target} , gas_target_{gas_target} , water_target_{water_target} , liquid_target_{liquid_target} , total_gas_{total_gas} , max_alq_{max_alq} {} Scalar alq() const { return alq_; } void assign(Scalar oil_rate, Scalar gas_rate, Scalar water_rate, Scalar alq) { oil_rate_ = oil_rate; gas_rate_ = gas_rate; water_rate_ = water_rate; alq_ = alq; } Scalar gasRate() const { return gas_rate_; } Scalar waterRate() const { return water_rate_; } std::optional gasTarget() const { return gas_target_; } std::optional waterTarget() const { return water_target_; } std::optional maxAlq() const { return max_alq_; } std::optional maxTotalGasRate() const { return total_gas_; } Scalar oilRate() const { return oil_rate_; } std::optional oilTarget() const { return oil_target_; } std::optional liquidTarget() const { return liquid_target_; } Scalar oilPotential() const { return oil_potential_; } Scalar gasPotential() const { return gas_potential_; } Scalar waterPotential() const { return water_potential_; } void update(Scalar delta_oil, Scalar delta_gas, Scalar delta_water, Scalar delta_alq) { oil_rate_ += delta_oil; gas_rate_ += delta_gas; water_rate_ += delta_water; alq_ += delta_alq; // Note. We don't updata the potentials at this point. They // are only needed initially. } private: Scalar oil_rate_; Scalar gas_rate_; Scalar water_rate_; Scalar alq_; Scalar oil_potential_; Scalar gas_potential_; Scalar water_potential_; std::optional oil_target_; std::optional gas_target_; std::optional water_target_; std::optional liquid_target_; std::optional total_gas_; std::optional max_alq_; }; GLiftEclWells& ecl_wells_; const Schedule& schedule_; const SummaryState& summary_state_; const int report_step_idx_; const int iteration_idx_; const PhaseUsage& phase_usage_; const GasLiftOpt& glo_; GroupRateMap group_rate_map_; Well2GroupMap well_group_map_; GroupIdxMap group_idx_; int next_group_idx_ = 0; // Optimize only wells under THP control bool optimize_only_thp_wells_ = false; }; } // namespace Opm #endif // OPM_GASLIFT_GROUP_INFO_INCLUDED