mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-01-07 15:03:01 -06:00
Merge pull request #3400 from hakonhagland/glift_config
Add missing header file to GasLiftGroupInfo.cpp
This commit is contained in:
commit
6f227f8177
@ -872,9 +872,10 @@ namespace Opm {
|
||||
ebosSimulator_.model().newtonMethod().numIterations(),
|
||||
phase_usage_,
|
||||
deferred_logger,
|
||||
this->wellState()
|
||||
this->wellState(),
|
||||
ebosSimulator_.vanguard().grid().comm()
|
||||
};
|
||||
group_info.initialize(ebosSimulator_.vanguard().grid().comm());
|
||||
group_info.initialize();
|
||||
gasLiftOptimizationStage1(
|
||||
deferred_logger, prod_wells, glift_wells, group_info, state_map);
|
||||
gasLiftOptimizationStage2(
|
||||
|
@ -17,6 +17,7 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <opm/simulators/wells/GasLiftGroupInfo.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@ -30,7 +31,8 @@ GasLiftGroupInfo(
|
||||
const int iteration_idx,
|
||||
const PhaseUsage &phase_usage,
|
||||
DeferredLogger &deferred_logger,
|
||||
WellState &well_state
|
||||
WellState &well_state,
|
||||
const Communication &comm
|
||||
) :
|
||||
ecl_wells_{ecl_wells},
|
||||
schedule_{schedule},
|
||||
@ -40,6 +42,7 @@ GasLiftGroupInfo(
|
||||
phase_usage_{phase_usage},
|
||||
deferred_logger_{deferred_logger},
|
||||
well_state_{well_state},
|
||||
comm_{comm},
|
||||
glo_{schedule_.glo(report_step_idx_)},
|
||||
debug{false}
|
||||
{
|
||||
@ -126,6 +129,17 @@ hasWell(const std::string& well_name)
|
||||
return this->well_group_map_.count(well_name) == 1;
|
||||
}
|
||||
|
||||
void
|
||||
GasLiftGroupInfo::
|
||||
initialize()
|
||||
{
|
||||
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
|
||||
initializeGroupRatesRecursive_(group);
|
||||
std::vector<std::string> group_names;
|
||||
std::vector<double> group_efficiency;
|
||||
initializeWell2GroupMapRecursive_(
|
||||
group, group_names, group_efficiency, /*current efficiency=*/1.0);
|
||||
}
|
||||
|
||||
std::optional<double>
|
||||
GasLiftGroupInfo::
|
||||
@ -293,6 +307,75 @@ getProducerWellRates_(int well_index)
|
||||
return {oil_rate, gas_rate};
|
||||
}
|
||||
|
||||
std::tuple<double, double, double>
|
||||
GasLiftGroupInfo::
|
||||
initializeGroupRatesRecursive_(const Group &group)
|
||||
{
|
||||
double oil_rate = 0.0;
|
||||
double gas_rate = 0.0;
|
||||
double alq = 0.0;
|
||||
if (group.wellgroup()) {
|
||||
for (const std::string& well_name : group.wells()) {
|
||||
// NOTE: we cannot simply use:
|
||||
//
|
||||
// const auto &well =
|
||||
// this->schedule_.getWell(well_name, this->report_step_idx_);
|
||||
//
|
||||
// since the well may not be active (present in the well container)
|
||||
auto itr = this->ecl_wells_.find(well_name);
|
||||
if (itr != this->ecl_wells_.end()) {
|
||||
const Well *well = (itr->second).first;
|
||||
assert(well); // Should never be nullptr
|
||||
const int index = (itr->second).second;
|
||||
if (well->isProducer()) {
|
||||
auto [sw_oil_rate, sw_gas_rate] = getProducerWellRates_(index);
|
||||
auto sw_alq = this->well_state_.getALQ(well_name);
|
||||
double factor = well->getEfficiencyFactor();
|
||||
oil_rate += (factor * sw_oil_rate);
|
||||
gas_rate += (factor * sw_gas_rate);
|
||||
alq += (factor * sw_alq);
|
||||
}
|
||||
}
|
||||
}
|
||||
oil_rate = this->comm_.sum(oil_rate);
|
||||
gas_rate = this->comm_.sum(gas_rate);
|
||||
alq = this->comm_.sum(alq);
|
||||
}
|
||||
else {
|
||||
for (const std::string& group_name : group.groups()) {
|
||||
if (!this->schedule_.back().groups.has(group_name))
|
||||
continue;
|
||||
const Group& sub_group = this->schedule_.getGroup(
|
||||
group_name, this->report_step_idx_);
|
||||
auto [sg_oil_rate, sg_gas_rate, sg_alq]
|
||||
= initializeGroupRatesRecursive_(sub_group);
|
||||
const auto gefac = sub_group.getGroupEfficiencyFactor();
|
||||
oil_rate += (gefac * sg_oil_rate);
|
||||
gas_rate += (gefac * sg_gas_rate);
|
||||
alq += (gefac * sg_alq);
|
||||
}
|
||||
}
|
||||
std::optional<double> oil_target, gas_target, max_total_gas, max_alq;
|
||||
const auto controls = group.productionControls(this->summary_state_);
|
||||
if (group.has_control(Group::ProductionCMode::ORAT)) {
|
||||
oil_target = controls.oil_target;
|
||||
}
|
||||
if (group.has_control(Group::ProductionCMode::GRAT)) {
|
||||
gas_target = controls.gas_target;
|
||||
}
|
||||
if (this->glo_.has_group(group.name())) {
|
||||
const auto &gl_group = this->glo_.group(group.name());
|
||||
max_alq = gl_group.max_lift_gas();
|
||||
max_total_gas = gl_group.max_total_gas();
|
||||
}
|
||||
if (oil_target || gas_target || max_total_gas || max_alq) {
|
||||
updateGroupIdxMap_(group.name());
|
||||
this->group_rate_map_.try_emplace(group.name(),
|
||||
oil_rate, gas_rate, alq, oil_target, gas_target, max_total_gas, max_alq);
|
||||
}
|
||||
return std::make_tuple(oil_rate, gas_rate, alq);
|
||||
}
|
||||
|
||||
void
|
||||
GasLiftGroupInfo::
|
||||
initializeWell2GroupMapRecursive_(
|
||||
|
@ -55,6 +55,12 @@ class GasLiftGroupInfo
|
||||
using GroupRateMap =
|
||||
std::map<std::string, GroupRates>;
|
||||
using GroupIdxMap = std::map<std::string, int>;
|
||||
using MPIComm = typename Dune::MPIHelper::MPICommunicator;
|
||||
#if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 7)
|
||||
using Communication = Dune::Communication<MPIComm>;
|
||||
#else
|
||||
using Communication = Dune::CollectiveCommunication<MPIComm>;
|
||||
#endif
|
||||
|
||||
// TODO: same definition with WellInterface, and
|
||||
// WellState eventually they should go to a common header file.
|
||||
@ -71,25 +77,11 @@ public:
|
||||
const int iteration_idx,
|
||||
const PhaseUsage& phase_usage,
|
||||
DeferredLogger& deferred_logger,
|
||||
WellState& well_state);
|
||||
WellState& well_state,
|
||||
const Communication& comm);
|
||||
std::vector<std::pair<std::string,double>>& getWellGroups(
|
||||
const std::string& well_name);
|
||||
|
||||
// TODO: See comment below for initializeGroupRatesRecursive_() for why
|
||||
// the implementation of initialize() is kept here in the header file instead
|
||||
// of in the .cpp file...
|
||||
template<class Comm>
|
||||
void
|
||||
initialize(const Comm& comm)
|
||||
{
|
||||
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
|
||||
initializeGroupRatesRecursive_(comm, group);
|
||||
std::vector<std::string> group_names;
|
||||
std::vector<double> group_efficiency;
|
||||
initializeWell2GroupMapRecursive_(
|
||||
group, group_names, group_efficiency, /*current efficiency=*/1.0);
|
||||
}
|
||||
|
||||
double alqRate(const std::string& group_name);
|
||||
double gasRate(const std::string& group_name);
|
||||
int getGroupIdx(const std::string& group_name);
|
||||
@ -97,6 +89,7 @@ public:
|
||||
std::optional<double> gasTarget(const std::string& group_name);
|
||||
const std::string& groupIdxToName(int group_idx);
|
||||
bool hasWell(const std::string& well_name);
|
||||
void initialize();
|
||||
std::optional<double> maxAlq(const std::string& group_name);
|
||||
double oilRate(const std::string& group_name);
|
||||
std::optional<double> oilTarget(const std::string& group_name);
|
||||
@ -110,101 +103,13 @@ private:
|
||||
void displayDebugMessage_(const std::string& msg);
|
||||
void displayDebugMessage_(const std::string& msg, const std::string& well_name);
|
||||
std::pair<double, double> getProducerWellRates_(const int index);
|
||||
std::tuple<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);
|
||||
|
||||
// TODO: I first tried to pass the MPI Communicator as a constructor argument
|
||||
// to this class (GasLiftGroupInfo) similar to what is done for
|
||||
// GasLiftStage2 (see GasLiftStage2.hpp), hower this did not work for this
|
||||
// class since we are also constructing a GasLiftGroupInfo object in the
|
||||
// test file test1_glift.cpp and when the linker tries to find a definition
|
||||
// of the GasLiftGroupInfo(...) constructor in libopmsimulators.a,
|
||||
// the template type of the MPI communicator (Dune::Communication<..>)
|
||||
// is not of the same type as the one needed by the test case.
|
||||
// The test case needs Dune::Communication<ompi_communicator_t*>, whereas
|
||||
// the one in libopmsimulators.a is Dune::Communication<Dune::No_Comm>.
|
||||
//
|
||||
// The error I got from the linker is:
|
||||
//
|
||||
// /bin/ld: CMakeFiles/test_glift1.dir/tests/test_glift1.cpp.o:
|
||||
// in function `G1::test_method()':
|
||||
// test_glift1.cpp:(.text+0x15b36): undefined reference to
|
||||
// `Opm::GasLiftGroupInfo::GasLiftGroupInfo(....)
|
||||
//
|
||||
// to work around this issue this function is templetized in terms of Comm
|
||||
// here in the header file instead of having it in the .cpp file.
|
||||
// (thanks to Tor Harald S. for the suggestion)
|
||||
template<class Comm>
|
||||
std::tuple<double, double, double>
|
||||
initializeGroupRatesRecursive_(const Comm& comm, const Group &group)
|
||||
{
|
||||
double oil_rate = 0.0;
|
||||
double gas_rate = 0.0;
|
||||
double alq = 0.0;
|
||||
if (group.wellgroup()) {
|
||||
for (const std::string& well_name : group.wells()) {
|
||||
// NOTE: we cannot simply use:
|
||||
//
|
||||
// const auto &well =
|
||||
// this->schedule_.getWell(well_name, this->report_step_idx_);
|
||||
//
|
||||
// since the well may not be active (present in the well container)
|
||||
auto itr = this->ecl_wells_.find(well_name);
|
||||
if (itr != this->ecl_wells_.end()) {
|
||||
const Well *well = (itr->second).first;
|
||||
assert(well); // Should never be nullptr
|
||||
const int index = (itr->second).second;
|
||||
if (well->isProducer()) {
|
||||
auto [sw_oil_rate, sw_gas_rate] = getProducerWellRates_(index);
|
||||
auto sw_alq = this->well_state_.getALQ(well_name);
|
||||
double factor = well->getEfficiencyFactor();
|
||||
oil_rate += (factor * sw_oil_rate);
|
||||
gas_rate += (factor * sw_gas_rate);
|
||||
alq += (factor * sw_alq);
|
||||
}
|
||||
}
|
||||
}
|
||||
// These sums needs to be communictated
|
||||
oil_rate = comm.sum(oil_rate);
|
||||
gas_rate = comm.sum(gas_rate);
|
||||
alq = comm.sum(alq);
|
||||
}
|
||||
else {
|
||||
for (const std::string& group_name : group.groups()) {
|
||||
if (!this->schedule_.back().groups.has(group_name))
|
||||
continue;
|
||||
const Group& sub_group = this->schedule_.getGroup(
|
||||
group_name, this->report_step_idx_);
|
||||
auto [sg_oil_rate, sg_gas_rate, sg_alq]
|
||||
= initializeGroupRatesRecursive_(comm, sub_group);
|
||||
const auto gefac = sub_group.getGroupEfficiencyFactor();
|
||||
oil_rate += (gefac * sg_oil_rate);
|
||||
gas_rate += (gefac * sg_gas_rate);
|
||||
alq += (gefac * sg_alq);
|
||||
}
|
||||
}
|
||||
std::optional<double> oil_target, gas_target, max_total_gas, max_alq;
|
||||
const auto controls = group.productionControls(this->summary_state_);
|
||||
if (group.has_control(Group::ProductionCMode::ORAT)) {
|
||||
oil_target = controls.oil_target;
|
||||
}
|
||||
if (group.has_control(Group::ProductionCMode::GRAT)) {
|
||||
gas_target = controls.gas_target;
|
||||
}
|
||||
if (this->glo_.has_group(group.name())) {
|
||||
const auto &gl_group = this->glo_.group(group.name());
|
||||
max_alq = gl_group.max_lift_gas();
|
||||
max_total_gas = gl_group.max_total_gas();
|
||||
}
|
||||
if (oil_target || gas_target || max_total_gas || max_alq) {
|
||||
updateGroupIdxMap_(group.name());
|
||||
this->group_rate_map_.try_emplace(group.name(),
|
||||
oil_rate, gas_rate, alq, oil_target, gas_target, max_total_gas, max_alq);
|
||||
}
|
||||
return std::make_tuple(oil_rate, gas_rate, alq);
|
||||
}
|
||||
|
||||
class GroupRates {
|
||||
public:
|
||||
@ -258,6 +163,7 @@ private:
|
||||
const PhaseUsage &phase_usage_;
|
||||
DeferredLogger &deferred_logger_;
|
||||
WellState &well_state_;
|
||||
const Communication &comm_;
|
||||
const GasLiftOpt& glo_;
|
||||
GroupRateMap group_rate_map_;
|
||||
Well2GroupMap well_group_map_;
|
||||
|
@ -178,7 +178,8 @@ BOOST_AUTO_TEST_CASE(G1)
|
||||
iteration_idx,
|
||||
well_model.phaseUsage(),
|
||||
deferred_logger,
|
||||
well_state
|
||||
well_state,
|
||||
simulator->vanguard().grid().comm()
|
||||
};
|
||||
GLiftSyncGroups sync_groups;
|
||||
GasLiftSingleWell glift {*std_well, *(simulator.get()), summary_state,
|
||||
|
Loading…
Reference in New Issue
Block a user