mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-25 10:40:21 -06:00
Merge pull request #2298 from totto82/muliple-group-inj-phases
Allow for multiple group injection phases
This commit is contained in:
commit
150dc54e79
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user