Merge pull request #3786 from hakonhagland/debug_hook

Small improvement of debugging tools in gaslift code
This commit is contained in:
Tor Harald Sandve 2022-01-25 08:44:34 +01:00 committed by GitHub
commit 90539a615d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 270 additions and 233 deletions

View File

@ -64,6 +64,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/utils/ParallelRestart.cpp opm/simulators/utils/ParallelRestart.cpp
opm/simulators/wells/ALQState.cpp opm/simulators/wells/ALQState.cpp
opm/simulators/wells/BlackoilWellModelGeneric.cpp opm/simulators/wells/BlackoilWellModelGeneric.cpp
opm/simulators/wells/GasLiftCommon.cpp
opm/simulators/wells/GasLiftGroupInfo.cpp opm/simulators/wells/GasLiftGroupInfo.cpp
opm/simulators/wells/GasLiftSingleWellGeneric.cpp opm/simulators/wells/GasLiftSingleWellGeneric.cpp
opm/simulators/wells/GasLiftStage2.cpp opm/simulators/wells/GasLiftStage2.cpp

View File

@ -48,6 +48,19 @@ void ALQState::set(const std::string& wname, double value) {
this->current_alq_[wname] = value; this->current_alq_[wname] = value;
} }
int ALQState::get_debug_counter() {
return this->debug_counter_;
}
int ALQState::update_debug_counter() {
this->debug_counter_++;
return this->debug_counter_;
}
void ALQState::set_debug_counter(int value) {
this->debug_counter_ = value;
}
namespace { namespace {
int get_counter(const std::map<std::string, int>& count_map, const std::string& wname) { int get_counter(const std::map<std::string, int>& count_map, const std::string& wname) {

View File

@ -42,12 +42,16 @@ public:
void reset_count(); void reset_count();
int get_increment_count(const std::string& wname) const; int get_increment_count(const std::string& wname) const;
int get_decrement_count(const std::string& wname) const; int get_decrement_count(const std::string& wname) const;
void set_debug_counter(int value);
int get_debug_counter();
int update_debug_counter();
private: private:
std::map<std::string, double> current_alq_; std::map<std::string, double> current_alq_;
std::map<std::string, double> default_alq_; std::map<std::string, double> default_alq_;
std::map<std::string, int> alq_increase_count_; std::map<std::string, int> alq_increase_count_;
std::map<std::string, int> alq_decrease_count_; std::map<std::string, int> alq_decrease_count_;
int debug_counter_ = 0;
}; };

View File

@ -2233,7 +2233,9 @@ gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
this->wellState(), this->wellState(),
prod_wells, prod_wells,
glift_wells, glift_wells,
glift_well_state_map}; glift_well_state_map,
this->glift_debug
};
glift.runOptimize(); glift.runOptimize();
} }

View File

@ -896,7 +896,8 @@ namespace Opm {
phase_usage_, phase_usage_,
deferred_logger, deferred_logger,
this->wellState(), this->wellState(),
ebosSimulator_.vanguard().grid().comm() ebosSimulator_.vanguard().grid().comm(),
this->glift_debug
}; };
group_info.initialize(); group_info.initialize();
gasLiftOptimizationStage1( gasLiftOptimizationStage1(
@ -951,9 +952,11 @@ namespace Opm {
// NOTE: Only the wells in "group_info" needs to be optimized // NOTE: Only the wells in "group_info" needs to be optimized
if (group_info.hasWell(well->name())) { if (group_info.hasWell(well->name())) {
well->gasLiftOptimizationStage1( well->gasLiftOptimizationStage1(
this->wellState(), this->groupState(), ebosSimulator_, deferred_logger, this->wellState(), this->groupState(), ebosSimulator_,
deferred_logger,
prod_wells, glift_wells, state_map, prod_wells, glift_wells, state_map,
group_info, groups_to_sync); group_info, groups_to_sync, this->glift_debug
);
} }
} }
num_rates_to_sync = groups_to_sync.size(); num_rates_to_sync = groups_to_sync.size();
@ -1006,6 +1009,16 @@ namespace Opm {
group_oil_rates[j], group_gas_rates[j], group_water_rates[j], group_alq_rates[j]); group_oil_rates[j], group_gas_rates[j], group_water_rates[j], group_alq_rates[j]);
} }
} }
if (this->glift_debug) {
int counter = 0;
if (comm.rank() == i) {
counter = this->wellState().gliftGetDebugCounter();
}
counter = comm.sum(counter);
if (comm.rank() != i) {
this->wellState().gliftSetDebugCounter(counter);
}
}
} }
} }
} }

View File

@ -0,0 +1,58 @@
/*
Copyright 2022 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <opm/simulators/wells/GasLiftCommon.hpp>
namespace Opm {
GasLiftCommon::
GasLiftCommon(
WellState &well_state,
DeferredLogger &deferred_logger,
bool glift_debug
) :
well_state_{well_state},
deferred_logger_{deferred_logger},
debug{glift_debug}
{
}
/****************************************
* Protected methods in alphabetical order
****************************************/
int
GasLiftCommon::
debugUpdateGlobalCounter_() const
{
auto count = this->well_state_.gliftUpdateDebugCounter();
const std::string msg = fmt::format("global counter = {}", count);
displayDebugMessage_(msg);
return count;
}
/****************************************
* Private methods in alphabetical order
****************************************/
} // namespace Opm

View File

@ -0,0 +1,51 @@
/*
Copyright 2022 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_GASLIFT_COMMON_HEADER_INCLUDED
#define OPM_GASLIFT_COMMON_HEADER_INCLUDED
#include <opm/simulators/utils/DeferredLogger.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <string>
#include <fmt/format.h>
namespace Opm
{
class GasLiftCommon
{
public:
virtual ~GasLiftCommon() = default;
protected:
GasLiftCommon(
WellState &well_state,
DeferredLogger &deferred_logger,
bool debug
);
int debugUpdateGlobalCounter_() const;
virtual void displayDebugMessage_(const std::string& msg) const = 0;
bool debug;
DeferredLogger &deferred_logger_;
WellState &well_state_;
};
} // namespace Opm
#endif // OPM_GASLIFT_COMMON_INCLUDED

View File

@ -32,19 +32,18 @@ GasLiftGroupInfo(
const PhaseUsage &phase_usage, const PhaseUsage &phase_usage,
DeferredLogger &deferred_logger, DeferredLogger &deferred_logger,
WellState &well_state, WellState &well_state,
const Communication &comm const Communication &comm,
bool glift_debug
) : ) :
ecl_wells_{ecl_wells}, GasLiftCommon(well_state, deferred_logger, glift_debug)
schedule_{schedule}, , ecl_wells_{ecl_wells}
summary_state_{summary_state}, , schedule_{schedule}
report_step_idx_{report_step_idx}, , summary_state_{summary_state}
iteration_idx_{iteration_idx}, , report_step_idx_{report_step_idx}
phase_usage_{phase_usage}, , iteration_idx_{iteration_idx}
deferred_logger_{deferred_logger}, , phase_usage_{phase_usage}
well_state_{well_state}, , comm_{comm}
comm_{comm}, , glo_{schedule_.glo(report_step_idx_)}
glo_{schedule_.glo(report_step_idx_)},
debug{false}
{ {
} }
@ -264,7 +263,7 @@ updateRate(int idx, double oil_rate, double gas_rate, double water_rate, double
} }
/**************************************** /****************************************
* Private methods in alphabetical order * Protected methods in alphabetical order
****************************************/ ****************************************/
@ -353,7 +352,7 @@ checkNewtonIterationIdxOk_(const std::string &well_name)
void void
GasLiftGroupInfo:: GasLiftGroupInfo::
displayDebugMessage_(const std::string &msg) displayDebugMessage_(const std::string &msg) const
{ {
if (this->debug) { if (this->debug) {
const std::string message = fmt::format( const std::string message = fmt::format(

View File

@ -31,6 +31,7 @@
#include <opm/input/eclipse/Schedule/Group/Group.hpp> #include <opm/input/eclipse/Schedule/Group/Group.hpp>
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp> #include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp> #include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/simulators/wells/GasLiftCommon.hpp>
#include <opm/simulators/wells/WellState.hpp> #include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/utils/DeferredLogger.hpp> #include <opm/simulators/utils/DeferredLogger.hpp>
@ -42,8 +43,9 @@
namespace Opm namespace Opm
{ {
class GasLiftGroupInfo class GasLiftGroupInfo : public GasLiftCommon
{ {
protected:
class GroupRates; class GroupRates;
// NOTE: In the Well2GroupMap below, in the std::vector value we store // NOTE: In the Well2GroupMap below, in the std::vector value we store
// pairs of group names and efficiency factors. The efficiency factors // pairs of group names and efficiency factors. The efficiency factors
@ -79,7 +81,9 @@ public:
const PhaseUsage& phase_usage, const PhaseUsage& phase_usage,
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
WellState& well_state, WellState& well_state,
const Parallel::Communication& comm); const Parallel::Communication& comm,
bool glift_debug
);
std::vector<std::pair<std::string,double>>& getWellGroups( std::vector<std::pair<std::string,double>>& getWellGroups(
const std::string& well_name); const std::string& well_name);
@ -105,10 +109,10 @@ public:
double delta_oil, double delta_gas, double delta_water, double delta_alq); double delta_oil, double delta_gas, double delta_water, double delta_alq);
void updateRate(int idx, double oil_rate, double gas_rate, double water_rate, double alq); void updateRate(int idx, double oil_rate, double gas_rate, double water_rate, double alq);
const Well2GroupMap& wellGroupMap() { return well_group_map_; } const Well2GroupMap& wellGroupMap() { return well_group_map_; }
private: protected:
void displayDebugMessage_(const std::string& msg) const override;
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 displayDebugMessage_(const std::string& msg);
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> getProducerWellRates_(const int index); std::tuple<double, double, double> getProducerWellRates_(const int index);
std::tuple<double, double, double, double> std::tuple<double, double, double, double>
@ -183,13 +187,10 @@ private:
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_;
WellState &well_state_;
const Parallel::Communication &comm_; const Parallel::Communication &comm_;
const GasLiftOpt& glo_; const GasLiftOpt& glo_;
GroupRateMap group_rate_map_; GroupRateMap group_rate_map_;
Well2GroupMap well_group_map_; Well2GroupMap well_group_map_;
bool debug;
GroupIdxMap group_idx_; GroupIdxMap group_idx_;
int next_group_idx_ = 0; int next_group_idx_ = 0;
// Optimize only wells under THP control // Optimize only wells under THP control

View File

@ -57,7 +57,8 @@ namespace Opm
WellState &well_state, WellState &well_state,
const GroupState& group_state, const GroupState& group_state,
GasLiftGroupInfo &group_info, GasLiftGroupInfo &group_info,
GLiftSyncGroups &sync_groups GLiftSyncGroups &sync_groups,
bool glift_debug
); );
const WellInterfaceGeneric &getStdWell() const override { return std_well_; } const WellInterfaceGeneric &getStdWell() const override { return std_well_; }

View File

@ -46,10 +46,10 @@ GasLiftSingleWellGeneric::GasLiftSingleWellGeneric(
GasLiftGroupInfo &group_info, GasLiftGroupInfo &group_info,
const Schedule& schedule, const Schedule& schedule,
const int report_step_idx, const int report_step_idx,
GLiftSyncGroups &sync_groups GLiftSyncGroups &sync_groups,
bool glift_debug
) : ) :
deferred_logger_{deferred_logger} GasLiftCommon(well_state, deferred_logger, glift_debug)
, well_state_{well_state}
, group_state_{group_state} , group_state_{group_state}
, ecl_well_{ecl_well} , ecl_well_{ecl_well}
, summary_state_{summary_state} , summary_state_{summary_state}
@ -57,7 +57,6 @@ GasLiftSingleWellGeneric::GasLiftSingleWellGeneric(
, sync_groups_{sync_groups} , sync_groups_{sync_groups}
, controls_{ecl_well_.productionControls(summary_state_)} , controls_{ecl_well_.productionControls(summary_state_)}
, num_phases_{well_state_.numPhases()} , num_phases_{well_state_.numPhases()}
, debug_{false} // extra debugging output
, debug_limit_increase_decrease_{false} , debug_limit_increase_decrease_{false}
{ {
this->well_name_ = ecl_well_.name(); this->well_name_ = ecl_well_.name();
@ -80,7 +79,6 @@ GasLiftSingleWellGeneric::GasLiftSingleWellGeneric(
// injection (which seems strange) // injection (which seems strange)
this->eco_grad_ = glo.min_eco_gradient(); this->eco_grad_ = glo.min_eco_gradient();
gl_well_ = &glo.well(this->well_name_); gl_well_ = &glo.well(this->well_name_);
} }
/**************************************** /****************************************
@ -134,7 +132,7 @@ runOptimize(const int iteration_idx)
// (either increase or decrease) // (either increase or decrease)
if (state->increase()) { // ALQ changed.. if (state->increase()) { // ALQ changed..
double alq = state->alq(); double alq = state->alq();
if (this->debug_) if (this->debug)
logSuccess_(alq, iteration_idx); logSuccess_(alq, iteration_idx);
this->well_state_.setALQ(this->well_name_, alq); this->well_state_.setALQ(this->well_name_, alq);
} }
@ -232,7 +230,7 @@ checkGroupTargetsViolated(double delta_oil, double delta_gas, double delta_water
double oil_rate = double oil_rate =
this->group_info_.oilRate(group_name) + efficiency * delta_oil; this->group_info_.oilRate(group_name) + efficiency * delta_oil;
if (oil_rate > *oil_target_opt) { if (oil_rate > *oil_target_opt) {
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Group {} : oil rate {} exceeds oil target {}. Stopping iteration", "Group {} : oil rate {} exceeds oil target {}. Stopping iteration",
group_name, oil_rate, *oil_target_opt); group_name, oil_rate, *oil_target_opt);
@ -246,7 +244,7 @@ checkGroupTargetsViolated(double delta_oil, double delta_gas, double delta_water
double gas_rate = double gas_rate =
this->group_info_.gasRate(group_name) + efficiency * delta_gas; this->group_info_.gasRate(group_name) + efficiency * delta_gas;
if (gas_rate > *gas_target_opt) { if (gas_rate > *gas_target_opt) {
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Group {} : gas rate {} exceeds gas target {}. Stopping iteration", "Group {} : gas rate {} exceeds gas target {}. Stopping iteration",
group_name, gas_rate, *gas_target_opt); group_name, gas_rate, *gas_target_opt);
@ -263,7 +261,7 @@ checkGroupTargetsViolated(double delta_oil, double delta_gas, double delta_water
this->group_info_.waterRate(group_name) + efficiency * delta_water; this->group_info_.waterRate(group_name) + efficiency * delta_water;
double liquid_rate = oil_rate + water_rate; double liquid_rate = oil_rate + water_rate;
if (liquid_rate > *liquid_target_opt) { if (liquid_rate > *liquid_target_opt) {
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Group {} : liquid rate {} exceeds liquid target {}. Stopping iteration", "Group {} : liquid rate {} exceeds liquid target {}. Stopping iteration",
group_name, liquid_rate, *liquid_target_opt); group_name, liquid_rate, *liquid_target_opt);
@ -277,7 +275,7 @@ checkGroupTargetsViolated(double delta_oil, double delta_gas, double delta_water
double water_rate = double water_rate =
this->group_info_.waterRate(group_name) + efficiency * delta_water; this->group_info_.waterRate(group_name) + efficiency * delta_water;
if (water_rate > *water_target_opt) { if (water_rate > *water_target_opt) {
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Group {} : water rate {} exceeds water target {}. Stopping iteration", "Group {} : water rate {} exceeds water target {}. Stopping iteration",
group_name, water_rate, *water_target_opt); group_name, water_rate, *water_target_opt);
@ -483,7 +481,7 @@ GasLiftSingleWellGeneric::
displayDebugMessage_(const std::string& msg) const displayDebugMessage_(const std::string& msg) const
{ {
if (this->debug_) { if (this->debug) {
const std::string message = fmt::format( const std::string message = fmt::format(
" GLIFT (DEBUG) : Well {} : {}", this->well_name_, msg); " GLIFT (DEBUG) : Well {} : {}", this->well_name_, msg);
this->deferred_logger_.info(message); this->deferred_logger_.info(message);
@ -749,7 +747,7 @@ getRateWithGroupLimit_(
} }
} }
} }
if (this->debug_ && group_name) { if (this->debug && group_name) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"limiting {} rate from {} to {} to meet group target {} " "limiting {} rate from {} to {} to meet group target {} "
"for group {}. Computed group rate was: {}", "for group {}. Computed group rate was: {}",
@ -887,7 +885,7 @@ maybeAdjustALQbeforeOptimizeLoop_(
std::vector<double> &potentials) std::vector<double> &potentials)
{ {
double orig_alq = alq; double orig_alq = alq;
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format("initial ALQ: {}", alq); const std::string msg = fmt::format("initial ALQ: {}", alq);
displayDebugMessage_(msg); displayDebugMessage_(msg);
} }
@ -928,7 +926,7 @@ maybeAdjustALQbeforeOptimizeLoop_(
oil_is_limited, gas_is_limited, potentials); oil_is_limited, gas_is_limited, potentials);
} }
} }
if (this->debug_ && (orig_alq != alq)) { if (this->debug && (orig_alq != alq)) {
const std::string msg = fmt::format("adjusted ALQ to: {}", alq); const std::string msg = fmt::format("adjusted ALQ to: {}", alq);
displayDebugMessage_(msg); displayDebugMessage_(msg);
} }
@ -1035,7 +1033,7 @@ reduceALQtoWellTarget_(double alq,
std::tie(gas_rate, gas_is_limited) = getGasRateWithLimit_(potentials); std::tie(gas_rate, gas_is_limited) = getGasRateWithLimit_(potentials);
std::tie(water_rate, water_is_limited) = getWaterRateWithLimit_(potentials); std::tie(water_rate, water_is_limited) = getWaterRateWithLimit_(potentials);
if (this->debug_) { if (this->debug) {
assert( alq <= orig_alq ); assert( alq <= orig_alq );
std::string type; std::string type;
double target = 0.0; double target = 0.0;
@ -1098,9 +1096,9 @@ runOptimizeLoop_(bool increase)
double oil_rate, gas_rate, water_rate; double oil_rate, gas_rate, water_rate;
std::tie(oil_rate, gas_rate, water_rate, oil_is_limited, gas_is_limited, water_is_limited) = std::tie(oil_rate, gas_rate, water_rate, oil_is_limited, gas_is_limited, water_is_limited) =
getInitialRatesWithLimit_(potentials); getInitialRatesWithLimit_(potentials);
//if (this->debug_) debugShowBhpAlqTable_(); //if (this->debug) debugShowBhpAlqTable_();
if (this->debug_) debugShowAlqIncreaseDecreaseCounts_(); if (this->debug) debugShowAlqIncreaseDecreaseCounts_();
if (this->debug_) debugShowTargets_(); if (this->debug) debugShowTargets_();
bool success = false; // did we succeed to increase alq? bool success = false; // did we succeed to increase alq?
auto cur_alq = this->orig_alq_; auto cur_alq = this->orig_alq_;
double new_oil_rate, new_gas_rate, new_water_rate, new_alq; double new_oil_rate, new_gas_rate, new_water_rate, new_alq;
@ -1143,7 +1141,7 @@ runOptimizeLoop_(bool increase)
} }
auto temp_alq = cur_alq; auto temp_alq = cur_alq;
if (this->debug_) debugShowStartIteration_(temp_alq, increase, oil_rate); if (this->debug) debugShowStartIteration_(temp_alq, increase, oil_rate);
while (!state.stop_iteration && (++state.it <= this->max_iterations_)) { while (!state.stop_iteration && (++state.it <= this->max_iterations_)) {
if (!increase && state.checkNegativeOilRate(oil_rate)) break; if (!increase && state.checkNegativeOilRate(oil_rate)) break;
if (state.checkWellRatesViolated(potentials)) break; if (state.checkWellRatesViolated(potentials)) break;
@ -1156,7 +1154,7 @@ runOptimizeLoop_(bool increase)
delta_alq = *alq_opt - temp_alq; delta_alq = *alq_opt - temp_alq;
if (state.checkGroupALQrateExceeded(delta_alq)) break; if (state.checkGroupALQrateExceeded(delta_alq)) break;
temp_alq = *alq_opt; temp_alq = *alq_opt;
if (this->debug_) state.debugShowIterationInfo(temp_alq); if (this->debug) state.debugShowIterationInfo(temp_alq);
if (!state.computeBhpAtThpLimit(temp_alq)) break; if (!state.computeBhpAtThpLimit(temp_alq)) break;
// NOTE: if BHP is below limit, we set state.stop_iteration = true // NOTE: if BHP is below limit, we set state.stop_iteration = true
auto bhp = state.getBhpWithLimit(); auto bhp = state.getBhpWithLimit();
@ -1194,7 +1192,7 @@ runOptimizeLoop_(bool increase)
*/ */
auto gradient = state.calcEcoGradient( auto gradient = state.calcEcoGradient(
oil_rate, new_oil_rate, gas_rate, new_gas_rate); oil_rate, new_oil_rate, gas_rate, new_gas_rate);
if (this->debug_) if (this->debug)
debugCheckNegativeGradient_( debugCheckNegativeGradient_(
gradient, cur_alq, temp_alq, oil_rate, new_oil_rate, gradient, cur_alq, temp_alq, oil_rate, new_oil_rate,
gas_rate, new_gas_rate, increase); gas_rate, new_gas_rate, increase);
@ -1492,7 +1490,7 @@ checkAlqOutsideLimits(double alq, [[maybe_unused]] double oil_rate)
} }
} }
} }
if (this->parent.debug_) { if (this->parent.debug) {
const std::string msg = ss.str(); const std::string msg = ss.str();
if (!msg.empty()) if (!msg.empty())
this->parent.displayDebugMessage_(msg); this->parent.displayDebugMessage_(msg);
@ -1512,7 +1510,7 @@ checkGroupALQrateExceeded(double delta_alq)
double alq = double alq =
this->parent.group_info_.alqRate(group_name) + efficiency * delta_alq; this->parent.group_info_.alqRate(group_name) + efficiency * delta_alq;
if (alq > *max_alq_opt) { if (alq > *max_alq_opt) {
if (this->parent.debug_) { if (this->parent.debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Group {} : alq {} exceeds max_alq {}. Stopping iteration", "Group {} : alq {} exceeds max_alq {}. Stopping iteration",
group_name, alq, *max_alq_opt); group_name, alq, *max_alq_opt);
@ -1568,30 +1566,30 @@ checkEcoGradient(double gradient)
std::ostringstream ss; std::ostringstream ss;
bool result = false; bool result = false;
if (this->parent.debug_) { if (this->parent.debug) {
ss << "checking gradient: " << gradient; ss << "checking gradient: " << gradient;
} }
if (this->increase) { if (this->increase) {
if (this->parent.debug_) ss << " <= " << this->parent.eco_grad_ << " --> "; if (this->parent.debug) ss << " <= " << this->parent.eco_grad_ << " --> ";
if (gradient <= this->parent.eco_grad_) { if (gradient <= this->parent.eco_grad_) {
if (this->parent.debug_) ss << "yes, stopping"; if (this->parent.debug) ss << "yes, stopping";
result = true; result = true;
} }
else { else {
if (this->parent.debug_) ss << "no, continue"; if (this->parent.debug) ss << "no, continue";
} }
} }
else { // decreasing lift gas else { // decreasing lift gas
if (this->parent.debug_) ss << " >= " << this->parent.eco_grad_ << " --> "; if (this->parent.debug) ss << " >= " << this->parent.eco_grad_ << " --> ";
if (gradient >= this->parent.eco_grad_) { if (gradient >= this->parent.eco_grad_) {
if (this->parent.debug_) ss << "yes, stopping"; if (this->parent.debug) ss << "yes, stopping";
result = true; result = true;
} }
else { else {
if (this->parent.debug_) ss << "no, continue"; if (this->parent.debug) ss << "no, continue";
} }
} }
if (this->parent.debug_) this->parent.displayDebugMessage_(ss.str()); if (this->parent.debug) this->parent.displayDebugMessage_(ss.str());
return result; return result;
} }
@ -1600,7 +1598,7 @@ GasLiftSingleWellGeneric::OptimizeState::
checkRate(double rate, double limit, const std::string& rate_str) const checkRate(double rate, double limit, const std::string& rate_str) const
{ {
if (limit < rate) { if (limit < rate) {
if (this->parent.debug_) { if (this->parent.debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"iteration {} : {} rate {} exceeds target {}. Stopping iteration", "iteration {} : {} rate {} exceeds target {}. Stopping iteration",
this->it, rate_str, rate, limit); this->it, rate_str, rate, limit);

View File

@ -28,6 +28,7 @@
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp> #include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp> #include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/simulators/wells/GasLiftGroupInfo.hpp> #include <opm/simulators/wells/GasLiftGroupInfo.hpp>
#include <opm/simulators/wells/GasLiftCommon.hpp>
#include <functional> #include <functional>
#include <optional> #include <optional>
@ -47,7 +48,7 @@ class WellInterfaceGeneric;
class WellState; class WellState;
class GroupState; class GroupState;
class GasLiftSingleWellGeneric class GasLiftSingleWellGeneric : public GasLiftCommon
{ {
protected: protected:
static const int Water = BlackoilPhases::Aqua; static const int Water = BlackoilPhases::Aqua;
@ -102,7 +103,8 @@ protected:
GasLiftGroupInfo &group_info, GasLiftGroupInfo &group_info,
const Schedule& schedule, const Schedule& schedule,
const int report_step_idx, const int report_step_idx,
GLiftSyncGroups &sync_groups GLiftSyncGroups &sync_groups,
bool glift_debug
); );
struct OptimizeState struct OptimizeState
@ -174,7 +176,7 @@ protected:
void debugShowTargets_(); void debugShowTargets_();
void displayDebugMessage_(const std::string& msg) const; 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> getBhpWithLimit_(double bhp) const;
@ -249,8 +251,6 @@ protected:
void warnMaxIterationsExceeded_(); void warnMaxIterationsExceeded_();
DeferredLogger& deferred_logger_;
WellState& well_state_;
const GroupState& group_state_; const GroupState& group_state_;
const Well& ecl_well_; const Well& ecl_well_;
const SummaryState& summary_state_; const SummaryState& summary_state_;
@ -279,7 +279,6 @@ protected:
const GasLiftOpt::Well* gl_well_; const GasLiftOpt::Well* gl_well_;
bool optimize_; bool optimize_;
bool debug_; // extra debug output
bool debug_limit_increase_decrease_; bool debug_limit_increase_decrease_;
bool debug_abort_if_decrease_and_oil_is_limited_ = false; bool debug_abort_if_decrease_and_oil_is_limited_ = false;
bool debug_abort_if_increase_and_gas_is_limited_ = false; bool debug_abort_if_increase_and_gas_is_limited_ = false;

View File

@ -28,7 +28,8 @@ GasLiftSingleWell(const StdWell &std_well,
WellState &well_state, WellState &well_state,
const GroupState &group_state, const GroupState &group_state,
GasLiftGroupInfo &group_info, GasLiftGroupInfo &group_info,
GLiftSyncGroups &sync_groups GLiftSyncGroups &sync_groups,
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
@ -41,7 +42,8 @@ GasLiftSingleWell(const StdWell &std_well,
group_info, group_info,
ebos_simulator.vanguard().schedule(), ebos_simulator.vanguard().schedule(),
ebos_simulator.episodeIndex(), ebos_simulator.episodeIndex(),
sync_groups sync_groups,
glift_debug
) )
, ebos_simulator_{ebos_simulator} , ebos_simulator_{ebos_simulator}
, std_well_{std_well} , std_well_{std_well}

View File

@ -46,19 +46,18 @@ GasLiftStage2::GasLiftStage2(
WellState &well_state, WellState &well_state,
GLiftProdWells &prod_wells, GLiftProdWells &prod_wells,
GLiftOptWells &glift_wells, GLiftOptWells &glift_wells,
GLiftWellStateMap &state_map GLiftWellStateMap &state_map,
bool glift_debug
) : ) :
deferred_logger_{deferred_logger}, GasLiftCommon(well_state, deferred_logger, glift_debug)
well_state_{well_state}, , prod_wells_{prod_wells}
prod_wells_{prod_wells}, , stage1_wells_{glift_wells}
stage1_wells_{glift_wells}, , well_state_map_{state_map}
well_state_map_{state_map}, , report_step_idx_{report_step_idx}
report_step_idx_{report_step_idx}, , summary_state_{summary_state}
summary_state_{summary_state}, , schedule_{schedule}
schedule_{schedule}, , glo_{schedule_.glo(report_step_idx_)}
glo_{schedule_.glo(report_step_idx_)}, , comm_{comm}
comm_{comm},
debug_{false}
{ {
// this->time_step_idx_ // this->time_step_idx_
// = this->ebos_simulator_.model().newtonMethod().currentTimeStep(); // = this->ebos_simulator_.model().newtonMethod().currentTimeStep();
@ -89,7 +88,7 @@ runOptimize()
/******************************************** /********************************************
* Private methods in alphabetical order * Protected methods in alphabetical order
********************************************/ ********************************************/
// Update GasLiftWellState and WellState for "well_name" to the // Update GasLiftWellState and WellState for "well_name" to the
@ -106,7 +105,7 @@ addOrRemoveALQincrement_(GradMap &grad_map, const std::string& well_name, bool a
GasLiftWellState &state = *(it->second.get()); GasLiftWellState &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();
const std::string msg = fmt::format("well {} : {} ALQ increment, " const std::string msg = fmt::format("well {} : {} ALQ increment, "
@ -237,9 +236,9 @@ displayWarning_(const std::string &msg)
void void
GasLiftStage2:: GasLiftStage2::
displayDebugMessage_(const std::string &msg) displayDebugMessage_(const std::string &msg) const
{ {
if (this->debug_) { if (this->debug) {
const std::string message = fmt::format( const std::string message = fmt::format(
" GLIFT2 (DEBUG) : {}", msg); " GLIFT2 (DEBUG) : {}", msg);
this->deferred_logger_.info(message); this->deferred_logger_.info(message);
@ -250,7 +249,7 @@ void
GasLiftStage2:: GasLiftStage2::
displayDebugMessage2B_(const std::string &msg) displayDebugMessage2B_(const std::string &msg)
{ {
if (this->debug_) { if (this->debug) {
const std::string message = fmt::format( const std::string message = fmt::format(
"Stage 2B : {}", msg); "Stage 2B : {}", msg);
displayDebugMessage_(message); displayDebugMessage_(message);
@ -261,7 +260,7 @@ void
GasLiftStage2:: GasLiftStage2::
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(
"Group {} : {}", group_name, msg); "Group {} : {}", group_name, msg);
displayDebugMessage_(message); displayDebugMessage_(message);
@ -275,7 +274,7 @@ getCurrentGroupRates_(const Group &group)
auto rates = getCurrentGroupRatesRecursive_(group); auto rates = getCurrentGroupRatesRecursive_(group);
this->comm_.sum(rates.data(), rates.size()); this->comm_.sum(rates.data(), rates.size());
auto [oil_rate, gas_rate, alq] = rates; auto [oil_rate, gas_rate, alq] = rates;
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Current group rates for {} : oil: {}, gas: {}, alq: {}", "Current group rates for {} : oil: {}, gas: {}, alq: {}",
group.name(), oil_rate, gas_rate, alq); group.name(), oil_rate, gas_rate, alq);
@ -342,13 +341,13 @@ getCurrentWellRates_(const std::string &well_name, const std::string &group_name
GasLiftWellState &state = *(this->well_state_map_.at(well_name).get()); GasLiftWellState &state = *(this->well_state_map_.at(well_name).get());
std::tie(oil_rate, gas_rate) = state.getRates(); std::tie(oil_rate, gas_rate) = state.getRates();
success = true; success = true;
if ( this->debug_) debug_info = "(A)"; if ( this->debug) debug_info = "(A)";
} }
else if (this->prod_wells_.count(well_name) == 1) { else if (this->prod_wells_.count(well_name) == 1) {
well_ptr = this->prod_wells_.at(well_name); well_ptr = this->prod_wells_.at(well_name);
std::tie(oil_rate, gas_rate) = getStdWellRates_(*well_ptr); std::tie(oil_rate, gas_rate) = getStdWellRates_(*well_ptr);
success = true; success = true;
if ( this->debug_) debug_info = "(B)"; if ( this->debug) debug_info = "(B)";
} }
if (well_ptr) { if (well_ptr) {
@ -362,7 +361,7 @@ getCurrentWellRates_(const std::string &well_name, const std::string &group_name
assert(well_ptr); assert(well_ptr);
assert(well_ptr->isProducer()); assert(well_ptr->isProducer());
alq = this->well_state_.getALQ(well_name); alq = this->well_state_.getALQ(well_name);
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Rates {} for well {} : oil: {}, gas: {}, alq: {}", "Rates {} for well {} : oil: {}, gas: {}, alq: {}",
debug_info, well_name, oil_rate, gas_rate, alq); debug_info, well_name, oil_rate, gas_rate, alq);
@ -380,7 +379,7 @@ getCurrentWellRates_(const std::string &well_name, const std::string &group_name
oil_rate *= factor; oil_rate *= factor;
gas_rate *= factor; gas_rate *= factor;
alq *= factor; alq *= factor;
if (this->debug_ && (factor != 1)) { if (this->debug && (factor != 1)) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Well {} : efficiency factor {}. New rates : oil: {}, gas: {}, alq: {}", "Well {} : efficiency factor {}. New rates : oil: {}, gas: {}, alq: {}",
well_name, factor, oil_rate, gas_rate, alq); well_name, factor, oil_rate, gas_rate, alq);
@ -389,7 +388,7 @@ getCurrentWellRates_(const std::string &well_name, const std::string &group_name
} }
else { else {
// NOTE: This happens for wells that are not producers, or not active. // NOTE: This happens for wells that are not producers, or not active.
if (this->debug_) { if (this->debug) {
const std::string msg = fmt::format("Could not determine current rates for " const std::string msg = fmt::format("Could not determine current rates for "
"well {}: (not active or injector)", well_name); "well {}: (not active or injector)", well_name);
displayDebugMessage_(msg, group_name); displayDebugMessage_(msg, group_name);
@ -716,7 +715,7 @@ removeSurplusALQ_(const Group &group,
auto [oil_rate, gas_rate, alq] = getCurrentGroupRates_(group); auto [oil_rate, gas_rate, alq] = getCurrentGroupRates_(group);
auto min_eco_grad = this->glo_.min_eco_gradient(); auto min_eco_grad = this->glo_.min_eco_gradient();
bool stop_iteration = false; bool stop_iteration = false;
if (this->debug_) { if (this->debug) {
std::string max_glift_str = "unlimited"; std::string max_glift_str = "unlimited";
if (max_glift) max_glift_str = fmt::format("{}", *max_glift); if (max_glift) max_glift_str = fmt::format("{}", *max_glift);
const std::string msg = fmt::format("Starting iteration for group: {}. " const std::string msg = fmt::format("Starting iteration for group: {}. "
@ -767,7 +766,7 @@ removeSurplusALQ_(const Group &group,
} }
} }
if (state.it >= 1) { if (state.it >= 1) {
if (this->debug_) { if (this->debug) {
auto [oil_rate2, gas_rate2, alq2] = getCurrentGroupRates_(group); auto [oil_rate2, gas_rate2, alq2] = getCurrentGroupRates_(group);
const std::string msg = fmt::format( const std::string msg = fmt::format(
"Finished after {} iterations for group: {}." "Finished after {} iterations for group: {}."
@ -1002,7 +1001,7 @@ void
GasLiftStage2::SurplusState:: GasLiftStage2::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",
this->group.name(), well_name, (add ? "adding" : "subtracting")); this->group.name(), well_name, (add ? "adding" : "subtracting"));
this->parent.displayDebugMessage2B_(msg); this->parent.displayDebugMessage2B_(msg);
@ -1019,7 +1018,7 @@ checkALQlimit()
double increment = this->parent.glo_.gaslift_increment(); double increment = this->parent.glo_.gaslift_increment();
double epsilon = 1e-6 * increment; double epsilon = 1e-6 * increment;
if ((max_alq+epsilon) < this->alq ) { if ((max_alq+epsilon) < this->alq ) {
if (this->parent.debug_) { if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : " const std::string msg = fmt::format("group: {} : "
"ALQ rate {} is greater than ALQ limit {}", this->group.name(), "ALQ rate {} is greater than ALQ limit {}", this->group.name(),
this->alq, max_alq); this->alq, max_alq);
@ -1036,7 +1035,7 @@ GasLiftStage2::SurplusState::
checkEcoGradient(const std::string &well_name, double eco_grad) checkEcoGradient(const std::string &well_name, double eco_grad)
{ {
if (eco_grad < this->min_eco_grad) { if (eco_grad < this->min_eco_grad) {
if (this->parent.debug_) { if (this->parent.debug) {
const std::string msg = fmt::format("group: {}, well: {} : " const std::string msg = fmt::format("group: {}, well: {} : "
"economic gradient {} less than minimum ({})", this->group.name(), "economic gradient {} less than minimum ({})", this->group.name(),
well_name, eco_grad, this->min_eco_grad); well_name, eco_grad, this->min_eco_grad);
@ -1055,7 +1054,7 @@ checkGasTarget()
{ {
if (this->group.has_control(Group::ProductionCMode::GRAT)) { if (this->group.has_control(Group::ProductionCMode::GRAT)) {
if (this->gas_target < this->gas_rate ) { if (this->gas_target < this->gas_rate ) {
if (this->parent.debug_) { if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : " const std::string msg = fmt::format("group: {} : "
"gas rate {} is greater than gas target {}", this->group.name(), "gas rate {} is greater than gas target {}", this->group.name(),
this->gas_rate, this->gas_target); this->gas_rate, this->gas_target);
@ -1073,7 +1072,7 @@ checkOilTarget()
{ {
if (this->group.has_control(Group::ProductionCMode::ORAT)) { if (this->group.has_control(Group::ProductionCMode::ORAT)) {
if (this->oil_target < this->oil_rate ) { if (this->oil_target < this->oil_rate ) {
if (this->parent.debug_) { if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : " const std::string msg = fmt::format("group: {} : "
"oil rate {} is greater than oil target {}", this->group.name(), "oil rate {} is greater than oil target {}", this->group.name(),
this->oil_rate, this->oil_target); this->oil_rate, this->oil_target);

View File

@ -45,7 +45,7 @@ class Schedule;
class WellInterfaceGeneric; class WellInterfaceGeneric;
class WellState; class WellState;
class GasLiftStage2 { class GasLiftStage2 : public GasLiftCommon {
using GasLiftSingleWell = GasLiftSingleWellGeneric; using GasLiftSingleWell = GasLiftSingleWellGeneric;
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*>;
@ -68,10 +68,11 @@ public:
WellState& well_state, WellState& well_state,
GLiftProdWells& prod_wells, GLiftProdWells& prod_wells,
GLiftOptWells& glift_wells, GLiftOptWells& glift_wells,
GLiftWellStateMap& state_map GLiftWellStateMap& state_map,
bool glift_debug
); );
void runOptimize(); void runOptimize();
private: protected:
void addOrRemoveALQincrement_( void addOrRemoveALQincrement_(
GradMap& grad_map, const std::string& well_name, bool add); GradMap& grad_map, const std::string& well_name, bool add);
std::optional<GradInfo> calcIncOrDecGrad_( std::optional<GradInfo> calcIncOrDecGrad_(
@ -80,7 +81,7 @@ private:
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); 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, const std::string& group_name);
void displayWarning_(const std::string& msg, const std::string& group_name); void displayWarning_(const std::string& msg, const std::string& group_name);
@ -121,8 +122,6 @@ private:
std::vector<GradPair>& grads_global) const; std::vector<GradPair>& grads_global) const;
DeferredLogger& deferred_logger_;
WellState& well_state_;
GLiftProdWells& prod_wells_; GLiftProdWells& prod_wells_;
GLiftOptWells& stage1_wells_; GLiftOptWells& stage1_wells_;
GLiftWellStateMap& well_state_map_; GLiftWellStateMap& well_state_map_;
@ -134,7 +133,6 @@ private:
const Parallel::Communication& comm_; const Parallel::Communication& comm_;
GradMap inc_grads_; GradMap inc_grads_;
GradMap dec_grads_; GradMap dec_grads_;
bool debug_;
int max_iterations_ = 1000; int max_iterations_ = 1000;
//int time_step_idx_; //int time_step_idx_;

View File

@ -108,7 +108,8 @@ namespace Opm
GLiftOptWells &, GLiftOptWells &,
GLiftWellStateMap &, GLiftWellStateMap &,
GasLiftGroupInfo &, GasLiftGroupInfo &,
GLiftSyncGroups & GLiftSyncGroups &,
bool
) const override { ) const override {
// Not implemented yet // Not implemented yet
} }

View File

@ -211,7 +211,8 @@ namespace Opm
GLiftOptWells &glift_wells, GLiftOptWells &glift_wells,
GLiftWellStateMap &state_map, GLiftWellStateMap &state_map,
GasLiftGroupInfo &group_info, GasLiftGroupInfo &group_info,
GLiftSyncGroups &sync_groups GLiftSyncGroups &sync_groups,
bool glift_debug
) const override; ) const override;
/* returns BHP */ /* returns BHP */

View File

@ -193,111 +193,6 @@ computeConnectionPressureDelta()
baseif_.parallelWellInfo().partialSumPerfValues(beg, end); baseif_.parallelWellInfo().partialSumPerfValues(beg, end);
} }
template<class Scalar>
void
StandardWellGeneric<Scalar>::
gliftDebug(const std::string &msg,
DeferredLogger& deferred_logger) const
{
if (glift_debug) {
const std::string message = fmt::format(
" GLIFT (DEBUG) : SW : Well {} : {}", baseif_.name(), msg);
deferred_logger.info(message);
}
}
template<class Scalar>
bool
StandardWellGeneric<Scalar>::
checkGliftNewtonIterationIdxOk(const int report_step_idx,
const int iteration_idx,
const Schedule& schedule,
DeferredLogger& deferred_logger ) const
{
const GasLiftOpt& glo = schedule.glo(report_step_idx);
if (glo.all_newton()) {
const int nupcol = schedule[report_step_idx].nupcol();
if (this->glift_debug) {
const std::string msg = fmt::format(
"LIFTOPT item4 == YES, it = {}, nupcol = {} --> GLIFT optimize = {}",
iteration_idx,
nupcol,
((iteration_idx <= nupcol) ? "TRUE" : "FALSE"));
gliftDebug(msg, deferred_logger);
}
return iteration_idx <= nupcol;
}
else {
if (this->glift_debug) {
const std::string msg = fmt::format(
"LIFTOPT item4 == NO, it = {} --> GLIFT optimize = {}",
iteration_idx, ((iteration_idx == 1) ? "TRUE" : "FALSE"));
gliftDebug(msg, deferred_logger);
}
return iteration_idx == 1;
}
}
/* At this point we know that the well does not have BHP control mode and
that it does have THP constraints, see computeWellPotentials().
* TODO: Currently we limit the application of gas lift optimization to wells
* operating under THP control mode, does it make sense to
* extend it to other modes?
*/
template<class Scalar>
bool
StandardWellGeneric<Scalar>::
doGasLiftOptimize(const WellState &well_state,
const int report_step_idx,
const int iteration_idx,
const Schedule& schedule,
DeferredLogger& deferred_logger) const
{
if (well_state.gliftCheckAlqOscillation(baseif_.name())) {
gliftDebug("further optimization skipped due to oscillation in ALQ",
deferred_logger);
return false;
}
if (glift_optimize_only_thp_wells) {
const int well_index = baseif_.indexOfWell();
auto control_mode = well_state.well(well_index).production_cmode;
if (control_mode != Well::ProducerCMode::THP ) {
gliftDebug("Not THP control", deferred_logger);
return false;
}
}
if (!checkGliftNewtonIterationIdxOk(report_step_idx,
iteration_idx,
schedule,
deferred_logger)) {
return false;
}
const GasLiftOpt& glo = schedule.glo(report_step_idx);
if (!glo.has_well(baseif_.name())) {
gliftDebug("Gas Lift not activated: WLIFTOPT is probably missing",
deferred_logger);
return false;
}
auto increment = glo.gaslift_increment();
// NOTE: According to the manual: LIFTOPT, item 1, :
// "Increment size for lift gas injection rate. Lift gas is
// allocated to individual wells in whole numbers of the increment
// size. If gas lift optimization is no longer required, it can be
// turned off by entering a zero or negative number."
if (increment <= 0) {
if (glift_debug) {
const std::string msg = fmt::format(
"Gas Lift switched off in LIFTOPT item 1 due to non-positive "
"value: {}", increment);
gliftDebug(msg, deferred_logger);
}
return false;
}
else {
return true;
}
}
template<class Scalar> template<class Scalar>
std::optional<double> std::optional<double>
StandardWellGeneric<Scalar>:: StandardWellGeneric<Scalar>::

View File

@ -107,18 +107,6 @@ protected:
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
double alq_value) const; double alq_value) const;
void gliftDebug(const std::string &msg,
DeferredLogger& deferred_logger) const;
bool checkGliftNewtonIterationIdxOk(const int report_step_idx,
const int iteration_idx,
const Schedule& schedule,
DeferredLogger& deferred_logger) const;
bool doGasLiftOptimize(const WellState &well_state,
const int report_step_idx,
const int iteration_idx,
const Schedule& schedule,
DeferredLogger& deferred_logger) const;
// Base interface reference // Base interface reference
const WellInterfaceGeneric& baseif_; const WellInterfaceGeneric& baseif_;
@ -130,11 +118,6 @@ protected:
// pressure drop between different perforations // pressure drop between different perforations
std::vector<double> perf_pressure_diffs_; std::vector<double> perf_pressure_diffs_;
// Enable GLIFT debug mode. This will enable output of logging messages.
bool glift_debug = false;
// Optimize only wells under THP control
bool glift_optimize_only_thp_wells = true;
// two off-diagonal matrices // two off-diagonal matrices
OffDiagMatWell duneB_; OffDiagMatWell duneB_;
OffDiagMatWell duneC_; OffDiagMatWell duneC_;

View File

@ -1824,14 +1824,16 @@ namespace Opm
GLiftOptWells &glift_wells, GLiftOptWells &glift_wells,
GLiftWellStateMap &glift_state_map, GLiftWellStateMap &glift_state_map,
GasLiftGroupInfo &group_info, GasLiftGroupInfo &group_info,
GLiftSyncGroups &sync_groups GLiftSyncGroups &sync_groups,
bool glift_debug
) const ) const
{ {
const auto& summary_state = ebos_simulator.vanguard().summaryState(); const auto& summary_state = ebos_simulator.vanguard().summaryState();
std::unique_ptr<GasLiftSingleWell> glift std::unique_ptr<GasLiftSingleWell> glift
= std::make_unique<GasLiftSingleWell>( = std::make_unique<GasLiftSingleWell>(
*this, ebos_simulator, summary_state, *this, ebos_simulator, summary_state,
deferred_logger, well_state, group_state, group_info, sync_groups); deferred_logger, well_state, group_state, group_info,
sync_groups, glift_debug);
auto state = glift->runOptimize( auto state = glift->runOptimize(
ebos_simulator.model().newtonMethod().numIterations()); ebos_simulator.model().newtonMethod().numIterations());
if (state) { if (state) {

View File

@ -168,7 +168,8 @@ public:
GLiftOptWells& glift_wells, GLiftOptWells& glift_wells,
GLiftWellStateMap& state_map, GLiftWellStateMap& state_map,
GasLiftGroupInfo &group_info, GasLiftGroupInfo &group_info,
GLiftSyncGroups &sync_groups GLiftSyncGroups &sync_groups,
bool glift_debug
) const = 0; ) const = 0;
/// using the solution x to recover the solution xw for wells and applying /// using the solution x to recover the solution xw for wells and applying

View File

@ -164,6 +164,18 @@ public:
this->alq_state.set(name, value); this->alq_state.set(name, value);
} }
int gliftGetDebugCounter() {
return this->alq_state.get_debug_counter();
}
void gliftSetDebugCounter(int value) {
return this->alq_state.set_debug_counter(value);
}
int gliftUpdateDebugCounter() {
return this->alq_state.update_debug_counter();
}
bool gliftCheckAlqOscillation(const std::string &name) const { bool gliftCheckAlqOscillation(const std::string &name) const {
return this->alq_state.oscillation(name); return this->alq_state.oscillation(name);
} }

View File

@ -181,11 +181,14 @@ BOOST_AUTO_TEST_CASE(G1)
well_model.phaseUsage(), well_model.phaseUsage(),
deferred_logger, deferred_logger,
well_state, well_state,
simulator->vanguard().grid().comm() simulator->vanguard().grid().comm(),
/*glift_debug=*/false
}; };
GLiftSyncGroups sync_groups; GLiftSyncGroups sync_groups;
GasLiftSingleWell glift {*std_well, *(simulator.get()), summary_state, GasLiftSingleWell glift {*std_well, *(simulator.get()), summary_state,
deferred_logger, well_state, group_state, group_info, sync_groups}; deferred_logger, well_state, group_state, group_info, sync_groups,
/*glift_debug=*/false
};
group_info.initialize(); group_info.initialize();
auto state = glift.runOptimize(iteration_idx); auto state = glift.runOptimize(iteration_idx);
BOOST_CHECK_CLOSE(state->oilRate(), 0.01736111111111111, 1e-8); BOOST_CHECK_CLOSE(state->oilRate(), 0.01736111111111111, 1e-8);