mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #5816 from akva2/fix_wcycle_glob
Allow query for efficiency scaling factor in off-process wells where required
This commit is contained in:
commit
4f5c86d72c
@ -1575,7 +1575,7 @@ calculateEfficiencyFactors(const int reportStepIdx)
|
||||
for (auto& well : well_container_generic_) {
|
||||
const Well& wellEcl = well->wellEcl();
|
||||
Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor() *
|
||||
wellState()[well->name()].efficiency_scaling_factor;
|
||||
wellState().getGlobalEfficiencyScalingFactor(well->name());
|
||||
WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(),
|
||||
reportStepIdx),
|
||||
schedule(),
|
||||
|
@ -657,7 +657,7 @@ namespace Opm {
|
||||
well->init(&this->phase_usage_, depth_, gravity_, B_avg_, true);
|
||||
|
||||
Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor() *
|
||||
this->wellState()[well_name].efficiency_scaling_factor;
|
||||
this->wellState().getGlobalEfficiencyScalingFactor(well_name);
|
||||
WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(),
|
||||
timeStepIdx),
|
||||
this->schedule(),
|
||||
@ -1063,7 +1063,7 @@ namespace Opm {
|
||||
this->well_open_times_,
|
||||
schedule_open))
|
||||
{
|
||||
this->wellState()[wname].efficiency_scaling_factor = wscale;
|
||||
this->wellState().updateEfficiencyScalingFactor(wname, wscale);
|
||||
this->schedule_.add_event(ScheduleEvents::WELLGROUP_EFFICIENCY_UPDATE, report_step);
|
||||
}
|
||||
}
|
||||
|
@ -585,7 +585,7 @@ initializeGroupRatesRecursive_(const Group& group)
|
||||
auto [sw_oil_rate, sw_gas_rate, sw_water_rate, sw_oil_pot, sw_gas_pot, sw_water_pot] = getProducerWellRates_(well, index);
|
||||
auto sw_alq = this->well_state_.getALQ(well_name);
|
||||
const Scalar factor = well->getEfficiencyFactor() *
|
||||
this->well_state_[well_name].efficiency_scaling_factor;
|
||||
this->well_state_.getGlobalEfficiencyScalingFactor(well_name);
|
||||
oil_rate += (factor * sw_oil_rate);
|
||||
gas_rate += (factor * sw_gas_rate);
|
||||
water_rate += (factor * sw_water_rate);
|
||||
@ -707,7 +707,7 @@ initializeWell2GroupMapRecursive_(const Group& group,
|
||||
const auto &well = this->schedule_.getWell(
|
||||
well_name, this->report_step_idx_);
|
||||
const Scalar wfac = well.getEfficiencyFactor() *
|
||||
this->well_state_[well_name].efficiency_scaling_factor;
|
||||
this->well_state_.getGlobalEfficiencyScalingFactor(well_name);
|
||||
auto [itr, success] = this->well_group_map_.insert(
|
||||
{well_name, /*empty vector*/ {}});
|
||||
assert(success);
|
||||
|
@ -29,14 +29,17 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
|
||||
|
||||
GlobalWellInfo::GlobalWellInfo(const Schedule& sched, std::size_t report_step, const std::vector<Well>& local_wells)
|
||||
template<class Scalar>
|
||||
GlobalWellInfo<Scalar>::
|
||||
GlobalWellInfo(const Schedule& sched,
|
||||
std::size_t report_step,
|
||||
const std::vector<Well>& local_wells)
|
||||
{
|
||||
auto num_wells = sched.numWells(report_step);
|
||||
this->m_in_injecting_group.resize(num_wells);
|
||||
this->m_in_producing_group.resize(num_wells);
|
||||
this->m_is_open.resize(num_wells);
|
||||
this->m_efficiency_scaling_factors.resize(num_wells);
|
||||
for (const auto& wname : sched.wellNames(report_step)) {
|
||||
const auto& well = sched.getWell(wname, report_step);
|
||||
auto global_well_index = well.seqIndex();
|
||||
@ -47,24 +50,36 @@ GlobalWellInfo::GlobalWellInfo(const Schedule& sched, std::size_t report_step, c
|
||||
this->local_map.push_back( well.seqIndex() );
|
||||
}
|
||||
|
||||
|
||||
bool GlobalWellInfo::in_injecting_group(const std::string& wname) const {
|
||||
template<class Scalar>
|
||||
bool GlobalWellInfo<Scalar>::
|
||||
in_injecting_group(const std::string& wname) const
|
||||
{
|
||||
auto global_well_index = this->name_map.at(wname);
|
||||
return this->m_in_injecting_group[global_well_index];
|
||||
}
|
||||
|
||||
|
||||
bool GlobalWellInfo::in_producing_group(const std::string& wname) const {
|
||||
template<class Scalar>
|
||||
bool GlobalWellInfo<Scalar>::
|
||||
in_producing_group(const std::string& wname) const
|
||||
{
|
||||
auto global_well_index = this->name_map.at(wname);
|
||||
return this->m_in_producing_group[global_well_index];
|
||||
}
|
||||
|
||||
bool GlobalWellInfo::is_open(const std::string& wname) const {
|
||||
template<class Scalar>
|
||||
bool GlobalWellInfo<Scalar>::
|
||||
is_open(const std::string& wname) const
|
||||
{
|
||||
auto global_well_index = this->name_map.at(wname);
|
||||
return this->m_is_open[global_well_index];
|
||||
}
|
||||
|
||||
void GlobalWellInfo::update_injector(std::size_t well_index, Well::Status well_status, Well::InjectorCMode injection_cmode) {
|
||||
template<class Scalar>
|
||||
void GlobalWellInfo<Scalar>::
|
||||
update_injector(std::size_t well_index,
|
||||
Well::Status well_status,
|
||||
Well::InjectorCMode injection_cmode)
|
||||
{
|
||||
if (well_status == Well::Status::OPEN) {
|
||||
this->m_is_open[this->local_map[well_index]] = 1;
|
||||
if (injection_cmode == Well::InjectorCMode::GRUP) {
|
||||
@ -73,7 +88,12 @@ void GlobalWellInfo::update_injector(std::size_t well_index, Well::Status well_s
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalWellInfo::update_producer(std::size_t well_index, Well::Status well_status, Well::ProducerCMode production_cmode) {
|
||||
template<class Scalar>
|
||||
void GlobalWellInfo<Scalar>::
|
||||
update_producer(std::size_t well_index,
|
||||
Well::Status well_status,
|
||||
Well::ProducerCMode production_cmode)
|
||||
{
|
||||
if (well_status == Well::Status::OPEN) {
|
||||
this->m_is_open[this->local_map[well_index]] = 1;
|
||||
if (production_cmode == Well::ProducerCMode::GRUP) {
|
||||
@ -82,22 +102,53 @@ void GlobalWellInfo::update_producer(std::size_t well_index, Well::Status well_s
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalWellInfo::clear() {
|
||||
template<class Scalar>
|
||||
void GlobalWellInfo<Scalar>::
|
||||
update_efficiency_scaling_factor(std::size_t well_index,
|
||||
const Scalar efficiency_scaling_factor)
|
||||
{
|
||||
this->m_efficiency_scaling_factors[this->local_map[well_index]] = efficiency_scaling_factor;
|
||||
}
|
||||
|
||||
template<class Scalar>
|
||||
void GlobalWellInfo<Scalar>::clear()
|
||||
{
|
||||
this->m_in_injecting_group.assign(this->name_map.size(), 0);
|
||||
this->m_in_producing_group.assign(this->name_map.size(), 0);
|
||||
this->m_is_open.assign(this->name_map.size(), 0);
|
||||
this->m_efficiency_scaling_factors.assign(this->name_map.size(), 1.0);
|
||||
}
|
||||
|
||||
template<class Scalar>
|
||||
Scalar GlobalWellInfo<Scalar>::
|
||||
efficiency_scaling_factor(const std::string& wname) const
|
||||
{
|
||||
auto global_well_index = this->name_map.at(wname);
|
||||
return this->m_efficiency_scaling_factors[global_well_index];
|
||||
}
|
||||
|
||||
std::size_t GlobalWellInfo::well_index(const std::string& wname) const {
|
||||
template<class Scalar>
|
||||
std::size_t GlobalWellInfo<Scalar>::
|
||||
well_index(const std::string& wname) const
|
||||
{
|
||||
return this->name_map.at(wname);
|
||||
}
|
||||
|
||||
const std::string& GlobalWellInfo::well_name(std::size_t well_index) const {
|
||||
template<class Scalar>
|
||||
const std::string& GlobalWellInfo<Scalar>::
|
||||
well_name(std::size_t well_index) const
|
||||
{
|
||||
for (const auto& [name, index] : this->name_map) {
|
||||
if (index == well_index)
|
||||
return name;
|
||||
}
|
||||
throw std::logic_error("No well with index: " + std::to_string(well_index));
|
||||
}
|
||||
|
||||
template class GlobalWellInfo<double>;
|
||||
|
||||
#if FLOW_INSTANTIATE_FLOAT
|
||||
template class GlobalWellInfo<float>;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ enum class WellStatus;
|
||||
under group control.
|
||||
*/
|
||||
|
||||
|
||||
template<class Scalar>
|
||||
class GlobalWellInfo {
|
||||
public:
|
||||
|
||||
@ -64,6 +64,7 @@ public:
|
||||
comm.sum( this->m_in_injecting_group.data(), size);
|
||||
comm.sum( this->m_in_producing_group.data(), size);
|
||||
comm.sum( this->m_is_open.data(), size);
|
||||
comm.min( this->m_efficiency_scaling_factors.data(), size);
|
||||
}
|
||||
|
||||
|
||||
@ -76,6 +77,8 @@ public:
|
||||
const std::string& well_name(std::size_t well_index) const;
|
||||
void update_injector(std::size_t well_index, WellStatus well_status, WellInjectorCMode injection_cmode);
|
||||
void update_producer(std::size_t well_index, WellStatus well_status, WellProducerCMode production_cmode);
|
||||
void update_efficiency_scaling_factor(std::size_t well_index, const Scalar efficiency_scaling_factor);
|
||||
Scalar efficiency_scaling_factor(const std::string& wname) const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
@ -85,6 +88,7 @@ private:
|
||||
std::vector<int> m_in_injecting_group; // global_index -> int/bool
|
||||
std::vector<int> m_in_producing_group; // global_index -> int/bool
|
||||
std::vector<int> m_is_open; // global_index -> int/bool
|
||||
std::vector<Scalar> m_efficiency_scaling_factors; // global_index --> double
|
||||
};
|
||||
|
||||
|
||||
|
@ -873,7 +873,7 @@ computeNetworkPressures(const Network::ExtNetwork& network,
|
||||
// available and using those (for wells with WEFAC(3) true only) when accumulating group
|
||||
// rates, but ONLY for network calculations.
|
||||
const Scalar efficiency = well.getEfficiencyFactor() *
|
||||
well_state[well.name()].efficiency_scaling_factor;
|
||||
well_state.getGlobalEfficiencyScalingFactor(wellname);
|
||||
node_inflows[node][BlackoilPhases::Vapour] += well_state.getALQ(wellname) * efficiency;
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ void WellState<Scalar>::init(const std::vector<Scalar>& cellPressures,
|
||||
this->base_init(cellPressures, cellTemperatures, wells_ecl, parallel_well_info,
|
||||
well_perf_data, summary_state);
|
||||
this->enableDistributedWells_ = enableDistributedWells;
|
||||
this->global_well_info = std::make_optional<GlobalWellInfo>(schedule,
|
||||
this->global_well_info = std::make_optional<GlobalWellInfo<Scalar>>(schedule,
|
||||
report_step,
|
||||
wells_ecl);
|
||||
well_rates.clear();
|
||||
@ -969,6 +969,7 @@ void WellState<Scalar>::updateGlobalIsGrup(const Parallel::Communication& comm)
|
||||
this->global_well_info.value().clear();
|
||||
for (std::size_t well_index = 0; well_index < this->size(); well_index++) {
|
||||
const auto& ws = this->well(well_index);
|
||||
this->global_well_info.value().update_efficiency_scaling_factor(well_index, ws.efficiency_scaling_factor);
|
||||
if (ws.producer)
|
||||
this->global_well_info.value().update_producer(well_index, ws.status, ws.production_cmode);
|
||||
else
|
||||
@ -977,6 +978,16 @@ void WellState<Scalar>::updateGlobalIsGrup(const Parallel::Communication& comm)
|
||||
this->global_well_info.value().communicate(comm);
|
||||
}
|
||||
|
||||
template<class Scalar>
|
||||
void WellState<Scalar>::
|
||||
updateEfficiencyScalingFactor(const std::string& wellName,
|
||||
const Scalar value)
|
||||
{
|
||||
const auto idx = this->index(wellName);
|
||||
this->global_well_info.value().update_efficiency_scaling_factor(*idx, value);
|
||||
this->well(*idx).efficiency_scaling_factor = value;
|
||||
}
|
||||
|
||||
template<class Scalar>
|
||||
data::Segment
|
||||
WellState<Scalar>::reportSegmentResults(const int well_id,
|
||||
|
@ -164,6 +164,8 @@ public:
|
||||
void communicateGroupRates(const Parallel::Communication& comm);
|
||||
|
||||
void updateGlobalIsGrup(const Parallel::Communication& comm);
|
||||
void updateEfficiencyScalingFactor(const std::string& wellName,
|
||||
const Scalar value);
|
||||
|
||||
bool isInjectionGrup(const std::string& name) const
|
||||
{
|
||||
@ -180,6 +182,11 @@ public:
|
||||
return this->global_well_info.value().is_open(name);
|
||||
}
|
||||
|
||||
Scalar getGlobalEfficiencyScalingFactor(const std::string& name) const
|
||||
{
|
||||
return this->global_well_info.value().efficiency_scaling_factor(name);
|
||||
}
|
||||
|
||||
Scalar getALQ(const std::string& name) const
|
||||
{
|
||||
return this->alq_state.get(name);
|
||||
@ -373,7 +380,7 @@ private:
|
||||
// Use of std::optional<> here is a technical crutch, the
|
||||
// WellStateFullyImplicitBlackoil class should be default constructible,
|
||||
// whereas the GlobalWellInfo is not.
|
||||
std::optional<GlobalWellInfo> global_well_info;
|
||||
std::optional<GlobalWellInfo<Scalar>> global_well_info;
|
||||
ALQState<Scalar> alq_state;
|
||||
|
||||
// The well_rates variable is defined for all wells on all processors. The
|
||||
|
Loading…
Reference in New Issue
Block a user