diff --git a/opm/autodiff/FlowMain.hpp b/opm/autodiff/FlowMain.hpp index aa613c890..a1fb5e05b 100644 --- a/opm/autodiff/FlowMain.hpp +++ b/opm/autodiff/FlowMain.hpp @@ -84,6 +84,8 @@ #include #include +#include +#include #ifdef _OPENMP #include @@ -109,6 +111,101 @@ namespace Opm { boost::filesystem::path simulationCaseName( const std::string& casename ); int64_t convertMessageType(const Message::type& mtype); + + namespace fs = boost::filesystem; + + /// \brief A functor that merges multiple files of a parallel run to one file. + /// + /// Without care multiple processes might log messages in a parallel run. + /// Non-root processes will do that to seperate files + /// .. debugStream_; + /// \brief Stream to *.PRT file + std::unique_ptr logStream_; + }; } @@ -152,7 +249,11 @@ namespace Opm asImpl().createSimulator(); // Run. - return asImpl().runSimulator(); + auto ret = asImpl().runSimulator(); + + asImpl().mergeParallelLogFiles(); + + return ret; } catch (const std::exception &e) { std::ostringstream message; @@ -390,12 +491,14 @@ namespace Opm baseName = path(fpath.filename()).string(); } if (param_.has("output_dir")) { - logFileStream << output_dir_ << "/" << baseName + ".PRT"; - debugFileStream << output_dir_ + "/." + baseName + ".DEBUG"; - } else { - logFileStream << baseName << ".PRT"; - debugFileStream << "." << baseName << ".DEBUG"; + logFileStream << output_dir_ << "/"; + debugFileStream << output_dir_ + "/"; } + + logFileStream << baseName; + debugFileStream << "." << baseName; + + if ( must_distribute_ && mpi_rank_ != 0 ) { // Added rank to log file for non-zero ranks. // This prevents message loss. @@ -403,6 +506,9 @@ namespace Opm // If the following file appears then there is a bug. logFileStream << "." << mpi_rank_; } + logFileStream << ".PRT"; + debugFileStream << ".DEBUG"; + std::string debugFile = debugFileStream.str(); logFile_ = logFileStream.str(); @@ -422,10 +528,29 @@ namespace Opm } } + void mergeParallelLogFiles() + { + // force closing of all log files. + OpmLog::removeAllBackends(); + if( mpi_rank_ != 0 || !must_distribute_ ) + { + return; + } + namespace fs = boost::filesystem; + fs::path output_path("."); + if ( param_.has("output_dir") ) + { + output_path = fs::path(output_dir_); + } + fs::path deck_filename(param_.get("deck_filename")); + std::for_each(fs::directory_iterator(output_path), + fs::directory_iterator(), + detail::ParallelFileMerger(output_path, deck_filename.stem().string())); + } // Parser the input and creates the Deck and EclipseState objects. // Writes to: