diff --git a/opm/simulators/wells/BlackoilWellModelConstraints.cpp b/opm/simulators/wells/BlackoilWellModelConstraints.cpp index c1f48024d..d0b5437c4 100644 --- a/opm/simulators/wells/BlackoilWellModelConstraints.cpp +++ b/opm/simulators/wells/BlackoilWellModelConstraints.cpp @@ -562,7 +562,7 @@ bool BlackoilWellModelConstraints:: updateGroupIndividualControl(const Group& group, const int reportStepIdx, std::map,std::string>& switched_inj, - std::map& switched_prod, + std::map>& switched_prod, std::map>& closed_offending_wells, GroupState& group_state, WellState& well_state, @@ -612,7 +612,7 @@ updateGroupIndividualControl(const Group& group, group_state, deferred_logger); if(changed) { - switched_prod.insert_or_assign(group.name(), + switched_prod[group.name()].push_back( Group::ProductionCMode2String(changed_this.first)); WellGroupHelpers::updateWellRatesFromGroupTargetScale(changed_this.second, group, diff --git a/opm/simulators/wells/BlackoilWellModelConstraints.hpp b/opm/simulators/wells/BlackoilWellModelConstraints.hpp index dc06ea7d1..d69fed569 100644 --- a/opm/simulators/wells/BlackoilWellModelConstraints.hpp +++ b/opm/simulators/wells/BlackoilWellModelConstraints.hpp @@ -74,7 +74,7 @@ public: bool updateGroupIndividualControl(const Group& group, const int reportStepIdx, std::map,std::string>& switched_inj, - std::map& switched_prod, + std::map>& switched_prod, std::map>& closed_offending_wells, GroupState& group_state, WellState& well_state, diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index dcf7d89b1..2e9dd650d 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -714,8 +714,7 @@ checkGroupHigherConstraints(const Group& group, deferred_logger); if (changed) { - switched_prod_groups_.insert_or_assign(group.name(), - Group::ProductionCMode2String(Group::ProductionCMode::FLD)); + switched_prod_groups_[group.name()].push_back(Group::ProductionCMode2String(Group::ProductionCMode::FLD)); WellGroupHelpers::updateWellRatesFromGroupTargetScale(scaling_factor, group, schedule(), diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index ed817d350..573a573b0 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -598,7 +598,7 @@ protected: bool wellStructureChangedDynamically_{false}; // Store maps of group name and new group controls for output - std::map switched_prod_groups_; + std::map> switched_prod_groups_; std::map, std::string> switched_inj_groups_; // Store map of group name and close offending well for output std::map> closed_offending_wells_; diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index bec51ecb7..19b67bd87 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -752,11 +752,11 @@ namespace Opm { for (const auto& [name, to] : this->switched_prod_groups_) { const Group::ProductionCMode& oldControl = this->prevWGState().group_state.production_control(name); std::string from = Group::ProductionCMode2String(oldControl); - if (to != from) { + if (to.back() != from) { std::string msg = " Production Group " + name + " control mode changed from "; msg += from; - msg += " to " + to; + msg += " to " + to.back(); local_deferredLogger.info(msg); } } @@ -2236,10 +2236,14 @@ namespace Opm { if (changed_well_to_group) { updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger); changed_well_group = true; + simulator_.gridView().comm()); } - // Check individual well constraints and communicate. - bool changed_well_individual = false; + changed_well_to_group = comm.sum(static_cast(changed_well_to_group)); + if (changed_well_to_group) { + updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger); + changed_well_group = true; + } { // For MS Wells a linear solve is performed below and the matrix might be singular. // We need to communicate the exception thrown to the others and rethrow. @@ -2262,7 +2266,7 @@ namespace Opm { } // update wsolvent fraction for REIN wells - const Group& fieldGroup = this->schedule().getGroup("FIELD", episodeIdx); + //const Group& fieldGroup = this->schedule().getGroup("FIELD", episodeIdx); this->updateWsolvent(fieldGroup, episodeIdx, this->nupcolWellState()); return { changed_well_group, more_network_update }; @@ -2471,6 +2475,16 @@ namespace Opm { const int reportStepIdx, const int iterationIdx) { + + if (this->switched_prod_groups_.count(group.name()) > 0) { + for (const auto& key : this->switched_prod_groups_[group.name()]) { + if (std::count(this->switched_prod_groups_[group.name()].begin(), this->switched_prod_groups_[group.name()].end(), key) >= 3) { + std::cout << "group control osccilating " << group.name() << " keep at " << key << std::endl; + return false; + } + } + } + bool changed = false; bool changed_hc = this->checkGroupHigherConstraints( group, deferred_logger, reportStepIdx); if (changed_hc) { diff --git a/tests/test_RestartSerialization.cpp b/tests/test_RestartSerialization.cpp index 6989be8b0..2a1ed1fb1 100644 --- a/tests/test_RestartSerialization.cpp +++ b/tests/test_RestartSerialization.cpp @@ -332,7 +332,7 @@ public: last_valid_wgstate_ = WGState::serializationTestObject(dummy); nupcol_wgstate_ = WGState::serializationTestObject(dummy); last_glift_opt_time_ = 5.0; - switched_prod_groups_ = {{"test4", "test5"}}; + switched_prod_groups_ = {{"test4", {"test5", "test6"}}}; switched_inj_groups_ = {{{"test4", Phase::SOLVENT}, "test5"}}; closed_offending_wells_ = {{"test4", {"test5", "test6"}}}; }