From 84910993c4f5cadedc8bf836bfcbe2336ec618bf Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Fri, 4 Nov 2016 13:37:50 +0100 Subject: [PATCH] different strategy is using when updating the well targets When the group has wells both under individual control and group control, since the well rates under individual control changes each iteration, the well targets for this kind of group need to be updated each iteration. When we change to use implicit well potentials later, which is supposed to be more accurate, we probably should always (unless we decided not to) update the well targets each iteration. --- opm/core/wells/WellCollection.cpp | 42 +++++++++++----------------- opm/core/wells/WellCollection.hpp | 8 ------ opm/core/wells/WellsGroup.cpp | 16 +++++++---- opm/core/wells/WellsGroup.hpp | 2 ++ opm/core/wells/WellsManager_impl.hpp | 1 - 5 files changed, 29 insertions(+), 40 deletions(-) diff --git a/opm/core/wells/WellCollection.cpp b/opm/core/wells/WellCollection.cpp index 720282d48..5305f1f23 100644 --- a/opm/core/wells/WellCollection.cpp +++ b/opm/core/wells/WellCollection.cpp @@ -231,45 +231,47 @@ namespace Opm // TODO: it should based on individual group // With current approach, it will potentially result in more update, // thus more iterations, while it will not cause result wrong. + // If the group control and individual control is mixed, then it need to + // update the well targets bool any_group_control_node = false; - bool any_should_update_node = false; + bool any_individual_control_node = false; for (size_t i = 0; i < leaf_nodes_.size(); ++i) { if (leaf_nodes_[i]->isInjector()) { - if (leaf_nodes_[i]->shouldUpdateWellTargets()) { - any_should_update_node = true; - } - - if (!leaf_nodes_[i]->individualControl()) { + if (leaf_nodes_[i]->individualControl()) { + any_individual_control_node = true; + } else { any_group_control_node = true; } } } - return (any_group_control_node && any_should_update_node); + return (any_group_control_node && any_individual_control_node); } + + // These two functions should be made one bool WellCollection::needUpdateProductionTargets() const { // TODO: it should based on individual group // With current approach, it will potentially result in more update, // thus more iterations, while it will not cause result wrong. + // If the group control and individual control is mixed, then it need to + // update the well targets bool any_group_control_node = false; - bool any_should_update_node = false; + bool any_individual_control_node = false; for (size_t i = 0; i < leaf_nodes_.size(); ++i) { if (leaf_nodes_[i]->isProducer()) { - if (leaf_nodes_[i]->shouldUpdateWellTargets()) { - any_should_update_node = true; - } - - if (!leaf_nodes_[i]->individualControl()) { + if (leaf_nodes_[i]->individualControl()) { + any_individual_control_node = true; + } else { any_group_control_node = true; } } } - return (any_group_control_node && any_should_update_node); + return (any_group_control_node && any_individual_control_node); } @@ -286,16 +288,6 @@ namespace Opm return leaf_nodes_[i]; } - bool WellCollection::justUpdateWellTargets() const - { - return just_update_well_targets_; - } - - void WellCollection::setJustUpdateWellTargets(const bool flag) - { - just_update_well_targets_ = flag; - } - void WellCollection::updateWellTargets(const std::vector well_rates) { // TODO: currently, we only handle the level of the well groups for the moment, i.e. the level just above wells @@ -316,8 +308,6 @@ namespace Opm } } } - - setJustUpdateWellTargets(true); } bool WellCollection::havingVREPGroups() const { diff --git a/opm/core/wells/WellCollection.hpp b/opm/core/wells/WellCollection.hpp index d4ac7d703..1a6b61952 100644 --- a/opm/core/wells/WellCollection.hpp +++ b/opm/core/wells/WellCollection.hpp @@ -139,14 +139,6 @@ namespace Opm /// Updating the well targets based on the well rates. void updateWellTargets(const std::vector well_rates); - /// True right after updating the well targets due to wells switching between individual control and group control. - /// It is used to force the simulation continue for another iteration in case that update the well targets are updated, - /// at the same time, the simulation is ended because of achieving the convergence with previous well targets. - bool justUpdateWellTargets() const; - - /// Setting the value for just_update_well_targets_ - void setJustUpdateWellTargets(const bool flag); - /// When we have VREP group, we need to update the targets based on the updated production voidage rates for each iteration. bool havingVREPGroups() const; diff --git a/opm/core/wells/WellsGroup.cpp b/opm/core/wells/WellsGroup.cpp index 6562c4da6..fdc342a06 100644 --- a/opm/core/wells/WellsGroup.cpp +++ b/opm/core/wells/WellsGroup.cpp @@ -555,7 +555,6 @@ namespace Opm } case InjectionSpecification::VREP: case InjectionSpecification::REIN: - std::cout << "Replacement keywords found, remember to call applyExplicitReinjectionControls." << std::endl; return; case InjectionSpecification::FLD: case InjectionSpecification::NONE: @@ -1069,6 +1068,8 @@ namespace Opm // The well only had its own controls, no group controls. append_well_controls(wct, effective_target, invalid_alq, invalid_vfp, distr, self_index_, wells_); group_control_index_ = well_controls_get_num(wells_->ctrls[self_index_]) - 1; + // It will possibly be changed when initializing WellState + // set_current_control(self_index_, group_control_index_, wells_); } else { // We will now modify the last control, that // "belongs to" the group control. @@ -1077,9 +1078,6 @@ namespace Opm well_controls_iset_alq(wells_->ctrls[self_index_] , group_control_index_ , -1e100); well_controls_iset_distr(wells_->ctrls[self_index_] , group_control_index_ , distr); } - set_current_control(self_index_, group_control_index_, wells_); - // TODO: it might not always be the case - setIndividualControl(false); } @@ -1167,6 +1165,8 @@ namespace Opm // TODO: basically, on group control index is not enough eventually. There can be more than one sources for the // group control group_control_index_ = well_controls_get_num(wells_->ctrls[self_index_]) - 1; + // it should only apply for nodes with GRUP injeciton control + individual_control_ = false; } else { well_controls_iset_type(wells_->ctrls[self_index_] , group_control_index_ , RESERVOIR_RATE); well_controls_iset_target(wells_->ctrls[self_index_] , group_control_index_ , ntarget); @@ -1249,6 +1249,8 @@ namespace Opm // The well only had its own controls, no group controls. append_well_controls(wct, ntarget, invalid_alq, invalid_vfp, distr, self_index_, wells_); group_control_index_ = well_controls_get_num(wells_->ctrls[self_index_]) - 1; + // It will possibly be changed when initializing WellState. + // set_current_control(self_index_, group_control_index_, wells_); } else { // We will now modify the last control, that // "belongs to" the group control. @@ -1257,7 +1259,6 @@ namespace Opm well_controls_iset_alq(wells_->ctrls[self_index_] , group_control_index_ , -1e100); well_controls_iset_distr(wells_->ctrls[self_index_] , group_control_index_ , distr); } - set_current_control(self_index_, group_control_index_, wells_); } @@ -1523,4 +1524,9 @@ namespace Opm return efficiency_factor; } + + int WellNode::selfIndex() const { + return self_index_; + } + } diff --git a/opm/core/wells/WellsGroup.hpp b/opm/core/wells/WellsGroup.hpp index fbdb52173..75948e4a6 100644 --- a/opm/core/wells/WellsGroup.hpp +++ b/opm/core/wells/WellsGroup.hpp @@ -510,6 +510,8 @@ namespace Opm /// to the well in a multi-layer group structure. double getAccumulativeEfficiencyFactor() const; + int selfIndex() const; + private: Wells* wells_; int self_index_; diff --git a/opm/core/wells/WellsManager_impl.hpp b/opm/core/wells/WellsManager_impl.hpp index 3e301416d..176677104 100644 --- a/opm/core/wells/WellsManager_impl.hpp +++ b/opm/core/wells/WellsManager_impl.hpp @@ -412,7 +412,6 @@ WellsManager::init(const Opm::EclipseState& eclipseState, well_collection_.setHavingVREPGroups(false); well_collection_.addField(fieldGroup, timeStep, pu); addChildGroups(*fieldNode, schedule, timeStep, pu); - well_collection_.setJustUpdateWellTargets(false); } for (auto w = wells.begin(), e = wells.end(); w != e; ++w) {