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/wells/ALQState.cpp
opm/simulators/wells/BlackoilWellModelGeneric.cpp
opm/simulators/wells/GasLiftCommon.cpp
opm/simulators/wells/GasLiftGroupInfo.cpp
opm/simulators/wells/GasLiftSingleWellGeneric.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;
}
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 {
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();
int get_increment_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:
std::map<std::string, double> current_alq_;
std::map<std::string, double> default_alq_;
std::map<std::string, int> alq_increase_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(),
prod_wells,
glift_wells,
glift_well_state_map};
glift_well_state_map,
this->glift_debug
};
glift.runOptimize();
}

View File

@ -896,7 +896,8 @@ namespace Opm {
phase_usage_,
deferred_logger,
this->wellState(),
ebosSimulator_.vanguard().grid().comm()
ebosSimulator_.vanguard().grid().comm(),
this->glift_debug
};
group_info.initialize();
gasLiftOptimizationStage1(
@ -951,9 +952,11 @@ namespace Opm {
// NOTE: Only the wells in "group_info" needs to be optimized
if (group_info.hasWell(well->name())) {
well->gasLiftOptimizationStage1(
this->wellState(), this->groupState(), ebosSimulator_, deferred_logger,
this->wellState(), this->groupState(), ebosSimulator_,
deferred_logger,
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();
@ -1006,6 +1009,16 @@ namespace Opm {
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,
DeferredLogger &deferred_logger,
WellState &well_state,
const Communication &comm
const Communication &comm,
bool glift_debug
) :
ecl_wells_{ecl_wells},
schedule_{schedule},
summary_state_{summary_state},
report_step_idx_{report_step_idx},
iteration_idx_{iteration_idx},
phase_usage_{phase_usage},
deferred_logger_{deferred_logger},
well_state_{well_state},
comm_{comm},
glo_{schedule_.glo(report_step_idx_)},
debug{false}
GasLiftCommon(well_state, deferred_logger, glift_debug)
, ecl_wells_{ecl_wells}
, schedule_{schedule}
, summary_state_{summary_state}
, report_step_idx_{report_step_idx}
, iteration_idx_{iteration_idx}
, phase_usage_{phase_usage}
, comm_{comm}
, glo_{schedule_.glo(report_step_idx_)}
{
}
@ -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
GasLiftGroupInfo::
displayDebugMessage_(const std::string &msg)
displayDebugMessage_(const std::string &msg) const
{
if (this->debug) {
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/GasLiftOpt.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/simulators/wells/GasLiftCommon.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/utils/DeferredLogger.hpp>
@ -42,8 +43,9 @@
namespace Opm
{
class GasLiftGroupInfo
class GasLiftGroupInfo : public GasLiftCommon
{
protected:
class GroupRates;
// NOTE: In the Well2GroupMap below, in the std::vector value we store
// pairs of group names and efficiency factors. The efficiency factors
@ -79,7 +81,9 @@ public:
const PhaseUsage& phase_usage,
DeferredLogger& deferred_logger,
WellState& well_state,
const Parallel::Communication& comm);
const Parallel::Communication& comm,
bool glift_debug
);
std::vector<std::pair<std::string,double>>& getWellGroups(
const std::string& well_name);
@ -105,10 +109,10 @@ public:
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);
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 checkNewtonIterationIdxOk_(const std::string& well_name);
void displayDebugMessage_(const std::string& msg);
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, double>
@ -183,13 +187,10 @@ private:
const int report_step_idx_;
const int iteration_idx_;
const PhaseUsage &phase_usage_;
DeferredLogger &deferred_logger_;
WellState &well_state_;
const Parallel::Communication &comm_;
const GasLiftOpt& glo_;
GroupRateMap group_rate_map_;
Well2GroupMap well_group_map_;
bool debug;
GroupIdxMap group_idx_;
int next_group_idx_ = 0;
// Optimize only wells under THP control

View File

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

View File

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

View File

@ -28,6 +28,7 @@
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/simulators/wells/GasLiftGroupInfo.hpp>
#include <opm/simulators/wells/GasLiftCommon.hpp>
#include <functional>
#include <optional>
@ -47,7 +48,7 @@ class WellInterfaceGeneric;
class WellState;
class GroupState;
class GasLiftSingleWellGeneric
class GasLiftSingleWellGeneric : public GasLiftCommon
{
protected:
static const int Water = BlackoilPhases::Aqua;
@ -102,7 +103,8 @@ protected:
GasLiftGroupInfo &group_info,
const Schedule& schedule,
const int report_step_idx,
GLiftSyncGroups &sync_groups
GLiftSyncGroups &sync_groups,
bool glift_debug
);
struct OptimizeState
@ -174,7 +176,7 @@ protected:
void debugShowTargets_();
void displayDebugMessage_(const std::string& msg) const;
void displayDebugMessage_(const std::string& msg) const override;
void displayWarning_(const std::string& warning);
std::pair<double, bool> getBhpWithLimit_(double bhp) const;
@ -249,8 +251,6 @@ protected:
void warnMaxIterationsExceeded_();
DeferredLogger& deferred_logger_;
WellState& well_state_;
const GroupState& group_state_;
const Well& ecl_well_;
const SummaryState& summary_state_;
@ -279,7 +279,6 @@ protected:
const GasLiftOpt::Well* gl_well_;
bool optimize_;
bool debug_; // extra debug output
bool debug_limit_increase_decrease_;
bool debug_abort_if_decrease_and_oil_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,
const GroupState &group_state,
GasLiftGroupInfo &group_info,
GLiftSyncGroups &sync_groups
GLiftSyncGroups &sync_groups,
bool glift_debug
)
// The parent class GasLiftSingleWellGeneric contains all stuff
// that is not dependent on TypeTag
@ -41,7 +42,8 @@ GasLiftSingleWell(const StdWell &std_well,
group_info,
ebos_simulator.vanguard().schedule(),
ebos_simulator.episodeIndex(),
sync_groups
sync_groups,
glift_debug
)
, ebos_simulator_{ebos_simulator}
, std_well_{std_well}

View File

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

View File

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

View File

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

View File

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

View File

@ -193,111 +193,6 @@ computeConnectionPressureDelta()
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>
std::optional<double>
StandardWellGeneric<Scalar>::

View File

@ -107,18 +107,6 @@ protected:
DeferredLogger& deferred_logger,
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
const WellInterfaceGeneric& baseif_;
@ -130,11 +118,6 @@ protected:
// pressure drop between different perforations
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
OffDiagMatWell duneB_;
OffDiagMatWell duneC_;

View File

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

View File

@ -168,7 +168,8 @@ public:
GLiftOptWells& glift_wells,
GLiftWellStateMap& state_map,
GasLiftGroupInfo &group_info,
GLiftSyncGroups &sync_groups
GLiftSyncGroups &sync_groups,
bool glift_debug
) const = 0;
/// 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);
}
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 {
return this->alq_state.oscillation(name);
}

View File

@ -181,11 +181,14 @@ BOOST_AUTO_TEST_CASE(G1)
well_model.phaseUsage(),
deferred_logger,
well_state,
simulator->vanguard().grid().comm()
simulator->vanguard().grid().comm(),
/*glift_debug=*/false
};
GLiftSyncGroups sync_groups;
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();
auto state = glift.runOptimize(iteration_idx);
BOOST_CHECK_CLOSE(state->oilRate(), 0.01736111111111111, 1e-8);