Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit communication of group state to actually changed vectors #5711

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 59 additions & 53 deletions opm/simulators/wells/BlackoilWellModelGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ prepareDeserialize(int report_step, const std::size_t numCells, bool handle_ms_w
this->well_perf_data_, this->summaryState_);

}
this->wellState().clearWellRates();
this->wellState().clearWellRatesForGuideRate();
this->commitWGState();
this->updateNupcolWGState();
}
Expand Down Expand Up @@ -1199,13 +1199,66 @@ updateAndCommunicateGroupData(const int reportStepIdx,
// before we copy to well_state_nupcol_.
this->wellState().updateGlobalIsGrup(comm_);

if (iterationIdx < nupcol) {
const bool update_nupcol = iterationIdx < nupcol;
if (update_nupcol) {
this->updateNupcolWGState();
}


auto& well_state = this->wellState();
const auto& well_state_nupcol = this->nupcolWellState();

if (iterationIdx == 0) {
// We use the rates from the previous time-step to reduce oscillations
WellGroupHelpers<Scalar>::updateWellRatesForGuideRate(fieldGroup,
schedule(),
reportStepIdx,
this->prevWellState(),
well_state);

// Set ALQ for off-process wells to zero
for (const auto& wname : schedule().wellNames(reportStepIdx)) {
const bool is_producer = schedule().getWell(wname, reportStepIdx).isProducer();
const bool not_on_this_process = !well_state.has(wname);
if (is_producer && not_on_this_process) {
well_state.setALQ(wname, 0.0);
}
}

well_state.communicateWellRatesForGuideRate(comm_);
}

if (update_nupcol) {
WellGroupHelpers<Scalar>::updateREINForGroups(fieldGroup,
schedule(),
reportStepIdx,
phase_usage_,
summaryState_,
well_state,
this->groupState(),
comm_.rank() == 0);
WellGroupHelpers<Scalar>::updateVREPForGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state,
this->groupState());

WellGroupHelpers<Scalar>::updateReservoirRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state,
this->groupState());
WellGroupHelpers<Scalar>::updateSurfaceRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state,
this->groupState());

WellGroupHelpers<Scalar>::updateGroupProductionRates(fieldGroup,
schedule(),
reportStepIdx,
well_state,
this->groupState());
}

// the group target reduction rates needs to be update since wells may have switched to/from GRUP control
// The group target reduction does not honor NUPCOL.
std::vector<Scalar> groupTargetReduction(numPhases(), 0.0);
Expand All @@ -1229,55 +1282,8 @@ updateAndCommunicateGroupData(const int reportStepIdx,
this->groupState(),
groupTargetReductionInj);

WellGroupHelpers<Scalar>::updateREINForGroups(fieldGroup,
schedule(),
reportStepIdx,
phase_usage_,
summaryState_,
well_state_nupcol,
this->groupState(),
comm_.rank() == 0);
WellGroupHelpers<Scalar>::updateVREPForGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());

WellGroupHelpers<Scalar>::updateReservoirRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers<Scalar>::updateSurfaceRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());

WellGroupHelpers<Scalar>::updateGroupProductionRates(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());

// We use the rates from the previous time-step to reduce oscillations
WellGroupHelpers<Scalar>::updateWellRates(fieldGroup,
schedule(),
reportStepIdx,
this->prevWellState(),
well_state);

// Set ALQ for off-process wells to zero
for (const auto& wname : schedule().wellNames(reportStepIdx)) {
const bool is_producer = schedule().getWell(wname, reportStepIdx).isProducer();
const bool not_on_this_process = !well_state.has(wname);
if (is_producer && not_on_this_process) {
well_state.setALQ(wname, 0.0);
}
}

well_state.communicateGroupRates(comm_);
this->groupState().communicate_rates(comm_);
// well_state.communicateGroupRates(comm_);
this->groupState().communicate_rates(comm_, update_nupcol);
}

template<class Scalar>
Expand Down
6 changes: 3 additions & 3 deletions opm/simulators/wells/BlackoilWellModelGuideRates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ getGuideRateValues(const Well& well) const
}

const auto qs = WellGroupHelpers<Scalar>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
getWellGuideRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);

this->getGuideRateValues(qs, well.isInjector(), wname, grval);

Expand Down Expand Up @@ -358,7 +358,7 @@ getGuideRateValues(const Group& group) const
}

const auto qs = WellGroupHelpers<Scalar>::
getProductionGroupRateVector(wellModel_.groupState(), wellModel_.phaseUsage(), gname);
getProductionGroupGuideRateVector(wellModel_.groupState(), wellModel_.phaseUsage(), gname);

const auto is_inj = false; // This procedure only applies to G*PGR.
this->getGuideRateValues(qs, is_inj, gname, grval);
Expand Down Expand Up @@ -438,7 +438,7 @@ assignWellGuideRates(data::Wells& wsrpt,
|| RetrieveWellGuideRate{wellModel_.guideRate(), wname};

const auto qs = WellGroupHelpers<Scalar>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
getWellGuideRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);

auto getGR = [this, &wname, &qs](const GuideRateModel::Target t)
{
Expand Down
1 change: 1 addition & 0 deletions opm/simulators/wells/BlackoilWellModel_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,7 @@ namespace Opm {
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "updateWellControlsAndNetworkIteration() failed: ",
this->terminal_output_, grid().comm());

// guideRateUpdateIsNeeded - only required at start of time step?
//update guide rates
const int reportStepIdx = simulator_.episodeIndex();
if (alq_updated || BlackoilWellModelGuideRates(*this).
Expand Down
6 changes: 3 additions & 3 deletions opm/simulators/wells/FractionCalculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ guideRate(const std::string& name,
} else {
if (groupControlledWells(name, always_included_child) > 0) {
if (is_producer_ && guide_rate_->has(name)) {
return guide_rate_->get(name, target_, getGroupRateVector(name));
return guide_rate_->get(name, target_, getGroupGuideRateVector(name));
} else if (!is_producer_ && guide_rate_->has(name, injection_phase_)) {
return guide_rate_->get(name, injection_phase_);
} else {
Expand Down Expand Up @@ -183,10 +183,10 @@ groupControlledWells(const std::string& group_name,

template<class Scalar>
GuideRate::RateVector FractionCalculator<Scalar>::
getGroupRateVector(const std::string& group_name)
getGroupGuideRateVector(const std::string& group_name)
{
assert(is_producer_);
return WellGroupHelpers<Scalar>::getProductionGroupRateVector(this->group_state_,
return WellGroupHelpers<Scalar>::getProductionGroupGuideRateVector(this->group_state_,
this->pu_,
group_name);
}
Expand Down
2 changes: 1 addition & 1 deletion opm/simulators/wells/FractionCalculator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class FractionCalculator
const std::string& always_included_child);
int groupControlledWells(const std::string& group_name,
const std::string& always_included_child);
GuideRate::RateVector getGroupRateVector(const std::string& group_name);
GuideRate::RateVector getGroupGuideRateVector(const std::string& group_name);
const Schedule& schedule_;
const WellState<Scalar>& well_state_;
const GroupState<Scalar>& group_state_;
Expand Down
30 changes: 20 additions & 10 deletions opm/simulators/wells/GroupState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class GroupState {
GPMaint::State& gpmaint(const std::string& gname);

template<class Comm>
void communicate_rates(const Comm& comm)
void communicate_rates(const Comm& comm, const bool update_nupcol)
{
// Note that injection_group_vrep_rates is handled separate from
// the forAllGroupData() function, since it contains single doubles,
Expand All @@ -128,12 +128,14 @@ class GroupState {


auto forAllGroupData = [&](auto& func) {
iterateContainer(m_production_rates, func);
iterateContainer(prod_red_rates, func);
iterateContainer(inj_red_rates, func);
iterateContainer(inj_resv_rates, func);
iterateContainer(inj_rein_rates, func);
iterateContainer(inj_surface_rates, func);
if (update_nupcol) {
iterateContainer(m_production_rates, func);
iterateContainer(inj_resv_rates, func);
iterateContainer(inj_rein_rates, func);
iterateContainer(inj_surface_rates, func);
}
};

// Compute the size of the data.
Expand All @@ -142,7 +144,9 @@ class GroupState {
sz += v.size();
};
forAllGroupData(computeSize);
sz += this->inj_vrep_rate.size();
if (update_nupcol) {
sz += this->inj_vrep_rate.size();
}

// Make a vector and collect all data into it.
std::vector<Scalar> data(sz);
Expand All @@ -157,9 +161,12 @@ class GroupState {
}
};
forAllGroupData(collect);
for (const auto& x : this->inj_vrep_rate) {
data[pos++] = x.second;
if (update_nupcol) {
for (const auto& x : this->inj_vrep_rate) {
data[pos++] = x.second;
}
}

if (pos != sz)
throw std::logic_error("Internal size mismatch when collecting groupData");

Expand All @@ -174,9 +181,12 @@ class GroupState {
}
};
forAllGroupData(distribute);
for (auto& x : this->inj_vrep_rate) {
x.second = data[pos++];
if (update_nupcol) {
for (auto& x : this->inj_vrep_rate) {
x.second = data[pos++];
}
}

if (pos != sz)
throw std::logic_error("Internal size mismatch when distributing groupData");
}
Expand Down
26 changes: 13 additions & 13 deletions opm/simulators/wells/WellGroupHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,15 +626,15 @@ updateSurfaceRatesInjectionGroups(const Group& group,

template<class Scalar>
void WellGroupHelpers<Scalar>::
updateWellRates(const Group& group,
updateWellRatesForGuideRate(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const WellState<Scalar>& wellStateNupcol,
const WellState<Scalar>& guiderateWellState,
WellState<Scalar>& wellState)
{
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateWellRates(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState);
updateWellRatesForGuideRate(groupTmp, schedule, reportStepIdx, guiderateWellState, wellState);
}
const int np = wellState.numPhases();
for (const std::string& wellName : group.wells()) {
Expand All @@ -643,16 +643,16 @@ updateWellRates(const Group& group,
if (well_index.has_value()) { // the well is found on this node
const auto& wellTmp = schedule.getWell(wellName, reportStepIdx);
int sign = 1;
// production wellRates are negative. The users of currentWellRates uses the convention in
// opm-common that production and injection rates are positive.
// production wellRates are negative. The users of wellRatesForGuideRate use
// the convention in opm-common that production and injection rates are positive.
if (!wellTmp.isInjector())
sign = -1;
const auto& ws = wellStateNupcol.well(well_index.value());
const auto& ws = guiderateWellState.well(well_index.value());
for (int phase = 0; phase < np; ++phase) {
rates[phase] = sign * ws.surface_rates[phase];
}
}
wellState.setCurrentWellRates(wellName, rates);
wellState.setWellRatesForGuideRate(wellName, rates);
}
}

Expand Down Expand Up @@ -955,17 +955,17 @@ computeNetworkPressures(const Network::ExtNetwork& network,
template<class Scalar>
GuideRate::RateVector
WellGroupHelpers<Scalar>::
getWellRateVector(const WellState<Scalar>& well_state,
getWellGuideRateVector(const WellState<Scalar>& well_state,
const PhaseUsage& pu,
const std::string& name)
{
return getGuideRateVector(well_state.currentWellRates(name), pu);
return getGuideRateVector(well_state.getWellRatesForGuideRate(name), pu);
}

template<class Scalar>
GuideRate::RateVector
WellGroupHelpers<Scalar>::
getProductionGroupRateVector(const GroupState<Scalar>& group_state,
getProductionGroupGuideRateVector(const GroupState<Scalar>& group_state,
const PhaseUsage& pu,
const std::string& group_name)
{
Expand All @@ -985,14 +985,14 @@ getGuideRate(const std::string& name,
{
if (schedule.hasWell(name, reportStepIdx)) {
if (guideRate->has(name) || guideRate->hasPotentials(name)) {
return guideRate->get(name, target, getWellRateVector(wellState, pu, name));
return guideRate->get(name, target, getWellGuideRateVector(wellState, pu, name));
} else {
return 0.0;
}
}

if (guideRate->has(name)) {
return guideRate->get(name, target, getProductionGroupRateVector(group_state, pu, name));
return guideRate->get(name, target, getProductionGroupGuideRateVector(group_state, pu, name));
}

Scalar totalGuideRate = 0.0;
Expand Down Expand Up @@ -1074,7 +1074,7 @@ getGuideRateInj(const std::string& name,
if (!wellState.isInjectionGrup(wellName))
continue;

totalGuideRate += guideRate->get(wellName, target, getWellRateVector(wellState, pu, wellName));
totalGuideRate += guideRate->get(wellName, target, getWellGuideRateVector(wellState, pu, wellName));
}
return totalGuideRate;
}
Expand Down
8 changes: 4 additions & 4 deletions opm/simulators/wells/WellGroupHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,10 @@ class WellGroupHelpers
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state);

static void updateWellRates(const Group& group,
static void updateWellRatesForGuideRate(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const WellState<Scalar>& wellStateNupcol,
const WellState<Scalar>& guiderateWellState,
WellState<Scalar>& wellState);

static void updateGroupProductionRates(const Group& group,
Expand Down Expand Up @@ -207,12 +207,12 @@ class WellGroupHelpers
const int report_time_step);

static GuideRate::RateVector
getWellRateVector(const WellState<Scalar>& well_state,
getWellGuideRateVector(const WellState<Scalar>& well_state,
const PhaseUsage& pu,
const std::string& name);

static GuideRate::RateVector
getProductionGroupRateVector(const GroupState<Scalar>& group_state,
getProductionGroupGuideRateVector(const GroupState<Scalar>& group_state,
const PhaseUsage& pu,
const std::string& group_name);

Expand Down
Loading