Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 28 additions & 30 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ option(ENABLE_XIOS "Enable XIOS library for IO" OFF)
option(BUILD_TESTS "Build the tests" ON)
set(DynamicsType
"DG2"
CACHE STRING
"Set the discretization order for the dynamics, either DG1 or DG2"
)
CACHE STRING "Set the discretization order for the dynamics, either DG1 or DG2")

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

# all nextsim code is collected in a library to allow for reuse in the tests
# the code is added after processing the subdirectories
# all nextsim code is collected in a library to allow for reuse in the tests the code is added after
# processing the subdirectories
add_library(nextsimlib SHARED)
# modern way to set the standard is redundant since we also do it globally
target_compile_features(nextsimlib PUBLIC cxx_std_17)
Expand All @@ -32,7 +30,10 @@ if(NETCDF_CXX4_FOUND)
set(netCDF_INCLUDE_DIR "${NETCDF_CXX4_INCLUDE_DIRS}")
set(netCDF_LIB_DIR "${NETCDF_CXX4_LIBRARY_DIRS}")
else()
find_package(NetCDF COMPONENTS C CXX REQUIRED)
find_package(
NetCDF
COMPONENTS C CXX
REQUIRED)
set(NSDG_NetCDF_Library "${NetCDF_LIBRARIES}")
set(netCDF_INCLUDE_DIR "${NetCDF_INCLUDE_DIRS}")
endif()
Expand All @@ -45,10 +46,8 @@ if(BUILD_TESTS)
# Add the doctest header library
set(DOCTEST_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_library(doctest::doctest IMPORTED INTERFACE)
set_property(
TARGET doctest::doctest
PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${DOCTEST_INCLUDE_DIR}"
)
set_property(TARGET doctest::doctest PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"${DOCTEST_INCLUDE_DIR}")
enable_testing() # Enable ctest
endif()

Expand All @@ -57,22 +56,23 @@ find_package(Eigen3 3.4 REQUIRED)
target_link_libraries(nextsimlib PUBLIC Eigen3::Eigen)

if(DEFINED PYTHON_EXECUTABLE)
set(Python_EXECUTABLE PYTHON_EXECUTABLE CACHE STRING "")
set(Python_EXECUTABLE
PYTHON_EXECUTABLE
CACHE STRING "")
else()
set(Python_FIND_VIRTUALENV FIRST)
find_package(Python COMPONENTS Interpreter)
endif()


# The location of the module_builder.py scripts
set(ScriptDirectory "${PROJECT_SOURCE_DIR}/scripts")
set(ModuleBuilderScript "${ScriptDirectory}/module_builder.py")
set(ModuleHeaderScript "${ScriptDirectory}/module_header.py")

# Dynamics type. Defaults to DG1.
# Available options are:
# DG1 Discontinuous Galerkin, degree 1 (3 components)
# DG2 Discontinuous Galerkin, degree 2 (6 components)
# Dynamics type. Defaults to DG1. Available options are:
#
# * "DG1" Discontinuous Galerkin, degree 1 (3 components)
# * "DG2" Discontinuous Galerkin, degree 2 (6 components)
set(isDG FALSE)

message("Dynamics is set to ${DynamicsType}")
Expand Down Expand Up @@ -109,21 +109,19 @@ if(isDG)
set(ModelArrayStructure "discontinuousgalerkin")
endif()
# set degree / component parameters
target_compile_definitions(
nextsimlib
PRIVATE DGCOMP=${DGComp} DGSTRESSCOMP=${DGStressComp} CGDEGREE=${CGDegree}
)
target_compile_definitions(nextsimlib PRIVATE DGCOMP=${DGComp} DGSTRESSCOMP=${DGStressComp}
CGDEGREE=${CGDegree})

# boost
find_package(Boost COMPONENTS program_options log REQUIRED)
target_link_libraries(nextsimlib PUBLIC Boost::program_options Boost::log)
# Regarding Boost.Log, if our application consists of more
# than one modules that use it, we must link to the shared
# version. If we have a single executable or a single module
# that works, we may use the static version.
# By default, it is assumed that the library is built in
# static mode. Use the following definition to indicate that
# the code will be linked against dynamically loaded boost
find_package(
Boost
COMPONENTS program_options log_setup log
REQUIRED)
target_link_libraries(nextsimlib PUBLIC Boost::program_options Boost::log_setup Boost::log)
# Regarding Boost.Log, if our application consists of more than one modules that use it, we must
# link to the shared version. If we have a single executable or a single module that works, we may
# use the static version. By default, it is assumed that the library is built in static mode. Use
# the following definition to indicate that the code will be linked against dynamically loaded boost
# libraries.
target_compile_definitions(nextsimlib PUBLIC BOOST_ALL_DYN_LINK)

Expand All @@ -150,7 +148,7 @@ if(ENABLE_XIOS)
)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(FORTRAN_RUNTIME_LIB "-lgfortran")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
set(FORTRAN_RUNTIME_LIB "-lifcore")
endif()
target_link_libraries(nextsimlib PUBLIC "${FORTRAN_RUNTIME_LIB}")
Expand Down
46 changes: 37 additions & 9 deletions core/src/Logged.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
/*!
* @author Tim Spain <timothy.spain@nersc.no>
* @author Robert Jendersie <robert.jendersie@ovgu.de>
*/

#include "include/Logged.hpp"

#include "include/Configured.hpp"

#include <boost/log/attributes/clock.hpp>
#include <boost/log/common.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <iostream>

using namespace std::literals::string_literals;

namespace Nextsim {

const std::map<std::string, Logged::level> Logged::levelNames = {
Expand Down Expand Up @@ -40,13 +44,30 @@ const std::map<std::string, Logged::level> Logged::levelNames = {
{ "NONE", level::NONE },
};

static constexpr std::array<const char*, static_cast<int>(Logged::level::count)> PRINTED_LEVEL_NAMES
= { "all", "trace", "debug", "info", "warning", "error", "critical", "fatal", "alert",
"emergency", "none" };

BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "Severity", Logged::level)

template <typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>& operator<<(
std::basic_ostream<CharT, TraitsT>& stream, const Logged::level& lvl)
{
stream << PRINTED_LEVEL_NAMES[static_cast<int>(lvl)];
return stream;
}

boost::log::sources::severity_logger<Logged::level> sl;

// Initialize the logger, that is set up boost::log how we want it
void Logged::configure()
{
// additional attributes to use during formatting
boost::log::register_simple_formatter_factory<Logged::level, char>("Severity");
boost::log::core::get()->add_global_attribute(
"TimeStamp", boost::log::attributes::local_clock());

/*
* The enum and keyMap that would usually be inherited from Configured are
* defined here so that a class can be derived from Logged
Expand All @@ -64,18 +85,25 @@ void Logged::configure()
{ CONSOLE_LOG_LEVEL_KEY, "Logged.console_log_level" },
};

level minimumLogLevel = levelNames.at(Configured<Logged>::getConfiguration(
keyMap.at(MINIMUM_LOG_LEVEL_KEY), std::string("info")));
std::string fileNamePattern = Configured<Logged>::getConfiguration(
keyMap.at(FILE_NAME_PATTERN_KEY), std::string("nextsim.%T.log"));
// the format string used for both console and file outputs
constexpr const char* format = "[%TimeStamp%] [%Severity%] %Message%";

level minimumLogLevel = levelNames.at(
Configured<Logged>::getConfiguration(keyMap.at(MINIMUM_LOG_LEVEL_KEY), "info"s));
std::string fileNamePattern
= Configured<Logged>::getConfiguration(keyMap.at(FILE_NAME_PATTERN_KEY), "nextsim.%T.log"s);

boost::log::add_file_log(boost::log::keywords::file_name = fileNamePattern,
// All logs go to file above the minimum level
boost::log::keywords::filter = (Severity >= minimumLogLevel));
boost::log::keywords::filter = (Severity >= minimumLogLevel),
boost::log::keywords::format = format);

level consoleLogLevel = levelNames.at(
Configured<Logged>::getConfiguration(keyMap.at(CONSOLE_LOG_LEVEL_KEY), "error"s));

level consoleLogLevel = levelNames.at(Configured<Logged>::getConfiguration(
keyMap.at(CONSOLE_LOG_LEVEL_KEY), std::string("error")));
boost::log::add_console_log(
std::cout, boost::log::keywords::filter = (Severity >= consoleLogLevel));
boost::log::add_console_log(std::cout,
boost::log::keywords::filter = (Severity >= consoleLogLevel),
boost::log::keywords::format = format);
}

void Logged::log(const std::string& message, Logged::level lvl)
Expand Down
3 changes: 2 additions & 1 deletion core/src/include/Logged.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class Logged {
CRITICAL,
ALERT,
EMERGENCY,
NONE
NONE,
count // special element to get the number of levels
};

static const std::map<std::string, level> levelNames;
Expand Down
Loading