diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 4f31b8992..6f62787c3 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -39,7 +39,6 @@ list (APPEND MAIN_SOURCE_FILES opm/core/wells/WellsManager.cpp opm/core/wells/well_controls.c opm/core/wells/wells.c - opm/simulators/WellSwitchingLogger.cpp opm/simulators/DeferredLogger.cpp opm/simulators/timestepping/TimeStepControl.cpp opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -58,7 +57,6 @@ list (APPEND TEST_SOURCE_FILES tests/test_milu.cpp tests/test_multmatrixtransposed.cpp tests/test_wellmodel.cpp - tests/test_wellswitchlogger.cpp tests/test_deferredlogger.cpp tests/test_timer.cpp tests/test_invert.cpp @@ -165,7 +163,6 @@ list (APPEND PUBLIC_HEADER_FILES opm/core/wells/WellsManager.hpp opm/core/wells/WellsManager_impl.hpp opm/simulators/ParallelFileMerger.hpp - opm/simulators/WellSwitchingLogger.hpp opm/simulators/DeferredLogger.hpp opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp diff --git a/opm/autodiff/BlackoilWellModel.hpp b/opm/autodiff/BlackoilWellModel.hpp index ecf5246e8..b4657a384 100644 --- a/opm/autodiff/BlackoilWellModel.hpp +++ b/opm/autodiff/BlackoilWellModel.hpp @@ -56,7 +56,7 @@ #include -#include +#include BEGIN_PROPERTIES diff --git a/opm/autodiff/BlackoilWellModel_impl.hpp b/opm/autodiff/BlackoilWellModel_impl.hpp index 17d787e34..0bf50368f 100644 --- a/opm/autodiff/BlackoilWellModel_impl.hpp +++ b/opm/autodiff/BlackoilWellModel_impl.hpp @@ -320,7 +320,7 @@ namespace Opm { // no wells needing testing, otherwise we will have locking. std::vector< Scalar > B_avg(numComponents(), Scalar() ); computeAverageFormationFactor(B_avg); - wellhelpers::WellSwitchingLogger logger; + Opm::DeferredLogger local_deferredLogger; const auto& wellsForTesting = wellTestState_.updateWell(wtest_config, simulationTime); for (const auto& testWell : wellsForTesting) { @@ -338,8 +338,12 @@ namespace Opm { const WellTestConfig::Reason testing_reason = testWell.second; - well->wellTesting(ebosSimulator_, B_avg, simulationTime, timeStepIdx, terminal_output_, - testing_reason, well_state_, wellTestState_, logger); + well->wellTesting(ebosSimulator_, B_avg, simulationTime, timeStepIdx, + testing_reason, well_state_, wellTestState_, local_deferredLogger); + } + Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger); + if (terminal_output_) { + global_deferredLogger.logMessages(); } } @@ -936,15 +940,20 @@ namespace Opm { updateWellControls() { // Even if there no wells active locally, we cannot - // return as the Destructor of the WellSwitchingLogger + // return as the Destructor of the DeferredLogger // uses global communication. For no well active globally // we simply return. if( !wellsActive() ) return ; - wellhelpers::WellSwitchingLogger logger; + Opm::DeferredLogger local_deferredLogger; for (const auto& well : well_container_) { - well->updateWellControl(ebosSimulator_, well_state_, logger); + well->updateWellControl(ebosSimulator_, well_state_, local_deferredLogger); + } + + Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger); + if (terminal_output_) { + global_deferredLogger.logMessages(); } updateGroupControls(); diff --git a/opm/autodiff/MultisegmentWell.hpp b/opm/autodiff/MultisegmentWell.hpp index d629fb98b..4f64216be 100644 --- a/opm/autodiff/MultisegmentWell.hpp +++ b/opm/autodiff/MultisegmentWell.hpp @@ -352,8 +352,7 @@ namespace Opm virtual void wellTestingPhysical(Simulator& simulator, const std::vector& B_avg, const double simulation_time, const int report_step, - const bool terminal_output, - WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override; + WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) override; virtual void updateWaterThroughput(const double dt, WellState& well_state) const override; }; diff --git a/opm/autodiff/MultisegmentWell_impl.hpp b/opm/autodiff/MultisegmentWell_impl.hpp index d027875bf..4c31a415e 100644 --- a/opm/autodiff/MultisegmentWell_impl.hpp +++ b/opm/autodiff/MultisegmentWell_impl.hpp @@ -1896,8 +1896,8 @@ namespace Opm void MultisegmentWell:: wellTestingPhysical(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) + const double simulation_time, const int report_step, + WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) { const std::string msg = "Support of well testing for physical limits for multisegment wells is not " "implemented yet, wellTestingPhysical() for " + name() + " will do nothing"; diff --git a/opm/autodiff/StandardWell.hpp b/opm/autodiff/StandardWell.hpp index 52aea4b9f..34f8ec89a 100644 --- a/opm/autodiff/StandardWell.hpp +++ b/opm/autodiff/StandardWell.hpp @@ -413,8 +413,8 @@ namespace Opm const BVectorWell& dwells); virtual void wellTestingPhysical(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override; + const double simulation_time, const int report_step, + WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) override; virtual void updateWaterThroughput(const double dt, WellState& well_state) const override; }; diff --git a/opm/autodiff/StandardWellV.hpp b/opm/autodiff/StandardWellV.hpp index cf9031e61..897aa4203 100644 --- a/opm/autodiff/StandardWellV.hpp +++ b/opm/autodiff/StandardWellV.hpp @@ -418,8 +418,8 @@ namespace Opm const BVectorWell& dwells); virtual void wellTestingPhysical(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override; + const double simulation_time, const int report_step, + WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) override; // calculate the skin pressure based on water velocity, throughput and polymer concentration. // throughput is used to describe the formation damage during water/polymer injection. diff --git a/opm/autodiff/StandardWellV_impl.hpp b/opm/autodiff/StandardWellV_impl.hpp index 3ed0cf299..a79d0f390 100644 --- a/opm/autodiff/StandardWellV_impl.hpp +++ b/opm/autodiff/StandardWellV_impl.hpp @@ -2867,8 +2867,8 @@ namespace Opm void StandardWellV:: wellTestingPhysical(Simulator& ebos_simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) + const double simulation_time, const int report_step, + WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) { OpmLog::debug(" well " + name() + " is being tested for physical limits"); @@ -2903,7 +2903,7 @@ namespace Opm updatePrimaryVariables(well_state_copy); initPrimaryVariablesEvaluation(); - const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, logger); + const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, deferredLogger); if (!converged) { const std::string msg = " well " + name() + " did not get converged during well testing for physical reason"; diff --git a/opm/autodiff/StandardWell_impl.hpp b/opm/autodiff/StandardWell_impl.hpp index 6f25d7538..110cdf45e 100644 --- a/opm/autodiff/StandardWell_impl.hpp +++ b/opm/autodiff/StandardWell_impl.hpp @@ -2747,8 +2747,8 @@ namespace Opm void StandardWell:: wellTestingPhysical(Simulator& ebos_simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) + const double simulation_time, const int report_step, + WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) { OpmLog::debug(" well " + name() + " is being tested for physical limits"); @@ -2783,7 +2783,7 @@ namespace Opm updatePrimaryVariables(well_state_copy); initPrimaryVariablesEvaluation(); - const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, logger); + const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, deferredLogger); if (!converged) { const std::string msg = " well " + name() + " did not get converged during well testing for physical reason"; diff --git a/opm/autodiff/WellInterface.hpp b/opm/autodiff/WellInterface.hpp index a1e5a3215..e6002c610 100644 --- a/opm/autodiff/WellInterface.hpp +++ b/opm/autodiff/WellInterface.hpp @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include @@ -183,7 +183,7 @@ namespace Opm void updateWellControl(/* const */ Simulator& ebos_simulator, WellState& well_state, - wellhelpers::WellSwitchingLogger& logger) /* const */; + Opm::DeferredLogger& deferredLogger) /* const */; virtual void updatePrimaryVariables(const WellState& well_state) const = 0; @@ -226,10 +226,10 @@ namespace Opm // TODO: theoretically, it should be a const function // Simulator is not const is because that assembleWellEq is non-const Simulator void wellTesting(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, + const double simulation_time, const int report_step, const WellTestConfig::Reason testing_reason, /* const */ WellState& well_state, WellTestState& welltest_state, - wellhelpers::WellSwitchingLogger& logger); + Opm::DeferredLogger& deferredLogger); void updatePerforatedCell(std::vector& is_cell_perforated); @@ -374,12 +374,12 @@ namespace Opm OperabilityStatus operability_status_; void wellTestingEconomic(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - const WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger); + const double simulation_time, const int report_step, + const WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger); virtual void wellTestingPhysical(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) = 0; + const double simulation_time, const int report_step, + WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) = 0; void updateWellTestStateEconomic(const WellState& well_state, const double simulation_time, @@ -392,13 +392,13 @@ namespace Opm WellTestState& well_test_state) const; void solveWellForTesting(Simulator& ebosSimulator, WellState& well_state, - const std::vector& B_avg, bool terminal_output, - wellhelpers::WellSwitchingLogger& logger); + const std::vector& B_avg, + Opm::DeferredLogger& deferredLogger); bool solveWellEqUntilConverged(Simulator& ebosSimulator, const std::vector& B_avg, WellState& well_state, - wellhelpers::WellSwitchingLogger& logger); + Opm::DeferredLogger& deferredLogger); void scaleProductivityIndex(const int perfIdx, double& productivity_index); @@ -453,6 +453,7 @@ namespace Opm bool obey_bhp_limit_with_thp_limit = true; }; + const std::string modestring[4] = { "BHP", "THP", "RESERVOIR_RATE", "SURFACE_RATE" }; } diff --git a/opm/autodiff/WellInterface_impl.hpp b/opm/autodiff/WellInterface_impl.hpp index e99dba664..2aecacec7 100644 --- a/opm/autodiff/WellInterface_impl.hpp +++ b/opm/autodiff/WellInterface_impl.hpp @@ -431,7 +431,7 @@ namespace Opm WellInterface:: updateWellControl(/* const */ Simulator& ebos_simulator, WellState& well_state, - wellhelpers::WellSwitchingLogger& logger) /* const */ + Opm::DeferredLogger& deferredLogger) /* const */ { const int np = number_of_phases_; const int w = index_of_well_; @@ -493,9 +493,15 @@ namespace Opm // checking whether control changed if (updated_control_index != old_control_index) { - logger.wellSwitched(name(), - well_controls_iget_type(wc, old_control_index), - well_controls_iget_type(wc, updated_control_index)); + + auto from = well_controls_iget_type(wc, old_control_index); + auto to = well_controls_iget_type(wc, updated_control_index); + std::ostringstream ss; + ss << " Switching control mode for well " << name() + << " from " << modestring[from] + << " to " << modestring[to]; + deferredLogger.info(ss.str()); + //logger.wellSwitched(name() } if (updated_control_index != old_control_index) { // || well_collection_->groupControlActive()) { @@ -924,20 +930,20 @@ namespace Opm void WellInterface:: wellTesting(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, + const double simulation_time, const int report_step, const WellTestConfig::Reason testing_reason, /* const */ WellState& well_state, WellTestState& well_test_state, - wellhelpers::WellSwitchingLogger& logger) + Opm::DeferredLogger& deferredLogger) { if (testing_reason == WellTestConfig::Reason::PHYSICAL) { wellTestingPhysical(simulator, B_avg, simulation_time, report_step, - terminal_output, well_state, well_test_state, logger); + well_state, well_test_state, deferredLogger); } if (testing_reason == WellTestConfig::Reason::ECONOMIC) { wellTestingEconomic(simulator, B_avg, simulation_time, report_step, - terminal_output, well_state, well_test_state, logger); + well_state, well_test_state, deferredLogger); } } @@ -949,8 +955,8 @@ namespace Opm void WellInterface:: wellTestingEconomic(Simulator& simulator, const std::vector& B_avg, - const double simulation_time, const int report_step, const bool terminal_output, - const WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) + const double simulation_time, const int report_step, + const WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) { OpmLog::debug(" well " + name() + " is being tested for economic limits"); @@ -968,7 +974,7 @@ namespace Opm // untill the number of closed completions do not increase anymore. while (testWell) { const size_t original_number_closed_completions = welltest_state_temp.sizeCompletions(); - solveWellForTesting(simulator, well_state_copy, B_avg, terminal_output, logger); + solveWellForTesting(simulator, well_state_copy, B_avg, deferredLogger); updateWellTestState(well_state_copy, simulation_time, /*writeMessageToOPMLog=*/ false, welltest_state_temp); closeCompletions(welltest_state_temp); @@ -1156,7 +1162,7 @@ namespace Opm solveWellEqUntilConverged(Simulator& ebosSimulator, const std::vector& B_avg, WellState& well_state, - wellhelpers::WellSwitchingLogger& logger) + Opm::DeferredLogger& deferredLogger) { const int max_iter = param_.max_welleq_iter_; int it = 0; @@ -1175,7 +1181,7 @@ namespace Opm ++it; solveEqAndUpdateWellState(well_state); - updateWellControl(ebosSimulator, well_state, logger); + updateWellControl(ebosSimulator, well_state, deferredLogger); initPrimaryVariablesEvaluation(); } while (it < max_iter); @@ -1225,22 +1231,18 @@ namespace Opm void WellInterface:: solveWellForTesting(Simulator& ebosSimulator, WellState& well_state, - const std::vector& B_avg, bool terminal_output, - wellhelpers::WellSwitchingLogger& logger) + const std::vector& B_avg, + Opm::DeferredLogger& deferredLogger) { // keep a copy of the original well state const WellState well_state0 = well_state; - const bool converged = solveWellEqUntilConverged(ebosSimulator, B_avg, well_state, logger); + const bool converged = solveWellEqUntilConverged(ebosSimulator, B_avg, well_state, deferredLogger); if (converged) { - if ( terminal_output ) { - OpmLog::debug("WellTest: Well equation for well " + name() + " solution gets converged"); - } + OpmLog::debug("WellTest: Well equation for well " + name() + " solution gets converged"); } else { - if ( terminal_output ) { - const int max_iter = param_.max_welleq_iter_; - OpmLog::debug("WellTest: Well equation for well" +name() + " solution failed in getting converged with " - + std::to_string(max_iter) + " iterations"); - } + const int max_iter = param_.max_welleq_iter_; + OpmLog::debug("WellTest: Well equation for well" +name() + " solution failed in getting converged with " + + std::to_string(max_iter) + " iterations"); well_state = well_state0; } } diff --git a/opm/simulators/WellSwitchingLogger.cpp b/opm/simulators/WellSwitchingLogger.cpp deleted file mode 100644 index 3974aff18..000000000 --- a/opm/simulators/WellSwitchingLogger.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - Copyright 2016 Dr. Blatt - HPC-Simulation-Software & Services - Copyright 2016 Statoil AS - - This file is part of the Open Porous Media project (OPM). - - OPM is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OPM is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OPM. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include -#include - -namespace Opm -{ -namespace wellhelpers -{ - -#if HAVE_MPI -int WellSwitchingLogger::calculateMessageSize(std::vector& well_name_lengths) -{ - - // Each process will send a message to the root process with - // the following data: - // total number of switches, for each switch the length of the - // well name, for each switch the well name and the two controls. - well_name_lengths.reserve(switchMap_.size()); - - for(const auto& switchEntry : switchMap_) - { - int length = switchEntry.first.size() +1; //we write an additional \0 - well_name_lengths.push_back(length); - } - - // compute the message size - int message_size = 0; - int increment = 0; - // number of switches - MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &message_size); - // const char* length include delimiter for each switch - MPI_Pack_size(switchMap_.size(), MPI_INT, MPI_COMM_WORLD, &increment); - message_size += increment; - - // for each well the name + two controls in one write - for(const auto& length : well_name_lengths) - { - // well name - MPI_Pack_size(length, MPI_CHAR, MPI_COMM_WORLD, &increment); - message_size += increment; - // controls - MPI_Pack_size(2, MPI_CHAR, MPI_COMM_WORLD, &increment); - message_size += increment; - } - return message_size; -} - -void WellSwitchingLogger::packData(std::vector& well_name_lengths, - std::vector& buffer) -{ - // Pack the data - // number of switches - int offset = 0; - int no_switches = switchMap_.size(); - MPI_Pack(&no_switches, 1, MPI_INT, buffer.data(), buffer.size(), - &offset, MPI_COMM_WORLD); - MPI_Pack(well_name_lengths.data(), well_name_lengths.size(), - MPI_INT, buffer.data(), buffer.size(), - &offset, MPI_COMM_WORLD); - - for(const auto& switchEntry : switchMap_) - { - // well name - auto& well_name = switchEntry.first; - MPI_Pack(const_cast(well_name.c_str()), well_name.size()+1, - MPI_CHAR, buffer.data(), buffer.size(), - &offset, MPI_COMM_WORLD); - - // controls - MPI_Pack(const_cast(switchEntry.second.data()), 2 , MPI_CHAR, - buffer.data(), buffer.size(), &offset, MPI_COMM_WORLD); - } -} - -void WellSwitchingLogger::unpackDataAndLog(std::vector& recv_buffer, - const std::vector& displ) -{ - for(int p=1; p < cc_.size(); ++p) - { - int offset = displ[p]; - int no_switches = 0; - MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset, - &no_switches, 1, MPI_INT, MPI_COMM_WORLD); - - if ( no_switches == 0 ) - { - continue; - } - - std::vector well_name_lengths(no_switches); - - MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset, - well_name_lengths.data(), well_name_lengths.size(), - MPI_INT, MPI_COMM_WORLD); - - std::vector well_name; - for ( int i = 0; i < no_switches; ++i ) - { - well_name.resize(well_name_lengths[i]); - MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset, - well_name.data(), well_name_lengths[i], MPI_CHAR, - MPI_COMM_WORLD); - - std::array fromto{{}}; - MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset, - fromto.data(), 2, MPI_CHAR, MPI_COMM_WORLD); - - logSwitch(well_name.data(), fromto, p); - } - } -} - -void WellSwitchingLogger::logSwitch(const char* name, std::array fromto, - int rank) -{ - std::ostringstream ss; - ss << " Switching control mode for well " << name - << " from " << modestring[WellControlType(fromto[0])] - << " to " << modestring[WellControlType(fromto[1])] - << " on rank " << rank; - OpmLog::info(ss.str()); -} -#endif - -void WellSwitchingLogger::gatherDataAndLog() -{ - -#if HAVE_MPI - if(cc_.size() == 1) - { - return; - } - - std::vector message_sizes; - std::vector well_name_lengths; - int message_size = calculateMessageSize(well_name_lengths); - - if ( cc_.rank() == 0 ){ - for(const auto& entry : switchMap_) - { - logSwitch(entry.first.c_str(), entry.second,0); - } - - message_sizes.resize(cc_.size()); - } - - MPI_Gather(&message_size, 1, MPI_INT, message_sizes.data(), - 1, MPI_INT, 0, MPI_COMM_WORLD); - - std::vector buffer(message_size); - packData(well_name_lengths, buffer); - - std::vector displ; - - if ( cc_.rank() == 0){ - // last entry will be total size of - displ.resize(cc_.size() + 1, 0); - std::partial_sum(message_sizes.begin(), message_sizes.end(), - displ.begin()+1); - } - std::vector recv_buffer; - if ( cc_.rank() == 0 ){ - recv_buffer.resize(displ[cc_.size()]); - } - - MPI_Gatherv(buffer.data(), buffer.size(), MPI_PACKED, - recv_buffer.data(), message_sizes.data(), - displ.data(), MPI_PACKED, 0, MPI_COMM_WORLD); - if ( cc_.rank() == 0 ) - { - unpackDataAndLog(recv_buffer, displ); - } -#endif -} - - -WellSwitchingLogger::~WellSwitchingLogger() -{ - gatherDataAndLog(); -} -} // end namespace wellhelpers -} // end namespace Opm diff --git a/opm/simulators/WellSwitchingLogger.hpp b/opm/simulators/WellSwitchingLogger.hpp deleted file mode 100644 index f76b08708..000000000 --- a/opm/simulators/WellSwitchingLogger.hpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright 2016 Dr. Blatt - HPC-Simulation-Software & Services - Copyright 2016 Statoil AS - - This file is part of the Open Porous Media project (OPM). - - OPM is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OPM is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OPM. If not, see . -*/ - -#ifndef OPM_WELLSWITCHINGLOGGER_HEADER_INCLUDED -#define OPM_WELLSWITCHINGLOGGER_HEADER_INCLUDED - -#include -#include -#include -#include - -#include - -#include - -#include - -namespace Opm -{ -namespace wellhelpers -{ - -/// \brief Utility class to handle the log messages about well switching. -/// -/// In parallel all the messages will be send to a root processor -/// and logged there. -class WellSwitchingLogger -{ - typedef std::map > SwitchMap; - -public: - /// \brief The type of the collective communication used. - typedef Dune::CollectiveCommunication - Communication; - - /// \brief Constructor. - /// - /// \param cc The collective communication to use. - explicit WellSwitchingLogger(const Communication& cc = - Dune::MPIHelper::getCollectiveCommunication()) - : cc_(cc) - {} - - /// \brief Log that a well switched. - /// \param name The name of the well. - /// \param from The control of the well before the switch. - /// \param to The control of the well after the switch. - void wellSwitched(std::string name, - WellControlType from, - WellControlType to) - { - if( cc_.size() > 1 ) - { - using Pair = typename SwitchMap::value_type; - switchMap_.insert(Pair(name, {{char(from), char(to)}})); - } - else - { - std::ostringstream ss; - ss << " Switching control mode for well " << name - << " from " << modestring[from] - << " to " << modestring[to]; - OpmLog::info(ss.str()); - } - } - - /// \brief Destructor send does the actual logging. - ~WellSwitchingLogger(); - -private: - -#if HAVE_MPI - void unpackDataAndLog(std::vector& recv_buffer, - const std::vector& displ); - - void packData(std::vector& well_name_length, - std::vector& buffer); - - int calculateMessageSize(std::vector& well_name_length); - - void logSwitch(const char* name, std::array fromto, - int rank); - -#endif // HAVE_MPI - - void gatherDataAndLog(); - - /// \brief A map containing the local switches - SwitchMap switchMap_; - /// \brief Collective communication object. - Communication cc_; - /// \brief The strings for printing. - const std::string modestring[4] = { "BHP", "THP", "RESERVOIR_RATE", "SURFACE_RATE" }; -}; -} // end namespace wellhelpers -} // end namespace Opm -#endif diff --git a/tests/test_wellswitchlogger.cpp b/tests/test_wellswitchlogger.cpp deleted file mode 100644 index f77280f83..000000000 --- a/tests/test_wellswitchlogger.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include - -#define BOOST_TEST_MODULE DistributedCpGridTests -#define BOOST_TEST_NO_MAIN - -#include - -#include - -#if HAVE_MPI -class MPIError { -public: - /** @brief Constructor. */ - MPIError(std::string s, int e) : errorstring(s), errorcode(e){} - /** @brief The error string. */ - std::string errorstring; - /** @brief The mpi error code. */ - int errorcode; -}; - -void MPI_err_handler(MPI_Comm *, int *err_code, ...){ - char *err_string=new char[MPI_MAX_ERROR_STRING]; - int err_length; - MPI_Error_string(*err_code, err_string, &err_length); - std::string s(err_string, err_length); - std::cerr << "An MPI Error ocurred:"<