Merge pull request #2298 from totto82/muliple-group-inj-phases

Allow for multiple group injection phases
This commit is contained in:
Joakim Hove 2020-02-14 10:31:45 +01:00 committed by GitHub
commit 150dc54e79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 361 additions and 253 deletions

View File

@ -832,6 +832,10 @@ std::size_t packSize(const IntervalTabulated2DFunction<Scalar>& data,
packSize(data.yExtrapolate(), comm);
}
template
std::size_t packSize(const std::map<Phase,Group::GroupInjectionProperties>& data,
Dune::MPIHelper::MPICommunicator comm);
template<class Scalar>
std::size_t packSize(const UniformXTabulated2DFunction<Scalar>& data,
Dune::MPIHelper::MPICommunicator comm)
@ -2169,6 +2173,13 @@ void pack(const std::unordered_map<T1,T2,H,P,A>& data, std::vector<char>& buffer
}
}
template void pack(const std::map<Phase, Group::GroupInjectionProperties>& data,
std::vector<char>& buffer, int& position,
Dune::MPIHelper::MPICommunicator comm);
void pack(const data::Well& data, std::vector<char>& buffer, int& position,
Dune::MPIHelper::MPICommunicator comm)
{
@ -5531,6 +5542,10 @@ void unpack(IOrderSet<T>& data, std::vector<char>& buffer, int& position,
data = IOrderSet<T>(index, storage);
}
template void unpack(std::map<Phase,Group::GroupInjectionProperties>& data,
std::vector<char>& buffer, int& position,
Dune::MPIHelper::MPICommunicator comm);
void unpack(Group::GroupInjectionProperties& data,
std::vector<char>& buffer, int& position,
Dune::MPIHelper::MPICommunicator comm)
@ -5546,6 +5561,7 @@ void unpack(Group::GroupInjectionProperties& data,
unpack(data.injection_controls, buffer, position, comm);
}
void unpack(Group::GroupProductionProperties& data,
std::vector<char>& buffer, int& position,
Dune::MPIHelper::MPICommunicator comm)
@ -5576,7 +5592,7 @@ void unpack(Group& data,
int groupNetVFPTable;
std::string parent;
IOrderSet<std::string> wells, groups;
Group::GroupInjectionProperties injection;
std::map<Phase, Group::GroupInjectionProperties> injection;
Group::GroupProductionProperties production;
unpack(name, buffer, position, comm);

View File

@ -378,7 +378,7 @@ namespace Opm {
void actionOnBrokenConstraints(const Group& group, const Group::ExceedAction& exceed_action, const Group::ProductionCMode& newControl, const int reportStepIdx, Opm::DeferredLogger& deferred_logger);
void actionOnBrokenConstraints(const Group& group, const Group::InjectionCMode& newControl, const int reportStepIdx, Opm::DeferredLogger& deferred_logger);
void actionOnBrokenConstraints(const Group& group, const Group::InjectionCMode& newControl, const Phase& topUpPhase, const int reportStepIdx, Opm::DeferredLogger& deferred_logger);
WellInterfacePtr getWell(const std::string& well_name) const;

View File

@ -1185,12 +1185,11 @@ namespace Opm {
// the group target reduction rates needs to be update since wells may have swicthed to/from GRUP control
// Currently the group targer reduction does not honor NUPCOL
std::vector<double> groupTargetReduction(numPhases(), 0.0);
wellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, well_state_nupcol_, well_state_, groupTargetReduction);
wellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, phase_usage_, well_state_nupcol_, well_state_, groupTargetReduction);
std::vector<double> groupTargetReductionInj(numPhases(), 0.0);
wellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, well_state_nupcol_, well_state_, groupTargetReductionInj);
wellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, phase_usage_, well_state_nupcol_, well_state_, groupTargetReductionInj);
const auto& comm = ebosSimulator_.vanguard().grid().comm();
well_state_.communicateGroupReductionRates(comm);
well_state_.updateGlobalIsGrup(schedule(), reportStepIdx, comm);
const double simulationTime = ebosSimulator_.time();
@ -1202,7 +1201,10 @@ namespace Opm {
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
wellGroupHelpers::updateREINForGroups(fieldGroup, schedule(), reportStepIdx, phase_usage_, summaryState, well_state_nupcol_, well_state_);
wellGroupHelpers::updateVREPForGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol_, well_state_);
well_state_.communicateReinVrep(comm);
wellGroupHelpers::updateReservoirRatesInjectionGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol_, well_state_);
well_state_.communicateGroupRates(comm);
// compute wsolvent fraction for REIN wells
updateWsolvent(fieldGroup, schedule(), reportStepIdx, well_state_nupcol_);
@ -1689,143 +1691,142 @@ namespace Opm {
const int reportStepIdx = ebosSimulator_.episodeIndex();
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
const auto& comm = ebosSimulator_.vanguard().grid().comm();
auto& well_state = well_state_;
auto& well_state = well_state_;
if (group.isInjectionGroup())
{
const Group::InjectionCMode& currentControl = well_state.currentInjectionGroupControl(group.name());
const auto controls = group.injectionControls(summaryState);
int phasePos;
switch (controls.phase) {
case Phase::WATER:
{
phasePos = phase_usage_.phase_pos[BlackoilPhases::Aqua];
break;
}
case Phase::OIL:
{
phasePos = phase_usage_.phase_pos[BlackoilPhases::Liquid];
break;
}
case Phase::GAS:
{
phasePos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
break;
}
default:
throw("Expected WATER, OIL or GAS as type for group injector: " + group.name());
}
if (group.has_control(Group::InjectionCMode::RATE))
{
if (checkCurrentControl || currentControl != Group::InjectionCMode::RATE)
const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS};
for (Phase phase : all) {
if (!group.hasInjectionControl(phase)) {
continue;
}
int phasePos;
if (phase == Phase::GAS && phase_usage_.phase_used[BlackoilPhases::Vapour] )
phasePos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
else if (phase == Phase::OIL && phase_usage_.phase_used[BlackoilPhases::Liquid])
phasePos = phase_usage_.phase_pos[BlackoilPhases::Liquid];
else if (phase == Phase::WATER && phase_usage_.phase_used[BlackoilPhases::Aqua] )
phasePos = phase_usage_.phase_pos[BlackoilPhases::Aqua];
else
continue;
const auto& controls = group.injectionControls(phase, summaryState);
const Group::InjectionCMode& currentControl = well_state.currentInjectionGroupControl(phase, group.name());
if (controls.has_control(Group::InjectionCMode::RATE))
{
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
if (checkCurrentControl || currentControl != Group::InjectionCMode::RATE)
{
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
// sum over all nodes
current_rate = comm.sum(current_rate);
// sum over all nodes
current_rate = comm.sum(current_rate);
if (controls.surface_max_rate < current_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::RATE, reportStepIdx, deferred_logger);
if (controls.surface_max_rate < current_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::RATE, phase, reportStepIdx, deferred_logger);
}
}
}
}
if (group.has_control(Group::InjectionCMode::RESV))
{
if (checkCurrentControl || currentControl != Group::InjectionCMode::RESV)
if (controls.has_control(Group::InjectionCMode::RESV))
{
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
// sum over all nodes
current_rate = comm.sum(current_rate);
if (checkCurrentControl || currentControl != Group::InjectionCMode::RESV)
{
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
// sum over all nodes
current_rate = comm.sum(current_rate);
if (controls.resv_max_rate < current_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::RESV, reportStepIdx, deferred_logger);
if (controls.resv_max_rate < current_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::RESV, phase, reportStepIdx, deferred_logger);
}
}
}}
if (group.has_control(Group::InjectionCMode::REIN))
{
if (checkCurrentControl || currentControl != Group::InjectionCMode::REIN)
}
if (controls.has_control(Group::InjectionCMode::REIN))
{
double production_Rate = 0.0;
const Group& groupRein = schedule().getGroup(controls.reinj_group, reportStepIdx);
production_Rate += wellGroupHelpers::sumWellRates(groupRein, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/false);
if (checkCurrentControl || currentControl != Group::InjectionCMode::REIN)
{
double production_Rate = 0.0;
const Group& groupRein = schedule().getGroup(controls.reinj_group, reportStepIdx);
production_Rate += wellGroupHelpers::sumWellRates(groupRein, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/false);
// sum over all nodes
production_Rate = comm.sum(production_Rate);
// sum over all nodes
production_Rate = comm.sum(production_Rate);
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true);
// sum over all nodes
current_rate = comm.sum(current_rate);
// sum over all nodes
current_rate = comm.sum(current_rate);
if (controls.target_reinj_fraction*production_Rate < current_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::REIN, reportStepIdx, deferred_logger);
if (controls.target_reinj_fraction*production_Rate < current_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::REIN, phase,reportStepIdx, deferred_logger);
}
}
}}
if (group.has_control(Group::InjectionCMode::VREP))
{
if (checkCurrentControl || currentControl != Group::InjectionCMode::VREP)
}
if (controls.has_control(Group::InjectionCMode::VREP))
{
double voidage_rate = 0.0;
const Group& groupVoidage = schedule().getGroup(controls.voidage_group, reportStepIdx);
voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], false);
voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], false);
voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Vapour], false);
if (checkCurrentControl || currentControl != Group::InjectionCMode::VREP)
{
double voidage_rate = 0.0;
const Group& groupVoidage = schedule().getGroup(controls.voidage_group, reportStepIdx);
voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], false);
voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], false);
voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Vapour], false);
// sum over all nodes
voidage_rate = comm.sum(voidage_rate);
// sum over all nodes
voidage_rate = comm.sum(voidage_rate);
double total_rate = 0.0;
total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], true);
total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], true);
total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Vapour], true);
double total_rate = 0.0;
total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], true);
total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], true);
total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Vapour], true);
// sum over all nodes
total_rate = comm.sum(total_rate);
// sum over all nodes
total_rate = comm.sum(total_rate);
if (controls.target_void_fraction*voidage_rate < total_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::VREP, reportStepIdx, deferred_logger);
if (controls.target_void_fraction*voidage_rate < total_rate) {
actionOnBrokenConstraints(group, Group::InjectionCMode::VREP, phase, reportStepIdx, deferred_logger);
}
}
}
}
// Handle GCONSALE
if (schedule().gConSale(reportStepIdx).has(group.name())) {
// Handle GCONSALE
if (schedule().gConSale(reportStepIdx).has(group.name())) {
if (controls.phase != Phase::GAS)
OPM_THROW(std::runtime_error, "Group " + group.name() + " has GCONSALE control but is not a GAS group" );
if (controls.phase != Phase::GAS)
OPM_THROW(std::runtime_error, "Group " + group.name() + " has GCONSALE control but is not a GAS group" );
const auto& gconsale = schedule().gConSale(reportStepIdx).get(group.name(), summaryState);
const auto& gconsale = schedule().gConSale(reportStepIdx).get(group.name(), summaryState);
double sales_rate = 0.0;
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
sales_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, gasPos, /*isInjector*/false);
sales_rate -= wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, gasPos, /*isInjector*/true);
double sales_rate = 0.0;
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
sales_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, gasPos, /*isInjector*/false);
sales_rate -= wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, gasPos, /*isInjector*/true);
// sum over all nodes
sales_rate = comm.sum(sales_rate);
// sum over all nodes
sales_rate = comm.sum(sales_rate);
// add import rate and substract consumption rate for group for gas
if (schedule().gConSump(reportStepIdx).has(group.name())) {
const auto& gconsump = schedule().gConSump(reportStepIdx).get(group.name(), summaryState);
if (phase_usage_.phase_used[BlackoilPhases::Vapour]) {
sales_rate += gconsump.import_rate;
sales_rate -= gconsump.consumption_rate;
// add import rate and substract consumption rate for group for gas
if (schedule().gConSump(reportStepIdx).has(group.name())) {
const auto& gconsump = schedule().gConSump(reportStepIdx).get(group.name(), summaryState);
if (phase_usage_.phase_used[BlackoilPhases::Vapour]) {
sales_rate += gconsump.import_rate;
sales_rate -= gconsump.consumption_rate;
}
}
if (sales_rate > gconsale.max_sales_rate) {
OPM_THROW(std::runtime_error, "Group " + group.name() + " has sale rate more then the maximum permitted value. Not implemented in Flow" );
}
if (sales_rate < gconsale.min_sales_rate) {
OPM_THROW(std::runtime_error, "Group " + group.name() + " has sale rate less then minimum permitted value. Not implemented in Flow" );
}
if (gconsale.sales_target < 0.0) {
OPM_THROW(std::runtime_error, "Group " + group.name() + " has sale rate target less then zero. Not implemented in Flow" );
}
}
if (sales_rate > gconsale.max_sales_rate) {
OPM_THROW(std::runtime_error, "Group " + group.name() + " has sale rate more then the maximum permitted value. Not implemented in Flow" );
}
if (sales_rate < gconsale.min_sales_rate) {
OPM_THROW(std::runtime_error, "Group " + group.name() + " has sale rate less then minimum permitted value. Not implemented in Flow" );
}
if (gconsale.sales_target < 0.0) {
OPM_THROW(std::runtime_error, "Group " + group.name() + " has sale rate target less then zero. Not implemented in Flow" );
}
}
}
}
if (group.isProductionGroup()) {
@ -1836,15 +1837,15 @@ namespace Opm {
{
if (checkCurrentControl || currentControl != Group::ProductionCMode::ORAT)
{
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], false);
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], false);
// sum over all nodes
current_rate = comm.sum(current_rate);
// sum over all nodes
current_rate = comm.sum(current_rate);
if (controls.oil_target < current_rate ) {
actionOnBrokenConstraints(group, controls.exceed_action, Group::ProductionCMode::ORAT, reportStepIdx, deferred_logger);
}
if (controls.oil_target < current_rate ) {
actionOnBrokenConstraints(group, controls.exceed_action, Group::ProductionCMode::ORAT, reportStepIdx, deferred_logger);
}
}
}
@ -1852,6 +1853,7 @@ namespace Opm {
{
if (checkCurrentControl || currentControl != Group::ProductionCMode::WRAT)
{
double current_rate = 0.0;
current_rate += wellGroupHelpers::sumWellRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], false);
@ -1996,9 +1998,9 @@ namespace Opm {
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
actionOnBrokenConstraints(const Group& group, const Group::InjectionCMode& newControl, const int reportStepIdx, Opm::DeferredLogger& deferred_logger) {
actionOnBrokenConstraints(const Group& group, const Group::InjectionCMode& newControl, const Phase& controlPhase, const int reportStepIdx, Opm::DeferredLogger& deferred_logger) {
auto& well_state = well_state_;
const Group::InjectionCMode& oldControl = well_state.currentInjectionGroupControl(group.name());
const Group::InjectionCMode& oldControl = well_state.currentInjectionGroupControl(controlPhase, group.name());
std::ostringstream ss;
if (oldControl != newControl) {
@ -2010,11 +2012,9 @@ namespace Opm {
if (cc.size() > 1) {
ss << " on rank " << cc.rank();
}
well_state.setCurrentInjectionGroupControl(group.name(), newControl);
well_state.setCurrentInjectionGroupControl(controlPhase, group.name(), newControl);
}
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
const Phase& topUpPhase = group.injectionControls(summaryState).phase;
wellGroupHelpers::setGroupControl(group, schedule(), topUpPhase, reportStepIdx, /*isInjector*/true, well_state, ss);
wellGroupHelpers::setGroupControl(group, schedule(), controlPhase, reportStepIdx, /*isInjector*/true, well_state, ss);
if (!ss.str().empty())
deferred_logger.info(ss.str());
@ -2033,7 +2033,7 @@ namespace Opm {
if (group.isProductionGroup())
return;
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(group.name());
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(Phase::GAS, group.name());
if( currentGroupControl == Group::InjectionCMode::REIN ) {
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
double gasProductionRate = wellGroupHelpers::sumWellRates(group, schedule, wellState, reportStepIdx, gasPos, /*isInjector*/false);

View File

@ -2116,8 +2116,43 @@ namespace Opm
assembleGroupInjectionControl(const Group& group, const WellState& well_state, const Opm::Schedule& schedule, const SummaryState& summaryState, const Well::InjectorType& injectorType, EvalWell& control_eq, double efficiencyFactor, Opm::DeferredLogger& deferred_logger)
{
const auto& well = well_ecl_;
const auto pu = phaseUsage();
const Group::InjectionCMode& currentGroupControl = well_state.currentInjectionGroupControl(group.name());
const auto& pu = phaseUsage();
int phasePos;
Well::GuideRateTarget wellTarget;
Phase injectionPhase;
double scaling = 1.0;
switch (injectorType) {
case Well::InjectorType::WATER:
{
phasePos = pu.phase_pos[BlackoilPhases::Aqua];
wellTarget = Well::GuideRateTarget::WAT;
injectionPhase = Phase::WATER;
scaling = scalingFactor(pu.phase_pos[BlackoilPhases::Aqua]);
break;
}
case Well::InjectorType::OIL:
{
phasePos = pu.phase_pos[BlackoilPhases::Liquid];
wellTarget = Well::GuideRateTarget::OIL;
injectionPhase = Phase::OIL;
scaling = scalingFactor(pu.phase_pos[BlackoilPhases::Liquid]);
break;
}
case Well::InjectorType::GAS:
{
phasePos = pu.phase_pos[BlackoilPhases::Vapour];
wellTarget = Well::GuideRateTarget::GAS;
injectionPhase = Phase::GAS;
scaling = scalingFactor(pu.phase_pos[BlackoilPhases::Vapour]);
break;
}
default:
throw("Expected WATER, OIL or GAS as type for injectors " + well.name());
}
const Group::InjectionCMode& currentGroupControl = well_state.currentInjectionGroupControl(injectionPhase, group.name());
if (currentGroupControl == Group::InjectionCMode::FLD) {
// Inject share of parents control
const auto& parent = schedule.getGroup( group.parent(), current_step_ );
@ -2135,42 +2170,13 @@ namespace Opm
return;
}
const auto& groupcontrols = group.injectionControls(summaryState);
int phasePos;
Well::GuideRateTarget wellTarget;
double scaling = 1.0;
switch (injectorType) {
case Well::InjectorType::WATER:
{
phasePos = pu.phase_pos[BlackoilPhases::Aqua];
wellTarget = Well::GuideRateTarget::WAT;
scaling = scalingFactor(pu.phase_pos[BlackoilPhases::Aqua]);
break;
}
case Well::InjectorType::OIL:
{
phasePos = pu.phase_pos[BlackoilPhases::Liquid];
wellTarget = Well::GuideRateTarget::OIL;
scaling = scalingFactor(pu.phase_pos[BlackoilPhases::Liquid]);
break;
}
case Well::InjectorType::GAS:
{
phasePos = pu.phase_pos[BlackoilPhases::Vapour];
wellTarget = Well::GuideRateTarget::GAS;
scaling = scalingFactor(pu.phase_pos[BlackoilPhases::Vapour]);
break;
}
default:
throw("Expected WATER, OIL or GAS as type for injectors " + well.name());
}
assert(group.hasInjectionControl(injectionPhase));
const auto& groupcontrols = group.injectionControls(injectionPhase, summaryState);
const std::vector<double>& groupInjectionReductions = well_state.currentInjectionGroupReductionRates(group.name());
double groupTargetReduction = groupInjectionReductions[phasePos];
double fraction = wellGroupHelpers::wellFractionFromGuideRates(well, schedule, well_state, current_step_, Base::guide_rate_, wellTarget, /*isInjector*/true);
wellGroupHelpers::accumulateGroupInjectionPotentialFractions(well.groupName(), group.name(), schedule, well_state, current_step_, phasePos, fraction);
wellGroupHelpers::accumulateGroupInjectionPotentialFractions(well.groupName(), group.name(), schedule, well_state, pu, current_step_, injectionPhase, fraction);
switch(currentGroupControl) {
case Group::InjectionCMode::NONE:
@ -2210,15 +2216,15 @@ namespace Opm
double voidageRate = well_state.currentInjectionVREPRates(groupcontrols.voidage_group)*groupcontrols.target_void_fraction;
double injReduction = 0.0;
std::vector<double> groupInjectionReservoirRates = well_state.currentInjectionGroupReservoirRates(group.name());
if (groupcontrols.phase != Phase::WATER)
injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Aqua]]*convert_coeff[pu.phase_pos[BlackoilPhases::Aqua]];
injReduction += groupInjectionReservoirRates[pu.phase_pos[BlackoilPhases::Aqua]];
if (groupcontrols.phase != Phase::OIL)
injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Liquid]]*convert_coeff[pu.phase_pos[BlackoilPhases::Liquid]];
injReduction += groupInjectionReservoirRates[pu.phase_pos[BlackoilPhases::Liquid]];
if (groupcontrols.phase != Phase::GAS)
injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Vapour]]*convert_coeff[pu.phase_pos[BlackoilPhases::Vapour]];
injReduction += groupInjectionReservoirRates[pu.phase_pos[BlackoilPhases::Vapour]];
voidageRate -= injReduction;

View File

@ -983,8 +983,37 @@ namespace Opm
{
const auto& well = well_ecl_;
const auto pu = phaseUsage();
const auto& groupcontrols = group.injectionControls(summaryState);
const Group::InjectionCMode& currentGroupControl = well_state.currentInjectionGroupControl(group.name());
int phasePos;
Well::GuideRateTarget wellTarget;
Phase injectionPhase;
switch (injectorType) {
case Well::InjectorType::WATER:
{
phasePos = pu.phase_pos[BlackoilPhases::Aqua];
wellTarget = Well::GuideRateTarget::WAT;
injectionPhase = Phase::WATER;
break;
}
case Well::InjectorType::OIL:
{
phasePos = pu.phase_pos[BlackoilPhases::Liquid];
wellTarget = Well::GuideRateTarget::OIL;
injectionPhase = Phase::OIL;
break;
}
case Well::InjectorType::GAS:
{
phasePos = pu.phase_pos[BlackoilPhases::Vapour];
wellTarget = Well::GuideRateTarget::GAS;
injectionPhase = Phase::GAS;
break;
}
default:
throw("Expected WATER, OIL or GAS as type for injectors " + well.name());
}
const Group::InjectionCMode& currentGroupControl = well_state.currentInjectionGroupControl(injectionPhase, group.name());
if (currentGroupControl == Group::InjectionCMode::FLD) {
// Inject share of parents control
@ -1003,37 +1032,14 @@ namespace Opm
return;
}
assert(group.hasInjectionControl(injectionPhase));
const auto& groupcontrols = group.injectionControls(injectionPhase, summaryState);
int phasePos;
Well::GuideRateTarget wellTarget;
switch (injectorType) {
case Well::InjectorType::WATER:
{
phasePos = pu.phase_pos[BlackoilPhases::Aqua];
wellTarget = Well::GuideRateTarget::WAT;
break;
}
case Well::InjectorType::OIL:
{
phasePos = pu.phase_pos[BlackoilPhases::Liquid];
wellTarget = Well::GuideRateTarget::OIL;
break;
}
case Well::InjectorType::GAS:
{
phasePos = pu.phase_pos[BlackoilPhases::Vapour];
wellTarget = Well::GuideRateTarget::GAS;
break;
}
default:
throw("Expected WATER, OIL or GAS as type for injectors " + well.name());
}
const std::vector<double>& groupInjectionReductions = well_state.currentInjectionGroupReductionRates(group.name());
double groupTargetReduction = groupInjectionReductions[phasePos];
double fraction = wellGroupHelpers::wellFractionFromGuideRates(well, schedule, well_state, current_step_, Base::guide_rate_, wellTarget, /*isInjector*/true);
wellGroupHelpers::accumulateGroupInjectionPotentialFractions(well.groupName(), group.name(), schedule, well_state, current_step_, phasePos, fraction);
wellGroupHelpers::accumulateGroupInjectionPotentialFractions(well.groupName(), group.name(), schedule, well_state, pu, current_step_, injectionPhase, fraction);
switch(currentGroupControl) {
case Group::InjectionCMode::NONE:
{
@ -1061,7 +1067,7 @@ namespace Opm
double productionRate = well_state.currentInjectionREINRates(groupcontrols.reinj_group)[phasePos];
productionRate /= efficiencyFactor;
double target = std::max(0.0, (groupcontrols.target_reinj_fraction*productionRate - groupTargetReduction));
control_eq = getWQTotal() - fraction * target;
control_eq = getWQTotal() - fraction * target;
break;
}
case Group::InjectionCMode::VREP:
@ -1072,15 +1078,15 @@ namespace Opm
double voidageRate = well_state.currentInjectionVREPRates(groupcontrols.voidage_group)*groupcontrols.target_void_fraction;
double injReduction = 0.0;
std::vector<double> groupInjectionReservoirRates = well_state.currentInjectionGroupReservoirRates(group.name());
if (groupcontrols.phase != Phase::WATER)
injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Aqua]]*convert_coeff[pu.phase_pos[BlackoilPhases::Aqua]];
injReduction += groupInjectionReservoirRates[pu.phase_pos[BlackoilPhases::Aqua]];
if (groupcontrols.phase != Phase::OIL)
injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Liquid]]*convert_coeff[pu.phase_pos[BlackoilPhases::Liquid]];
injReduction += groupInjectionReservoirRates[pu.phase_pos[BlackoilPhases::Liquid]];
if (groupcontrols.phase != Phase::GAS)
injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Vapour]]*convert_coeff[pu.phase_pos[BlackoilPhases::Vapour]];
injReduction += groupInjectionReservoirRates[pu.phase_pos[BlackoilPhases::Vapour]];
voidageRate -= injReduction;

View File

@ -29,14 +29,13 @@ namespace Opm {
namespace wellGroupHelpers
{
inline void setGroupControl(const Group& group, const Schedule& schedule, const Phase& topUpPhase, const int reportStepIdx, const bool injector, WellStateFullyImplicitBlackoil& wellState, std::ostringstream& ss) {
inline void setGroupControl(const Group& group, const Schedule& schedule, const Phase& groupInjectionPhase, const int reportStepIdx, const bool injector, WellStateFullyImplicitBlackoil& wellState, std::ostringstream& ss) {
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
setGroupControl(groupTmp, schedule, topUpPhase, reportStepIdx, injector, wellState, ss);
setGroupControl(groupTmp, schedule, groupInjectionPhase, reportStepIdx, injector, wellState, ss);
if (injector) {
if (groupTmp.injection_phase() == topUpPhase || wellState.currentInjectionGroupControl(groupName) == Group::InjectionCMode::NONE) // only switch sub groups with same phase or NONE
wellState.setCurrentInjectionGroupControl(groupName, Group::InjectionCMode::FLD);
wellState.setCurrentInjectionGroupControl(groupInjectionPhase, groupName, Group::InjectionCMode::FLD);
} else {
wellState.setCurrentProductionGroupControl(groupName, Group::ProductionCMode::FLD);
}
@ -69,13 +68,13 @@ namespace Opm {
// Get the current controls.
const Well::InjectorType& injectorType = wellEcl.getInjectionProperties().injectorType;
if (injectorType == Well::InjectorType::WATER && topUpPhase != Phase::WATER)
if (injectorType == Well::InjectorType::WATER && groupInjectionPhase != Phase::WATER)
continue;
if (injectorType == Well::InjectorType::OIL && topUpPhase != Phase::OIL)
if (injectorType == Well::InjectorType::OIL && groupInjectionPhase != Phase::OIL)
continue;
if (injectorType == Well::InjectorType::GAS && topUpPhase != Phase::GAS)
if (injectorType == Well::InjectorType::GAS && groupInjectionPhase != Phase::GAS)
continue;
if (injectorType == Well::InjectorType::MULTI)
@ -96,16 +95,25 @@ namespace Opm {
}
// use NONE as default control
if (!wellState.hasInjectionGroupControl(group.name())) {
wellState.setCurrentInjectionGroupControl(group.name(), Group::InjectionCMode::NONE);
const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS};
for (Phase phase : all) {
if (!wellState.hasInjectionGroupControl(phase, group.name())) {
wellState.setCurrentInjectionGroupControl(phase, group.name(), Group::InjectionCMode::NONE);
}
}
if (!wellState.hasProductionGroupControl(group.name())) {
wellState.setCurrentProductionGroupControl(group.name(), Group::ProductionCMode::NONE);
}
if (group.isInjectionGroup() && schedule.hasWellGroupEvent(group.name(), ScheduleEvents::GROUP_INJECTION_UPDATE, reportStepIdx)) {
const auto controls = group.injectionControls(summaryState);
wellState.setCurrentInjectionGroupControl(group.name(), controls.cmode);
if (group.isInjectionGroup() && schedule.hasWellGroupEvent(group.name(), ScheduleEvents::GROUP_INJECTION_UPDATE, reportStepIdx)) {
for (Phase phase : all) {
if (!group.hasInjectionControl(phase))
continue;
const auto& controls = group.injectionControls(phase, summaryState);
wellState.setCurrentInjectionGroupControl(phase, group.name(), controls.cmode);
}
}
if (group.isProductionGroup() && schedule.hasWellGroupEvent(group.name(), ScheduleEvents::GROUP_PRODUCTION_UPDATE, reportStepIdx)) {
@ -114,7 +122,7 @@ namespace Opm {
}
if (schedule.gConSale(reportStepIdx).has(group.name())) {
wellState.setCurrentInjectionGroupControl(group.name(), Group::InjectionCMode::SALE);
wellState.setCurrentInjectionGroupControl(Phase::GAS, group.name(), Group::InjectionCMode::SALE);
std::ostringstream ss;
setGroupControl(group, schedule, Phase::GAS, reportStepIdx, /*injector*/true, wellState, ss);
}
@ -240,22 +248,34 @@ namespace Opm {
return rate;
}
inline void updateGroupTargetReduction(const Group& group, const Schedule& schedule, const int reportStepIdx, const bool isInjector, const WellStateFullyImplicitBlackoil& wellStateNupcol, WellStateFullyImplicitBlackoil& wellState, std::vector<double>& groupTargetReduction)
inline void updateGroupTargetReduction(const Group& group, const Schedule& schedule, const int reportStepIdx, const bool isInjector, const PhaseUsage& pu, const WellStateFullyImplicitBlackoil& wellStateNupcol, WellStateFullyImplicitBlackoil& wellState, std::vector<double>& groupTargetReduction)
{
const int np = wellState.numPhases();
for (const std::string& groupName : group.groups()) {
std::vector<double> thisGroupTargetReduction(np, 0.0);
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateGroupTargetReduction(groupTmp, schedule, reportStepIdx, isInjector, wellStateNupcol, wellState, thisGroupTargetReduction);
updateGroupTargetReduction(groupTmp, schedule, reportStepIdx, isInjector, pu, wellStateNupcol, wellState, thisGroupTargetReduction);
// accumulate group contribution from sub group
if (isInjector) {
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(groupName);
if (currentGroupControl != Group::InjectionCMode::FLD) {
for (int phase = 0; phase < np; phase++) {
groupTargetReduction[phase] += sumWellRates(groupTmp, schedule, wellStateNupcol, reportStepIdx, phase, isInjector);
const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS};
for (Phase phase : all) {
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(phase, groupName);
int phasePos;
if (phase == Phase::GAS && pu.phase_used[BlackoilPhases::Vapour] )
phasePos = pu.phase_pos[BlackoilPhases::Vapour];
else if (phase == Phase::OIL && pu.phase_used[BlackoilPhases::Liquid])
phasePos = pu.phase_pos[BlackoilPhases::Liquid];
else if (phase == Phase::WATER && pu.phase_used[BlackoilPhases::Aqua] )
phasePos = pu.phase_pos[BlackoilPhases::Aqua];
else
continue;
if (currentGroupControl != Group::InjectionCMode::FLD) {
groupTargetReduction[phasePos] += sumWellRates(groupTmp, schedule, wellStateNupcol, reportStepIdx, phasePos, isInjector);
} else {
groupTargetReduction[phasePos] += thisGroupTargetReduction[phasePos];
}
continue;
}
} else {
const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName);
@ -263,13 +283,13 @@ namespace Opm {
for (int phase = 0; phase < np; phase++) {
groupTargetReduction[phase] += sumWellRates(groupTmp, schedule, wellStateNupcol, reportStepIdx, phase, isInjector);
}
continue;
} else {
// or accumulate directly from the wells if controled from its parents
for (int phase = 0; phase < np; phase++) {
groupTargetReduction[phase] += thisGroupTargetReduction[phase];
}
}
}
// or accumulate directly from the wells if controled from its parents
for (int phase = 0; phase < np; phase++) {
groupTargetReduction[phase] += thisGroupTargetReduction[phase];
}
}
for (const std::string& wellName : group.wells()) {
const auto& wellTmp = schedule.getWell(wellName, reportStepIdx);
@ -320,19 +340,34 @@ namespace Opm {
// accumulate group contribution from sub group if FLD
if (isInjector) {
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(groupName);
if (currentGroupControl != Group::InjectionCMode::FLD) {
continue;
const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS};
for (Phase phase : all) {
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(phase, groupName);
if (currentGroupControl != Group::InjectionCMode::FLD) {
continue;
}
int phasePos;
if (phase == Phase::GAS && pu.phase_used[BlackoilPhases::Vapour] )
phasePos = pu.phase_pos[BlackoilPhases::Vapour];
else if (phase == Phase::OIL && pu.phase_used[BlackoilPhases::Liquid])
phasePos = pu.phase_pos[BlackoilPhases::Liquid];
else if (phase == Phase::WATER && pu.phase_used[BlackoilPhases::Aqua] )
phasePos = pu.phase_pos[BlackoilPhases::Aqua];
else
continue;
pot[phasePos] += thisPot[phasePos];
}
} else {
const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName);
if (currentGroupControl != Group::ProductionCMode::FLD) {
continue;
}
for (int phase = 0; phase < np; phase++) {
pot[phase] += thisPot[phase];
}
}
for (int phase = 0; phase < np; phase++) {
pot[phase] += thisPot[phase];
}
}
for (const std::string& wellName : group.wells()) {
const auto& wellTmp = schedule.getWell(wellName, reportStepIdx);
@ -435,6 +470,19 @@ namespace Opm {
wellState.setCurrentInjectionVREPRates(group.name(), resv);
}
inline void updateReservoirRatesInjectionGroups(const Group& group, const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellStateNupcol, WellStateFullyImplicitBlackoil& wellState) {
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateReservoirRatesInjectionGroups(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState);
}
const int np = wellState.numPhases();
std::vector<double> resv(np, 0.0);
for (int phase = 0; phase < np; ++phase) {
resv[phase] = sumWellPhaseRates(wellStateNupcol.wellReservoirRates(), group, schedule, wellState, reportStepIdx, phase, /*isInjector*/ true);
}
wellState.setCurrentInjectionGroupReservoirRates(group.name(), resv);
}
inline void updateREINForGroups(const Group& group, const Schedule& schedule, const int reportStepIdx, const PhaseUsage& pu, const SummaryState& st, const WellStateFullyImplicitBlackoil& wellStateNupcol, WellStateFullyImplicitBlackoil& wellState) {
const int np = wellState.numPhases();
for (const std::string& groupName : group.groups()) {
@ -523,12 +571,22 @@ namespace Opm {
return;
}
inline double groupFractionFromInjectionPotentials(const Group& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const int phasePos) {
inline double groupFractionFromInjectionPotentials(const Group& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const PhaseUsage& pu, const int reportStepIdx, const Phase& injectionPhase) {
double groupTotalGuideRate = 0.0;
const Group& groupParent = schedule.getGroup(group.parent(), reportStepIdx);
int phasePos;
if (injectionPhase == Phase::GAS && pu.phase_used[BlackoilPhases::Vapour] )
phasePos = pu.phase_pos[ pu.phase_pos[BlackoilPhases::Vapour] ];
else if (injectionPhase == Phase::OIL && pu.phase_used[BlackoilPhases::Liquid])
phasePos = pu.phase_pos[ pu.phase_pos[BlackoilPhases::Liquid] ];
else if (injectionPhase == Phase::WATER && pu.phase_used[BlackoilPhases::Aqua] )
phasePos = pu.phase_pos[ pu.phase_pos[BlackoilPhases::Aqua] ];
else
throw("this should not happen");
for (const std::string& groupName : groupParent.groups()) {
// only count group under group control from its parent
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(groupName);
const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(injectionPhase, groupName);
if (currentGroupControl != Group::InjectionCMode::FLD)
continue;
@ -541,11 +599,11 @@ namespace Opm {
return groupGuideRate / groupTotalGuideRate;
}
inline void accumulateGroupInjectionPotentialFractions(const std::string& groupName, const std::string& controlGroupName, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState,const int reportStepIdx, const int phasePos, double& fraction) {
inline void accumulateGroupInjectionPotentialFractions(const std::string& groupName, const std::string& controlGroupName, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const PhaseUsage& pu, const int reportStepIdx, const Phase& injectionPhase, double& fraction) {
const Group& group = schedule.getGroup(groupName, reportStepIdx);
if (groupName != controlGroupName) {
fraction *= groupFractionFromInjectionPotentials(group, schedule, wellState, reportStepIdx, phasePos);
accumulateGroupInjectionPotentialFractions(group.parent(), controlGroupName, schedule, wellState, reportStepIdx, phasePos, fraction);
fraction *= groupFractionFromInjectionPotentials(group, schedule, wellState, pu, reportStepIdx, injectionPhase);
accumulateGroupInjectionPotentialFractions(group.parent(), controlGroupName, schedule, wellState, pu, reportStepIdx, injectionPhase, fraction);
}
return;
}

View File

@ -319,14 +319,15 @@ namespace Opm
return current_production_group_controls_.count(groupName) > 0;
}
bool hasInjectionGroupControl(const std::string& groupName) {
return current_injection_group_controls_.count(groupName) > 0;
bool hasInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName) {
return current_injection_group_controls_.count(std::make_pair(phase, groupName)) > 0;
}
/// One current control per group.
void setCurrentProductionGroupControl(const std::string& groupName, const Group::ProductionCMode& groupControl ) {
current_production_group_controls_[groupName] = groupControl;
}
const Group::ProductionCMode& currentProductionGroupControl(const std::string& groupName) const {
auto it = current_production_group_controls_.find(groupName);
@ -337,14 +338,15 @@ namespace Opm
}
/// One current control per group.
void setCurrentInjectionGroupControl(const std::string& groupName, const Group::InjectionCMode& groupControl ) {
current_injection_group_controls_[groupName] = groupControl;
void setCurrentInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName, const Group::InjectionCMode& groupControl ) {
current_injection_group_controls_[std::make_pair(phase, groupName)] = groupControl;
}
const Group::InjectionCMode& currentInjectionGroupControl(const std::string& groupName) const {
auto it = current_injection_group_controls_.find(groupName);
const Group::InjectionCMode& currentInjectionGroupControl(const Opm::Phase& phase, const std::string& groupName) const {
auto it = current_injection_group_controls_.find(std::make_pair(phase, groupName));
if (it == current_injection_group_controls_.end())
OPM_THROW(std::logic_error, "Could not find any control for injection group " << groupName);
OPM_THROW(std::logic_error, "Could not find any control for " << phase << " injection group " << groupName);
return it->second;
}
@ -353,6 +355,7 @@ namespace Opm
void setCurrentProductionGroupReductionRates(const std::string& groupName, const std::vector<double>& target ) {
production_group_reduction_rates[groupName] = target;
}
const std::vector<double>& currentProductionGroupReductionRates(const std::string& groupName) const {
auto it = production_group_reduction_rates.find(groupName);
@ -365,6 +368,7 @@ namespace Opm
void setCurrentInjectionGroupReductionRates(const std::string& groupName, const std::vector<double>& target ) {
injection_group_reduction_rates[groupName] = target;
}
const std::vector<double>& currentInjectionGroupReductionRates(const std::string& groupName) const {
auto it = injection_group_reduction_rates.find(groupName);
@ -374,9 +378,23 @@ namespace Opm
return it->second;
}
void setCurrentInjectionGroupReservoirRates(const std::string& groupName, const std::vector<double>& target ) {
injection_group_reservoir_rates[groupName] = target;
}
const std::vector<double>& currentInjectionGroupReservoirRates(const std::string& groupName) const {
auto it = injection_group_reservoir_rates.find(groupName);
if (it == injection_group_reservoir_rates.end())
OPM_THROW(std::logic_error, "Could not find any reservoir rates for injection group " << groupName);
return it->second;
}
void setCurrentInjectionVREPRates(const std::string& groupName, const double& target ) {
injection_group_vrep_rates[groupName] = target;
}
const double& currentInjectionVREPRates(const std::string& groupName) const {
auto it = injection_group_vrep_rates.find(groupName);
@ -389,6 +407,7 @@ namespace Opm
void setCurrentInjectionREINRates(const std::string& groupName, const std::vector<double>& target ) {
injection_group_rein_rates[groupName] = target;
}
const std::vector<double>& currentInjectionREINRates(const std::string& groupName) const {
auto it = injection_group_rein_rates.find(groupName);
@ -401,6 +420,7 @@ namespace Opm
void setCurrentGroupInjectionPotentials(const std::string& groupName, const std::vector<double>& pot ) {
injection_group_potentials[groupName] = pot;
}
const std::vector<double>& currentGroupInjectionPotentials(const std::string& groupName) const {
auto it = injection_group_potentials.find(groupName);
@ -836,18 +856,7 @@ namespace Opm
}
template<class Comm>
void communicateGroupReductionRates(const Comm& comm) {
// sum over all nodes
for (auto& x : production_group_reduction_rates) {
comm.sum(x.second.data(), x.second.size());
}
for (auto& x : injection_group_reduction_rates) {
comm.sum(x.second.data(), x.second.size());
}
}
template<class Comm>
void communicateReinVrep(const Comm& comm) {
void communicateGroupRates(const Comm& comm) {
// sum over all nodes
for (auto& x : injection_group_rein_rates) {
comm.sum(x.second.data(), x.second.size());
@ -855,6 +864,15 @@ namespace Opm
for (auto& x : injection_group_vrep_rates) {
x.second = comm.sum(x.second);
}
for (auto& x : production_group_reduction_rates) {
comm.sum(x.second.data(), x.second.size());
}
for (auto& x : injection_group_reduction_rates) {
comm.sum(x.second.data(), x.second.size());
}
for (auto& x : injection_group_reservoir_rates) {
comm.sum(x.second.data(), x.second.size());
}
}
template<class Comm>
@ -912,10 +930,11 @@ namespace Opm
std::map<std::string, int> wellNameToGlobalIdx_;
std::map<std::string, Group::ProductionCMode> current_production_group_controls_;
std::map<std::string, Group::InjectionCMode> current_injection_group_controls_;
std::map<std::pair<Opm::Phase, std::string>, Group::InjectionCMode> current_injection_group_controls_;
std::map<std::string, std::vector<double>> production_group_reduction_rates;
std::map<std::string, std::vector<double>> injection_group_reduction_rates;
std::map<std::string, std::vector<double>> injection_group_reservoir_rates;
std::map<std::string, std::vector<double>> injection_group_potentials;
std::map<std::string, double> injection_group_vrep_rates;
std::map<std::string, std::vector<double>> injection_group_rein_rates;

View File

@ -1709,12 +1709,14 @@ BOOST_AUTO_TEST_CASE(Group)
{
#ifdef HAVE_MPI
Opm::UnitSystem unitSystem;
std::map<Opm::Phase, Opm::Group::GroupInjectionProperties> injection;
Opm::Group val1("test1", 1, 2, 3.0, unitSystem,
Opm::Group::GroupType::PRODUCTION,
4.0, true, 5, "test2",
Opm::IOrderSet<std::string>({"test3", "test4"}, {"test3","test4"}),
Opm::IOrderSet<std::string>({"test5", "test6"}, {"test5","test6"}),
Opm::Group::GroupInjectionProperties(),
injection,
Opm::Group::GroupProductionProperties());
auto val2 = PackUnpack(val1);
@ -2103,12 +2105,13 @@ BOOST_AUTO_TEST_CASE(Schedule)
Opm::Schedule::WellMap wells;
wells.insert({"test", {{std::make_shared<Opm::Well>(getFullWell())},1}});
Opm::Schedule::GroupMap groups;
std::map<Opm::Phase, Opm::Group::GroupInjectionProperties> injection;
groups.insert({"test", {{std::make_shared<Opm::Group>("test1", 1, 2, 3.0, unitSystem,
Opm::Group::GroupType::PRODUCTION,
4.0, true, 5, "test2",
Opm::IOrderSet<std::string>({"test3", "test4"}, {"test3","test4"}),
Opm::IOrderSet<std::string>({"test5", "test6"}, {"test5","test6"}),
Opm::Group::GroupInjectionProperties(),
injection,
Opm::Group::GroupProductionProperties())},1}});
using VapType = Opm::OilVaporizationProperties::OilVaporization;
Opm::DynamicState<Opm::OilVaporizationProperties> oilvap{{Opm::OilVaporizationProperties(VapType::VAPPARS,