diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index b54ead280..1dc9def2d 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -456,6 +456,10 @@ namespace Opm { well->updateWaterThroughput(dt, this->wellState()); } } + // report well switching + for (const auto& well : well_container_) { + well->reportWellSwitching(this->wellState().well(well->indexOfWell()), local_deferredLogger); + } // update the rate converter with current averages pressures etc in rateConverter_->template defineState(ebosSimulator_); diff --git a/opm/simulators/wells/WellInterface.hpp b/opm/simulators/wells/WellInterface.hpp index ddc4229d6..28a7042b6 100644 --- a/opm/simulators/wells/WellInterface.hpp +++ b/opm/simulators/wells/WellInterface.hpp @@ -278,8 +278,6 @@ protected: bool changed_to_stopped_this_step_ = false; - std::vector< std::string> well_control_log_; - double wpolymer() const; double wfoam() const; diff --git a/opm/simulators/wells/WellInterfaceGeneric.cpp b/opm/simulators/wells/WellInterfaceGeneric.cpp index 2e426696b..8cead2441 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.cpp +++ b/opm/simulators/wells/WellInterfaceGeneric.cpp @@ -96,6 +96,8 @@ WellInterfaceGeneric::WellInterfaceGeneric(const Well& well, } wsolvent_ = 0.0; + + well_control_log_.clear(); } const std::string& WellInterfaceGeneric::name() const @@ -377,4 +379,25 @@ double WellInterfaceGeneric::getALQ(const WellState& well_state) const return well_state.getALQ(name()); } +void WellInterfaceGeneric::reportWellSwitching(const SingleWellState& ws, DeferredLogger& deferred_logger) const +{ + if (well_control_log_.empty()) + return; + + std::string msg = " Well " + name() + + " control mode changed from "; + for (const std::string& from : well_control_log_) { + msg += from + "->"; + } + std::string to; + if (isInjector()) { + to = Well::InjectorCMode2String(ws.injection_cmode); + } else { + to = Well::ProducerCMode2String(ws.production_cmode); + } + msg += to; + deferred_logger.info(msg); +} + + } // namespace Opm diff --git a/opm/simulators/wells/WellInterfaceGeneric.hpp b/opm/simulators/wells/WellInterfaceGeneric.hpp index a78e00f66..9357435c4 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.hpp +++ b/opm/simulators/wells/WellInterfaceGeneric.hpp @@ -169,6 +169,8 @@ public: // whether a well is specified with a non-zero and valid VFP table number bool isVFPActive(DeferredLogger& deferred_logger) const; + void reportWellSwitching(const SingleWellState& ws, DeferredLogger& deferred_logger) const; + protected: bool getAllowCrossFlow() const; double mostStrictBhpFromBhpLimits(const SummaryState& summaryState) const; @@ -301,6 +303,8 @@ protected: double well_efficiency_factor_; const VFPProperties* vfp_properties_; const GuideRate* guide_rate_; + + std::vector< std::string> well_control_log_; }; } diff --git a/opm/simulators/wells/WellInterface_impl.hpp b/opm/simulators/wells/WellInterface_impl.hpp index 1860479fb..1edb22a3c 100644 --- a/opm/simulators/wells/WellInterface_impl.hpp +++ b/opm/simulators/wells/WellInterface_impl.hpp @@ -63,7 +63,6 @@ namespace Opm } } } - well_control_log_.clear(); } @@ -175,11 +174,11 @@ namespace Opm } else { from = Well::ProducerCMode2String(ws.production_cmode); } - bool oscillating = std::count(well_control_log_.begin(), well_control_log_.end(), from) >= param_.max_number_of_well_switches_; + bool oscillating = std::count(this->well_control_log_.begin(), this->well_control_log_.end(), from) >= param_.max_number_of_well_switches_; if (oscillating) { // only output frist time - bool output = std::count(well_control_log_.begin(), well_control_log_.end(), from) == param_.max_number_of_well_switches_; + bool output = std::count(this->well_control_log_.begin(), this->well_control_log_.end(), from) == param_.max_number_of_well_switches_; if (output) { std::ostringstream ss; ss << " The control model for well " << this->name() @@ -189,7 +188,7 @@ namespace Opm << " switches. The control is kept at " << from; deferred_logger.info(ss.str()); // add one more to avoid outputting the same info again - well_control_log_.push_back(from); + this->well_control_log_.push_back(from); } return false; } @@ -202,7 +201,6 @@ namespace Opm assert(iog == IndividualOrGroup::Both); changed = this->checkConstraints(well_state, group_state, schedule, summaryState, deferred_logger); } - Parallel::Communication cc = ebos_simulator.vanguard().grid().comm(); // checking whether control changed if (changed) { @@ -212,7 +210,6 @@ namespace Opm } else { to = Well::ProducerCMode2String(ws.production_cmode); } - well_control_log_.push_back(from); std::ostringstream ss; ss << " Switching control mode for well " << this->name() << " from " << from @@ -220,7 +217,9 @@ namespace Opm if (cc.size() > 1) { ss << " on rank " << cc.rank(); } - deferred_logger.info(ss.str()); + deferred_logger.debug(ss.str()); + + this->well_control_log_.push_back(from); updateWellStateWithTarget(ebos_simulator, group_state, well_state, deferred_logger); updatePrimaryVariables(well_state, deferred_logger); }