mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-11-03 12:47:42 -06:00
marking some groups are NONE group control
based whether the group contribute to some SingleWellState::group_target
This commit is contained in:
1 parent
5e5a57dfd3
commit
7c70f91109
7 files changed
+103
-15
No files matched your search
@@ -1947,6 +1947,82 @@ operator==(const BlackoilWellModelGeneric& rhs) const
|
||||
&& this->gen_gaslift_ == rhs.gen_gaslift_;
|
||||
}
|
||||
|
||||
template <typename Scalar, typename IndexTraits>
|
||||
void
|
||||
BlackoilWellModelGeneric<Scalar, IndexTraits>::
|
||||
updateNONEProductionGroups(DeferredLogger& deferred_logger)
|
||||
{
|
||||
auto& group_state = this->groupState();
|
||||
const auto& prod_group_controls = group_state.get_production_controls();
|
||||
if (prod_group_controls.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& well_state = this->wellState();
|
||||
// numbers of the group production controls
|
||||
// one group can have multiple controls, including NONE
|
||||
const std::size_t size_pc = prod_group_controls.size();
|
||||
// Collect groups that currently provide production targets to any well on this rank
|
||||
std::unordered_set<std::string> targeted_production_groups; // TODO: better name
|
||||
targeted_production_groups.reserve(size_pc);
|
||||
|
||||
for (const auto& wname : well_state.wells()) {
|
||||
const auto& ws = well_state.well(wname);
|
||||
if (ws.producer && ws.production_cmode == WellProducerCMode::GRUP) {
|
||||
const auto& group_target = ws.group_target;
|
||||
if (group_target.has_value()) {
|
||||
targeted_production_groups.insert(group_target->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parallel communication to synchronize production groups used on all processes
|
||||
std::vector<std::string> gnames;
|
||||
gnames.reserve(size_pc);
|
||||
for (const auto& gprod : prod_group_controls) {
|
||||
gnames.push_back(gprod.first);
|
||||
}
|
||||
|
||||
std::vector<int> local_used(size_pc, 0);
|
||||
for (std::size_t i = 0; i < size_pc; ++i) {
|
||||
if (targeted_production_groups.find(gnames[i]) != targeted_production_groups.end()) {
|
||||
local_used[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> global_used(size_pc, 0);
|
||||
|
||||
// with the following code, we only need to communicate once
|
||||
if (comm_.size() > 1 && size_pc > 0) {
|
||||
std::vector<int> gathered(comm_.size() * size_pc, 0);
|
||||
comm_.allgather(local_used.data(), static_cast<int>(size_pc), gathered.data());
|
||||
|
||||
for (int r = 0; r < comm_.size(); ++r) {
|
||||
const std::size_t base = static_cast<std::size_t>(r) * size_pc;
|
||||
for (std::size_t i = 0; i < size_pc; ++i) {
|
||||
global_used[i] = global_used[i] || gathered[base + i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
global_used = local_used;
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < size_pc; ++i) {
|
||||
if (global_used[i] > 0) {
|
||||
continue;
|
||||
}
|
||||
const auto& gname = gnames[i];
|
||||
if (group_state.production_control(gname) != Group::ProductionCMode::NONE) {
|
||||
if (comm_.rank() == 0) {
|
||||
const std::string msg = fmt::format("Production group {} has no constraints active, setting control mode to NONE", gname);
|
||||
deferred_logger.info(msg);
|
||||
}
|
||||
group_state.production_control(gname, Group::ProductionCMode::NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template class BlackoilWellModelGeneric<double, BlackOilDefaultFluidSystemIndices>;
|
||||
|
||||
#if FLOW_INSTANTIATE_FLOAT
|
||||
|
||||
@@ -508,6 +508,8 @@ protected:
|
||||
void assignMassGasRate(data::Wells& wsrpt,
|
||||
const Scalar gasDensity) const;
|
||||
|
||||
void updateNONEProductionGroups(DeferredLogger& deferred_logger);
|
||||
|
||||
Schedule& schedule_;
|
||||
|
||||
const SummaryState& summaryState_;
|
||||
|
||||
@@ -770,6 +770,8 @@ namespace Opm {
|
||||
|
||||
this->calculateProductivityIndexValues(local_deferredLogger);
|
||||
|
||||
this->updateNONEProductionGroups(local_deferredLogger);
|
||||
|
||||
this->commitWGState();
|
||||
|
||||
//reporting output temperatures
|
||||
|
||||
@@ -412,6 +412,13 @@ GroupState<Scalar>::production_control(const std::string& gname) const
|
||||
return group_iter->second;
|
||||
}
|
||||
|
||||
template<class Scalar>
|
||||
const std::map<std::string, Group::ProductionCMode>&
|
||||
GroupState<Scalar>::get_production_controls() const
|
||||
{
|
||||
return this->production_controls;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
template<class Scalar>
|
||||
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
bool has_production_control(const std::string& gname) const;
|
||||
void production_control(const std::string& gname, Group::ProductionCMode cmode);
|
||||
Group::ProductionCMode production_control(const std::string& gname) const;
|
||||
const std::map<std::string, Group::ProductionCMode>& get_production_controls() const;
|
||||
|
||||
bool has_injection_control(const std::string& gname, Phase phase) const;
|
||||
void injection_control(const std::string& gname, Phase phase, Group::InjectionCMode cmode);
|
||||
|
||||
@@ -553,7 +553,7 @@ getGroupRatesAvailableForHigherLevelControl(const Group& group, const bool is_in
|
||||
}
|
||||
|
||||
template <typename Scalar, typename IndexTraits>
|
||||
std::optional<Scalar>
|
||||
std::optional<std::pair<std::string, Scalar>>
|
||||
GroupStateHelper<Scalar, IndexTraits>::getWellGroupTargetInjector(const std::string& name,
|
||||
const std::string& parent,
|
||||
const Group& group,
|
||||
@@ -644,7 +644,7 @@ GroupStateHelper<Scalar, IndexTraits>::getWellGroupTargetInjector(const std::str
|
||||
do_addback);
|
||||
|
||||
// Avoid negative target rates coming from too large local reductions.
|
||||
return std::max(Scalar(0.0), target / efficiency_factor);
|
||||
return std::make_pair(group.name(), std::max(Scalar(0.0), target / efficiency_factor));
|
||||
}
|
||||
|
||||
template <typename Scalar, typename IndexTraits>
|
||||
@@ -660,7 +660,7 @@ GroupStateHelper<Scalar, IndexTraits>::getWellGroupTargetProducer(const std::str
|
||||
// 'parent' will be the name of 'group'. But if we recurse, 'name' and
|
||||
// 'parent' will stay fixed while 'group' will be higher up
|
||||
// in the group tree.
|
||||
// Eficiencyfactor is the well efficiency factor for the first group the well is
|
||||
// Efficiency factor is the well efficiency factor for the first group the well is
|
||||
// part of. Later it is the accumulated factor including the group efficiency factor
|
||||
// of the child of group.
|
||||
OPM_TIMEFUNCTION();
|
||||
|
||||
@@ -243,20 +243,20 @@ public:
|
||||
|
||||
GuideRate::RateVector getProductionGroupRateVector(const std::string& group_name) const;
|
||||
|
||||
std::optional<Scalar> getWellGroupTargetInjector(const std::string& name,
|
||||
const std::string& parent,
|
||||
const Group& group,
|
||||
const Scalar* rates,
|
||||
const Phase injection_phase,
|
||||
const Scalar efficiency_factor,
|
||||
const std::vector<Scalar>& resv_coeff) const;
|
||||
std::optional<std::pair<std::string, Scalar>> getWellGroupTargetInjector(const std::string& name,
|
||||
const std::string& parent,
|
||||
const Group& group,
|
||||
const Scalar* rates,
|
||||
const Phase injection_phase,
|
||||
const Scalar efficiency_factor,
|
||||
const std::vector<Scalar>& resv_coeff) const;
|
||||
|
||||
std::optional<std::pair<std::string, Scalar>> getWellGroupTargetProducer(const std::string& name,
|
||||
const std::string& parent,
|
||||
const Group& group,
|
||||
const Scalar* rates,
|
||||
const Scalar efficiency_factor,
|
||||
const std::vector<Scalar>& resv_coeff) const;
|
||||
const std::string& parent,
|
||||
const Group& group,
|
||||
const Scalar* rates,
|
||||
const Scalar efficiency_factor,
|
||||
const std::vector<Scalar>& resv_coeff) const;
|
||||
|
||||
GuideRate::RateVector getWellRateVector(const std::string& name) const;
|
||||
|
||||
|
||||
Reference in new issue
Block a user