mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #5303 from akva2/gaslift_template_scalar
GasLift: template Scalar type
This commit is contained in:
commit
226410cd44
@ -118,8 +118,8 @@ class WellContributions;
|
|||||||
using GLiftProdWells = typename BlackoilWellModelGeneric<Scalar>::GLiftProdWells;
|
using GLiftProdWells = typename BlackoilWellModelGeneric<Scalar>::GLiftProdWells;
|
||||||
using GLiftWellStateMap =
|
using GLiftWellStateMap =
|
||||||
typename BlackoilWellModelGeneric<Scalar>::GLiftWellStateMap;
|
typename BlackoilWellModelGeneric<Scalar>::GLiftWellStateMap;
|
||||||
using GLiftEclWells = typename GasLiftGroupInfo::GLiftEclWells;
|
using GLiftEclWells = typename GasLiftGroupInfo<Scalar>::GLiftEclWells;
|
||||||
using GLiftSyncGroups = typename GasLiftSingleWellGeneric::GLiftSyncGroups;
|
using GLiftSyncGroups = typename GasLiftSingleWellGeneric<Scalar>::GLiftSyncGroups;
|
||||||
constexpr static std::size_t pressureVarIndex = GetPropType<TypeTag, Properties::Indices>::pressureSwitchIdx;
|
constexpr static std::size_t pressureVarIndex = GetPropType<TypeTag, Properties::Indices>::pressureSwitchIdx;
|
||||||
typedef typename BaseAuxiliaryModule<TypeTag>::NeighborSet NeighborSet;
|
typedef typename BaseAuxiliaryModule<TypeTag>::NeighborSet NeighborSet;
|
||||||
|
|
||||||
@ -524,15 +524,19 @@ class WellContributions;
|
|||||||
bool maybeDoGasLiftOptimize(DeferredLogger& deferred_logger);
|
bool maybeDoGasLiftOptimize(DeferredLogger& deferred_logger);
|
||||||
|
|
||||||
void gasLiftOptimizationStage1(DeferredLogger& deferred_logger,
|
void gasLiftOptimizationStage1(DeferredLogger& deferred_logger,
|
||||||
GLiftProdWells &prod_wells, GLiftOptWells &glift_wells,
|
GLiftProdWells& prod_wells,
|
||||||
GasLiftGroupInfo &group_info, GLiftWellStateMap &state_map);
|
GLiftOptWells& glift_wells,
|
||||||
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
|
GLiftWellStateMap& state_map);
|
||||||
|
|
||||||
// cannot be const since it accesses the non-const WellState
|
// cannot be const since it accesses the non-const WellState
|
||||||
void gasLiftOptimizationStage1SingleWell(WellInterface<TypeTag> *well,
|
void gasLiftOptimizationStage1SingleWell(WellInterface<TypeTag>* well,
|
||||||
DeferredLogger& deferred_logger,
|
DeferredLogger& deferred_logger,
|
||||||
GLiftProdWells &prod_wells, GLiftOptWells &glift_wells,
|
GLiftProdWells& prod_wells,
|
||||||
GasLiftGroupInfo &group_info, GLiftWellStateMap &state_map,
|
GLiftOptWells& glift_wells,
|
||||||
GLiftSyncGroups& groups_to_sync);
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
|
GLiftWellStateMap& state_map,
|
||||||
|
GLiftSyncGroups& groups_to_sync);
|
||||||
|
|
||||||
void extractLegacyCellPvtRegionIndex_();
|
void extractLegacyCellPvtRegionIndex_();
|
||||||
|
|
||||||
|
@ -1397,7 +1397,7 @@ void BlackoilWellModelGeneric<Scalar>::
|
|||||||
gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
|
gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
|
||||||
GLiftProdWells& prod_wells,
|
GLiftProdWells& prod_wells,
|
||||||
GLiftOptWells& glift_wells,
|
GLiftOptWells& glift_wells,
|
||||||
GasLiftGroupInfo& group_info,
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
GLiftWellStateMap& glift_well_state_map,
|
GLiftWellStateMap& glift_well_state_map,
|
||||||
const int episodeIndex)
|
const int episodeIndex)
|
||||||
{
|
{
|
||||||
|
@ -53,9 +53,9 @@
|
|||||||
namespace Opm {
|
namespace Opm {
|
||||||
class DeferredLogger;
|
class DeferredLogger;
|
||||||
class EclipseState;
|
class EclipseState;
|
||||||
class GasLiftGroupInfo;
|
template<class Scalar> class GasLiftGroupInfo;
|
||||||
class GasLiftSingleWellGeneric;
|
template<class Scalar> class GasLiftSingleWellGeneric;
|
||||||
class GasLiftWellState;
|
template<class Scalar> class GasLiftWellState;
|
||||||
class Group;
|
class Group;
|
||||||
class GuideRateConfig;
|
class GuideRateConfig;
|
||||||
class ParallelWellInfo;
|
class ParallelWellInfo;
|
||||||
@ -83,9 +83,9 @@ class BlackoilWellModelGeneric
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// --------- Types ---------
|
// --------- Types ---------
|
||||||
using GLiftOptWells = std::map<std::string, std::unique_ptr<GasLiftSingleWellGeneric>>;
|
using GLiftOptWells = std::map<std::string, std::unique_ptr<GasLiftSingleWellGeneric<Scalar>>>;
|
||||||
using GLiftProdWells = std::map<std::string, const WellInterfaceGeneric*>;
|
using GLiftProdWells = std::map<std::string, const WellInterfaceGeneric*>;
|
||||||
using GLiftWellStateMap = std::map<std::string, std::unique_ptr<GasLiftWellState>>;
|
using GLiftWellStateMap = std::map<std::string, std::unique_ptr<GasLiftWellState<Scalar>>>;
|
||||||
|
|
||||||
BlackoilWellModelGeneric(Schedule& schedule,
|
BlackoilWellModelGeneric(Schedule& schedule,
|
||||||
const SummaryState& summaryState,
|
const SummaryState& summaryState,
|
||||||
@ -387,7 +387,7 @@ protected:
|
|||||||
void gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
|
void gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
|
||||||
GLiftProdWells& prod_wells,
|
GLiftProdWells& prod_wells,
|
||||||
GLiftOptWells& glift_wells,
|
GLiftOptWells& glift_wells,
|
||||||
GasLiftGroupInfo& group_info,
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
GLiftWellStateMap& map,
|
GLiftWellStateMap& map,
|
||||||
const int episodeIndex);
|
const int episodeIndex);
|
||||||
|
|
||||||
|
@ -1343,8 +1343,10 @@ namespace Opm {
|
|||||||
void
|
void
|
||||||
BlackoilWellModel<TypeTag>::
|
BlackoilWellModel<TypeTag>::
|
||||||
gasLiftOptimizationStage1(DeferredLogger& deferred_logger,
|
gasLiftOptimizationStage1(DeferredLogger& deferred_logger,
|
||||||
GLiftProdWells &prod_wells, GLiftOptWells &glift_wells,
|
GLiftProdWells& prod_wells,
|
||||||
GasLiftGroupInfo &group_info, GLiftWellStateMap &state_map)
|
GLiftOptWells &glift_wells,
|
||||||
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
|
GLiftWellStateMap& state_map)
|
||||||
{
|
{
|
||||||
auto comm = simulator_.vanguard().grid().comm();
|
auto comm = simulator_.vanguard().grid().comm();
|
||||||
int num_procs = comm.size();
|
int num_procs = comm.size();
|
||||||
@ -1448,11 +1450,13 @@ namespace Opm {
|
|||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
void
|
void
|
||||||
BlackoilWellModel<TypeTag>::
|
BlackoilWellModel<TypeTag>::
|
||||||
gasLiftOptimizationStage1SingleWell(WellInterface<TypeTag> *well,
|
gasLiftOptimizationStage1SingleWell(WellInterface<TypeTag>* well,
|
||||||
DeferredLogger& deferred_logger,
|
DeferredLogger& deferred_logger,
|
||||||
GLiftProdWells &prod_wells, GLiftOptWells &glift_wells,
|
GLiftProdWells& prod_wells,
|
||||||
GasLiftGroupInfo &group_info, GLiftWellStateMap &state_map,
|
GLiftOptWells& glift_wells,
|
||||||
GLiftSyncGroups& sync_groups)
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
|
GLiftWellStateMap& state_map,
|
||||||
|
GLiftSyncGroups& sync_groups)
|
||||||
{
|
{
|
||||||
const auto& summary_state = simulator_.vanguard().summaryState();
|
const auto& summary_state = simulator_.vanguard().summaryState();
|
||||||
std::unique_ptr<GasLiftSingleWell> glift
|
std::unique_ptr<GasLiftSingleWell> glift
|
||||||
|
@ -28,30 +28,27 @@
|
|||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
GasLiftCommon::
|
template<class Scalar>
|
||||||
GasLiftCommon(
|
GasLiftCommon<Scalar>::
|
||||||
WellState<double>& well_state,
|
GasLiftCommon(WellState<Scalar>& well_state,
|
||||||
const GroupState<double>& group_state,
|
const GroupState<Scalar>& group_state,
|
||||||
DeferredLogger &deferred_logger,
|
DeferredLogger& deferred_logger,
|
||||||
const Parallel::Communication& comm,
|
const Parallel::Communication& comm,
|
||||||
bool glift_debug
|
bool glift_debug)
|
||||||
) :
|
: well_state_{well_state}
|
||||||
well_state_{well_state},
|
, group_state_{group_state}
|
||||||
group_state_{group_state},
|
, deferred_logger_{deferred_logger}
|
||||||
deferred_logger_{deferred_logger},
|
, comm_{comm}
|
||||||
comm_{comm},
|
, debug{glift_debug}
|
||||||
debug{glift_debug}
|
{}
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* Protected methods in alphabetical order
|
* Protected methods in alphabetical order
|
||||||
****************************************/
|
****************************************/
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
int
|
int
|
||||||
GasLiftCommon::
|
GasLiftCommon<Scalar>::debugUpdateGlobalCounter_() const
|
||||||
debugUpdateGlobalCounter_() const
|
|
||||||
{
|
{
|
||||||
auto count = this->well_state_.gliftUpdateDebugCounter();
|
auto count = this->well_state_.gliftUpdateDebugCounter();
|
||||||
const std::string msg = fmt::format("global counter = {}", count);
|
const std::string msg = fmt::format("global counter = {}", count);
|
||||||
@ -59,9 +56,9 @@ debugUpdateGlobalCounter_() const
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftCommon::
|
void GasLiftCommon<Scalar>::
|
||||||
displayDebugMessageOnRank0_(const std::string &msg) const
|
displayDebugMessageOnRank0_(const std::string& msg) const
|
||||||
{
|
{
|
||||||
// This output should be identical for all ranks.
|
// This output should be identical for all ranks.
|
||||||
|
|
||||||
@ -71,12 +68,13 @@ displayDebugMessageOnRank0_(const std::string &msg) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftCommon::
|
void GasLiftCommon<Scalar>::
|
||||||
logMessage_(
|
logMessage_(const std::string& prefix,
|
||||||
const std::string& prefix, const std::string& msg, MessageType msg_type) const
|
const std::string& msg,
|
||||||
|
MessageType msg_type) const
|
||||||
{
|
{
|
||||||
std::string rank = "";
|
std::string rank;
|
||||||
if (this->comm_.size() > 1) {
|
if (this->comm_.size() > 1) {
|
||||||
rank = fmt::format(" Rank #{} :", this->comm_.rank());
|
rank = fmt::format(" Rank #{} :", this->comm_.rank());
|
||||||
}
|
}
|
||||||
@ -105,9 +103,6 @@ logMessage_(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************
|
template class GasLiftCommon<double>;
|
||||||
* Private methods in alphabetical order
|
|
||||||
****************************************/
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
@ -24,39 +24,37 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm {
|
||||||
{
|
|
||||||
|
|
||||||
class DeferredLogger;
|
class DeferredLogger;
|
||||||
template<class Scalar> class GroupState;
|
template<class Scalar> class GroupState;
|
||||||
template<class Scalar> class WellState;
|
template<class Scalar> class WellState;
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
class GasLiftCommon
|
class GasLiftCommon
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~GasLiftCommon() = default;
|
virtual ~GasLiftCommon() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GasLiftCommon(
|
GasLiftCommon(WellState<Scalar>& well_state,
|
||||||
WellState<double>& well_state,
|
const GroupState<Scalar>& group_state,
|
||||||
const GroupState<double>& group_state,
|
DeferredLogger& deferred_logger,
|
||||||
DeferredLogger &deferred_logger,
|
const Parallel::Communication& comm,
|
||||||
const Parallel::Communication& comm,
|
bool glift_debug);
|
||||||
bool debug
|
|
||||||
);
|
|
||||||
enum class MessageType { INFO, WARNING };
|
enum class MessageType { INFO, WARNING };
|
||||||
|
|
||||||
int debugUpdateGlobalCounter_() const;
|
int debugUpdateGlobalCounter_() const;
|
||||||
virtual void displayDebugMessage_(const std::string& msg) const = 0;
|
virtual void displayDebugMessage_(const std::string& msg) const = 0;
|
||||||
void displayDebugMessageOnRank0_(const std::string &msg) const;
|
void displayDebugMessageOnRank0_(const std::string& msg) const;
|
||||||
void logMessage_(
|
void logMessage_(const std::string& prefix,
|
||||||
const std::string& prefix,
|
const std::string& msg,
|
||||||
const std::string& msg,
|
MessageType msg_type = MessageType::INFO) const;
|
||||||
MessageType msg_type = MessageType::INFO) const;
|
|
||||||
|
|
||||||
WellState<double>& well_state_;
|
WellState<Scalar>& well_state_;
|
||||||
const GroupState<double>& group_state_;
|
const GroupState<Scalar>& group_state_;
|
||||||
DeferredLogger &deferred_logger_;
|
DeferredLogger& deferred_logger_;
|
||||||
const Parallel::Communication& comm_;
|
const Parallel::Communication& comm_;
|
||||||
bool debug;
|
bool debug;
|
||||||
// By setting this variable to true we restrict some debug output
|
// By setting this variable to true we restrict some debug output
|
||||||
|
@ -32,21 +32,20 @@
|
|||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
GasLiftGroupInfo::
|
template<class Scalar>
|
||||||
GasLiftGroupInfo(
|
GasLiftGroupInfo<Scalar>::
|
||||||
GLiftEclWells &ecl_wells,
|
GasLiftGroupInfo(GLiftEclWells& ecl_wells,
|
||||||
const Schedule &schedule,
|
const Schedule& schedule,
|
||||||
const SummaryState &summary_state,
|
const SummaryState& summary_state,
|
||||||
const int report_step_idx,
|
const int report_step_idx,
|
||||||
const int iteration_idx,
|
const int iteration_idx,
|
||||||
const PhaseUsage &phase_usage,
|
const PhaseUsage& phase_usage,
|
||||||
DeferredLogger &deferred_logger,
|
DeferredLogger& deferred_logger,
|
||||||
WellState<double>& well_state,
|
WellState<Scalar>& well_state,
|
||||||
const GroupState<double>& group_state,
|
const GroupState<Scalar>& group_state,
|
||||||
const Communication &comm,
|
const Communication& comm,
|
||||||
bool glift_debug
|
bool glift_debug)
|
||||||
) :
|
: GasLiftCommon<Scalar>(well_state, group_state, deferred_logger, comm, glift_debug)
|
||||||
GasLiftCommon(well_state, group_state, deferred_logger, comm, glift_debug)
|
|
||||||
, ecl_wells_{ecl_wells}
|
, ecl_wells_{ecl_wells}
|
||||||
, schedule_{schedule}
|
, schedule_{schedule}
|
||||||
, summary_state_{summary_state}
|
, summary_state_{summary_state}
|
||||||
@ -54,69 +53,70 @@ GasLiftGroupInfo(
|
|||||||
, iteration_idx_{iteration_idx}
|
, iteration_idx_{iteration_idx}
|
||||||
, phase_usage_{phase_usage}
|
, phase_usage_{phase_usage}
|
||||||
, glo_{schedule_.glo(report_step_idx_)}
|
, glo_{schedule_.glo(report_step_idx_)}
|
||||||
{
|
{}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* Public methods in alphabetical order
|
* Public methods in alphabetical order
|
||||||
****************************************/
|
****************************************/
|
||||||
|
|
||||||
double
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
alqRate(const std::string& group_name)
|
alqRate(const std::string& group_name)
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.alq();
|
return group_rate.alq();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
int GasLiftGroupInfo<Scalar>::
|
||||||
getGroupIdx(const std::string& group_name)
|
getGroupIdx(const std::string& group_name)
|
||||||
{
|
{
|
||||||
return this->group_idx_.at(group_name);
|
return this->group_idx_.at(group_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
gasRate(const std::string& group_name) const
|
gasRate(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.gasRate();
|
return group_rate.gasRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
gasPotential(const std::string& group_name) const
|
gasPotential(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.gasPotential();
|
return group_rate.gasPotential();
|
||||||
}
|
}
|
||||||
double
|
|
||||||
GasLiftGroupInfo::
|
template<class Scalar>
|
||||||
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
waterPotential(const std::string& group_name) const
|
waterPotential(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.waterPotential();
|
return group_rate.waterPotential();
|
||||||
}
|
}
|
||||||
double
|
|
||||||
GasLiftGroupInfo::
|
template<class Scalar>
|
||||||
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
oilPotential(const std::string& group_name) const
|
oilPotential(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.oilPotential();
|
return group_rate.oilPotential();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::optional<Scalar>
|
||||||
|
GasLiftGroupInfo<Scalar>::
|
||||||
gasTarget(const std::string& group_name) const
|
gasTarget(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.gasTarget();
|
return group_rate.gasTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
getRate(Rate rate_type, const std::string& group_name) const
|
getRate(Rate rate_type, const std::string& group_name) const
|
||||||
{
|
{
|
||||||
switch (rate_type) {
|
switch (rate_type) {
|
||||||
@ -133,8 +133,9 @@ getRate(Rate rate_type, const std::string& group_name) const
|
|||||||
throw std::runtime_error("This should not happen");
|
throw std::runtime_error("This should not happen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double
|
|
||||||
GasLiftGroupInfo::
|
template<class Scalar>
|
||||||
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
getPotential(Rate rate_type, const std::string& group_name) const
|
getPotential(Rate rate_type, const std::string& group_name) const
|
||||||
{
|
{
|
||||||
switch (rate_type) {
|
switch (rate_type) {
|
||||||
@ -152,8 +153,9 @@ getPotential(Rate rate_type, const std::string& group_name) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<double, double, double, double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::tuple<Scalar, Scalar, Scalar, Scalar>
|
||||||
|
GasLiftGroupInfo<Scalar>::
|
||||||
getRates(const int group_idx) const
|
getRates(const int group_idx) const
|
||||||
{
|
{
|
||||||
const auto& group_name = groupIdxToName(group_idx);
|
const auto& group_name = groupIdxToName(group_idx);
|
||||||
@ -161,8 +163,9 @@ getRates(const int group_idx) const
|
|||||||
return std::make_tuple(rates.oilRate(), rates.gasRate(), rates.waterRate(), rates.alq());
|
return std::make_tuple(rates.oilRate(), rates.gasRate(), rates.waterRate(), rates.alq());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::optional<Scalar>
|
||||||
|
GasLiftGroupInfo<Scalar>::
|
||||||
getTarget(Rate rate_type, const std::string& group_name) const
|
getTarget(Rate rate_type, const std::string& group_name) const
|
||||||
{
|
{
|
||||||
switch (rate_type) {
|
switch (rate_type) {
|
||||||
@ -180,19 +183,21 @@ getTarget(Rate rate_type, const std::string& group_name) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string,double>>&
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::vector<std::pair<std::string,Scalar>>&
|
||||||
|
GasLiftGroupInfo<Scalar>::
|
||||||
getWellGroups(const std::string& well_name)
|
getWellGroups(const std::string& well_name)
|
||||||
{
|
{
|
||||||
assert(this->well_group_map_.count(well_name) == 1);
|
assert(this->well_group_map_.count(well_name) == 1);
|
||||||
return this->well_group_map_[well_name];
|
return this->well_group_map_[well_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
const std::string&
|
const std::string&
|
||||||
GasLiftGroupInfo::
|
GasLiftGroupInfo<Scalar>::
|
||||||
groupIdxToName(int group_idx) const
|
groupIdxToName(int group_idx) const
|
||||||
{
|
{
|
||||||
const std::string *group_name = nullptr;
|
const std::string* group_name = nullptr;
|
||||||
// TODO: An alternative to the below loop is to set up a reverse map from idx ->
|
// TODO: An alternative to the below loop is to set up a reverse map from idx ->
|
||||||
// string, then we could in theory do faster lookup here..
|
// string, then we could in theory do faster lookup here..
|
||||||
for (const auto& [key, value] : this->group_idx_) {
|
for (const auto& [key, value] : this->group_idx_) {
|
||||||
@ -209,75 +214,80 @@ groupIdxToName(int group_idx) const
|
|||||||
return *group_name;
|
return *group_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
bool GasLiftGroupInfo<Scalar>::
|
||||||
hasAnyTarget(const std::string& group_name) const
|
hasAnyTarget(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
return oilTarget(group_name) || gasTarget(group_name)
|
return oilTarget(group_name) || gasTarget(group_name)
|
||||||
|| waterTarget(group_name) || liquidTarget(group_name);
|
|| waterTarget(group_name) || liquidTarget(group_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
bool GasLiftGroupInfo<Scalar>::
|
||||||
hasWell(const std::string& well_name)
|
hasWell(const std::string& well_name)
|
||||||
{
|
{
|
||||||
return this->well_group_map_.count(well_name) == 1;
|
return this->well_group_map_.count(well_name) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
initialize()
|
initialize()
|
||||||
{
|
{
|
||||||
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
|
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
|
||||||
initializeGroupRatesRecursive_(group);
|
initializeGroupRatesRecursive_(group);
|
||||||
std::vector<std::string> group_names;
|
std::vector<std::string> group_names;
|
||||||
std::vector<double> group_efficiency;
|
std::vector<Scalar> group_efficiency;
|
||||||
initializeWell2GroupMapRecursive_(
|
initializeWell2GroupMapRecursive_(
|
||||||
group, group_names, group_efficiency, /*current efficiency=*/1.0);
|
group, group_names, group_efficiency, /*current efficiency=*/1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::optional<Scalar>
|
||||||
liquidTarget(const std::string &group_name) const
|
GasLiftGroupInfo<Scalar>::
|
||||||
|
liquidTarget(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.liquidTarget();
|
return group_rate.liquidTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::optional<Scalar>
|
||||||
|
GasLiftGroupInfo<Scalar>::
|
||||||
maxAlq(const std::string& group_name)
|
maxAlq(const std::string& group_name)
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.maxAlq();
|
return group_rate.maxAlq();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::optional<Scalar>
|
||||||
|
GasLiftGroupInfo<Scalar>::
|
||||||
maxTotalGasRate(const std::string& group_name)
|
maxTotalGasRate(const std::string& group_name)
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.maxTotalGasRate();
|
return group_rate.maxTotalGasRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
oilRate(const std::string &group_name) const
|
oilRate(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.oilRate();
|
return group_rate.oilRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::optional<Scalar>
|
||||||
oilTarget(const std::string &group_name) const
|
GasLiftGroupInfo<Scalar>::
|
||||||
|
oilTarget(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.oilTarget();
|
return group_rate.oilTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
const std::string
|
const std::string
|
||||||
GasLiftGroupInfo::
|
GasLiftGroupInfo<Scalar>::
|
||||||
rateToString(Rate rate) {
|
rateToString(Rate rate) {
|
||||||
switch (rate) {
|
switch (rate) {
|
||||||
case Rate::oil:
|
case Rate::oil:
|
||||||
@ -293,34 +303,42 @@ rateToString(Rate rate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
Scalar GasLiftGroupInfo<Scalar>::
|
||||||
waterRate(const std::string &group_name) const
|
waterRate(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.waterRate();
|
return group_rate.waterRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::optional<Scalar>
|
||||||
waterTarget(const std::string &group_name) const
|
GasLiftGroupInfo<Scalar>::
|
||||||
|
waterTarget(const std::string& group_name) const
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
return group_rate.waterTarget();
|
return group_rate.waterTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
update(
|
update(const std::string& group_name,
|
||||||
const std::string &group_name, double delta_oil, double delta_gas, double delta_water, double delta_alq)
|
Scalar delta_oil,
|
||||||
|
Scalar delta_gas,
|
||||||
|
Scalar delta_water,
|
||||||
|
Scalar delta_alq)
|
||||||
{
|
{
|
||||||
auto& group_rate = this->group_rate_map_.at(group_name);
|
auto& group_rate = this->group_rate_map_.at(group_name);
|
||||||
group_rate.update(delta_oil, delta_gas, delta_water, delta_alq);
|
group_rate.update(delta_oil, delta_gas, delta_water, delta_alq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
updateRate(int idx, double oil_rate, double gas_rate, double water_rate, double alq)
|
updateRate(int idx,
|
||||||
|
Scalar oil_rate,
|
||||||
|
Scalar gas_rate,
|
||||||
|
Scalar water_rate,
|
||||||
|
Scalar alq)
|
||||||
{
|
{
|
||||||
const auto& group_name = groupIdxToName(idx);
|
const auto& group_name = groupIdxToName(idx);
|
||||||
auto& rates = this->group_rate_map_.at(group_name);
|
auto& rates = this->group_rate_map_.at(group_name);
|
||||||
@ -331,10 +349,9 @@ updateRate(int idx, double oil_rate, double gas_rate, double water_rate, double
|
|||||||
* Protected methods in alphabetical order
|
* Protected methods in alphabetical order
|
||||||
****************************************/
|
****************************************/
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
bool
|
bool GasLiftGroupInfo<Scalar>::
|
||||||
GasLiftGroupInfo::
|
checkDoGasLiftOptimization_(const std::string& well_name)
|
||||||
checkDoGasLiftOptimization_(const std::string &well_name)
|
|
||||||
{
|
{
|
||||||
if (this->well_state_.gliftCheckAlqOscillation(well_name)) {
|
if (this->well_state_.gliftCheckAlqOscillation(well_name)) {
|
||||||
displayDebugMessage_(
|
displayDebugMessage_(
|
||||||
@ -390,9 +407,9 @@ checkDoGasLiftOptimization_(const std::string &well_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
bool GasLiftGroupInfo<Scalar>::
|
||||||
checkNewtonIterationIdxOk_(const std::string &well_name)
|
checkNewtonIterationIdxOk_(const std::string& well_name)
|
||||||
{
|
{
|
||||||
if (this->glo_.all_newton()) {
|
if (this->glo_.all_newton()) {
|
||||||
const int nupcol = this->schedule_[this->report_step_idx_].nupcol();
|
const int nupcol = this->schedule_[this->report_step_idx_].nupcol();
|
||||||
@ -419,17 +436,20 @@ checkNewtonIterationIdxOk_(const std::string &well_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is called by each rank, but the value of "well_name" should be unique
|
// This is called by each rank, but the value of "well_name" should be unique
|
||||||
// across ranks
|
// across ranks
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
debugDisplayWellContribution_(
|
debugDisplayWellContribution_(const std::string& gr_name,
|
||||||
const std::string& gr_name, const std::string& well_name,
|
const std::string& well_name,
|
||||||
double eff_factor,
|
Scalar eff_factor,
|
||||||
double well_oil_rate, double well_gas_rate, double well_water_rate,
|
Scalar well_oil_rate,
|
||||||
double well_alq,
|
Scalar well_gas_rate,
|
||||||
double oil_rate, double gas_rate, double water_rate,
|
Scalar well_water_rate,
|
||||||
double alq
|
Scalar well_alq,
|
||||||
) const
|
Scalar oil_rate,
|
||||||
|
Scalar gas_rate,
|
||||||
|
Scalar water_rate,
|
||||||
|
Scalar alq) const
|
||||||
{
|
{
|
||||||
const std::string msg = fmt::format("Group rate for {} : Well {} : "
|
const std::string msg = fmt::format("Group rate for {} : Well {} : "
|
||||||
"eff_factor = {}, oil_rate = {}, gas_rate = {}, water_rate = {}, "
|
"eff_factor = {}, oil_rate = {}, gas_rate = {}, water_rate = {}, "
|
||||||
@ -439,47 +459,49 @@ debugDisplayWellContribution_(
|
|||||||
displayDebugMessage_(msg);
|
displayDebugMessage_(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
debugDisplayUpdatedGroupRates(
|
debugDisplayUpdatedGroupRates(const std::string& name,
|
||||||
const std::string& name,
|
Scalar oil_rate,
|
||||||
double oil_rate, double gas_rate, double water_rate, double alq) const
|
Scalar gas_rate,
|
||||||
|
Scalar water_rate,
|
||||||
|
Scalar alq) const
|
||||||
{
|
{
|
||||||
const std::string msg = fmt::format("Updated group info for {} : "
|
const std::string msg = fmt::format("Updated group info for {} : "
|
||||||
"oil_rate = {}, gas_rate = {}, water_rate = {}, alq = {}",
|
"oil_rate = {}, gas_rate = {}, water_rate = {}, alq = {}",
|
||||||
name, oil_rate, gas_rate, water_rate, alq);
|
name, oil_rate, gas_rate, water_rate, alq);
|
||||||
displayDebugMessageOnRank0_(msg);
|
this->displayDebugMessageOnRank0_(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
debugEndInitializeGroup(const std::string& name) const
|
debugEndInitializeGroup(const std::string& name) const
|
||||||
{
|
{
|
||||||
const std::string msg = fmt::format("Finished with group {} ...", name);
|
const std::string msg = fmt::format("Finished with group {} ...", name);
|
||||||
displayDebugMessageOnRank0_(msg);
|
this->displayDebugMessageOnRank0_(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
debugStartInitializeGroup(const std::string& name) const
|
debugStartInitializeGroup(const std::string& name) const
|
||||||
{
|
{
|
||||||
const std::string msg = fmt::format("Initializing group {} ...", name);
|
const std::string msg = fmt::format("Initializing group {} ...", name);
|
||||||
displayDebugMessageOnRank0_(msg);
|
this->displayDebugMessageOnRank0_(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
displayDebugMessage_(const std::string &msg) const
|
displayDebugMessage_(const std::string& msg) const
|
||||||
{
|
{
|
||||||
if (this->debug) {
|
if (this->debug) {
|
||||||
const std::string message = fmt::format("Init group info : {}", msg);
|
const std::string message = fmt::format("Init group info : {}", msg);
|
||||||
logMessage_(/*prefix=*/"GLIFT", message);
|
this->logMessage_(/*prefix=*/"GLIFT", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
displayDebugMessage_(const std::string &msg, const std::string &well_name)
|
displayDebugMessage_(const std::string& msg, const std::string& well_name)
|
||||||
{
|
{
|
||||||
if (this->debug) {
|
if (this->debug) {
|
||||||
const std::string message = fmt::format("Well {} : {}", well_name, msg);
|
const std::string message = fmt::format("Well {} : {}", well_name, msg);
|
||||||
@ -487,9 +509,9 @@ displayDebugMessage_(const std::string &msg, const std::string &well_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
std::tuple<double, double, double, double, double, double>
|
std::tuple<Scalar, Scalar, Scalar, Scalar, Scalar, Scalar>
|
||||||
GasLiftGroupInfo::
|
GasLiftGroupInfo<Scalar>::
|
||||||
getProducerWellRates_(const Well* well, int well_index)
|
getProducerWellRates_(const Well* well, int well_index)
|
||||||
{
|
{
|
||||||
const auto& pu = this->phase_usage_;
|
const auto& pu = this->phase_usage_;
|
||||||
@ -509,21 +531,21 @@ getProducerWellRates_(const Well* well, int well_index)
|
|||||||
: 0.0;
|
: 0.0;
|
||||||
|
|
||||||
const auto controls = well->productionControls(this->summary_state_);
|
const auto controls = well->productionControls(this->summary_state_);
|
||||||
double oil_rate = oil_pot;
|
Scalar oil_rate = oil_pot;
|
||||||
if (controls.hasControl(Well::ProducerCMode::ORAT)) {
|
if (controls.hasControl(Well::ProducerCMode::ORAT)) {
|
||||||
oil_rate = std::min(controls.oil_rate, oil_rate);
|
oil_rate = std::min(static_cast<Scalar>(controls.oil_rate), oil_rate);
|
||||||
}
|
}
|
||||||
double gas_rate = gas_pot;
|
Scalar gas_rate = gas_pot;
|
||||||
if (controls.hasControl(Well::ProducerCMode::GRAT)) {
|
if (controls.hasControl(Well::ProducerCMode::GRAT)) {
|
||||||
gas_rate = std::min(controls.gas_rate, gas_rate);
|
gas_rate = std::min(static_cast<Scalar>(controls.gas_rate), gas_rate);
|
||||||
}
|
}
|
||||||
double water_rate = water_pot;
|
Scalar water_rate = water_pot;
|
||||||
if (controls.hasControl(Well::ProducerCMode::WRAT)) {
|
if (controls.hasControl(Well::ProducerCMode::WRAT)) {
|
||||||
water_rate = std::min(controls.water_rate, water_rate);
|
water_rate = std::min(static_cast<Scalar>(controls.water_rate), water_rate);
|
||||||
}
|
}
|
||||||
if (controls.hasControl(Well::ProducerCMode::LRAT)) {
|
if (controls.hasControl(Well::ProducerCMode::LRAT)) {
|
||||||
double liquid_rate = oil_rate + water_rate;
|
Scalar liquid_rate = oil_rate + water_rate;
|
||||||
double liquid_rate_lim = std::min(controls.liquid_rate, liquid_rate);
|
Scalar liquid_rate_lim = std::min(static_cast<Scalar>(controls.liquid_rate), liquid_rate);
|
||||||
water_rate = water_rate / liquid_rate * liquid_rate_lim;
|
water_rate = water_rate / liquid_rate * liquid_rate_lim;
|
||||||
oil_rate = oil_rate / liquid_rate * liquid_rate_lim;
|
oil_rate = oil_rate / liquid_rate * liquid_rate_lim;
|
||||||
}
|
}
|
||||||
@ -531,11 +553,12 @@ getProducerWellRates_(const Well* well, int well_index)
|
|||||||
return {oil_rate, gas_rate, water_rate, oil_pot, gas_pot, water_pot};
|
return {oil_rate, gas_rate, water_rate, oil_pot, gas_pot, water_pot};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<double, double, double, double, double, double, double>
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
std::tuple<Scalar, Scalar, Scalar, Scalar, Scalar, Scalar, Scalar>
|
||||||
initializeGroupRatesRecursive_(const Group &group)
|
GasLiftGroupInfo<Scalar>::
|
||||||
|
initializeGroupRatesRecursive_(const Group& group)
|
||||||
{
|
{
|
||||||
std::array<double,7> rates{};
|
std::array<Scalar,7> rates{};
|
||||||
if (this->debug) debugStartInitializeGroup(group.name());
|
if (this->debug) debugStartInitializeGroup(group.name());
|
||||||
auto& [oil_rate, water_rate, gas_rate, oil_potential, water_potential, gas_potential, alq] = rates;
|
auto& [oil_rate, water_rate, gas_rate, oil_potential, water_potential, gas_potential, alq] = rates;
|
||||||
if (group.wellgroup()) {
|
if (group.wellgroup()) {
|
||||||
@ -554,7 +577,7 @@ initializeGroupRatesRecursive_(const Group &group)
|
|||||||
if (well->isProducer()) {
|
if (well->isProducer()) {
|
||||||
auto [sw_oil_rate, sw_gas_rate, sw_water_rate, sw_oil_pot, sw_gas_pot, sw_water_pot] = getProducerWellRates_(well, index);
|
auto [sw_oil_rate, sw_gas_rate, sw_water_rate, sw_oil_pot, sw_gas_pot, sw_water_pot] = getProducerWellRates_(well, index);
|
||||||
auto sw_alq = this->well_state_.getALQ(well_name);
|
auto sw_alq = this->well_state_.getALQ(well_name);
|
||||||
double factor = well->getEfficiencyFactor();
|
Scalar factor = well->getEfficiencyFactor();
|
||||||
oil_rate += (factor * sw_oil_rate);
|
oil_rate += (factor * sw_oil_rate);
|
||||||
gas_rate += (factor * sw_gas_rate);
|
gas_rate += (factor * sw_gas_rate);
|
||||||
water_rate += (factor * sw_water_rate);
|
water_rate += (factor * sw_water_rate);
|
||||||
@ -595,7 +618,7 @@ initializeGroupRatesRecursive_(const Group &group)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->debug) debugEndInitializeGroup(group.name());
|
if (this->debug) debugEndInitializeGroup(group.name());
|
||||||
std::optional<double> oil_target, gas_target, water_target, liquid_target, max_total_gas, max_alq;
|
std::optional<Scalar> oil_target, gas_target, water_target, liquid_target, max_total_gas, max_alq;
|
||||||
const auto controls = group.productionControls(this->summary_state_);
|
const auto controls = group.productionControls(this->summary_state_);
|
||||||
if (group.has_control(Group::ProductionCMode::LRAT)) {
|
if (group.has_control(Group::ProductionCMode::LRAT)) {
|
||||||
liquid_target = controls.liquid_target;
|
liquid_target = controls.liquid_target;
|
||||||
@ -610,21 +633,21 @@ initializeGroupRatesRecursive_(const Group &group)
|
|||||||
water_target = controls.water_target;
|
water_target = controls.water_target;
|
||||||
}
|
}
|
||||||
if (this->glo_.has_group(group.name())) {
|
if (this->glo_.has_group(group.name())) {
|
||||||
const auto &gl_group = this->glo_.group(group.name());
|
const auto& gl_group = this->glo_.group(group.name());
|
||||||
max_alq = gl_group.max_lift_gas();
|
max_alq = gl_group.max_lift_gas();
|
||||||
max_total_gas = gl_group.max_total_gas();
|
max_total_gas = gl_group.max_total_gas();
|
||||||
}
|
}
|
||||||
if (oil_target || liquid_target || water_target || gas_target || max_total_gas || max_alq) {
|
if (oil_target || liquid_target || water_target || gas_target || max_total_gas || max_alq) {
|
||||||
updateGroupIdxMap_(group.name());
|
updateGroupIdxMap_(group.name());
|
||||||
if(oil_target)
|
if (oil_target)
|
||||||
oil_rate = std::min(oil_rate, *oil_target);
|
oil_rate = std::min(oil_rate, *oil_target);
|
||||||
if(gas_target)
|
if (gas_target)
|
||||||
gas_rate = std::min(gas_rate, *gas_target);
|
gas_rate = std::min(gas_rate, *gas_target);
|
||||||
if(water_target)
|
if (water_target)
|
||||||
water_rate = std::min(water_rate, *water_target);
|
water_rate = std::min(water_rate, *water_target);
|
||||||
if(liquid_target) {
|
if (liquid_target) {
|
||||||
double liquid_rate = oil_rate + water_rate;
|
Scalar liquid_rate = oil_rate + water_rate;
|
||||||
double liquid_rate_limited = std::min(liquid_rate, *liquid_target);
|
Scalar liquid_rate_limited = std::min(liquid_rate, *liquid_target);
|
||||||
oil_rate = oil_rate / liquid_rate * liquid_rate_limited;
|
oil_rate = oil_rate / liquid_rate * liquid_rate_limited;
|
||||||
water_rate = water_rate / liquid_rate * liquid_rate_limited;
|
water_rate = water_rate / liquid_rate * liquid_rate_limited;
|
||||||
}
|
}
|
||||||
@ -641,15 +664,14 @@ initializeGroupRatesRecursive_(const Group &group)
|
|||||||
return std::make_tuple(oil_rate, gas_rate, water_rate, oil_potential, gas_potential, water_potential, alq);
|
return std::make_tuple(oil_rate, gas_rate, water_rate, oil_potential, gas_potential, water_potential, alq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
initializeWell2GroupMapRecursive_(
|
initializeWell2GroupMapRecursive_(const Group& group,
|
||||||
const Group &group,
|
std::vector<std::string>& group_names,
|
||||||
std::vector<std::string> &group_names,
|
std::vector<Scalar>& group_efficiency,
|
||||||
std::vector<double> &group_efficiency,
|
Scalar cur_efficiency)
|
||||||
double cur_efficiency)
|
|
||||||
{
|
{
|
||||||
double gfac = group.getGroupEfficiencyFactor();
|
Scalar gfac = group.getGroupEfficiencyFactor();
|
||||||
cur_efficiency = gfac * cur_efficiency;
|
cur_efficiency = gfac * cur_efficiency;
|
||||||
for (auto &item : group_efficiency) {
|
for (auto &item : group_efficiency) {
|
||||||
item *= gfac;
|
item *= gfac;
|
||||||
@ -668,17 +690,17 @@ initializeWell2GroupMapRecursive_(
|
|||||||
if (checkDoGasLiftOptimization_(well_name)) {
|
if (checkDoGasLiftOptimization_(well_name)) {
|
||||||
const auto &well = this->schedule_.getWell(
|
const auto &well = this->schedule_.getWell(
|
||||||
well_name, this->report_step_idx_);
|
well_name, this->report_step_idx_);
|
||||||
double wfac = well.getEfficiencyFactor();
|
Scalar wfac = well.getEfficiencyFactor();
|
||||||
auto [itr, success] = this->well_group_map_.insert(
|
auto [itr, success] = this->well_group_map_.insert(
|
||||||
{well_name, /*empty vector*/ {}});
|
{well_name, /*empty vector*/ {}});
|
||||||
assert(success);
|
assert(success);
|
||||||
auto &vec = itr->second;
|
auto& vec = itr->second;
|
||||||
assert(group_names.size() == group_efficiency.size());
|
assert(group_names.size() == group_efficiency.size());
|
||||||
auto iter2 = group_efficiency.begin();
|
auto iter2 = group_efficiency.begin();
|
||||||
for (auto iter1 = group_names.begin();
|
for (auto iter1 = group_names.begin();
|
||||||
iter1 != group_names.end(); ++iter1)
|
iter1 != group_names.end(); ++iter1)
|
||||||
{
|
{
|
||||||
double efficiency = (*iter2) * wfac;
|
Scalar efficiency = (*iter2) * wfac;
|
||||||
vec.emplace_back(/*group_name=*/*iter1, efficiency);
|
vec.emplace_back(/*group_name=*/*iter1, efficiency);
|
||||||
++iter2;
|
++iter2;
|
||||||
}
|
}
|
||||||
@ -701,15 +723,13 @@ initializeWell2GroupMapRecursive_(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: It would be more efficient if the group idx map was build once
|
// TODO: It would be more efficient if the group idx map was build once
|
||||||
// per time step (or better: once per report step) and saved e.g. in
|
// per time step (or better: once per report step) and saved e.g. in
|
||||||
// the well state object, instead of rebuilding here for each of
|
// the well state object, instead of rebuilding here for each of
|
||||||
// NUPCOL well iteration for each time step.
|
// NUPCOL well iteration for each time step.
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftGroupInfo::
|
void GasLiftGroupInfo<Scalar>::
|
||||||
updateGroupIdxMap_(const std::string &group_name)
|
updateGroupIdxMap_(const std::string& group_name)
|
||||||
{
|
{
|
||||||
if (this->group_idx_.count(group_name) == 0) {
|
if (this->group_idx_.count(group_name) == 0) {
|
||||||
//auto [itr, success] =
|
//auto [itr, success] =
|
||||||
@ -718,4 +738,6 @@ updateGroupIdxMap_(const std::string &group_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template class GasLiftGroupInfo<double>;
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
@ -29,8 +29,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm {
|
||||||
{
|
|
||||||
|
|
||||||
class DeferredLogger;
|
class DeferredLogger;
|
||||||
class GasLiftOpt;
|
class GasLiftOpt;
|
||||||
@ -41,7 +40,8 @@ class SummaryState;
|
|||||||
class Well;
|
class Well;
|
||||||
template<class Scalar> class WellState;
|
template<class Scalar> class WellState;
|
||||||
|
|
||||||
class GasLiftGroupInfo : public GasLiftCommon
|
template<class Scalar>
|
||||||
|
class GasLiftGroupInfo : public GasLiftCommon<Scalar>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
class GroupRates;
|
class GroupRates;
|
||||||
@ -51,7 +51,7 @@ protected:
|
|||||||
// factors of the child groups of the group all the way down
|
// factors of the child groups of the group all the way down
|
||||||
// to the well group.
|
// to the well group.
|
||||||
using Well2GroupMap =
|
using Well2GroupMap =
|
||||||
std::map<std::string, std::vector<std::pair<std::string,double>>>;
|
std::map<std::string, std::vector<std::pair<std::string,Scalar>>>;
|
||||||
using GroupRateMap =
|
using GroupRateMap =
|
||||||
std::map<std::string, GroupRates>;
|
std::map<std::string, GroupRates>;
|
||||||
using GroupIdxMap = std::map<std::string, int>;
|
using GroupIdxMap = std::map<std::string, int>;
|
||||||
@ -62,128 +62,155 @@ protected:
|
|||||||
static const int Water = BlackoilPhases::Aqua;
|
static const int Water = BlackoilPhases::Aqua;
|
||||||
static const int Oil = BlackoilPhases::Liquid;
|
static const int Oil = BlackoilPhases::Liquid;
|
||||||
static const int Gas = BlackoilPhases::Vapour;
|
static const int Gas = BlackoilPhases::Vapour;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Rate {oil, gas, water, liquid};
|
enum class Rate {oil, gas, water, liquid};
|
||||||
|
|
||||||
using GLiftEclWells = std::map<std::string,std::pair<const Well *,int>>;
|
using GLiftEclWells = std::map<std::string,std::pair<const Well *,int>>;
|
||||||
GasLiftGroupInfo(
|
GasLiftGroupInfo(GLiftEclWells& ecl_wells,
|
||||||
GLiftEclWells& ecl_wells,
|
const Schedule& schedule,
|
||||||
const Schedule& schedule,
|
const SummaryState& summary_state,
|
||||||
const SummaryState& summary_state,
|
const int report_step_idx,
|
||||||
const int report_step_idx,
|
const int iteration_idx,
|
||||||
const int iteration_idx,
|
const PhaseUsage& phase_usage,
|
||||||
const PhaseUsage& phase_usage,
|
DeferredLogger& deferred_logger,
|
||||||
DeferredLogger& deferred_logger,
|
WellState<Scalar>& well_state,
|
||||||
WellState<double>& well_state,
|
const GroupState<Scalar>& group_state,
|
||||||
const GroupState<double>& group_state,
|
const Parallel::Communication& comm,
|
||||||
const Parallel::Communication& comm,
|
bool glift_debug);
|
||||||
bool glift_debug
|
|
||||||
);
|
|
||||||
std::vector<std::pair<std::string,double>>& getWellGroups(
|
|
||||||
const std::string& well_name);
|
|
||||||
|
|
||||||
double alqRate(const std::string& group_name);
|
std::vector<std::pair<std::string,Scalar>>&
|
||||||
double gasRate(const std::string& group_name) const;
|
getWellGroups(const std::string& well_name);
|
||||||
double gasPotential(const std::string& group_name) const;
|
|
||||||
double waterPotential(const std::string& group_name) const;
|
Scalar alqRate(const std::string& group_name);
|
||||||
double oilPotential(const std::string& group_name) const;
|
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);
|
int getGroupIdx(const std::string& group_name);
|
||||||
double getRate(Rate rate_type, const std::string& group_name) const;
|
Scalar getRate(Rate rate_type, const std::string& group_name) const;
|
||||||
double getPotential(Rate rate_type, const std::string& group_name) const;
|
Scalar getPotential(Rate rate_type, const std::string& group_name) const;
|
||||||
std::tuple<double,double,double,double> getRates(const int group_idx) const;
|
std::tuple<Scalar,Scalar,Scalar,Scalar> getRates(const int group_idx) const;
|
||||||
std::optional<double> gasTarget(const std::string& group_name) const;
|
std::optional<Scalar> gasTarget(const std::string& group_name) const;
|
||||||
std::optional<double> getTarget(
|
std::optional<Scalar> getTarget(Rate rate_type, const std::string& group_name) const;
|
||||||
Rate rate_type, const std::string& group_name) const;
|
|
||||||
const std::string& groupIdxToName(int group_idx) const;
|
const std::string& groupIdxToName(int group_idx) const;
|
||||||
bool hasAnyTarget(const std::string& group_name) const;
|
bool hasAnyTarget(const std::string& group_name) const;
|
||||||
bool hasWell(const std::string& well_name);
|
bool hasWell(const std::string& well_name);
|
||||||
void initialize();
|
void initialize();
|
||||||
std::optional<double> liquidTarget(const std::string& group_name) const;
|
std::optional<Scalar> liquidTarget(const std::string& group_name) const;
|
||||||
std::optional<double> maxAlq(const std::string& group_name);
|
std::optional<Scalar> maxAlq(const std::string& group_name);
|
||||||
std::optional<double> maxTotalGasRate(const std::string& group_name);
|
std::optional<Scalar> maxTotalGasRate(const std::string& group_name);
|
||||||
double oilRate(const std::string& group_name) const;
|
Scalar oilRate(const std::string& group_name) const;
|
||||||
std::optional<double> oilTarget(const std::string& group_name) const;
|
std::optional<Scalar> oilTarget(const std::string& group_name) const;
|
||||||
static const std::string rateToString(Rate rate);
|
static const std::string rateToString(Rate rate);
|
||||||
double waterRate(const std::string& group_name) const;
|
Scalar waterRate(const std::string& group_name) const;
|
||||||
std::optional<double> waterTarget(const std::string& group_name) const;
|
std::optional<Scalar> waterTarget(const std::string& group_name) const;
|
||||||
void update(const std::string& well_name,
|
void update(const std::string& well_name,
|
||||||
double delta_oil, double delta_gas, double delta_water, double delta_alq);
|
Scalar delta_oil,
|
||||||
void updateRate(int idx, double oil_rate, double gas_rate, double water_rate, double alq);
|
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_; }
|
const Well2GroupMap& wellGroupMap() { return well_group_map_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool checkDoGasLiftOptimization_(const std::string& well_name);
|
bool checkDoGasLiftOptimization_(const std::string& well_name);
|
||||||
bool checkNewtonIterationIdxOk_(const std::string& well_name);
|
bool checkNewtonIterationIdxOk_(const std::string& well_name);
|
||||||
void debugDisplayWellContribution_(
|
void debugDisplayWellContribution_(const std::string& gr_name,
|
||||||
const std::string& gr_name, const std::string& well_name,
|
const std::string& well_name,
|
||||||
double eff_factor,
|
Scalar eff_factor,
|
||||||
double well_oil_rate, double well_gas_rate, double well_water_rate,
|
Scalar well_oil_rate,
|
||||||
double well_alq,
|
Scalar well_gas_rate,
|
||||||
double oil_rate, double gas_rate, double water_rate,
|
Scalar well_water_rate,
|
||||||
double alq
|
Scalar well_alq,
|
||||||
) const;
|
Scalar oil_rate,
|
||||||
|
Scalar gas_rate,
|
||||||
|
Scalar water_rate,
|
||||||
|
Scalar alq) const;
|
||||||
void debugDisplayUpdatedGroupRates(const std::string& name,
|
void debugDisplayUpdatedGroupRates(const std::string& name,
|
||||||
double oil_rate, double gas_rate, double water_rate, double alq) const;
|
Scalar oil_rate,
|
||||||
|
Scalar gas_rate,
|
||||||
|
Scalar water_rate,
|
||||||
|
Scalar alq) const;
|
||||||
void debugEndInitializeGroup(const std::string& name) const;
|
void debugEndInitializeGroup(const std::string& name) const;
|
||||||
void debugStartInitializeGroup(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 override;
|
||||||
void displayDebugMessage_(const std::string& msg, const std::string& well_name);
|
void displayDebugMessage_(const std::string& msg, const std::string& well_name);
|
||||||
std::tuple<double, double, double, double, double, double>
|
|
||||||
getProducerWellRates_(const Well* well, const int index);
|
|
||||||
std::tuple<double, double, double, double, double, double, double>
|
|
||||||
initializeGroupRatesRecursive_(const Group &group);
|
|
||||||
void initializeWell2GroupMapRecursive_(
|
|
||||||
const Group& group, std::vector<std::string>& group_names,
|
|
||||||
std::vector<double>& group_efficiency, double cur_efficiency);
|
|
||||||
void updateGroupIdxMap_(const std::string& group_name);
|
|
||||||
|
|
||||||
|
std::tuple<Scalar, Scalar, Scalar, Scalar, Scalar, Scalar>
|
||||||
|
getProducerWellRates_(const Well* well, const int index);
|
||||||
|
|
||||||
|
std::tuple<Scalar, Scalar, Scalar, Scalar, Scalar, Scalar, Scalar>
|
||||||
|
initializeGroupRatesRecursive_(const Group &group);
|
||||||
|
|
||||||
|
void initializeWell2GroupMapRecursive_(const Group& group,
|
||||||
|
std::vector<std::string>& group_names,
|
||||||
|
std::vector<Scalar>& group_efficiency,
|
||||||
|
Scalar cur_efficiency);
|
||||||
|
void updateGroupIdxMap_(const std::string& group_name);
|
||||||
|
|
||||||
class GroupRates {
|
class GroupRates {
|
||||||
public:
|
public:
|
||||||
GroupRates( double oil_rate, double gas_rate, double water_rate, double alq,
|
GroupRates(Scalar oil_rate,
|
||||||
double oil_potential, double gas_potential, double water_potential,
|
Scalar gas_rate,
|
||||||
std::optional<double> oil_target,
|
Scalar water_rate,
|
||||||
std::optional<double> gas_target,
|
Scalar alq,
|
||||||
std::optional<double> water_target,
|
Scalar oil_potential,
|
||||||
std::optional<double> liquid_target,
|
Scalar gas_potential,
|
||||||
std::optional<double> total_gas,
|
Scalar water_potential,
|
||||||
std::optional<double> max_alq
|
std::optional<Scalar> oil_target,
|
||||||
) :
|
std::optional<Scalar> gas_target,
|
||||||
oil_rate_{oil_rate},
|
std::optional<Scalar> water_target,
|
||||||
gas_rate_{gas_rate},
|
std::optional<Scalar> liquid_target,
|
||||||
water_rate_{water_rate},
|
std::optional<Scalar> total_gas,
|
||||||
alq_{alq},
|
std::optional<Scalar> max_alq)
|
||||||
oil_potential_{oil_potential},
|
: oil_rate_{oil_rate}
|
||||||
gas_potential_{gas_potential},
|
, gas_rate_{gas_rate}
|
||||||
water_potential_{water_potential},
|
, water_rate_{water_rate}
|
||||||
oil_target_{oil_target},
|
, alq_{alq}
|
||||||
gas_target_{gas_target},
|
, oil_potential_{oil_potential}
|
||||||
water_target_{water_target},
|
, gas_potential_{gas_potential}
|
||||||
liquid_target_{liquid_target},
|
, water_potential_{water_potential}
|
||||||
total_gas_{total_gas},
|
, oil_target_{oil_target}
|
||||||
max_alq_{max_alq}
|
, gas_target_{gas_target}
|
||||||
|
, water_target_{water_target}
|
||||||
|
, liquid_target_{liquid_target}
|
||||||
|
, total_gas_{total_gas}
|
||||||
|
, max_alq_{max_alq}
|
||||||
{}
|
{}
|
||||||
double alq() const { return alq_; }
|
|
||||||
void assign(double oil_rate, double gas_rate, double water_rate, double alq)
|
Scalar alq() const { return alq_; }
|
||||||
|
void assign(Scalar oil_rate,
|
||||||
|
Scalar gas_rate,
|
||||||
|
Scalar water_rate,
|
||||||
|
Scalar alq)
|
||||||
{
|
{
|
||||||
oil_rate_ = oil_rate;
|
oil_rate_ = oil_rate;
|
||||||
gas_rate_ = gas_rate;
|
gas_rate_ = gas_rate;
|
||||||
water_rate_ = water_rate;
|
water_rate_ = water_rate;
|
||||||
alq_ = alq;
|
alq_ = alq;
|
||||||
}
|
}
|
||||||
double gasRate() const { return gas_rate_; }
|
Scalar gasRate() const { return gas_rate_; }
|
||||||
double waterRate() const { return water_rate_; }
|
Scalar waterRate() const { return water_rate_; }
|
||||||
std::optional<double> gasTarget() const { return gas_target_; }
|
std::optional<Scalar> gasTarget() const { return gas_target_; }
|
||||||
std::optional<double> waterTarget() const { return water_target_; }
|
std::optional<Scalar> waterTarget() const { return water_target_; }
|
||||||
std::optional<double> maxAlq() const { return max_alq_; }
|
std::optional<Scalar> maxAlq() const { return max_alq_; }
|
||||||
std::optional<double> maxTotalGasRate() const { return total_gas_; }
|
std::optional<Scalar > maxTotalGasRate() const { return total_gas_; }
|
||||||
double oilRate() const { return oil_rate_; }
|
Scalar oilRate() const { return oil_rate_; }
|
||||||
std::optional<double> oilTarget() const { return oil_target_; }
|
std::optional<Scalar> oilTarget() const { return oil_target_; }
|
||||||
std::optional<double> liquidTarget() const { return liquid_target_; }
|
std::optional<Scalar> liquidTarget() const { return liquid_target_; }
|
||||||
double oilPotential() const { return oil_potential_; }
|
Scalar oilPotential() const { return oil_potential_; }
|
||||||
double gasPotential() const { return gas_potential_; }
|
Scalar gasPotential() const { return gas_potential_; }
|
||||||
double waterPotential() const { return water_potential_; }
|
Scalar waterPotential() const { return water_potential_; }
|
||||||
|
|
||||||
void update(double delta_oil, double delta_gas, double delta_water, double delta_alq)
|
void update(Scalar delta_oil,
|
||||||
|
Scalar delta_gas,
|
||||||
|
Scalar delta_water,
|
||||||
|
Scalar delta_alq)
|
||||||
{
|
{
|
||||||
oil_rate_ += delta_oil;
|
oil_rate_ += delta_oil;
|
||||||
gas_rate_ += delta_gas;
|
gas_rate_ += delta_gas;
|
||||||
@ -192,28 +219,29 @@ protected:
|
|||||||
// Note. We don't updata the potentials at this point. They
|
// Note. We don't updata the potentials at this point. They
|
||||||
// are only needed initially.
|
// are only needed initially.
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double oil_rate_;
|
Scalar oil_rate_;
|
||||||
double gas_rate_;
|
Scalar gas_rate_;
|
||||||
double water_rate_;
|
Scalar water_rate_;
|
||||||
double alq_;
|
Scalar alq_;
|
||||||
double oil_potential_;
|
Scalar oil_potential_;
|
||||||
double gas_potential_;
|
Scalar gas_potential_;
|
||||||
double water_potential_;
|
Scalar water_potential_;
|
||||||
std::optional<double> oil_target_;
|
std::optional<Scalar> oil_target_;
|
||||||
std::optional<double> gas_target_;
|
std::optional<Scalar> gas_target_;
|
||||||
std::optional<double> water_target_;
|
std::optional<Scalar> water_target_;
|
||||||
std::optional<double> liquid_target_;
|
std::optional<Scalar> liquid_target_;
|
||||||
std::optional<double> total_gas_;
|
std::optional<Scalar> total_gas_;
|
||||||
std::optional<double> max_alq_;
|
std::optional<Scalar> max_alq_;
|
||||||
};
|
};
|
||||||
|
|
||||||
GLiftEclWells &ecl_wells_;
|
GLiftEclWells& ecl_wells_;
|
||||||
const Schedule &schedule_;
|
const Schedule& schedule_;
|
||||||
const SummaryState &summary_state_;
|
const SummaryState& summary_state_;
|
||||||
const int report_step_idx_;
|
const int report_step_idx_;
|
||||||
const int iteration_idx_;
|
const int iteration_idx_;
|
||||||
const PhaseUsage &phase_usage_;
|
const PhaseUsage& phase_usage_;
|
||||||
const GasLiftOpt& glo_;
|
const GasLiftOpt& glo_;
|
||||||
GroupRateMap group_rate_map_;
|
GroupRateMap group_rate_map_;
|
||||||
Well2GroupMap well_group_map_;
|
Well2GroupMap well_group_map_;
|
||||||
@ -221,7 +249,6 @@ protected:
|
|||||||
int next_group_idx_ = 0;
|
int next_group_idx_ = 0;
|
||||||
// Optimize only wells under THP control
|
// Optimize only wells under THP control
|
||||||
bool optimize_only_thp_wells_ = false;
|
bool optimize_only_thp_wells_ = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
@ -28,45 +28,47 @@
|
|||||||
#include <opm/simulators/wells/WellInterface.hpp>
|
#include <opm/simulators/wells/WellInterface.hpp>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm {
|
||||||
|
|
||||||
|
template<class TypeTag>
|
||||||
|
class GasLiftSingleWell : public GasLiftSingleWellGeneric<GetPropType<TypeTag, Properties::Scalar>>
|
||||||
{
|
{
|
||||||
template<class TypeTag>
|
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
|
||||||
class GasLiftSingleWell : public GasLiftSingleWellGeneric
|
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
|
||||||
{
|
using GLiftSyncGroups = typename GasLiftSingleWellGeneric<Scalar>::GLiftSyncGroups;
|
||||||
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
|
using BasicRates = typename GasLiftSingleWellGeneric<Scalar>::BasicRates;
|
||||||
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
|
|
||||||
using GLiftSyncGroups = typename GasLiftSingleWellGeneric::GLiftSyncGroups;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GasLiftSingleWell(
|
GasLiftSingleWell(const WellInterface<TypeTag>& well,
|
||||||
const WellInterface<TypeTag> &well,
|
const Simulator& simulator,
|
||||||
const Simulator& simulator,
|
const SummaryState& summary_state,
|
||||||
const SummaryState &summary_state,
|
DeferredLogger& deferred_logger,
|
||||||
DeferredLogger &deferred_logger,
|
WellState<Scalar>& well_state,
|
||||||
WellState<Scalar>& well_state,
|
const GroupState<Scalar>& group_state,
|
||||||
const GroupState<Scalar>& group_state,
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
GasLiftGroupInfo &group_info,
|
GLiftSyncGroups& sync_groups,
|
||||||
GLiftSyncGroups &sync_groups,
|
const Parallel::Communication& comm,
|
||||||
const Parallel::Communication& comm,
|
bool glift_debug);
|
||||||
bool glift_debug
|
|
||||||
);
|
|
||||||
const WellInterfaceGeneric &getWell() const override { return well_; }
|
|
||||||
|
|
||||||
private:
|
const WellInterfaceGeneric& getWell() const override { return well_; }
|
||||||
std::optional<double> computeBhpAtThpLimit_(double alq, bool debug_ouput=true) const override;
|
|
||||||
BasicRates computeWellRates_(
|
|
||||||
double bhp, bool bhp_is_limited, bool debug_output=true) const override;
|
|
||||||
void setAlqMaxRate_(const GasLiftWell& well);
|
|
||||||
void setupPhaseVariables_();
|
|
||||||
bool checkThpControl_() const override;
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<Scalar>
|
||||||
|
computeBhpAtThpLimit_(Scalar alq,
|
||||||
|
bool debug_ouput = true) const override;
|
||||||
|
|
||||||
const Simulator& simulator_;
|
BasicRates computeWellRates_(Scalar bhp,
|
||||||
const WellInterface<TypeTag> &well_;
|
bool bhp_is_limited,
|
||||||
};
|
bool debug_output = true) const override;
|
||||||
|
|
||||||
|
void setAlqMaxRate_(const GasLiftWell& well);
|
||||||
|
void setupPhaseVariables_();
|
||||||
|
bool checkThpControl_() const override;
|
||||||
|
|
||||||
|
const Simulator& simulator_;
|
||||||
|
const WellInterface<TypeTag>& well_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -33,55 +33,63 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm {
|
||||||
{
|
|
||||||
|
|
||||||
class DeferredLogger;
|
class DeferredLogger;
|
||||||
class GasLiftWell;
|
class GasLiftWell;
|
||||||
class GasLiftWellState;
|
template<class Scalar> class GasLiftWellState;
|
||||||
class Schedule;
|
class Schedule;
|
||||||
class SummaryState;
|
class SummaryState;
|
||||||
class WellInterfaceGeneric;
|
class WellInterfaceGeneric;
|
||||||
template<class Scalar> class WellState;
|
template<class Scalar> class WellState;
|
||||||
template<class Scalar> class GroupState;
|
template<class Scalar> class GroupState;
|
||||||
|
|
||||||
class GasLiftSingleWellGeneric : public GasLiftCommon
|
template<class Scalar>
|
||||||
|
class GasLiftSingleWellGeneric : public GasLiftCommon<Scalar>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
static constexpr int Water = BlackoilPhases::Aqua;
|
static constexpr int Water = BlackoilPhases::Aqua;
|
||||||
static constexpr int Oil = BlackoilPhases::Liquid;
|
static constexpr int Oil = BlackoilPhases::Liquid;
|
||||||
static constexpr int Gas = BlackoilPhases::Vapour;
|
static constexpr int Gas = BlackoilPhases::Vapour;
|
||||||
static constexpr int NUM_PHASES = 3;
|
static constexpr int NUM_PHASES = 3;
|
||||||
static constexpr double ALQ_EPSILON = 1e-8;
|
static constexpr Scalar ALQ_EPSILON = 1e-8;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using GLiftSyncGroups = std::set<int>;
|
using GLiftSyncGroups = std::set<int>;
|
||||||
using Rate = GasLiftGroupInfo::Rate;
|
using Rate = typename GasLiftGroupInfo<Scalar>::Rate;
|
||||||
|
using MessageType = typename GasLiftCommon<Scalar>::MessageType;
|
||||||
|
|
||||||
struct GradInfo
|
struct GradInfo
|
||||||
{
|
{
|
||||||
GradInfo() { }
|
GradInfo() = default;
|
||||||
|
GradInfo(Scalar grad_,
|
||||||
|
Scalar new_oil_rate_,
|
||||||
|
bool oil_is_limited_,
|
||||||
|
Scalar new_gas_rate_,
|
||||||
|
bool gas_is_limited_,
|
||||||
|
Scalar new_water_rate_,
|
||||||
|
bool water_is_limited_,
|
||||||
|
Scalar alq_,
|
||||||
|
bool alq_is_limited_)
|
||||||
|
: grad{grad_}
|
||||||
|
, new_oil_rate{new_oil_rate_}
|
||||||
|
, oil_is_limited{oil_is_limited_}
|
||||||
|
, new_gas_rate{new_gas_rate_}
|
||||||
|
, gas_is_limited{gas_is_limited_}
|
||||||
|
, new_water_rate{new_water_rate_}
|
||||||
|
, water_is_limited{water_is_limited_}
|
||||||
|
, alq{alq_}
|
||||||
|
, alq_is_limited{alq_is_limited_}
|
||||||
|
{}
|
||||||
|
|
||||||
GradInfo(double grad_, double new_oil_rate_, bool oil_is_limited_,
|
Scalar grad;
|
||||||
double new_gas_rate_, bool gas_is_limited_,
|
Scalar new_oil_rate;
|
||||||
double new_water_rate_, bool water_is_limited_,
|
|
||||||
double alq_, bool alq_is_limited_) :
|
|
||||||
grad{grad_},
|
|
||||||
new_oil_rate{new_oil_rate_},
|
|
||||||
oil_is_limited{oil_is_limited_},
|
|
||||||
new_gas_rate{new_gas_rate_},
|
|
||||||
gas_is_limited{gas_is_limited_},
|
|
||||||
new_water_rate{new_water_rate_},
|
|
||||||
water_is_limited{water_is_limited_},
|
|
||||||
alq{alq_},
|
|
||||||
alq_is_limited{alq_is_limited_} {}
|
|
||||||
double grad;
|
|
||||||
double new_oil_rate;
|
|
||||||
bool oil_is_limited;
|
bool oil_is_limited;
|
||||||
double new_gas_rate;
|
Scalar new_gas_rate;
|
||||||
bool gas_is_limited;
|
bool gas_is_limited;
|
||||||
double new_water_rate;
|
Scalar new_water_rate;
|
||||||
bool water_is_limited;
|
bool water_is_limited;
|
||||||
double alq;
|
Scalar alq;
|
||||||
bool alq_is_limited;
|
bool alq_is_limited;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,33 +97,31 @@ public:
|
|||||||
|
|
||||||
const std::string& name() const { return well_name_; }
|
const std::string& name() const { return well_name_; }
|
||||||
|
|
||||||
std::optional<GradInfo> calcIncOrDecGradient(double oil_rate, double gas_rate,
|
std::optional<GradInfo> calcIncOrDecGradient(Scalar oil_rate,
|
||||||
double water_rate,
|
Scalar gas_rate,
|
||||||
double alq,
|
Scalar water_rate,
|
||||||
|
Scalar alq,
|
||||||
const std::string& gr_name_dont_limit,
|
const std::string& gr_name_dont_limit,
|
||||||
bool increase,
|
bool increase,
|
||||||
bool debug_output = true
|
bool debug_output = true) const;
|
||||||
) const;
|
|
||||||
|
|
||||||
std::unique_ptr<GasLiftWellState> runOptimize(const int iteration_idx);
|
std::unique_ptr<GasLiftWellState<Scalar>> runOptimize(const int iteration_idx);
|
||||||
|
|
||||||
virtual const WellInterfaceGeneric& getWell() const = 0;
|
virtual const WellInterfaceGeneric& getWell() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GasLiftSingleWellGeneric(
|
GasLiftSingleWellGeneric(DeferredLogger& deferred_logger,
|
||||||
DeferredLogger& deferred_logger,
|
WellState<Scalar>& well_state,
|
||||||
WellState<double>& well_state,
|
const GroupState<Scalar>& group_state,
|
||||||
const GroupState<double>& group_state,
|
const Well& ecl_well,
|
||||||
const Well& ecl_well,
|
const SummaryState& summary_state,
|
||||||
const SummaryState& summary_state,
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
GasLiftGroupInfo& group_info,
|
const PhaseUsage& phase_usage,
|
||||||
const PhaseUsage& phase_usage,
|
const Schedule& schedule,
|
||||||
const Schedule& schedule,
|
const int report_step_idx,
|
||||||
const int report_step_idx,
|
GLiftSyncGroups& sync_groups,
|
||||||
GLiftSyncGroups& sync_groups,
|
const Parallel::Communication& comm,
|
||||||
const Parallel::Communication& comm,
|
bool glift_debug);
|
||||||
bool glift_debug
|
|
||||||
);
|
|
||||||
|
|
||||||
struct LimitedRates;
|
struct LimitedRates;
|
||||||
struct BasicRates
|
struct BasicRates
|
||||||
@ -126,24 +132,33 @@ protected:
|
|||||||
water{rates.water},
|
water{rates.water},
|
||||||
bhp_is_limited{rates.bhp_is_limited}
|
bhp_is_limited{rates.bhp_is_limited}
|
||||||
{}
|
{}
|
||||||
BasicRates(double oil_, double gas_, double water_, bool bhp_is_limited_) :
|
|
||||||
oil{oil_},
|
BasicRates(Scalar oil_,
|
||||||
gas{gas_},
|
Scalar gas_,
|
||||||
water{water_},
|
Scalar water_,
|
||||||
bhp_is_limited{bhp_is_limited_}
|
bool bhp_is_limited_)
|
||||||
|
: oil{oil_}
|
||||||
|
, gas{gas_}
|
||||||
|
, water{water_}
|
||||||
|
, bhp_is_limited{bhp_is_limited_}
|
||||||
{}
|
{}
|
||||||
BasicRates& operator=(const BasicRates& rates) {
|
|
||||||
|
BasicRates& operator=(const BasicRates& rates)
|
||||||
|
{
|
||||||
oil = rates.oil;
|
oil = rates.oil;
|
||||||
gas = rates.gas;
|
gas = rates.gas;
|
||||||
water = rates.water;
|
water = rates.water;
|
||||||
bhp_is_limited = rates.bhp_is_limited;
|
bhp_is_limited = rates.bhp_is_limited;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This copy constructor cannot be defined inline here since LimitedRates
|
// This copy constructor cannot be defined inline here since LimitedRates
|
||||||
// has not been defined yet (it is defined below). Instead it is defined in
|
// has not been defined yet (it is defined below). Instead it is defined in
|
||||||
// in the .cpp file
|
// in the .cpp file
|
||||||
BasicRates(const LimitedRates& rates);
|
BasicRates(const LimitedRates& rates);
|
||||||
double operator[](Rate rate_type) const {
|
|
||||||
|
Scalar operator[](Rate rate_type) const
|
||||||
|
{
|
||||||
switch (rate_type) {
|
switch (rate_type) {
|
||||||
case Rate::oil:
|
case Rate::oil:
|
||||||
return this->oil;
|
return this->oil;
|
||||||
@ -158,46 +173,49 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double oil, gas, water;
|
Scalar oil, gas, water;
|
||||||
bool bhp_is_limited;
|
bool bhp_is_limited;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LimitedRates : public BasicRates
|
struct LimitedRates : public BasicRates
|
||||||
{
|
{
|
||||||
enum class LimitType {well, group, none};
|
enum class LimitType {well, group, none};
|
||||||
LimitedRates(
|
LimitedRates(Scalar oil_,
|
||||||
double oil_, double gas_, double water_,
|
Scalar gas_,
|
||||||
bool oil_is_limited_, bool gas_is_limited_,
|
Scalar water_,
|
||||||
bool water_is_limited_, bool bhp_is_limited_,
|
bool oil_is_limited_,
|
||||||
std::optional<Rate> oil_limiting_target_,
|
bool gas_is_limited_,
|
||||||
std::optional<Rate> water_limiting_target_
|
bool water_is_limited_,
|
||||||
) :
|
bool bhp_is_limited_,
|
||||||
BasicRates(oil_, gas_, water_, bhp_is_limited_),
|
std::optional<Rate> oil_limiting_target_,
|
||||||
oil_is_limited{oil_is_limited_},
|
std ::optional<Rate> water_limiting_target_)
|
||||||
gas_is_limited{gas_is_limited_},
|
: BasicRates(oil_, gas_, water_, bhp_is_limited_)
|
||||||
water_is_limited{water_is_limited_},
|
, oil_is_limited{oil_is_limited_}
|
||||||
oil_limiting_target{oil_limiting_target_},
|
, gas_is_limited{gas_is_limited_}
|
||||||
water_limiting_target{water_limiting_target_}
|
, water_is_limited{water_is_limited_}
|
||||||
|
, oil_limiting_target{oil_limiting_target_}
|
||||||
|
, water_limiting_target{water_limiting_target_}
|
||||||
{
|
{
|
||||||
set_initial_limit_type_();
|
set_initial_limit_type_();
|
||||||
}
|
}
|
||||||
|
|
||||||
LimitedRates(
|
LimitedRates(const BasicRates& rates,
|
||||||
const BasicRates& rates,
|
bool oil_is_limited_,
|
||||||
bool oil_is_limited_, bool gas_is_limited_,
|
bool gas_is_limited_,
|
||||||
bool water_is_limited_
|
bool water_is_limited_)
|
||||||
) :
|
: BasicRates(rates)
|
||||||
BasicRates(rates),
|
, oil_is_limited{oil_is_limited_}
|
||||||
oil_is_limited{oil_is_limited_},
|
, gas_is_limited{gas_is_limited_}
|
||||||
gas_is_limited{gas_is_limited_},
|
, water_is_limited{water_is_limited_}
|
||||||
water_is_limited{water_is_limited_}
|
|
||||||
{
|
{
|
||||||
set_initial_limit_type_();
|
set_initial_limit_type_();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool limited() const {
|
bool limited() const
|
||||||
|
{
|
||||||
return oil_is_limited || gas_is_limited || water_is_limited;
|
return oil_is_limited || gas_is_limited || water_is_limited;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For a given ALQ value, were the rates limited due to group targets
|
// For a given ALQ value, were the rates limited due to group targets
|
||||||
// or due to well targets?
|
// or due to well targets?
|
||||||
LimitType limit_type;
|
LimitType limit_type;
|
||||||
@ -206,145 +224,221 @@ protected:
|
|||||||
bool water_is_limited;
|
bool water_is_limited;
|
||||||
std::optional<Rate> oil_limiting_target;
|
std::optional<Rate> oil_limiting_target;
|
||||||
std::optional<Rate> water_limiting_target;
|
std::optional<Rate> water_limiting_target;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_initial_limit_type_() {
|
void set_initial_limit_type_()
|
||||||
|
{
|
||||||
limit_type = limited() ? LimitType::well : LimitType::none;
|
limit_type = limited() ? LimitType::well : LimitType::none;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OptimizeState
|
struct OptimizeState
|
||||||
{
|
{
|
||||||
OptimizeState( GasLiftSingleWellGeneric& parent_, bool increase_ ) :
|
OptimizeState( GasLiftSingleWellGeneric& parent_, bool increase_ )
|
||||||
parent{parent_},
|
: parent{parent_}
|
||||||
increase{increase_},
|
, increase{increase_}
|
||||||
it{0},
|
, it{0}
|
||||||
stop_iteration{false},
|
, stop_iteration{false}
|
||||||
bhp{-1}
|
, bhp{-1}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GasLiftSingleWellGeneric& parent;
|
GasLiftSingleWellGeneric& parent;
|
||||||
bool increase;
|
bool increase;
|
||||||
int it;
|
int it;
|
||||||
bool stop_iteration;
|
bool stop_iteration;
|
||||||
double bhp;
|
Scalar bhp;
|
||||||
|
|
||||||
std::pair<std::optional<double>,bool> addOrSubtractAlqIncrement(double alq);
|
std::pair<std::optional<Scalar>,bool> addOrSubtractAlqIncrement(Scalar alq);
|
||||||
double calcEcoGradient(double oil_rate, double new_oil_rate,
|
Scalar calcEcoGradient(Scalar oil_rate,
|
||||||
double gas_rate, double new_gas_rate);
|
Scalar new_oil_rate,
|
||||||
bool checkAlqOutsideLimits(double alq, double oil_rate);
|
Scalar gas_rate,
|
||||||
bool checkEcoGradient(double gradient);
|
Scalar new_gas_rate);
|
||||||
bool checkOilRateExceedsTarget(double oil_rate);
|
|
||||||
|
bool checkAlqOutsideLimits(Scalar alq, Scalar oil_rate);
|
||||||
|
bool checkEcoGradient(Scalar gradient);
|
||||||
|
bool checkOilRateExceedsTarget(Scalar oil_rate);
|
||||||
bool checkRatesViolated(const LimitedRates& rates) const;
|
bool checkRatesViolated(const LimitedRates& rates) const;
|
||||||
void debugShowIterationInfo(double alq);
|
|
||||||
double getBhpWithLimit();
|
|
||||||
void warn_(std::string msg) {parent.displayWarning_(msg);}
|
|
||||||
};
|
|
||||||
bool checkGroupALQrateExceeded(double delta_alq, const std::string& gr_name_dont_limit = "") const;
|
|
||||||
bool checkGroupTotalRateExceeded(double delta_alq, double delta_gas_rate) const;
|
|
||||||
|
|
||||||
std::pair<std::optional<double>, bool> addOrSubtractAlqIncrement_(
|
void debugShowIterationInfo(Scalar alq);
|
||||||
double alq, bool increase) const;
|
|
||||||
double calcEcoGradient_(double oil_rate, double new_oil_rate,
|
Scalar getBhpWithLimit();
|
||||||
double gas_rate, double new_gas_rate, bool increase) const;
|
|
||||||
bool checkALQequal_(double alq1, double alq2) const;
|
void warn_(const std::string& msg) { parent.displayWarning_(msg); }
|
||||||
bool checkGroupTargetsViolated(
|
};
|
||||||
const BasicRates& rates, const BasicRates& new_rates) const;
|
|
||||||
bool checkInitialALQmodified_(double alq, double initial_alq) const;
|
bool checkGroupALQrateExceeded(Scalar delta_alq,
|
||||||
|
const std::string& gr_name_dont_limit = "") const;
|
||||||
|
bool checkGroupTotalRateExceeded(Scalar delta_alq,
|
||||||
|
Scalar delta_gas_rate) const;
|
||||||
|
|
||||||
|
std::pair<std::optional<Scalar>, bool>
|
||||||
|
addOrSubtractAlqIncrement_(Scalar alq, bool increase) const;
|
||||||
|
|
||||||
|
Scalar calcEcoGradient_(Scalar oil_rate, Scalar new_oil_rate,
|
||||||
|
Scalar gas_rate, Scalar new_gas_rate, bool increase) const;
|
||||||
|
|
||||||
|
bool checkALQequal_(Scalar alq1, Scalar alq2) const;
|
||||||
|
|
||||||
|
bool checkGroupTargetsViolated(const BasicRates& rates,
|
||||||
|
const BasicRates& new_rates) const;
|
||||||
|
bool checkInitialALQmodified_(Scalar alq, Scalar initial_alq) const;
|
||||||
|
|
||||||
virtual bool checkThpControl_() const = 0;
|
virtual bool checkThpControl_() const = 0;
|
||||||
virtual std::optional<double> computeBhpAtThpLimit_(double alq, bool debug_output = true) const = 0;
|
virtual std::optional<Scalar > computeBhpAtThpLimit_(Scalar alq,
|
||||||
std::pair<std::optional<double>,double> computeConvergedBhpAtThpLimitByMaybeIncreasingALQ_() const;
|
bool debug_output = true) const = 0;
|
||||||
std::pair<std::optional<BasicRates>,double> computeInitialWellRates_() const;
|
|
||||||
std::optional<LimitedRates> computeLimitedWellRatesWithALQ_(double alq) const;
|
std::pair<std::optional<Scalar>,Scalar>
|
||||||
virtual BasicRates computeWellRates_(double bhp, bool bhp_is_limited, bool debug_output = true) const = 0;
|
computeConvergedBhpAtThpLimitByMaybeIncreasingALQ_() const;
|
||||||
std::optional<BasicRates> computeWellRatesWithALQ_(double alq) const;
|
|
||||||
void debugCheckNegativeGradient_(double grad, double alq, double new_alq,
|
std::pair<std::optional<BasicRates>,Scalar>
|
||||||
double oil_rate, double new_oil_rate,
|
computeInitialWellRates_() const;
|
||||||
double gas_rate, double new_gas_rate,
|
|
||||||
|
std::optional<LimitedRates>
|
||||||
|
computeLimitedWellRatesWithALQ_(Scalar alq) const;
|
||||||
|
|
||||||
|
virtual BasicRates computeWellRates_(Scalar bhp,
|
||||||
|
bool bhp_is_limited,
|
||||||
|
bool debug_output = true) const = 0;
|
||||||
|
|
||||||
|
std::optional<BasicRates> computeWellRatesWithALQ_(Scalar alq) const;
|
||||||
|
|
||||||
|
void debugCheckNegativeGradient_(Scalar grad, Scalar alq, Scalar new_alq,
|
||||||
|
Scalar oil_rate, Scalar new_oil_rate,
|
||||||
|
Scalar gas_rate, Scalar new_gas_rate,
|
||||||
bool increase) const;
|
bool increase) const;
|
||||||
|
|
||||||
void debugPrintWellStateRates() const;
|
void debugPrintWellStateRates() const;
|
||||||
void debugShowAlqIncreaseDecreaseCounts_();
|
void debugShowAlqIncreaseDecreaseCounts_();
|
||||||
void debugShowBhpAlqTable_();
|
void debugShowBhpAlqTable_();
|
||||||
void debugShowLimitingTargets_(const LimitedRates& rates) const;
|
void debugShowLimitingTargets_(const LimitedRates& rates) const;
|
||||||
void debugShowProducerControlMode() const;
|
void debugShowProducerControlMode() const;
|
||||||
void debugShowStartIteration_(double alq, bool increase, double oil_rate);
|
void debugShowStartIteration_(Scalar alq, bool increase, Scalar oil_rate);
|
||||||
void debugShowTargets_();
|
void debugShowTargets_();
|
||||||
void displayDebugMessage_(const std::string& msg) const override;
|
void displayDebugMessage_(const std::string& msg) const override;
|
||||||
void displayWarning_(const std::string& warning);
|
void displayWarning_(const std::string& warning);
|
||||||
std::pair<double, bool> getBhpWithLimit_(double bhp) const;
|
|
||||||
std::pair<double, bool> getGasRateWithLimit_(
|
std::pair<Scalar, bool> getBhpWithLimit_(Scalar bhp) const;
|
||||||
const BasicRates& rates) const;
|
std::pair<Scalar, bool> getGasRateWithLimit_(const BasicRates& rates) const;
|
||||||
std::pair<double, bool> getGasRateWithGroupLimit_(
|
std::pair<Scalar, bool> getGasRateWithGroupLimit_(Scalar new_gas_rate,
|
||||||
double new_gas_rate, double gas_rate, const std::string& gr_name_dont_limit) const;
|
Scalar gas_rate,
|
||||||
std::pair<std::optional<LimitedRates>,double> getInitialRatesWithLimit_() const;
|
const std::string& gr_name_dont_limit) const;
|
||||||
|
|
||||||
|
std::pair<std::optional<LimitedRates>,Scalar >
|
||||||
|
getInitialRatesWithLimit_() const;
|
||||||
|
|
||||||
LimitedRates getLimitedRatesFromRates_(const BasicRates& rates) const;
|
LimitedRates getLimitedRatesFromRates_(const BasicRates& rates) const;
|
||||||
std::tuple<double,double,bool,bool> getLiquidRateWithGroupLimit_(
|
|
||||||
const double new_oil_rate, const double oil_rate,
|
std::tuple<Scalar,Scalar,bool,bool>
|
||||||
const double new_water_rate, const double water_rate, const std::string& gr_name_dont_limit) const;
|
getLiquidRateWithGroupLimit_(const Scalar new_oil_rate,
|
||||||
std::pair<double, bool> getOilRateWithGroupLimit_(
|
const Scalar oil_rate,
|
||||||
double new_oil_rate, double oil_rate, const std::string& gr_name_dont_limit) const;
|
const Scalar new_water_rate,
|
||||||
std::pair<double, bool> getOilRateWithLimit_(const BasicRates& rates) const;
|
const Scalar water_rate,
|
||||||
std::pair<double, std::optional<Rate>> getOilRateWithLimit2_(
|
const std::string& gr_name_dont_limit) const;
|
||||||
const BasicRates& rates) const;
|
|
||||||
double getProductionTarget_(Rate rate) const;
|
std::pair<Scalar, bool>
|
||||||
double getRate_(Rate rate_type, const BasicRates& rates) const;
|
getOilRateWithGroupLimit_(Scalar new_oil_rate,
|
||||||
std::pair<double, std::optional<Rate>> getRateWithLimit_(
|
Scalar oil_rate,
|
||||||
Rate rate_type, const BasicRates& rates) const;
|
const std::string& gr_name_dont_limit) const;
|
||||||
std::tuple<double, const std::string*, double> getRateWithGroupLimit_(
|
|
||||||
Rate rate_type, const double new_rate, const double old_rate, const std::string& gr_name_dont_limit) const;
|
std::pair<Scalar, bool> getOilRateWithLimit_(const BasicRates& rates) const;
|
||||||
std::pair<double, bool> getWaterRateWithGroupLimit_(
|
|
||||||
double new_water_rate, double water_rate, const std::string& gr_name_dont_limit) const;
|
std::pair<Scalar, std::optional<Rate>>
|
||||||
std::pair<double, bool> getWaterRateWithLimit_(const BasicRates& rates) const;
|
getOilRateWithLimit2_(const BasicRates& rates) const;
|
||||||
std::pair<double, std::optional<Rate>> getWaterRateWithLimit2_(
|
|
||||||
const BasicRates& rates) const;
|
Scalar getProductionTarget_(Rate rate) const;
|
||||||
|
Scalar getRate_(Rate rate_type, const BasicRates& rates) const;
|
||||||
|
|
||||||
|
std::pair<Scalar, std::optional<Rate>>
|
||||||
|
getRateWithLimit_(Rate rate_type, const BasicRates& rates) const;
|
||||||
|
|
||||||
|
std::tuple<Scalar, const std::string*, Scalar>
|
||||||
|
getRateWithGroupLimit_(Rate rate_type,
|
||||||
|
const Scalar new_rate,
|
||||||
|
const Scalar old_rate,
|
||||||
|
const std::string& gr_name_dont_limit) const;
|
||||||
|
|
||||||
|
std::pair<Scalar, bool>
|
||||||
|
getWaterRateWithGroupLimit_(Scalar new_water_rate,
|
||||||
|
Scalar water_rate,
|
||||||
|
const std::string& gr_name_dont_limit) const;
|
||||||
|
|
||||||
|
std::pair<Scalar, bool> getWaterRateWithLimit_(const BasicRates& rates) const;
|
||||||
|
|
||||||
|
std::pair<Scalar, std::optional<Rate>>
|
||||||
|
getWaterRateWithLimit2_(const BasicRates& rates) const;
|
||||||
|
|
||||||
BasicRates getWellStateRates_() const;
|
BasicRates getWellStateRates_() const;
|
||||||
bool hasProductionControl_(Rate rate) const;
|
bool hasProductionControl_(Rate rate) const;
|
||||||
std::pair<LimitedRates, double> increaseALQtoPositiveOilRate_(
|
|
||||||
double alq, const LimitedRates& orig_rates) const;
|
std::pair<LimitedRates, Scalar>
|
||||||
std::pair<LimitedRates, double> increaseALQtoMinALQ_(
|
increaseALQtoPositiveOilRate_(Scalar alq,
|
||||||
double alq, const LimitedRates& orig_rates) const;
|
const LimitedRates& orig_rates) const;
|
||||||
void logSuccess_(double alq,
|
|
||||||
|
std::pair<LimitedRates, Scalar>
|
||||||
|
increaseALQtoMinALQ_(Scalar alq,
|
||||||
|
const LimitedRates& orig_rates) const;
|
||||||
|
|
||||||
|
void logSuccess_(Scalar alq,
|
||||||
const int iteration_idx);
|
const int iteration_idx);
|
||||||
std::pair<LimitedRates, double> maybeAdjustALQbeforeOptimizeLoop_(
|
|
||||||
const LimitedRates& rates, double alq, bool increase) const;
|
std::pair<LimitedRates, Scalar>
|
||||||
std::pair<LimitedRates, double> reduceALQtoGroupAlqLimits_(
|
maybeAdjustALQbeforeOptimizeLoop_(const LimitedRates& rates,
|
||||||
double alq, const LimitedRates& rates) const;
|
Scalar alq,
|
||||||
std::pair<LimitedRates, double> reduceALQtoGroupTarget(
|
bool increase) const;
|
||||||
double alq, const LimitedRates& rates) const;
|
|
||||||
std::pair<LimitedRates, double> reduceALQtoWellTarget_(
|
std::pair<LimitedRates, Scalar>
|
||||||
double alq, const LimitedRates& rates) const;
|
reduceALQtoGroupAlqLimits_(Scalar alq,
|
||||||
std::unique_ptr<GasLiftWellState> runOptimize1_();
|
const LimitedRates& rates) const;
|
||||||
std::unique_ptr<GasLiftWellState> runOptimize2_();
|
|
||||||
std::unique_ptr<GasLiftWellState> runOptimizeLoop_(bool increase);
|
std::pair<LimitedRates, Scalar>
|
||||||
|
reduceALQtoGroupTarget(Scalar alq,
|
||||||
|
const LimitedRates& rates) const;
|
||||||
|
|
||||||
|
std::pair<LimitedRates, Scalar>
|
||||||
|
reduceALQtoWellTarget_(Scalar alq,
|
||||||
|
const LimitedRates& rates) const;
|
||||||
|
|
||||||
|
std::unique_ptr<GasLiftWellState<Scalar>> runOptimize1_();
|
||||||
|
std::unique_ptr<GasLiftWellState<Scalar>> runOptimize2_();
|
||||||
|
std::unique_ptr<GasLiftWellState<Scalar>> runOptimizeLoop_(bool increase);
|
||||||
|
|
||||||
void setAlqMinRate_(const GasLiftWell& well);
|
void setAlqMinRate_(const GasLiftWell& well);
|
||||||
std::unique_ptr<GasLiftWellState> tryIncreaseLiftGas_();
|
std::unique_ptr<GasLiftWellState<Scalar>> tryIncreaseLiftGas_();
|
||||||
std::unique_ptr<GasLiftWellState> tryDecreaseLiftGas_();
|
std::unique_ptr<GasLiftWellState<Scalar>> tryDecreaseLiftGas_();
|
||||||
void updateGroupRates_(
|
|
||||||
const LimitedRates& rates,
|
void updateGroupRates_(const LimitedRates& rates,
|
||||||
const LimitedRates& new_rates,
|
const LimitedRates& new_rates,
|
||||||
double delta_alq) const;
|
Scalar delta_alq) const;
|
||||||
LimitedRates updateRatesToGroupLimits_(
|
|
||||||
const BasicRates& rates, const LimitedRates& new_rates, const std::string& gr_name = "") const;
|
LimitedRates
|
||||||
|
updateRatesToGroupLimits_(const BasicRates& rates,
|
||||||
|
const LimitedRates& new_rates,
|
||||||
|
const std::string& gr_name = "") const;
|
||||||
|
|
||||||
void updateWellStateAlqFixedValue_(const GasLiftWell& well);
|
void updateWellStateAlqFixedValue_(const GasLiftWell& well);
|
||||||
bool useFixedAlq_(const GasLiftWell& well);
|
bool useFixedAlq_(const GasLiftWell& well);
|
||||||
void debugInfoGroupRatesExceedTarget(
|
|
||||||
Rate rate_type, const std::string& gr_name, double rate, double target) const;
|
void debugInfoGroupRatesExceedTarget(Rate rate_type,
|
||||||
|
const std::string& gr_name,
|
||||||
|
Scalar rate,
|
||||||
|
Scalar target) const;
|
||||||
void warnMaxIterationsExceeded_();
|
void warnMaxIterationsExceeded_();
|
||||||
|
|
||||||
const Well& ecl_well_;
|
const Well& ecl_well_;
|
||||||
const SummaryState& summary_state_;
|
const SummaryState& summary_state_;
|
||||||
GasLiftGroupInfo& group_info_;
|
GasLiftGroupInfo<Scalar>& group_info_;
|
||||||
const PhaseUsage& phase_usage_;
|
const PhaseUsage& phase_usage_;
|
||||||
GLiftSyncGroups& sync_groups_;
|
GLiftSyncGroups& sync_groups_;
|
||||||
const WellProductionControls controls_;
|
const WellProductionControls controls_;
|
||||||
|
|
||||||
double increment_;
|
Scalar increment_;
|
||||||
double max_alq_;
|
Scalar max_alq_;
|
||||||
double min_alq_;
|
Scalar min_alq_;
|
||||||
double orig_alq_;
|
Scalar orig_alq_;
|
||||||
|
|
||||||
double alpha_w_;
|
Scalar alpha_w_;
|
||||||
double alpha_g_;
|
Scalar alpha_g_;
|
||||||
double eco_grad_;
|
Scalar eco_grad_;
|
||||||
|
|
||||||
int gas_pos_;
|
int gas_pos_;
|
||||||
int oil_pos_;
|
int oil_pos_;
|
||||||
|
@ -27,43 +27,43 @@
|
|||||||
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
|
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
GasLiftSingleWell<TypeTag>::
|
GasLiftSingleWell<TypeTag>::
|
||||||
GasLiftSingleWell(const WellInterface<TypeTag> &well,
|
GasLiftSingleWell(const WellInterface<TypeTag>& well,
|
||||||
const Simulator& simulator,
|
const Simulator& simulator,
|
||||||
const SummaryState &summary_state,
|
const SummaryState& summary_state,
|
||||||
DeferredLogger &deferred_logger,
|
DeferredLogger& deferred_logger,
|
||||||
WellState<Scalar>& well_state,
|
WellState<Scalar>& well_state,
|
||||||
const GroupState<Scalar>& group_state,
|
const GroupState<Scalar>& group_state,
|
||||||
GasLiftGroupInfo &group_info,
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
GLiftSyncGroups &sync_groups,
|
GLiftSyncGroups &sync_groups,
|
||||||
const Parallel::Communication& comm,
|
const Parallel::Communication& comm,
|
||||||
bool glift_debug
|
bool glift_debug)
|
||||||
)
|
|
||||||
// The parent class GasLiftSingleWellGeneric contains all stuff
|
// The parent class GasLiftSingleWellGeneric contains all stuff
|
||||||
// that is not dependent on TypeTag
|
// that is not dependent on TypeTag
|
||||||
: GasLiftSingleWellGeneric(
|
: GasLiftSingleWellGeneric<Scalar>(deferred_logger,
|
||||||
deferred_logger,
|
well_state,
|
||||||
well_state,
|
group_state,
|
||||||
group_state,
|
well.wellEcl(),
|
||||||
well.wellEcl(),
|
summary_state,
|
||||||
summary_state,
|
group_info,
|
||||||
group_info,
|
well.phaseUsage(),
|
||||||
well.phaseUsage(),
|
simulator.vanguard().schedule(),
|
||||||
simulator.vanguard().schedule(),
|
simulator.episodeIndex(),
|
||||||
simulator.episodeIndex(),
|
sync_groups,
|
||||||
sync_groups,
|
comm,
|
||||||
comm,
|
glift_debug)
|
||||||
glift_debug
|
|
||||||
)
|
|
||||||
, simulator_{simulator}
|
, simulator_{simulator}
|
||||||
, well_{well}
|
, well_{well}
|
||||||
{
|
{
|
||||||
const auto& gl_well = *gl_well_;
|
const auto& gl_well = *this->gl_well_;
|
||||||
if(useFixedAlq_(gl_well)) {
|
if (this->useFixedAlq_(gl_well)) {
|
||||||
updateWellStateAlqFixedValue_(gl_well);
|
this->updateWellStateAlqFixedValue_(gl_well);
|
||||||
this->optimize_ = false; // lift gas supply is fixed
|
this->optimize_ = false; // lift gas supply is fixed
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -77,14 +77,14 @@ GasLiftSingleWell(const WellInterface<TypeTag> &well,
|
|||||||
// If gas lift optimization has not been applied to this well yet, the
|
// If gas lift optimization has not been applied to this well yet, the
|
||||||
// default value is used.
|
// default value is used.
|
||||||
this->orig_alq_ = this->well_state_.getALQ(this->well_name_);
|
this->orig_alq_ = this->well_state_.getALQ(this->well_name_);
|
||||||
if(this->optimize_) {
|
if (this->optimize_) {
|
||||||
setAlqMinRate_(gl_well);
|
this->setAlqMinRate_(gl_well);
|
||||||
// NOTE: According to item 4 in WLIFTOPT, this value does not
|
// NOTE: According to item 4 in WLIFTOPT, this value does not
|
||||||
// have to be positive.
|
// have to be positive.
|
||||||
// TODO: Does it make sense to have a negative value?
|
// TODO: Does it make sense to have a negative value?
|
||||||
this->alpha_w_ = gl_well.weight_factor();
|
this->alpha_w_ = gl_well.weight_factor();
|
||||||
if (this->alpha_w_ <= 0 ) {
|
if (this->alpha_w_ <= 0 ) {
|
||||||
displayWarning_("Nonpositive value for alpha_w ignored");
|
this->displayWarning_("Nonpositive value for alpha_w ignored");
|
||||||
this->alpha_w_ = 1.0;
|
this->alpha_w_ = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,23 +107,25 @@ GasLiftSingleWell(const WellInterface<TypeTag> &well,
|
|||||||
****************************************/
|
****************************************/
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
GasLiftSingleWellGeneric::BasicRates
|
typename GasLiftSingleWell<TypeTag>::BasicRates
|
||||||
GasLiftSingleWell<TypeTag>::
|
GasLiftSingleWell<TypeTag>::
|
||||||
computeWellRates_( double bhp, bool bhp_is_limited, bool debug_output ) const
|
computeWellRates_(Scalar bhp, bool bhp_is_limited, bool debug_output ) const
|
||||||
{
|
{
|
||||||
std::vector<double> potentials(NUM_PHASES, 0.0);
|
std::vector<Scalar> potentials(this->NUM_PHASES, 0.0);
|
||||||
this->well_.computeWellRatesWithBhp(
|
this->well_.computeWellRatesWithBhp(this->simulator_,
|
||||||
this->simulator_, bhp, potentials, this->deferred_logger_);
|
bhp,
|
||||||
|
potentials,
|
||||||
|
this->deferred_logger_);
|
||||||
if (debug_output) {
|
if (debug_output) {
|
||||||
const std::string msg = fmt::format("computed well potentials given bhp {}, "
|
const std::string msg = fmt::format("computed well potentials given bhp {}, "
|
||||||
"oil: {}, gas: {}, water: {}", bhp,
|
"oil: {}, gas: {}, water: {}", bhp,
|
||||||
-potentials[this->oil_pos_], -potentials[this->gas_pos_],
|
-potentials[this->oil_pos_], -potentials[this->gas_pos_],
|
||||||
-potentials[this->water_pos_]);
|
-potentials[this->water_pos_]);
|
||||||
displayDebugMessage_(msg);
|
this->displayDebugMessage_(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& potential : potentials) {
|
for (auto& potential : potentials) {
|
||||||
potential = std::min(0.0, potential);
|
potential = std::min(Scalar{0.0}, potential);
|
||||||
}
|
}
|
||||||
return {-potentials[this->oil_pos_],
|
return {-potentials[this->oil_pos_],
|
||||||
-potentials[this->gas_pos_],
|
-potentials[this->gas_pos_],
|
||||||
@ -133,9 +135,9 @@ computeWellRates_( double bhp, bool bhp_is_limited, bool debug_output ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
std::optional<double>
|
std::optional<typename GasLiftSingleWell<TypeTag>::Scalar>
|
||||||
GasLiftSingleWell<TypeTag>::
|
GasLiftSingleWell<TypeTag>::
|
||||||
computeBhpAtThpLimit_(double alq, bool debug_output) const
|
computeBhpAtThpLimit_(Scalar alq, bool debug_output) const
|
||||||
{
|
{
|
||||||
auto bhp_at_thp_limit = this->well_.computeBhpAtThpLimitProdWithAlq(
|
auto bhp_at_thp_limit = this->well_.computeBhpAtThpLimitProdWithAlq(
|
||||||
this->simulator_,
|
this->simulator_,
|
||||||
@ -150,7 +152,7 @@ computeBhpAtThpLimit_(double alq, bool debug_output) const
|
|||||||
" Using bhp limit instead",
|
" Using bhp limit instead",
|
||||||
*bhp_at_thp_limit, this->controls_.bhp_limit, alq
|
*bhp_at_thp_limit, this->controls_.bhp_limit, alq
|
||||||
);
|
);
|
||||||
displayDebugMessage_(msg);
|
this->displayDebugMessage_(msg);
|
||||||
}
|
}
|
||||||
bhp_at_thp_limit = this->controls_.bhp_limit;
|
bhp_at_thp_limit = this->controls_.bhp_limit;
|
||||||
}
|
}
|
||||||
@ -159,7 +161,7 @@ computeBhpAtThpLimit_(double alq, bool debug_output) const
|
|||||||
else {
|
else {
|
||||||
const std::string msg = fmt::format(
|
const std::string msg = fmt::format(
|
||||||
"Failed in getting converged bhp potential from thp limit (ALQ = {})", alq);
|
"Failed in getting converged bhp potential from thp limit (ALQ = {})", alq);
|
||||||
displayDebugMessage_(msg);
|
this->displayDebugMessage_(msg);
|
||||||
}
|
}
|
||||||
return bhp_at_thp_limit;
|
return bhp_at_thp_limit;
|
||||||
}
|
}
|
||||||
@ -198,15 +200,15 @@ setupPhaseVariables_()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(num_phases_ok);
|
assert(num_phases_ok);
|
||||||
this->oil_pos_ = pu.phase_pos[Oil];
|
this->oil_pos_ = pu.phase_pos[this->Oil];
|
||||||
this->gas_pos_ = pu.phase_pos[Gas];
|
this->gas_pos_ = pu.phase_pos[this->Gas];
|
||||||
this->water_pos_ = pu.phase_pos[Water];
|
this->water_pos_ = pu.phase_pos[this->Water];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
void
|
void
|
||||||
GasLiftSingleWell<TypeTag>::
|
GasLiftSingleWell<TypeTag>::
|
||||||
setAlqMaxRate_(const GasLiftWell &well)
|
setAlqMaxRate_(const GasLiftWell& well)
|
||||||
{
|
{
|
||||||
auto& max_alq_optional = well.max_rate();
|
auto& max_alq_optional = well.max_rate();
|
||||||
if (max_alq_optional) {
|
if (max_alq_optional) {
|
||||||
@ -240,7 +242,7 @@ checkThpControl_() const
|
|||||||
thp_control = thp_control || well.thpLimitViolatedButNotSwitched();
|
thp_control = thp_control || well.thpLimitViolatedButNotSwitched();
|
||||||
if (this->debug) {
|
if (this->debug) {
|
||||||
if (!thp_control) {
|
if (!thp_control) {
|
||||||
displayDebugMessage_("Well is not under THP control, skipping iteration..");
|
this->displayDebugMessage_("Well is not under THP control, skipping iteration..");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return thp_control;
|
return thp_control;
|
||||||
|
@ -39,21 +39,20 @@
|
|||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
GasLiftStage2::GasLiftStage2(
|
template<class Scalar>
|
||||||
const int report_step_idx,
|
GasLiftStage2<Scalar>::GasLiftStage2(const int report_step_idx,
|
||||||
const Parallel::Communication& comm,
|
const Parallel::Communication& comm,
|
||||||
const Schedule& schedule,
|
const Schedule& schedule,
|
||||||
const SummaryState& summary_state,
|
const SummaryState& summary_state,
|
||||||
DeferredLogger &deferred_logger,
|
DeferredLogger &deferred_logger,
|
||||||
WellState<double>& well_state,
|
WellState<Scalar>& well_state,
|
||||||
const GroupState<double>& group_state,
|
const GroupState<Scalar>& group_state,
|
||||||
GLiftProdWells &prod_wells,
|
GLiftProdWells &prod_wells,
|
||||||
GLiftOptWells &glift_wells,
|
GLiftOptWells &glift_wells,
|
||||||
GasLiftGroupInfo& group_info,
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
GLiftWellStateMap &state_map,
|
GLiftWellStateMap &state_map,
|
||||||
bool glift_debug
|
bool glift_debug)
|
||||||
) :
|
: GasLiftCommon<Scalar>(well_state, group_state, deferred_logger, comm, glift_debug)
|
||||||
GasLiftCommon(well_state, group_state, deferred_logger, comm, glift_debug)
|
|
||||||
, prod_wells_{prod_wells}
|
, prod_wells_{prod_wells}
|
||||||
, stage1_wells_{glift_wells}
|
, stage1_wells_{glift_wells}
|
||||||
, group_info_{group_info}
|
, group_info_{group_info}
|
||||||
@ -80,14 +79,11 @@ GasLiftStage2::GasLiftStage2(
|
|||||||
// currently has the largest weighted incremental gradient. The
|
// currently has the largest weighted incremental gradient. The
|
||||||
// procedure takes account of any limits on the group production rate
|
// procedure takes account of any limits on the group production rate
|
||||||
// or lift gas supply applied to any level of group, including the FIELD level group.
|
// or lift gas supply applied to any level of group, including the FIELD level group.
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::runOptimize()
|
||||||
runOptimize()
|
|
||||||
{
|
{
|
||||||
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
|
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
|
||||||
|
|
||||||
optimizeGroupsRecursive_(group);
|
optimizeGroupsRecursive_(group);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,17 +96,19 @@ runOptimize()
|
|||||||
// saved in "grad_map")
|
// saved in "grad_map")
|
||||||
// INPUT: grad_map : map of incremental (if "add" is true) or decremental
|
// INPUT: grad_map : map of incremental (if "add" is true) or decremental
|
||||||
// (if "add" is false) GradInfo structs for each well name.
|
// (if "add" is false) GradInfo structs for each well name.
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
addOrRemoveALQincrement_(GradMap &grad_map, const std::string& well_name, bool add)
|
addOrRemoveALQincrement_(GradMap &grad_map,
|
||||||
|
const std::string& well_name,
|
||||||
|
bool add)
|
||||||
{
|
{
|
||||||
// only applies to wells in the well_state_map (i.e. wells on this rank)
|
// only applies to wells in the well_state_map (i.e. wells on this rank)
|
||||||
auto it = this->well_state_map_.find(well_name);
|
auto it = this->well_state_map_.find(well_name);
|
||||||
if (it == this->well_state_map_.end())
|
if (it == this->well_state_map_.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GasLiftWellState &state = *(it->second.get());
|
GasLiftWellState<Scalar>& state = *(it->second.get());
|
||||||
const GradInfo &gi = grad_map.at(well_name);
|
const GradInfo& gi = grad_map.at(well_name);
|
||||||
if (this->debug) {
|
if (this->debug) {
|
||||||
auto new_alq = gi.alq;
|
auto new_alq = gi.alq;
|
||||||
auto old_alq = state.alq();
|
auto old_alq = state.alq();
|
||||||
@ -120,32 +118,35 @@ addOrRemoveALQincrement_(GradMap &grad_map, const std::string& well_name, bool a
|
|||||||
this->displayDebugMessage_(msg);
|
this->displayDebugMessage_(msg);
|
||||||
}
|
}
|
||||||
state.update(gi.new_oil_rate, gi.oil_is_limited,
|
state.update(gi.new_oil_rate, gi.oil_is_limited,
|
||||||
gi.new_gas_rate, gi.gas_is_limited,
|
gi.new_gas_rate, gi.gas_is_limited,
|
||||||
gi.alq, gi.alq_is_limited, gi.new_water_rate, gi.water_is_limited, add);
|
gi.alq, gi.alq_is_limited,
|
||||||
|
gi.new_water_rate, gi.water_is_limited, add);
|
||||||
|
|
||||||
this->well_state_.setALQ(well_name, gi.alq);
|
this->well_state_.setALQ(well_name, gi.alq);
|
||||||
const auto& pu = this->well_state_.phaseUsage();
|
const auto& pu = this->well_state_.phaseUsage();
|
||||||
std::vector<double> well_pot(pu.num_phases, 0.0);
|
std::vector<Scalar> well_pot(pu.num_phases, 0.0);
|
||||||
if(pu.phase_used[BlackoilPhases::PhaseIndex::Liquid])
|
if (pu.phase_used[BlackoilPhases::PhaseIndex::Liquid])
|
||||||
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Liquid]] = gi.new_oil_rate;
|
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Liquid]] = gi.new_oil_rate;
|
||||||
if(pu.phase_used[BlackoilPhases::PhaseIndex::Aqua])
|
if (pu.phase_used[BlackoilPhases::PhaseIndex::Aqua])
|
||||||
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Aqua]] = gi.new_water_rate;
|
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Aqua]] = gi.new_water_rate;
|
||||||
if(pu.phase_used[BlackoilPhases::PhaseIndex::Vapour])
|
if (pu.phase_used[BlackoilPhases::PhaseIndex::Vapour])
|
||||||
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Vapour]] = gi.new_gas_rate;
|
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Vapour]] = gi.new_gas_rate;
|
||||||
|
|
||||||
this->well_state_[well_name].well_potentials = well_pot;
|
this->well_state_[well_name].well_potentials = well_pot;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<GasLiftStage2::GradInfo>
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
std::optional<typename GasLiftStage2<Scalar>::GradInfo>
|
||||||
calcIncOrDecGrad_(
|
GasLiftStage2<Scalar>::
|
||||||
const std::string well_name, const GasLiftSingleWell &gs_well, const std::string& gr_name_dont_limit, bool increase)
|
calcIncOrDecGrad_(const std::string well_name,
|
||||||
|
const GasLiftSingleWell& gs_well,
|
||||||
|
const std::string& gr_name_dont_limit,
|
||||||
|
bool increase)
|
||||||
{
|
{
|
||||||
|
|
||||||
// only applies to wells in the well_state_map (i.e. wells on this rank)
|
// only applies to wells in the well_state_map (i.e. wells on this rank)
|
||||||
if(this->well_state_map_.count(well_name) == 0)
|
if (this->well_state_map_.count(well_name) == 0)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
GasLiftWellState &state = *(this->well_state_map_.at(well_name).get());
|
GasLiftWellState<Scalar>& state = *(this->well_state_map_.at(well_name).get());
|
||||||
if (checkRateAlreadyLimited_(well_name, state, increase)) {
|
if (checkRateAlreadyLimited_(well_name, state, increase)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@ -179,14 +180,18 @@ calcIncOrDecGrad_(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
bool GasLiftStage2<Scalar>::
|
||||||
checkRateAlreadyLimited_(const std::string& well_name, GasLiftWellState &state, bool increase)
|
checkRateAlreadyLimited_(const std::string& well_name,
|
||||||
|
GasLiftWellState<Scalar>& state,
|
||||||
|
bool increase)
|
||||||
{
|
{
|
||||||
auto current_increase = state.increase();
|
auto current_increase = state.increase();
|
||||||
bool do_check = false;
|
bool do_check = false;
|
||||||
if (current_increase) {
|
if (current_increase) {
|
||||||
if (*current_increase == increase) do_check = true;
|
if (*current_increase == increase) {
|
||||||
|
do_check = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If current_increase is not defined, it means that stage1
|
// If current_increase is not defined, it means that stage1
|
||||||
@ -196,10 +201,13 @@ checkRateAlreadyLimited_(const std::string& well_name, GasLiftWellState &state,
|
|||||||
// cause the new rates not to be limited. However, if
|
// cause the new rates not to be limited. However, if
|
||||||
// "increase" is false, subtracting ALQ can make the new rates
|
// "increase" is false, subtracting ALQ can make the new rates
|
||||||
// not limited.
|
// not limited.
|
||||||
if (increase) do_check = true;
|
if (increase) {
|
||||||
|
do_check = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (do_check) {
|
if (do_check) {
|
||||||
if (state.gasIsLimited() || state.oilIsLimited() || state.alqIsLimited() || state.waterIsLimited()) {
|
if (state.gasIsLimited() || state.oilIsLimited() ||
|
||||||
|
state.alqIsLimited() || state.waterIsLimited()) {
|
||||||
const std::string msg = fmt::format(
|
const std::string msg = fmt::format(
|
||||||
"Well {} : alq = {} : skipping {} gradient since {} was limited in previous step",
|
"Well {} : alq = {} : skipping {} gradient since {} was limited in previous step",
|
||||||
well_name,
|
well_name,
|
||||||
@ -214,9 +222,10 @@ checkRateAlreadyLimited_(const std::string& well_name, GasLiftWellState &state,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GasLiftStage2::GradInfo
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
typename GasLiftStage2<Scalar>::GradInfo
|
||||||
deleteGrad_(const std::string &name, bool increase)
|
GasLiftStage2<Scalar>::
|
||||||
|
deleteGrad_(const std::string& name, bool increase)
|
||||||
{
|
{
|
||||||
GradMap &map = increase ? this->inc_grads_ : this->dec_grads_;
|
GradMap &map = increase ? this->inc_grads_ : this->dec_grads_;
|
||||||
auto value = map.at(name);
|
auto value = map.at(name);
|
||||||
@ -224,56 +233,58 @@ deleteGrad_(const std::string &name, bool increase)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
GasLiftStage2::GradInfo
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
typename GasLiftStage2<Scalar>::GradInfo
|
||||||
deleteDecGradItem_(const std::string &name)
|
GasLiftStage2<Scalar>::
|
||||||
|
deleteDecGradItem_(const std::string& name)
|
||||||
{
|
{
|
||||||
return deleteGrad_(name, /*increase=*/false);
|
return deleteGrad_(name, /*increase=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
GasLiftStage2::GradInfo
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
typename GasLiftStage2<Scalar>::GradInfo
|
||||||
deleteIncGradItem_(const std::string &name)
|
GasLiftStage2<Scalar>::
|
||||||
|
deleteIncGradItem_(const std::string& name)
|
||||||
{
|
{
|
||||||
return deleteGrad_(name, /*increase=*/true);
|
return deleteGrad_(name, /*increase=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
displayWarning_(const std::string &msg, const std::string &group_name)
|
displayWarning_(const std::string& msg, const std::string& group_name)
|
||||||
{
|
{
|
||||||
const std::string message = fmt::format("GROUP: {} : {}", group_name, msg);
|
const std::string message = fmt::format("GROUP: {} : {}", group_name, msg);
|
||||||
displayWarning_(message);
|
displayWarning_(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
displayWarning_(const std::string &msg)
|
displayWarning_(const std::string& msg)
|
||||||
{
|
{
|
||||||
logMessage_(/*prefix=*/"GLIFT2", msg, MessageType::WARNING);
|
this->logMessage_(/*prefix=*/"GLIFT2", msg, MessageType::WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
displayDebugMessage_(const std::string &msg) const
|
displayDebugMessage_(const std::string& msg) const
|
||||||
{
|
{
|
||||||
if (this->debug) {
|
if (this->debug) {
|
||||||
logMessage_(/*prefix=*/"GLIFT2", msg);
|
this->logMessage_(/*prefix=*/"GLIFT2", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
displayDebugMessage2B_(const std::string &msg)
|
displayDebugMessage2B_(const std::string& msg)
|
||||||
{
|
{
|
||||||
if (this->debug) {
|
if (this->debug) {
|
||||||
logMessage_(/*prefix=*/"GLIFT2B", msg);
|
this->logMessage_(/*prefix=*/"GLIFT2B", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
displayDebugMessage_(const std::string &msg, const std::string &group_name)
|
displayDebugMessage_(const std::string& msg, const std::string& group_name)
|
||||||
{
|
{
|
||||||
if (this->debug) {
|
if (this->debug) {
|
||||||
const std::string message = fmt::format(
|
const std::string message = fmt::format(
|
||||||
@ -282,9 +293,10 @@ displayDebugMessage_(const std::string &msg, const std::string &group_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<double, double, double, double>
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
std::tuple<Scalar, Scalar, Scalar, Scalar>
|
||||||
getCurrentGroupRates_(const Group &group)
|
GasLiftStage2<Scalar>::
|
||||||
|
getCurrentGroupRates_(const Group& group)
|
||||||
{
|
{
|
||||||
return {this->group_info_.oilRate(group.name()),
|
return {this->group_info_.oilRate(group.name()),
|
||||||
this->group_info_.gasRate(group.name()),
|
this->group_info_.gasRate(group.name()),
|
||||||
@ -292,21 +304,23 @@ getCurrentGroupRates_(const Group &group)
|
|||||||
this->group_info_.alqRate(group.name())};
|
this->group_info_.alqRate(group.name())};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftStage2::getGroupMaxALQ_(const Group &group)
|
std::optional<Scalar>
|
||||||
|
GasLiftStage2<Scalar>::getGroupMaxALQ_(const Group& group)
|
||||||
{
|
{
|
||||||
if (this->glo_.has_group(group.name())) {
|
if (this->glo_.has_group(group.name())) {
|
||||||
const auto &gl_group = this->glo_.group(group.name());
|
const auto& gl_group = this->glo_.group(group.name());
|
||||||
return gl_group.max_lift_gas();
|
return gl_group.max_lift_gas();
|
||||||
}
|
}
|
||||||
return std::nullopt; // If GLIFTOPT is missing from schedule, assume unlimited alq
|
return std::nullopt; // If GLIFTOPT is missing from schedule, assume unlimited alq
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double>
|
template<class Scalar>
|
||||||
GasLiftStage2::getGroupMaxTotalGas_(const Group &group)
|
std::optional<Scalar>
|
||||||
|
GasLiftStage2<Scalar>::getGroupMaxTotalGas_(const Group& group)
|
||||||
{
|
{
|
||||||
if (this->glo_.has_group(group.name())) {
|
if (this->glo_.has_group(group.name())) {
|
||||||
const auto &gl_group = this->glo_.group(group.name());
|
const auto& gl_group = this->glo_.group(group.name());
|
||||||
return gl_group.max_total_gas();
|
return gl_group.max_total_gas();
|
||||||
}
|
}
|
||||||
return std::nullopt; // If GLIFTOPT is missing from schedule, assume unlimited alq
|
return std::nullopt; // If GLIFTOPT is missing from schedule, assume unlimited alq
|
||||||
@ -320,22 +334,23 @@ GasLiftStage2::getGroupMaxTotalGas_(const Group &group)
|
|||||||
// NOTE: This means that wells are located at the leaf nodes of the tree, and
|
// NOTE: This means that wells are located at the leaf nodes of the tree, and
|
||||||
// groups are located at the other nodes (not leaf nodes) of the tree
|
// groups are located at the other nodes (not leaf nodes) of the tree
|
||||||
//
|
//
|
||||||
std::vector<GasLiftSingleWellGeneric*>
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
std::vector<GasLiftSingleWellGeneric<Scalar>*>
|
||||||
getGroupGliftWells_(const Group &group)
|
GasLiftStage2<Scalar>::
|
||||||
|
getGroupGliftWells_(const Group& group)
|
||||||
{
|
{
|
||||||
std::vector<GasLiftSingleWell *> wells;
|
std::vector<GasLiftSingleWell*> wells;
|
||||||
getGroupGliftWellsRecursive_(group, wells);
|
getGroupGliftWellsRecursive_(group, wells);
|
||||||
return wells;
|
return wells;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
getGroupGliftWellsRecursive_(const Group &group,
|
getGroupGliftWellsRecursive_(const Group& group,
|
||||||
std::vector<GasLiftSingleWell *> &wells)
|
std::vector<GasLiftSingleWell*> &wells)
|
||||||
{
|
{
|
||||||
for (const std::string& group_name : group.groups()) {
|
for (const std::string& group_name : group.groups()) {
|
||||||
if(this->schedule_.back().groups.has(group_name)) {
|
if (this->schedule_.back().groups.has(group_name)) {
|
||||||
const Group& sub_group =
|
const Group& sub_group =
|
||||||
this->schedule_.getGroup(group_name, this->report_step_idx_);
|
this->schedule_.getGroup(group_name, this->report_step_idx_);
|
||||||
getGroupGliftWellsRecursive_(sub_group, wells);
|
getGroupGliftWellsRecursive_(sub_group, wells);
|
||||||
@ -343,15 +358,15 @@ getGroupGliftWellsRecursive_(const Group &group,
|
|||||||
}
|
}
|
||||||
for (const std::string& well_name : group.wells()) {
|
for (const std::string& well_name : group.wells()) {
|
||||||
if (this->stage1_wells_.count(well_name) == 1) {
|
if (this->stage1_wells_.count(well_name) == 1) {
|
||||||
GasLiftSingleWell *well_ptr = this->stage1_wells_.at(well_name).get();
|
GasLiftSingleWell* well_ptr = this->stage1_wells_.at(well_name).get();
|
||||||
wells.push_back(well_ptr);
|
wells.push_back(well_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
mpiSyncGlobalGradVector_(std::vector<GradPair> &grads_global) const
|
mpiSyncGlobalGradVector_(std::vector<GradPair>& grads_global) const
|
||||||
{
|
{
|
||||||
if (this->comm_.size() == 1)
|
if (this->comm_.size() == 1)
|
||||||
return;
|
return;
|
||||||
@ -365,10 +380,10 @@ mpiSyncGlobalGradVector_(std::vector<GradPair> &grads_global) const
|
|||||||
mpiSyncLocalToGlobalGradVector_(grads_local, grads_global);
|
mpiSyncLocalToGlobalGradVector_(grads_local, grads_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
mpiSyncLocalToGlobalGradVector_(
|
mpiSyncLocalToGlobalGradVector_(const std::vector<GradPair>& grads_local,
|
||||||
const std::vector<GradPair> &grads_local, std::vector<GradPair> &grads_global) const
|
std::vector<GradPair>& grads_global) const
|
||||||
{
|
{
|
||||||
assert(this->comm_.size() > 1); // The parent should check if comm. size is > 1
|
assert(this->comm_.size() > 1); // The parent should check if comm. size is > 1
|
||||||
using Pair = std::pair<int, double>;
|
using Pair = std::pair<int, double>;
|
||||||
@ -400,14 +415,14 @@ mpiSyncLocalToGlobalGradVector_(
|
|||||||
for (std::size_t i = 0; i < grads_global_tmp.size(); ++i) {
|
for (std::size_t i = 0; i < grads_global_tmp.size(); ++i) {
|
||||||
grads_global.emplace_back(
|
grads_global.emplace_back(
|
||||||
std::make_pair(
|
std::make_pair(
|
||||||
well_state_.globalIdxToWellName(grads_global_tmp[i].first),
|
this->well_state_.globalIdxToWellName(grads_global_tmp[i].first),
|
||||||
grads_global_tmp[i].second));
|
grads_global_tmp[i].second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
optimizeGroup_(const Group &group)
|
optimizeGroup_(const Group& group)
|
||||||
{
|
{
|
||||||
const auto& group_name = group.name();
|
const auto& group_name = group.name();
|
||||||
const auto prod_control = this->group_state_.production_control(group_name);
|
const auto prod_control = this->group_state_.production_control(group_name);
|
||||||
@ -431,9 +446,9 @@ optimizeGroup_(const Group &group)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
optimizeGroupsRecursive_(const Group &group)
|
optimizeGroupsRecursive_(const Group& group)
|
||||||
{
|
{
|
||||||
for (const std::string& group_name : group.groups()) {
|
for (const std::string& group_name : group.groups()) {
|
||||||
if(!this->schedule_.back().groups.has(group_name))
|
if(!this->schedule_.back().groups.has(group_name))
|
||||||
@ -445,15 +460,16 @@ optimizeGroupsRecursive_(const Group &group)
|
|||||||
optimizeGroup_(group);
|
optimizeGroup_(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
recalculateGradientAndUpdateData_(
|
recalculateGradientAndUpdateData_(GradPairItr& grad_itr,
|
||||||
GradPairItr &grad_itr, const std::string& gr_name_dont_limit, bool increase,
|
const std::string& gr_name_dont_limit,
|
||||||
|
bool increase,
|
||||||
//incremental and decremental gradients, if 'grads' are incremental, then
|
//incremental and decremental gradients, if 'grads' are incremental, then
|
||||||
// 'other_grads' are decremental, or conversely, if 'grads' are decremental, then
|
// 'other_grads' are decremental, or conversely, if 'grads' are decremental, then
|
||||||
// 'other_grads' are incremental
|
// 'other_grads' are incremental
|
||||||
std::vector<GradPair> &grads, std::vector<GradPair> &other_grads)
|
std::vector<GradPair>& grads,
|
||||||
|
std::vector<GradPair>& other_grads)
|
||||||
{
|
{
|
||||||
// NOTE: We make a copy of the name string instead of taking a reference
|
// NOTE: We make a copy of the name string instead of taking a reference
|
||||||
// since we may have to erase grad_itr (in the "else" condition below)
|
// since we may have to erase grad_itr (in the "else" condition below)
|
||||||
@ -547,10 +563,12 @@ recalculateGradientAndUpdateData_(
|
|||||||
// just do it once for the topmost group "PLAT-A" and then skip redistribution for
|
// just do it once for the topmost group "PLAT-A" and then skip redistribution for
|
||||||
// all sub groups of "PLAT-A"
|
// all sub groups of "PLAT-A"
|
||||||
//
|
//
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
redistributeALQ_(std::vector<GasLiftSingleWell *> &wells, const Group &group,
|
redistributeALQ_(std::vector<GasLiftSingleWell*>& wells,
|
||||||
std::vector<GradPair> &inc_grads, std::vector<GradPair> &dec_grads)
|
const Group& group,
|
||||||
|
std::vector<GradPair>& inc_grads,
|
||||||
|
std::vector<GradPair>& dec_grads)
|
||||||
{
|
{
|
||||||
OptimizeState state {*this, group};
|
OptimizeState state {*this, group};
|
||||||
if (this->comm_.size() == 1) {
|
if (this->comm_.size() == 1) {
|
||||||
@ -613,10 +631,11 @@ redistributeALQ_(std::vector<GasLiftSingleWell *> &wells, const Group &group,
|
|||||||
// Lift gas increments are removed in turn from the well that currently has
|
// Lift gas increments are removed in turn from the well that currently has
|
||||||
// the smallest weighted decremental gradient, until there is no surplus
|
// the smallest weighted decremental gradient, until there is no surplus
|
||||||
// lift gas in the group.
|
// lift gas in the group.
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
removeSurplusALQ_(const Group &group,
|
removeSurplusALQ_(const Group& group,
|
||||||
std::vector<GradPair> &inc_grads, std::vector<GradPair> &dec_grads)
|
std::vector<GradPair>& inc_grads,
|
||||||
|
std::vector<GradPair>& dec_grads)
|
||||||
{
|
{
|
||||||
if (dec_grads.empty()) {
|
if (dec_grads.empty()) {
|
||||||
displayDebugMessage_("no wells to remove ALQ from. Skipping");
|
displayDebugMessage_("no wells to remove ALQ from. Skipping");
|
||||||
@ -642,8 +661,12 @@ removeSurplusALQ_(const Group &group,
|
|||||||
displayDebugMessage_(msg);
|
displayDebugMessage_(msg);
|
||||||
}
|
}
|
||||||
SurplusState state {*this, group, oil_rate, gas_rate, water_rate, alq,
|
SurplusState state {*this, group, oil_rate, gas_rate, water_rate, alq,
|
||||||
min_eco_grad, controls.oil_target, controls.gas_target, controls.water_target,
|
static_cast<Scalar>(min_eco_grad),
|
||||||
controls.liquid_target, max_glift, max_totalgas };
|
static_cast<Scalar>(controls.oil_target),
|
||||||
|
static_cast<Scalar>(controls.gas_target),
|
||||||
|
static_cast<Scalar>(controls.water_target),
|
||||||
|
static_cast<Scalar>(controls.liquid_target),
|
||||||
|
max_glift, max_totalgas };
|
||||||
|
|
||||||
while (!stop_iteration) {
|
while (!stop_iteration) {
|
||||||
if (dec_grads.size() >= 2) {
|
if (dec_grads.size() >= 2) {
|
||||||
@ -707,9 +730,9 @@ removeSurplusALQ_(const Group &group,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
saveGrad_(GradMap &map, const std::string &name, GradInfo &grad)
|
saveGrad_(GradMap& map, const std::string& name, GradInfo& grad)
|
||||||
{
|
{
|
||||||
if (auto it = map.find(name); it == map.end()) {
|
if (auto it = map.find(name); it == map.end()) {
|
||||||
[[maybe_unused]] auto result = map.emplace(name, grad);
|
[[maybe_unused]] auto result = map.emplace(name, grad);
|
||||||
@ -720,23 +743,23 @@ saveGrad_(GradMap &map, const std::string &name, GradInfo &grad)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
saveDecGrad_(const std::string &name, GradInfo &grad)
|
saveDecGrad_(const std::string& name, GradInfo& grad)
|
||||||
{
|
{
|
||||||
saveGrad_(this->dec_grads_, name, grad);
|
saveGrad_(this->dec_grads_, name, grad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
saveIncGrad_(const std::string &name, GradInfo &grad)
|
saveIncGrad_(const std::string& name, GradInfo& grad)
|
||||||
{
|
{
|
||||||
saveGrad_(this->inc_grads_, name, grad);
|
saveGrad_(this->inc_grads_, name, grad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
sortGradients_(std::vector<GradPair> &grads)
|
sortGradients_(std::vector<GradPair>& grads)
|
||||||
{
|
{
|
||||||
auto cmp = [](GradPair a, GradPair b) {
|
auto cmp = [](GradPair a, GradPair b) {
|
||||||
return a.second < b.second;
|
return a.second < b.second;
|
||||||
@ -744,11 +767,12 @@ sortGradients_(std::vector<GradPair> &grads)
|
|||||||
std::sort(grads.begin(), grads.end(), cmp);
|
std::sort(grads.begin(), grads.end(), cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<GasLiftStage2::GradInfo>
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
std::optional<typename GasLiftStage2<Scalar>::GradInfo>
|
||||||
updateGrad_(const std::string &name, GradInfo &grad, bool increase)
|
GasLiftStage2<Scalar>::
|
||||||
|
updateGrad_(const std::string& name, GradInfo& grad, bool increase)
|
||||||
{
|
{
|
||||||
GradMap &map = increase ? this->inc_grads_ : this->dec_grads_;
|
GradMap& map = increase ? this->inc_grads_ : this->dec_grads_;
|
||||||
std::optional<GradInfo> old_value = std::nullopt;
|
std::optional<GradInfo> old_value = std::nullopt;
|
||||||
if (map.count(name) == 1) {
|
if (map.count(name) == 1) {
|
||||||
old_value = map.at(name);
|
old_value = map.at(name);
|
||||||
@ -757,9 +781,11 @@ updateGrad_(const std::string &name, GradInfo &grad, bool increase)
|
|||||||
return old_value;
|
return old_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::
|
void GasLiftStage2<Scalar>::
|
||||||
updateGradVector_(const std::string &name, std::vector<GradPair> &grads, double grad)
|
updateGradVector_(const std::string& name,
|
||||||
|
std::vector<GradPair>& grads,
|
||||||
|
Scalar grad)
|
||||||
{
|
{
|
||||||
for (auto itr = grads.begin(); itr != grads.end(); itr++) {
|
for (auto itr = grads.begin(); itr != grads.end(); itr++) {
|
||||||
if (itr->first == name) {
|
if (itr->first == name) {
|
||||||
@ -776,14 +802,15 @@ updateGradVector_(const std::string &name, std::vector<GradPair> &grads, double
|
|||||||
* Public methods declared in OptimizeState
|
* Public methods declared in OptimizeState
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::OptimizeState::
|
void GasLiftStage2<Scalar>::OptimizeState::
|
||||||
calculateEcoGradients(std::vector<GasLiftSingleWell *> &wells,
|
calculateEcoGradients(std::vector<GasLiftSingleWell*>& wells,
|
||||||
std::vector<GradPair> &inc_grads, std::vector<GradPair> &dec_grads)
|
std::vector<GradPair>& inc_grads,
|
||||||
|
std::vector<GradPair>& dec_grads)
|
||||||
{
|
{
|
||||||
for (auto well_ptr : wells) {
|
for (auto well_ptr : wells) {
|
||||||
const auto &gs_well = *well_ptr; // gs = GasLiftSingleWell
|
const auto& gs_well = *well_ptr; // gs = GasLiftSingleWell
|
||||||
const auto &name = gs_well.name();
|
const auto& name = gs_well.name();
|
||||||
auto inc_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group.name(), /*increase=*/true);
|
auto inc_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group.name(), /*increase=*/true);
|
||||||
if (inc_grad) {
|
if (inc_grad) {
|
||||||
inc_grads.emplace_back(std::make_pair(name, inc_grad->grad));
|
inc_grads.emplace_back(std::make_pair(name, inc_grad->grad));
|
||||||
@ -797,10 +824,9 @@ calculateEcoGradients(std::vector<GasLiftSingleWell *> &wells,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
bool
|
bool GasLiftStage2<Scalar>::OptimizeState::
|
||||||
GasLiftStage2::OptimizeState::
|
checkAtLeastTwoWells(std::vector<GasLiftSingleWell*>& wells)
|
||||||
checkAtLeastTwoWells(std::vector<GasLiftSingleWell *> &wells)
|
|
||||||
{
|
{
|
||||||
int numberOfwells = 0;
|
int numberOfwells = 0;
|
||||||
for (auto well : wells){
|
for (auto well : wells){
|
||||||
@ -819,18 +845,20 @@ checkAtLeastTwoWells(std::vector<GasLiftSingleWell *> &wells)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::OptimizeState::
|
void GasLiftStage2<Scalar>::OptimizeState::
|
||||||
debugShowIterationInfo()
|
debugShowIterationInfo()
|
||||||
{
|
{
|
||||||
const std::string msg = fmt::format("redistribute ALQ iteration {}", this->it);
|
const std::string msg = fmt::format("redistribute ALQ iteration {}", this->it);
|
||||||
displayDebugMessage_(msg);
|
displayDebugMessage_(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::optional<GasLiftStage2::GradPairItr>,
|
template<class Scalar>
|
||||||
std::optional<GasLiftStage2::GradPairItr>>
|
std::pair<std::optional<typename GasLiftStage2<Scalar>::GradPairItr>,
|
||||||
GasLiftStage2::OptimizeState::
|
std::optional<typename GasLiftStage2<Scalar>::GradPairItr>>
|
||||||
getEcoGradients(std::vector<GradPair> &inc_grads, std::vector<GradPair> &dec_grads)
|
GasLiftStage2<Scalar>::OptimizeState::
|
||||||
|
getEcoGradients(std::vector<GradPair>& inc_grads,
|
||||||
|
std::vector<GradPair>& dec_grads)
|
||||||
{
|
{
|
||||||
if (!inc_grads.empty() && !dec_grads.empty()) {
|
if (!inc_grads.empty() && !dec_grads.empty()) {
|
||||||
this->parent.sortGradients_(inc_grads);
|
this->parent.sortGradients_(inc_grads);
|
||||||
@ -869,11 +897,12 @@ getEcoGradients(std::vector<GradPair> &inc_grads, std::vector<GradPair> &dec_gra
|
|||||||
// a new decremental gradient given the new ALQ. The new incremental gradient
|
// a new decremental gradient given the new ALQ. The new incremental gradient
|
||||||
// for this well is set equal to the current decremental gradient
|
// for this well is set equal to the current decremental gradient
|
||||||
// (before the ALQ is subtracted)
|
// (before the ALQ is subtracted)
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::OptimizeState::
|
void GasLiftStage2<Scalar>::OptimizeState::
|
||||||
recalculateGradients(
|
recalculateGradients(std::vector<GradPair>& inc_grads,
|
||||||
std::vector<GradPair> &inc_grads, std::vector<GradPair> &dec_grads,
|
std::vector<GradPair>& dec_grads,
|
||||||
GradPairItr &min_dec_grad_itr, GradPairItr &max_inc_grad_itr)
|
GradPairItr& min_dec_grad_itr,
|
||||||
|
GradPairItr& max_inc_grad_itr)
|
||||||
{
|
{
|
||||||
this->parent.recalculateGradientAndUpdateData_(
|
this->parent.recalculateGradientAndUpdateData_(
|
||||||
max_inc_grad_itr, this->group.name(), /*increase=*/true, inc_grads, dec_grads);
|
max_inc_grad_itr, this->group.name(), /*increase=*/true, inc_grads, dec_grads);
|
||||||
@ -886,9 +915,10 @@ recalculateGradients(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Take one ALQ increment from well1, and give it to well2
|
// Take one ALQ increment from well1, and give it to well2
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::OptimizeState::
|
void GasLiftStage2<Scalar>::OptimizeState::
|
||||||
redistributeALQ( GradPairItr &min_dec_grad, GradPairItr &max_inc_grad)
|
redistributeALQ(GradPairItr& min_dec_grad,
|
||||||
|
GradPairItr& max_inc_grad)
|
||||||
{
|
{
|
||||||
const std::string msg = fmt::format(
|
const std::string msg = fmt::format(
|
||||||
"redistributing ALQ from well {} (dec gradient: {}) "
|
"redistributing ALQ from well {} (dec gradient: {}) "
|
||||||
@ -906,16 +936,16 @@ GasLiftStage2::OptimizeState::
|
|||||||
* Private methods declared in OptimizeState
|
* Private methods declared in OptimizeState
|
||||||
**********************************************/
|
**********************************************/
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::OptimizeState::
|
void GasLiftStage2<Scalar>::OptimizeState::
|
||||||
displayDebugMessage_(const std::string &msg)
|
displayDebugMessage_(const std::string& msg)
|
||||||
{
|
{
|
||||||
this->parent.displayDebugMessage_(msg, this->group.name());
|
this->parent.displayDebugMessage_(msg, this->group.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::OptimizeState::
|
void GasLiftStage2<Scalar>::OptimizeState::
|
||||||
displayWarning_(const std::string &msg)
|
displayWarning_(const std::string& msg)
|
||||||
{
|
{
|
||||||
this->parent.displayWarning_(msg, this->group.name());
|
this->parent.displayWarning_(msg, this->group.name());
|
||||||
}
|
}
|
||||||
@ -924,9 +954,11 @@ displayWarning_(const std::string &msg)
|
|||||||
* Public methods declared in SurplusState
|
* Public methods declared in SurplusState
|
||||||
**********************************************/
|
**********************************************/
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
void GasLiftStage2<Scalar>::SurplusState::
|
||||||
addOrRemoveALQincrement(GradMap &grad_map, const std::string& well_name, bool add)
|
addOrRemoveALQincrement(GradMap& grad_map,
|
||||||
|
const std::string& well_name,
|
||||||
|
bool add)
|
||||||
{
|
{
|
||||||
if (this->parent.debug) {
|
if (this->parent.debug) {
|
||||||
const std::string msg = fmt::format("group: {} : well {} : {} ALQ increment",
|
const std::string msg = fmt::format("group: {} : well {} : {} ALQ increment",
|
||||||
@ -936,12 +968,12 @@ addOrRemoveALQincrement(GradMap &grad_map, const std::string& well_name, bool ad
|
|||||||
this->parent.addOrRemoveALQincrement_(grad_map, well_name, add);
|
this->parent.addOrRemoveALQincrement_(grad_map, well_name, add);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
bool GasLiftStage2<Scalar>::SurplusState::
|
||||||
checkALQlimit()
|
checkALQlimit()
|
||||||
{
|
{
|
||||||
if (this->max_glift) {
|
if (this->max_glift) {
|
||||||
double max_alq = *(this->max_glift);
|
Scalar max_alq = *(this->max_glift);
|
||||||
if ((max_alq) < (this->alq) ) {
|
if ((max_alq) < (this->alq) ) {
|
||||||
if (this->parent.debug) {
|
if (this->parent.debug) {
|
||||||
const std::string msg = fmt::format("group: {} : "
|
const std::string msg = fmt::format("group: {} : "
|
||||||
@ -953,8 +985,8 @@ checkALQlimit()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->max_total_gas) {
|
if (this->max_total_gas) {
|
||||||
double max_total = *(this->max_total_gas);
|
Scalar max_total = *(this->max_total_gas);
|
||||||
double total_gas_rate = (this->alq + this->gas_rate);
|
Scalar total_gas_rate = (this->alq + this->gas_rate);
|
||||||
if ((max_total) < total_gas_rate ) {
|
if ((max_total) < total_gas_rate ) {
|
||||||
if (this->parent.debug) {
|
if (this->parent.debug) {
|
||||||
const std::string msg = fmt::format("group: {} : "
|
const std::string msg = fmt::format("group: {} : "
|
||||||
@ -968,9 +1000,9 @@ checkALQlimit()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
bool GasLiftStage2<Scalar>::SurplusState::
|
||||||
checkEcoGradient(const std::string &well_name, double eco_grad)
|
checkEcoGradient(const std::string& well_name, Scalar eco_grad)
|
||||||
{
|
{
|
||||||
if (eco_grad < this->min_eco_grad) {
|
if (eco_grad < this->min_eco_grad) {
|
||||||
if (this->parent.debug) {
|
if (this->parent.debug) {
|
||||||
@ -986,9 +1018,9 @@ checkEcoGradient(const std::string &well_name, double eco_grad)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
bool GasLiftStage2<Scalar>::SurplusState::
|
||||||
checkGasTarget(double delta_gas)
|
checkGasTarget(Scalar delta_gas)
|
||||||
{
|
{
|
||||||
if (this->group.has_control(Group::ProductionCMode::GRAT)) {
|
if (this->group.has_control(Group::ProductionCMode::GRAT)) {
|
||||||
// the change in gas rate is added to the gas rate to make sure the
|
// the change in gas rate is added to the gas rate to make sure the
|
||||||
@ -1007,9 +1039,10 @@ checkGasTarget(double delta_gas)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool
|
|
||||||
GasLiftStage2::SurplusState::
|
template<class Scalar>
|
||||||
checkLiquidTarget(double delta_liquid)
|
bool GasLiftStage2<Scalar>::SurplusState::
|
||||||
|
checkLiquidTarget(Scalar delta_liquid)
|
||||||
{
|
{
|
||||||
if (this->group.has_control(Group::ProductionCMode::LRAT)) {
|
if (this->group.has_control(Group::ProductionCMode::LRAT)) {
|
||||||
// the change in liquid rate is added to the liquid rate to make sure the
|
// the change in liquid rate is added to the liquid rate to make sure the
|
||||||
@ -1030,9 +1063,9 @@ checkLiquidTarget(double delta_liquid)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
bool GasLiftStage2<Scalar>::SurplusState::
|
||||||
checkOilTarget(double delta_oil)
|
checkOilTarget(Scalar delta_oil)
|
||||||
{
|
{
|
||||||
if (this->group.has_control(Group::ProductionCMode::ORAT)) {
|
if (this->group.has_control(Group::ProductionCMode::ORAT)) {
|
||||||
// the change in oil rate is added to the oil rate to make sure the
|
// the change in oil rate is added to the oil rate to make sure the
|
||||||
@ -1052,10 +1085,10 @@ checkOilTarget(double delta_oil)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
bool GasLiftStage2<Scalar>::SurplusState::
|
||||||
checkWaterTarget(double delta_water)
|
checkWaterTarget(Scalar delta_water)
|
||||||
{
|
{
|
||||||
if (this->group.has_control(Group::ProductionCMode::WRAT)) {
|
if (this->group.has_control(Group::ProductionCMode::WRAT)) {
|
||||||
// the change in water rate is added to the water rate to make sure the
|
// the change in water rate is added to the water rate to make sure the
|
||||||
// group still can produce its target
|
// group still can produce its target
|
||||||
@ -1074,21 +1107,22 @@ checkWaterTarget(double delta_water)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<double, 4>
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
std::array<Scalar, 4>
|
||||||
computeDelta(const std::string &well_name)
|
GasLiftStage2<Scalar>::SurplusState::
|
||||||
|
computeDelta(const std::string& well_name)
|
||||||
{
|
{
|
||||||
std::array<double, 4> delta = {0.0, 0.0, 0.0, 0.0};
|
std::array<Scalar, 4> delta = {0.0, 0.0, 0.0, 0.0};
|
||||||
// compute the delta on wells on own rank
|
// compute the delta on wells on own rank
|
||||||
if (this->parent.well_state_map_.count(well_name) > 0) {
|
if (this->parent.well_state_map_.count(well_name) > 0) {
|
||||||
const GradInfo &gi = this->parent.dec_grads_.at(well_name);
|
const GradInfo& gi = this->parent.dec_grads_.at(well_name);
|
||||||
GasLiftWellState &state = *(this->parent.well_state_map_.at(well_name).get());
|
GasLiftWellState<Scalar>& state = *(this->parent.well_state_map_.at(well_name).get());
|
||||||
GasLiftSingleWell &gs_well = *(this->parent.stage1_wells_.at(well_name).get());
|
GasLiftSingleWell& gs_well = *(this->parent.stage1_wells_.at(well_name).get());
|
||||||
const WellInterfaceGeneric &well = gs_well.getWell();
|
const WellInterfaceGeneric& well = gs_well.getWell();
|
||||||
// only get deltas for wells owned by this rank
|
// only get deltas for wells owned by this rank
|
||||||
if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) {
|
if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) {
|
||||||
const auto &well_ecl = well.wellEcl();
|
const auto& well_ecl = well.wellEcl();
|
||||||
double factor = well_ecl.getEfficiencyFactor();
|
Scalar factor = well_ecl.getEfficiencyFactor();
|
||||||
auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
|
auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
|
||||||
delta_oil = factor * (gi.new_oil_rate - state.oilRate());
|
delta_oil = factor * (gi.new_oil_rate - state.oilRate());
|
||||||
delta_gas = factor * (gi.new_gas_rate - state.gasRate());
|
delta_gas = factor * (gi.new_gas_rate - state.gasRate());
|
||||||
@ -1103,9 +1137,9 @@ computeDelta(const std::string &well_name)
|
|||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template<class Scalar>
|
||||||
GasLiftStage2::SurplusState::
|
void GasLiftStage2<Scalar>::SurplusState::
|
||||||
updateRates(const std::array<double, 4>& delta)
|
updateRates(const std::array<Scalar, 4>& delta)
|
||||||
{
|
{
|
||||||
const auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
|
const auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
|
||||||
this->oil_rate += delta_oil;
|
this->oil_rate += delta_oil;
|
||||||
@ -1114,5 +1148,6 @@ updateRates(const std::array<double, 4>& delta)
|
|||||||
this->alq += delta_alq;
|
this->alq += delta_alq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template class GasLiftStage2<double>;
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
@ -30,96 +30,124 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm {
|
||||||
{
|
|
||||||
|
|
||||||
class DeferredLogger;
|
class DeferredLogger;
|
||||||
class GasLiftOpt;
|
class GasLiftOpt;
|
||||||
class GasLiftWellState;
|
template<class Scalar> class GasLiftWellState;
|
||||||
class Group;
|
class Group;
|
||||||
template<class Scalar> class GroupState;
|
template<class Scalar> class GroupState;
|
||||||
class Schedule;
|
class Schedule;
|
||||||
class WellInterfaceGeneric;
|
class WellInterfaceGeneric;
|
||||||
template<class Scalar> class WellState;
|
template<class Scalar> class WellState;
|
||||||
|
|
||||||
class GasLiftStage2 : public GasLiftCommon {
|
template<class Scalar>
|
||||||
using GasLiftSingleWell = GasLiftSingleWellGeneric;
|
class GasLiftStage2 : public GasLiftCommon<Scalar>
|
||||||
|
{
|
||||||
|
using GasLiftSingleWell = GasLiftSingleWellGeneric<Scalar>;
|
||||||
using GLiftOptWells = std::map<std::string,std::unique_ptr<GasLiftSingleWell>>;
|
using GLiftOptWells = std::map<std::string,std::unique_ptr<GasLiftSingleWell>>;
|
||||||
using GLiftProdWells = std::map<std::string,const WellInterfaceGeneric*>;
|
using GLiftProdWells = std::map<std::string,const WellInterfaceGeneric*>;
|
||||||
using GLiftWellStateMap = std::map<std::string,std::unique_ptr<GasLiftWellState>>;
|
using GLiftWellStateMap = std::map<std::string,std::unique_ptr<GasLiftWellState<Scalar>>>;
|
||||||
using GradPair = std::pair<std::string, double>;
|
using GradPair = std::pair<std::string, Scalar>;
|
||||||
using GradPairItr = std::vector<GradPair>::iterator;
|
using GradPairItr = typename std::vector<GradPair>::iterator;
|
||||||
using GradInfo = typename GasLiftSingleWellGeneric::GradInfo;
|
using GradInfo = typename GasLiftSingleWellGeneric<Scalar>::GradInfo;
|
||||||
using GradMap = std::map<std::string, GradInfo>;
|
using GradMap = std::map<std::string, GradInfo>;
|
||||||
using MPIComm = typename Dune::MPIHelper::MPICommunicator;
|
using MessageType = typename GasLiftCommon<Scalar>::MessageType;
|
||||||
|
|
||||||
static const int Water = BlackoilPhases::Aqua;
|
static const int Water = BlackoilPhases::Aqua;
|
||||||
static const int Oil = BlackoilPhases::Liquid;
|
static const int Oil = BlackoilPhases::Liquid;
|
||||||
static const int Gas = BlackoilPhases::Vapour;
|
static const int Gas = BlackoilPhases::Vapour;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GasLiftStage2(
|
GasLiftStage2(const int report_step_idx,
|
||||||
const int report_step_idx,
|
const Parallel::Communication& comm,
|
||||||
const Parallel::Communication& comm,
|
const Schedule& schedule,
|
||||||
const Schedule& schedule,
|
const SummaryState& summary_state,
|
||||||
const SummaryState& summary_state,
|
DeferredLogger& deferred_logger,
|
||||||
DeferredLogger& deferred_logger,
|
WellState<Scalar>& well_state,
|
||||||
WellState<double>& well_state,
|
const GroupState<Scalar>& group_state,
|
||||||
const GroupState<double>& group_state,
|
GLiftProdWells& prod_wells,
|
||||||
GLiftProdWells& prod_wells,
|
GLiftOptWells& glift_wells,
|
||||||
GLiftOptWells& glift_wells,
|
GasLiftGroupInfo<Scalar>& group_info,
|
||||||
GasLiftGroupInfo& group_info,
|
GLiftWellStateMap& state_map,
|
||||||
GLiftWellStateMap& state_map,
|
bool glift_debug);
|
||||||
bool glift_debug
|
|
||||||
);
|
|
||||||
void runOptimize();
|
void runOptimize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addOrRemoveALQincrement_(
|
void addOrRemoveALQincrement_(GradMap& grad_map,
|
||||||
GradMap& grad_map, const std::string& well_name, bool add);
|
const std::string& well_name,
|
||||||
std::optional<GradInfo> calcIncOrDecGrad_(
|
bool add);
|
||||||
const std::string name, const GasLiftSingleWell& gs_well, const std::string& gr_name_dont_limit, bool increase);
|
|
||||||
bool checkRateAlreadyLimited_(const std::string& well_name, GasLiftWellState& state, bool increase);
|
std::optional<GradInfo> calcIncOrDecGrad_(const std::string name,
|
||||||
|
const GasLiftSingleWell& gs_well,
|
||||||
|
const std::string& gr_name_dont_limit,
|
||||||
|
bool increase);
|
||||||
|
|
||||||
|
bool checkRateAlreadyLimited_(const std::string& well_name,
|
||||||
|
GasLiftWellState<Scalar>& state,
|
||||||
|
bool increase);
|
||||||
|
|
||||||
GradInfo deleteDecGradItem_(const std::string& name);
|
GradInfo deleteDecGradItem_(const std::string& name);
|
||||||
GradInfo deleteIncGradItem_(const std::string& name);
|
GradInfo deleteIncGradItem_(const std::string& name);
|
||||||
GradInfo deleteGrad_(const std::string& name, bool increase);
|
GradInfo deleteGrad_(const std::string& name, bool increase);
|
||||||
|
|
||||||
void displayDebugMessage_(const std::string& msg) const override;
|
void displayDebugMessage_(const std::string& msg) const override;
|
||||||
void displayDebugMessage2B_(const std::string& msg);
|
void displayDebugMessage2B_(const std::string& msg);
|
||||||
void displayDebugMessage_(const std::string& msg, const std::string& group_name);
|
void displayDebugMessage_(const std::string& msg,
|
||||||
void displayWarning_(const std::string& msg, const std::string& group_name);
|
const std::string& group_name);
|
||||||
|
void displayWarning_(const std::string& msg,
|
||||||
|
const std::string& group_name);
|
||||||
void displayWarning_(const std::string& msg);
|
void displayWarning_(const std::string& msg);
|
||||||
std::tuple<double, double, double, double> getCurrentGroupRates_(const Group& group);
|
|
||||||
std::optional<double> getGroupMaxALQ_(const Group &group);
|
std::tuple<Scalar, Scalar, Scalar, Scalar>
|
||||||
std::optional<double> getGroupMaxTotalGas_(const Group &group);
|
getCurrentGroupRates_(const Group& group);
|
||||||
std::vector<GasLiftSingleWell *> getGroupGliftWells_(
|
|
||||||
const Group& group);
|
std::optional<Scalar> getGroupMaxALQ_(const Group& group);
|
||||||
void getGroupGliftWellsRecursive_(
|
std::optional<Scalar> getGroupMaxTotalGas_(const Group& group);
|
||||||
const Group& group, std::vector<GasLiftSingleWell *>& wells);
|
|
||||||
|
std::vector<GasLiftSingleWell*> getGroupGliftWells_(const Group& group);
|
||||||
|
|
||||||
|
void getGroupGliftWellsRecursive_(const Group& group,
|
||||||
|
std::vector<GasLiftSingleWell*>& wells);
|
||||||
|
|
||||||
void optimizeGroup_(const Group& group);
|
void optimizeGroup_(const Group& group);
|
||||||
void optimizeGroupsRecursive_(const Group& group);
|
void optimizeGroupsRecursive_(const Group& group);
|
||||||
void recalculateGradientAndUpdateData_(
|
|
||||||
GradPairItr& grad_itr, const std::string& gr_name_dont_limit, bool increase,
|
void recalculateGradientAndUpdateData_(GradPairItr& grad_itr,
|
||||||
std::vector<GradPair>& grads, std::vector<GradPair>& other_grads);
|
const std::string& gr_name_dont_limit,
|
||||||
void redistributeALQ_(
|
bool increase,
|
||||||
std::vector<GasLiftSingleWell *>& wells, const Group& group,
|
std::vector<GradPair>& grads,
|
||||||
std::vector<GradPair>& inc_grads, std::vector<GradPair>& dec_grads);
|
std::vector<GradPair>& other_grads);
|
||||||
void removeSurplusALQ_(
|
|
||||||
const Group& group,
|
void redistributeALQ_(std::vector<GasLiftSingleWell*>& wells,
|
||||||
std::vector<GradPair>& inc_grads, std::vector<GradPair>& dec_grads);
|
const Group& group,
|
||||||
|
std::vector<GradPair>& inc_grads,
|
||||||
|
std::vector<GradPair>& dec_grads);
|
||||||
|
|
||||||
|
void removeSurplusALQ_(const Group& group,
|
||||||
|
std::vector<GradPair>& inc_grads,
|
||||||
|
std::vector<GradPair>& dec_grads);
|
||||||
|
|
||||||
void saveGrad_(GradMap& map, const std::string& name, GradInfo& grad);
|
void saveGrad_(GradMap& map, const std::string& name, GradInfo& grad);
|
||||||
void saveDecGrad_(const std::string& name, GradInfo& grad);
|
void saveDecGrad_(const std::string& name, GradInfo& grad);
|
||||||
void saveIncGrad_(const std::string& name, GradInfo& grad);
|
void saveIncGrad_(const std::string& name, GradInfo& grad);
|
||||||
void sortGradients_(std::vector<GradPair>& grads);
|
void sortGradients_(std::vector<GradPair>& grads);
|
||||||
std::optional<GradInfo> updateGrad_(
|
|
||||||
const std::string& name, GradInfo& grad, bool increase);
|
|
||||||
void updateGradVector_(
|
|
||||||
const std::string& name, std::vector<GradPair>& grads, double grad);
|
|
||||||
void mpiSyncGlobalGradVector_(std::vector<GradPair>& grads_global) const;
|
|
||||||
void mpiSyncLocalToGlobalGradVector_(
|
|
||||||
const std::vector<GradPair>& grads_local,
|
|
||||||
std::vector<GradPair>& grads_global) const;
|
|
||||||
|
|
||||||
|
std::optional<GradInfo> updateGrad_(const std::string& name,
|
||||||
|
GradInfo& grad, bool increase);
|
||||||
|
|
||||||
|
void updateGradVector_(const std::string& name,
|
||||||
|
std::vector<GradPair>& grads,
|
||||||
|
Scalar grad);
|
||||||
|
|
||||||
|
void mpiSyncGlobalGradVector_(std::vector<GradPair>& grads_global) const;
|
||||||
|
void mpiSyncLocalToGlobalGradVector_(const std::vector<GradPair>& grads_local,
|
||||||
|
std::vector<GradPair>& grads_global) const;
|
||||||
|
|
||||||
GLiftProdWells& prod_wells_;
|
GLiftProdWells& prod_wells_;
|
||||||
GLiftOptWells& stage1_wells_;
|
GLiftOptWells& stage1_wells_;
|
||||||
GasLiftGroupInfo& group_info_;
|
GasLiftGroupInfo<Scalar>& group_info_;
|
||||||
GLiftWellStateMap& well_state_map_;
|
GLiftWellStateMap& well_state_map_;
|
||||||
|
|
||||||
int report_step_idx_;
|
int report_step_idx_;
|
||||||
@ -131,12 +159,14 @@ protected:
|
|||||||
int max_iterations_ = 1000;
|
int max_iterations_ = 1000;
|
||||||
//int time_step_idx_;
|
//int time_step_idx_;
|
||||||
|
|
||||||
struct OptimizeState {
|
struct OptimizeState
|
||||||
OptimizeState(GasLiftStage2& parent_, const Group& group_ ) :
|
{
|
||||||
parent{parent_},
|
OptimizeState(GasLiftStage2& parent_, const Group& group_)
|
||||||
group{group_},
|
: parent{parent_}
|
||||||
it{0}
|
, group{group_}
|
||||||
|
, it{0}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GasLiftStage2& parent;
|
GasLiftStage2& parent;
|
||||||
const Group& group;
|
const Group& group;
|
||||||
int it;
|
int it;
|
||||||
@ -145,70 +175,90 @@ protected:
|
|||||||
using GradPair = typename GasLiftStage2::GradPair;
|
using GradPair = typename GasLiftStage2::GradPair;
|
||||||
using GradPairItr = typename GasLiftStage2::GradPairItr;
|
using GradPairItr = typename GasLiftStage2::GradPairItr;
|
||||||
using GradMap = typename GasLiftStage2::GradMap;
|
using GradMap = typename GasLiftStage2::GradMap;
|
||||||
void calculateEcoGradients(std::vector<GasLiftSingleWell *>& wells,
|
|
||||||
std::vector<GradPair>& inc_grads, std::vector<GradPair>& dec_grads);
|
void calculateEcoGradients(std::vector<GasLiftSingleWell*>& wells,
|
||||||
bool checkAtLeastTwoWells(std::vector<GasLiftSingleWell *>& wells);
|
std::vector<GradPair>& inc_grads,
|
||||||
|
std::vector<GradPair>& dec_grads);
|
||||||
|
|
||||||
|
bool checkAtLeastTwoWells(std::vector<GasLiftSingleWell*>& wells);
|
||||||
|
|
||||||
void debugShowIterationInfo();
|
void debugShowIterationInfo();
|
||||||
|
|
||||||
std::pair<std::optional<GradPairItr>,std::optional<GradPairItr>>
|
std::pair<std::optional<GradPairItr>,std::optional<GradPairItr>>
|
||||||
getEcoGradients(
|
getEcoGradients(std::vector<GradPair>& inc_grads,
|
||||||
std::vector<GradPair>& inc_grads, std::vector<GradPair>& dec_grads);
|
std::vector<GradPair>& dec_grads);
|
||||||
void recalculateGradients(
|
|
||||||
std::vector<GradPair>& inc_grads, std::vector<GradPair>& dec_grads,
|
void recalculateGradients(std::vector<GradPair>& inc_grads,
|
||||||
GradPairItr& min_dec_grad_itr, GradPairItr &max_inc_grad_itr);
|
std::vector<GradPair>& dec_grads,
|
||||||
void redistributeALQ( GradPairItr& min_dec_grad, GradPairItr& max_inc_grad);
|
GradPairItr& min_dec_grad_itr,
|
||||||
|
GradPairItr &max_inc_grad_itr);
|
||||||
|
|
||||||
|
void redistributeALQ( GradPairItr& min_dec_grad,
|
||||||
|
GradPairItr& max_inc_grad);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void displayDebugMessage_(const std::string& msg);
|
void displayDebugMessage_(const std::string& msg);
|
||||||
void displayWarning_(const std::string& msg);
|
void displayWarning_(const std::string& msg);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SurplusState {
|
struct SurplusState
|
||||||
SurplusState( GasLiftStage2& parent_, const Group& group_,
|
{
|
||||||
double oil_rate_, double gas_rate_, double water_rate_, double alq_,
|
SurplusState(GasLiftStage2& parent_,
|
||||||
double min_eco_grad_,
|
const Group& group_,
|
||||||
double oil_target_, double gas_target_, double water_target_, double liquid_target_,
|
Scalar oil_rate_,
|
||||||
std::optional<double> max_glift_, std::optional<double> max_total_gas_) :
|
Scalar gas_rate_,
|
||||||
parent{parent_},
|
Scalar water_rate_,
|
||||||
group{group_},
|
Scalar alq_,
|
||||||
oil_rate{oil_rate_},
|
Scalar min_eco_grad_,
|
||||||
gas_rate{gas_rate_},
|
Scalar oil_target_,
|
||||||
water_rate{water_rate_},
|
Scalar gas_target_,
|
||||||
alq{alq_},
|
Scalar water_target_,
|
||||||
min_eco_grad{min_eco_grad_},
|
Scalar liquid_target_,
|
||||||
oil_target{oil_target_},
|
std::optional<Scalar> max_glift_,
|
||||||
gas_target{gas_target_},
|
std::optional<Scalar> max_total_gas_)
|
||||||
water_target(water_target_),
|
: parent{parent_}
|
||||||
liquid_target{liquid_target_},
|
, group{group_}
|
||||||
max_glift{max_glift_},
|
, oil_rate{oil_rate_}
|
||||||
max_total_gas{max_total_gas_},
|
, gas_rate{gas_rate_}
|
||||||
it{0}
|
, water_rate{water_rate_}
|
||||||
|
, alq{alq_}
|
||||||
|
, min_eco_grad{min_eco_grad_}
|
||||||
|
, oil_target{oil_target_}
|
||||||
|
, gas_target{gas_target_}
|
||||||
|
, water_target(water_target_)
|
||||||
|
, liquid_target{liquid_target_}
|
||||||
|
, max_glift{max_glift_}
|
||||||
|
, max_total_gas{max_total_gas_}
|
||||||
|
, it{0}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GasLiftStage2 &parent;
|
GasLiftStage2 &parent;
|
||||||
const Group &group;
|
const Group &group;
|
||||||
double oil_rate;
|
Scalar oil_rate;
|
||||||
double gas_rate;
|
Scalar gas_rate;
|
||||||
double water_rate;
|
Scalar water_rate;
|
||||||
double alq;
|
Scalar alq;
|
||||||
const double min_eco_grad;
|
const Scalar min_eco_grad;
|
||||||
const double oil_target;
|
const Scalar oil_target;
|
||||||
const double gas_target;
|
const Scalar gas_target;
|
||||||
const double water_target;
|
const Scalar water_target;
|
||||||
const double liquid_target;
|
const Scalar liquid_target;
|
||||||
std::optional<double> max_glift;
|
std::optional<Scalar> max_glift;
|
||||||
std::optional<double> max_total_gas;
|
std::optional<Scalar> max_total_gas;
|
||||||
int it;
|
int it;
|
||||||
|
|
||||||
void addOrRemoveALQincrement(
|
void addOrRemoveALQincrement(GradMap &grad_map,
|
||||||
GradMap &grad_map, const std::string& well_name, bool add);
|
const std::string& well_name,
|
||||||
|
bool add);
|
||||||
|
|
||||||
bool checkALQlimit();
|
bool checkALQlimit();
|
||||||
bool checkEcoGradient(const std::string& well_name, double eco_grad);
|
bool checkEcoGradient(const std::string& well_name, Scalar eco_grad);
|
||||||
bool checkGasTarget(double delta_gas);
|
bool checkGasTarget(Scalar delta_gas);
|
||||||
bool checkLiquidTarget(double delta_liquid);
|
bool checkLiquidTarget(Scalar delta_liquid);
|
||||||
bool checkOilTarget(double delta_oil);
|
bool checkOilTarget(Scalar delta_oil);
|
||||||
bool checkWaterTarget(double delta_water);
|
bool checkWaterTarget(Scalar delta_water);
|
||||||
std::array<double, 4> computeDelta(const std::string& name);
|
std::array<Scalar, 4> computeDelta(const std::string& name);
|
||||||
void updateRates(const std::array<double, 4>& delta);
|
void updateRates(const std::array<Scalar, 4>& delta);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,63 +23,75 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm {
|
||||||
|
|
||||||
|
template<class Scalar>
|
||||||
|
class GasLiftWellState
|
||||||
{
|
{
|
||||||
class GasLiftWellState
|
public:
|
||||||
|
GasLiftWellState(Scalar oil_rate,
|
||||||
|
bool oil_is_limited,
|
||||||
|
Scalar gas_rate,
|
||||||
|
bool gas_is_limited,
|
||||||
|
Scalar alq,
|
||||||
|
bool alq_is_limited,
|
||||||
|
Scalar water_rate,
|
||||||
|
bool water_is_limited,
|
||||||
|
std::optional<bool> increase)
|
||||||
|
: oil_rate_{oil_rate}
|
||||||
|
, oil_is_limited_{oil_is_limited}
|
||||||
|
, gas_rate_{gas_rate}
|
||||||
|
, gas_is_limited_{gas_is_limited}
|
||||||
|
, alq_{alq}
|
||||||
|
, alq_is_limited_{alq_is_limited}
|
||||||
|
, water_rate_{water_rate}
|
||||||
|
, water_is_limited_{water_is_limited}
|
||||||
|
, increase_{increase}
|
||||||
|
{}
|
||||||
|
|
||||||
|
Scalar alq() const { return alq_; }
|
||||||
|
bool alqChanged() { return increase_.has_value(); }
|
||||||
|
bool alqIsLimited() const { return alq_is_limited_; }
|
||||||
|
bool gasIsLimited() const { return gas_is_limited_; }
|
||||||
|
Scalar gasRate() const { return gas_rate_; }
|
||||||
|
std::pair<Scalar, Scalar> getRates() { return {oil_rate_, gas_rate_}; }
|
||||||
|
std::optional<bool> increase() const { return increase_; }
|
||||||
|
bool oilIsLimited() const { return oil_is_limited_; }
|
||||||
|
Scalar oilRate() const { return oil_rate_; }
|
||||||
|
Scalar waterRate() const { return water_rate_; }
|
||||||
|
bool waterIsLimited() const { return water_is_limited_; }
|
||||||
|
void update(Scalar oil_rate,
|
||||||
|
bool oil_is_limited,
|
||||||
|
Scalar gas_rate,
|
||||||
|
bool gas_is_limited,
|
||||||
|
Scalar alq,
|
||||||
|
bool alq_is_limited,
|
||||||
|
Scalar water_rate,
|
||||||
|
Scalar water_is_limited,
|
||||||
|
bool increase)
|
||||||
{
|
{
|
||||||
public:
|
oil_rate_ = oil_rate;
|
||||||
//GasLiftWellState() { }
|
oil_is_limited_ = oil_is_limited;
|
||||||
GasLiftWellState(double oil_rate, bool oil_is_limited,
|
gas_rate_ = gas_rate;
|
||||||
double gas_rate, bool gas_is_limited,
|
gas_is_limited_ = gas_is_limited;
|
||||||
double alq, bool alq_is_limited, double water_rate, bool water_is_limited, std::optional<bool> increase) :
|
alq_ = alq;
|
||||||
oil_rate_{oil_rate},
|
alq_is_limited_ = alq_is_limited;
|
||||||
oil_is_limited_{oil_is_limited},
|
water_rate_ = water_rate;
|
||||||
gas_rate_{gas_rate},
|
water_is_limited_ = water_is_limited;
|
||||||
gas_is_limited_{gas_is_limited},
|
increase_ = increase;
|
||||||
alq_{alq},
|
}
|
||||||
alq_is_limited_{alq_is_limited},
|
|
||||||
water_rate_{water_rate},
|
private:
|
||||||
water_is_limited_{water_is_limited},
|
Scalar oil_rate_;
|
||||||
increase_{increase}
|
bool oil_is_limited_;
|
||||||
{}
|
Scalar gas_rate_;
|
||||||
double alq() const { return alq_; }
|
bool gas_is_limited_;
|
||||||
bool alqChanged() { return increase_.has_value(); }
|
Scalar alq_;
|
||||||
bool alqIsLimited() const { return alq_is_limited_; }
|
bool alq_is_limited_;
|
||||||
bool gasIsLimited() const { return gas_is_limited_; }
|
Scalar water_rate_;
|
||||||
double gasRate() const { return gas_rate_; }
|
bool water_is_limited_;
|
||||||
std::pair<double, double> getRates() { return {oil_rate_, gas_rate_}; }
|
std::optional<bool> increase_;
|
||||||
std::optional<bool> increase() const { return increase_; }
|
};
|
||||||
bool oilIsLimited() const { return oil_is_limited_; }
|
|
||||||
double oilRate() const { return oil_rate_; }
|
|
||||||
double waterRate() const { return water_rate_; }
|
|
||||||
bool waterIsLimited() const { return water_is_limited_; }
|
|
||||||
void update(double oil_rate, bool oil_is_limited,
|
|
||||||
double gas_rate, bool gas_is_limited,
|
|
||||||
double alq, bool alq_is_limited, double water_rate,
|
|
||||||
double water_is_limited,
|
|
||||||
bool increase)
|
|
||||||
{
|
|
||||||
oil_rate_ = oil_rate;
|
|
||||||
oil_is_limited_ = oil_is_limited;
|
|
||||||
gas_rate_ = gas_rate;
|
|
||||||
gas_is_limited_ = gas_is_limited;
|
|
||||||
alq_ = alq;
|
|
||||||
alq_is_limited_ = alq_is_limited;
|
|
||||||
water_rate_ = water_rate;
|
|
||||||
water_is_limited_ = water_is_limited;
|
|
||||||
increase_ = increase;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
double oil_rate_;
|
|
||||||
bool oil_is_limited_;
|
|
||||||
double gas_rate_;
|
|
||||||
bool gas_is_limited_;
|
|
||||||
double alq_;
|
|
||||||
bool alq_is_limited_;
|
|
||||||
double water_rate_;
|
|
||||||
bool water_is_limited_;
|
|
||||||
std::optional<bool> increase_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ public:
|
|||||||
|
|
||||||
using Grid = GetPropType<TypeTag, Properties::Grid>;
|
using Grid = GetPropType<TypeTag, Properties::Grid>;
|
||||||
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
|
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
|
||||||
|
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
|
||||||
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
|
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
|
||||||
using Indices = GetPropType<TypeTag, Properties::Indices>;
|
using Indices = GetPropType<TypeTag, Properties::Indices>;
|
||||||
using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
|
using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
|
||||||
@ -91,9 +92,7 @@ public:
|
|||||||
using GLiftProdWells = typename BlackoilWellModel<TypeTag>::GLiftProdWells;
|
using GLiftProdWells = typename BlackoilWellModel<TypeTag>::GLiftProdWells;
|
||||||
using GLiftWellStateMap =
|
using GLiftWellStateMap =
|
||||||
typename BlackoilWellModel<TypeTag>::GLiftWellStateMap;
|
typename BlackoilWellModel<TypeTag>::GLiftWellStateMap;
|
||||||
using GLiftSyncGroups = typename GasLiftSingleWellGeneric::GLiftSyncGroups;
|
using GLiftSyncGroups = typename GasLiftSingleWellGeneric<Scalar>::GLiftSyncGroups;
|
||||||
|
|
||||||
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
|
|
||||||
|
|
||||||
using VectorBlockType = Dune::FieldVector<Scalar, Indices::numEq>;
|
using VectorBlockType = Dune::FieldVector<Scalar, Indices::numEq>;
|
||||||
using MatrixBlockType = Dune::FieldMatrix<Scalar, Indices::numEq, Indices::numEq>;
|
using MatrixBlockType = Dune::FieldMatrix<Scalar, Indices::numEq, Indices::numEq>;
|
||||||
|
@ -126,8 +126,8 @@ BOOST_AUTO_TEST_CASE(G1)
|
|||||||
using WellState = Opm::WellState<double>;
|
using WellState = Opm::WellState<double>;
|
||||||
using StdWell = Opm::StandardWell<TypeTag>;
|
using StdWell = Opm::StandardWell<TypeTag>;
|
||||||
using GasLiftSingleWell = Opm::GasLiftSingleWell<TypeTag>;
|
using GasLiftSingleWell = Opm::GasLiftSingleWell<TypeTag>;
|
||||||
using GasLiftGroupInfo = Opm::GasLiftGroupInfo;
|
using GasLiftGroupInfo = Opm::GasLiftGroupInfo<double>;
|
||||||
using GasLiftSingleWellGeneric = Opm::GasLiftSingleWellGeneric;
|
using GasLiftSingleWellGeneric = Opm::GasLiftSingleWellGeneric<double>;
|
||||||
using GLiftEclWells = typename GasLiftGroupInfo::GLiftEclWells;
|
using GLiftEclWells = typename GasLiftGroupInfo::GLiftEclWells;
|
||||||
const std::string filename = "GLIFT1.DATA";
|
const std::string filename = "GLIFT1.DATA";
|
||||||
using GLiftSyncGroups = typename GasLiftSingleWellGeneric::GLiftSyncGroups;
|
using GLiftSyncGroups = typename GasLiftSingleWellGeneric::GLiftSyncGroups;
|
||||||
|
Loading…
Reference in New Issue
Block a user