Merge pull request #2046 from totto82/sync_logging

Add logging in ebos
This commit is contained in:
dr-robertk 2019-10-15 14:19:34 +02:00 committed by GitHub
commit abf793726d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 270 additions and 18 deletions

View File

@ -32,6 +32,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
namespace Opm {
class EclAlternativeBlackOilIndexTraits
@ -67,5 +68,5 @@ END_PROPERTIES
int main(int argc, char **argv)
{
typedef TTAG(EbosAltIdxTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}

View File

@ -28,6 +28,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
namespace Opm {
@ -105,7 +106,7 @@ void ebosBlackOilSetDeck(Opm::Deck* deck,
int ebosBlackOilMain(int argc, char **argv)
{
typedef TTAG(EbosTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}
}

View File

@ -28,6 +28,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
BEGIN_PROPERTIES
@ -57,7 +58,7 @@ void ebosFoamSetDeck(Opm::Deck* deck,
int ebosFoamMain(int argc, char **argv)
{
typedef TTAG(EbosFoamTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}
}

View File

@ -28,6 +28,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
BEGIN_PROPERTIES
@ -72,7 +73,7 @@ void ebosGasOilSetDeck(Opm::Deck* deck,
int ebosGasOilMain(int argc, char **argv)
{
typedef TTAG(EbosGasOilTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}
}

View File

@ -28,6 +28,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
BEGIN_PROPERTIES
@ -72,7 +73,7 @@ void ebosOilWaterSetDeck(Opm::Deck* deck,
int ebosOilWaterMain(int argc, char **argv)
{
typedef TTAG(EbosOilWaterTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}
}

View File

@ -28,6 +28,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
BEGIN_PROPERTIES
@ -57,7 +58,7 @@ void ebosPolymerSetDeck(Opm::Deck* deck,
int ebosPolymerMain(int argc, char **argv)
{
typedef TTAG(EbosPolymerTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}
}

View File

@ -28,6 +28,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
BEGIN_PROPERTIES
@ -57,7 +58,7 @@ void ebosSolventSetDeck(Opm::Deck* deck,
int ebosSolventMain(int argc, char **argv)
{
typedef TTAG(EbosSolventTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}
}

View File

@ -28,6 +28,7 @@
#include "config.h"
#include "ebos.hh"
#include "startEbos.hh"
BEGIN_PROPERTIES
@ -57,7 +58,7 @@ void ebosThermalSetDeck(Opm::Deck* deck,
int ebosThermalMain(int argc, char **argv)
{
typedef TTAG(EbosThermalTypeTag) ProblemTypeTag;
return Opm::start<ProblemTypeTag>(argc, argv);
return Opm::startEbos<ProblemTypeTag>(argc, argv);
}
}

View File

@ -30,6 +30,8 @@
#include <opm/models/blackoil/blackoilnewtonmethod.hh>
#include <opm/models/utils/signum.hh>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/material/common/Unused.hpp>
@ -227,6 +229,16 @@ public:
+std::to_string(double(newtonMaxError)));
}
void endIteration_(SolutionVector& nextSolution,
const SolutionVector& currentSolution)
{
ParentType::endIteration_(nextSolution, currentSolution);
OpmLog::debug( "Newton iteration " + std::to_string(this->numIterations_) + ""
+ " error: " + std::to_string(double(this->error_))
+ this->endIterMsg().str());
this->endIterMsg().str("");
}
private:
Scalar errorPvFraction_;
Scalar errorSum_;

View File

@ -160,6 +160,7 @@ NEW_PROP_TAG(EclEnableAquifers);
NEW_PROP_TAG(EclMaxTimeStepSizeAfterWellEvent);
NEW_PROP_TAG(EclRestartShrinkFactor);
NEW_PROP_TAG(EclEnableTuning);
NEW_PROP_TAG(OutputMode);
// Set the problem property
SET_TYPE_PROP(EclBaseProblem, Problem, Opm::EclProblem<TypeTag>);
@ -370,6 +371,10 @@ SET_SCALAR_PROP(EclBaseProblem, EclMaxTimeStepSizeAfterWellEvent, 3600*24*365.25
SET_SCALAR_PROP(EclBaseProblem, EclRestartShrinkFactor, 3);
SET_BOOL_PROP(EclBaseProblem, EclEnableTuning, false);
SET_STRING_PROP(EclBaseProblem, OutputMode, "all");
END_PROPERTIES
namespace Opm {
@ -492,6 +497,9 @@ public:
"Factor by which the time step is reduced after convergence failure");
EWOMS_REGISTER_PARAM(TypeTag, bool, EclEnableTuning,
"Honor some aspects of the TUNING keyword from the ECL deck.");
EWOMS_REGISTER_PARAM(TypeTag, std::string, OutputMode,
"Specify which messages are going to be printed. Valid values are: none, log, all (default)");
}
/*!
@ -636,6 +644,7 @@ public:
// Set the start time of the simulation
simulator.setStartTime(timeMap.getStartTime(/*reportStepIdx=*/0));
simulator.setEndTime(timeMap.getTotalTime());
// We want the episode index to be the same as the report step index to make
// things simpler, so we have to set the episode index to -1 because it is
@ -777,11 +786,11 @@ public:
{
// Proceed to the next report step
auto& simulator = this->simulator();
int episodeIdx = simulator.episodeIndex();
auto& eclState = simulator.vanguard().eclState();
const auto& schedule = simulator.vanguard().schedule();
const auto& events = schedule.getEvents();
const auto& timeMap = schedule.getTimeMap();
int episodeIdx = simulator.episodeIndex();
if (episodeIdx >= 0 && events.hasEvent(Opm::ScheduleEvents::GEO_MODIFIER, episodeIdx)) {
// bring the contents of the keywords to the current state of the SCHEDULE
@ -803,14 +812,18 @@ public:
if (enableExperiments && this->gridView().comm().rank() == 0 && episodeIdx >= 0) {
// print some useful information in experimental mode. (the production
// simulator does this externally.)
std::ostringstream ss;
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
boost::posix_time::ptime curDateTime =
boost::posix_time::from_time_t(timeMap.getStartTime(episodeIdx));
std::cout << "Report step " << episodeIdx + 1
ss.imbue(std::locale(std::locale::classic(), facet));
ss << "Report step " << episodeIdx + 1
<< "/" << timeMap.numTimesteps()
<< " at day " << timeMap.getTimePassedUntil(episodeIdx)/(24*3600)
<< "/" << timeMap.getTotalTime()/(24*3600)
<< ", date = " << curDateTime.date()
<< "\n ";
OpmLog::info(ss.str());
}
// react to TUNING changes
@ -859,9 +872,23 @@ public:
void beginTimeStep()
{
const auto& simulator = this->simulator();
int epsiodeIdx = simulator.episodeIndex();
int episodeIdx = simulator.episodeIndex();
if (enableExperiments && this->gridView().comm().rank() == 0 && episodeIdx >= 0) {
std::ostringstream ss;
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
boost::posix_time::ptime date = boost::posix_time::from_time_t((this->simulator().startTime())) + boost::posix_time::milliseconds(static_cast<long long>(this->simulator().time() / Opm::prefix::milli));
ss.imbue(std::locale(std::locale::classic(), facet));
ss <<"\nTime step " << this->simulator().timeStepIndex() << ", stepsize "
<< unit::convert::to(this->simulator().timeStepSize(), unit::day) << " days,"
<< " at day " << (double)unit::convert::to(this->simulator().time(), unit::day)
<< "/" << (double)unit::convert::to(this->simulator().endTime(), unit::day)
<< ", date = " << date;
OpmLog::info(ss.str());
}
bool invalidateIntensiveQuantities = false;
const auto& oilVaporizationControl = simulator.vanguard().schedule().getOilVaporizationProperties(epsiodeIdx);
const auto& oilVaporizationControl = simulator.vanguard().schedule().getOilVaporizationProperties(episodeIdx);
if (drsdtActive_())
// DRSDT is enabled
for (size_t pvtRegionIdx = 0; pvtRegionIdx < maxDRs_.size(); ++pvtRegionIdx)

211
ebos/startEbos.hh Normal file
View File

@ -0,0 +1,211 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
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 2 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 <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
* \brief Provides convenience routines to bring up the simulation at runtime.
*/
#ifndef EWOMS_STARTEBOS_HH
#define EWOMS_STARTEBOS_HH
#include "ebos.hh"
#include <opm/models/utils/start.hh>
#if HAVE_MPI
#include <mpi.h>
#endif
#if HAVE_ECL_INPUT
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/OpmLog/EclipsePRTLog.hpp>
#include <opm/common/OpmLog/LogUtil.hpp>
#endif
BEGIN_PROPERTIES
// forward declaration of property tags
NEW_PROP_TAG(Scalar);
NEW_PROP_TAG(Simulator);
NEW_PROP_TAG(ThreadManager);
NEW_PROP_TAG(PrintProperties);
NEW_PROP_TAG(PrintParameters);
NEW_PROP_TAG(ParameterFile);
NEW_PROP_TAG(Problem);
END_PROPERTIES
//! \cond SKIP_THIS
namespace Opm {
enum class FileOutputMode {
//! \brief No output to files.
OUTPUT_NONE = 0,
//! \brief Output only to log files, no eclipse output.
OUTPUT_LOG_ONLY = 1,
//! \brief Output to all files.
OUTPUT_ALL = 3
};
static void ensureOutputDirExists(const std::string& cmdline_output_dir)
{
if (!boost::filesystem::is_directory(cmdline_output_dir)) {
try {
boost::filesystem::create_directories(cmdline_output_dir);
}
catch (...) {
throw std::runtime_error("Creation of output directory '" + cmdline_output_dir + "' failed\n");
}
}
}
// Setup the OpmLog backends
static FileOutputMode setupLogging(int mpi_rank_, const std::string& deck_filename, const std::string& cmdline_output_dir, const std::string& cmdline_output, bool output_cout_, const std::string& stdout_log_id) {
if (!cmdline_output_dir.empty()) {
ensureOutputDirExists(cmdline_output_dir);
}
// create logFile
using boost::filesystem::path;
path fpath(deck_filename);
std::string baseName;
std::ostringstream debugFileStream;
std::ostringstream logFileStream;
// Strip extension "." or ".DATA"
std::string extension = boost::to_upper_copy(fpath.extension().string());
if (extension == ".DATA" || extension == ".") {
baseName = boost::to_upper_copy(fpath.stem().string());
} else {
baseName = boost::to_upper_copy(fpath.filename().string());
}
std::string output_dir = cmdline_output_dir;
if (output_dir.empty()) {
output_dir = absolute(path(baseName).parent_path()).string();
}
logFileStream << output_dir << "/" << baseName;
debugFileStream << output_dir << "/" << baseName;
if (mpi_rank_ != 0) {
// Added rank to log file for non-zero ranks.
// This prevents message loss.
debugFileStream << "." << mpi_rank_;
// If the following file appears then there is a bug.
logFileStream << "." << mpi_rank_;
}
logFileStream << ".PRT";
debugFileStream << ".DBG";
FileOutputMode output;
{
static std::map<std::string, FileOutputMode> stringToOutputMode =
{ {"none", FileOutputMode::OUTPUT_NONE },
{"false", FileOutputMode::OUTPUT_LOG_ONLY },
{"log", FileOutputMode::OUTPUT_LOG_ONLY },
{"all" , FileOutputMode::OUTPUT_ALL },
{"true" , FileOutputMode::OUTPUT_ALL }};
auto outputModeIt = stringToOutputMode.find(cmdline_output);
if (outputModeIt != stringToOutputMode.end()) {
output = outputModeIt->second;
}
else {
output = FileOutputMode::OUTPUT_ALL;
std::cerr << "Value " << cmdline_output <<
" is not a recognized output mode. Using \"all\" instead."
<< std::endl;
}
}
if (output > FileOutputMode::OUTPUT_NONE) {
std::shared_ptr<Opm::EclipsePRTLog> prtLog = std::make_shared<Opm::EclipsePRTLog>(logFileStream.str(), Opm::Log::NoDebugMessageTypes, false, output_cout_);
Opm::OpmLog::addBackend("ECLIPSEPRTLOG", prtLog);
prtLog->setMessageLimiter(std::make_shared<Opm::MessageLimiter>());
prtLog->setMessageFormatter(std::make_shared<Opm::SimpleMessageFormatter>(false));
}
if (output >= FileOutputMode::OUTPUT_LOG_ONLY) {
std::string debugFile = debugFileStream.str();
std::shared_ptr<Opm::StreamLog> debugLog = std::make_shared<Opm::EclipsePRTLog>(debugFileStream.str(), Opm::Log::DefaultMessageTypes, false, output_cout_);
Opm::OpmLog::addBackend("DEBUGLOG", debugLog);
}
std::shared_ptr<Opm::StreamLog> streamLog = std::make_shared<Opm::StreamLog>(std::cout, Opm::Log::StdoutMessageTypes);
Opm::OpmLog::addBackend(stdout_log_id, streamLog);
streamLog->setMessageFormatter(std::make_shared<Opm::SimpleMessageFormatter>(true));
return output;
}
//! \endcond
/*!
* \ingroup Common
*
* \brief Wrapper around the main function that set up the OPM
* logging (.PRT, .DBG) for ebos.
*
* \tparam TypeTag The type tag of the problem which needs to be solved
*
* \param argc The number of command line arguments
* \param argv The array of the command line arguments
*/
template <class TypeTag>
static inline int startEbos(int argc, char **argv)
{
int myRank = 0;
#if HAVE_DUNE_FEM
Dune::Fem::MPIManager::initialize(argc, argv);
myRank = Dune::Fem::MPIManager::rank();
#else
myRank = Dune::MPIHelper::instance(argc, argv).rank();
#endif
int paramStatus = setupParameters_<TypeTag>(argc, const_cast<const char**>(argv), /*registerParams=*/true);
if (paramStatus == 1)
return 1;
if (paramStatus == 2)
return 0;
bool outputCout = false;
if (myRank == 0)
outputCout = EWOMS_GET_PARAM(TypeTag, bool, EnableTerminalOutput);
std::string deckFilename = EWOMS_GET_PARAM(TypeTag, std::string, EclDeckFileName);
setupLogging(myRank,
deckFilename,
EWOMS_GET_PARAM(TypeTag, std::string, OutputDir),
EWOMS_GET_PARAM(TypeTag, std::string, OutputMode),
outputCout, "STDOUT_LOGGER");
// Call the main function. Parameters are already registered
// They should not be registered again
return Opm::start<TypeTag>(argc, argv, /*registerParams=*/false);
}
} // namespace Opm
#endif

View File

@ -50,14 +50,11 @@
BEGIN_PROPERTIES
NEW_PROP_TAG(OutputMode);
NEW_PROP_TAG(EnableDryRun);
NEW_PROP_TAG(OutputInterval);
NEW_PROP_TAG(UseAmg);
NEW_PROP_TAG(EnableLoggingFalloutWarning);
SET_STRING_PROP(EclFlowProblem, OutputMode, "all");
// TODO: enumeration parameters. we use strings for now.
SET_STRING_PROP(EclFlowProblem, EnableDryRun, "auto");
// Do not merge parallel output files or warn about them
@ -87,8 +84,6 @@ namespace Opm
static int setupParameters_(int argc, char** argv)
{
// register the flow specific parameters
EWOMS_REGISTER_PARAM(TypeTag, std::string, OutputMode,
"Specify which messages are going to be printed. Valid values are: none, log, all (default)");
EWOMS_REGISTER_PARAM(TypeTag, std::string, EnableDryRun,
"Specify if the simulation ought to be actually run, or just pretended to be");
EWOMS_REGISTER_PARAM(TypeTag, int, OutputInterval,
@ -472,7 +467,6 @@ namespace Opm
SimulatorReport successReport = simulator_->run(simtimer);
SimulatorReport failureReport = simulator_->failureReport();
if (output_cout) {
std::ostringstream ss;
ss << "\n\n================ End of simulation ===============\n\n";