WellGroupHelpers: template Scalar type

This commit is contained in:
Arne Morten Kvarving 2024-02-19 13:47:25 +01:00
parent 522625aca8
commit aa03d06c4d
10 changed files with 683 additions and 462 deletions

View File

@ -74,7 +74,12 @@ checkGroupInjectionConstraints(const Group& group,
if (currentControl != Group::InjectionCMode::RATE)
{
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
phasePos,
/*isInjector*/true);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
@ -98,7 +103,12 @@ checkGroupInjectionConstraints(const Group& group,
if (currentControl != Group::InjectionCMode::RESV)
{
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellResRates(group, wellModel_.schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
current_rate += WellGroupHelpers<double>::sumWellResRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
phasePos,
/*isInjector*/true);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
@ -123,17 +133,23 @@ checkGroupInjectionConstraints(const Group& group,
double production_Rate = 0.0;
const auto& controls = group.injectionControls(phase, wellModel_.summaryState());
const Group& groupRein = wellModel_.schedule().getGroup(controls.reinj_group, reportStepIdx);
production_Rate += WellGroupHelpers::sumWellSurfaceRates(groupRein, wellModel_.schedule(),
well_state, reportStepIdx,
phasePos, /*isInjector*/false);
production_Rate += WellGroupHelpers<double>::sumWellSurfaceRates(groupRein,
wellModel_.schedule(),
well_state,
reportStepIdx,
phasePos,
/*isInjector*/false);
// sum over all nodes
production_Rate = wellModel_.comm().sum(production_Rate);
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
phasePos, /*isInjector*/true);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
phasePos,
/*isInjector*/true);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
@ -153,29 +169,46 @@ checkGroupInjectionConstraints(const Group& group,
double voidage_rate = 0.0;
const auto& controls = group.injectionControls(phase, wellModel_.summaryState());
const Group& groupVoidage = wellModel_.schedule().getGroup(controls.voidage_group, reportStepIdx);
voidage_rate += WellGroupHelpers::sumWellResRates(groupVoidage, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], false);
voidage_rate += WellGroupHelpers::sumWellResRates(groupVoidage, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], false);
voidage_rate += WellGroupHelpers::sumWellResRates(groupVoidage, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour], false);
voidage_rate += WellGroupHelpers<double>::sumWellResRates(groupVoidage,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua],
false);
voidage_rate += WellGroupHelpers<double>::sumWellResRates(groupVoidage,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid],
false);
voidage_rate += WellGroupHelpers<double>::sumWellResRates(groupVoidage,
wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour],
false);
// sum over all nodes
voidage_rate = wellModel_.comm().sum(voidage_rate);
double total_rate = 0.0;
total_rate += WellGroupHelpers::sumWellResRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], true);
total_rate += WellGroupHelpers::sumWellResRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], true);
total_rate += WellGroupHelpers::sumWellResRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour], true);
total_rate += WellGroupHelpers<double>::sumWellResRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua],
true);
total_rate += WellGroupHelpers<double>::sumWellResRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid],
true);
total_rate += WellGroupHelpers<double>::sumWellResRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour],
true);
// sum over all nodes
total_rate = wellModel_.comm().sum(total_rate);
@ -208,9 +241,12 @@ checkGroupProductionConstraints(const Group& group,
if (currentControl != Group::ProductionCMode::ORAT)
{
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], false);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid],
false);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
@ -228,11 +264,13 @@ checkGroupProductionConstraints(const Group& group,
{
if (currentControl != Group::ProductionCMode::WRAT)
{
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], false);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua],
false);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
@ -250,9 +288,12 @@ checkGroupProductionConstraints(const Group& group,
if (currentControl != Group::ProductionCMode::GRAT)
{
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour], false);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour],
false);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
@ -269,21 +310,30 @@ checkGroupProductionConstraints(const Group& group,
if (currentControl != Group::ProductionCMode::LRAT)
{
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], false);
current_rate += WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], false);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid],
false);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua],
false);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
bool skip = false;
if (controls.liquid_target == controls.oil_target) {
double current_water_rate = WellGroupHelpers::sumWellSurfaceRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], false);
double current_water_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua],
false);
current_water_rate = wellModel_.comm().sum(current_water_rate);
if (std::abs(current_water_rate) < 1e-12) {
skip = true;
@ -309,15 +359,24 @@ checkGroupProductionConstraints(const Group& group,
if (currentControl != Group::ProductionCMode::RESV)
{
double current_rate = 0.0;
current_rate += WellGroupHelpers::sumWellResRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], false);
current_rate += WellGroupHelpers::sumWellResRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], false);
current_rate += WellGroupHelpers::sumWellResRates(group, wellModel_.schedule(),
well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour], false);
current_rate += WellGroupHelpers<double>::sumWellResRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua],
false);
current_rate += WellGroupHelpers<double>::sumWellResRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid],
false);
current_rate += WellGroupHelpers<double>::sumWellResRates(group,
wellModel_.schedule(),
well_state,
reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour],
false);
// sum over all nodes
current_rate = wellModel_.comm().sum(current_rate);
@ -457,11 +516,10 @@ actionOnBrokenConstraints(const Group& group,
break;
}
case Group::ExceedAction::WELL: {
std::tie(worst_offending_well, std::ignore) =
WellGroupHelpers::worstOffendingWell(group, wellModel_.schedule(), reportStepIdx,
newControl, wellModel_.phaseUsage(),
wellModel_.comm(), well_state, deferred_logger);
WellGroupHelpers<double>::worstOffendingWell(group, wellModel_.schedule(), reportStepIdx,
newControl, wellModel_.phaseUsage(),
wellModel_.comm(), well_state, deferred_logger);
break;
}
case Group::ExceedAction::PLUG: {
@ -520,13 +578,13 @@ updateGroupIndividualControl(const Group& group,
Group::InjectionCMode2String(changed_this.first));
this->actionOnBrokenConstraints(group, changed_this.first, phase,
group_state, deferred_logger);
WellGroupHelpers::updateWellRatesFromGroupTargetScale(changed_this.second,
group,
wellModel_.schedule(),
reportStepIdx,
/* isInjector */ false,
wellModel_.groupState(),
well_state);
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(changed_this.second,
group,
wellModel_.schedule(),
reportStepIdx,
/* isInjector */ false,
wellModel_.groupState(),
well_state);
changed = true;
}
}
@ -549,13 +607,13 @@ updateGroupIndividualControl(const Group& group,
if(changed) {
switched_prod.insert_or_assign(group.name(),
Group::ProductionCMode2String(changed_this.first));
WellGroupHelpers::updateWellRatesFromGroupTargetScale(changed_this.second,
group,
wellModel_.schedule(),
reportStepIdx,
/* isInjector */ false,
wellModel_.groupState(),
well_state);
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(changed_this.second,
group,
wellModel_.schedule(),
reportStepIdx,
/* isInjector */ false,
wellModel_.groupState(),
well_state);
} else if (worst_offending_well) {
closed_offending_wells.insert_or_assign(group.name(),
std::make_pair(Group::ProductionCMode2String(changed_this.first), *worst_offending_well));

View File

@ -450,8 +450,18 @@ checkGconsaleLimits(const Group& group,
const Group::ProductionCMode& oldProductionControl = this->groupState().production_control(group.name());
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
double production_rate = WellGroupHelpers::sumWellSurfaceRates(group, schedule(), well_state, reportStepIdx, gasPos, /*isInjector*/false);
double injection_rate = WellGroupHelpers::sumWellSurfaceRates(group, schedule(), well_state, reportStepIdx, gasPos, /*isInjector*/true);
double production_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group,
schedule(),
well_state,
reportStepIdx,
gasPos,
/*isInjector*/false);
double injection_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group,
schedule(),
well_state,
reportStepIdx,
gasPos,
/*isInjector*/true);
// sum over all nodes
injection_rate = comm_.sum(injection_rate);
@ -585,7 +595,12 @@ checkGroupHigherConstraints(const Group& group,
calcInjRates(fipnum, pvtreg, resv_coeff_inj);
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
const double local_current_rate = WellGroupHelpers::sumWellSurfaceRates(group, schedule(), this->wellState(), reportStepIdx, phasePos, /* isInjector */ true);
const double local_current_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group,
schedule(),
this->wellState(),
reportStepIdx,
phasePos,
/* isInjector */ true);
// Sum over all processes
rates[phasePos] = comm_.sum(local_current_rate);
}
@ -595,29 +610,35 @@ checkGroupHigherConstraints(const Group& group,
auto currentControl = this->groupState().injection_control(group.name(), phase);
if (currentControl != Group::InjectionCMode::FLD && group.injectionGroupControlAvailable(phase)) {
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
const auto [is_changed, scaling_factor] = WellGroupHelpers::checkGroupConstraintsInj(
group.name(),
group.parent(),
parentGroup,
this->wellState(),
this->groupState(),
reportStepIdx,
&guideRate_,
rates.data(),
phase,
phase_usage_,
group.getGroupEfficiencyFactor(),
schedule(),
summaryState_,
resv_coeff_inj,
deferred_logger);
const auto [is_changed, scaling_factor] =
WellGroupHelpers<double>::checkGroupConstraintsInj(group.name(),
group.parent(),
parentGroup,
this->wellState(),
this->groupState(),
reportStepIdx,
&guideRate_,
rates.data(),
phase,
phase_usage_,
group.getGroupEfficiencyFactor(),
schedule(),
summaryState_,
resv_coeff_inj,
deferred_logger);
if (is_changed) {
switched_inj_groups_.insert_or_assign({group.name(), phase}, Group::InjectionCMode2String(Group::InjectionCMode::FLD));
BlackoilWellModelConstraints(*this).
actionOnBrokenConstraints(group, Group::InjectionCMode::FLD,
phase, this->groupState(),
deferred_logger);
WellGroupHelpers::updateWellRatesFromGroupTargetScale(scaling_factor, group, schedule(), reportStepIdx, /* isInjector */ true, this->groupState(), this->wellState());
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(scaling_factor,
group,
schedule(),
reportStepIdx,
/* isInjector */ true,
this->groupState(),
this->wellState());
changed = true;
}
}
@ -627,7 +648,12 @@ checkGroupHigherConstraints(const Group& group,
if (!isField && group.isProductionGroup()) {
// Obtain rates for group.
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
const double local_current_rate = WellGroupHelpers::sumWellSurfaceRates(group, schedule(), this->wellState(), reportStepIdx, phasePos, /* isInjector */ false);
const double local_current_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group,
schedule(),
this->wellState(),
reportStepIdx,
phasePos,
/* isInjector */ false);
// Sum over all processes
rates[phasePos] = -comm_.sum(local_current_rate);
}
@ -637,21 +663,21 @@ checkGroupHigherConstraints(const Group& group,
const Group::ProductionCMode& currentControl = this->groupState().production_control(group.name());
if (currentControl != Group::ProductionCMode::FLD && group.productionGroupControlAvailable()) {
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
const auto [is_changed, scaling_factor] = WellGroupHelpers::checkGroupConstraintsProd(
group.name(),
group.parent(),
parentGroup,
this->wellState(),
this->groupState(),
reportStepIdx,
&guideRate_,
rates.data(),
phase_usage_,
group.getGroupEfficiencyFactor(),
schedule(),
summaryState_,
resv_coeff,
deferred_logger);
const auto [is_changed, scaling_factor] =
WellGroupHelpers<double>::checkGroupConstraintsProd(group.name(),
group.parent(),
parentGroup,
this->wellState(),
this->groupState(),
reportStepIdx,
&guideRate_,
rates.data(),
phase_usage_,
group.getGroupEfficiencyFactor(),
schedule(),
summaryState_,
resv_coeff,
deferred_logger);
if (is_changed) {
const auto group_limit_action = group.productionControls(summaryState_).group_limit_action;
std::optional<std::string> worst_offending_well = std::nullopt;
@ -664,8 +690,15 @@ checkGroupHigherConstraints(const Group& group,
deferred_logger);
if (changed) {
switched_prod_groups_.insert_or_assign(group.name(), Group::ProductionCMode2String(Group::ProductionCMode::FLD));
WellGroupHelpers::updateWellRatesFromGroupTargetScale(scaling_factor, group, schedule(), reportStepIdx, /* isInjector */ false, this->groupState(), this->wellState());
switched_prod_groups_.insert_or_assign(group.name(),
Group::ProductionCMode2String(Group::ProductionCMode::FLD));
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(scaling_factor,
group,
schedule(),
reportStepIdx,
/* isInjector */ false,
this->groupState(),
this->wellState());
}
}
}
@ -808,8 +841,17 @@ updateWsolvent(const Group& group,
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
const auto& controls = group.injectionControls(Phase::GAS, summaryState_);
const Group& groupRein = schedule_.getGroup(controls.reinj_group, reportStepIdx);
double gasProductionRate = WellGroupHelpers::sumWellSurfaceRates(groupRein, schedule_, wellState, reportStepIdx, gasPos, /*isInjector*/false);
double solventProductionRate = WellGroupHelpers::sumSolventRates(groupRein, schedule_, wellState, reportStepIdx, /*isInjector*/false);
double gasProductionRate = WellGroupHelpers<double>::sumWellSurfaceRates(groupRein,
schedule_,
wellState,
reportStepIdx,
gasPos,
/*isInjector*/false);
double solventProductionRate = WellGroupHelpers<double>::sumSolventRates(groupRein,
schedule_,
wellState,
reportStepIdx,
/*isInjector*/false);
solventProductionRate = comm_.sum(solventProductionRate);
gasProductionRate = comm_.sum(gasProductionRate);
@ -956,12 +998,12 @@ assignNodeValues(std::map<std::string, data::NodeData>& nodevalues, const int re
const auto& network = schedule()[reportStepIdx].network();
if (!network.active()) return;
auto converged_pressures = WellGroupHelpers::computeNetworkPressures(network,
this->wellState(),
this->groupState(),
*(vfp_properties_->getProd()),
schedule(),
reportStepIdx);
auto converged_pressures = WellGroupHelpers<double>::computeNetworkPressures(network,
this->wellState(),
this->groupState(),
*(vfp_properties_->getProd()),
schedule(),
reportStepIdx);
for (const auto& [node, converged_pressure] : converged_pressures) {
auto it = nodevalues.find(node);
assert(it != nodevalues.end() );
@ -1011,20 +1053,63 @@ updateAndCommunicateGroupData(const int reportStepIdx,
// 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<double> groupTargetReduction(numPhases(), 0.0);
WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, phase_usage_, guideRate_, well_state, this->groupState(), groupTargetReduction);
WellGroupHelpers<double>::updateGroupTargetReduction(fieldGroup,
schedule(),
reportStepIdx,
/*isInjector*/ false,
phase_usage_,
guideRate_,
well_state,
this->groupState(),
groupTargetReduction);
std::vector<double> groupTargetReductionInj(numPhases(), 0.0);
WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, phase_usage_, guideRate_, well_state, this->groupState(), groupTargetReductionInj);
WellGroupHelpers<double>::updateGroupTargetReduction(fieldGroup,
schedule(),
reportStepIdx,
/*isInjector*/ true,
phase_usage_,
guideRate_,
well_state,
this->groupState(),
groupTargetReductionInj);
WellGroupHelpers::updateREINForGroups(fieldGroup, schedule(), reportStepIdx, phase_usage_, summaryState_, well_state_nupcol, this->groupState(), comm_.rank()==0);
WellGroupHelpers::updateVREPForGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, this->groupState());
WellGroupHelpers<double>::updateREINForGroups(fieldGroup,
schedule(),
reportStepIdx,
phase_usage_,
summaryState_,
well_state_nupcol,
this->groupState(),
comm_.rank() == 0);
WellGroupHelpers<double>::updateVREPForGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers::updateReservoirRatesInjectionGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, this->groupState());
WellGroupHelpers::updateSurfaceRatesInjectionGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, this->groupState());
WellGroupHelpers<double>::updateReservoirRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers<double>::updateSurfaceRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers::updateGroupProductionRates(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, this->groupState());
WellGroupHelpers<double>::updateGroupProductionRates(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
// We use the rates from the previous time-step to reduce oscillations
WellGroupHelpers::updateWellRates(fieldGroup, schedule(), reportStepIdx, this->prevWellState(), well_state);
WellGroupHelpers<double>::updateWellRates(fieldGroup,
schedule(),
reportStepIdx,
this->prevWellState(),
well_state);
// Set ALQ for off-process wells to zero
for (const auto& wname : schedule().wellNames(reportStepIdx)) {
@ -1151,12 +1236,12 @@ updateNetworkPressures(const int reportStepIdx)
const auto previous_node_pressures = node_pressures_;
node_pressures_ = WellGroupHelpers::computeNetworkPressures(network,
this->wellState(),
this->groupState(),
*(vfp_properties_->getProd()),
schedule(),
reportStepIdx);
node_pressures_ = WellGroupHelpers<double>::computeNetworkPressures(network,
this->wellState(),
this->groupState(),
*(vfp_properties_->getProd()),
schedule(),
reportStepIdx);
// here, the network imbalance is the difference between the previous nodal pressure and the new nodal pressure
double network_imbalance = 0.;
@ -1225,7 +1310,11 @@ calculateEfficiencyFactors(const int reportStepIdx)
for (auto& well : well_container_generic_) {
const Well& wellEcl = well->wellEcl();
double well_efficiency_factor = wellEcl.getEfficiencyFactor();
WellGroupHelpers::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(), reportStepIdx), schedule(), reportStepIdx, well_efficiency_factor);
WellGroupHelpers<double>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(),
reportStepIdx),
schedule(),
reportStepIdx,
well_efficiency_factor);
well->setWellEfficiencyFactor(well_efficiency_factor);
}
}

View File

@ -328,7 +328,7 @@ getGuideRateValues(const Well& well) const
return grval;
}
const auto qs = WellGroupHelpers::
const auto qs = WellGroupHelpers<double>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
this->getGuideRateValues(qs, well.isInjector(), wname, grval);
@ -355,7 +355,7 @@ getGuideRateValues(const Group& group) const
return grval;
}
const auto qs = WellGroupHelpers::
const auto qs = WellGroupHelpers<double>::
getProductionGroupRateVector(wellModel_.groupState(), wellModel_.phaseUsage(), gname);
const auto is_inj = false; // This procedure only applies to G*PGR.
@ -433,7 +433,7 @@ assignWellGuideRates(data::Wells& wsrpt,
const auto get_gr = parent
|| RetrieveWellGuideRate{wellModel_.guideRate(), wname};
const auto qs = WellGroupHelpers::
const auto qs = WellGroupHelpers<double>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
auto getGR = [this, &wname, &qs](const GuideRateModel::Target t)

View File

@ -343,16 +343,16 @@ namespace Opm {
const auto& fieldGroup =
this->schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers::setCmodeGroup(fieldGroup,
this->schedule(),
this->summaryState(),
reportStepIdx,
this->groupState());
WellGroupHelpers<Scalar>::setCmodeGroup(fieldGroup,
this->schedule(),
this->summaryState(),
reportStepIdx,
this->groupState());
// Define per region average pressure calculators for use by
// pressure maintenance groups (GPMAINT keyword).
if (this->schedule()[reportStepIdx].has_gpmaint()) {
WellGroupHelpers::setRegionAveragePressureCalculator
WellGroupHelpers<Scalar>::setRegionAveragePressureCalculator
(fieldGroup,
this->schedule(),
reportStepIdx,
@ -505,10 +505,20 @@ namespace Opm {
//update guide rates
const auto& comm = simulator_.vanguard().grid().comm();
std::vector<double> pot(numPhases(), 0.0);
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers::updateGuideRates(fieldGroup, schedule(), summaryState, this->phase_usage_, reportStepIdx, simulationTime,
this->wellState(), this->groupState(), comm, &this->guideRate_, pot, local_deferredLogger);
std::vector<double> pot(this->numPhases(), 0.0);
const Group& fieldGroup = this->schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers<double>::updateGuideRates(fieldGroup,
this->schedule(),
summaryState,
this->phase_usage_,
reportStepIdx,
simulationTime,
this->wellState(),
this->groupState(),
comm,
&this->guideRate_,
pot,
local_deferredLogger);
std::string exc_msg;
auto exc_type = ExceptionType::NONE;
// update gpmaint targets
@ -517,8 +527,13 @@ namespace Opm {
calculator.second->template defineState<ElementContext>(simulator_);
}
const double dt = simulator_.timeStepSize();
WellGroupHelpers::updateGpMaintTargetForGroups(fieldGroup,
schedule_, regionalAveragePressureCalculator_, reportStepIdx, dt, this->wellState(), this->groupState());
WellGroupHelpers<double>::updateGpMaintTargetForGroups(fieldGroup,
this->schedule_,
regionalAveragePressureCalculator_,
reportStepIdx,
dt,
this->wellState(),
this->groupState());
}
try {
// Compute initial well solution for new wells and injectors that change injection type i.e. WAG.
@ -574,8 +589,11 @@ namespace Opm {
well->init(&phase_usage_, depth_, gravity_, local_num_cells_, B_avg_, true);
double well_efficiency_factor = wellEcl.getEfficiencyFactor();
WellGroupHelpers::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(), timeStepIdx),
schedule(), timeStepIdx, well_efficiency_factor);
WellGroupHelpers<double>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(),
timeStepIdx),
this->schedule(),
timeStepIdx,
well_efficiency_factor);
well->setWellEfficiencyFactor(well_efficiency_factor);
well->setVFPProperties(vfp_properties_.get());
@ -1191,13 +1209,22 @@ namespace Opm {
const double simulationTime = simulator_.time();
const auto& comm = simulator_.vanguard().grid().comm();
const auto& summaryState = simulator_.vanguard().summaryState();
std::vector<double> pot(numPhases(), 0.0);
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers::updateGuideRates(fieldGroup, schedule(), summaryState, this->phase_usage_, reportStepIdx, simulationTime,
this->wellState(), this->groupState(), comm, &this->guideRate_, pot, local_deferredLogger);
std::vector<double> pot(this->numPhases(), 0.0);
const Group& fieldGroup = this->schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers<double>::updateGuideRates(fieldGroup,
this->schedule(),
summaryState,
this->phase_usage_,
reportStepIdx,
simulationTime,
this->wellState(),
this->groupState(),
comm,
&this->guideRate_,
pot,
local_deferredLogger);
}
return {more_network_update, well_group_control_changed};
}

View File

@ -144,8 +144,8 @@ guideRate(const std::string& name,
const std::string& always_included_child)
{
if (schedule_.hasWell(name, report_step_)) {
return WellGroupHelpers::getGuideRate(name, schedule_, well_state_, group_state_,
report_step_, guide_rate_, target_, pu_);
return WellGroupHelpers<Scalar>::getGuideRate(name, schedule_, well_state_, group_state_,
report_step_, guide_rate_, target_, pu_);
} else {
if (groupControlledWells(name, always_included_child) > 0) {
if (is_producer_ && guide_rate_->has(name)) {
@ -171,14 +171,14 @@ int FractionCalculator<Scalar>::
groupControlledWells(const std::string& group_name,
const std::string& always_included_child)
{
return WellGroupHelpers::groupControlledWells(schedule_,
well_state_,
this->group_state_,
report_step_,
group_name,
always_included_child,
is_producer_,
injection_phase_);
return WellGroupHelpers<Scalar>::groupControlledWells(schedule_,
well_state_,
this->group_state_,
report_step_,
group_name,
always_included_child,
is_producer_,
injection_phase_);
}
template<class Scalar>
@ -186,9 +186,9 @@ GuideRate::RateVector FractionCalculator<Scalar>::
getGroupRateVector(const std::string& group_name)
{
assert(is_producer_);
return WellGroupHelpers::getProductionGroupRateVector(this->group_state_,
this->pu_,
group_name);
return WellGroupHelpers<Scalar>::getProductionGroupRateVector(this->group_state_,
this->pu_,
group_name);
}
template class FractionCalculator<double>;

View File

@ -77,9 +77,12 @@ GroupEconomicLimitsChecker(const BlackoilWellModelGeneric& well_model,
auto phase_idx = this->phase_idx_map_[i];
this->phase_idx_reverse_map_[phase_idx] = static_cast<int>(i);
auto phase_pos = this->well_model_.phaseUsage().phase_pos[phase_idx];
Scalar production_rate = WellGroupHelpers::sumWellSurfaceRates(
this->group_, this->schedule_, this->well_state_,
this->report_step_idx_, phase_pos, /*isInjector*/false);
Scalar production_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(this->group_,
this->schedule_,
this->well_state_,
this->report_step_idx_,
phase_pos,
/*isInjector*/false);
this->production_rates_[i] = this->well_model_.comm().sum(production_rate);
}
}

View File

@ -74,21 +74,21 @@ checkGroupConstraintsInj(const Group& group,
const auto& ws = well_state.well(well_.indexOfWell());
// Call check for the well's injection phase.
return WellGroupHelpers::checkGroupConstraintsInj(well_.name(),
well_.wellEcl().groupName(),
group,
well_state,
group_state,
well_.currentStep(),
well_.guideRate(),
ws.surface_rates.data(),
injectionPhase,
well_.phaseUsage(),
efficiencyFactor,
schedule,
summaryState,
resv_coeff,
deferred_logger);
return WellGroupHelpers<double>::checkGroupConstraintsInj(well_.name(),
well_.wellEcl().groupName(),
group,
well_state,
group_state,
well_.currentStep(),
well_.guideRate(),
ws.surface_rates.data(),
injectionPhase,
well_.phaseUsage(),
efficiencyFactor,
schedule,
summaryState,
resv_coeff,
deferred_logger);
}
std::pair<bool, double>
@ -107,20 +107,20 @@ checkGroupConstraintsProd(const Group& group,
rateConverter(0, well_.pvtRegionIdx(), group.name(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS.
const auto& ws = well_state.well(well_.indexOfWell());
return WellGroupHelpers::checkGroupConstraintsProd(well_.name(),
well_.wellEcl().groupName(),
group,
well_state,
group_state,
well_.currentStep(),
well_.guideRate(),
ws.surface_rates.data(),
well_.phaseUsage(),
efficiencyFactor,
schedule,
summaryState,
resv_coeff,
deferred_logger);
return WellGroupHelpers<double>::checkGroupConstraintsProd(well_.name(),
well_.wellEcl().groupName(),
group,
well_state,
group_state,
well_.currentStep(),
well_.guideRate(),
ws.surface_rates.data(),
well_.phaseUsage(),
efficiencyFactor,
schedule,
summaryState,
resv_coeff,
deferred_logger);
}
bool WellGroupConstraints::

View File

@ -173,8 +173,8 @@ getGroupInjectionControl(const Group& group,
const double orig_target = tcalc.groupTarget(ctrl,
deferred_logger);
const auto chain = WellGroupHelpers::groupChainTopBot(well_.name(), group.name(),
schedule, well_.currentStep());
const auto chain = WellGroupHelpers<double>::groupChainTopBot(well_.name(), group.name(),
schedule, well_.currentStep());
// Because 'name' is the last of the elements, and not an ancestor, we subtract one below.
const std::size_t num_ancestors = chain.size() - 1;
double target = orig_target;
@ -306,7 +306,10 @@ getGroupInjectionTargetRate(const Group& group,
const double orig_target = tcalc.groupTarget(ctrl, deferred_logger);
const auto chain = WellGroupHelpers::groupChainTopBot(well_.name(), group.name(), schedule, well_.currentStep());
const auto chain = WellGroupHelpers<double>::groupChainTopBot(well_.name(),
group.name(),
schedule,
well_.currentStep());
// Because 'name' is the last of the elements, and not an ancestor, we subtract one below.
const std::size_t num_ancestors = chain.size() - 1;
double target = orig_target;
@ -417,8 +420,8 @@ void WellGroupControls::getGroupProductionControl(const Group& group,
ctrl = group.productionControls(summaryState);
const double orig_target = tcalc.groupTarget(ctrl, deferred_logger);
const auto chain = WellGroupHelpers::groupChainTopBot(well_.name(), group.name(),
schedule, well_.currentStep());
const auto chain = WellGroupHelpers<double>::groupChainTopBot(well_.name(), group.name(),
schedule, well_.currentStep());
// Because 'name' is the last of the elements, and not an ancestor, we subtract one below.
const std::size_t num_ancestors = chain.size() - 1;
double target = orig_target;
@ -514,8 +517,8 @@ getGroupProductionTargetRate(const Group& group,
ctrl = group.productionControls(summaryState);
const double orig_target = tcalc.groupTarget(ctrl, deferred_logger);
const auto chain = WellGroupHelpers::groupChainTopBot(well_.name(), group.name(),
schedule, well_.currentStep());
const auto chain = WellGroupHelpers<double>::groupChainTopBot(well_.name(), group.name(),
schedule, well_.currentStep());
// Because 'name' is the last of the elements, and not an ancestor, we subtract one below.
const std::size_t num_ancestors = chain.size() - 1;
double target = orig_target;

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,7 @@ class FieldPropsManager;
namespace Network { class ExtNetwork; }
template<class Scalar>
class WellGroupHelpers
{
public:
@ -50,41 +51,41 @@ public:
const Schedule& schedule,
const SummaryState& summaryState,
const int reportStepIdx,
GroupState<double>& group_state);
GroupState<Scalar>& group_state);
static void accumulateGroupEfficiencyFactor(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
double& factor);
Scalar& factor);
static double sumWellSurfaceRates(const Group& group,
static Scalar sumWellSurfaceRates(const Group& group,
const Schedule& schedule,
const WellState<double>& wellState,
const WellState<Scalar>& wellState,
const int reportStepIdx,
const int phasePos,
const bool injector);
/// Returns the name of the worst offending well and its fraction (i.e. violated_phase / preferred_phase)
static std::pair<std::optional<std::string>, double>
static std::pair<std::optional<std::string>, Scalar>
worstOffendingWell(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const Group::ProductionCMode& offendedControl,
const PhaseUsage& pu,
const Parallel::Communication& comm,
const WellState<double>& wellState,
const WellState<Scalar>& wellState,
DeferredLogger& deferred_logger);
static double sumWellResRates(const Group& group,
static Scalar sumWellResRates(const Group& group,
const Schedule& schedule,
const WellState<double>& wellState,
const WellState<Scalar>& wellState,
const int reportStepIdx,
const int phasePos,
const bool injector);
static double sumSolventRates(const Group& group,
static Scalar sumSolventRates(const Group& group,
const Schedule& schedule,
const WellState<double>& wellState,
const WellState<Scalar>& wellState,
const int reportStepIdx,
const bool injector);
@ -94,9 +95,9 @@ public:
const bool isInjector,
const PhaseUsage& pu,
const GuideRate& guide_rate,
const WellState<double>& wellState,
GroupState<double>& group_state,
std::vector<double>& groupTargetReduction);
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state,
std::vector<Scalar>& groupTargetReduction);
static void updateGuideRates(const Group& group,
const Schedule& schedule,
@ -104,29 +105,29 @@ public:
const PhaseUsage& pu,
int report_step,
double sim_time,
WellState<double>& well_state,
const GroupState<double>& group_state,
WellState<Scalar>& well_state,
const GroupState<Scalar>& group_state,
const Parallel::Communication& comm,
GuideRate* guide_rate,
std::vector<double>& pot,
DeferredLogger& deferred_logge);
std::vector<Scalar>& pot,
DeferredLogger& deferred_logger);
static void updateGuideRateForProductionGroups(const Group& group,
const Schedule& schedule,
const PhaseUsage& pu,
const int reportStepIdx,
const double& simTime,
WellState<double>& wellState,
const GroupState<double>& group_state,
WellState<Scalar>& wellState,
const GroupState<Scalar>& group_state,
const Parallel::Communication& comm,
GuideRate* guideRate,
std::vector<double>& pot);
std::vector<Scalar>& pot);
static void updateGuideRatesForWells(const Schedule& schedule,
const PhaseUsage& pu,
const int reportStepIdx,
const double& simTime,
const WellState<double>& wellState,
const WellState<Scalar>& wellState,
const Parallel::Communication& comm,
GuideRate* guideRate);
@ -135,16 +136,16 @@ public:
const SummaryState& summaryState,
const PhaseUsage& pu,
const int reportStepIdx,
const WellState<double>& wellState,
const GroupState<double>& group_state,
const WellState<Scalar>& wellState,
const GroupState<Scalar>& group_state,
GuideRate* guideRate,
DeferredLogger& deferred_logger);
static void updateVREPForGroups(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const WellState<double>& wellState,
GroupState<double>& group_state);
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state);
template <class RegionalValues>
static void updateGpMaintTargetForGroups(const Group& group,
@ -152,81 +153,82 @@ public:
const RegionalValues& regional_values,
const int reportStepIdx,
const double dt,
const WellState<double>& well_state,
GroupState<double>& group_state);
const WellState<Scalar>& well_state,
GroupState<Scalar>& group_state);
static void updateReservoirRatesInjectionGroups(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const WellState<double>& wellState,
GroupState<double>& group_state);
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state);
static void updateSurfaceRatesInjectionGroups(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const WellState<double>& wellState,
GroupState<double>& group_state);
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state);
static void updateWellRates(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const WellState<double>& wellStateNupcol,
WellState<double>& wellState);
const WellState<Scalar>& wellStateNupcol,
WellState<Scalar>& wellState);
static void updateGroupProductionRates(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const WellState<double>& wellState,
GroupState<double>& group_state);
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state);
static void updateWellRatesFromGroupTargetScale(const double scale,
static void updateWellRatesFromGroupTargetScale(const Scalar scale,
const Group& group,
const Schedule& schedule,
const int reportStepIdx,
bool isInjector,
const GroupState<double>& group_state,
WellState<double>& wellState);
const GroupState<Scalar>& group_state,
WellState<Scalar>& wellState);
static void updateREINForGroups(const Group& group,
const Schedule& schedule,
const int reportStepIdx,
const PhaseUsage& pu,
const SummaryState& st,
const WellState<double>& wellState,
GroupState<double>& group_state,
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state,
bool sum_rank);
static std::map<std::string, double>
static std::map<std::string, Scalar>
computeNetworkPressures(const Network::ExtNetwork& network,
const WellState<double>& well_state,
const GroupState<double>& group_state,
const WellState<Scalar>& well_state,
const GroupState<Scalar>& group_state,
const VFPProdProperties& vfp_prod_props,
const Schedule& schedule,
const int report_time_step);
static GuideRate::RateVector
getWellRateVector(const WellState<double>& well_state,
getWellRateVector(const WellState<Scalar>& well_state,
const PhaseUsage& pu,
const std::string& name);
static GuideRate::RateVector
getProductionGroupRateVector(const GroupState<double>& group_state,
getProductionGroupRateVector(const GroupState<Scalar>& group_state,
const PhaseUsage& pu,
const std::string& group_name);
static double getGuideRate(const std::string& name,
static Scalar getGuideRate(const std::string& name,
const Schedule& schedule,
const WellState<double>& wellState,
const GroupState<double>& group_state,
const WellState<Scalar>& wellState,
const GroupState<Scalar>& group_state,
const int reportStepIdx,
const GuideRate* guideRate,
const GuideRateModel::Target target,
const PhaseUsage& pu);
static double getGuideRateInj(const std::string& name,
static Scalar getGuideRateInj(const std::string& name,
const Schedule& schedule,
const WellState<double>& wellState,
const GroupState<double>& group_state,
const WellState<Scalar>& wellState,
const GroupState<Scalar>& group_state,
const int reportStepIdx,
const GuideRate* guideRate,
const GuideRateModel::Target target,
@ -234,29 +236,29 @@ public:
const PhaseUsage& pu);
static int groupControlledWells(const Schedule& schedule,
const WellState<double>& well_state,
const GroupState<double>& group_state,
const WellState<Scalar>& well_state,
const GroupState<Scalar>& group_state,
const int report_step,
const std::string& group_name,
const std::string& always_included_child,
const bool is_production_group,
const Phase injection_phase);
static std::pair<bool, double>
static std::pair<bool, Scalar>
checkGroupConstraintsInj(const std::string& name,
const std::string& parent,
const Group& group,
const WellState<double>& wellState,
const GroupState<double>& group_state,
const WellState<Scalar>& wellState,
const GroupState<Scalar>& group_state,
const int reportStepIdx,
const GuideRate* guideRate,
const double* rates,
const Scalar* rates,
Phase injectionPhase,
const PhaseUsage& pu,
const double efficiencyFactor,
const Scalar efficiencyFactor,
const Schedule& schedule,
const SummaryState& summaryState,
const std::vector<double>& resv_coeff,
const std::vector<Scalar>& resv_coeff,
DeferredLogger& deferred_logger);
static std::vector<std::string>
@ -265,20 +267,20 @@ public:
const Schedule& schedule,
const int report_step);
static std::pair<bool, double>
static std::pair<bool, Scalar>
checkGroupConstraintsProd(const std::string& name,
const std::string& parent,
const Group& group,
const WellState<double>& wellState,
const GroupState<double>& group_state,
const WellState<Scalar>& wellState,
const GroupState<Scalar>& group_state,
const int reportStepIdx,
const GuideRate* guideRate,
const double* rates,
const Scalar* rates,
const PhaseUsage& pu,
const double efficiencyFactor,
const Scalar efficiencyFactor,
const Schedule& schedule,
const SummaryState& summaryState,
const std::vector<double>& resv_coeff,
const std::vector<Scalar>& resv_coeff,
DeferredLogger& deferred_logger);
template <class AverageRegionalPressureType>