diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 365b6207a..18f59a365 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -26,6 +26,8 @@ list (APPEND MAIN_SOURCE_FILES src/opm/common/OpmLog/LogBackend.cpp src/opm/common/OpmLog/Logger.cpp src/opm/common/OpmLog/LogUtil.cpp + src/opm/common/OpmLog/KeywordLocation.cpp + src/opm/common/OpmLog/InfoLogger.cpp src/opm/common/OpmLog/OpmLog.cpp src/opm/common/OpmLog/StreamLog.cpp src/opm/common/OpmLog/TimerLog.cpp @@ -515,6 +517,7 @@ list( APPEND PUBLIC_HEADER_FILES opm/common/OpmLog/MessageFormatter.hpp opm/common/OpmLog/MessageLimiter.hpp opm/common/OpmLog/KeywordLocation.hpp + opm/common/OpmLog/InfoLogger.hpp opm/common/OpmLog/OpmLog.hpp opm/common/OpmLog/StreamLog.hpp opm/common/OpmLog/TimerLog.hpp diff --git a/opm/common/OpmLog/InfoLogger.hpp b/opm/common/OpmLog/InfoLogger.hpp new file mode 100644 index 000000000..c144d73da --- /dev/null +++ b/opm/common/OpmLog/InfoLogger.hpp @@ -0,0 +1,47 @@ +/* + Copyright 2020 Statoil ASA. + + 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 INFO_LOGGER_HPP +#define INFO_LOGGER_HPP + +#include +#include + +namespace Opm { + +/* + A small utility class to use in the situation where the first N messages + should go to OpmLog::info() and then the subsequent messages should go to + OpmLog::note() +*/ + +class InfoLogger { +public: + InfoLogger(const std::string& context_arg, std::size_t info_limit); + void operator()(const std::string& msg); +private: + std::string context; + std::size_t info_limit; + std::size_t info_count=0; + void (*log_function)(const std::string&); +}; + +} + +#endif diff --git a/opm/common/OpmLog/KeywordLocation.hpp b/opm/common/OpmLog/KeywordLocation.hpp index 13b955b8d..ade3f706e 100644 --- a/opm/common/OpmLog/KeywordLocation.hpp +++ b/opm/common/OpmLog/KeywordLocation.hpp @@ -50,9 +50,8 @@ public: lineno(lno) {} - std::string message() const { - return this->keyword + " in " + this->filename + " at line " + std::to_string(this->lineno); - } + + std::string format(const std::string& msg_fmt) const; static KeywordLocation serializeObject() { diff --git a/src/opm/common/OpmLog/InfoLogger.cpp b/src/opm/common/OpmLog/InfoLogger.cpp new file mode 100644 index 000000000..51fe52f1b --- /dev/null +++ b/src/opm/common/OpmLog/InfoLogger.cpp @@ -0,0 +1,43 @@ +/* + Copyright 2020 Statoil ASA. + + 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 . +*/ + +#include +#include +#include + +namespace Opm { + +InfoLogger::InfoLogger(const std::string& context_arg, std::size_t info_limit_arg): + context(context_arg), + info_limit(info_limit_arg) +{ + this->log_function = &OpmLog::info; +} + + +void InfoLogger::operator()(const std::string& msg) { + if (this->info_count == this->info_limit) { + OpmLog::info(fmt::format("Reporting limit reached for {} - see PRT file for additional messages", this->context)); + this->log_function = &OpmLog::note; + } + this->log_function(msg); + this->info_count += 1; +} + +} diff --git a/src/opm/common/OpmLog/KeywordLocation.cpp b/src/opm/common/OpmLog/KeywordLocation.cpp new file mode 100644 index 000000000..1ca246cb2 --- /dev/null +++ b/src/opm/common/OpmLog/KeywordLocation.cpp @@ -0,0 +1,33 @@ +/* + Copyright 2020 Statoil ASA. + + 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 . +*/ + +#include +#include + + +namespace Opm { + +std::string KeywordLocation::format(const std::string& msg_fmt) const { + return fmt::format(msg_fmt, + fmt::arg("keyword", this->keyword), + fmt::arg("file", this->filename), + fmt::arg("line", this->lineno)); +} + +} diff --git a/src/opm/parser/eclipse/EclipseState/EclipseState.cpp b/src/opm/parser/eclipse/EclipseState/EclipseState.cpp index bbadd5986..6c208a36f 100644 --- a/src/opm/parser/eclipse/EclipseState/EclipseState.cpp +++ b/src/opm/parser/eclipse/EclipseState/EclipseState.cpp @@ -21,6 +21,7 @@ #include +#include #include #include @@ -232,14 +233,14 @@ namespace Opm { for (size_t index=0; index < section.count("MULTFLT"); index++) { const auto& faultsKeyword = section.getKeyword("MULTFLT" , index); OpmLog::info(OpmInputError::format("Applying {keyword} in {file} line {line}", faultsKeyword.location())); + InfoLogger logger("MULTFLT",3); for (auto iter = faultsKeyword.begin(); iter != faultsKeyword.end(); ++iter) { - const auto& faultRecord = *iter; const std::string& faultName = faultRecord.getItem(0).get< std::string >(0); double multFlt = faultRecord.getItem(1).get< double >(0); - m_faults.setTransMult( faultName , multFlt ); - OpmLog::info(fmt::format("Setting fault transmissibility multiplier {} for fault {}", multFlt, faultName)); + + logger(fmt::format("Setting fault transmissibility multiplier {} for fault {}", multFlt, faultName)); } } } diff --git a/src/opm/parser/eclipse/EclipseState/TracerConfig.cpp b/src/opm/parser/eclipse/EclipseState/TracerConfig.cpp index ea37a9620..158b4e410 100644 --- a/src/opm/parser/eclipse/EclipseState/TracerConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/TracerConfig.cpp @@ -18,6 +18,7 @@ */ #include #include +#include #include #include #include @@ -50,7 +51,8 @@ TracerConfig::TracerConfig(const UnitSystem& unit_system, const Deck& deck) using TR = ParserKeywords::TRACER; if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); - OpmLog::info(OpmInputError::format("Initializing tracers from {keyword} in {file} line {line}", keyword.location())); + OpmLog::info( keyword.location().format("Initializing tracers from {keyword} in {file} line {line}") ); + InfoLogger logger("Tracer tables", 3); for (const auto& record : keyword) { const auto& name = record.getItem().get(0); Phase phase = phase_from_string(record.getItem().get(0)); @@ -65,7 +67,7 @@ TracerConfig::TracerConfig(const UnitSystem& unit_system, const Deck& deck) if (deck.hasKeyword(tracer_field)) { const auto& tracer_keyword = deck.getKeyword(tracer_field); auto concentration = tracer_keyword.getRecord(0).getItem(0).getData(); - OpmLog::info(OpmInputError::format("Loading tracer concentration from {keyword} in {file} line {line}", tracer_keyword.location())); + logger(tracer_keyword.location().format("Loading tracer concentration from {keyword} in {file} line {line}")); for (auto& c : concentration) c *= inv_volume; @@ -77,7 +79,7 @@ TracerConfig::TracerConfig(const UnitSystem& unit_system, const Deck& deck) if (deck.hasKeyword(tracer_table)) { const auto& tracer_keyword = deck.getKeyword(tracer_table); const auto& deck_item = tracer_keyword.getRecord(0).getItem(0); - OpmLog::info(OpmInputError::format("Loading tracer table from {keyword} in {file} line {line}", tracer_keyword.location())); + logger(tracer_keyword.location().format("Loading tracer concentration from {keyword} in {file} line {line}")); this->tracers.emplace_back(name, phase, TracerVdTable(deck_item, inv_volume)); continue; }