Compare commits
3 Commits
release/20
...
release/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e77807ff0 | ||
|
|
a732ddeb50 | ||
|
|
4768b5cd95 |
@@ -1,20 +0,0 @@
|
||||
{
|
||||
BasedOnStyle: WebKit,
|
||||
AlignAfterOpenBracket: AlwaysBreak,
|
||||
AlignConsecutiveAssignments: false,
|
||||
AlignConsecutiveDeclarations: false,
|
||||
AlignAfterOpenBracket: Align,
|
||||
AllowShortBlocksOnASingleLine: false,
|
||||
AllowShortFunctionsOnASingleLine: None,
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions,
|
||||
AlwaysBreakTemplateDeclarations: Yes,
|
||||
BinPackArguments: false,
|
||||
BinPackParameters: false,
|
||||
BreakBeforeBraces: Linux,
|
||||
BreakConstructorInitializers: BeforeComma,
|
||||
ColumnLimit: 120,
|
||||
Cpp11BracedListStyle: true,
|
||||
FixNamespaceComments: true,
|
||||
MaxEmptyLinesToKeep: 5,
|
||||
NamespaceIndentation: Inner,
|
||||
}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -69,7 +69,3 @@ install
|
||||
|
||||
# emacs directory setting:
|
||||
.dir-locals.el
|
||||
|
||||
*.pyc
|
||||
*.eggs
|
||||
*.egg-info
|
||||
|
||||
0
.gitmodules
vendored
0
.gitmodules
vendored
356
CMakeLists.txt
356
CMakeLists.txt
@@ -1,5 +1,5 @@
|
||||
project(opm-common C CXX)
|
||||
cmake_minimum_required (VERSION 3.10)
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
option(SIBLING_SEARCH "Search for other modules in sibling directories?" ON)
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)
|
||||
@@ -7,10 +7,6 @@ set(OPM_MACROS_ROOT ${PROJECT_SOURCE_DIR})
|
||||
|
||||
option(ENABLE_ECL_INPUT "Enable eclipse input support?" ON)
|
||||
option(ENABLE_ECL_OUTPUT "Enable eclipse output support?" ON)
|
||||
option(ENABLE_MOCKSIM "Build the mock simulator for io testing" ON)
|
||||
option(OPM_ENABLE_PYTHON "Enable python bindings?" OFF)
|
||||
option(OPM_INSTALL_PYTHON "Enable python bindings?" OFF)
|
||||
option(OPM_ENABLE_EMBEDDED_PYTHON "Enable embedded python?" OFF)
|
||||
|
||||
# Output implies input
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
@@ -22,7 +18,6 @@ if(NOT ENABLE_ECL_INPUT)
|
||||
set(ENABLE_ECL_OUTPUT OFF)
|
||||
endif()
|
||||
|
||||
|
||||
# not the same location as most of the other projects; this hook overrides
|
||||
macro (dir_hook)
|
||||
endmacro (dir_hook)
|
||||
@@ -53,7 +48,6 @@ endif()
|
||||
# we cannot generate dune.module since it is read by dunecontrol before
|
||||
# the build starts, so it makes sense to keep the data there then.
|
||||
include (OpmInit)
|
||||
OpmSetPolicies()
|
||||
|
||||
# Look for the opm-tests repository; if found the variable
|
||||
# HAVE_OPM_TESTS will be set to true.
|
||||
@@ -64,20 +58,6 @@ include(Findopm-tests)
|
||||
# with the find module
|
||||
include (${project}-prereqs)
|
||||
|
||||
if(ENABLE_ECL_INPUT)
|
||||
# source_hook runs before config_hook and the former needs fmt, hence this
|
||||
# needs to be here.
|
||||
if(fmt_FOUND)
|
||||
# OpmSatellites will not add the library, do it here.
|
||||
list(APPEND opm-common_LIBRARIES fmt::fmt)
|
||||
else()
|
||||
add_definitions(-DFMT_HEADER_ONLY)
|
||||
include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/external/fmtlib/include)
|
||||
# Not sure why this is needed.
|
||||
list(APPEND EXTRA_INCLUDES ${PROJECT_SOURCE_DIR}/external/fmtlib/include)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# read the list of components from this file (in the project directory);
|
||||
# it should set various lists with the names of the files to include
|
||||
include (CMakeLists_files.cmake)
|
||||
@@ -87,9 +67,9 @@ macro (config_hook)
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND EXTRA_INCLUDES ${PROJECT_SOURCE_DIR}/external/cjson)
|
||||
endif()
|
||||
|
||||
# For this project
|
||||
include_directories(${EXTRA_INCLUDES} ${PROJECT_BINARY_DIR}/include)
|
||||
|
||||
# For downstreams
|
||||
list(APPEND EXTRA_INCLUDES ${PROJECT_BINARY_DIR}/include)
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
|
||||
@@ -125,16 +105,8 @@ macro (sources_hook)
|
||||
include(GenerateKeywords.cmake)
|
||||
|
||||
# Append generated sources
|
||||
list(INSERT opm-common_SOURCES 0 ${PROJECT_BINARY_DIR}/ParserInit.cpp)
|
||||
foreach (name A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
|
||||
list(INSERT opm-common_SOURCES 0 ${PROJECT_BINARY_DIR}/ParserKeywords/${name}.cpp)
|
||||
endforeach()
|
||||
if (OPM_ENABLE_PYTHON)
|
||||
list(INSERT opm-common_SOURCES 0 ${PROJECT_BINARY_DIR}/python/cxx/builtin_pybind11.cpp)
|
||||
endif()
|
||||
list(APPEND opm-common_SOURCES ${PROJECT_BINARY_DIR}/ParserKeywords.cpp)
|
||||
endif()
|
||||
set_source_files_properties(src/opm/parser/eclipse/Python/Python.cpp
|
||||
PROPERTIES COMPILE_FLAGS -Wno-shadow)
|
||||
endmacro (sources_hook)
|
||||
|
||||
macro (fortran_hook)
|
||||
@@ -155,316 +127,40 @@ macro (install_hook)
|
||||
PATTERN *.hpp)
|
||||
endmacro (install_hook)
|
||||
|
||||
# If opm-common is configured to embed the python interpreter we must make sure
|
||||
# that all downstream modules link libpython transitively. Due to the required
|
||||
# integration with Python+cmake machinery provided by pybind11 this is done by
|
||||
# manually adding to the opm-common_LIBRARIES variable here, and not in the
|
||||
# OpmnLibMain function. Here only the library dependency is implemented, the
|
||||
# bulk of the python configuration is further down in the file.
|
||||
if (OPM_ENABLE_PYTHON)
|
||||
# We need to be compatible with older CMake versions
|
||||
# that do not offer FindPython3
|
||||
# e.g. Ubuntu LTS 18.04 uses cmake 3.10
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
|
||||
find_package(PythonInterp REQUIRED)
|
||||
if (OPM_ENABLE_EMBEDDED_PYTHON)
|
||||
find_package(PythonLibs REQUIRED)
|
||||
list(APPEND opm-common_LIBRARIES ${PYTHON_LIBRARIES})
|
||||
endif()
|
||||
if(PYTHON_VERSION_MAJOR LESS 3)
|
||||
message(SEND_ERROR "OPM requires version 3 of Python but only version ${PYTHON_VERSION_STRING} was found")
|
||||
endif()
|
||||
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
|
||||
set(Python3_LIBRARIES ${PYTHON_LIBRARIES})
|
||||
else()
|
||||
# Be backwards compatible.
|
||||
if(PYTHON_EXECUTABLE AND NOT Python3_EXECUTABLE)
|
||||
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
|
||||
endif()
|
||||
if (OPM_ENABLE_EMBEDDED_PYTHON)
|
||||
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
|
||||
get_target_property(_lib_path Python3::Python IMPORTED_LOCATION)
|
||||
set(PYTHON_LIBRARY ${_lib_path})
|
||||
set(PYTHON_LIBRARIES {PYTHON_LIBRARY})
|
||||
list(APPEND opm-common_LIBRARIES ${PYTHON_LIBRARY})
|
||||
set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS})
|
||||
else()
|
||||
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||
endif()
|
||||
# Compatibility settings for PythonInterp and PythonLibs
|
||||
# used e.g. in FindCwrap, pybind11
|
||||
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
|
||||
endif()
|
||||
# We always need the PYTHON_INCLUDE_DIR. Unfortunately
|
||||
# When we build pypi packages CMake will fail to determine
|
||||
# these via the usual find_package(PythonLibs or
|
||||
# find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
|
||||
# Hence we overwrite them here.
|
||||
if(NOT PYTHON_INCLUDE_DIRS)
|
||||
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "from distutils import sysconfig; print(sysconfig.get_python_inc(plat_specific=True), end=\"\");"
|
||||
RESULT_VARIABLE _PYTHON_DIR_SUCCESS
|
||||
OUTPUT_VARIABLE PYTHON_INCLUDE_DIR
|
||||
ERROR_VARIABLE _PYTHON_ERROR_VALUE)
|
||||
if(NOT _PYTHON_DIR_SUCCESS MATCHES 0)
|
||||
message(FATAL_ERROR "Could not determine Python include directory. Error: ${_PYTHON_ERROR_VALUE}.")
|
||||
endif()
|
||||
set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIR})
|
||||
endif()
|
||||
find_package(pybind11 2.2 CONFIG)
|
||||
if (NOT pybind11_FOUND)
|
||||
# Use full path for reuse with pypi
|
||||
set(pybind11_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/python/pybind11/include ${PYTHON_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# all setup common to the OPM library modules is done here
|
||||
include (OpmLibMain)
|
||||
|
||||
if (ENABLE_MOCKSIM)
|
||||
add_library(mocksim
|
||||
msim/src/msim.cpp)
|
||||
target_link_libraries(mocksim opmcommon)
|
||||
target_include_directories(mocksim PUBLIC msim/include)
|
||||
add_executable(msim examples/msim.cpp)
|
||||
target_link_libraries(msim mocksim)
|
||||
|
||||
if (Boost_UNIT_TEST_FRAMEWORK_FOUND)
|
||||
set(_libs mocksim opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
|
||||
foreach( test test_msim test_msim_ACTIONX test_msim_EXIT)
|
||||
opm_add_test(${test} SOURCES tests/msim/${test}.cpp
|
||||
LIBRARIES ${_libs}
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests
|
||||
CONDITION ${HAVE_ECL_INPUT})
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ENABLE_SCHEDULE_DEBUG)
|
||||
add_compile_definitions( SCHEDULE_DEBUG )
|
||||
endif()
|
||||
|
||||
# Build the compare utilities
|
||||
if(ENABLE_ECL_INPUT)
|
||||
add_executable(compareECL
|
||||
test_util/EclFilesComparator.cpp
|
||||
test_util/EclRegressionTest.cpp
|
||||
test_util/compareECL.cpp
|
||||
)
|
||||
|
||||
add_executable(convertECL
|
||||
test_util/convertECL.cpp
|
||||
)
|
||||
|
||||
add_executable(summary
|
||||
test_util/summary.cpp
|
||||
)
|
||||
|
||||
add_executable(rewriteEclFile
|
||||
test_util/rewriteEclFile.cpp
|
||||
)
|
||||
|
||||
foreach(target compareECL convertECL summary rewriteEclFile)
|
||||
target_link_libraries(${target} opmcommon)
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
endforeach()
|
||||
add_library(testutil STATIC
|
||||
examples/test_util/EclFilesComparator.cpp
|
||||
examples/test_util/EclIntegrationTest.cpp
|
||||
examples/test_util/EclRegressionTest.cpp
|
||||
examples/test_util/summaryComparator.cpp
|
||||
examples/test_util/summaryIntegrationTest.cpp
|
||||
examples/test_util/summaryRegressionTest.cpp)
|
||||
target_link_libraries(testutil ecl)
|
||||
add_executable(compareECL examples/test_util/compareECL.cpp)
|
||||
target_link_libraries(compareECL testutil opmcommon)
|
||||
|
||||
# Add the tests
|
||||
set(_libs opmcommon
|
||||
set(_libs testutil opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
|
||||
opm_add_test(test_EclFilesComparator
|
||||
CONDITION
|
||||
ENABLE_ECL_INPUT AND Boost_UNIT_TEST_FRAMEWORK_FOUND
|
||||
SOURCES
|
||||
tests/test_EclFilesComparator.cpp
|
||||
test_util/EclFilesComparator.cpp
|
||||
LIBRARIES
|
||||
${_libs}
|
||||
WORKING_DIRECTORY
|
||||
${PROJECT_BINARY_DIR}/tests
|
||||
)
|
||||
|
||||
opm_add_test(test_EclRegressionTest
|
||||
CONDITION
|
||||
ENABLE_ECL_INPUT AND Boost_UNIT_TEST_FRAMEWORK_FOUND
|
||||
SOURCES
|
||||
tests/test_EclRegressionTest.cpp
|
||||
test_util/EclFilesComparator.cpp
|
||||
test_util/EclRegressionTest.cpp
|
||||
LIBRARIES
|
||||
${_libs}
|
||||
WORKING_DIRECTORY
|
||||
${PROJECT_BINARY_DIR}/tests
|
||||
)
|
||||
|
||||
foreach(test test_EclIO test_EGrid test_ERft test_ERst test_ESmry test_EInit)
|
||||
opm_add_test(${test} CONDITION ENABLE_ECL_INPUT AND Boost_UNIT_TEST_FRAMEWORK_FOUND
|
||||
LIBRARIES ${_libs}
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests)
|
||||
endforeach()
|
||||
opm_add_test(test_compareSummary CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs})
|
||||
opm_add_test(test_EclFilesComparator CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs})
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties(test_compareSummary PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
set_target_properties(test_EclFilesComparator PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
install(TARGETS compareECL DESTINATION bin)
|
||||
endif()
|
||||
|
||||
# Install build system files
|
||||
install(DIRECTORY cmake DESTINATION share/opm USE_SOURCE_PERMISSIONS)
|
||||
install(DIRECTORY cmake DESTINATION share/opm)
|
||||
|
||||
# Install tab completion skeleton
|
||||
install(FILES etc/opm_bash_completion.sh.in DESTINATION share/opm/etc)
|
||||
|
||||
if (OPM_ENABLE_PYTHON)
|
||||
# -------------------------------------------------------------------------
|
||||
# 1: Wrap C++ functionality in Python
|
||||
if (EXISTS "/etc/debian_version")
|
||||
set(PYTHON_PACKAGE_PATH "dist-packages")
|
||||
else()
|
||||
set(PYTHON_PACKAGE_PATH "site-packages")
|
||||
endif()
|
||||
set(PYTHON_INSTALL_PREFIX "lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/${PYTHON_PACKAGE_PATH}" CACHE STRING "Subdirectory to install Python modules in")
|
||||
|
||||
make_directory(${PROJECT_BINARY_DIR}/python)
|
||||
get_target_property(_opmcommon_include_dirs opmcommon INCLUDE_DIRECTORIES)
|
||||
list(APPEND _opmcommon_include_dirs ${_ecl_include_dirs})
|
||||
string(REPLACE ";" ":" _setup_include_dirs "${_opmcommon_include_dirs}")
|
||||
|
||||
get_target_property(_opmcommon_lib_dirs opmcommon LINK_DIRECTORIES)
|
||||
if (CMAKE_PREFIX_PATH)
|
||||
list(APPEND _opmcommon_lib_dirs ${PROJECT_BINARY_DIR}/lib ${CMAKE_PREFIX_PATH}/${CMAKE_INSTALL_LIBDIR})
|
||||
else()
|
||||
list(APPEND _opmcommon_lib_dirs ${PROJECT_BINARY_DIR}/lib)
|
||||
endif()
|
||||
string(REPLACE ";" ":" _setup_lib_dirs "${_opmcommon_lib_dirs}")
|
||||
|
||||
if (USE_RUNPATH)
|
||||
set (_python_rpath_list)
|
||||
if (CMAKE_PREFIX_PATH)
|
||||
foreach(path ${CMAKE_PREFIX_PATH})
|
||||
list(APPEND _python_rpath_list "${path}/${CMAKE_INSTALL_LIBDIR}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
list(APPEND _python_rpath_list "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
||||
endif()
|
||||
|
||||
if (_python_rpath_list)
|
||||
string(REPLACE ";" ":" _rpath "${_python_rpath_list}")
|
||||
set( _rpath_arg "--rpath=${_rpath}")
|
||||
else()
|
||||
set(_rpath_arg "")
|
||||
endif()
|
||||
else()
|
||||
set( _rpath_arg "")
|
||||
endif()
|
||||
|
||||
set(opm-common_PYTHON_PACKAGE_VERSION ${OPM_PYTHON_PACKAGE_VERSION_TAG})
|
||||
|
||||
# Generate versioned setup.py
|
||||
if (pybind11_INCLUDE_DIRS)
|
||||
string(REGEX REPLACE ";" "', '" _tmp "${pybind11_INCLUDE_DIRS}")
|
||||
set(SETUP_PY_PYBIND_INCLUDE_DIR "'${_tmp}'")
|
||||
endif()
|
||||
|
||||
if (TARGET fmt::fmt)
|
||||
get_target_property(SETUP_PY_FMT_LIBS fmt::fmt LOCATION)
|
||||
get_target_property(FMT_FLAGS fmt::fmt INTERFACE_COMPILE_DEFINITIONS)
|
||||
foreach(flag ${FMT_FLAGS})
|
||||
set(SETUP_PY_FMT_FLAGS "${SETUP_PY_FMT_FLAGS} '-D${flag}',")
|
||||
endforeach()
|
||||
list(APPEND opm-common_PYTHON_LINKAGE "'${SETUP_PY_FMT_LIBS}'")
|
||||
else()
|
||||
set(SETUP_PY_FMT_FLAGS "'-DFMT_HEADER_ONLY'")
|
||||
endif()
|
||||
|
||||
configure_file (${PROJECT_SOURCE_DIR}/python/setup.py.in ${PROJECT_BINARY_DIR}/python/setup.py)
|
||||
file(COPY ${PROJECT_SOURCE_DIR}/python/README.md DESTINATION ${PROJECT_BINARY_DIR}/python)
|
||||
execute_process(COMMAND ${Python3_EXECUTABLE} target_name.py
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/python
|
||||
OUTPUT_VARIABLE python_lib_target)
|
||||
|
||||
add_custom_target(copy_python ALL
|
||||
COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/install.py ${PROJECT_SOURCE_DIR}/python ${PROJECT_BINARY_DIR} 0)
|
||||
|
||||
add_custom_command(OUTPUT python/opm/${python_lib_target}
|
||||
DEPENDS ${PYTHON_CXX_DEPENDS}
|
||||
DEPENDS copy_python
|
||||
COMMAND ${Python3_EXECUTABLE} ${PROJECT_BINARY_DIR}/python/setup.py
|
||||
build
|
||||
build_ext
|
||||
--build-lib=${PROJECT_BINARY_DIR}/python
|
||||
--library-dirs=${_setup_lib_dirs}
|
||||
${_rpath_arg}
|
||||
--include-dirs=${_setup_include_dirs}
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/python
|
||||
COMMENT "Building python bindings at python/opm/${python_lib_target}")
|
||||
add_custom_target(opmcommon_python ALL DEPENDS python/opm/${python_lib_target})
|
||||
add_dependencies(opmcommon_python opmcommon)
|
||||
|
||||
# The install target is based on manually copying the python file tree to the
|
||||
# installation area with a small installation script 'install.py'. Would have
|
||||
# preferred to use standard setup.py install, but the setup.py based solution
|
||||
# refuses to install to a location which the current python executable can not
|
||||
# load from, and the use of eggs in the setup.py based installation makes
|
||||
# debugging quite difficult.
|
||||
#
|
||||
# Since the installation of Python code is nonstandard it is protected by an
|
||||
# extra cmake switch, OPM_INSTALL_PYTHON. If you prefer you can still invoke
|
||||
# setup.py install manually - optionally with the generated script
|
||||
# setup-install.sh - and completely bypass cmake in the installation phase.
|
||||
if (OPM_INSTALL_PYTHON)
|
||||
install( CODE "execute_process(COMMAND ${Python3_EXECUTABLE} ${PROJECT_BINARY_DIR}/python/install.py ${PROJECT_BINARY_DIR}/python/opm ${DEST_PREFIX}${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX} 1)")
|
||||
endif()
|
||||
|
||||
# Observe that if the opmcommon library has been built as a shared library the
|
||||
# python library opmcommon_python will in general not find it runtime while
|
||||
# testing.
|
||||
add_test(NAME python_tests
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/python
|
||||
COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/lib ${Python3_EXECUTABLE} setup.py build_ext --dry-run --build-lib ${PROJECT_BINARY_DIR}/python test
|
||||
)
|
||||
|
||||
set_target_properties(opmcommon PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${PROJECT_BINARY_DIR}/python)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Let cmake configure some small shell scripts which can be used to simplify
|
||||
# building, testing and installation of the Python extensions.
|
||||
configure_file(python/setup-build.sh.in tmp/setup-build.sh)
|
||||
file( COPY ${PROJECT_BINARY_DIR}/tmp/setup-build.sh
|
||||
DESTINATION ${PROJECT_BINARY_DIR}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
|
||||
|
||||
configure_file(python/setup-package.sh.in tmp/setup-package.sh)
|
||||
file( COPY ${PROJECT_BINARY_DIR}/tmp/setup-package.sh
|
||||
DESTINATION ${PROJECT_BINARY_DIR}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
|
||||
|
||||
configure_file(python/setup-test.sh.in tmp/setup-test.sh)
|
||||
file( COPY ${PROJECT_BINARY_DIR}/tmp/setup-test.sh
|
||||
DESTINATION ${PROJECT_BINARY_DIR}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
|
||||
|
||||
configure_file(python/setup-install.sh.in tmp/setup-install.sh)
|
||||
file( COPY ${PROJECT_BINARY_DIR}/tmp/setup-install.sh
|
||||
DESTINATION ${PROJECT_BINARY_DIR}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
|
||||
|
||||
configure_file(python/enable-python.sh.in enable-python.sh)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# 2: Embed the Python interpreter for keywords like PYACTION and PYINPUT
|
||||
target_include_directories(opmcommon SYSTEM PRIVATE "${pybind11_INCLUDE_DIRS}")
|
||||
if (OPM_ENABLE_EMBEDDED_PYTHON)
|
||||
target_link_libraries(opmcommon PUBLIC ${PYTHON_LIBRARY})
|
||||
add_definitions(-DEMBEDDED_PYTHON)
|
||||
endif()
|
||||
else()
|
||||
if (OPM_ENABLE_EMBEDDED_PYTHON)
|
||||
message(WARNING "Inconsistent settings OPM_ENABLE_PYTHON / OPM_ENABLE_EMBEDDED_PYTHON")
|
||||
set(OPM_ENABLE_EMBEDDED_PYTHON OFF CACHE BOOL "Enable embedded python?" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(DIRECTORY docs/man1 DESTINATION ${CMAKE_INSTALL_MANDIR}
|
||||
FILES_MATCHING PATTERN "*.1")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file sets up five lists:
|
||||
# MAIN_SOURCE_FILES List of compilation units which will be included in
|
||||
# MAIN_SOURCE_FILES List of compilation units which will be included in
|
||||
# the library. If it isn't on this list, it won't be
|
||||
# part of the library. Please try to keep it sorted to
|
||||
# maintain sanity.
|
||||
@@ -21,56 +21,37 @@
|
||||
# the library needs it.
|
||||
|
||||
list (APPEND MAIN_SOURCE_FILES
|
||||
src/opm/common/data/SimulationDataContainer.cpp
|
||||
src/opm/common/OpmLog/CounterLog.cpp
|
||||
src/opm/common/OpmLog/EclipsePRTLog.cpp
|
||||
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
|
||||
src/opm/common/utility/ActiveGridCells.cpp
|
||||
src/opm/common/utility/FileSystem.cpp
|
||||
src/opm/common/utility/numeric/MonotCubicInterpolator.cpp
|
||||
src/opm/common/utility/OpmInputError.cpp
|
||||
src/opm/common/utility/parameters/Parameter.cpp
|
||||
src/opm/common/utility/parameters/ParameterGroup.cpp
|
||||
src/opm/common/utility/parameters/ParameterTools.cpp
|
||||
src/opm/common/utility/numeric/calculateCellVol.cpp
|
||||
src/opm/common/utility/TimeService.cpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND MAIN_SOURCE_FILES
|
||||
src/opm/io/eclipse/SummaryNode.cpp
|
||||
src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Deck/Deck.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckItem.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckValue.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckKeyword.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckRecord.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckOutput.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckSection.cpp
|
||||
src/opm/parser/eclipse/Deck/ImportContainer.cpp
|
||||
src/opm/parser/eclipse/Deck/UDAValue.cpp
|
||||
src/opm/parser/eclipse/Python/Python.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/PyAction.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/AquiferConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/AquiferCT.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/Aquifetp.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/Aquancon.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/AquiferHelpers.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquiferCell.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquiferConnection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/SingleNumericalAquifer.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquifers.cpp
|
||||
src/opm/parser/eclipse/Deck/Section.cpp
|
||||
src/opm/parser/eclipse/EclipseState/AquiferCT.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquancon.cpp
|
||||
src/opm/parser/eclipse/EclipseState/checkDeck.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EclipseConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EclipseState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EndpointScaling.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/FieldProps.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/Box.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/BoxManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.cpp
|
||||
@@ -79,304 +60,157 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Grid/Fault.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/FaultFace.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/GridDims.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/GridProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/NNC.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/Operate.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/PinchMode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/setKeywordBox.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/TransMult.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/Equil.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/FoamConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/InitConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Runspec.cpp
|
||||
src/opm/parser/eclipse/EclipseState/TracerConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/Actdims.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/Actions.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionParser.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionValue.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ASTNode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/Condition.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/State.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/eval_uda.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ActionX.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GPMaint.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/Group.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GConSump.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/GroupTree.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MessageLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/icd.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/AICD.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/SICD.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Network/Branch.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Network/Node.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/RFTConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/RPTConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/RSTConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ScheduleDeck.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ScheduleState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ScheduleTypes.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/Connection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/injection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculator.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/NameOrder.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellFoamProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellPolymerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellBrineProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellTracerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellTestState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/BCConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/RockConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/ColumnSchema.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/DenT.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/JFunc.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/PvtxTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/SimpleTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/PolyInjTables.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/StandardCond.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableColumn.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableContainer.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableIndex.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TLMixpar.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableSchema.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/Tables.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/Rock2dTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/Rock2dtrTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/PvtwsaltTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/BrineDensityTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/RwgsaltTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/SolventDensityTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQASTNode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParser.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQToken.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/UDQConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQExpression.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp
|
||||
src/opm/parser/eclipse/Parser/ErrorGuard.cpp
|
||||
src/opm/parser/eclipse/Parser/ParseContext.cpp
|
||||
src/opm/parser/eclipse/Parser/Parser.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserEnums.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserItem.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserRecord.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawRecord.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/StarToken.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/StarToken.cpp
|
||||
src/opm/parser/eclipse/Units/Dimension.cpp
|
||||
src/opm/parser/eclipse/Units/UnitSystem.cpp
|
||||
src/opm/parser/eclipse/Utility/Functional.cpp
|
||||
src/opm/parser/eclipse/Utility/Stringview.cpp
|
||||
)
|
||||
|
||||
|
||||
# This list is only used to register a CMake dependency between the the python
|
||||
# extension and the corresponding C++ wrapper files. The cpp files actually
|
||||
# listed here are repeated in the actual definition of the extension in the
|
||||
# setup.py file.
|
||||
list( APPEND PYTHON_CXX_SOURCE_FILES
|
||||
python/cxx/connection.cpp
|
||||
python/cxx/converters.cpp
|
||||
python/cxx/deck.cpp
|
||||
python/cxx/deck_keyword.cpp
|
||||
python/cxx/eclipse_io.cpp
|
||||
python/cxx/field_props.cpp
|
||||
python/cxx/eclipse_config.cpp
|
||||
python/cxx/eclipse_grid.cpp
|
||||
python/cxx/eclipse_state.cpp
|
||||
python/cxx/export.cpp
|
||||
python/cxx/group.cpp
|
||||
python/cxx/log.cpp
|
||||
python/cxx/parsecontext.cpp
|
||||
python/cxx/parser.cpp
|
||||
python/cxx/schedule.cpp
|
||||
python/cxx/summary_state.cpp
|
||||
python/cxx/table_manager.cpp
|
||||
python/cxx/unit_system.cpp
|
||||
python/cxx/well.cpp
|
||||
)
|
||||
|
||||
if (OPM_ENABLE_EMBEDDED_PYTHON)
|
||||
set_source_files_properties(${PYTHON_CXX_SOURCE_FILES} PROPERTIES COMPILE_FLAGS -Wno-shadow)
|
||||
set_source_files_properties(src/opm/parser/eclipse/Python/PythonInterp.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow)
|
||||
set_source_files_properties(src/opm/parser/eclipse/EclipseState/Schedule/Action/PyAction.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow)
|
||||
list( APPEND MAIN_SOURCE_FILES
|
||||
src/opm/parser/eclipse/Python/PythonInterp.cpp
|
||||
src/opm/parser/eclipse/Python/PyRunModule.cpp
|
||||
${PYTHON_CXX_SOURCE_FILES})
|
||||
endif()
|
||||
|
||||
list( APPEND PYTHON_CXX_DEPENDS ${PYTHON_CXX_SOURCE_FILES}
|
||||
python/cxx/converters.hpp
|
||||
python/cxx/export.hpp)
|
||||
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND MAIN_SOURCE_FILES external/cjson/cJSON.c)
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list( APPEND MAIN_SOURCE_FILES
|
||||
src/opm/io/eclipse/EclFile.cpp
|
||||
src/opm/io/eclipse/EclOutput.cpp
|
||||
src/opm/io/eclipse/EclUtil.cpp
|
||||
src/opm/io/eclipse/EGrid.cpp
|
||||
src/opm/io/eclipse/EInit.cpp
|
||||
src/opm/io/eclipse/ERft.cpp
|
||||
src/opm/io/eclipse/ERst.cpp
|
||||
src/opm/io/eclipse/ERsm.cpp
|
||||
src/opm/io/eclipse/ESmry.cpp
|
||||
src/opm/io/eclipse/ESmry_write_rsm.cpp
|
||||
src/opm/io/eclipse/OutputStream.cpp
|
||||
src/opm/io/eclipse/SummaryNode.cpp
|
||||
src/opm/io/eclipse/rst/connection.cpp
|
||||
src/opm/io/eclipse/rst/group.cpp
|
||||
src/opm/io/eclipse/rst/header.cpp
|
||||
src/opm/io/eclipse/rst/segment.cpp
|
||||
src/opm/io/eclipse/rst/state.cpp
|
||||
src/opm/io/eclipse/rst/well.cpp
|
||||
src/opm/output/eclipse/ActiveIndexByColumns.cpp
|
||||
src/opm/output/eclipse/AggregateActionxData.cpp
|
||||
src/opm/output/eclipse/AggregateConnectionData.cpp
|
||||
src/opm/output/eclipse/AggregateGroupData.cpp
|
||||
src/opm/output/eclipse/AggregateNetworkData.cpp
|
||||
src/opm/output/eclipse/AggregateMSWData.cpp
|
||||
src/opm/output/eclipse/AggregateUDQData.cpp
|
||||
src/opm/output/eclipse/AggregateWellData.cpp
|
||||
src/opm/output/eclipse/CreateActionxDims.cpp
|
||||
src/opm/output/eclipse/CreateDoubHead.cpp
|
||||
src/opm/output/eclipse/CreateInteHead.cpp
|
||||
src/opm/output/eclipse/CreateLogiHead.cpp
|
||||
src/opm/output/eclipse/CreateUdqDims.cpp
|
||||
src/opm/output/eclipse/WellDataSerializers.cpp
|
||||
src/opm/output/eclipse/DoubHEAD.cpp
|
||||
src/opm/output/eclipse/EclipseGridInspector.cpp
|
||||
src/opm/output/eclipse/EclipseIO.cpp
|
||||
src/opm/output/eclipse/InteHEAD.cpp
|
||||
src/opm/output/eclipse/libECLRestart.cpp
|
||||
src/opm/output/eclipse/LinearisedOutputTable.cpp
|
||||
src/opm/output/eclipse/LoadRestart.cpp
|
||||
src/opm/output/eclipse/LogiHEAD.cpp
|
||||
src/opm/output/eclipse/RestartIO.cpp
|
||||
src/opm/output/eclipse/Inplace.cpp
|
||||
src/opm/output/eclipse/Summary.cpp
|
||||
src/opm/output/eclipse/SummaryState.cpp
|
||||
src/opm/output/eclipse/Tables.cpp
|
||||
src/opm/output/eclipse/RegionCache.cpp
|
||||
src/opm/output/eclipse/RestartValue.cpp
|
||||
src/opm/output/eclipse/WriteInit.cpp
|
||||
src/opm/output/eclipse/WriteRFT.cpp
|
||||
src/opm/output/eclipse/WriteRPT.cpp
|
||||
src/opm/output/eclipse/report/WELSPECS.cpp
|
||||
src/opm/output/data/Solution.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_ActiveGridCells.cpp
|
||||
tests/test_calculateCellVol.cpp
|
||||
tests/test_cmp.cpp
|
||||
tests/test_cubic.cpp
|
||||
tests/test_messagelimiter.cpp
|
||||
tests/test_nonuniformtablelinear.cpp
|
||||
tests/test_OpmInputError_format.cpp
|
||||
tests/test_OpmLog.cpp
|
||||
tests/test_param.cpp
|
||||
tests/test_RootFinders.cpp
|
||||
tests/test_SimulationDataContainer.cpp
|
||||
tests/test_sparsevector.cpp
|
||||
tests/test_uniformtablelinear.cpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
tests/rst_test.cpp
|
||||
tests/test_ERsm.cpp
|
||||
tests/test_GuideRate.cpp
|
||||
tests/parser/ACTIONX.cpp
|
||||
tests/parser/ADDREGTests.cpp
|
||||
tests/parser/AquiferTests.cpp
|
||||
tests/parser/AquiferCTTests.cpp
|
||||
tests/parser/AqudimsTests.cpp
|
||||
tests/parser/AquanconTests.cpp
|
||||
tests/parser/BoxTests.cpp
|
||||
tests/parser/ColumnSchemaTests.cpp
|
||||
tests/parser/ConnectionTests.cpp
|
||||
tests/parser/COMPSEGUnits.cpp
|
||||
tests/parser/CopyRegTests.cpp
|
||||
tests/parser/DeckValueTests.cpp
|
||||
tests/parser/DeckTests.cpp
|
||||
tests/parser/DynamicStateTests.cpp
|
||||
tests/parser/DynamicVectorTests.cpp
|
||||
tests/parser/Eclipse3DPropertiesTests.cpp
|
||||
tests/parser/EclipseGridTests.cpp
|
||||
tests/parser/EmbeddedPython.cpp
|
||||
tests/parser/EqualRegTests.cpp
|
||||
tests/parser/EventTests.cpp
|
||||
tests/parser/FaceDirTests.cpp
|
||||
tests/parser/FaultTests.cpp
|
||||
tests/parser/FieldPropsTests.cpp
|
||||
tests/parser/FoamTests.cpp
|
||||
tests/parser/FunctionalTests.cpp
|
||||
tests/parser/GeomodifierTests.cpp
|
||||
tests/parser/GridPropertyTests.cpp
|
||||
tests/parser/GroupTests.cpp
|
||||
tests/parser/ImportTests.cpp
|
||||
tests/parser/InitConfigTest.cpp
|
||||
tests/parser/IOConfigTests.cpp
|
||||
tests/parser/MessageLimitTests.cpp
|
||||
tests/parser/MultiRegTests.cpp
|
||||
tests/parser/MultisegmentWellTests.cpp
|
||||
tests/parser/MULTREGTScannerTests.cpp
|
||||
tests/parser/NetworkTests.cpp
|
||||
tests/parser/OrderedMapTests.cpp
|
||||
tests/parser/ParseContextTests.cpp
|
||||
tests/parser/ParseContext_EXIT1.cpp
|
||||
tests/parser/ParseDATAWithDefault.cpp
|
||||
tests/parser/PAvgTests.cpp
|
||||
tests/parser/PYACTION.cpp
|
||||
tests/parser/PORVTests.cpp
|
||||
tests/parser/RawKeywordTests.cpp
|
||||
tests/parser/test_ReportConfig.cpp
|
||||
tests/parser/ResinsightTest.cpp
|
||||
tests/parser/RestartConfigTests.cpp
|
||||
tests/parser/RFTConfigTests.cpp
|
||||
tests/parser/RockTableTests.cpp
|
||||
tests/parser/RunspecTests.cpp
|
||||
tests/parser/SaltTableTests.cpp
|
||||
tests/parser/ScheduleSerializeTest.cpp
|
||||
tests/parser/ScheduleRestartTests.cpp
|
||||
tests/parser/SatfuncPropertyInitializersTests.cpp
|
||||
tests/parser/ScheduleTests.cpp
|
||||
tests/parser/SectionTests.cpp
|
||||
tests/parser/SimpleTableTests.cpp
|
||||
@@ -391,51 +225,35 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/TableSchemaTests.cpp
|
||||
tests/parser/ThresholdPressureTest.cpp
|
||||
tests/parser/TimeMapTest.cpp
|
||||
tests/parser/TracerTests.cpp
|
||||
tests/parser/TransMultTests.cpp
|
||||
tests/parser/TuningTests.cpp
|
||||
tests/parser/UDQTests.cpp
|
||||
tests/parser/UnitTests.cpp
|
||||
tests/parser/integration/NNCTests.cpp
|
||||
tests/parser/ValueTests.cpp
|
||||
tests/parser/WellSolventTests.cpp
|
||||
tests/parser/WellTracerTests.cpp
|
||||
tests/parser/WellTests.cpp
|
||||
tests/parser/WLIST.cpp
|
||||
tests/parser/WTEST.cpp)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_ActiveIndexByColumns.cpp
|
||||
tests/test_AggregateActionxData.cpp
|
||||
tests/test_AggregateWellData.cpp
|
||||
tests/test_AggregateGroupData.cpp
|
||||
tests/test_AggregateNetworkData.cpp
|
||||
tests/test_AggregateMSWData.cpp
|
||||
tests/test_AggregateConnectionData.cpp
|
||||
tests/test_AggregateUDQData.cpp
|
||||
tests/test_ArrayDimChecker.cpp
|
||||
tests/test_data_GuideRateValue.cpp
|
||||
tests/test_CharArrayNullTerm.cpp
|
||||
tests/test_EclipseIO.cpp
|
||||
tests/test_DoubHEAD.cpp
|
||||
tests/test_InteHEAD.cpp
|
||||
tests/test_LinearisedOutputTable.cpp
|
||||
tests/test_LogiHEAD.cpp
|
||||
tests/test_LGOData.cpp
|
||||
tests/test_OutputStream.cpp
|
||||
tests/test_regionCache.cpp
|
||||
tests/test_PaddedOutputString.cpp
|
||||
tests/test_Restart.cpp
|
||||
tests/test_RFT.cpp
|
||||
tests/test_rst.cpp
|
||||
tests/test_Solution.cpp
|
||||
tests/test_Serializer.cpp
|
||||
tests/test_Inplace.cpp
|
||||
tests/test_Summary.cpp
|
||||
tests/test_Summary_Group.cpp
|
||||
tests/test_Tables.cpp
|
||||
tests/test_Wells.cpp
|
||||
tests/test_WindowedArray.cpp
|
||||
tests/test_restartwellinfo.cpp
|
||||
tests/test_writenumwells.cpp
|
||||
tests/test_serialize_ICON.cpp
|
||||
tests/test_serialize_SCON.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -444,9 +262,8 @@ list (APPEND TEST_DATA_FILES
|
||||
)
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/BASE_SIM.DATA
|
||||
tests/BASE_SIM_THPRES.DATA
|
||||
tests/RESTART_SIM.DATA
|
||||
tests/FIRST_SIM.DATA
|
||||
tests/FIRST_SIM_THPRES.DATA
|
||||
tests/summary_deck.DATA
|
||||
tests/group_group.DATA
|
||||
tests/testblackoilstate3.DATA
|
||||
@@ -455,73 +272,16 @@ if(ENABLE_ECL_OUTPUT)
|
||||
tests/summary_deck_non_constant_porosity.DATA
|
||||
tests/SUMMARY_EFF_FAC.DATA
|
||||
tests/SPE1CASE1.DATA
|
||||
tests/SPE1CASE1.SMSPEC
|
||||
tests/SPE1CASE1A.SMSPEC
|
||||
tests/SPE9_CP_PACKED.DATA
|
||||
tests/SOFR_TEST.DATA
|
||||
tests/UDQ_BASE.DATA
|
||||
tests/UDQ_RESTART.DATA
|
||||
tests/UDQ_TEST_WCONPROD_IUAD-2.DATA
|
||||
tests/UDQ_ACTIONX_TEST1.DATA
|
||||
tests/UDQ_ACTIONX_TEST1_U.DATA
|
||||
tests/TEST_AGGREGATE_MSW.DATA
|
||||
tests/include_example_pvt.txt
|
||||
tests/include_example_summary.txt
|
||||
tests/include_sgof.txt
|
||||
tests/include_swof.txt
|
||||
tests/include_grid_3x5x4.grdecl
|
||||
tests/SPE1CASE2.DATA
|
||||
tests/SPE1CASE2_RESTART.DATA
|
||||
tests/SPE1CASE2.X0060
|
||||
tests/PYACTION.DATA
|
||||
tests/0A4_GRCTRL_LRAT_LRAT_GGR_BASE_MODEL2_MSW_ALL.DATA
|
||||
tests/2_WLIFT_MODEL5_NOINC.DATA
|
||||
tests/TEST_NETWORK_ALL.DATA
|
||||
tests/act1.py
|
||||
tests/MSW.DATA
|
||||
tests/EXIT_TEST.DATA
|
||||
tests/action_syntax_error.py
|
||||
tests/action_missing_run.py
|
||||
tests/EMBEDDED_PYTHON.DATA
|
||||
tests/wclose.py
|
||||
tests/msim/MSIM_PYACTION.DATA
|
||||
tests/msim/action1.py
|
||||
tests/msim/action2.py
|
||||
tests/VFP_CASE.DATA)
|
||||
)
|
||||
endif()
|
||||
|
||||
list (APPEND EXAMPLE_SOURCE_FILES
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/ECLFILE.INIT
|
||||
tests/ECLFILE.FINIT
|
||||
tests/LGR_TESTMOD.EGRID
|
||||
tests/LGR_TESTMOD.INIT
|
||||
tests/LGR_TESTMOD.UNRST
|
||||
tests/LGR_TESTMOD.X0002
|
||||
tests/MODEL1_IX.INIT
|
||||
tests/MODEL1_IX.SMSPEC
|
||||
tests/MODEL1_IX.UNSMRY
|
||||
tests/SPE1CASE1.EGRID
|
||||
tests/SPE1CASE1.RFT
|
||||
tests/SPE1_TESTCASE.UNRST
|
||||
tests/SPE1_TESTCASE.FUNRST
|
||||
tests/SPE1_TESTCASE.F0025
|
||||
tests/SPE1_TESTCASE.X0025
|
||||
tests/SPE1CASE1.UNSMRY
|
||||
tests/SPE1CASE1A.UNSMRY
|
||||
tests/SPE1CASE1_RST60.SMSPEC
|
||||
tests/SPE1CASE1_RST60.UNSMRY
|
||||
tests/MODEL2_RESTART.DATA
|
||||
tests/restart/MODEL2.UNRST
|
||||
)
|
||||
list (APPEND EXAMPLE_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
examples/opmhash.cpp
|
||||
examples/wellgraph.cpp
|
||||
examples/make_lodsmry.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -533,14 +293,13 @@ if(ENABLE_ECL_INPUT)
|
||||
list (APPEND PROGRAM_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
examples/opmhash.cpp
|
||||
examples/make_lodsmry.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/ErrorMacros.hpp
|
||||
opm/common/Exceptions.hpp
|
||||
opm/common/data/SimulationDataContainer.hpp
|
||||
opm/common/OpmLog/CounterLog.hpp
|
||||
opm/common/OpmLog/EclipsePRTLog.hpp
|
||||
opm/common/OpmLog/LogBackend.hpp
|
||||
@@ -548,15 +307,9 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/OpmLog/LogUtil.hpp
|
||||
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
|
||||
opm/common/utility/Serializer.hpp
|
||||
opm/common/utility/ActiveGridCells.hpp
|
||||
opm/common/utility/FileSystem.hpp
|
||||
opm/common/utility/OpmInputError.hpp
|
||||
opm/common/utility/numeric/cmp.hpp
|
||||
opm/common/utility/platform_dependent/disable_warnings.h
|
||||
opm/common/utility/platform_dependent/reenable_warnings.h
|
||||
@@ -576,21 +329,19 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/utility/parameters/ParameterStrings.hpp
|
||||
opm/common/utility/parameters/ParameterTools.hpp
|
||||
opm/common/utility/numeric/calculateCellVol.hpp
|
||||
opm/common/utility/String.hpp
|
||||
opm/common/utility/TimeService.hpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
opm/io/eclipse/SummaryNode.hpp
|
||||
opm/json/JsonObject.hpp
|
||||
opm/parser/eclipse/Utility/Stringview.hpp
|
||||
opm/parser/eclipse/Utility/Functional.hpp
|
||||
opm/parser/eclipse/Utility/Typetools.hpp
|
||||
opm/parser/eclipse/Utility/String.hpp
|
||||
opm/parser/eclipse/Generator/KeywordGenerator.hpp
|
||||
opm/parser/eclipse/Generator/KeywordLoader.hpp
|
||||
opm/parser/eclipse/Units/UnitSystem.hpp
|
||||
opm/parser/eclipse/Units/Units.hpp
|
||||
opm/parser/eclipse/Units/Dimension.hpp
|
||||
opm/parser/eclipse/Parser/ErrorGuard.hpp
|
||||
opm/parser/eclipse/Parser/ParserItem.hpp
|
||||
opm/parser/eclipse/Parser/Parser.hpp
|
||||
opm/parser/eclipse/Parser/ParserRecord.hpp
|
||||
@@ -601,34 +352,28 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/Parser/ParserConst.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/Equil.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/FoamConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/IOrderSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/Value.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp
|
||||
opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FieldData.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/Keywords.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridDims.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/TranCalculator.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/TransMult.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/PinchMode.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/Fault.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/Box.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/NNC.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/MinpvMode.hpp
|
||||
opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/EndpointScaling.hpp
|
||||
opm/parser/eclipse/EclipseState/TracerConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/DenT.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/StandardCond.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PolyInjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PdvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TlpmixpaTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvdgTable.hpp
|
||||
@@ -637,23 +382,12 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/Regdims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Eqldims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SpecrockTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtwsaltTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/BrineDensityTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PermfactTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RwgsaltTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SaltvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SaltpvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SolventDensityTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlydhflfTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlymwinjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyshlogTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RsvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SkprwatTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SkprpolyTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SpecheatTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgcwmisTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Sof2Table.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TLMixpar.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SwfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/EnptvdTable.hpp
|
||||
@@ -663,8 +397,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/JFunc.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableIndex.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtgTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtgwTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtgwoTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableSchema.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RocktabTable.hpp
|
||||
@@ -677,8 +409,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/AqutabTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyadsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/FoamadsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/FoammobTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PbvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SorwmisTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlymaxTable.hpp
|
||||
@@ -692,11 +422,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/SgwfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvdsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtoTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtsolTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Rock2dTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Rock2dtrTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RockwnodTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/OverburdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/ColumnSchema.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PmiscTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RtempvdTable.hpp
|
||||
@@ -705,185 +430,86 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/ImkrvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Sof3Table.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgofTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TracerVdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/EclipseState.hpp
|
||||
opm/parser/eclipse/EclipseState/EclipseConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/Aquancon.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/AquiferConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/AquiferCT.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/Aquifetp.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquiferCell.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquiferConnection.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/SingleNumericalAquifer.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquifers.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionValue.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/Actdims.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/Condition.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/ASTNode.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/PyAction.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Action/State.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Network/Branch.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Network/Node.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquancon.hpp
|
||||
opm/parser/eclipse/EclipseState/AquiferCT.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/ProductionControls.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/InjectionControls.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculator.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/NameOrder.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellFoamProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellBrineProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellPolymerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellTracerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellTestState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/RFTConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/RPTConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/RSTConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ScheduleDeck.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ScheduleState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ScheduleTypes.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GPMaint.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GConSump.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Events.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/icd.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Connection.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/AICD.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/SICD.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/BCConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/RockConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp
|
||||
opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/checkDeck.hpp
|
||||
opm/parser/eclipse/EclipseState/Runspec.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQASTNode.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQToken.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp
|
||||
opm/parser/eclipse/EclipseState/UDQConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQExpression.hpp
|
||||
opm/parser/eclipse/Deck/DeckItem.hpp
|
||||
opm/parser/eclipse/Deck/Deck.hpp
|
||||
opm/parser/eclipse/Deck/DeckSection.hpp
|
||||
opm/parser/eclipse/Deck/Section.hpp
|
||||
opm/parser/eclipse/Deck/DeckOutput.hpp
|
||||
opm/parser/eclipse/Deck/DeckValue.hpp
|
||||
opm/parser/eclipse/Deck/DeckKeyword.hpp
|
||||
opm/parser/eclipse/Deck/DeckRecord.hpp
|
||||
opm/parser/eclipse/Deck/ImportContainer.hpp
|
||||
opm/parser/eclipse/Deck/UDAValue.hpp
|
||||
opm/parser/eclipse/Deck/value_status.hpp
|
||||
opm/parser/eclipse/Python/Python.hpp)
|
||||
opm/parser/eclipse/RawDeck/StarToken.hpp
|
||||
opm/parser/eclipse/RawDeck/RawEnums.hpp
|
||||
opm/parser/eclipse/RawDeck/RawRecord.hpp
|
||||
opm/parser/eclipse/RawDeck/RawKeyword.hpp
|
||||
opm/parser/eclipse/RawDeck/RawConsts.hpp)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
opm/io/eclipse/EclFile.hpp
|
||||
opm/io/eclipse/EclIOdata.hpp
|
||||
opm/io/eclipse/EclOutput.hpp
|
||||
opm/io/eclipse/EclUtil.hpp
|
||||
opm/io/eclipse/EGrid.hpp
|
||||
opm/io/eclipse/EInit.hpp
|
||||
opm/io/eclipse/ERft.hpp
|
||||
opm/io/eclipse/ERst.hpp
|
||||
opm/io/eclipse/ERsm.hpp
|
||||
opm/io/eclipse/ESmry.hpp
|
||||
opm/io/eclipse/PaddedOutputString.hpp
|
||||
opm/io/eclipse/OutputStream.hpp
|
||||
opm/io/eclipse/SummaryNode.hpp
|
||||
opm/io/eclipse/rst/connection.hpp
|
||||
opm/io/eclipse/rst/group.hpp
|
||||
opm/io/eclipse/rst/header.hpp
|
||||
opm/io/eclipse/rst/segment.hpp
|
||||
opm/io/eclipse/rst/state.hpp
|
||||
opm/io/eclipse/rst/well.hpp
|
||||
opm/output/data/Aquifer.hpp
|
||||
opm/output/data/Cells.hpp
|
||||
opm/output/data/GuideRateValue.hpp
|
||||
opm/output/data/Groups.hpp
|
||||
opm/output/data/Solution.hpp
|
||||
opm/output/data/Wells.hpp
|
||||
opm/output/eclipse/VectorItems/aquifer.hpp
|
||||
opm/output/eclipse/VectorItems/connection.hpp
|
||||
opm/output/eclipse/VectorItems/group.hpp
|
||||
opm/output/eclipse/VectorItems/network.hpp
|
||||
opm/output/eclipse/VectorItems/intehead.hpp
|
||||
opm/output/eclipse/VectorItems/logihead.hpp
|
||||
opm/output/eclipse/VectorItems/msw.hpp
|
||||
opm/output/eclipse/VectorItems/tabdims.hpp
|
||||
opm/output/eclipse/VectorItems/well.hpp
|
||||
opm/output/eclipse/ActiveIndexByColumns.hpp
|
||||
opm/output/eclipse/AggregateActionxData.hpp
|
||||
opm/output/eclipse/AggregateGroupData.hpp
|
||||
opm/output/eclipse/AggregateNetworkData.hpp
|
||||
opm/output/eclipse/AggregateConnectionData.hpp
|
||||
opm/output/eclipse/AggregateMSWData.hpp
|
||||
opm/output/eclipse/AggregateUDQData.hpp
|
||||
opm/output/eclipse/AggregateWellData.hpp
|
||||
opm/output/eclipse/CharArrayNullTerm.hpp
|
||||
opm/output/eclipse/DoubHEAD.hpp
|
||||
opm/output/eclipse/EclipseGridInspector.hpp
|
||||
opm/output/eclipse/EclipseIO.hpp
|
||||
opm/output/eclipse/EclipseIOUtil.hpp
|
||||
opm/output/eclipse/InteHEAD.hpp
|
||||
opm/output/eclipse/libECLRestart.hpp
|
||||
opm/output/eclipse/LinearisedOutputTable.hpp
|
||||
opm/output/eclipse/LogiHEAD.hpp
|
||||
opm/output/eclipse/RegionCache.hpp
|
||||
opm/output/eclipse/RestartIO.hpp
|
||||
opm/output/eclipse/RestartValue.hpp
|
||||
opm/output/eclipse/Inplace.hpp
|
||||
opm/output/eclipse/Summary.hpp
|
||||
opm/output/eclipse/SummaryState.hpp
|
||||
opm/output/eclipse/Tables.hpp
|
||||
opm/output/eclipse/WindowedArray.hpp
|
||||
opm/output/eclipse/WriteInit.hpp
|
||||
opm/output/eclipse/WriteRFT.hpp
|
||||
opm/output/eclipse/WriteRPT.hpp
|
||||
opm/output/eclipse/WriteRestartHelpers.hpp
|
||||
opm/output/OutputWriter.hpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ECL_INPUT OR ENABLE_ECL_OUTPUT)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
tests/test_SummaryNode.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/ParserInit.cpp
|
||||
${BASE_DIR}/ParserInit.cpp)
|
||||
${BASE_DIR}/tmp_gen/ParserKeywords.cpp
|
||||
${BASE_DIR}/ParserKeywords.cpp)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/TestKeywords.cpp
|
||||
${BASE_DIR}/TestKeywords.cpp)
|
||||
|
||||
if (EXISTS ${BASE_DIR}/python/cxx)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/builtin_pybind11.cpp
|
||||
${BASE_DIR}/python/cxx/builtin_pybind11.cpp)
|
||||
endif()
|
||||
${BASE_DIR}/tmp_gen/inlinekw.cpp
|
||||
${BASE_DIR}/inlinekw.cpp)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords/Builtin.hpp
|
||||
${BASE_DIR}/include/opm/parser/eclipse/Parser/ParserKeywords/Builtin.hpp)
|
||||
${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords.hpp
|
||||
${BASE_DIR}/include/opm/parser/eclipse/Parser/ParserKeywords.hpp)
|
||||
|
||||
|
||||
file(GLOB HDRS ${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords/*.hpp)
|
||||
@@ -24,11 +18,4 @@ foreach(HDR ${HDRS})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${HDR}
|
||||
${BASE_DIR}/include/opm/parser/eclipse/Parser/ParserKeywords/${hdr})
|
||||
|
||||
endforeach()
|
||||
|
||||
foreach (name A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/ParserKeywords/${name}.cpp
|
||||
${BASE_DIR}/ParserKeywords/${name}.cpp)
|
||||
endforeach()
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
# Libs to link tests against
|
||||
set(TEST_LIBS opmcommon Boost::unit_test_framework)
|
||||
set(TEST_LIBS opmcommon ecl Boost::unit_test_framework)
|
||||
set(EXTRA_TESTS)
|
||||
|
||||
if (Boost_UNIT_TEST_FRAMEWORK_FOUND)
|
||||
|
||||
# Generated source, needs to be here
|
||||
opm_add_test(InlineKeywordTest
|
||||
EXE_NAME TestKeywords
|
||||
SOURCES ${PROJECT_BINARY_DIR}/TestKeywords.cpp
|
||||
EXE_NAME inlinekw
|
||||
SOURCES ${PROJECT_BINARY_DIR}/inlinekw.cpp
|
||||
LIBRARIES ${TEST_LIBS})
|
||||
list(APPEND EXTRA_TESTS TestKeywords)
|
||||
list(APPEND EXTRA_TESTS inlinekw)
|
||||
|
||||
# Extra compile definitions and extra parameters
|
||||
include(cmake/Modules/CheckCaseSensitiveFileSystem.cmake)
|
||||
set(_testdir ${PROJECT_SOURCE_DIR}/tests/parser/data)
|
||||
|
||||
opm_add_test(LoaderTest
|
||||
SOURCES tests/parser/KeywordLoaderTests.cpp
|
||||
src/opm/parser/eclipse/Generator/KeywordLoader.cpp
|
||||
LIBRARIES ${TEST_LIBS}
|
||||
TEST_ARGS ${_testdir}/parser/keyword-generator/)
|
||||
list(APPEND EXTRA_TESTS LoaderTest)
|
||||
|
||||
opm_add_test(ParserTests
|
||||
SOURCES tests/parser/ParserTests.cpp
|
||||
LIBRARIES ${TEST_LIBS}
|
||||
@@ -47,8 +52,11 @@ foreach (test BoxTest
|
||||
IncludeTest
|
||||
IntegrationTests
|
||||
IOConfigIntegrationTest
|
||||
NNCTests
|
||||
ParseKEYWORD
|
||||
ParseDATAWithDefault
|
||||
Polymer
|
||||
ResinsightTest
|
||||
ScheduleCreateFromDeck
|
||||
TransMultIntegrationTests)
|
||||
|
||||
@@ -59,16 +67,6 @@ foreach (test BoxTest
|
||||
list(APPEND EXTRA_TESTS ${test})
|
||||
endforeach ()
|
||||
|
||||
opm_add_test( rst_spe1
|
||||
SOURCES tests/rst_test.cpp
|
||||
LIBRARIES ${TEST_LIBS}
|
||||
TEST_ARGS tests/SPE1CASE2.DATA tests/SPE1CASE2_RESTART.DATA )
|
||||
|
||||
opm_add_test( rst_msw
|
||||
SOURCES tests/rst_test.cpp
|
||||
LIBRARIES ${TEST_LIBS}
|
||||
TEST_ARGS tests/MSW.DATA tests/MSW_RESTART.DATA )
|
||||
|
||||
# opm-tests dependent tests
|
||||
if(HAVE_OPM_TESTS)
|
||||
opm_add_test(parse_write ONLY_COMPILE
|
||||
@@ -88,29 +86,15 @@ if(HAVE_OPM_TESTS)
|
||||
${OPM_TESTS_ROOT}/spe3/SPE3CASE2.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP_GROUP.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP_SHORT.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9_CP_SHORT_RESTART.DATA
|
||||
${OPM_TESTS_ROOT}/spe9/SPE9.DATA
|
||||
${OPM_TESTS_ROOT}/spe10model1/SPE10_MODEL1.DATA
|
||||
${OPM_TESTS_ROOT}/spe10model2/SPE10_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/msw_2d_h/2D_H__.DATA
|
||||
${OPM_TESTS_ROOT}/model2/0_BASE_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/1_MULTREGT_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/2_MULTXYZ_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/3_MULTFLT_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/4_MINPVV_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/5_SWATINIT_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/6_ENDSCALE_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/7_HYSTERESIS_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/8_MULTIPLY_TRANXYZ_MODEL2.DATA
|
||||
${OPM_TESTS_ROOT}/model2/9_EDITNNC_MODEL2.DATA)
|
||||
|
||||
${OPM_TESTS_ROOT}/msw_2d_h/2D_H__.DATA )
|
||||
get_filename_component(test_name ${deck} NAME_WE)
|
||||
opm_add_test(${test_name} NO_COMPILE
|
||||
EXE_NAME parse_write
|
||||
TEST_ARGS ${deck})
|
||||
endforeach()
|
||||
opm_add_test("SPE9_CP_GROUP2" NO_COMPILE EXE_NAME parse_write TEST_ARGS "${OPM_TESTS_ROOT}/spe9group/SPE9_CP_GROUP.DATA")
|
||||
set_property(TEST NORNE_ATW2013
|
||||
PROPERTY ENVIRONMENT "OPM_ERRORS_IGNORE=PARSE_RANDOM_SLASH")
|
||||
endif()
|
||||
@@ -121,5 +105,3 @@ opm_add_test(jsonTests
|
||||
LIBRARIES ${TEST_LIBS}
|
||||
TEST_ARGS ${PROJECT_SOURCE_DIR}/tests/json/example1.json)
|
||||
list(APPEND EXTRA_TESTS jsonTests)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
set(genkw_SOURCES src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Parser/createDefaultKeywordList.cpp
|
||||
src/opm/parser/eclipse/Deck/UDAValue.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckValue.cpp
|
||||
src/opm/parser/eclipse/Deck/Deck.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckItem.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckKeyword.cpp
|
||||
@@ -9,18 +7,17 @@ set(genkw_SOURCES src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckOutput.cpp
|
||||
src/opm/parser/eclipse/Generator/KeywordGenerator.cpp
|
||||
src/opm/parser/eclipse/Generator/KeywordLoader.cpp
|
||||
src/opm/parser/eclipse/Parser/ErrorGuard.cpp
|
||||
src/opm/parser/eclipse/Parser/ParseContext.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserEnums.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserItem.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserRecord.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/RawRecord.cpp
|
||||
src/opm/parser/eclipse/Parser/raw/StarToken.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/StarToken.cpp
|
||||
src/opm/parser/eclipse/Units/Dimension.cpp
|
||||
src/opm/parser/eclipse/Units/UnitSystem.cpp
|
||||
src/opm/common/utility/OpmInputError.cpp
|
||||
src/opm/parser/eclipse/Utility/Stringview.cpp
|
||||
src/opm/common/OpmLog/OpmLog.cpp
|
||||
src/opm/common/OpmLog/Logger.cpp
|
||||
src/opm/common/OpmLog/StreamLog.cpp
|
||||
@@ -32,7 +29,7 @@ if(NOT cjson_FOUND)
|
||||
endif()
|
||||
add_executable(genkw ${genkw_SOURCES})
|
||||
|
||||
target_link_libraries(genkw ${opm-common_LIBRARIES})
|
||||
target_link_libraries(genkw ecl Boost::regex Boost::filesystem Boost::system)
|
||||
|
||||
# Generate keyword list
|
||||
include(src/opm/parser/eclipse/share/keywords/keyword_list.cmake)
|
||||
@@ -40,91 +37,18 @@ string(REGEX REPLACE "([^;]+)" "${PROJECT_SOURCE_DIR}/src/opm/parser/eclipse/sha
|
||||
configure_file(src/opm/parser/eclipse/keyword_list.argv.in keyword_list.argv)
|
||||
|
||||
# Generate keyword source
|
||||
|
||||
set( genkw_argv keyword_list.argv
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserInit.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/include/
|
||||
opm/parser/eclipse/Parser/ParserKeywords
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/TestKeywords.cpp)
|
||||
|
||||
set( _tmp_output
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/A.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/B.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/C.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/D.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/E.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/F.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/G.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/H.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/I.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/J.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/K.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/L.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/M.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/N.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/O.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/P.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/Q.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/R.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/S.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/T.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/U.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/V.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/W.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/X.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/Y.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/Z.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserInit.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/TestKeywords.cpp)
|
||||
|
||||
|
||||
set( _target_output
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/A.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/B.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/C.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/D.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/E.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/F.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/G.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/H.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/I.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/J.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/K.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/L.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/M.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/N.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/O.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/P.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/Q.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/R.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/S.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/T.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/U.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/V.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/W.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/X.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/Y.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserKeywords/Z.cpp
|
||||
${PROJECT_BINARY_DIR}/TestKeywords.cpp
|
||||
${PROJECT_BINARY_DIR}/ParserInit.cpp)
|
||||
|
||||
|
||||
if (OPM_ENABLE_PYTHON)
|
||||
list(APPEND genkw_argv ${PROJECT_BINARY_DIR}/tmp_gen/builtin_pybind11.cpp)
|
||||
list(APPEND _tmp_output ${PROJECT_BINARY_DIR}/tmp_gen/builtin_pybind11.cpp)
|
||||
list(APPEND _target_output ${PROJECT_BINARY_DIR}/python/cxx/builtin_pybind11.cpp)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
add_custom_command( OUTPUT
|
||||
${_tmp_output}
|
||||
COMMAND genkw ${genkw_argv}
|
||||
DEPENDS genkw ${keyword_files} src/opm/parser/eclipse/share/keywords/keyword_list.cmake)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords.cpp ${PROJECT_BINARY_DIR}/tmp_gen/inlinekw.cpp
|
||||
COMMAND genkw keyword_list.argv
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords.cpp
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/include/
|
||||
opm/parser/eclipse/Parser/ParserKeywords
|
||||
${PROJECT_BINARY_DIR}/tmp_gen/inlinekw.cpp
|
||||
DEPENDS genkw ${keyword_files} src/opm/parser/eclipse/share/keywords/keyword_list.cmake
|
||||
)
|
||||
|
||||
# To avoid some rebuilds
|
||||
add_custom_command(OUTPUT
|
||||
${_target_output}
|
||||
DEPENDS ${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/A.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -DBASE_DIR=${PROJECT_BINARY_DIR} -P ${PROJECT_SOURCE_DIR}/CopyHeaders.cmake)
|
||||
add_custom_command(OUTPUT ParserKeywords.cpp inlinekw.cpp
|
||||
DEPENDS ${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -DBASE_DIR=${PROJECT_BINARY_DIR}
|
||||
-P ${PROJECT_SOURCE_DIR}/CopyHeaders.cmake)
|
||||
|
||||
18
changelog.md
18
changelog.md
@@ -3,24 +3,6 @@
|
||||
A short month-by-month synopsis of change highlights. Most bugfixes won't make
|
||||
it in here, only the bigger features and interface changes.
|
||||
|
||||
# Important changes between release 2019.04 and 2019.10
|
||||
|
||||
* opm-common and the rest of OPM does not use libecl anymore and
|
||||
supports reading and writing Eclipse files directly
|
||||
* Improved Eclipse compatible restart, support for unified and non unified
|
||||
files, and formatted and unformatted files
|
||||
* Support for reading and checking various additional keywords was introduced (those
|
||||
starting with A - M, R, T, V, W, Z).
|
||||
* ACTIONX support implemented
|
||||
* NUPCOL support implemented
|
||||
* UDA, UDQ support implemented
|
||||
* Implemented writing saturation function scaled end-point arrays (e.g., SWL, SGU,
|
||||
SOWCR, KRORW, PCG) to INIT file
|
||||
* Fixes concerning interaction of WELOPEN and WCON* with WECON and
|
||||
WTEST
|
||||
* Added support for FOAM keywords (FOAMMOB, FOAMROCK, WFOAM)
|
||||
* Refactored and reimplemented Well representation in deck
|
||||
|
||||
# 2016.12
|
||||
* ZCORN adjustments improved, considers cell-cell relations
|
||||
* Slightly more robust compilation - won't crash if locales are broken
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
find_library(ALBERTA_LTDL_LIB
|
||||
NAMES ltdl
|
||||
PATH_SUFFIXES lib lib32 lib64
|
||||
)
|
||||
find_path(ALBERTA_INCLUDE_DIR
|
||||
NAMES alberta/alberta.h
|
||||
PATHS ${ALBERTA_ROOT}
|
||||
PATH_SUFFIXES alberta include NO_DEFAULT_PATH
|
||||
DOC "Include path of Alberta")
|
||||
find_path(ALBERTA_INCLUDE_DIR
|
||||
NAMES
|
||||
alberta/alberta.h
|
||||
PATHS /usr/local /opt
|
||||
PATH_SUFFIXES alberta)
|
||||
#look for libraries
|
||||
find_library(ALBERTA_UTIL_LIB
|
||||
NAMES alberta_util alberta_utilities
|
||||
PATHS ${ALBERTA_ROOT}
|
||||
PATH_SUFFIXES lib lib32 lib64
|
||||
NO_DEFAULT_PATH)
|
||||
find_library(ALBERTA_UTIL_LIB
|
||||
NAMES alberta_util alberta_utilities
|
||||
PATH_SUFFIXES lib lib32 lib64)
|
||||
|
||||
foreach(dim RANGE 1 9)
|
||||
find_library(ALBERTA_${dim}D_LIB alberta_${dim}d
|
||||
PATHS ${ALBERTA_ROOT}
|
||||
PATH_SUFFIXES lib lib32 lib64
|
||||
Cache FILEPATH DOC "Alberta lib for ${dim}D" NO_DEFAULT_PATH)
|
||||
find_library(ALBERTA_${dim}D_LIB alberta_${dim}d PATH_SUFFIXES lib lib32 lib64)
|
||||
if(ALBERTA_${dim}D_LIB)
|
||||
set(ALBERTA_LIBRARIES ${ALBERTA_LIBRARIES} ${ALBERTA_${dim}D_LIB})
|
||||
endif()
|
||||
endforeach(dim RANGE 1 9)
|
||||
|
||||
if(ALBERTA_LIBRARIES AND ALBERTA_INCLUDE_DIR)
|
||||
set(ALBERTA_INCLUDE_DIRS ${ALBERTA_INCLUDE_DIR})
|
||||
set(ALBERTA_LIBRARIES ${ALBERTA_LIBRARIES} ${ALBERTA_UTIL_LIB} ${ALBERTA_LTDL_LIB})
|
||||
set(ALBERTA_FOUND ON)
|
||||
set(Alberta_FOUND ON)
|
||||
set(HAVE_ALBERTA 1)
|
||||
set(DUNE_ALBERTA_VERSION 0x300)
|
||||
else()
|
||||
set(ALBERTA_FOUND OFF)
|
||||
set(Alberta_FOUND OFF)
|
||||
endif()
|
||||
468
cmake/Modules/FindCXX11Features.cmake
Normal file
468
cmake/Modules/FindCXX11Features.cmake
Normal file
@@ -0,0 +1,468 @@
|
||||
#
|
||||
# Module that checks for supported C++11 (former C++0x) features.
|
||||
#
|
||||
# Sets the follwing variable:
|
||||
#
|
||||
# HAVE_FINAL True if the compiler supports the "final" quantifier
|
||||
# HAVE_TYPE_TRAITS True if the <type_traits> header is available and implements sufficient functionality
|
||||
# HAVE_SHARED_PTR True if std::shared_ptr is available
|
||||
# HAVE_UNIQUE_PTR True if std::unique_ptr is available
|
||||
# HAVE_NULLPTR True if nullptr is available
|
||||
# HAVE_ARRAY True if header <array> and fill() are available
|
||||
# HAVE_ATTRIBUTE_ALWAYS_INLINE True if attribute always inline is supported
|
||||
# HAS_ATTRIBUTE_UNUSED True if attribute unused is supported
|
||||
# HAS_ATTRIBUTE_DEPRECATED True if attribute deprecated is supported
|
||||
# HAS_ATTRIBUTE_DEPRECATED_MSG True if attribute deprecated("msg") is supported
|
||||
# HAVE_CONSTEXPR True if constexpr attribute is available
|
||||
# HAVE_INTEGRAL_CONSTANT True if compiler supports integral_constant
|
||||
# HAVE_STATIC_ASSERT True if static_assert is available
|
||||
# HAVE_AUTO True if the compiler supports the auto keyword
|
||||
# HAVE_VARIADIC_TEMPLATES True if variadic templates are supported
|
||||
# HAVE_VARIADIC_CONSTRUCTOR_SFINAE True if variadic constructor sfinae is supported
|
||||
# HAVE_RVALUE_REFERENCES True if rvalue references are supported
|
||||
# HAVE_TUPLE True if std::tuple is available
|
||||
# HAVE_TR1_TUPLE True if std::tr1::tuple is available
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckCXXSourceRuns)
|
||||
|
||||
# test for C++11 flags
|
||||
include(TestCXXAcceptsFlag)
|
||||
include(CheckIncludeFileCXX)
|
||||
|
||||
# macro to only add option once
|
||||
include(AddOptions)
|
||||
|
||||
# Force CXX Standard cross platfrom for CMakeVersion >=3.1
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
|
||||
if(NOT MSVC)
|
||||
foreach(_flag "14" "11")
|
||||
set(_FLAG "CXX_FLAG_CXX${_flag}")
|
||||
string(TOUPPER ${_FLAG} _FLAG)
|
||||
# try to use compiler flag -std=c++${_flag}
|
||||
CHECK_CXX_ACCEPTS_FLAG("-std=c++${_flag}" ${_FLAG})
|
||||
|
||||
if(${_FLAG})
|
||||
if(CMAKE_VERSION VERSION_LESS 3.1)
|
||||
add_options (CXX ALL_BUILDS "-std=c++${_flag}")
|
||||
endif()
|
||||
set(CXX_STD0X_FLAGS "-std=c++${_flag}")
|
||||
#Use vriables for CMake > 3.1 set the standard with no extensions
|
||||
set(CMAKE_CXX_STANDARD ${_flag})
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif(NOT MSVC)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.1)
|
||||
# if we are building with an Apple toolchain in MacOS X,
|
||||
# we cannot use the old GCC 4.2 fork, but must use the
|
||||
# new runtime library
|
||||
set (CXX_STDLIB_FLAGS)
|
||||
string (TOUPPER "${CMAKE_CXX_COMPILER_ID}" _comp_id)
|
||||
if (APPLE AND (_comp_id MATCHES "CLANG"))
|
||||
CHECK_CXX_ACCEPTS_FLAG ("-stdlib=libc++" CXX_FLAG_STDLIB_LIBCXX)
|
||||
if (CXX_FLAG_STDLIB_LIBCXX)
|
||||
add_options (CXX ALL_BUILDS "-stdlib=libc++")
|
||||
set (CXX_STDLIB_FLAGS "-stdlib=libc++")
|
||||
endif (CXX_FLAG_STDLIB_LIBCXX)
|
||||
endif (APPLE AND (_comp_id MATCHES "CLANG"))
|
||||
|
||||
# to format the command-line options pretty, we have an optional space
|
||||
if (CXX_STD0X_FLAGS AND CXX_STDLIB_FLAGS)
|
||||
set (CXX_SPACE " ")
|
||||
else (CXX_STD0X_FLAGS AND CXX_STDLIB_FLAGS)
|
||||
set (CXX_SPACE)
|
||||
endif (CXX_STD0X_FLAGS AND CXX_STDLIB_FLAGS)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.1)
|
||||
# Workaround bug in cmake:
|
||||
# cxx standard flags are not applied in CheckCXXSourceCompiles
|
||||
if (CMAKE_CXX_STANDARD EQUAL 14)
|
||||
add_options(CXX ALL_BUILDS ${CMAKE_CXX14_STANDARD_COMPILE_OPTION})
|
||||
else()
|
||||
add_options(CXX ALL_BUILDS ${CMAKE_CXX11_STANDARD_COMPILE_OPTION})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# perform tests
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
# the "final" method specifier
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
struct Base {
|
||||
virtual void foo() = 0;
|
||||
};
|
||||
struct Derived : public Base {
|
||||
virtual void foo() final {};
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
" HAVE_FINAL
|
||||
)
|
||||
|
||||
# std::is_convertible, std::is_base_of
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <type_traits>
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
|
||||
int main()
|
||||
{
|
||||
bool foo = std::is_convertible<int, double>::value;
|
||||
bool bar = std::is_base_of<Base, Derived>::value;
|
||||
bool foobar = std::is_integral<double>::value;
|
||||
return 0;
|
||||
}
|
||||
" HAVE_TYPE_TRAITS
|
||||
)
|
||||
|
||||
# nullptr
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <memory>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::shared_ptr<int> foo(new int(123));
|
||||
return 0;
|
||||
}
|
||||
" HAVE_SHARED_PTR
|
||||
)
|
||||
|
||||
# this is required by dune-common to avoid linker errors. "fun"!
|
||||
if (HAVE_SHARED_PTR)
|
||||
set(HAVE_MAKE_SHARED 1)
|
||||
set(SHARED_PTR_HEADER "<memory>")
|
||||
set(SHARED_PTR_NAMESPACE "std")
|
||||
endif()
|
||||
|
||||
# nullptr
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <memory>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::unique_ptr<int> foo(new int(123));
|
||||
return 0;
|
||||
}
|
||||
" HAVE_UNIQUE_PTR
|
||||
)
|
||||
|
||||
# nullptr
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
int main(void)
|
||||
{
|
||||
char* ch = nullptr;
|
||||
return 0;
|
||||
}
|
||||
" HAVE_NULLPTR
|
||||
)
|
||||
|
||||
# constexpr
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
template <class T>
|
||||
inline constexpr int foo(T bar) { return bar*2; }
|
||||
int main(void)
|
||||
{
|
||||
constexpr int foobar = foo(100);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_CONSTEXPR
|
||||
)
|
||||
|
||||
# array and fill
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <array>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::array<int,2> a;
|
||||
a.fill(9);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_ARRAY
|
||||
)
|
||||
|
||||
# Check whether if std::integral_constant< T, v > is supported and casts into T
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <type_traits>
|
||||
void f( int ){}
|
||||
|
||||
int main(void){
|
||||
f( std::integral_constant< int, 42 >() );
|
||||
}
|
||||
" HAVE_INTEGRAL_CONSTANT
|
||||
)
|
||||
|
||||
# Check whether if <tuple> is available
|
||||
check_include_file_cxx("tuple" HAVE_TUPLE)
|
||||
|
||||
# Check whether if <tr1/tuple> is available
|
||||
check_include_file_cxx("tr1/tuple" HAVE_TR1_TUPLE)
|
||||
|
||||
# __attribute__((always_inline))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
void __attribute__((always_inline)) foo(void) {}
|
||||
int main(void)
|
||||
{
|
||||
foo();
|
||||
return 0;
|
||||
};
|
||||
" HAVE_ATTRIBUTE_ALWAYS_INLINE
|
||||
)
|
||||
|
||||
# __attribute__((unused))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
int main(void)
|
||||
{
|
||||
int __attribute__((unused)) foo;
|
||||
return 0;
|
||||
};
|
||||
" HAS_ATTRIBUTE_UNUSED
|
||||
)
|
||||
|
||||
# __attribute__((deprecated))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#define DEP __attribute__((deprecated))
|
||||
class bar
|
||||
{
|
||||
bar() DEP;
|
||||
};
|
||||
|
||||
class peng { } DEP;
|
||||
|
||||
template <class T>
|
||||
class t_bar
|
||||
{
|
||||
t_bar() DEP;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class t_peng {
|
||||
t_peng() {};
|
||||
} DEP;
|
||||
|
||||
void foo() DEP;
|
||||
|
||||
void foo() {};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
" HAS_ATTRIBUTE_DEPRECATED
|
||||
)
|
||||
|
||||
# __attribute__((deprecated("msg")))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#define DEP __attribute__((deprecated(\"message\")))
|
||||
class bar {
|
||||
bar() DEP;
|
||||
};
|
||||
|
||||
class peng { } DEP;
|
||||
|
||||
template <class T>
|
||||
class t_bar
|
||||
{
|
||||
t_bar() DEP;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class t_peng
|
||||
{
|
||||
t_peng() {};
|
||||
} DEP;
|
||||
|
||||
void foo() DEP;
|
||||
|
||||
void foo() {};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
" HAS_ATTRIBUTE_DEPRECATED_MSG
|
||||
)
|
||||
|
||||
# static assert
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
int main(void)
|
||||
{
|
||||
static_assert(true,\"MSG\");
|
||||
return 0;
|
||||
}
|
||||
" HAVE_STATIC_ASSERT
|
||||
)
|
||||
|
||||
# auto keyword
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
int main(void)
|
||||
{
|
||||
auto foo = 1.23;
|
||||
return 0;
|
||||
}
|
||||
" HAVE_AUTO
|
||||
)
|
||||
|
||||
# variadic template support
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <cassert>
|
||||
|
||||
template<typename... T>
|
||||
int addints(T... x);
|
||||
|
||||
int add_ints()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T1, typename... T>
|
||||
int add_ints(T1 t1, T... t)
|
||||
{
|
||||
return t1 + add_ints(t...);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
assert( 5 == add_ints(9,3,-5,-2) );
|
||||
return 0;
|
||||
}
|
||||
" HAVE_VARIADIC_TEMPLATES
|
||||
)
|
||||
|
||||
# SFINAE on variadic template constructors within template classes
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <functional>
|
||||
|
||||
template<typename... U>
|
||||
struct A
|
||||
{
|
||||
template<typename... T,
|
||||
typename = typename std::enable_if<(sizeof...(T) < 2)>::type
|
||||
>
|
||||
A(T... t)
|
||||
: i(1)
|
||||
{}
|
||||
|
||||
template<typename... T,
|
||||
typename = typename std::enable_if<(sizeof...(T) >= 2)>::type,
|
||||
typename = void
|
||||
>
|
||||
A(T... t)
|
||||
: i(-1)
|
||||
{}
|
||||
|
||||
A()
|
||||
: i(1)
|
||||
{}
|
||||
|
||||
int i;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return (A<int>().i + A<int>(2).i + A<int>(\"foo\",3.4).i + A<int>(8,'a',A<int>()).i == 0 ? 0 : 1);
|
||||
}
|
||||
" HAVE_VARIADIC_CONSTRUCTOR_SFINAE
|
||||
)
|
||||
|
||||
# rvalue references
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
int foo(int&& x) { return 1; }
|
||||
int foo(const int& x) { return -1; }
|
||||
|
||||
template<typename T>
|
||||
int forward(T&& x)
|
||||
{
|
||||
return foo(std::forward<T>(x));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = 0;
|
||||
assert( forward(i) + forward(int(2)) == 0);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_RVALUE_REFERENCES
|
||||
)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFileCXX)
|
||||
# Search for some tr1 headers
|
||||
foreach(_HEADER tuple tr1/tuple type_traits tr1/type_traits)
|
||||
string(REPLACE "/" "_" _HEADER_VAR ${_HEADER})
|
||||
string(TOUPPER ${_HEADER_VAR} _HEADER_VAR )
|
||||
check_include_file_cxx(${_HEADER} "HAVE_${_HEADER_VAR}")
|
||||
endforeach(_HEADER tuple tr1/tuple tr1/type_traits)
|
||||
|
||||
# make sure that the C++-11 features implemented by the compiler are a
|
||||
# superset of those provided by GCC 4.4. This makes the test fail on
|
||||
# all GCC compilers before 4.4.
|
||||
set(CXX_FEATURES_MISSING "")
|
||||
if (NOT HAVE_TYPE_TRAITS)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Sufficiently conformant type traits (defined by the 'type_traits' header file)\n")
|
||||
endif()
|
||||
if (NOT HAVE_SHARED_PTR)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Shared pointers (the std::shared_ptr class)\n")
|
||||
endif()
|
||||
if (NOT HAVE_UNIQUE_PTR)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Unique pointers (the std::unique_ptr class)\n")
|
||||
endif()
|
||||
if (NOT HAVE_ARRAY)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Statically sized arrays (the std::array class)\n")
|
||||
endif()
|
||||
if (NOT HAVE_STATIC_ASSERT)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Static assertations (the static_assert() mechanism)\n")
|
||||
endif()
|
||||
if (NOT HAVE_AUTO)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Automatically typed variables (the 'auto' keyword)\n")
|
||||
endif()
|
||||
if (NOT HAVE_VARIADIC_TEMPLATES)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Variable number of template arguments\n")
|
||||
endif()
|
||||
if (NOT HAVE_VARIADIC_CONSTRUCTOR_SFINAE)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Constructors with variable number of template arguments obeying the SFINAE (specialization failure is not an error) rule\n")
|
||||
endif()
|
||||
if (NOT HAVE_RVALUE_REFERENCES)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - References to rvalue objects\n")
|
||||
endif()
|
||||
if (NOT HAVE_TUPLE)
|
||||
set(CXX_FEATURES_MISSING
|
||||
"${CXX_FEATURES_MISSING} - Tuples (the std::tuple class)\n")
|
||||
endif()
|
||||
|
||||
if(CXX_FEATURES_MISSING)
|
||||
set (CXX11FEATURES_FOUND FALSE)
|
||||
if (CXX11Features_FIND_REQUIRED)
|
||||
message(FATAL_ERROR
|
||||
"Your C++ compiler does not support the minimum set of C++-2011 features required. "
|
||||
"Make sure to use a compiler which implements all C++-2011 features provided by GCC 4.4. "
|
||||
"Your compiler does not seem to implement the following features:\n"
|
||||
"${CXX_FEATURES_MISSING}")
|
||||
endif()
|
||||
else ()
|
||||
set (CXX11FEATURES_FOUND TRUE)
|
||||
endif()
|
||||
49
cmake/Modules/FindCwrap.cmake
Normal file
49
cmake/Modules/FindCwrap.cmake
Normal file
@@ -0,0 +1,49 @@
|
||||
# Find the Python wrappers for module cwrap from ert
|
||||
#
|
||||
# Set the cache variable CWRAP_PYTHON_PATH to the install location of the root
|
||||
# ert package.
|
||||
|
||||
find_package(PythonInterp)
|
||||
if(PYTHONINTERP_FOUND)
|
||||
|
||||
# We try to find the cwrap Python distribution. This is done by running Python
|
||||
# code which tries to 'import cwrap' and prints out the path to the module if
|
||||
# the import succeeds.
|
||||
#
|
||||
# The normal Python import machinery is employed, so if you have installed cwrap
|
||||
# python in a default location, or alternatively set the PYTHONPATH variable the
|
||||
# cwrap Python distribution will eventually be found there, independently of the
|
||||
# alternatives which are tested with the ${PATH_LIST} variable.
|
||||
|
||||
if (EXISTS "/etc/debian_version")
|
||||
set( PYTHON_PACKAGE_PATH "dist-packages")
|
||||
else()
|
||||
set( PYTHON_PACKAGE_PATH "site-packages")
|
||||
endif()
|
||||
set(PYTHON_INSTALL_PREFIX "lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/${PYTHON_PACKAGE_PATH}" CACHE STRING "Subdirectory to install Python modules in")
|
||||
|
||||
set(PATH_LIST)
|
||||
if (ERT_ROOT)
|
||||
list(APPEND PATH_LIST ${ERT_ROOT})
|
||||
endif()
|
||||
list(APPEND PATH_LIST ${CMAKE_PREFIX_PATH})
|
||||
|
||||
# Add various popular sibling alternatives.
|
||||
list(APPEND PATH_LIST "${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build")
|
||||
|
||||
foreach( PATH ${PATH_LIST})
|
||||
set( python_code "import sys; sys.path.insert(0 , '${PATH}/${PYTHON_INSTALL_PREFIX}'); import os.path; import inspect; import cwrap; print os.path.dirname(os.path.dirname(inspect.getfile(cwrap)))")
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}"
|
||||
RESULT_VARIABLE import_result
|
||||
OUTPUT_VARIABLE stdout_output
|
||||
ERROR_VARIABLE stderr_output
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
|
||||
if (${import_result} EQUAL 0)
|
||||
set( CWRAP_PYTHON_PATH ${stdout_output} CACHE PATH "Python path for cwrap" )
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
find_package_handle_standard_args("Cwrap" DEFAULT_MSG CWRAP_PYTHON_PATH)
|
||||
287
cmake/Modules/FindERT.cmake
Normal file
287
cmake/Modules/FindERT.cmake
Normal file
@@ -0,0 +1,287 @@
|
||||
# - Find the Ensemble-based Reservoir Tool (ERT)
|
||||
#
|
||||
# Set the cache variable ERT_ROOT to the install location of the ERT
|
||||
# libraries and header files.
|
||||
#
|
||||
# If found, it sets these variables:
|
||||
#
|
||||
# ERT_INCLUDE_DIRS Header file directories
|
||||
# ERT_LIBRARIES Archives and shared objects
|
||||
# ERT_CONFIG_VARS Definitions that goes in config.h
|
||||
# ERT_LINKER_FLAGS Options that must be passed to linker
|
||||
#
|
||||
# It will also add to CMAKE_C_FLAGS and CMAKE_CXX_FLAGS if necessary to
|
||||
# link with the ERT libraries.
|
||||
|
||||
# variables to pass on to other packages
|
||||
if (FIND_QUIETLY)
|
||||
set (ERT_QUIET "QUIET")
|
||||
else (FIND_QUIETLY)
|
||||
set (ERT_QUIET "")
|
||||
endif (FIND_QUIETLY)
|
||||
|
||||
# if a directory has been specified by the user, then don't go look
|
||||
# in the system directories as well
|
||||
if (ERT_ROOT)
|
||||
set (_no_default_path "NO_DEFAULT_PATH")
|
||||
else (ERT_ROOT)
|
||||
set (_no_default_path "")
|
||||
endif (ERT_ROOT)
|
||||
|
||||
# ERT doesn't have any config-mode file, so we need to specify the root
|
||||
# directory in its own variable
|
||||
find_path (ERT_ECL_INCLUDE_DIR
|
||||
NAMES "ert/ecl/ecl_util.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libecl/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_ECL_WELL_INCLUDE_DIR
|
||||
NAMES "ert/ecl_well/well_const.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libecl_well/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_ECLXX_INCLUDE_DIR
|
||||
NAMES "ert/ecl/EclKW.hpp"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libeclxx/include/" "include"
|
||||
DOC "Path to ERT Eclipse C++ library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_UTIL_INCLUDE_DIR
|
||||
NAMES "ert/util/stringlist.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_util/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_UTILXX_INCLUDE_DIR
|
||||
NAMES "ert/util/ert_unique_ptr.hpp"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_utilxx/include/" "include"
|
||||
DOC "Path to ERT Eclipse C++ library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_path (ERT_GEN_INCLUDE_DIR
|
||||
NAMES "ert/util/int_vector.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_util/include"
|
||||
"include" "build/libert_util/include" "build/libert_util/include"
|
||||
DOC "Path to ERT generated library header files"
|
||||
${_no_default_path}
|
||||
)
|
||||
|
||||
|
||||
# need all of these libraries
|
||||
if (CMAKE_SIZEOF_VOID_P)
|
||||
math (EXPR _BITS "8 * ${CMAKE_SIZEOF_VOID_P}")
|
||||
endif (CMAKE_SIZEOF_VOID_P)
|
||||
find_library (ERT_LIBRARY_ECL
|
||||
NAMES "ecl"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Eclipse library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_ECLXX
|
||||
NAMES "eclxx"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Eclipse C++ library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_ECL_WELL
|
||||
NAMES "ecl_well"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Eclipse library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_GEOMETRY
|
||||
NAMES "ert_geometry"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Geometry library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_UTIL
|
||||
NAMES "ert_util"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Utilities library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
find_library (ERT_LIBRARY_UTILXX
|
||||
NAMES "ert_utilxx"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../libecl"
|
||||
"${PROJECT_SOURCE_DIR}/../libecl/build"
|
||||
"${PROJECT_BINARY_DIR}/../libecl-build"
|
||||
"${PROJECT_BINARY_DIR}/../ert"
|
||||
"${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build"
|
||||
PATH_SUFFIXES "lib" "lib/Release" "lib/Debug" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
DOC "Path to ERT Utilities library archive/shared object files"
|
||||
${_no_default_path}
|
||||
)
|
||||
# the "library" found here is actually a list of several files
|
||||
list (APPEND ERT_INCLUDE_DIR
|
||||
${ERT_ECL_INCLUDE_DIR}
|
||||
${ERT_ECL_WELL_INCLUDE_DIR}
|
||||
${ERT_ECLXX_INCLUDE_DIR}
|
||||
${ERT_UTIL_INCLUDE_DIR}
|
||||
${ERT_UTILXX_INCLUDE_DIR}
|
||||
${ERT_GEN_INCLUDE_DIR}
|
||||
)
|
||||
list (APPEND ERT_LIBRARY
|
||||
${ERT_LIBRARY_ECL}
|
||||
${ERT_LIBRARY_ECLXX}
|
||||
${ERT_LIBRARY_ECL_WELL}
|
||||
${ERT_LIBRARY_GEOMETRY}
|
||||
${ERT_LIBRARY_UTIL}
|
||||
${ERT_LIBRARY_UTILXX}
|
||||
)
|
||||
list (APPEND ERT_LIBRARIES ${ERT_LIBRARY})
|
||||
list (APPEND ERT_INCLUDE_DIRS ${ERT_INCLUDE_DIR})
|
||||
|
||||
# if we didn't find any files, then don't proceed through the entire dependency list
|
||||
include (FindPackageHandleStandardArgs)
|
||||
if (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND")
|
||||
find_package_handle_standard_args (ERT
|
||||
DEFAULT_MSG
|
||||
ERT_INCLUDE_DIR ERT_LIBRARY
|
||||
)
|
||||
# clear the cache so the find probe is attempted again if files becomes
|
||||
# available (only upon a unsuccessful *compile* should we disable further
|
||||
# probing)
|
||||
set (HAVE_ERT)
|
||||
unset (HAVE_ERT CACHE)
|
||||
return ()
|
||||
endif (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND")
|
||||
|
||||
|
||||
# dependencies
|
||||
|
||||
# parallel programming
|
||||
include (UseOpenMP)
|
||||
find_openmp (ERT)
|
||||
|
||||
# compression library
|
||||
find_package (ZLIB ${ERT_QUIET})
|
||||
if (ZLIB_FOUND)
|
||||
list (APPEND ERT_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
|
||||
list (APPEND ERT_LIBRARIES ${ZLIB_LIBRARIES})
|
||||
endif (ZLIB_FOUND)
|
||||
|
||||
# numerics
|
||||
find_package (BLAS ${ERT_QUIET})
|
||||
if (BLAS_FOUND)
|
||||
list (APPEND ERT_INCLUDE_DIRS ${BLAS_INCLUDE_DIRS})
|
||||
list (APPEND ERT_LIBRARIES ${BLAS_LIBRARIES})
|
||||
list (APPEND ERT_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
|
||||
endif (BLAS_FOUND)
|
||||
|
||||
find_package (LAPACK ${ERT_QUIET})
|
||||
if (LAPACK_FOUND)
|
||||
list (APPEND ERT_INCLUDE_DIRS ${LAPACK_INCLUDE_DIRS})
|
||||
list (APPEND ERT_LIBRARIES ${LAPACK_LIBRARIES})
|
||||
list (APPEND ERT_LINKER_FLAGS ${LAPACK_LINKER_FLAGS})
|
||||
endif (LAPACK_FOUND)
|
||||
|
||||
# math library (should exist on all unices; automatically linked on Windows)
|
||||
if (UNIX)
|
||||
find_library (MATH_LIBRARY
|
||||
NAMES "m"
|
||||
)
|
||||
list (APPEND ERT_LIBRARIES ${MATH_LIBRARY})
|
||||
endif (UNIX)
|
||||
|
||||
# if shared libraries are disabled on linux, explcitly linking to the
|
||||
# pthreads library is required by ERT
|
||||
find_package(Threads ${ERT_QUIET})
|
||||
if (CMAKE_THREAD_LIBS_INIT)
|
||||
list (APPEND ERT_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
# Platform specific library where dlopen with friends lives
|
||||
list (APPEND ERT_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
|
||||
# since OpenMP often implies pthreads, we need to tidy up
|
||||
# (last instance of library must be left standing, thus reversing that
|
||||
# list before removing duplicates)
|
||||
include (Duplicates)
|
||||
remove_dup_deps (ERT)
|
||||
|
||||
# see if we can compile a minimum example
|
||||
# CMake logical test doesn't handle lists (sic)
|
||||
if (NOT (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND"))
|
||||
include (CMakePushCheckState)
|
||||
include (CheckCSourceCompiles)
|
||||
cmake_push_check_state ()
|
||||
set (CMAKE_REQUIRED_INCLUDES ${ERT_INCLUDE_DIR})
|
||||
set (CMAKE_REQUIRED_LIBRARIES ${ERT_LIBRARIES})
|
||||
check_cxx_source_compiles (
|
||||
"#include <ert/ecl/ecl_grid.h>
|
||||
int main ( ) {
|
||||
ecl_grid_type * grid = ecl_grid_alloc_rectangular( 10,10,10,1,1,1, NULL);
|
||||
ecl_grid_free( grid );
|
||||
return 0;
|
||||
}" HAVE_ERT)
|
||||
cmake_pop_check_state ()
|
||||
else (NOT (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND"))
|
||||
# clear the cache so the find probe is attempted again if files becomes
|
||||
# available (only upon a unsuccessful *compile* should we disable further
|
||||
# probing)
|
||||
set (HAVE_ERT)
|
||||
unset (HAVE_ERT CACHE)
|
||||
endif (NOT (ERT_INCLUDE_DIR MATCHES "-NOTFOUND" OR ERT_LIBRARIES MATCHES "-NOTFOUND"))
|
||||
|
||||
# if the test program didn't compile, but was required to do so, bail
|
||||
# out now and display an error; otherwise limp on
|
||||
find_package_handle_standard_args (ERT
|
||||
DEFAULT_MSG
|
||||
ERT_INCLUDE_DIR ERT_LIBRARY HAVE_ERT
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
53
cmake/Modules/FindERTPython.cmake
Normal file
53
cmake/Modules/FindERTPython.cmake
Normal file
@@ -0,0 +1,53 @@
|
||||
# - Find the Python wrappers for Ensemble-based Reservoir Tool (ERT)
|
||||
#
|
||||
# Set the cache variable ERT_PYTHON_PATH to the install location of
|
||||
# the root ert package.
|
||||
|
||||
find_package(PythonInterp)
|
||||
if(PYTHONINTERP_FOUND)
|
||||
|
||||
# We try to find the ert Python distribution. This is done by running
|
||||
# Python code which tries to 'import ert' and prints out the path to
|
||||
# the module if the import succeeds.
|
||||
#
|
||||
# The normal Python import machinery is employed, so if you have
|
||||
# installed ert python in a default location, or alternatively set the
|
||||
# PYTHONPATH variable the ert Python distribution will eventually be
|
||||
# found there, independently of the alternatives which are tested with
|
||||
# the ${PATH_LIST} variable.
|
||||
|
||||
if (EXISTS "/etc/debian_version")
|
||||
set( PYTHON_PACKAGE_PATH "dist-packages")
|
||||
else()
|
||||
set( PYTHON_PACKAGE_PATH "site-packages")
|
||||
endif()
|
||||
set(PYTHON_INSTALL_PREFIX "lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/${PYTHON_PACKAGE_PATH}" CACHE STRING "Subdirectory to install Python modules in")
|
||||
|
||||
set(PATH_LIST)
|
||||
if (ERT_ROOT)
|
||||
list(APPEND PATH_LIST ${ERT_ROOT})
|
||||
endif()
|
||||
list(APPEND PATH_LIST ${CMAKE_PREFIX_PATH})
|
||||
|
||||
# Add various popular sibling alternatives.
|
||||
list(APPEND PATH_LIST "${PROJECT_SOURCE_DIR}/../ert/build"
|
||||
"${PROJECT_BINARY_DIR}/../ert-build")
|
||||
|
||||
foreach( PATH ${PATH_LIST})
|
||||
set( python_code "import sys; sys.path.insert(0 , '${PATH}/${PYTHON_INSTALL_PREFIX}'); import os.path; import inspect; import ert; print os.path.dirname(os.path.dirname(inspect.getfile(ert))); from ert.ecl import EclSum")
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}"
|
||||
RESULT_VARIABLE import_result
|
||||
OUTPUT_VARIABLE stdout_output
|
||||
ERROR_VARIABLE stderr_output
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
|
||||
if (${import_result} EQUAL 0)
|
||||
set( ERT_PYTHON_PATH ${stdout_output} CACHE PATH "Python path for ERT Python" )
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
find_package_handle_standard_args("ERTPython" DEFAULT_MSG ERT_PYTHON_PATH)
|
||||
|
||||
|
||||
|
||||
@@ -58,21 +58,7 @@ if(PARMETIS_INCLUDE_DIR)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${MPI_C_COMPILE_FLAGS}")
|
||||
|
||||
include(CheckIncludeFile)
|
||||
check_include_file(parmetis.h PARMETIS_FOUND)
|
||||
|
||||
if(NOT PARMETIS_FOUND)
|
||||
# If we are using the ParMETIS bindings of PTScotch, we need
|
||||
# to use the scotch include path as partmetis.h includes scotch.h
|
||||
find_package(PTScotch)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${PTSCOTCH_INCLUDE_DIR})
|
||||
unset(PARMETIS_FOUND CACHE) # force recheck of include file
|
||||
check_include_file(parmetis.h PARMETIS_FOUND)
|
||||
if(PARMETIS_FOUND)
|
||||
set(PARMETIS_SCOTCH_INCLUDE_DIRS ${PTSCOTCH_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
_search_parmetis_lib(PARMETIS_LIBRARY parmetis "The main ParMETIS library.")
|
||||
|
||||
# behave like a CMake module is supposed to behave
|
||||
@@ -90,7 +76,7 @@ find_package_handle_standard_args(
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(PARMETIS_FOUND)
|
||||
set(PARMETIS_INCLUDE_DIRS ${PARMETIS_INCLUDE_DIR} ${PARMETIS_SCOTCH_INCLUDE_DIRS})
|
||||
set(PARMETIS_INCLUDE_DIRS ${PARMETIS_INCLUDE_DIR})
|
||||
set(PARMETIS_LIBRARIES ${PARMETIS_LIBRARY} ${METIS_LIBRARIES} ${MPI_C_LIBRARIES}
|
||||
CACHE FILEPATH "All libraries needed to link programs using ParMETIS")
|
||||
set(PARMETIS_LINK_FLAGS "${DUNE_C_LINK_FLAGS}"
|
||||
|
||||
@@ -16,9 +16,6 @@ if(ZOLTAN_ROOT)
|
||||
set(ZOLTAN_NO_DEFAULT_PATH "NO_DEFAULT_PATH")
|
||||
endif()
|
||||
|
||||
# We only need zoltan with MPI. Otherwise usage of alugrid is broken.
|
||||
find_package(MPI)
|
||||
|
||||
# Make sure we have checked for the underlying partitioners.
|
||||
find_package(PTScotch)
|
||||
#find_package(ParMETIS)
|
||||
@@ -42,23 +39,20 @@ find_library(ZOLTAN_LIBRARIES
|
||||
${ZOLTAN_NO_DEFAULT_PATH})
|
||||
|
||||
set (ZOLTAN_FOUND FALSE)
|
||||
|
||||
set (ZOLTAN_CONFIG_VAR HAVE_ZOLTAN)
|
||||
|
||||
# print a message to indicate status of this package
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(ZOLTAN
|
||||
DEFAULT_MSG
|
||||
ZOLTAN_LIBRARIES
|
||||
ZOLTAN_INCLUDE_DIRS
|
||||
MPI_FOUND
|
||||
)
|
||||
|
||||
if (ZOLTAN_FOUND)
|
||||
if (ZOLTAN_INCLUDE_DIRS OR ZOLTAN_LIBRARIES)
|
||||
set(ZOLTAN_FOUND TRUE)
|
||||
set(HAVE_ZOLTAN 1)
|
||||
set(ZOLTAN_LIBRARIES ${ZOLTAN_LIBRARIES} ${PARMETIS_LIBRARIES} ${PTSCOTCH_LIBRARIES})
|
||||
set(ZOLTAN_INCLUDE_DIRS ${ZOLTAN_INCLUDE_DIRS} ${PARMETIS_INCLUDE_DIRS}
|
||||
${PTSCOTCH_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
set (ZOLTAN_CONFIG_VAR HAVE_ZOLTAN)
|
||||
|
||||
# print a message to indicate status of this package
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(ZOLTAN
|
||||
DEFAULT_MSG
|
||||
ZOLTAN_LIBRARIES
|
||||
ZOLTAN_INCLUDE_DIRS
|
||||
)
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
if ((NOT CJSON_ROOT) AND OPM_PARSER_ROOT)
|
||||
set( CJSON_ROOT ${OPM_PARSER_ROOT})
|
||||
endif()
|
||||
|
||||
if (CJSON_ROOT)
|
||||
set (_no_default_path "NO_DEFAULT_PATH")
|
||||
else (CJSON_ROOT)
|
||||
@@ -14,9 +18,10 @@ endif (CJSON_ROOT)
|
||||
|
||||
|
||||
find_path (CJSON_INCLUDE_DIR
|
||||
NAMES "cJSON.h"
|
||||
NAMES "cjson/cJSON.h"
|
||||
HINTS "${CJSON_ROOT}"
|
||||
PATH_SUFFIXES "cjson"
|
||||
PATHS "${PROJECT_SOURCE_DIR}"
|
||||
PATH_SUFFIXES "include" "external"
|
||||
DOC "Path to cjson library header files"
|
||||
${_no_default_path} )
|
||||
|
||||
@@ -31,7 +36,11 @@ string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/?(.*)" "\\1" BUILD_DIR_SUFFIX "${PR
|
||||
find_library (CJSON_LIBRARY
|
||||
NAMES "cjson"
|
||||
HINTS "${CJSON_ROOT}"
|
||||
PATHS "${PROJECT_BINARY_DIR}/../opm-parser"
|
||||
"${PROJECT_BINARY_DIR}/../opm-parser${BUILD_DIR_SUFFIX}"
|
||||
"${PROJECT_BINARY_DIR}/../../opm-parser/${BUILD_DIR_SUFFIX}"
|
||||
PATH_SUFFIXES "lib" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
"opm/json"
|
||||
DOC "Path to cjson library archive/shared object files"
|
||||
${_no_default_path} )
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ find_opm_package (
|
||||
# TODO: we should probe for all the HAVE_* values listed below;
|
||||
# however, we don't actually use them in our implementation, so
|
||||
# we just include them to forward here in case anyone else does
|
||||
"dune-grid REQUIRED;
|
||||
"CXX11Features REQUIRED;
|
||||
dune-grid REQUIRED;
|
||||
ZLIB;
|
||||
ZOLTAN;
|
||||
METIS
|
||||
|
||||
@@ -16,7 +16,8 @@ find_opm_package (
|
||||
"dune-common"
|
||||
|
||||
# dependencies
|
||||
"BLAS REQUIRED;
|
||||
"CXX11Features REQUIRED;
|
||||
BLAS REQUIRED;
|
||||
LAPACK REQUIRED;
|
||||
CxaDemangle;
|
||||
MPI
|
||||
@@ -28,7 +29,7 @@ find_opm_package (
|
||||
"dunecommon"
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
"DUNE_COMMON_FIELDVECTOR_SIZE_IS_METHOD=1"
|
||||
|
||||
# test program
|
||||
"#include <dune/common/fvector.hh>
|
||||
|
||||
@@ -19,7 +19,8 @@ find_opm_package (
|
||||
# TODO: we should probe for all the HAVE_* values listed below;
|
||||
# however, we don't actually use them in our implementation, so
|
||||
# we just include them to forward here in case anyone else does
|
||||
"dune-common REQUIRED;
|
||||
"CXX11Features REQUIRED;
|
||||
dune-common REQUIRED;
|
||||
dune-grid REQUIRED;
|
||||
dune-alugrid;
|
||||
ZLIB;
|
||||
|
||||
@@ -19,7 +19,8 @@ find_opm_package (
|
||||
# TODO: we should probe for all the HAVE_* values listed below;
|
||||
# however, we don't actually use them in our implementation, so
|
||||
# we just include them to forward here in case anyone else does
|
||||
"dune-common REQUIRED
|
||||
"CXX11Features REQUIRED;
|
||||
dune-common REQUIRED
|
||||
"
|
||||
# header to search for
|
||||
"dune/geometry/quadraturerules.hh"
|
||||
@@ -33,7 +34,8 @@ find_opm_package (
|
||||
# test program
|
||||
"#include <dune/geometry/quadraturerules.hh>
|
||||
int main (void) {
|
||||
Dune::GeometryType gt = Dune::GeometryTypes::quadrilateral;
|
||||
Dune::GeometryType gt;
|
||||
gt.makeQuadrilateral();
|
||||
Dune::QuadratureRules<double, 2>::rule(gt, 2).size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ find_opm_package (
|
||||
# TODO: we should probe for all the HAVE_* values listed below;
|
||||
# however, we don't actually use them in our implementation, so
|
||||
# we just include them to forward here in case anyone else does
|
||||
"dune-common REQUIRED;
|
||||
"CXX11Features REQUIRED;
|
||||
dune-common REQUIRED;
|
||||
dune-geometry REQUIRED;
|
||||
dune-uggrid;
|
||||
MPI;
|
||||
UG;
|
||||
Alberta
|
||||
UG
|
||||
"
|
||||
# header to search for
|
||||
"dune/grid/onedgrid.hh"
|
||||
@@ -55,8 +55,7 @@ int main (void) {
|
||||
HAVE_AMIRAMESH;
|
||||
HAVE_ALBERTA;
|
||||
HAVE_STDINT_H;
|
||||
DUNE_GRID_EXPERIMENTAL_GRID_EXTENSIONS;
|
||||
DUNE_ALBERTA_VERSION
|
||||
DUNE_GRID_EXPERIMENTAL_GRID_EXTENSIONS
|
||||
")
|
||||
|
||||
#debug_find_vars ("dune-grid")
|
||||
|
||||
@@ -7,7 +7,8 @@ find_opm_package (
|
||||
# dependencies
|
||||
# TODO: we should probe for all the HAVE_* values listed below;
|
||||
# however, we don't actually use them in our implementation, so
|
||||
"dune-common REQUIRED
|
||||
"CXX11Features REQUIRED;
|
||||
dune-common REQUIRED
|
||||
"
|
||||
# header to search for
|
||||
""
|
||||
|
||||
@@ -16,36 +16,7 @@ function (linker_cmdline what INTO outvar FROM)
|
||||
# (you get an error message about argument not parsed). translate each
|
||||
# of the libraries into a linker option
|
||||
set (deplib_list "")
|
||||
set (deplib_list_tmp "")
|
||||
foreach (deplib IN LISTS ARGN)
|
||||
# resolve imported targets
|
||||
string(FIND ${deplib} "::" _sep)
|
||||
if (_sep GREATER "-1")
|
||||
set(_lib "")
|
||||
# the code below does not really work for imported interface library
|
||||
# as cmake will error out whene querying IMPORTED_LOCATION, because the
|
||||
# property is not whitelisted. I have no idea how to determine if
|
||||
# a library is an imported interface library
|
||||
# At least it works for resolving OpenMP::OpenMP_CXX
|
||||
#
|
||||
# get_property(_def TARGET ${deplib} PROPERTY IMPORTED_LOCATION DEFINED)
|
||||
# if (_def)
|
||||
# get_property(_def TARGET ${deplib} PROPERTY IMPORTED_LOCATION SET)
|
||||
# if (_def)
|
||||
# get_target_property(_tmp_lib ${deplib} IMPORTED_LOCATION)
|
||||
# list(APPEND _lib ${_tmp_lib})
|
||||
# endif()
|
||||
# endif()
|
||||
get_property(_def TARGET ${deplib} PROPERTY INTERFACE_LINK_LIBRARIES SET)
|
||||
if (_def)
|
||||
get_target_property(_tmp_lib ${deplib} INTERFACE_LINK_LIBRARIES)
|
||||
list(APPEND _lib ${_tmp_lib})
|
||||
endif()
|
||||
set(deplib ${_lib})
|
||||
endif()
|
||||
list(APPEND deplib_list_tmp ${deplib})
|
||||
endforeach()
|
||||
foreach (deplib IN LISTS deplib_list_tmp)
|
||||
# starts with a hyphen already? then just add it
|
||||
string (SUBSTRING ${deplib} 0 1 dash)
|
||||
if (${dash} STREQUAL "-")
|
||||
@@ -73,20 +44,18 @@ function (linker_cmdline what INTO outvar FROM)
|
||||
# is more or less lost. remove system default path, to lessen the
|
||||
# chance that we pick the wrong library
|
||||
if (NOT ((deplib_dir STREQUAL "/usr/lib") OR
|
||||
(deplib_dir STREQUAL "") OR
|
||||
(deplib_dir STREQUAL "/usr/${CMAKE_INSTALL_LIBDIR}")))
|
||||
list (APPEND deplib_list "-L${deplib_dir}")
|
||||
endif ()
|
||||
(deplib_dir STREQUAL "/usr/${CMAKE_INSTALL_LIBDIR}")))
|
||||
list (APPEND deplib_list "-L${deplib_dir}")
|
||||
endif (NOT ((deplib_dir STREQUAL "/usr/lib") OR
|
||||
(deplib_dir STREQUAL "/usr/${CMAKE_INSTALL_LIBDIR}")))
|
||||
# if there was no translation of the name, the library is named
|
||||
# unconventionally (.so.3gf, I'm looking at you), so pass this
|
||||
# name unmodified to the linker switch
|
||||
if (deplib_orig STREQUAL deplib_name AND
|
||||
NOT deplib_orig STREQUAL "stdc++fs")
|
||||
if (deplib_orig STREQUAL deplib_name)
|
||||
list (APPEND deplib_list "-l:${deplib_orig}")
|
||||
else ()
|
||||
else (deplib_orig STREQUAL deplib_name)
|
||||
list (APPEND deplib_list "-l${deplib_name}")
|
||||
endif (deplib_orig STREQUAL deplib_name AND
|
||||
NOT deplib_orig STREQUAL "stdc++fs")
|
||||
endif (deplib_orig STREQUAL deplib_name)
|
||||
endif (${dash} STREQUAL "-")
|
||||
endforeach (deplib)
|
||||
# caller determines whether we want it returned as a list or a string
|
||||
|
||||
@@ -29,18 +29,12 @@ macro (opm_compile opm)
|
||||
|
||||
# create this library, if there are any compilation units
|
||||
link_directories (${${opm}_LIBRARY_DIRS})
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.12")
|
||||
# Some modules may still export definitions using -D, strip it
|
||||
string(REGEX REPLACE "-D" "" _clean_defs "${${opm}_DEFINITIONS}")
|
||||
add_compile_definitions(${_clean_defs})
|
||||
else()
|
||||
add_definitions(${${opm}_DEFINITIONS})
|
||||
endif()
|
||||
add_definitions (${${opm}_DEFINITIONS})
|
||||
set (${opm}_VERSION "${${opm}_VERSION_MAJOR}.${${opm}_VERSION_MINOR}")
|
||||
if (${opm}_SOURCES)
|
||||
add_library (${${opm}_TARGET} ${${opm}_LIBRARY_TYPE} ${${opm}_SOURCES})
|
||||
set_target_properties (${${opm}_TARGET} PROPERTIES
|
||||
SOVERSION ${${opm}_VERSION}
|
||||
SOVERSION ${${opm}_VERSION_MAJOR}
|
||||
VERSION ${${opm}_VERSION}
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
|
||||
POSITION_INDEPENDENT_CODE TRUE
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
# Check for various compiler extensions
|
||||
|
||||
# HAVE_ATTRIBUTE_ALWAYS_INLINE True if attribute always inline is supported
|
||||
# HAS_ATTRIBUTE_UNUSED True if attribute unused is supported
|
||||
# HAS_ATTRIBUTE_DEPRECATED True if attribute deprecated is supported
|
||||
# HAS_ATTRIBUTE_DEPRECATED_MSG True if attribute deprecated("msg") is supported
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
# __attribute__((always_inline))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
void __attribute__((always_inline)) foo(void) {}
|
||||
int main(void)
|
||||
{
|
||||
foo();
|
||||
return 0;
|
||||
};
|
||||
" HAVE_ATTRIBUTE_ALWAYS_INLINE
|
||||
)
|
||||
|
||||
# __attribute__((unused))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
int main(void)
|
||||
{
|
||||
int __attribute__((unused)) foo;
|
||||
return 0;
|
||||
};
|
||||
" HAS_ATTRIBUTE_UNUSED
|
||||
)
|
||||
|
||||
# __attribute__((deprecated))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#define DEP __attribute__((deprecated))
|
||||
class bar
|
||||
{
|
||||
bar() DEP;
|
||||
};
|
||||
|
||||
class peng { } DEP;
|
||||
|
||||
template <class T>
|
||||
class t_bar
|
||||
{
|
||||
t_bar() DEP;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class t_peng {
|
||||
t_peng() {};
|
||||
} DEP;
|
||||
|
||||
void foo() DEP;
|
||||
|
||||
void foo() {};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
" HAS_ATTRIBUTE_DEPRECATED
|
||||
)
|
||||
|
||||
# __attribute__((deprecated("msg")))
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#define DEP __attribute__((deprecated(\"message\")))
|
||||
class bar {
|
||||
bar() DEP;
|
||||
};
|
||||
|
||||
class peng { } DEP;
|
||||
|
||||
template <class T>
|
||||
class t_bar
|
||||
{
|
||||
t_bar() DEP;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class t_peng
|
||||
{
|
||||
t_peng() {};
|
||||
} DEP;
|
||||
|
||||
void foo() DEP;
|
||||
|
||||
void foo() {};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
" HAS_ATTRIBUTE_DEPRECATED_MSG
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
||||
list(APPEND ${project}_LIBRARIES stdc++fs)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(OPM_CLANG_WITH_STDC++FS "Using libstdc++ with clang and we want to link to stdc++fs" OFF)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND OPM_CLANG_WITH_STDC++FS)
|
||||
list(APPEND ${project}_LIBRARIES stdc++fs)
|
||||
endif()
|
||||
@@ -5,8 +5,6 @@ is_compiler_gcc_compatible ()
|
||||
include(TestCXXAcceptsFlag)
|
||||
|
||||
macro (opm_defaults opm)
|
||||
|
||||
message("Processing opm_defaults ${opm}")
|
||||
# if we are installing a development version (default when checking out of
|
||||
# VCS), then remember which directories were used when configuring. package
|
||||
# distribution should disable this option.
|
||||
|
||||
@@ -54,6 +54,21 @@ foreach (name IN LISTS _opm_proj_vars)
|
||||
endif (NOT DEFINED ${CMAKE_PROJECT_NAME}_${name})
|
||||
endforeach (name)
|
||||
|
||||
# these dependencies needs special treatment
|
||||
set (_opm_proj_exemptions
|
||||
dune-common
|
||||
dune-istl
|
||||
dune-grid
|
||||
dune-geometry
|
||||
dune-uggrid
|
||||
dune-alugrid
|
||||
dune-localfunctions
|
||||
dune-fem
|
||||
)
|
||||
|
||||
# although a DUNE module, it is delivered in the OPM suite
|
||||
set (opm-core_SUITE "opm")
|
||||
set (ewoms_SUITE "opm")
|
||||
|
||||
# insert this boilerplate whenever we are going to find a new package
|
||||
macro (find_and_append_package_to prefix name)
|
||||
@@ -104,15 +119,25 @@ macro (find_and_append_package_to prefix name)
|
||||
endif (EXISTS ${${NAME}_ROOT}/${name}-config.cmake OR EXISTS ${${NAME}_ROOT}/${name}Config.cmake)
|
||||
endif (NOT DEFINED ${name}_DIR AND (DEFINED ${name}_ROOT OR DEFINED ${NAME}_ROOT))
|
||||
|
||||
# these libraries need special handling which is not provided in
|
||||
# the -config.cmake file, but which must be provided by this project,
|
||||
# something which is done in our find module
|
||||
list (FIND _opm_proj_exemptions "${name}" _${name}_exempted)
|
||||
if ((NOT (_${name}_exempted EQUAL -1)) AND (DEFINED ${name}_DIR))
|
||||
set (${name}_ROOT "${${name}_DIR}")
|
||||
# store this for later, in case we reconfigure
|
||||
set (${name}_ROOT "${${name}_ROOT}" CACHE LOCATION "Path to ${name}")
|
||||
# clear this to not use config mode
|
||||
unset (${name}_DIR)
|
||||
# variables that are given on the command-line is also put in the cache
|
||||
# removing the local copy only "unshadows" this one
|
||||
unset (${name}_DIR CACHE)
|
||||
endif ((NOT (_${name}_exempted EQUAL -1)) AND (DEFINED ${name}_DIR))
|
||||
|
||||
# if we're told not to look for the package, pretend it was never found
|
||||
if (CMAKE_DISABLE_FIND_PACKAGE_${name})
|
||||
# If required send an error
|
||||
cmake_parse_arguments(FIND "REQUIRED" "" "" ${ARGN} )
|
||||
set (${name}_FOUND FALSE)
|
||||
set (${NAME}_FOUND FALSE)
|
||||
if (FIND_REQUIRED)
|
||||
message(SEND_ERROR "package ${name} but disable with CMAKE_DISABLE_FIND_PACKAGE_${name}")
|
||||
endif ()
|
||||
set (${name}_FOUND FALSE)
|
||||
set (${NAME}_FOUND FALSE)
|
||||
else ()
|
||||
# List of components might differ for every module. Therefore we will
|
||||
# need to research for a library multiple times. _search_components
|
||||
@@ -130,8 +155,28 @@ macro (find_and_append_package_to prefix name)
|
||||
# and the likes which is only done via opm_find_package
|
||||
if ( (NOT DEFINED ${name}_FOUND AND NOT DEFINED ${NAME}_FOUND )
|
||||
OR _search_components GREATER -1)
|
||||
string(REGEX MATCH "(opm)-.*" _is_opm ${name})
|
||||
string(REGEX MATCH "(dune|opm)-.*" _is_opm ${name})
|
||||
if(NOT _is_opm)
|
||||
string(REGEX MATCH "ewoms" _is_opm ${name})
|
||||
endif()
|
||||
if(${name} STREQUAL "ecl")
|
||||
# Give us a chance to find ecl installed to CMAKE_INSTALL_PREFIX.
|
||||
# We need to deactivate the package registry for this.
|
||||
create_module_dir_var(ecl)
|
||||
set(ARGN_NO_REQUIRED ${ARGN})
|
||||
if(ARGN)
|
||||
list(REMOVE_ITEM ARGN_NO_REQUIRED "REQUIRED")
|
||||
endif()
|
||||
find_package (${name} ${ARGN_NO_REQUIRED} NO_CMAKE_SYSTEM_PACKAGE_REGISTRY NO_CMAKE_PACKAGE_REGISTRY)
|
||||
if(TARGET ecl)
|
||||
# Need to grab from target to enable transitional depends
|
||||
#get_target_property(ecl_INCLUDE_DIRS ecl INTERFACE_INCLUDE_DIRECTORIES)
|
||||
set(ecl_LIBRARIES ecl)
|
||||
set(HAVE_ERT 1)
|
||||
endif()
|
||||
elseif(_${name}_exempted LESS 0 AND NOT _is_opm)
|
||||
find_package (${name} ${ARGN})
|
||||
elseif(_${name}_exempted GREATER -1)
|
||||
find_package (${name} ${ARGN})
|
||||
else()
|
||||
if(${name}_DIR)
|
||||
@@ -163,21 +208,7 @@ macro (find_and_append_package_to prefix name)
|
||||
string (REPLACE "-" "_" NAME "${NAME}")
|
||||
|
||||
if (${name}_FOUND OR ${NAME}_FOUND)
|
||||
foreach (var IN LISTS _opm_proj_vars)
|
||||
if("${var}" STREQUAL "DEFINITIONS"
|
||||
AND CMAKE_VERSION VERSION_LESS "3.12")
|
||||
# For old Cmake versions we use add_definitions which
|
||||
# requires -D qualifier add that
|
||||
set(_defs)
|
||||
foreach(_def IN LISTS ${name}_${var})
|
||||
if(_def MATCHES "^[a-zA-Z].*")
|
||||
list(APPEND _defs "-D${_def}")
|
||||
else()
|
||||
list(APPEND _defs "${_def}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${name}_${var} "${_defs}")
|
||||
endif()
|
||||
foreach (var IN LISTS _opm_proj_vars)
|
||||
if (DEFINED ${name}_${var})
|
||||
list (APPEND ${prefix}_${var} ${${name}_${var}})
|
||||
# some packages define an uppercase version of their own name
|
||||
|
||||
@@ -12,59 +12,6 @@
|
||||
# This module should be the first to be included in the project,
|
||||
# because most of the others (OpmXxx.cmake) use these variables.
|
||||
|
||||
# for CMake >= 3.0, we need to change a few policies:
|
||||
#
|
||||
# - CMP0026 to allow access to the LOCATION target property
|
||||
# - CMP0048 to indicate that we want to deal with the *VERSION*
|
||||
# variables ourselves
|
||||
# - CMP0064 to indicate that we want TEST if conditions to be evaluated
|
||||
# - CMP0074 to indicate that <PackageName>_ROOT can be used to find package
|
||||
# config files
|
||||
macro(OpmSetPolicies)
|
||||
if (POLICY CMP0026)
|
||||
# Needed as we query LOCATION in OpmCompile.cmake and OpmSatellites.cmake
|
||||
cmake_policy(SET CMP0026 OLD)
|
||||
endif()
|
||||
|
||||
if (POLICY CMP0048)
|
||||
# We do not set version. Hence NEW should work and this can be removed later
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0064)
|
||||
cmake_policy(SET CMP0064 NEW)
|
||||
endif()
|
||||
|
||||
# set the behavior of the policy 0054 to NEW. (i.e. do not implicitly
|
||||
# expand variables in if statements)
|
||||
if (POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
|
||||
# set the behavior of policy 0074 to new as we always used <PackageName>_ROOT as the
|
||||
# root of the installation
|
||||
if(POLICY CMP0074)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
endif()
|
||||
|
||||
# include special
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.3")
|
||||
message (STATUS "Enabling compatibility modules for CMake 2.8.3")
|
||||
list (APPEND CMAKE_MODULE_PATH "${OPM_MACROS_ROOT}/cmake/Modules/compat-2.8.3")
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.3")
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.5")
|
||||
message (STATUS "Enabling compatibility modules for CMake 2.8.5")
|
||||
list (APPEND CMAKE_MODULE_PATH "${OPM_MACROS_ROOT}/cmake/Modules/compat-2.8.5")
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.5")
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.7")
|
||||
message (STATUS "Enabling compatibility modules for CMake 2.8.7")
|
||||
list (APPEND CMAKE_MODULE_PATH "${OPM_MACROS_ROOT}/cmake/Modules/compat-2.8.7")
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.7")
|
||||
endmacro()
|
||||
|
||||
|
||||
# helper macro to retrieve a single field of a dune.module file
|
||||
macro(OpmGetDuneModuleDirective field variable contents)
|
||||
string (REGEX MATCH ".*${field}:[ ]*([^\n]+).*" ${variable} "${contents}")
|
||||
@@ -135,18 +82,6 @@ if (NOT USE_MPI)
|
||||
set (CMAKE_DISABLE_FIND_PACKAGE_MPI TRUE)
|
||||
endif ()
|
||||
|
||||
# Compiler standard version needs to be requested here as prereqs is included
|
||||
# before OpmLibMain and some tests need/use CXX_STANDARD_VERSION (e.g. pybind11)
|
||||
# Languages and global compiler settings
|
||||
if(CMAKE_VERSION VERSION_LESS 3.8)
|
||||
message(WARNING "CMake version does not support c++17, guessing -std=c++17")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
|
||||
# quadmath must be explicitly enabled
|
||||
# This needs to be in OpmInit as prereqs is called before OpmLibMain is included.
|
||||
option (USE_QUADMATH "Use high precision floating point library (slow)" OFF)
|
||||
|
||||
@@ -40,7 +40,7 @@ macro (opm_install opm)
|
||||
set (_sys_dbg_def OFF)
|
||||
endif (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
|
||||
option (SYSTEM_DEBUG "Put .debug files in GDB debug file directory" ${_sys_dbg_def})
|
||||
set (DEBUG_FILE_DIRECTORY /usr/lib/debug CACHE PATH "GDB debug file directory")
|
||||
set (DEBUG_FILE_DIRECTORY /usr/lib/debug CACHE LOCATION "GDB debug file directory")
|
||||
mark_as_advanced (DEBUG_FILE_DIRECTORY)
|
||||
if (SYSTEM_DEBUG AND NOT APPLE)
|
||||
set (_dbg_prefix "${DEBUG_FILE_DIRECTORY}/")
|
||||
|
||||
@@ -15,13 +15,49 @@
|
||||
# tests_hook Do special processing before tests are compiled
|
||||
# files_hook Do special processing before final targets are added
|
||||
|
||||
# for CMake >= 3.0, we need to change a few policies:
|
||||
#
|
||||
# - CMP0026 to allow access to the LOCATION target property
|
||||
# - CMP0048 to indicate that we want to deal with the *VERSION*
|
||||
# variables ourselves
|
||||
if (POLICY CMP0026)
|
||||
cmake_policy(SET CMP0026 OLD)
|
||||
endif()
|
||||
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 OLD)
|
||||
endif()
|
||||
|
||||
# set the behavior of the policy 0054 to NEW. (i.e. do not implicitly
|
||||
# expand variables in if statements)
|
||||
if (POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
|
||||
# include special
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.3")
|
||||
message (STATUS "Enabling compatibility modules for CMake 2.8.3")
|
||||
list (APPEND CMAKE_MODULE_PATH "${OPM_MACROS_ROOT}/cmake/Modules/compat-2.8.3")
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.3")
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.5")
|
||||
message (STATUS "Enabling compatibility modules for CMake 2.8.5")
|
||||
list (APPEND CMAKE_MODULE_PATH "${OPM_MACROS_ROOT}/cmake/Modules/compat-2.8.5")
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.5")
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.7")
|
||||
message (STATUS "Enabling compatibility modules for CMake 2.8.7")
|
||||
list (APPEND CMAKE_MODULE_PATH "${OPM_MACROS_ROOT}/cmake/Modules/compat-2.8.7")
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.7")
|
||||
|
||||
# don't write default flags into the cache, preserve that for user set values
|
||||
include (AddOptions)
|
||||
no_default_options ()
|
||||
|
||||
# Various compiler extension checks
|
||||
include(OpmCompilerChecks)
|
||||
# C++ project
|
||||
project (${${project}_NAME})
|
||||
enable_language (C)
|
||||
enable_language (CXX)
|
||||
|
||||
# print system information to better pinpoint issues from log alone
|
||||
include (UseSystemInfo)
|
||||
@@ -52,10 +88,7 @@ include (UseOptimization)
|
||||
|
||||
# turn on all warnings; this must be done before adding any
|
||||
# dependencies, in case they alter the list of warnings
|
||||
option(OPM_DISABLE_WARNINGS "Disable warning flags" OFF)
|
||||
if(NOT OPM_DISABLE_WARNINGS)
|
||||
include (UseWarnings)
|
||||
endif()
|
||||
include (UseWarnings)
|
||||
|
||||
# parallel programming
|
||||
include (UseOpenMP)
|
||||
@@ -223,13 +256,9 @@ macro (cond_disable_test name)
|
||||
endif ((NOT DEFINED HAVE_${name}) OR (NOT HAVE_${name}))
|
||||
endmacro (cond_disable_test name)
|
||||
|
||||
# use this target to run all tests, with parallel execution
|
||||
cmake_host_system_information(RESULT TESTJOBS QUERY NUMBER_OF_PHYSICAL_CORES)
|
||||
if(TESTJOBS EQUAL 0)
|
||||
set(TESTJOBS 1)
|
||||
endif()
|
||||
# use this target to run all tests
|
||||
add_custom_target (check
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} -j${TESTJOBS}
|
||||
COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
DEPENDS test-suite
|
||||
COMMENT "Checking if library is functional"
|
||||
VERBATIM
|
||||
|
||||
@@ -95,19 +95,10 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
|
||||
# compile with this option to avoid avalanche of warnings
|
||||
set (${module}_DEFINITIONS "${${module}_DEFINITIONS}")
|
||||
# -D to compile definitions for older CMake versions
|
||||
set (_D_PREFIX "")
|
||||
if(CMAKE_VERSION VERSION_LESS "3.12")
|
||||
set(_D_PREFIX "-D")
|
||||
endif()
|
||||
foreach (_def IN ITEMS ${defs})
|
||||
if(_def MATCHES "^[A-Za-z].*")
|
||||
list (APPEND ${module}_DEFINITIONS "${_D_PREFIX}${_def}")
|
||||
endif()
|
||||
list (APPEND ${module}_DEFINITIONS "-D${_def}")
|
||||
endforeach (_def)
|
||||
|
||||
list (APPEND ${module}_DEFINITIONS ${defs})
|
||||
|
||||
# tidy the lists before returning them
|
||||
remove_dup_deps (${module})
|
||||
|
||||
@@ -124,34 +115,26 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
# without config.h
|
||||
config_cmd_line (${module}_CMD_CONFIG ${module}_CONFIG_VARS)
|
||||
|
||||
if(prog)
|
||||
# check that we can compile a small test-program
|
||||
include (CMakePushCheckState)
|
||||
cmake_push_check_state ()
|
||||
include (CheckCXXSourceCompiles)
|
||||
# only add these if they are actually found; otherwise it won't
|
||||
# compile and the variable won't be set
|
||||
append_found (${module}_INCLUDE_DIRS CMAKE_REQUIRED_INCLUDES)
|
||||
append_found (${module}_LIBRARIES CMAKE_REQUIRED_LIBRARIES)
|
||||
# since we don't have any config.h yet
|
||||
list (APPEND CMAKE_REQUIRED_DEFINITIONS ${${module}_DEFINITIONS})
|
||||
list (APPEND CMAKE_REQUIRED_DEFINITIONS ${${module}_CMD_CONFIG})
|
||||
check_cxx_source_compiles ("${prog}" HAVE_${MODULE})
|
||||
cmake_pop_check_state ()
|
||||
else(prog)
|
||||
if(${module}_FOUND)
|
||||
# No test code provided, mark compilation as successful
|
||||
# if module was founf
|
||||
set(HAVE_${MODULE} 1)
|
||||
endif(${module}_FOUND)
|
||||
endif(prog)
|
||||
# check that we can compile a small test-program
|
||||
include (CMakePushCheckState)
|
||||
cmake_push_check_state ()
|
||||
include (CheckCXXSourceCompiles)
|
||||
# only add these if they are actually found; otherwise it won't
|
||||
# compile and the variable won't be set
|
||||
append_found (${module}_INCLUDE_DIRS CMAKE_REQUIRED_INCLUDES)
|
||||
append_found (${module}_LIBRARIES CMAKE_REQUIRED_LIBRARIES)
|
||||
# since we don't have any config.h yet
|
||||
list (APPEND CMAKE_REQUIRED_DEFINITIONS ${${module}_DEFINITIONS})
|
||||
list (APPEND CMAKE_REQUIRED_DEFINITIONS ${${module}_CMD_CONFIG})
|
||||
check_cxx_source_compiles ("${prog}" HAVE_${MODULE})
|
||||
cmake_pop_check_state ()
|
||||
|
||||
# write status message in the same manner as everyone else
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (
|
||||
${module}
|
||||
DEFAULT_MSG
|
||||
${module}_INCLUDE_DIRS ${module}_LIBRARIES ${module}_FOUND ${module}_ALL_PREREQS HAVE_${MODULE}
|
||||
${module}_INCLUDE_DIRS ${module}_LIBRARIES ${module}_FOUND ${module}_ALL_PREREQS
|
||||
)
|
||||
|
||||
# some genius that coded the FindPackageHandleStandardArgs figured out
|
||||
@@ -179,7 +162,7 @@ macro (find_package_deps module)
|
||||
# (i.e. if an optional package requests a package to be required,
|
||||
# the build will fail if it's not found)
|
||||
string (REPLACE "REQUIRED" "${_${module}_required}" _args_req "${_${module}_args}")
|
||||
if(_dep MATCHES "opm-")
|
||||
if(_dep MATCHES "opm-" OR _dep MATCHES "ewoms")
|
||||
set(deplist ${_dep})
|
||||
string(STRIP "${_dep}" _dep)
|
||||
string(REPLACE " " ";" deplist "${_dep}")
|
||||
|
||||
@@ -30,6 +30,7 @@ function (configure_pc_file name source dest prefix libdir includedir)
|
||||
set (minor "${${name}_VERSION_MINOR}")
|
||||
set (target "${${name}_LIBRARY}")
|
||||
linker_cmdline (STRING INTO target from ${target})
|
||||
|
||||
configure_file (${source} ${dest} @ONLY)
|
||||
endfunction (configure_pc_file name source dist prefix libdir includedir)
|
||||
|
||||
@@ -100,24 +101,16 @@ function (opm_cmake_config name)
|
||||
# and we have existing entries pointing to that install directory.
|
||||
# Since they will yield a duplicate in next replace anyways, we filter them out first
|
||||
# to get avoid those the bogus entries.
|
||||
# First with trailing / to change /usr/include/package to package and not /package
|
||||
# Fixes broken pkg-config files for Debian/Ubuntu packaging.
|
||||
string(FIND "${${name}_INCLUDE_DIRS}" "${PROJECT_SOURCE_DIR}" _source_in_include)
|
||||
string(REPLACE "${CMAKE_INSTALL_PREFIX}/include${${name}_VER_DIR}" "" ${name}_INCLUDE_DIRS "${${name}_INCLUDE_DIRS}")
|
||||
|
||||
if(_source_in_include GREATER "-1")
|
||||
string(REGEX REPLACE "${CMAKE_INSTALL_PREFIX}/include${${name}_VER_DIR}[;$]" "" ${name}_INCLUDE_DIRS "${${name}_INCLUDE_DIRS}")
|
||||
# Get rid of empty entries
|
||||
string(REPLACE ";;" ";" ${name}_INCLUDE_DIRS "${${name}_INCLUDE_DIRS}")
|
||||
|
||||
# replace the build directory with the target directory in the
|
||||
# variables that contains build paths
|
||||
string (REPLACE
|
||||
"${PROJECT_SOURCE_DIR}"
|
||||
"${CMAKE_INSTALL_PREFIX}/include${${name}_VER_DIR}"
|
||||
${name}_INCLUDE_DIRS
|
||||
"${${name}_INCLUDE_DIRS}"
|
||||
)
|
||||
endif()
|
||||
# replace the build directory with the target directory in the
|
||||
# variables that contains build paths
|
||||
string (REPLACE
|
||||
"${PROJECT_SOURCE_DIR}"
|
||||
"${CMAKE_INSTALL_PREFIX}/include${${name}_VER_DIR}"
|
||||
${name}_INCLUDE_DIRS
|
||||
"${${name}_INCLUDE_DIRS}"
|
||||
)
|
||||
string (REPLACE
|
||||
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
|
||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${${name}_VER_DIR}"
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# - Build satellites that are dependent of main library
|
||||
|
||||
option(ADD_DISABLED_CTESTS "Add the tests which are disabled due to failed preconditions to the ctest output (this makes ctest return an error if such a test is present)" ON)
|
||||
mark_as_advanced(ADD_DISABLED_CTESTS)
|
||||
|
||||
#
|
||||
# Enumerate all source code in a "satellite" directory such as tests/,
|
||||
# compile each of them and optionally set them as a test for CTest to
|
||||
@@ -8,139 +11,144 @@
|
||||
# The following suffices must be defined for the opm prefix passed as
|
||||
# parameter:
|
||||
#
|
||||
# _LINKER_FLAGS Necessary flags to link with this library
|
||||
# _TARGET CMake target which creates the library
|
||||
# _LIBRARIES Other dependencies that must also be linked
|
||||
# _LINKER_FLAGS Necessary flags to link with this library
|
||||
# _TARGET CMake target which creates the library
|
||||
# _LIBRARIES Other dependencies that must also be linked
|
||||
|
||||
# Synopsis:
|
||||
# opm_compile_satellites (opm satellite excl_all test_regexp)
|
||||
# opm_compile_satellites (opm satellite excl_all test_regexp)
|
||||
#
|
||||
# Parameters:
|
||||
# opm Prefix of the variable which contain information
|
||||
# about the library these satellites depends on, e.g.
|
||||
# pass "opm-core" if opm-core_TARGET is the name of
|
||||
# the target the builds this library. Variables with
|
||||
# suffixes _TARGET and _LIBRARIES must exist.
|
||||
# opm Prefix of the variable which contain information
|
||||
# about the library these satellites depends on, e.g.
|
||||
# pass "opm-core" if opm-core_TARGET is the name of
|
||||
# the target the builds this library. Variables with
|
||||
# suffixes _TARGET and _LIBRARIES must exist.
|
||||
#
|
||||
# satellite Prefix of variable which contain the names of the
|
||||
# files, e.g. pass "tests" if the files are in the
|
||||
# variable tests_SOURCES. Variables with suffixes
|
||||
# _DATAFILES, _SOURCES and _DIR should exist. This
|
||||
# name is also used as name of the target that builds
|
||||
# all these files.
|
||||
# satellite Prefix of variable which contain the names of the
|
||||
# files, e.g. pass "tests" if the files are in the
|
||||
# variable tests_SOURCES. Variables with suffixes
|
||||
# _DATAFILES, _SOURCES and _DIR should exist. This
|
||||
# name is also used as name of the target that builds
|
||||
# all these files.
|
||||
#
|
||||
# excl_all EXCLUDE_FROM_ALL if these targets should not be built by
|
||||
# default, otherwise empty string.
|
||||
# excl_all EXCLUDE_FROM_ALL if these targets should not be built by
|
||||
# default, otherwise empty string.
|
||||
#
|
||||
# test_regexp Regular expression which picks the name of a test
|
||||
# out of the filename, or blank if no test should be
|
||||
# setup.
|
||||
# test_regexp Regular expression which picks the name of a test
|
||||
# out of the filename, or blank if no test should be
|
||||
# setup.
|
||||
#
|
||||
# Example:
|
||||
# opm_compile_satellites (opm-core test "" "^test_([^/]*)$")
|
||||
# opm_compile_satellites (opm-core test "" "^test_([^/]*)$")
|
||||
#
|
||||
macro (opm_compile_satellites opm satellite excl_all test_regexp)
|
||||
# if we are going to build the tests always, then make sure that
|
||||
# the datafiles are present too
|
||||
if (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
||||
set (_incl_all "ALL")
|
||||
set (_incl_all "ALL")
|
||||
else (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
||||
set (_incl_all "")
|
||||
set (_incl_all "")
|
||||
endif (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
||||
|
||||
# if a set of datafiles has been setup, pull those in
|
||||
add_custom_target (${satellite} ${_incl_all})
|
||||
if (${satellite}_DATAFILES)
|
||||
add_dependencies (${satellite} ${${satellite}_DATAFILES})
|
||||
add_dependencies (${satellite} ${${satellite}_DATAFILES})
|
||||
endif (${satellite}_DATAFILES)
|
||||
|
||||
# compile each of these separately
|
||||
foreach (_sat_FILE IN LISTS ${satellite}_SOURCES)
|
||||
if (NOT "${test_regexp}" STREQUAL "" AND NOT Boost_UNIT_TEST_FRAMEWORK_FOUND)
|
||||
continue()
|
||||
endif()
|
||||
get_filename_component (_sat_NAME "${_sat_FILE}" NAME_WE)
|
||||
add_executable (${_sat_NAME} ${excl_all} ${_sat_FILE})
|
||||
add_dependencies (${satellite} ${_sat_NAME})
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}")
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
# are we building a test? luckily, the testing framework doesn't
|
||||
# require anything else, so we don't have to figure out where it
|
||||
# should go in the library list
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
|
||||
else (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "")
|
||||
add_static_analysis_tests(_sat_FILE ${opm}_INCLUDE_DIRS)
|
||||
endif (NOT "${test_regexp}" STREQUAL "")
|
||||
target_link_libraries (${_sat_NAME} ${${opm}_TARGET} ${${opm}_LIBRARIES} ${_test_lib})
|
||||
if (STRIP_DEBUGGING_SYMBOLS)
|
||||
strip_debug_symbols (${_sat_NAME} _sat_DEBUG)
|
||||
list (APPEND ${satellite}_DEBUG ${_sat_DEBUG})
|
||||
endif()
|
||||
|
||||
# variable with regular expression doubles as a flag for
|
||||
# whether tests should be setup or not
|
||||
set(_sat_FANCY)
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
foreach (_regexp IN ITEMS ${test_regexp})
|
||||
if ("${_sat_NAME}" MATCHES "${_regexp}")
|
||||
string (REGEX REPLACE "${_regexp}" "\\1" _sat_FANCY "${_sat_NAME}")
|
||||
elseif(NOT _sat_FANCY)
|
||||
set(_sat_FANCY ${_sat_NAME})
|
||||
get_filename_component (_sat_NAME "${_sat_FILE}" NAME_WE)
|
||||
add_executable (${_sat_NAME} ${excl_all} ${_sat_FILE})
|
||||
add_dependencies (${satellite} ${_sat_NAME})
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
|
||||
)
|
||||
if(HAVE_DYNAMIC_BOOST_TEST AND NOT (${opm} STREQUAL "opm-parser" AND NOT BUILD_SHARED_LIBS))
|
||||
set_target_properties (${_sat_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK
|
||||
)
|
||||
endif()
|
||||
# are we building a test? luckily, the testing framework doesn't
|
||||
# require anything else, so we don't have to figure out where it
|
||||
# should go in the library list
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
|
||||
else (NOT "${test_regexp}" STREQUAL "")
|
||||
set (_test_lib "")
|
||||
add_static_analysis_tests(_sat_FILE ${opm}_INCLUDE_DIRS)
|
||||
endif (NOT "${test_regexp}" STREQUAL "")
|
||||
target_link_libraries (${_sat_NAME} ${${opm}_TARGET} ${${opm}_LIBRARIES} ${_test_lib})
|
||||
if (STRIP_DEBUGGING_SYMBOLS)
|
||||
strip_debug_symbols (${_sat_NAME} _sat_DEBUG)
|
||||
list (APPEND ${satellite}_DEBUG ${_sat_DEBUG})
|
||||
endif()
|
||||
endforeach (_regexp)
|
||||
get_target_property (_sat_LOC ${_sat_NAME} LOCATION)
|
||||
# Run tests through mpi-run. Ubuntu 14.04 provided mpi libs will crash
|
||||
# in the MPI_Finalize() call otherwise.
|
||||
if(MPI_FOUND)
|
||||
set(_sat_LOC ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 1 ${_sat_LOC})
|
||||
endif()
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (NAME ${_sat_FANCY}
|
||||
COMMAND ${CMAKE_COMMAND} -E chdir "${PROJECT_BINARY_DIR}/${${satellite}_DIR}" ${_sat_LOC})
|
||||
else (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (${_sat_FANCY} ${_sat_LOC})
|
||||
# run the test in the directory where the data files are
|
||||
set_tests_properties (${_sat_FANCY} PROPERTIES
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${${satellite}_DIR})
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
endif()
|
||||
add_dependencies(test-suite "${_sat_NAME}")
|
||||
endif(NOT "${test_regexp}" STREQUAL "")
|
||||
|
||||
# if this program on the list of files that should be distributed?
|
||||
# we check by the name of the source file
|
||||
list (FIND ${satellite}_SOURCES_DIST "${_sat_FILE}" _is_util)
|
||||
if (NOT (_is_util EQUAL -1))
|
||||
install (TARGETS ${_sat_NAME} RUNTIME
|
||||
DESTINATION bin${${opm}_VER_DIR}/)
|
||||
endif (NOT (_is_util EQUAL -1))
|
||||
# variable with regular expression doubles as a flag for
|
||||
# whether tests should be setup or not
|
||||
set(_sat_FANCY)
|
||||
if (NOT "${test_regexp}" STREQUAL "")
|
||||
foreach (_regexp IN ITEMS ${test_regexp})
|
||||
if ("${_sat_NAME}" MATCHES "${_regexp}")
|
||||
string (REGEX REPLACE "${_regexp}" "\\1" _sat_FANCY "${_sat_NAME}")
|
||||
elseif(NOT _sat_FANCY)
|
||||
set(_sat_FANCY ${_sat_NAME})
|
||||
endif()
|
||||
endforeach (_regexp)
|
||||
get_target_property (_sat_LOC ${_sat_NAME} LOCATION)
|
||||
# Run tests through mpi-run. Ubuntu 14.04 provided mpi libs will crash
|
||||
# in the MPI_Finalize() call otherwise.
|
||||
if(MPI_FOUND)
|
||||
set(_sat_LOC ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 1 ${_sat_LOC})
|
||||
endif()
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (
|
||||
NAME ${_sat_FANCY}
|
||||
COMMAND ${CMAKE_COMMAND} -E chdir "${PROJECT_BINARY_DIR}/${${satellite}_DIR}" ${_sat_LOC}
|
||||
)
|
||||
else (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
add_test (${_sat_FANCY} ${_sat_LOC})
|
||||
# run the test in the directory where the data files are
|
||||
set_tests_properties (${_sat_FANCY} PROPERTIES
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${${satellite}_DIR}
|
||||
)
|
||||
endif (CMAKE_VERSION VERSION_LESS "2.8.4")
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
endif()
|
||||
add_dependencies(test-suite "${_sat_NAME}")
|
||||
endif(NOT "${test_regexp}" STREQUAL "")
|
||||
|
||||
# if this program on the list of files that should be distributed?
|
||||
# we check by the name of the source file
|
||||
list (FIND ${satellite}_SOURCES_DIST "${_sat_FILE}" _is_util)
|
||||
if (NOT (_is_util EQUAL -1))
|
||||
install (TARGETS ${_sat_NAME} RUNTIME
|
||||
DESTINATION bin${${opm}_VER_DIR}/
|
||||
)
|
||||
endif (NOT (_is_util EQUAL -1))
|
||||
endforeach (_sat_FILE)
|
||||
endmacro (opm_compile_satellites opm prefix)
|
||||
|
||||
# Synopsis:
|
||||
# opm_data (satellite target dirname files)
|
||||
# opm_data (satellite target dirname files)
|
||||
#
|
||||
# provides these output variables:
|
||||
#
|
||||
# ${satellite}_INPUT_FILES List of all files that are copied
|
||||
# ${satellite}_DATAFILES Name of target which copies these files
|
||||
# ${satellite}_INPUT_FILES List of all files that are copied
|
||||
# ${satellite}_DATAFILES Name of target which copies these files
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# opm_data (tests datafiles "tests/")
|
||||
# opm_data (tests datafiles "tests/")
|
||||
#
|
||||
macro (opm_data satellite target dirname)
|
||||
# even if there are no datafiles, create the directory so the
|
||||
# satellite programs have a homedir to run in
|
||||
execute_process (COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${dirname})
|
||||
execute_process (
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${dirname}
|
||||
)
|
||||
|
||||
# if ever huge test datafiles are necessary, then change this
|
||||
# into "create_symlink" (on UNIX only, apparently)
|
||||
@@ -150,27 +158,26 @@ macro (opm_data satellite target dirname)
|
||||
# to a tests/ directory in the output tree (if different)
|
||||
set (${satellite}_INPUT_FILES)
|
||||
if (NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||
foreach (input_datafile IN LISTS ${satellite}_DATA)
|
||||
if (IS_ABSOLUTE ${input_datafile})
|
||||
file (RELATIVE_PATH rel_datafile "${PROJECT_SOURCE_DIR}" ${input_datafile})
|
||||
else()
|
||||
set(rel_datafile ${input_datafile})
|
||||
endif()
|
||||
set (output_datafile "${PROJECT_BINARY_DIR}/${rel_datafile}")
|
||||
add_custom_command (OUTPUT ${output_datafile}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E ${make_avail} ${input_datafile} ${output_datafile}
|
||||
DEPENDS ${input_datafile}
|
||||
VERBATIM)
|
||||
list (APPEND ${satellite}_INPUT_FILES "${output_datafile}")
|
||||
endforeach (input_datafile)
|
||||
foreach (input_datafile IN LISTS ${satellite}_DATA)
|
||||
file (RELATIVE_PATH rel_datafile "${PROJECT_SOURCE_DIR}" ${input_datafile})
|
||||
set (output_datafile "${PROJECT_BINARY_DIR}/${rel_datafile}")
|
||||
add_custom_command (
|
||||
OUTPUT ${output_datafile}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E ${make_avail} ${input_datafile} ${output_datafile}
|
||||
DEPENDS ${input_datafile}
|
||||
VERBATIM
|
||||
)
|
||||
list (APPEND ${satellite}_INPUT_FILES "${output_datafile}")
|
||||
endforeach (input_datafile)
|
||||
endif(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||
|
||||
# setup a target which does all the copying
|
||||
set (${satellite}_DATAFILES "${target}")
|
||||
add_custom_target (${${satellite}_DATAFILES}
|
||||
DEPENDS ${${satellite}_INPUT_FILES}
|
||||
COMMENT "Making \"${satellite}\" data available in output tree")
|
||||
DEPENDS ${${satellite}_INPUT_FILES}
|
||||
COMMENT "Making \"${satellite}\" data available in output tree"
|
||||
)
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
endif()
|
||||
@@ -185,7 +192,6 @@ endmacro (opm_data satellite target dirname files)
|
||||
# Parameters:
|
||||
# TestName Name of test
|
||||
# ONLY_COMPILE Only build test but do not run it (optional)
|
||||
# DEFAULT_ENABLE_IF Only enable by default if a given condition is true (optional)
|
||||
# ALWAYS_ENABLE Force enabling test even if -DBUILD_TESTING=OFF was set (optional)
|
||||
# EXE_NAME Name of test executable (optional, default: ./bin/${TestName})
|
||||
# CONDITION Condition to enable test (optional, cmake code)
|
||||
@@ -198,7 +204,6 @@ endmacro (opm_data satellite target dirname files)
|
||||
# TEST_DEPENDS Other tests which must be run before running this test (optional, default: None)
|
||||
# LIBRARIES Libraries to link test against (optional)
|
||||
# WORKING_DIRECTORY Working directory for test (optional, default: ${PROJECT_BINARY_DIR})
|
||||
# CONFIGURATION Configuration to add test to
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
@@ -212,8 +217,8 @@ include(CMakeParseArguments)
|
||||
macro(opm_add_test TestName)
|
||||
cmake_parse_arguments(CURTEST
|
||||
"NO_COMPILE;ONLY_COMPILE;ALWAYS_ENABLE" # flags
|
||||
"EXE_NAME;PROCESSORS;WORKING_DIRECTORY;CONFIGURATION" # one value args
|
||||
"CONDITION;DEFAULT_ENABLE_IF;TEST_DEPENDS;DRIVER;DRIVER_ARGS;DEPENDS;TEST_ARGS;SOURCES;LIBRARIES" # multi-value args
|
||||
"EXE_NAME;PROCESSORS;WORKING_DIRECTORY" # one value args
|
||||
"CONDITION;TEST_DEPENDS;DRIVER;DRIVER_ARGS;DEPENDS;TEST_ARGS;SOURCES;LIBRARIES" # multi-value args
|
||||
${ARGN})
|
||||
|
||||
set(BUILD_TESTING "${BUILD_TESTING}")
|
||||
@@ -261,11 +266,6 @@ macro(opm_add_test TestName)
|
||||
# case. They can still be build using 'make test-suite' and they can
|
||||
# be build and run using 'make check'
|
||||
set(CURTEST_EXCLUDE_FROM_ALL "")
|
||||
if (NOT "AND OR ${CURTEST_DEFAULT_ENABLE_IF}" STREQUAL "AND OR ")
|
||||
if (NOT ${CURTEST_DEFAULT_ENABLE_IF})
|
||||
set(CURTEST_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
|
||||
endif()
|
||||
endif()
|
||||
if (NOT BUILD_TESTING AND NOT CURTEST_ALWAYS_ENABLE)
|
||||
set(CURTEST_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
|
||||
endif()
|
||||
@@ -303,8 +303,6 @@ macro(opm_add_test TestName)
|
||||
# only compile the binary but do not run it as a test
|
||||
add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES})
|
||||
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
||||
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
|
||||
add_static_analysis_tests(CURTEST_SOURCES dirs)
|
||||
|
||||
if(TARGET ${project}_prepare)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare)
|
||||
@@ -318,13 +316,7 @@ macro(opm_add_test TestName)
|
||||
# run-only case occurs if the binary is already compiled by an
|
||||
# earlier test.)
|
||||
add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES})
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties (${CURTEST_EXE_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
||||
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
|
||||
add_static_analysis_tests(CURTEST_SOURCES dirs)
|
||||
|
||||
if(CURTEST_DEPENDS)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS})
|
||||
@@ -348,17 +340,16 @@ macro(opm_add_test TestName)
|
||||
|
||||
add_test(NAME ${_FANCY}
|
||||
WORKING_DIRECTORY "${CURTEST_WORKING_DIRECTORY}"
|
||||
COMMAND ${CURTEST_COMMAND}
|
||||
CONFIGURATIONS ${CURTEST_CONFIGURATION})
|
||||
COMMAND ${CURTEST_COMMAND})
|
||||
|
||||
# specify the dependencies between the tests
|
||||
if (CURTEST_TEST_DEPENDS)
|
||||
set_tests_properties(${_FANCY} PROPERTIES DEPENDS "${CURTEST_TEST_DEPENDS}")
|
||||
set_tests_properties(${TestName} PROPERTIES DEPENDS "${CURTEST_TEST_DEPENDS}")
|
||||
endif()
|
||||
|
||||
# tell ctest how many cores it should reserve to run the test
|
||||
if (CURTEST_PROCESSORS)
|
||||
set_tests_properties(${_FANCY} PROPERTIES PROCESSORS "${CURTEST_PROCESSORS}")
|
||||
set_tests_properties(${TestName} PROPERTIES PROCESSORS "${CURTEST_PROCESSORS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -368,6 +359,15 @@ macro(opm_add_test TestName)
|
||||
endif()
|
||||
add_dependencies(test-suite "${CURTEST_EXE_NAME}")
|
||||
endif()
|
||||
|
||||
else() # test is skipped
|
||||
|
||||
# the following causes the test to appear as 'skipped' in the
|
||||
# CDash dashboard. it this is removed, the test is just silently
|
||||
# ignored.
|
||||
if (NOT CURTEST_ONLY_COMPILE AND ADD_DISABLED_CTESTS)
|
||||
add_test(${_FANCY} skip_test_dummy)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
@@ -9,7 +9,12 @@ macro(create_module_dir_var module)
|
||||
get_filename_component(_parent_dir_name ${_parent_full_dir} NAME)
|
||||
#Try if <module-name>/<build-dir> is used
|
||||
get_filename_component(_modules_dir ${_parent_full_dir} DIRECTORY)
|
||||
set(_clone_dir "${module}")
|
||||
if ("${module}" STREQUAL "ecl")
|
||||
#use clone directory libecl
|
||||
set(_clone_dir "libecl")
|
||||
else()
|
||||
set(_clone_dir "${module}")
|
||||
endif()
|
||||
if(IS_DIRECTORY ${_modules_dir}/${_clone_dir}/${_leaf_dir_name})
|
||||
set(${module}_DIR ${_modules_dir}/${_clone_dir}/${_leaf_dir_name})
|
||||
else()
|
||||
@@ -18,8 +23,7 @@ macro(create_module_dir_var module)
|
||||
AND IS_DIRECTORY ${_parent_full_dir}/${_module_leaf})
|
||||
# We are using build directories named <prefix><module-name><postfix>
|
||||
set(${module}_DIR ${_parent_full_dir}/${_module_leaf})
|
||||
elseif(IS_DIRECTORY ${_parent_full_dir}/${_clone_dir} AND
|
||||
EXISTS ${_parent_full_dir}/${_clone_dir}/CMakeCache.txt)
|
||||
elseif(IS_DIRECTORY ${_parent_full_dir}/${_clone_dir})
|
||||
# All modules are in a common build dir
|
||||
set(${module}_DIR "${_parent_full_dir}/${_clone_dir}")
|
||||
endif()
|
||||
|
||||
@@ -42,13 +42,7 @@ macro (find_openmp opm)
|
||||
# enabling OpenMP is supposedly enough to make the compiler link with
|
||||
# the appropriate libraries
|
||||
find_package (OpenMP ${${opm}_QUIET})
|
||||
|
||||
if(OpenMP_CXX_FOUND)
|
||||
list (APPEND ${opm}_LIBRARIES OpenMP::OpenMP_CXX)
|
||||
else()
|
||||
list (APPEND ${opm}_LIBRARIES ${OpenMP_LIBRARIES})
|
||||
endif()
|
||||
|
||||
list (APPEND ${opm}_LIBRARIES ${OpenMP_LIBRARIES})
|
||||
if (OPENMP_FOUND)
|
||||
add_options (C ALL_BUILDS "${OpenMP_C_FLAGS}")
|
||||
add_options (CXX ALL_BUILDS "${OpenMP_CXX_FLAGS}")
|
||||
|
||||
@@ -34,29 +34,16 @@ function(add_static_analysis_tests sources includes)
|
||||
list(APPEND IPATHS -I ${dep})
|
||||
endforeach()
|
||||
foreach(src ${${sources}})
|
||||
if(src MATCHES "TARGET_OBJECTS:")
|
||||
string(REGEX REPLACE "\\$<TARGET_OBJECTS:(.*)>" "\\1" TGT ${src})
|
||||
get_target_property(src ${TGT} SOURCES)
|
||||
endif()
|
||||
if(IS_ABSOLUTE ${src})
|
||||
file(RELATIVE_PATH name ${PROJECT_SOURCE_DIR} ${src})
|
||||
else()
|
||||
set(name ${src})
|
||||
set(src ${PROJECT_SOURCE_DIR}/${src})
|
||||
endif()
|
||||
file(RELATIVE_PATH name ${PROJECT_SOURCE_DIR} ${src})
|
||||
if(CPPCHECK_FOUND)
|
||||
if(NOT TEST cppcheck+${name})
|
||||
add_test(NAME cppcheck+${name}
|
||||
COMMAND bin/cppcheck-test.sh ${CPPCHECK_PROGRAM} ${src} ${IPATHS}
|
||||
CONFIGURATIONS analyze cppcheck)
|
||||
endif()
|
||||
add_test(NAME cppcheck+${name}
|
||||
COMMAND bin/cppcheck-test.sh ${CPPCHECK_PROGRAM} ${src} ${IPATHS}
|
||||
CONFIGURATIONS analyze cppcheck)
|
||||
endif()
|
||||
if(CLANGCHECK_FOUND AND CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
if(NOT TEST clang-check+${name})
|
||||
add_test(NAME clang-check+${name}
|
||||
COMMAND bin/clang-check-test.sh ${CLANGCHECK_PROGRAM} ${src}
|
||||
CONFIGURATIONS analyze clang-check)
|
||||
endif()
|
||||
add_test(NAME clang-check+${name}
|
||||
COMMAND bin/clang-check-test.sh ${CLANGCHECK_PROGRAM} ${src}
|
||||
CONFIGURATIONS analyze clang-check)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
# makes changes to any of the unit tests.
|
||||
|
||||
message("-- Writing version information to local header project-version.h")
|
||||
string (TIMESTAMP build_timestamp "%Y-%m-%d at %H:%M:%S hrs")
|
||||
|
||||
string (TOUPPER "${CMAKE_BUILD_TYPE}" cmake_build_type_upper_)
|
||||
if (cmake_build_type_upper_ MATCHES DEBUG)
|
||||
@@ -26,14 +25,6 @@ if (cmake_build_type_upper_ MATCHES DEBUG)
|
||||
"#define PROJECT_VERSION \"${${project}_LABEL} (debug)\"\n"
|
||||
"#endif // OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
|
||||
)
|
||||
|
||||
# Write header file with build timestamp
|
||||
file (WRITE "${PROJECT_BINARY_DIR}/project-timestamp.h"
|
||||
"#ifndef OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
"#define OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
"#define BUILD_TIMESTAMP \"${build_timestamp}\"\n"
|
||||
"#endif // OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
)
|
||||
else ()
|
||||
if (NOT GIT_FOUND)
|
||||
find_package (Git)
|
||||
@@ -52,13 +43,6 @@ else ()
|
||||
"#define PROJECT_VERSION \"${${project}_LABEL} (unknown git version)\"\n"
|
||||
"#endif // OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
|
||||
)
|
||||
# Write header file with build timestamp
|
||||
file (WRITE "${PROJECT_BINARY_DIR}/project-timestamp.h"
|
||||
"#ifndef OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
"#define OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
"#define BUILD_TIMESTAMP \"${build_timestamp}\"\n"
|
||||
"#endif // OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
)
|
||||
else ()
|
||||
add_custom_target (update-version ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
|
||||
@@ -6,7 +6,7 @@ is_compiler_gcc_compatible ()
|
||||
|
||||
if (CXX_COMPAT_GCC)
|
||||
# default warnings flags, if not set by user
|
||||
set_default_option (CXX _warn_flag "-Wall -Wextra -Wshadow" "(^|\ )-W")
|
||||
set_default_option (CXX _warn_flag "-Wall" "(^|\ )-W")
|
||||
if (_warn_flag)
|
||||
message (STATUS "All warnings enabled: ${_warn_flag}")
|
||||
add_options (ALL_LANGUAGES ALL_BUILDS "${_warn_flag}")
|
||||
|
||||
138
cmake/Modules/compat-2.8.3/CMakeParseArguments.cmake
Normal file
138
cmake/Modules/compat-2.8.3/CMakeParseArguments.cmake
Normal file
@@ -0,0 +1,138 @@
|
||||
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
|
||||
#
|
||||
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
|
||||
# parsing the arguments given to that macro or function.
|
||||
# It processes the arguments and defines a set of variables which hold the
|
||||
# values of the respective options.
|
||||
#
|
||||
# The <options> argument contains all options for the respective macro,
|
||||
# i.e. keywords which can be used when calling the macro without any value
|
||||
# following, like e.g. the OPTIONAL keyword of the install() command.
|
||||
#
|
||||
# The <one_value_keywords> argument contains all keywords for this macro
|
||||
# which are followed by one value, like e.g. DESTINATION keyword of the
|
||||
# install() command.
|
||||
#
|
||||
# The <multi_value_keywords> argument contains all keywords for this macro
|
||||
# which can be followed by more than one value, like e.g. the TARGETS or
|
||||
# FILES keywords of the install() command.
|
||||
#
|
||||
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
|
||||
# keywords listed in <options>, <one_value_keywords> and
|
||||
# <multi_value_keywords> a variable composed of the given <prefix>
|
||||
# followed by "_" and the name of the respective keyword.
|
||||
# These variables will then hold the respective value from the argument list.
|
||||
# For the <options> keywords this will be TRUE or FALSE.
|
||||
#
|
||||
# All remaining arguments are collected in a variable
|
||||
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
|
||||
# your macro was called with unrecognized parameters.
|
||||
#
|
||||
# As an example here a my_install() macro, which takes similar arguments as the
|
||||
# real install() command:
|
||||
#
|
||||
# function(MY_INSTALL)
|
||||
# set(options OPTIONAL FAST)
|
||||
# set(oneValueArgs DESTINATION RENAME)
|
||||
# set(multiValueArgs TARGETS CONFIGURATIONS)
|
||||
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
# ...
|
||||
#
|
||||
# Assume my_install() has been called like this:
|
||||
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
|
||||
#
|
||||
# After the cmake_parse_arguments() call the macro will have set the following
|
||||
# variables:
|
||||
# MY_INSTALL_OPTIONAL = TRUE
|
||||
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
|
||||
# MY_INSTALL_DESTINATION = "bin"
|
||||
# MY_INSTALL_RENAME = "" (was not used)
|
||||
# MY_INSTALL_TARGETS = "foo;bar"
|
||||
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
|
||||
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
|
||||
#
|
||||
# You can the continue and process these variables.
|
||||
#
|
||||
# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
|
||||
# another recognized keyword follows, this is interpreted as the beginning of
|
||||
# the new option.
|
||||
# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
|
||||
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
|
||||
# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
|
||||
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
|
||||
return()
|
||||
endif()
|
||||
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
|
||||
|
||||
|
||||
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
|
||||
# first set all result variables to empty/FALSE
|
||||
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
|
||||
set(${prefix}_${arg_name})
|
||||
endforeach(arg_name)
|
||||
|
||||
foreach(option ${_optionNames})
|
||||
set(${prefix}_${option} FALSE)
|
||||
endforeach(option)
|
||||
|
||||
set(${prefix}_UNPARSED_ARGUMENTS)
|
||||
|
||||
set(insideValues FALSE)
|
||||
set(currentArgName)
|
||||
|
||||
# now iterate over all arguments and fill the result variables
|
||||
foreach(currentArg ${ARGN})
|
||||
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||
|
||||
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
|
||||
if(insideValues)
|
||||
if("${insideValues}" STREQUAL "SINGLE")
|
||||
set(${prefix}_${currentArgName} ${currentArg})
|
||||
set(insideValues FALSE)
|
||||
elseif("${insideValues}" STREQUAL "MULTI")
|
||||
list(APPEND ${prefix}_${currentArgName} ${currentArg})
|
||||
endif()
|
||||
else(insideValues)
|
||||
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
|
||||
endif(insideValues)
|
||||
else()
|
||||
if(NOT ${optionIndex} EQUAL -1)
|
||||
set(${prefix}_${currentArg} TRUE)
|
||||
set(insideValues FALSE)
|
||||
elseif(NOT ${singleArgIndex} EQUAL -1)
|
||||
set(currentArgName ${currentArg})
|
||||
set(${prefix}_${currentArgName})
|
||||
set(insideValues "SINGLE")
|
||||
elseif(NOT ${multiArgIndex} EQUAL -1)
|
||||
set(currentArgName ${currentArg})
|
||||
set(${prefix}_${currentArgName})
|
||||
set(insideValues "MULTI")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endforeach(currentArg)
|
||||
|
||||
# propagate the result variables to the caller:
|
||||
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
|
||||
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
|
||||
endforeach(arg_name)
|
||||
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
|
||||
|
||||
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
|
||||
47
cmake/Modules/compat-2.8.5/FindGit.cmake
Normal file
47
cmake/Modules/compat-2.8.5/FindGit.cmake
Normal file
@@ -0,0 +1,47 @@
|
||||
# The module defines the following variables:
|
||||
# GIT_EXECUTABLE - path to git command line client
|
||||
# GIT_FOUND - true if the command line client was found
|
||||
# Example usage:
|
||||
# find_package(Git)
|
||||
# if(GIT_FOUND)
|
||||
# message("git found: ${GIT_EXECUTABLE}")
|
||||
# endif()
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Look for 'git' or 'eg' (easy git)
|
||||
#
|
||||
set(git_names git eg)
|
||||
|
||||
# Prefer .cmd variants on Windows unless running in a Makefile
|
||||
# in the MSYS shell.
|
||||
#
|
||||
if(WIN32)
|
||||
if(NOT CMAKE_GENERATOR MATCHES "MSYS")
|
||||
set(git_names git.cmd git eg.cmd eg)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(GIT_EXECUTABLE
|
||||
NAMES ${git_names}
|
||||
PATH_SUFFIXES Git/cmd Git/bin
|
||||
DOC "git command line client"
|
||||
)
|
||||
mark_as_advanced(GIT_EXECUTABLE)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set GIT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Git DEFAULT_MSG GIT_EXECUTABLE)
|
||||
61
cmake/Modules/compat-2.8.7/CMakePushCheckState.cmake
Normal file
61
cmake/Modules/compat-2.8.7/CMakePushCheckState.cmake
Normal file
@@ -0,0 +1,61 @@
|
||||
# This module defines two macros:
|
||||
# CMAKE_PUSH_CHECK_STATE()
|
||||
# and
|
||||
# CMAKE_POP_CHECK_STATE()
|
||||
# These two macros can be used to save and restore the state of the variables
|
||||
# CMAKE_REQUIRED_FLAGS, CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_LIBRARIES
|
||||
# and CMAKE_REQUIRED_INCLUDES used by the various Check-files coming with CMake,
|
||||
# like e.g. check_function_exists() etc.
|
||||
# The variable contents are pushed on a stack, pushing multiple times is supported.
|
||||
# This is useful e.g. when executing such tests in a Find-module, where they have to be set,
|
||||
# but after the Find-module has been executed they should have the same value
|
||||
# as they had before.
|
||||
#
|
||||
# Usage:
|
||||
# cmake_push_check_state()
|
||||
# set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DSOME_MORE_DEF)
|
||||
# check_function_exists(...)
|
||||
# cmake_pop_check_state()
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2006-2011 Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
|
||||
MACRO(CMAKE_PUSH_CHECK_STATE)
|
||||
|
||||
IF(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER)
|
||||
SET(_CMAKE_PUSH_CHECK_STATE_COUNTER 0)
|
||||
ENDIF()
|
||||
|
||||
MATH(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1")
|
||||
|
||||
SET(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES})
|
||||
SET(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS})
|
||||
SET(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES})
|
||||
SET(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS})
|
||||
ENDMACRO(CMAKE_PUSH_CHECK_STATE)
|
||||
|
||||
MACRO(CMAKE_POP_CHECK_STATE)
|
||||
|
||||
# don't pop more than we pushed
|
||||
IF("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0")
|
||||
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
|
||||
SET(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
|
||||
SET(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
|
||||
|
||||
MATH(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
|
||||
ENDIF()
|
||||
|
||||
ENDMACRO(CMAKE_POP_CHECK_STATE)
|
||||
624
cmake/Modules/compat-2.8.7/FindBLAS.cmake
Normal file
624
cmake/Modules/compat-2.8.7/FindBLAS.cmake
Normal file
@@ -0,0 +1,624 @@
|
||||
# - Find BLAS library
|
||||
# This module finds an installed fortran library that implements the BLAS
|
||||
# linear-algebra interface (see http://www.netlib.org/blas/).
|
||||
# The list of libraries searched for is taken
|
||||
# from the autoconf macro file, acx_blas.m4 (distributed at
|
||||
# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
|
||||
#
|
||||
# This module sets the following variables:
|
||||
# BLAS_FOUND - set to true if a library implementing the BLAS interface
|
||||
# is found
|
||||
# BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l
|
||||
# and -L).
|
||||
# BLAS_LIBRARIES - uncached list of libraries (using full path name) to
|
||||
# link against to use BLAS
|
||||
# BLAS95_LIBRARIES - uncached list of libraries (using full path name)
|
||||
# to link against to use BLAS95 interface
|
||||
# BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface
|
||||
# is found
|
||||
# BLA_STATIC if set on this determines what kind of linkage we do (static)
|
||||
# BLA_VENDOR if set checks only the specified vendor, if not set checks
|
||||
# all the possibilities
|
||||
# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
|
||||
##########
|
||||
### List of vendors (BLA_VENDOR) valid in this module
|
||||
## Goto,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model),
|
||||
## Intel( older versions of mkl 32 and 64 bit), ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic
|
||||
# C/CXX should be enabled to use Intel mkl
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckFortranFunctionExists)
|
||||
|
||||
set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
|
||||
# Check the language being used
|
||||
get_property( _LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES )
|
||||
if( _LANGUAGES_ MATCHES Fortran )
|
||||
set( _CHECK_FORTRAN TRUE )
|
||||
elseif( (_LANGUAGES_ MATCHES C) OR (_LANGUAGES_ MATCHES CXX) )
|
||||
set( _CHECK_FORTRAN FALSE )
|
||||
else()
|
||||
if(BLAS_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
|
||||
else(BLAS_FIND_REQUIRED)
|
||||
message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)")
|
||||
return()
|
||||
endif(BLAS_FIND_REQUIRED)
|
||||
endif( )
|
||||
|
||||
macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
|
||||
# This macro checks for the existence of the combination of fortran libraries
|
||||
# given by _list. If the combination is found, this macro checks (using the
|
||||
# Check_Fortran_Function_Exists macro) whether can link against that library
|
||||
# combination using the name of a routine given by _name using the linker
|
||||
# flags given by _flags. If the combination of libraries is found and passes
|
||||
# the link test, LIBRARIES is set to the list of complete library paths that
|
||||
# have been found. Otherwise, LIBRARIES is set to FALSE.
|
||||
|
||||
# N.B. _prefix is the prefix applied to the names of all cached variables that
|
||||
# are generated internally and marked advanced by this macro.
|
||||
|
||||
set(_libdir ${ARGN})
|
||||
|
||||
set(_libraries_work TRUE)
|
||||
set(${LIBRARIES})
|
||||
set(_combined_name)
|
||||
if (NOT _libdir)
|
||||
if (WIN32)
|
||||
set(_libdir ENV LIB)
|
||||
elseif (APPLE)
|
||||
set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH)
|
||||
else ()
|
||||
set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH)
|
||||
endif ()
|
||||
endif ()
|
||||
foreach(_library ${_list})
|
||||
set(_combined_name ${_combined_name}_${_library})
|
||||
|
||||
if(_libraries_work)
|
||||
if (BLA_STATIC)
|
||||
if (WIN32)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif ( WIN32 )
|
||||
if (APPLE)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
else (APPLE)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif (APPLE)
|
||||
else (BLA_STATIC)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# for ubuntu's libblas3gf and liblapack3gf packages
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
|
||||
endif ()
|
||||
endif (BLA_STATIC)
|
||||
find_library(${_prefix}_${_library}_LIBRARY
|
||||
NAMES ${_library}
|
||||
PATHS ${_libdir}
|
||||
)
|
||||
mark_as_advanced(${_prefix}_${_library}_LIBRARY)
|
||||
set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
|
||||
set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
|
||||
endif(_libraries_work)
|
||||
endforeach(_library ${_list})
|
||||
if(_libraries_work)
|
||||
# Test this combination of libraries.
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threads})
|
||||
# message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
|
||||
if (_CHECK_FORTRAN)
|
||||
check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
|
||||
else()
|
||||
check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
mark_as_advanced(${_prefix}${_combined_name}_WORKS)
|
||||
set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
|
||||
endif(_libraries_work)
|
||||
if(NOT _libraries_work)
|
||||
set(${LIBRARIES} FALSE)
|
||||
endif(NOT _libraries_work)
|
||||
#message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
|
||||
endmacro(Check_Fortran_Libraries)
|
||||
|
||||
set(BLAS_LINKER_FLAGS)
|
||||
set(BLAS_LIBRARIES)
|
||||
set(BLAS95_LIBRARIES)
|
||||
if ($ENV{BLA_VENDOR} MATCHES ".+")
|
||||
set(BLA_VENDOR $ENV{BLA_VENDOR})
|
||||
else ($ENV{BLA_VENDOR} MATCHES ".+")
|
||||
if(NOT BLA_VENDOR)
|
||||
set(BLA_VENDOR "All")
|
||||
endif(NOT BLA_VENDOR)
|
||||
endif ($ENV{BLA_VENDOR} MATCHES ".+")
|
||||
|
||||
if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
# gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"goto2"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
dgemm
|
||||
""
|
||||
"f77blas;atlas"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
|
||||
if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"sgemm;dgemm;blas"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
# BLAS in Alpha CXML library?
|
||||
if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"cxml"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
# BLAS in Alpha DXML library? (now called CXML, see above)
|
||||
if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"dxml"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
# BLAS in Sun Performance library?
|
||||
if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
"-xlic_lib=sunperf"
|
||||
"sunperf;sunmath"
|
||||
""
|
||||
)
|
||||
if(BLAS_LIBRARIES)
|
||||
set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
|
||||
endif(BLAS_LIBRARIES)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
# BLAS in SCSL library? (SGI/Cray Scientific Library)
|
||||
if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"scsl"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
# BLAS in SGIMATH library?
|
||||
if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"complib.sgimath"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
|
||||
if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"essl;blas"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
#BLAS in acml library?
|
||||
if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All")
|
||||
if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
|
||||
((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
|
||||
((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))
|
||||
)
|
||||
# try to find acml in "standard" paths
|
||||
if( WIN32 )
|
||||
file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" )
|
||||
else()
|
||||
file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" )
|
||||
endif()
|
||||
if( WIN32 )
|
||||
file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" )
|
||||
else()
|
||||
file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" )
|
||||
endif()
|
||||
list(GET _ACML_ROOT 0 _ACML_ROOT)
|
||||
list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
|
||||
if( _ACML_ROOT )
|
||||
get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH )
|
||||
if( SIZEOF_INTEGER EQUAL 8 )
|
||||
set( _ACML_PATH_SUFFIX "_int64" )
|
||||
else()
|
||||
set( _ACML_PATH_SUFFIX "" )
|
||||
endif()
|
||||
if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" )
|
||||
set( _ACML_COMPILER32 "ifort32" )
|
||||
set( _ACML_COMPILER64 "ifort64" )
|
||||
elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" )
|
||||
set( _ACML_COMPILER32 "sun32" )
|
||||
set( _ACML_COMPILER64 "sun64" )
|
||||
elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" )
|
||||
set( _ACML_COMPILER32 "pgi32" )
|
||||
if( WIN32 )
|
||||
set( _ACML_COMPILER64 "win64" )
|
||||
else()
|
||||
set( _ACML_COMPILER64 "pgi64" )
|
||||
endif()
|
||||
elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" )
|
||||
# 32 bit builds not supported on Open64 but for code simplicity
|
||||
# We'll just use the same directory twice
|
||||
set( _ACML_COMPILER32 "open64_64" )
|
||||
set( _ACML_COMPILER64 "open64_64" )
|
||||
elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" )
|
||||
set( _ACML_COMPILER32 "nag32" )
|
||||
set( _ACML_COMPILER64 "nag64" )
|
||||
else() #if( CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" )
|
||||
set( _ACML_COMPILER32 "gfortran32" )
|
||||
set( _ACML_COMPILER64 "gfortran64" )
|
||||
endif()
|
||||
|
||||
if( BLA_VENDOR STREQUAL "ACML_MP" )
|
||||
set(_ACML_MP_LIB_DIRS
|
||||
"${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
|
||||
"${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" )
|
||||
else() #if( _BLAS_VENDOR STREQUAL "ACML" )
|
||||
set(_ACML_LIB_DIRS
|
||||
"${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
|
||||
"${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" )
|
||||
endif()
|
||||
endif()
|
||||
elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
|
||||
set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
|
||||
endif()
|
||||
|
||||
if( BLA_VENDOR STREQUAL "ACML_MP" )
|
||||
foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
|
||||
check_fortran_libraries (
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
"" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS}
|
||||
)
|
||||
if( BLAS_LIBRARIES )
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
elseif( BLA_VENDOR STREQUAL "ACML_GPU" )
|
||||
foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
|
||||
check_fortran_libraries (
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
"" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS}
|
||||
)
|
||||
if( BLAS_LIBRARIES )
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
else() #if( _BLAS_VENDOR STREQUAL "ACML" )
|
||||
foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} )
|
||||
check_fortran_libraries (
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
"" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS}
|
||||
)
|
||||
if( BLAS_LIBRARIES )
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"acml;acml_mv"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"acml_mp;acml_mv"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"acml;acml_mv;CALBLAS"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif () # ACML
|
||||
|
||||
# Apple BLAS library?
|
||||
if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
dgemm
|
||||
""
|
||||
"Accelerate"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
|
||||
if ( NOT BLAS_LIBRARIES )
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
dgemm
|
||||
""
|
||||
"vecLib"
|
||||
""
|
||||
)
|
||||
endif ( NOT BLAS_LIBRARIES )
|
||||
endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
|
||||
# Generic BLAS library?
|
||||
if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"blas"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
#BLAS in intel mkl 10 library? (em64t 64bit)
|
||||
if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
|
||||
if (NOT WIN32)
|
||||
set(LM "-lm")
|
||||
endif ()
|
||||
if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
|
||||
if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
|
||||
find_package(Threads)
|
||||
else(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
endif(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
|
||||
if (WIN32)
|
||||
if(BLA_F95)
|
||||
if(NOT BLAS95_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS95_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl_blas95;mkl_intel_c;mkl_intel_thread;mkl_core;libguide40"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS95_LIBRARIES)
|
||||
else(BLA_F95)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
SGEMM
|
||||
""
|
||||
"mkl_c_dll;mkl_intel_thread_dll;mkl_core_dll;libguide40"
|
||||
""
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif(BLA_F95)
|
||||
else(WIN32)
|
||||
if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
|
||||
if(BLA_F95)
|
||||
if(NOT BLAS95_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS95_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl_blas95;mkl_intel;mkl_intel_thread;mkl_core;guide"
|
||||
"${CMAKE_THREAD_LIBS_INIT};${LM}"
|
||||
)
|
||||
endif(NOT BLAS95_LIBRARIES)
|
||||
else(BLA_F95)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl_intel;mkl_intel_thread;mkl_core;guide"
|
||||
"${CMAKE_THREAD_LIBS_INIT}"
|
||||
"${LM}"
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif(BLA_F95)
|
||||
endif (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
|
||||
if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
|
||||
if(BLA_F95)
|
||||
if(NOT BLAS95_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS95_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl_blas95;mkl_intel_lp64;mkl_intel_thread;mkl_core;guide"
|
||||
"${CMAKE_THREAD_LIBS_INIT};${LM}"
|
||||
)
|
||||
endif(NOT BLAS95_LIBRARIES)
|
||||
else(BLA_F95)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl_intel_lp64;mkl_intel_thread;mkl_core;guide"
|
||||
"${CMAKE_THREAD_LIBS_INIT};${LM}"
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif(BLA_F95)
|
||||
endif (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
|
||||
endif (WIN32)
|
||||
#older vesions of intel mkl libs
|
||||
# BLAS in intel mkl library? (shared)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl;guide"
|
||||
"${CMAKE_THREAD_LIBS_INIT};${LM}"
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
#BLAS in intel mkl library? (static, 32bit)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl_ia32;guide"
|
||||
"${CMAKE_THREAD_LIBS_INIT};${LM}"
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
#BLAS in intel mkl library? (static, em64t 64bit)
|
||||
if(NOT BLAS_LIBRARIES)
|
||||
check_fortran_libraries(
|
||||
BLAS_LIBRARIES
|
||||
BLAS
|
||||
sgemm
|
||||
""
|
||||
"mkl_em64t;guide"
|
||||
"${CMAKE_THREAD_LIBS_INIT};${LM}"
|
||||
)
|
||||
endif(NOT BLAS_LIBRARIES)
|
||||
endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
|
||||
endif (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
|
||||
if(BLA_F95)
|
||||
if(BLAS95_LIBRARIES)
|
||||
set(BLAS95_FOUND TRUE)
|
||||
else(BLAS95_LIBRARIES)
|
||||
set(BLAS95_FOUND FALSE)
|
||||
endif(BLAS95_LIBRARIES)
|
||||
|
||||
if(NOT BLAS_FIND_QUIETLY)
|
||||
if(BLAS95_FOUND)
|
||||
message(STATUS "A library with BLAS95 API found.")
|
||||
else(BLAS95_FOUND)
|
||||
if(BLAS_FIND_REQUIRED)
|
||||
message(FATAL_ERROR
|
||||
"A required library with BLAS95 API not found. Please specify library location.")
|
||||
else(BLAS_FIND_REQUIRED)
|
||||
message(STATUS
|
||||
"A library with BLAS95 API not found. Please specify library location.")
|
||||
endif(BLAS_FIND_REQUIRED)
|
||||
endif(BLAS95_FOUND)
|
||||
endif(NOT BLAS_FIND_QUIETLY)
|
||||
set(BLAS_FOUND TRUE)
|
||||
set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}")
|
||||
else(BLA_F95)
|
||||
if(BLAS_LIBRARIES)
|
||||
set(BLAS_FOUND TRUE)
|
||||
else(BLAS_LIBRARIES)
|
||||
set(BLAS_FOUND FALSE)
|
||||
endif(BLAS_LIBRARIES)
|
||||
|
||||
if(NOT BLAS_FIND_QUIETLY)
|
||||
if(BLAS_FOUND)
|
||||
message(STATUS "A library with BLAS API found.")
|
||||
else(BLAS_FOUND)
|
||||
if(BLAS_FIND_REQUIRED)
|
||||
message(FATAL_ERROR
|
||||
"A required library with BLAS API not found. Please specify library location."
|
||||
)
|
||||
else(BLAS_FIND_REQUIRED)
|
||||
message(STATUS
|
||||
"A library with BLAS API not found. Please specify library location."
|
||||
)
|
||||
endif(BLAS_FIND_REQUIRED)
|
||||
endif(BLAS_FOUND)
|
||||
endif(NOT BLAS_FIND_QUIETLY)
|
||||
endif(BLA_F95)
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
307
cmake/Modules/compat-2.8.7/FindLAPACK.cmake
Normal file
307
cmake/Modules/compat-2.8.7/FindLAPACK.cmake
Normal file
@@ -0,0 +1,307 @@
|
||||
# - Find LAPACK library
|
||||
# This module finds an installed fortran library that implements the LAPACK
|
||||
# linear-algebra interface (see http://www.netlib.org/lapack/).
|
||||
#
|
||||
# The approach follows that taken for the autoconf macro file, acx_lapack.m4
|
||||
# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
|
||||
#
|
||||
# This module sets the following variables:
|
||||
# LAPACK_FOUND - set to true if a library implementing the LAPACK interface
|
||||
# is found
|
||||
# LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l
|
||||
# and -L).
|
||||
# LAPACK_LIBRARIES - uncached list of libraries (using full path name) to
|
||||
# link against to use LAPACK
|
||||
# LAPACK95_LIBRARIES - uncached list of libraries (using full path name) to
|
||||
# link against to use LAPACK95
|
||||
# LAPACK95_FOUND - set to true if a library implementing the LAPACK f95
|
||||
# interface is found
|
||||
# BLA_STATIC if set on this determines what kind of linkage we do (static)
|
||||
# BLA_VENDOR if set checks only the specified vendor, if not set checks
|
||||
# all the possibilities
|
||||
# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
|
||||
### List of vendors (BLA_VENDOR) valid in this module
|
||||
## Intel(mkl), ACML,Apple, NAS, Generic
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
|
||||
get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
if (NOT _LANGUAGES_ MATCHES Fortran)
|
||||
include(CheckFunctionExists)
|
||||
else (NOT _LANGUAGES_ MATCHES Fortran)
|
||||
include(CheckFortranFunctionExists)
|
||||
endif (NOT _LANGUAGES_ MATCHES Fortran)
|
||||
|
||||
set(LAPACK_FOUND FALSE)
|
||||
set(LAPACK95_FOUND FALSE)
|
||||
|
||||
# TODO: move this stuff to separate module
|
||||
|
||||
macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads)
|
||||
# This macro checks for the existence of the combination of fortran libraries
|
||||
# given by _list. If the combination is found, this macro checks (using the
|
||||
# Check_Fortran_Function_Exists macro) whether can link against that library
|
||||
# combination using the name of a routine given by _name using the linker
|
||||
# flags given by _flags. If the combination of libraries is found and passes
|
||||
# the link test, LIBRARIES is set to the list of complete library paths that
|
||||
# have been found. Otherwise, LIBRARIES is set to FALSE.
|
||||
|
||||
# N.B. _prefix is the prefix applied to the names of all cached variables that
|
||||
# are generated internally and marked advanced by this macro.
|
||||
|
||||
set(_libraries_work TRUE)
|
||||
set(${LIBRARIES})
|
||||
set(_combined_name)
|
||||
if (NOT _libdir)
|
||||
if (WIN32)
|
||||
set(_libdir ENV LIB)
|
||||
elseif (APPLE)
|
||||
set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH)
|
||||
else ()
|
||||
set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH)
|
||||
endif ()
|
||||
endif ()
|
||||
foreach(_library ${_list})
|
||||
set(_combined_name ${_combined_name}_${_library})
|
||||
|
||||
if(_libraries_work)
|
||||
if (BLA_STATIC)
|
||||
if (WIN32)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif ( WIN32 )
|
||||
if (APPLE)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
else (APPLE)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif (APPLE)
|
||||
else (BLA_STATIC)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# for ubuntu's libblas3gf and liblapack3gf packages
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
|
||||
endif ()
|
||||
endif (BLA_STATIC)
|
||||
find_library(${_prefix}_${_library}_LIBRARY
|
||||
NAMES ${_library}
|
||||
PATHS ${_libdir}
|
||||
)
|
||||
mark_as_advanced(${_prefix}_${_library}_LIBRARY)
|
||||
set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
|
||||
set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
|
||||
endif(_libraries_work)
|
||||
endforeach(_library ${_list})
|
||||
|
||||
if(_libraries_work)
|
||||
# Test this combination of libraries.
|
||||
if(UNIX AND BLA_STATIC)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads})
|
||||
else(UNIX AND BLA_STATIC)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads})
|
||||
endif(UNIX AND BLA_STATIC)
|
||||
# message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
|
||||
if (NOT _LANGUAGES_ MATCHES Fortran)
|
||||
check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
|
||||
else (NOT _LANGUAGES_ MATCHES Fortran)
|
||||
check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS)
|
||||
endif (NOT _LANGUAGES_ MATCHES Fortran)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
mark_as_advanced(${_prefix}${_combined_name}_WORKS)
|
||||
set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
|
||||
#message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
|
||||
endif(_libraries_work)
|
||||
|
||||
if(_libraries_work)
|
||||
set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads})
|
||||
else(_libraries_work)
|
||||
set(${LIBRARIES} FALSE)
|
||||
endif(_libraries_work)
|
||||
|
||||
endmacro(Check_Lapack_Libraries)
|
||||
|
||||
|
||||
set(LAPACK_LINKER_FLAGS)
|
||||
set(LAPACK_LIBRARIES)
|
||||
set(LAPACK95_LIBRARIES)
|
||||
|
||||
|
||||
if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
|
||||
find_package(BLAS)
|
||||
else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
|
||||
find_package(BLAS REQUIRED)
|
||||
endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
|
||||
|
||||
|
||||
if(BLAS_FOUND)
|
||||
set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
|
||||
if ($ENV{BLA_VENDOR} MATCHES ".+")
|
||||
set(BLA_VENDOR $ENV{BLA_VENDOR})
|
||||
else ($ENV{BLA_VENDOR} MATCHES ".+")
|
||||
if(NOT BLA_VENDOR)
|
||||
set(BLA_VENDOR "All")
|
||||
endif(NOT BLA_VENDOR)
|
||||
endif ($ENV{BLA_VENDOR} MATCHES ".+")
|
||||
|
||||
if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT LAPACK_LIBRARIES)
|
||||
check_lapack_libraries(
|
||||
LAPACK_LIBRARIES
|
||||
LAPACK
|
||||
cheev
|
||||
""
|
||||
"goto2"
|
||||
"${BLAS_LIBRARIES}"
|
||||
""
|
||||
)
|
||||
endif(NOT LAPACK_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
|
||||
|
||||
|
||||
#acml lapack
|
||||
if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All")
|
||||
if (BLAS_LIBRARIES MATCHES ".+acml.+")
|
||||
set (LAPACK_LIBRARIES ${BLAS_LIBRARIES})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Apple LAPACK library?
|
||||
if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
|
||||
if(NOT LAPACK_LIBRARIES)
|
||||
check_lapack_libraries(
|
||||
LAPACK_LIBRARIES
|
||||
LAPACK
|
||||
cheev
|
||||
""
|
||||
"Accelerate"
|
||||
"${BLAS_LIBRARIES}"
|
||||
""
|
||||
)
|
||||
endif(NOT LAPACK_LIBRARIES)
|
||||
endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
|
||||
if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
|
||||
if ( NOT LAPACK_LIBRARIES )
|
||||
check_lapack_libraries(
|
||||
LAPACK_LIBRARIES
|
||||
LAPACK
|
||||
cheev
|
||||
""
|
||||
"vecLib"
|
||||
"${BLAS_LIBRARIES}"
|
||||
""
|
||||
)
|
||||
endif ( NOT LAPACK_LIBRARIES )
|
||||
endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
|
||||
# Generic LAPACK library?
|
||||
if (BLA_VENDOR STREQUAL "Generic" OR
|
||||
BLA_VENDOR STREQUAL "ATLAS" OR
|
||||
BLA_VENDOR STREQUAL "All")
|
||||
if ( NOT LAPACK_LIBRARIES )
|
||||
check_lapack_libraries(
|
||||
LAPACK_LIBRARIES
|
||||
LAPACK
|
||||
cheev
|
||||
""
|
||||
"lapack"
|
||||
"${BLAS_LIBRARIES}"
|
||||
""
|
||||
)
|
||||
endif ( NOT LAPACK_LIBRARIES )
|
||||
endif ()
|
||||
#intel lapack
|
||||
if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
|
||||
if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
|
||||
if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
|
||||
find_PACKAGE(Threads)
|
||||
else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
|
||||
if (BLA_F95)
|
||||
if(NOT LAPACK95_LIBRARIES)
|
||||
check_lapack_libraries(
|
||||
LAPACK95_LIBRARIES
|
||||
LAPACK
|
||||
cheev
|
||||
""
|
||||
"mkl_lapack95"
|
||||
"${BLAS95_LIBRARIES}"
|
||||
"${CMAKE_THREAD_LIBS_INIT}"
|
||||
)
|
||||
endif(NOT LAPACK95_LIBRARIES)
|
||||
else(BLA_F95)
|
||||
if(NOT LAPACK_LIBRARIES)
|
||||
check_lapack_libraries(
|
||||
LAPACK_LIBRARIES
|
||||
LAPACK
|
||||
cheev
|
||||
""
|
||||
"mkl_lapack"
|
||||
"${BLAS_LIBRARIES}"
|
||||
"${CMAKE_THREAD_LIBS_INIT}"
|
||||
)
|
||||
endif(NOT LAPACK_LIBRARIES)
|
||||
endif(BLA_F95)
|
||||
endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
|
||||
endif(BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
|
||||
else(BLAS_FOUND)
|
||||
message(STATUS "LAPACK requires BLAS")
|
||||
endif(BLAS_FOUND)
|
||||
|
||||
if(BLA_F95)
|
||||
if(LAPACK95_LIBRARIES)
|
||||
set(LAPACK95_FOUND TRUE)
|
||||
else(LAPACK95_LIBRARIES)
|
||||
set(LAPACK95_FOUND FALSE)
|
||||
endif(LAPACK95_LIBRARIES)
|
||||
if(NOT LAPACK_FIND_QUIETLY)
|
||||
if(LAPACK95_FOUND)
|
||||
message(STATUS "A library with LAPACK95 API found.")
|
||||
else(LAPACK95_FOUND)
|
||||
if(LAPACK_FIND_REQUIRED)
|
||||
message(FATAL_ERROR
|
||||
"A required library with LAPACK95 API not found. Please specify library location."
|
||||
)
|
||||
else(LAPACK_FIND_REQUIRED)
|
||||
message(STATUS
|
||||
"A library with LAPACK95 API not found. Please specify library location."
|
||||
)
|
||||
endif(LAPACK_FIND_REQUIRED)
|
||||
endif(LAPACK95_FOUND)
|
||||
endif(NOT LAPACK_FIND_QUIETLY)
|
||||
set(LAPACK_FOUND "${LAPACK95_FOUND}")
|
||||
set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}")
|
||||
else(BLA_F95)
|
||||
if(LAPACK_LIBRARIES)
|
||||
set(LAPACK_FOUND TRUE)
|
||||
else(LAPACK_LIBRARIES)
|
||||
set(LAPACK_FOUND FALSE)
|
||||
endif(LAPACK_LIBRARIES)
|
||||
|
||||
if(NOT LAPACK_FIND_QUIETLY)
|
||||
if(LAPACK_FOUND)
|
||||
message(STATUS "A library with LAPACK API found.")
|
||||
else(LAPACK_FOUND)
|
||||
if(LAPACK_FIND_REQUIRED)
|
||||
message(FATAL_ERROR
|
||||
"A required library with LAPACK API not found. Please specify library location."
|
||||
)
|
||||
else(LAPACK_FIND_REQUIRED)
|
||||
message(STATUS
|
||||
"A library with LAPACK API not found. Please specify library location."
|
||||
)
|
||||
endif(LAPACK_FIND_REQUIRED)
|
||||
endif(LAPACK_FOUND)
|
||||
endif(NOT LAPACK_FIND_QUIETLY)
|
||||
endif(BLA_F95)
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
@@ -31,15 +31,30 @@ if(NOT check_target)
|
||||
endif()
|
||||
|
||||
# Build threads
|
||||
include(ProcessorCount)
|
||||
set(build_threads $ENV{CHECK_THREADS})
|
||||
if(NOT build_threads)
|
||||
ProcessorCount(build_threads)
|
||||
if(build_threads EQUAL 0)
|
||||
set(build_threads 1)
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
execute_process(COMMAND sysctl hw.ncpu
|
||||
OUTPUT_VARIABLE build_threads)
|
||||
string(REPLACE " " ";" build_threads_list ${build_threads)
|
||||
list(GET build_threads_list 1 build_threads)
|
||||
else()
|
||||
find_program(NPROC_COMMAND nproc)
|
||||
if(NPROC_COMMAND)
|
||||
execute_process(COMMAND ${NPROC_COMMAND}
|
||||
OUTPUT_VARIABLE build_threads)
|
||||
string(REGEX REPLACE "(\r?\n)+$" "" build_threads "${build_threads}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If for some reason we could not find the info - e.g. centos5 where nproc is missing
|
||||
if(NOT build_threads)
|
||||
set(build_threads 1)
|
||||
endif()
|
||||
|
||||
# Record current HEAD
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
||||
OUTPUT_VARIABLE current_branch
|
||||
|
||||
@@ -47,8 +47,6 @@ if (sha1)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
string (TIMESTAMP build_timestamp "%Y-%m-%d at %H:%M:%S hrs")
|
||||
|
||||
# write the content to a temporary file in a C compatible format
|
||||
file (WRITE "${PROJECT_BINARY_DIR}/project-version.tmp"
|
||||
"#ifndef OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
|
||||
@@ -65,11 +63,3 @@ file (WRITE "${PROJECT_BINARY_DIR}/project-version.tmp"
|
||||
execute_process (COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different "${PROJECT_BINARY_DIR}/project-version.tmp" "${PROJECT_BINARY_DIR}/project-version.h"
|
||||
)
|
||||
|
||||
# Write header file with build timestamp
|
||||
file (WRITE "${PROJECT_BINARY_DIR}/project-timestamp.h"
|
||||
"#ifndef OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
"#define OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
"#define BUILD_TIMESTAMP \"${build_timestamp}\"\n"
|
||||
"#endif // OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n"
|
||||
)
|
||||
|
||||
@@ -30,11 +30,6 @@ if(NOT @opm-project_NAME@_FOUND)
|
||||
set (@opm-project_NAME@_LINKER_FLAGS "@opm-project_LINKER_FLAGS@")
|
||||
set (@opm-project_NAME@_CONFIG_VARS "@opm-project_CONFIG_VARS@")
|
||||
|
||||
# The flag whether embedded Python is supported or not is passed to downstream modules,
|
||||
# it is only used to enable/disable regression testing with Python enabled input. The
|
||||
# actual code is self contained - and can be used downstream without awareness of this.
|
||||
set (@opm-project_NAME@_EMBEDDED_PYTHON @OPM_ENABLE_EMBEDDED_PYTHON@)
|
||||
|
||||
# libraries come from the build tree where this file was generated
|
||||
set (@opm-project_NAME@_LIBRARY "@opm-project_LIBRARY@")
|
||||
set (@opm-project_NAME@_LIBRARIES ${@opm-project_NAME@_LIBRARY} "@opm-project_LIBRARIES@")
|
||||
@@ -74,6 +69,12 @@ if(NOT @opm-project_NAME@_FOUND)
|
||||
endif()
|
||||
endif (NOT "@opm-project_TARGET@" STREQUAL "")
|
||||
|
||||
# ensure that we build with support for C++11 to preserve ABI
|
||||
string (REPLACE "@CXX_STD0X_FLAGS@" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string (REPLACE "@CXX_STDLIB_FLAGS@" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string (STRIP "${CMAKE_CXX_FLAGS}" CMAKE_CXX_FLAGS)
|
||||
set (CMAKE_CXX_FLAGS "@CXX_STD0X_FLAGS@@CXX_SPACE@@CXX_STDLIB_FLAGS@ ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# same as above, but for C99
|
||||
string (REPLACE "@C_STD99_FLAGS@" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string (STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS)
|
||||
|
||||
2
debian/changelog
vendored
2
debian/changelog
vendored
@@ -1,4 +1,4 @@
|
||||
opm-common (2021.04-rfinal-1~bionic) bionic; urgency=medium
|
||||
opm-common (2018.10-rc1-1~xenial) xenial; urgency=medium
|
||||
|
||||
* New release
|
||||
|
||||
|
||||
28
debian/control
vendored
28
debian/control
vendored
@@ -2,12 +2,11 @@ Source: opm-common
|
||||
Priority: extra
|
||||
Maintainer: Arne Morten Kvarving <arne.morten.kvarving@sintef.no>
|
||||
Build-Depends: build-essential, debhelper (>= 9),
|
||||
pkg-config, cmake, git, libtool, doxygen, graphviz,
|
||||
pkg-config, cmake, git, libtool, doxygen,
|
||||
texlive-latex-extra, texlive-latex-recommended,
|
||||
ghostscript, libboost-system-dev, libboost-test-dev,
|
||||
zlib1g-dev, libpython3-dev, python3-numpy, python3-distutils,
|
||||
python3-setuptools, python3-setuptools-scm, python3-pytest-runner,
|
||||
python3-decorator
|
||||
libecl-dev, libboost-regex-dev, libboost-filesystem-dev,
|
||||
zlib1g-dev
|
||||
Standards-Version: 3.9.2
|
||||
Section: libs
|
||||
Homepage: http://opm-project.org
|
||||
@@ -16,7 +15,7 @@ Vcs-Browser: https://github.com/OPM/opm-common
|
||||
|
||||
Package: libopm-common1
|
||||
Section: libs
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Pre-Depends: ${misc:Pre-Depends}, multiarch-support
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
@@ -24,16 +23,6 @@ Provides: libopm-common
|
||||
Description: OPM common library
|
||||
The OPM common library contains generic code shared across all OPM modules.
|
||||
|
||||
Package: libopm-common1-bin
|
||||
Section: libs
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Provides: libopm-common-bin
|
||||
Description: OPM common binaries
|
||||
The OPM common binaries.
|
||||
|
||||
Package: libopm-common1-dev
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
@@ -53,12 +42,3 @@ Provides: libopm-common-doc
|
||||
Description: OPM common library -- documentation
|
||||
The OPM common library contains the shared buildsystem
|
||||
and helpers shared across all OPM modules.
|
||||
|
||||
Package: python3-opm-common
|
||||
Section: libs
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libopm-common1, python3-numpy, python3-decorator
|
||||
Description: OPM common python bindings
|
||||
Python package for opm-common
|
||||
|
||||
1
debian/libopm-common1-bin.install
vendored
1
debian/libopm-common1-bin.install
vendored
@@ -1 +0,0 @@
|
||||
usr/bin/*
|
||||
1
debian/python3-opm-common.install
vendored
1
debian/python3-opm-common.install
vendored
@@ -1 +0,0 @@
|
||||
usr/lib/python*/*
|
||||
4
debian/rules
vendored
4
debian/rules
vendored
@@ -10,7 +10,7 @@
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
%:
|
||||
dh $@ --parallel
|
||||
dh $@
|
||||
|
||||
override_dh_auto_clean:
|
||||
dh_auto_clean --buildsystem=cmake
|
||||
@@ -20,7 +20,7 @@ override_dh_auto_build:
|
||||
|
||||
# consider using -DUSE_VERSIONED_DIR=ON if backporting
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSTRIP_DEBUGGING_SYMBOLS=ON -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_DOCDIR=share/doc/libopm-common1 -DWHOLE_PROG_OPTIM=ON -DUSE_RUNPATH=OFF -DWITH_NATIVE=OFF -DOPM_ENABLE_PYTHON=1 -DOPM_INSTALL_PYTHON=1 -DPYTHON_EXECUTABLE=/usr/bin/python3 -DOPM_ENABLE_EMBEDDED_PYTHON=1
|
||||
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSTRIP_DEBUGGING_SYMBOLS=ON -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_DOCDIR=share/doc/libopm-common1 -DWHOLE_PROG_OPTIM=ON -DUSE_RUNPATH=OFF -DWITH_NATIVE=OFF
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install -- install-html
|
||||
|
||||
@@ -184,8 +184,8 @@ the WCONHIST keyword has the the following items specification:
|
||||
{"name" : "ORAT" , "value_type" : "DOUBLE", "default" : 0.0, "dimension" : "LiquidSurfaceVolume/Time"},
|
||||
{"name" : "WRAT" , "value_type" : "DOUBLE" , "default" : 0.0, "dimension" : "LiquidSurfaceVolume/Time"},
|
||||
{"name" : "GRAT" , "value_type" : "DOUBLE" , "default" : 0.0, "dimension" : "GasSurfaceVolume/Time"},
|
||||
{"name" : "VFP_TABLE" , "value_type" : "INT" , "default" : 0.0 , "comment":"The default is a state variable"},
|
||||
{"name" : "LIFT" , "value_type" : "DOUBLE" , "default" : 0.0 , "comment":"The default is a state variable"},
|
||||
{"name" : "VFPTable" , "value_type" : "INT" , "default" : 0.0 , "comment":"The default is a state variable"},
|
||||
{"name" : "Lift" , "value_type" : "DOUBLE" , "default" : 0.0 , "comment":"The default is a state variable"},
|
||||
{"name" : "THP" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Pressure"},
|
||||
{"name" : "BHP" , "value_type" : "DOUBLE" , "default" : 0.0 ,"dimension" : "Pressure"},
|
||||
{"name" : "NGLRAT" , "value_type" : "DOUBLE" , "default" : 0.0 ,"dimension" : "LiquidSurfaceVolume/Time"}]}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.8.
|
||||
.TH COMPAREECL "1" "April 2021" "compareECL 2020.04" "User Commands"
|
||||
.SH NAME
|
||||
compareECL \- Comparator for Eclipse files
|
||||
.SH DESCRIPTION
|
||||
compareECL compares ECLIPSE files (restart (.RST), unified restart (.UNRST), initial (.INIT), summary (.SMRY), unified summary (.UNSMRY) or .RFT) and gridsizes (from .EGRID or .GRID file) from two simulations.
|
||||
The program takes four arguments:
|
||||
.PP
|
||||
1. Case number 1, reference case (full path without extension)
|
||||
2. Case number 2, test case (full path without extension)
|
||||
3. Absolute tolerance
|
||||
4. Relative tolerance (between 0 and 1)
|
||||
.PP
|
||||
In addition, the program takes these options (which must be given before the arguments):
|
||||
.PP
|
||||
\fB\-a\fR Run a full analysis of errors.
|
||||
\fB\-h\fR Print help and exit.
|
||||
\fB\-d\fR Use report steps only when comparing results from summary files.
|
||||
\fB\-i\fR Execute integration test (regression test is default).
|
||||
.IP
|
||||
The integration test compares SGAS, SWAT and PRESSURE in unified restart files, and WOPR, WGPR, WWPR and WBHP (all wells) in summary file.
|
||||
.PP
|
||||
\fB\-k\fR Specify specific keyword to compare (capitalized), for examples \fB\-k\fR PRESSURE or \fB\-k\fR WOPR:A\-1H
|
||||
\fB\-l\fR Only do comparison for the last Report Step. This option is only valid for restart files.
|
||||
\fB\-n\fR Do not throw on errors.
|
||||
\fB\-p\fR Print keywords in both cases and exit.
|
||||
\fB\-r\fR compare a spesific report time step number in a restart file.
|
||||
\fB\-t\fR Specify ECLIPSE filetype to compare, (default behaviour is that all files are compared if found). Different possible arguments are:
|
||||
.TP
|
||||
\fB\-t\fR UNRST
|
||||
Compare two unified restart files (.UNRST). This the default value, so it is the same as not passing option \fB\-t\fR.
|
||||
.TP
|
||||
\fB\-t\fR EGRID
|
||||
Compare two EGrid files (.EGRID).
|
||||
.TP
|
||||
\fB\-t\fR INIT
|
||||
Compare two initial files (.INIT).
|
||||
.TP
|
||||
\fB\-t\fR RFT
|
||||
Compare two RFT files (.RFT).
|
||||
.TP
|
||||
\fB\-t\fR SMRY
|
||||
Compare two cases consistent of (unified) summary files.
|
||||
.PP
|
||||
\fB\-x\fR Allow extra keywords in case number 2. These additional keywords (not found in case number1) will be ignored in the comparison.
|
||||
.PP
|
||||
Example usage of the program:
|
||||
.PP
|
||||
compareECL \fB\-k\fR PRESSURE <path to first casefile> <path to second casefile> 1e\-3 1e\-5
|
||||
compareECL \fB\-t\fR INIT \fB\-k\fR PORO <path to first casefile> <path to second casefile> 1e\-3 1e\-5
|
||||
compareECL \fB\-i\fR <path to first casefile> <path to second casefile> 0.01 1e\-6
|
||||
.PP
|
||||
Exceptions are thrown (and hence program exits) when deviations are larger than the specified tolerances, or when the number of cells does not match \fB\-\-\fR either in the grid file or for a specific keyword. Information about the keyword, keyword occurrence (zero based) and cell coordinate is printed when an exception is thrown. For more information about how the cases are compared, see the documentation of the EclFilesComparator class.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B compareECL
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B compareECL
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info compareECL
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
@@ -1,24 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.8.
|
||||
.TH CONVERTECL "1" "April 2021" "convertECL 2020.04" "User Commands"
|
||||
.SH NAME
|
||||
convertECL \- Converter for Eclipse files (binary <-> formatted format)
|
||||
.SH DESCRIPTION
|
||||
convertECL needs one argument which is the input file to be converted. If this is a binary file the output file will be formatted. If the input file is formatted the output will be binary.
|
||||
.PP
|
||||
In addition, the program takes these options (which must be given before the arguments):
|
||||
.PP
|
||||
\fB\-h\fR Print help and exit.
|
||||
\fB\-l\fR list report step numbers in the selected restart file.
|
||||
\fB\-r\fR extract and convert a spesific report time step number from a unified restart file.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B convertECL
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B convertECL
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info convertECL
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
@@ -1,54 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.8.
|
||||
.TH OPMHASH "1" "April 2021" "opmhash 2020.04" "User Commands"
|
||||
.SH NAME
|
||||
opmhash \- Hasher for summary keywords in Eclipse files
|
||||
.SH DESCRIPTION
|
||||
opmhash: invalid option \fB\-\-\fR 'h'
|
||||
The purpose of the opmhash program is to load a deck and create a summary, by
|
||||
diffing two such summaries it is simple to determine if two decks are similar.
|
||||
For each keyword a hash of the normalized content is calculated. The output of
|
||||
the program will look like this:
|
||||
.TP
|
||||
RUNSPEC
|
||||
: 13167205945009276792
|
||||
.TP
|
||||
TITLE
|
||||
: 16047371705964514902
|
||||
.TP
|
||||
DIMENS
|
||||
: 1264233216877515756
|
||||
.TP
|
||||
NONNC
|
||||
: 10052807539267647959
|
||||
.TP
|
||||
OIL
|
||||
: 6013609912232720008
|
||||
.TP
|
||||
WATER
|
||||
: 14106203893673265964
|
||||
.TP
|
||||
Total
|
||||
: 7362809723723482303
|
||||
.PP
|
||||
Where the 'random' integer following each keyword is the hash of the content of
|
||||
that keyword. The hashing is insensitive to changes in white\-space and comments
|
||||
and file location. At the bottom comes a total hash of the complete content. The
|
||||
hash of each keyword is insensitive to shuffling of keywords, but the total hash
|
||||
depends on the keyword order.
|
||||
.SH OPTIONS
|
||||
.HP
|
||||
\fB\-l\fR : Add filename and linenumber information to each keyword.
|
||||
.HP
|
||||
\fB\-s\fR : Short form \- only print the hash of the complete deck.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B opmhash
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B opmhash
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info opmhash
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
@@ -1,42 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.8.
|
||||
.TH OPMPACK "1" "April 2021" "opmpack 2020.04" "User Commands"
|
||||
.SH NAME
|
||||
opmpack \- Validator and printer of deck in Eclipse files without comments
|
||||
.SH DESCRIPTION
|
||||
opmpack: invalid option \fB\-\-\fR 'h'
|
||||
.PP
|
||||
The opmpack program will load a deck, resolve all include
|
||||
files and then print it out again on stdout. All comments
|
||||
will be stripped and the value types will be validated.
|
||||
.PP
|
||||
By passing the option \fB\-o\fR you can redirect the output to a file
|
||||
or a directory.
|
||||
.PP
|
||||
Print on stdout:
|
||||
.TP
|
||||
opmpack
|
||||
\fI\,/path/to/case/CASE.DATA\/\fP
|
||||
.PP
|
||||
Print MY_CASE.DATA in /tmp:
|
||||
.IP
|
||||
opmpack \fB\-o\fR \fI\,/tmp\/\fP /path/to/MY_CASE.DATA
|
||||
.PP
|
||||
Print NEW_CASE in cwd:
|
||||
.IP
|
||||
opmpack \fB\-o\fR NEW_CASE.DATA path/to/MY_CASE.DATA
|
||||
.PP
|
||||
As an alternative to the \fB\-o\fR option you can use \fB\-c\fR; that is equivalent to \fB\-o\fR \-
|
||||
but restart and import files referred to in the deck are also copied. The \fB\-o\fR and
|
||||
\fB\-c\fR options are mutually exclusive.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B opmpack
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B opmpack
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info opmpack
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
@@ -1,24 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.8.
|
||||
.TH SUMMARY "1" "April 2021" "summary 2020.04" "User Commands"
|
||||
.SH NAME
|
||||
summary \- Printer for summary keys in Eclipse summary files
|
||||
.SH DESCRIPTION
|
||||
summary needs a minimum of two arguments. First is smspec filename and then list of vectors
|
||||
.PP
|
||||
In addition, the program takes these options (which must be given before the arguments):
|
||||
.PP
|
||||
\fB\-h\fR Print help and exit.
|
||||
\fB\-l\fR list all summary vectors.
|
||||
\fB\-r\fR extract data only for report steps.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B summary
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B summary
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info summary
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
Module: opm-common
|
||||
Description: Open Porous Media Initiative shared infrastructure
|
||||
Version: 2021.04
|
||||
Label: 2021.04
|
||||
Version: 2018.10-rc1
|
||||
Label: 2018.10-rc1
|
||||
Maintainer: opm@opm-project.org
|
||||
MaintainerName: OPM community
|
||||
Url: http://opm-project.org
|
||||
|
||||
@@ -11,7 +11,7 @@ _ewoms_parameter_completor()
|
||||
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
fullcmd="$(which "$cmd" 2> /dev/null)"
|
||||
fullcmd="$(which "$cmd")"
|
||||
ALL_OPTS=$("$fullcmd" --help 2> /dev/null | grep '^ *--' | sed 's/ *\(--[a-zA-Z0-9\-]*\)=.*/\1=/')
|
||||
ALL_OPTS=$(echo "$ALL_OPTS" | sed 's/^ *--help.*/--help/')
|
||||
COMPREPLY=( $(compgen -A file -W "$ALL_OPTS" -- "${cur}") )
|
||||
@@ -32,7 +32,7 @@ _ewoms_generic_parameter_completor()
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
fullcmd="$(which "$cmd" 2> /dev/null)"
|
||||
fullcmd="$(which "$cmd")"
|
||||
if test -z "$fullcmd" || \
|
||||
! test -x "$fullcmd" || \
|
||||
(! test -f "$fullcmd" && ! test -h "$fullcmd" ) || \
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Equinor 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include <opm/io/eclipse/ESmry.hpp>
|
||||
#include <opm/io/eclipse/EclUtil.hpp>
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
|
||||
|
||||
static void printHelp() {
|
||||
|
||||
std::cout << "\nThis program create one or more lodsmry files, designed for effective load on the demand. \n"
|
||||
<< "These files are created with input from the smspec and unsmry file. \n"
|
||||
<< "\nIn addition, the program takes these options (which must be given before the arguments):\n\n"
|
||||
<< "-f if LODSMRY file exist, this will be replaced. Default behaviour is that existing file is kept.\n"
|
||||
<< "-n Maximum number of threads to be used if mulitple files should be created.\n"
|
||||
<< "-h Print help and exit.\n\n";
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int c = 0;
|
||||
int max_threads [[maybe_unused]] = -1;
|
||||
bool force = false;
|
||||
|
||||
while ((c = getopt(argc, argv, "fn:h")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
force = true;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
case 'n':
|
||||
max_threads = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int argOffset = optind;
|
||||
|
||||
#ifdef _OPENMP
|
||||
int available_threads = omp_get_max_threads();
|
||||
|
||||
if (max_threads < 0)
|
||||
max_threads = available_threads-2;
|
||||
else if (max_threads > (available_threads - 1))
|
||||
max_threads = available_threads-1;
|
||||
|
||||
if (max_threads > (argc-argOffset))
|
||||
max_threads = argc-argOffset;
|
||||
|
||||
omp_set_num_threads(max_threads);
|
||||
#endif
|
||||
|
||||
auto lap0 = std::chrono::system_clock::now();
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int f = argOffset; f < argc; f ++){
|
||||
Opm::filesystem::path inputFileName = argv[f];
|
||||
|
||||
Opm::filesystem::path lodFileName = inputFileName.parent_path() / inputFileName.stem();
|
||||
lodFileName = lodFileName += ".LODSMRY";
|
||||
|
||||
if (Opm::EclIO::fileExists(lodFileName) && (force))
|
||||
remove (lodFileName);
|
||||
|
||||
Opm::EclIO::ESmry smryFile(argv[f]);
|
||||
if (!smryFile.make_lodsmry_file()){
|
||||
std::cout << "\n! Warning, smspec already have one lod file, existing kept use option -f to replace this" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
auto lap1 = std::chrono::system_clock::now();
|
||||
std::chrono::duration<double> elapsed_seconds1 = lap1-lap0;
|
||||
std::cout << "\nruntime for creating " << (argc-argOffset) << " LODSMRY files: " << elapsed_seconds1.count() << " seconds\n" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/output/eclipse/EclipseIO.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Python/Python.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
|
||||
#include <opm/msim/msim.hpp>
|
||||
|
||||
|
||||
int main(int /* argc */, char** argv) {
|
||||
std::string deck_file = argv[1];
|
||||
Opm::Parser parser;
|
||||
Opm::ParseContext parse_context;
|
||||
Opm::ErrorGuard error_guard;
|
||||
auto python = std::make_shared<Opm::Python>();
|
||||
|
||||
Opm::OpmLog::setupSimpleDefaultLogging();
|
||||
Opm::Deck deck = parser.parseFile(deck_file, parse_context, error_guard);
|
||||
Opm::EclipseState state(deck);
|
||||
Opm::Schedule schedule(deck, state, parse_context, error_guard, python);
|
||||
Opm::SummaryConfig summary_config(deck, schedule, state.fieldProps(), state.aquifer(),
|
||||
parse_context, error_guard);
|
||||
|
||||
if (error_guard) {
|
||||
error_guard.dump();
|
||||
error_guard.terminate();
|
||||
}
|
||||
|
||||
Opm::msim msim(state);
|
||||
Opm::EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
|
||||
msim.run(schedule, io, false);
|
||||
}
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Equinor 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
|
||||
struct keyword {
|
||||
keyword(const std::string& name_arg, const std::string& filename_arg,
|
||||
std::size_t line_number_arg, std::size_t content_hash_arg) :
|
||||
name(name_arg),
|
||||
filename(filename_arg),
|
||||
line_number(line_number_arg),
|
||||
content_hash(content_hash_arg)
|
||||
{}
|
||||
|
||||
|
||||
std::string name;
|
||||
std::string filename;
|
||||
std::size_t line_number;
|
||||
std::size_t content_hash;
|
||||
};
|
||||
|
||||
|
||||
std::vector<keyword> load_deck(const char * deck_file) {
|
||||
Opm::ParseContext parseContext;
|
||||
Opm::ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
std::vector<keyword> keywords;
|
||||
|
||||
/* Use the same default ParseContext as flow. */
|
||||
parseContext.update(Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputError::IGNORE);
|
||||
parseContext.update(Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputError::WARN);
|
||||
parseContext.update(Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputError::WARN);
|
||||
parseContext.update(Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputError::WARN);
|
||||
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
for (const auto& kw : deck) {
|
||||
std::stringstream ss;
|
||||
const auto& location = kw.location();
|
||||
ss << kw;
|
||||
|
||||
keywords.emplace_back(kw.name(), location.filename, location.lineno, std::hash<std::string>{}(ss.str()));
|
||||
}
|
||||
return keywords;
|
||||
}
|
||||
|
||||
|
||||
std::size_t deck_hash(const std::vector<keyword>& keywords) {
|
||||
std::stringstream ss;
|
||||
for (const auto& kw : keywords)
|
||||
ss << kw.content_hash;
|
||||
|
||||
return std::hash<std::string>{}(ss.str());
|
||||
}
|
||||
|
||||
|
||||
void print_keywords(const std::vector<keyword>& keywords, bool location_info) {
|
||||
for (const auto& kw : keywords) {
|
||||
if (location_info)
|
||||
fmt::print("{:8s} : {}:{} {} \n", kw.name, kw.filename, kw.line_number, kw.content_hash);
|
||||
else
|
||||
fmt::print("{:8s} : {} \n", kw.name, kw.content_hash);
|
||||
}
|
||||
fmt::print("\n{:8s} : {}\n", "Total", deck_hash(keywords));
|
||||
}
|
||||
|
||||
|
||||
void print_help_and_exit() {
|
||||
const char * help_text = R"(The purpose of the opmhash program is to load a deck and create a summary, by
|
||||
diffing two such summaries it is simple to determine if two decks are similar.
|
||||
For each keyword a hash of the normalized content is calculated. The output of
|
||||
the program will look like this:
|
||||
|
||||
RUNSPEC : 13167205945009276792
|
||||
TITLE : 16047371705964514902
|
||||
DIMENS : 1264233216877515756
|
||||
NONNC : 10052807539267647959
|
||||
OIL : 6013609912232720008
|
||||
WATER : 14106203893673265964
|
||||
|
||||
Total : 7362809723723482303
|
||||
|
||||
Where the 'random' integer following each keyword is the hash of the content of
|
||||
that keyword. The hashing is insensitive to changes in white-space and comments
|
||||
and file location. At the bottom comes a total hash of the complete content. The
|
||||
hash of each keyword is insensitive to shuffling of keywords, but the total hash
|
||||
depends on the keyword order.
|
||||
|
||||
Options:
|
||||
|
||||
-l : Add filename and linenumber information to each keyword.
|
||||
-s : Short form - only print the hash of the complete deck.
|
||||
|
||||
)";
|
||||
std::cerr << help_text << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int arg_offset = 1;
|
||||
bool location_info = false;
|
||||
bool short_form = false;
|
||||
|
||||
while (true) {
|
||||
int c;
|
||||
c = getopt(argc, argv, "ls");
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch(c) {
|
||||
case 'l':
|
||||
location_info = true;
|
||||
break;
|
||||
case 's':
|
||||
short_form = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
arg_offset = optind;
|
||||
if (arg_offset >= argc)
|
||||
print_help_and_exit();
|
||||
|
||||
auto keywords = load_deck(argv[arg_offset]);
|
||||
if (short_form)
|
||||
std::cout << deck_hash(keywords) << std::endl;
|
||||
else
|
||||
print_keywords(keywords, location_info);
|
||||
}
|
||||
|
||||
@@ -18,74 +18,32 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/Python/Python.hpp>
|
||||
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
#include <opm/common/OpmLog/StreamLog.hpp>
|
||||
#include <opm/common/OpmLog/LogUtil.hpp>
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
|
||||
|
||||
void initLogging() {
|
||||
std::shared_ptr<Opm::StreamLog> cout_log = std::make_shared<Opm::StreamLog>(std::cout, Opm::Log::DefaultMessageTypes);
|
||||
Opm::OpmLog::addBackend( "COUT" , cout_log);
|
||||
}
|
||||
|
||||
inline void loadDeck( const char * deck_file) {
|
||||
Opm::ParseContext parseContext;
|
||||
Opm::ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
auto python = std::make_shared<Opm::Python>();
|
||||
|
||||
std::cout << "Loading deck: " << deck_file << " ..... "; std::cout.flush();
|
||||
|
||||
Opm::time_point start;
|
||||
|
||||
start = Opm::TimeService::now();
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
auto deck_time = Opm::TimeService::now() - start;
|
||||
|
||||
auto deck = parser.parseFile(deck_file, parseContext);
|
||||
std::cout << "parse complete - creating EclipseState .... "; std::cout.flush();
|
||||
Opm::EclipseState state( deck, parseContext );
|
||||
Opm::Schedule schedule( deck, state.getInputGrid(), state.get3DProperties(), state.runspec().phases(), parseContext);
|
||||
Opm::SummaryConfig summary( deck, schedule, state.getTableManager( ), parseContext );
|
||||
std::cout << "complete." << std::endl;
|
||||
|
||||
start = Opm::TimeService::now();
|
||||
Opm::EclipseState state( deck );
|
||||
auto state_time = Opm::TimeService::now() - start;
|
||||
|
||||
std::cout << "creating Schedule .... "; std::cout.flush();
|
||||
|
||||
start = Opm::TimeService::now();
|
||||
Opm::Schedule schedule( deck, state, python);
|
||||
auto schedule_time = Opm::TimeService::now() - start;
|
||||
|
||||
std::cout << "creating SummaryConfig .... "; std::cout.flush();
|
||||
|
||||
start = Opm::TimeService::now();
|
||||
Opm::SummaryConfig summary( deck, schedule, state.fieldProps(), state.aquifer(),
|
||||
parseContext, errors );
|
||||
auto summary_time = Opm::TimeService::now() - start;
|
||||
|
||||
std::cout << "complete." << std::endl << std::endl;
|
||||
std::cout << "Time: " << std::endl;
|
||||
std::cout << " deck.....: " << std::chrono::duration<double>(deck_time).count() << " seconds" << std::endl;
|
||||
std::cout << " state....: " << std::chrono::duration<double>(state_time).count() << " seconds" << std::endl;
|
||||
std::cout << " schedule.: " << std::chrono::duration<double>(schedule_time).count() << " seconds" << std::endl;
|
||||
std::cout << " summary..: " << std::chrono::duration<double>(summary_time).count() << " seconds" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
initLogging();
|
||||
for (int iarg = 1; iarg < argc; iarg++)
|
||||
loadDeck( argv[iarg] );
|
||||
}
|
||||
|
||||
@@ -17,31 +17,23 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <getopt.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/I.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/P.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/G.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
|
||||
namespace fs = Opm::filesystem;
|
||||
|
||||
Opm::Deck pack_deck( const char * deck_file, std::ostream& os) {
|
||||
inline void pack_deck( const char * deck_file, std::ostream& os) {
|
||||
Opm::ParseContext parseContext(Opm::InputError::WARN);
|
||||
Opm::ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
auto deck = parser.parseFile(deck_file, parseContext);
|
||||
os << deck;
|
||||
|
||||
return deck;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,46 +60,21 @@ Print NEW_CASE in cwd:
|
||||
|
||||
opmpack -o NEW_CASE.DATA path/to/MY_CASE.DATA
|
||||
|
||||
As an alternative to the -o option you can use -c; that is equivalent to -o -
|
||||
but restart and import files referred to in the deck are also copied. The -o and
|
||||
-c options are mutually exclusive. )";
|
||||
|
||||
)";
|
||||
std::cerr << help_text << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void copy_file(const fs::path& source_dir, fs::path fname, const fs::path& target_dir) {
|
||||
if (fname.is_absolute()) {
|
||||
// change when moving to gcc8+
|
||||
// fname = fs::relative(fname, source_dir);
|
||||
auto prefix_len = fs::canonical(source_dir).string().size();
|
||||
fname = fs::canonical(fname);
|
||||
fname = fs::path( fname.string().substr(prefix_len + 1) );
|
||||
}
|
||||
|
||||
auto source_file = source_dir / fname;
|
||||
auto target_file = target_dir / fname;
|
||||
{
|
||||
const auto& parent_path = target_file.parent_path();
|
||||
if (!parent_path.empty() && !fs::is_directory(parent_path))
|
||||
fs::create_directories(parent_path);
|
||||
}
|
||||
|
||||
fs::copy_file(source_file, target_file, fs::copy_options::overwrite_existing);
|
||||
std::cerr << "Copying file " << source_file.string() << " -> " << target_file.string() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int arg_offset = 1;
|
||||
bool stdout_output = true;
|
||||
bool copy_binary = false;
|
||||
const char * coutput_arg;
|
||||
|
||||
while (true) {
|
||||
int c;
|
||||
c = getopt(argc, argv, "c:o:");
|
||||
c = getopt(argc, argv, "o:");
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
@@ -116,11 +83,6 @@ int main(int argc, char** argv) {
|
||||
stdout_output = false;
|
||||
coutput_arg = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
stdout_output = false;
|
||||
copy_binary = true;
|
||||
coutput_arg = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
arg_offset = optind;
|
||||
@@ -131,51 +93,16 @@ int main(int argc, char** argv) {
|
||||
pack_deck(argv[arg_offset], std::cout);
|
||||
else {
|
||||
std::ofstream os;
|
||||
fs::path input_arg(argv[arg_offset]);
|
||||
fs::path output_arg(coutput_arg);
|
||||
fs::path output_dir(coutput_arg);
|
||||
|
||||
if (fs::is_directory(output_arg)) {
|
||||
fs::path output_path = output_arg / input_arg.filename();
|
||||
using path = boost::filesystem::path;
|
||||
path input_arg(argv[arg_offset]);
|
||||
path output_arg(coutput_arg);
|
||||
if (boost::filesystem::is_directory(output_arg)) {
|
||||
path output_path = output_arg / input_arg.filename();
|
||||
os.open(output_path.string());
|
||||
} else {
|
||||
} else
|
||||
os.open(output_arg.string());
|
||||
output_dir = output_arg.parent_path();
|
||||
}
|
||||
|
||||
|
||||
const auto& deck = pack_deck(argv[arg_offset], os);
|
||||
if (copy_binary) {
|
||||
Opm::InitConfig init_config(deck);
|
||||
if (init_config.restartRequested()) {
|
||||
Opm::IOConfig io_config(deck);
|
||||
fs::path restart_file(io_config.getRestartFileName( init_config.getRestartRootName(), init_config.getRestartStep(), false ));
|
||||
copy_file(input_arg.parent_path(), restart_file, output_dir);
|
||||
}
|
||||
|
||||
using IMPORT = Opm::ParserKeywords::IMPORT;
|
||||
for (std::size_t import_index = 0; import_index < deck.count<IMPORT>(); import_index++) {
|
||||
const auto& import_keyword = deck.getKeyword<IMPORT>(import_index);
|
||||
const auto& fname = import_keyword.getRecord(0).getItem<IMPORT::FILE>().get<std::string>(0);
|
||||
copy_file(input_arg.parent_path(), fname, output_dir);
|
||||
}
|
||||
|
||||
|
||||
using PYACTION = Opm::ParserKeywords::PYACTION;
|
||||
for (std::size_t pyaction_index = 0; pyaction_index < deck.count<PYACTION>(); pyaction_index++) {
|
||||
const auto& pyaction_keyword = deck.getKeyword<PYACTION>(pyaction_index);
|
||||
const auto& fname = pyaction_keyword.getRecord(1).getItem<PYACTION::FILENAME>().get<std::string>(0);
|
||||
copy_file(input_arg.parent_path(), fname, output_dir);
|
||||
}
|
||||
|
||||
|
||||
using GDFILE = Opm::ParserKeywords::GDFILE;
|
||||
if (deck.hasKeyword<GDFILE>()) {
|
||||
const auto& gdfile_keyword = deck.getKeyword<GDFILE>();
|
||||
const auto& fname = gdfile_keyword.getRecord(0).getItem<GDFILE::filename>().get<std::string>(0);
|
||||
copy_file(input_arg.parent_path(), fname, output_dir);
|
||||
}
|
||||
}
|
||||
pack_deck(argv[arg_offset], os);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
300
examples/test_util/EclFilesComparator.cpp
Normal file
300
examples/test_util/EclFilesComparator.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/common/utility/numeric/calculateCellVol.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
/*
|
||||
This is just a basic survival test; we verify that the ERT well
|
||||
loader which is used in Resinsight can load the well description
|
||||
from the restart file.
|
||||
*/
|
||||
|
||||
void loadWells( const ecl_grid_type * grid , ecl_file_type * rst_file ) {
|
||||
well_info_type * well_info = well_info_alloc( grid );
|
||||
well_info_add_UNRST_wells2( well_info , ecl_file_get_global_view( rst_file ), true );
|
||||
well_info_free( well_info );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ECLFilesComparator::keywordValidForComparing(const std::string& keyword) const {
|
||||
auto it = std::find(keywords1.begin(), keywords1.end(), keyword);
|
||||
if (it == keywords1.end()) {
|
||||
OPM_THROW(std::runtime_error, "Keyword " << keyword << " does not exist in first file.");
|
||||
}
|
||||
it = find(keywords2.begin(), keywords2.end(), keyword);
|
||||
if (it == keywords2.end()) {
|
||||
OPM_THROW(std::runtime_error, "Keyword " << keyword << " does not exist in second file.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int ECLFilesComparator::getEclKeywordData(ecl_kw_type*& ecl_kw1, ecl_kw_type*& ecl_kw2, const std::string& keyword, int occurrence1, int occurrence2) const {
|
||||
ecl_kw1 = ecl_file_iget_named_kw(ecl_file1, keyword.c_str(), occurrence1);
|
||||
ecl_kw2 = ecl_file_iget_named_kw(ecl_file2, keyword.c_str(), occurrence2);
|
||||
const unsigned int numCells1 = ecl_kw_get_size(ecl_kw1);
|
||||
const unsigned int numCells2 = ecl_kw_get_size(ecl_kw2);
|
||||
if (numCells1 != numCells2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nOccurrence in first file " << occurrence1
|
||||
<< "\nOccurrence in second file " << occurrence2
|
||||
<< "\nCells in first file: " << numCells1
|
||||
<< "\nCells in second file: " << numCells2
|
||||
<< "\nThe number of cells differ.");
|
||||
}
|
||||
return numCells1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
void ECLFilesComparator::printValuesForCell(const std::string& /*keyword*/, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const T& value1, const T& value2) const {
|
||||
if (kw_size == static_cast<size_t>(ecl_grid_get_active_size(ecl_grid1))) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1A(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "Grid coordinate = (" << i << ", " << j << ", " << k << ")" << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (kw_size == static_cast<size_t>(ecl_grid_get_global_size(ecl_grid1))) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "Grid coordinate = (" << i << ", " << j << ", " << k << ")" << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
}
|
||||
|
||||
template void ECLFilesComparator::printValuesForCell<bool> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const bool& value1, const bool& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<int> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const int& value1, const int& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<double> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const double& value1, const double& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<std::string>(const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const std::string& value1, const std::string& value2) const;
|
||||
|
||||
|
||||
ECLFilesComparator::ECLFilesComparator(int file_type_arg, const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absToleranceArg, double relToleranceArg) :
|
||||
file_type(file_type_arg), absTolerance(absToleranceArg), relTolerance(relToleranceArg) {
|
||||
|
||||
std::string file1, file2;
|
||||
if (file_type == ECL_UNIFIED_RESTART_FILE) {
|
||||
file1 = basename1 + ".UNRST";
|
||||
file2 = basename2 + ".UNRST";
|
||||
}
|
||||
else if (file_type == ECL_INIT_FILE) {
|
||||
file1 = basename1 + ".INIT";
|
||||
file2 = basename2 + ".INIT";
|
||||
}
|
||||
else if (file_type == ECL_RFT_FILE) {
|
||||
file1 = basename1 + ".RFT";
|
||||
file2 = basename2 + ".RFT";
|
||||
}
|
||||
else {
|
||||
OPM_THROW(std::invalid_argument, "Unsupported filetype sent to ECLFilesComparator's constructor."
|
||||
<< "Only unified restart (.UNRST), initial (.INIT) and .RFT files are supported.");
|
||||
}
|
||||
ecl_file1 = ecl_file_open(file1.c_str(), 0);
|
||||
ecl_file2 = ecl_file_open(file2.c_str(), 0);
|
||||
ecl_grid1 = ecl_grid_load_case(basename1.c_str());
|
||||
ecl_grid2 = ecl_grid_load_case(basename2.c_str());
|
||||
if (ecl_file1 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening first file: " << file1);
|
||||
}
|
||||
if (ecl_file2 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening second file: " << file2);
|
||||
}
|
||||
if (ecl_grid1 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening first grid file: " << basename1);
|
||||
}
|
||||
if (ecl_grid2 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening second grid file. " << basename2);
|
||||
}
|
||||
unsigned int numKeywords1 = ecl_file_get_num_distinct_kw(ecl_file1);
|
||||
unsigned int numKeywords2 = ecl_file_get_num_distinct_kw(ecl_file2);
|
||||
keywords1.reserve(numKeywords1);
|
||||
keywords2.reserve(numKeywords2);
|
||||
for (unsigned int i = 0; i < numKeywords1; ++i) {
|
||||
std::string keyword(ecl_file_iget_distinct_kw(ecl_file1, i));
|
||||
keywords1.push_back(keyword);
|
||||
}
|
||||
for (unsigned int i = 0; i < numKeywords2; ++i) {
|
||||
std::string keyword(ecl_file_iget_distinct_kw(ecl_file2, i));
|
||||
keywords2.push_back(keyword);
|
||||
}
|
||||
|
||||
if (file_type == ECL_UNIFIED_RESTART_FILE) {
|
||||
loadWells( ecl_grid1 , ecl_file1 );
|
||||
loadWells( ecl_grid2 , ecl_file2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ECLFilesComparator::~ECLFilesComparator() {
|
||||
ecl_file_close(ecl_file1);
|
||||
ecl_file_close(ecl_file2);
|
||||
ecl_grid_free(ecl_grid1);
|
||||
ecl_grid_free(ecl_grid2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLFilesComparator::printKeywords() const {
|
||||
std::cout << "\nKeywords in the first file:\n";
|
||||
for (const auto& it : keywords1) {
|
||||
std::cout << std::setw(15) << std::left << it << " of type " << ecl_type_get_name( ecl_file_iget_named_data_type(ecl_file1, it.c_str(), 0)) << std::endl;
|
||||
}
|
||||
std::cout << "\nKeywords in second file:\n";
|
||||
for (const auto& it : keywords2) {
|
||||
std::cout << std::setw(15) << std::left << it << " of type " << ecl_type_get_name( ecl_file_iget_named_data_type(ecl_file2, it.c_str(), 0)) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLFilesComparator::printKeywordsDifference() const {
|
||||
std::vector<std::string> common;
|
||||
std::vector<std::string> uncommon;
|
||||
const std::vector<std::string>* keywordsShort = &keywords1;
|
||||
const std::vector<std::string>* keywordsLong = &keywords2;
|
||||
if (keywords1.size() > keywords2.size()) {
|
||||
keywordsLong = &keywords1;
|
||||
keywordsShort = &keywords2;
|
||||
}
|
||||
for (const auto& it : *keywordsLong) {
|
||||
const auto position = std::find(keywordsShort->begin(), keywordsShort->end(), it);
|
||||
if (position != keywordsShort->end()) {
|
||||
common.push_back(*position);
|
||||
}
|
||||
else {
|
||||
uncommon.push_back(it);
|
||||
}
|
||||
}
|
||||
std::cout << "\nCommon keywords for the two cases:\n";
|
||||
for (const auto& it : common) std::cout << it << std::endl;
|
||||
std::cout << "\nUncommon keywords for the two cases:\n";
|
||||
for (const auto& it : uncommon) std::cout << it << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Deviation ECLFilesComparator::calculateDeviations(double val1, double val2) {
|
||||
val1 = std::abs(val1);
|
||||
val2 = std::abs(val2);
|
||||
Deviation deviation;
|
||||
if (val1 != 0 || val2 != 0) {
|
||||
deviation.abs = std::abs(val1 - val2);
|
||||
if (val1 != 0 && val2 != 0) {
|
||||
deviation.rel = deviation.abs/(std::max(val1, val2));
|
||||
}
|
||||
}
|
||||
return deviation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::median(std::vector<double> vec) {
|
||||
if (vec.empty()) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
size_t n = vec.size()/2;
|
||||
nth_element(vec.begin(), vec.begin() + n, vec.end());
|
||||
if (vec.size() % 2 == 0) {
|
||||
return 0.5*(vec[n-1]+vec[n]);
|
||||
}
|
||||
else {
|
||||
return vec[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::average(const std::vector<double>& vec) {
|
||||
if (vec.empty()) {
|
||||
return 0;
|
||||
}
|
||||
double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
|
||||
return sum/vec.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::getCellVolume(const ecl_grid_type* ecl_grid,
|
||||
const int globalIndex) {
|
||||
std::vector<double> x(8, 0.0);
|
||||
std::vector<double> y(8, 0.0);
|
||||
std::vector<double> z(8, 0.0);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ecl_grid_get_cell_corner_xyz1(ecl_grid, globalIndex, i, &x.data()[i], &y.data()[i], &z.data()[i]);
|
||||
}
|
||||
return calculateCellVol(x,y,z);
|
||||
}
|
||||
127
examples/test_util/EclFilesComparator.hpp
Normal file
127
examples/test_util/EclFilesComparator.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLFILESCOMPARATOR_HPP
|
||||
#define ECLFILESCOMPARATOR_HPP
|
||||
|
||||
#include "Deviation.hpp"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct ecl_file_struct; //!< Prototype for eclipse file struct, from ERT library.
|
||||
typedef struct ecl_file_struct ecl_file_type;
|
||||
|
||||
struct ecl_grid_struct; //!< Prototype for eclipse grid struct, from ERT library.
|
||||
typedef struct ecl_grid_struct ecl_grid_type;
|
||||
struct ecl_kw_struct; //!< Prototype for eclipse keyword struct, from ERT library.
|
||||
typedef struct ecl_kw_struct ecl_kw_type;
|
||||
|
||||
|
||||
/*! \brief A class for comparing ECLIPSE files.
|
||||
\details ECLFilesComparator opens ECLIPSE files
|
||||
(unified restart, initial and RFT in addition to grid file)
|
||||
from two simulations. This class has only the functions
|
||||
printKeywords() and printKeywordsDifference(), in addition to a
|
||||
couple of get-functions: the comparison logic is implemented in
|
||||
the subclasses RegressionTest and IntegrationTest. */
|
||||
class ECLFilesComparator {
|
||||
private:
|
||||
int file_type;
|
||||
double absTolerance = 0;
|
||||
double relTolerance = 0;
|
||||
protected:
|
||||
ecl_file_type* ecl_file1 = nullptr;
|
||||
ecl_grid_type* ecl_grid1 = nullptr;
|
||||
ecl_file_type* ecl_file2 = nullptr;
|
||||
ecl_grid_type* ecl_grid2 = nullptr;
|
||||
std::vector<std::string> keywords1, keywords2;
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform full error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
mutable size_t num_errors = 0;
|
||||
|
||||
//! \brief Checks if the keyword exists in both cases.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
//! \details If the keyword does not exist in one of the cases, the function throws an exception.
|
||||
void keywordValidForComparing(const std::string& keyword) const;
|
||||
//! \brief Stores keyword data for a given occurrence
|
||||
//! \param[out] ecl_kw1 Pointer to a ecl_kw_type, which stores keyword data for first case given the occurrence.
|
||||
//! \param[out] ecl_kw2 Pointer to a ecl_kw_type, which stores keyword data for second case given the occurrence.
|
||||
//! \param[in] keyword Which keyword to consider.
|
||||
//! \param[in] occurrence Which keyword occurrence to consider.
|
||||
//! \details This function stores keyword data for the given keyword and occurrence in #ecl_kw1 and #ecl_kw2, and returns the number of cells (for which the keyword has a value at the occurrence). If the number of cells differ for the two cases, an exception is thrown.
|
||||
unsigned int getEclKeywordData(ecl_kw_type*& ecl_kw1, ecl_kw_type*& ecl_kw2, const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
//! \brief Prints values for a given keyword, occurrence and cell
|
||||
//! \param[in] keyword Which keyword to consider.
|
||||
//! \param[in] occurrence Which keyword occurrence to consider.
|
||||
//! \param[in] cell Which cell occurrence to consider (numbered by global index).
|
||||
//! \param[in] value1 Value for first file, the data type can be bool, int, double or std::string.
|
||||
//! \param[in] value2 Value for second file, the data type can be bool, int, double or std::string.
|
||||
//! \details Templatefunction for printing values when exceptions are thrown. The function is defined for bool, int, double and std::string.
|
||||
template <typename T>
|
||||
void printValuesForCell(const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const T& value1, const T& value2) const;
|
||||
|
||||
public:
|
||||
//! \brief Open ECLIPSE files and set tolerances and keywords.
|
||||
//! \param[in] file_type Specifies which filetype to be compared, possible inputs are UNRSTFILE, INITFILE and RFTFILE.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details The content of the ECLIPSE files specified in the input is stored in the ecl_file_type and ecl_grid_type member variables. In addition the keywords and absolute and relative tolerances (member variables) are set. If the constructor is unable to open one of the ECLIPSE files, an exception will be thrown.
|
||||
ECLFilesComparator(int file_type, const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance);
|
||||
//! \brief Closing the ECLIPSE files.
|
||||
~ECLFilesComparator();
|
||||
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether to perform a full error analysis.
|
||||
void doAnalysis(bool analize) { analysis = analize; }
|
||||
|
||||
//! \brief Returns the number of errors encountered in the performed comparisons.
|
||||
size_t getNoErrors() const { return num_errors; }
|
||||
|
||||
//! \brief Returns the ECLIPSE filetype of this
|
||||
int getFileType() const {return file_type;}
|
||||
//! \brief Returns the absolute tolerance stored as a private member variable in the class
|
||||
double getAbsTolerance() const {return absTolerance;}
|
||||
//! \brief Returns the relative tolerance stored as a private member variable in the class
|
||||
double getRelTolerance() const {return relTolerance;}
|
||||
|
||||
//! \brief Print all keywords and their respective Eclipse type for the two input cases.
|
||||
void printKeywords() const;
|
||||
//! \brief Print common and uncommon keywords for the two input cases.
|
||||
void printKeywordsDifference() const;
|
||||
|
||||
//! \brief Calculate deviations for two values.
|
||||
//! \details Using absolute values of the input arguments: If one of the values are non-zero, the Deviation::abs returned is the difference between the two input values. In addition, if both values are non-zero, the Deviation::rel returned is the absolute deviation divided by the largest value.
|
||||
static Deviation calculateDeviations(double val1, double val2);
|
||||
//! \brief Calculate median of a vector.
|
||||
//! \details Returning the median of the input vector, i.e. the middle value of the sorted vector if the number of elements is odd or the mean of the two middle values if the number of elements are even.
|
||||
static double median(std::vector<double> vec);
|
||||
//! \brief Calculate average of a vector.
|
||||
//! \details Returning the average of the input vector, i.e. the sum of all values divided by the number of elements.
|
||||
static double average(const std::vector<double>& vec);
|
||||
//! \brief Obtain the volume of a cell.
|
||||
static double getCellVolume(const ecl_grid_type* ecl_grid, const int globalIndex);
|
||||
};
|
||||
|
||||
#endif
|
||||
199
examples/test_util/EclIntegrationTest.cpp
Normal file
199
examples/test_util/EclIntegrationTest.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclIntegrationTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
void ECLIntegrationTest::setCellVolumes() {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
const unsigned int globalGridCount1 = ecl_grid_get_global_size(ecl_grid1);
|
||||
const unsigned int activeGridCount1 = ecl_grid_get_active_size(ecl_grid1);
|
||||
const unsigned int globalGridCount2 = ecl_grid_get_global_size(ecl_grid2);
|
||||
const unsigned int activeGridCount2 = ecl_grid_get_active_size(ecl_grid2);
|
||||
if (globalGridCount1 != globalGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << globalGridCount1
|
||||
<< "\nCells in second file: " << globalGridCount2
|
||||
<< "\nThe number of global cells differ.");
|
||||
}
|
||||
if (activeGridCount1 != activeGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << activeGridCount1
|
||||
<< "\nCells in second file: " << activeGridCount2
|
||||
<< "\nThe number of active cells differ.");
|
||||
}
|
||||
for (unsigned int cell = 0; cell < globalGridCount1; ++cell) {
|
||||
const double cellVolume1 = getCellVolume(ecl_grid1, cell);
|
||||
const double cellVolume2 = getCellVolume(ecl_grid2, cell);
|
||||
Deviation dev = calculateDeviations(cellVolume1, cellVolume2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
OPM_THROW(std::runtime_error, "In grid file: Deviations of cell volume exceed tolerances. "
|
||||
<< "\nFor cell with coordinate (" << i << ", " << j << ", " << k << "):"
|
||||
<< "\nCell volume in first file: " << cellVolume1
|
||||
<< "\nCell volume in second file: " << cellVolume2
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
} // The second input case is used as reference.
|
||||
cellVolumes.push_back(cellVolume2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::initialOccurrenceCompare(const std::string& keyword) {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, 0, 0);
|
||||
std::vector<double> values1(numCells);
|
||||
initialCellValues.resize(numCells);
|
||||
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, initialCellValues.data());
|
||||
|
||||
// This variable sums up the difference between the keyword value for the first case and the keyword value for the second case, for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedDifference = 0;
|
||||
// This variable sums up the keyword value for the first case for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedTotal = 0;
|
||||
for (size_t cell = 0; cell < initialCellValues.size(); ++cell) {
|
||||
weightedTotal += initialCellValues[cell]*cellVolumes[cell];
|
||||
weightedDifference += std::abs(values1[cell] - initialCellValues[cell])*cellVolumes[cell];
|
||||
}
|
||||
if (weightedTotal != 0) {
|
||||
double ratioValue = weightedDifference/weightedTotal;
|
||||
if ((ratioValue) > getRelTolerance()) {
|
||||
OPM_THROW(std::runtime_error, "\nFor keyword " << keyword << " and occurrence 0:"
|
||||
<< "\nThe ratio of the deviation and the total value is " << ratioValue
|
||||
<< ", which exceeds the relative tolerance of " << getRelTolerance() << "."
|
||||
<< "\nSee the docs for more information about how the ratio is computed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::occurrenceCompare(const std::string& keyword, int occurrence) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence, occurrence);
|
||||
std::vector<double> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, values2.data());
|
||||
|
||||
// This variable sums up the difference between the keyword value for the first case and the keyword value for the second case, for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedDifference = 0;
|
||||
// This variable sums up the difference between the keyword value for the occurrence and the initial keyword value for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double relativeWeightedTotal = 0;
|
||||
|
||||
for (size_t cell = 0; cell < values1.size(); ++cell) {
|
||||
relativeWeightedTotal += std::abs(values1[cell] - initialCellValues[cell])*cellVolumes[cell];
|
||||
weightedDifference += std::abs(values1[cell] - values2[cell])*cellVolumes[cell];
|
||||
}
|
||||
|
||||
if (relativeWeightedTotal != 0) {
|
||||
double ratioValue = weightedDifference/relativeWeightedTotal;
|
||||
if ((ratioValue) > getRelTolerance()) {
|
||||
OPM_THROW(std::runtime_error, "\nFor keyword " << keyword << " and occurrence " << occurrence << ":"
|
||||
<< "\nThe ratio of the deviation and the total value is " << ratioValue
|
||||
<< ", which exceeds the relative tolerance of " << getRelTolerance() << "."
|
||||
<< "\nSee the docs for more information about how the ratio is computed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ECLIntegrationTest::ECLIntegrationTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absTolerance, double relTolerance) :
|
||||
ECLFilesComparator(ECL_UNIFIED_RESTART_FILE, basename1, basename2, absTolerance, relTolerance) {
|
||||
std::cout << "\nUsing cell volumes and keyword values from case " << basename2
|
||||
<< " as reference." << std::endl << std::endl;
|
||||
setCellVolumes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ECLIntegrationTest::elementInWhitelist(const std::string& keyword) const {
|
||||
auto it = std::find(keywordWhitelist.begin(), keywordWhitelist.end(), keyword);
|
||||
return it != keywordWhitelist.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::equalNumKeywords() const {
|
||||
if (keywords1.size() != keywords2.size()) {
|
||||
OPM_THROW(std::runtime_error, "\nKeywords in first file: " << keywords1.size()
|
||||
<< "\nKeywords in second file: " << keywords2.size()
|
||||
<< "\nThe number of keywords differ.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::results() {
|
||||
for (const auto& it : keywordWhitelist)
|
||||
resultsForKeyword(it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::resultsForKeyword(const std::string& keyword) {
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
keywordValidForComparing(keyword);
|
||||
const unsigned int occurrences1 = ecl_file_get_num_named_kw(ecl_file1, keyword.c_str());
|
||||
const unsigned int occurrences2 = ecl_file_get_num_named_kw(ecl_file2, keyword.c_str());
|
||||
if (occurrences1 != occurrences2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nKeyword occurrences in first file: " << occurrences1
|
||||
<< "\nKeyword occurrences in second file: " << occurrences2
|
||||
<< "\nThe number of occurrences differ.");
|
||||
}
|
||||
initialOccurrenceCompare(keyword);
|
||||
for (unsigned int occurrence = 1; occurrence < occurrences1; ++occurrence) {
|
||||
occurrenceCompare(keyword, occurrence);
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
78
examples/test_util/EclIntegrationTest.hpp
Normal file
78
examples/test_util/EclIntegrationTest.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLINTEGRATIONTEST_HPP
|
||||
#define ECLINTEGRATIONTEST_HPP
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
|
||||
/*! \brief A class for executing a integration test for two ECLIPSE files.
|
||||
\details This class inherits from ECLFilesComparator, which opens and closes
|
||||
the input cases and stores keywordnames. The three public functions
|
||||
equalNumKeywords(), results() and resultsForKeyword() can be invoked
|
||||
to compare griddata or keyworddata for all keywords or a given
|
||||
keyword (resultsForKeyword()).
|
||||
*/
|
||||
class ECLIntegrationTest: public ECLFilesComparator {
|
||||
private:
|
||||
std::vector<double> cellVolumes; //!< Vector of cell volumes in second input case (indexed by global index)
|
||||
std::vector<double> initialCellValues; //!< Keyword values for all cells at first occurrence (index by global index)
|
||||
|
||||
// These are the only keywords which are compared, since SWAT should be "1 - SOIL - SGAS", this keyword is omitted.
|
||||
const std::vector<std::string> keywordWhitelist = {"SGAS", "SWAT", "PRESSURE"};
|
||||
|
||||
void setCellVolumes();
|
||||
void initialOccurrenceCompare(const std::string& keyword);
|
||||
void occurrenceCompare(const std::string& keyword, int occurrence) const;
|
||||
public:
|
||||
//! \brief Sets up the integration test.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details This constructor calls the constructor of the superclass, with input filetype unified restart. See the docs for ECLFilesComparator for more information.
|
||||
ECLIntegrationTest(const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance);
|
||||
|
||||
//! \brief Checks if a keyword is supported for comparison.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
bool elementInWhitelist(const std::string& keyword) const;
|
||||
//! \brief Checks if the number of keywords equal in the two input cases.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
void equalNumKeywords() const;
|
||||
|
||||
//! \brief Finds deviations for all supported keywords.
|
||||
//! \details results() loops through all supported keywords for integration test (defined in keywordWhitelist -- this is SGAS, SWAT and PRESSURE) and calls resultsForKeyword() for each keyword.
|
||||
void results();
|
||||
//! \brief Finds deviations for a specific keyword.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
/*! \details First, resultsForKeyword() checks if the keyword exits in both cases, and if the number of keyword occurrences in the two cases differ. If these tests fail, an exception is thrown. Then deviaitons are calculated as described below for each occurrence, and an exception is thrown if the relative error ratio \f$E\f$ is larger than the relative tolerance.
|
||||
* Calculation:\n
|
||||
* Let the keyword values for occurrence \f$n\f$ and cell \f$i\f$ be \f$p_{n,i}\f$ and \f$q_{n,i}\f$ for input case 1 and 2, respectively.
|
||||
* Consider first the initial occurrence (\f$n=0\f$). The function uses the second cases as reference, and calculates the volume weighted sum of \f$q_{0,i}\f$ over all cells \f$i\f$:
|
||||
* \f[ S_0 = \sum_{i} q_{0,i} v_i \f]
|
||||
* where \f$v_{i}\f$ is the volume of cell \f$i\f$ in case 2. Then, the deviations between the cases for each cell are calculated:
|
||||
* \f[ \Delta = \sum_{i} |p_{0,i} - q_{0,i}| v_i.\f]
|
||||
* The error ratio is then \f$E = \Delta/S_0\f$.\n
|
||||
* For all other occurrences \f$n\f$, the deviation value \f$\Delta\f$ is calculated the same way, but the total value \f$S\f$ is calculated relative to the initial occurrence total \f$S_0\f$:
|
||||
* \f[ S = \sum_{i} |q_{n,i} - q_{0,i}| v_i. \f]
|
||||
* The error ratio is \f$ E = \Delta/S\f$. */
|
||||
void resultsForKeyword(const std::string& keyword);
|
||||
};
|
||||
|
||||
#endif
|
||||
352
examples/test_util/EclRegressionTest.cpp
Normal file
352
examples/test_util/EclRegressionTest.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclRegressionTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
void ECLRegressionTest::printResultsForKeyword(const std::string& keyword) const {
|
||||
std::cout << "Deviation results for keyword " << keyword << " of type "
|
||||
<< ecl_type_get_name(ecl_file_iget_named_data_type(ecl_file1, keyword.c_str(), 0))
|
||||
<< ":\n";
|
||||
const double absDeviationAverage = average(absDeviation);
|
||||
const double relDeviationAverage = average(relDeviation);
|
||||
std::cout << "Average absolute deviation = " << absDeviationAverage << std::endl;
|
||||
std::cout << "Median absolute deviation = " << median(absDeviation) << std::endl;
|
||||
std::cout << "Average relative deviation = " << relDeviationAverage << std::endl;
|
||||
std::cout << "Median relative deviation = " << median(relDeviation) << "\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::boolComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
for (size_t cell = 0; cell < numCells; cell++) {
|
||||
bool data1 = ecl_kw_iget_bool(ecl_kw1, cell);
|
||||
bool data2 = ecl_kw_iget_bool(ecl_kw2, cell);
|
||||
if (data1 != data2) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, numCells, cell, data1, data2);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of bool type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::charComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
for (size_t cell = 0; cell < numCells; cell++) {
|
||||
std::string data1(ecl_kw_iget_char_ptr(ecl_kw1, cell));
|
||||
std::string data2(ecl_kw_iget_char_ptr(ecl_kw2, cell));
|
||||
if (data1.compare(data2) != 0) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, numCells, cell, data1, data2);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of char type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::intComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
std::vector<int> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_memcpy_int_data(ecl_kw1, values1.data());
|
||||
ecl_kw_get_memcpy_int_data(ecl_kw2, values2.data());
|
||||
for (size_t cell = 0; cell < values1.size(); cell++) {
|
||||
if (values1[cell] != values2[cell]) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, values1.size(), cell, values1[cell], values2[cell]);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of int type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::doubleComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
std::vector<double> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, values2.data());
|
||||
|
||||
auto it = std::find(keywordDisallowNegatives.begin(), keywordDisallowNegatives.end(), keyword);
|
||||
for (size_t cell = 0; cell < values1.size(); cell++) {
|
||||
deviationsForCell(values1[cell], values2[cell], keyword, occurrence1, occurrence2, cell, it == keywordDisallowNegatives.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::deviationsForCell(double val1, double val2,
|
||||
const std::string& keyword,
|
||||
int occurrence1, int occurrence2,
|
||||
size_t kw_size, size_t cell,
|
||||
bool allowNegativeValues) {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
if (!allowNegativeValues) {
|
||||
if (val1 < 0) {
|
||||
if (std::abs(val1) > absTolerance) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Negative value in first file, "
|
||||
<< "which in absolute value exceeds the absolute tolerance of " << absTolerance << ".");
|
||||
}
|
||||
val1 = 0;
|
||||
}
|
||||
if (val2 < 0) {
|
||||
if (std::abs(val2) > absTolerance) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Negative value in second file, "
|
||||
<< "which in absolute value exceeds the absolute tolerance of " << absTolerance << ".");
|
||||
}
|
||||
val2 = 0;
|
||||
}
|
||||
}
|
||||
Deviation dev = calculateDeviations(val1, val2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(dev);
|
||||
} else {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Deviations exceed tolerances."
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
}
|
||||
}
|
||||
if (dev.abs != -1) {
|
||||
absDeviation.push_back(dev.abs);
|
||||
}
|
||||
if (dev.rel != -1) {
|
||||
relDeviation.push_back(dev.rel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::gridCompare(const bool volumecheck) const {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
const unsigned int globalGridCount1 = ecl_grid_get_global_size(ecl_grid1);
|
||||
const unsigned int activeGridCount1 = ecl_grid_get_active_size(ecl_grid1);
|
||||
const unsigned int globalGridCount2 = ecl_grid_get_global_size(ecl_grid2);
|
||||
const unsigned int activeGridCount2 = ecl_grid_get_active_size(ecl_grid2);
|
||||
if (globalGridCount1 != globalGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << globalGridCount1
|
||||
<< "\nCells in second file: " << globalGridCount2
|
||||
<< "\nThe number of global cells differ.");
|
||||
}
|
||||
if (activeGridCount1 != activeGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << activeGridCount1
|
||||
<< "\nCells in second file: " << activeGridCount2
|
||||
<< "\nThe number of active cells differ.");
|
||||
}
|
||||
|
||||
if (!volumecheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int cell = 0; cell < globalGridCount1; ++cell) {
|
||||
const bool active1 = ecl_grid_cell_active1(ecl_grid1, cell);
|
||||
const bool active2 = ecl_grid_cell_active1(ecl_grid2, cell);
|
||||
if (active1 != active2) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
HANDLE_ERROR(std::runtime_error, "Grid cell with one-based indices ( "
|
||||
<< i << ", " << j << ", " << k << " ) is "
|
||||
<< (active1 ? "active" : "inactive") << " in first grid, but "
|
||||
<< (active2 ? "active" : "inactive") << " in second grid.");
|
||||
}
|
||||
const double cellVolume1 = getCellVolume(ecl_grid1, cell);
|
||||
const double cellVolume2 = getCellVolume(ecl_grid2, cell);
|
||||
Deviation dev = calculateDeviations(cellVolume1, cellVolume2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
HANDLE_ERROR(std::runtime_error, "In grid file: Deviations of cell volume exceed tolerances. "
|
||||
<< "\nFor cell with one-based indices (" << i << ", " << j << ", " << k << "):"
|
||||
<< "\nCell volume in first file: " << cellVolume1
|
||||
<< "\nCell volume in second file: " << cellVolume2
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << "."
|
||||
<< "\nCell 1 active: " << active1
|
||||
<< "\nCell 2 active: " << active2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::results() {
|
||||
if (!this->acceptExtraKeywords) {
|
||||
if (keywords1.size() != keywords2.size()) {
|
||||
std::set<std::string> keys(keywords1.begin() , keywords1.end());
|
||||
for (const auto& key2: keywords2)
|
||||
keys.insert( key2 );
|
||||
|
||||
for (const auto& key : keys)
|
||||
fprintf(stderr," %8s:%3d %8s:%3d \n",key.c_str() , ecl_file_get_num_named_kw( ecl_file1 , key.c_str()),
|
||||
key.c_str() , ecl_file_get_num_named_kw( ecl_file2 , key.c_str()));
|
||||
|
||||
|
||||
OPM_THROW(std::runtime_error, "\nKeywords in first file: " << keywords1.size()
|
||||
<< "\nKeywords in second file: " << keywords2.size()
|
||||
<< "\nThe number of keywords differ.");
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& it : keywords1)
|
||||
resultsForKeyword(it);
|
||||
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " entries" << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::resultsForKeyword(const std::string& keyword) {
|
||||
keywordValidForComparing(keyword);
|
||||
const unsigned int occurrences1 = ecl_file_get_num_named_kw(ecl_file1, keyword.c_str());
|
||||
const unsigned int occurrences2 = ecl_file_get_num_named_kw(ecl_file2, keyword.c_str());
|
||||
if (!onlyLastOccurrence && occurrences1 != occurrences2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nKeyword occurrences in first file: " << occurrences1
|
||||
<< "\nKeyword occurrences in second file: " << occurrences2
|
||||
<< "\nThe number of occurrences differ.");
|
||||
}
|
||||
// Assuming keyword type is constant for every occurrence:
|
||||
const ecl_type_enum kw_type = ecl_type_get_type( ecl_file_iget_named_data_type(ecl_file1, keyword.c_str(), 0) );
|
||||
switch(kw_type) {
|
||||
case ECL_DOUBLE_TYPE:
|
||||
case ECL_FLOAT_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
doubleComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
doubleComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
printResultsForKeyword(keyword);
|
||||
absDeviation.clear();
|
||||
relDeviation.clear();
|
||||
return;
|
||||
case ECL_INT_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
intComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
intComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_CHAR_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
charComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
charComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_BOOL_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
boolComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
boolComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_MESS_TYPE:
|
||||
std::cout << "\nKeyword " << keyword << " is of type MESS"
|
||||
<< ", which is not supported in regression test." << "\n\n";
|
||||
return;
|
||||
default:
|
||||
std::cout << "\nKeyword " << keyword << "has undefined type." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
93
examples/test_util/EclRegressionTest.hpp
Normal file
93
examples/test_util/EclRegressionTest.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLREGRESSIONTEST_HPP
|
||||
#define ECLREGRESSIONTEST_HPP
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
|
||||
/*! \brief A class for executing a regression test for two ECLIPSE files.
|
||||
\details This class inherits from ECLFilesComparator, which opens and
|
||||
closes the input cases and stores keywordnames.
|
||||
The three public functions gridCompare(), results() and
|
||||
resultsForKeyword() can be invoked to compare griddata
|
||||
or keyworddata for all keywords or a given keyword (resultsForKeyword()).
|
||||
*/
|
||||
|
||||
class ECLRegressionTest: public ECLFilesComparator {
|
||||
private:
|
||||
// These vectors store absolute and relative deviations, respecively. Note that they are whiped clean for every new keyword comparison.
|
||||
std::vector<double> absDeviation, relDeviation;
|
||||
// Keywords which should not contain negative values, i.e. uses allowNegativeValues = false in deviationsForCell():
|
||||
const std::vector<std::string> keywordDisallowNegatives = {"SGAS", "SWAT", "PRESSURE"};
|
||||
|
||||
// Only compare last occurrence
|
||||
bool onlyLastOccurrence = false;
|
||||
|
||||
// Accept extra keywords in the restart file of the 'new' simulation.
|
||||
bool acceptExtraKeywords = false;
|
||||
|
||||
|
||||
// Prints results stored in absDeviation and relDeviation.
|
||||
void printResultsForKeyword(const std::string& keyword) const;
|
||||
|
||||
// Function which compares data at specific occurrences and for a specific keyword type. The functions takes two occurrence inputs to also be able to
|
||||
// compare keywords which are shifted relative to each other in the two files. This is for instance handy when running flow with restart from different timesteps,
|
||||
// and comparing the last timestep from the two runs.
|
||||
void boolComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void charComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void intComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void doubleComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2);
|
||||
// deviationsForCell throws an exception if both the absolute deviation AND the relative deviation
|
||||
// are larger than absTolerance and relTolerance, respectively. In addition,
|
||||
// if allowNegativeValues is passed as false, an exception will be thrown when the absolute value
|
||||
// of a negative value exceeds absTolerance. If no exceptions are thrown, the absolute and relative deviations are added to absDeviation and relDeviation.
|
||||
void deviationsForCell(double val1, double val2, const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, bool allowNegativeValues = true);
|
||||
public:
|
||||
//! \brief Sets up the regression test.
|
||||
//! \param[in] file_type Specifies which filetype to be compared, possible inputs are UNRSTFILE, INITFILE and RFTFILE.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details This constructor only calls the constructor of the superclass, see the docs for ECLFilesComparator for more information.
|
||||
ECLRegressionTest(int file_type, const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance):
|
||||
ECLFilesComparator(file_type, basename1, basename2, absTolerance, relTolerance) {}
|
||||
|
||||
//! \brief Option to only compare last occurrence
|
||||
void setOnlyLastOccurrence(bool onlyLastOccurrenceArg) {this->onlyLastOccurrence = onlyLastOccurrenceArg;}
|
||||
|
||||
// Accept extra keywords: If this switch is set to true the comparison
|
||||
// of restart files will ignore extra keywords which are only present
|
||||
// in the new simulation.
|
||||
void setAcceptExtraKeywords(bool acceptExtraKeywords) { this->acceptExtraKeywords = acceptExtraKeywords; }
|
||||
|
||||
//! \brief Compares grid properties of the two cases.
|
||||
// gridCompare() checks if both the number of active and global cells in the two cases are the same. If they are, and volumecheck is true, all cells are looped over to calculate the cell volume deviation for the two cases. If the both the relative and absolute deviation exceeds the tolerances, an exception is thrown.
|
||||
void gridCompare(const bool volumecheck) const;
|
||||
//! \brief Calculates deviations for all keywords.
|
||||
// This function checks if the number of keywords of the two cases are equal, and if it is, resultsForKeyword() is called for every keyword. If not, an exception is thrown.
|
||||
void results();
|
||||
//! \brief Calculates deviations for a specific keyword.
|
||||
//! \param[in] keyword Keyword which should be compared, if this keyword is absent in one of the cases, an exception will be thrown.
|
||||
//! \details This function loops through every report step and every cell and compares the values for the given keyword from the two input cases. If the absolute or relative deviation between the two values for each step exceeds both the absolute tolerance and the relative tolerance (stored in ECLFilesComparator), an exception is thrown. In addition, some keywords are marked for "disallow negative values" -- these are SGAS, SWAT and PRESSURE. An exception is thrown if a value of one of these keywords is both negative and has an absolute value larger than the absolute tolerance. If no exceptions are thrown, resultsForKeyword() uses the private member funtion printResultsForKeyword to print the average and median deviations.
|
||||
void resultsForKeyword(const std::string& keyword);
|
||||
};
|
||||
|
||||
#endif
|
||||
380
examples/test_util/compareECL.cpp
Normal file
380
examples/test_util/compareECL.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclIntegrationTest.hpp"
|
||||
#include "EclRegressionTest.hpp"
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include "summaryRegressionTest.hpp"
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/ecl/ecl_endian_flip.h>
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <getopt.h>
|
||||
|
||||
static void printHelp() {
|
||||
std::cout << "\ncompareECL compares ECLIPSE files (restart (.RST), unified restart (.UNRST), initial (.INIT), summary (.SMRY), unified summary (.UNSMRY) or .RFT) and gridsizes (from .EGRID or .GRID file) from two simulations.\n"
|
||||
<< "The program takes four arguments:\n\n"
|
||||
<< "1. Case number 1 (full path without extension)\n"
|
||||
<< "2. Case number 2 (full path without extension)\n"
|
||||
<< "3. Absolute tolerance\n"
|
||||
<< "4. Relative tolerance (between 0 and 1)\n\n"
|
||||
<< "In addition, the program takes these options (which must be given before the arguments):\n\n"
|
||||
<< "-a Run a full analysis of errors.\n"
|
||||
<< "-g Will print the vector with the greatest error ratio.\n"
|
||||
<< "-h Print help and exit.\n"
|
||||
<< "-i Execute integration test (regression test is default).\n"
|
||||
<< " The integration test compares SGAS, SWAT and PRESSURE in unified restart files, so this option can not be used in combination with -t.\n"
|
||||
<< "-I Same as -i, but throws an exception when the number of keywords in the two cases differ. Can not be used in combination with -t.\n"
|
||||
<< "-k Specify specific keyword to compare (capitalized), for example -k PRESSURE.\n"
|
||||
<< "-K Will not allow different amount of keywords in the two files. Throws an exception if the amount are different.\n"
|
||||
<< "-l Only do comparison for the last occurrence. This option is only for the regression test, and can therefore not be used in combination with -i or -I.\n"
|
||||
<< "-m mainVar. Will calculate the error ratio for one main variable. Valid input is WOPR, WWPR, WGPR or WBHP.\n"
|
||||
<< "-n Do not throw on errors.\n"
|
||||
<< "-p Print keywords in both cases and exit. Can not be used in combination with -P.\n"
|
||||
<< "-P Print common and uncommon keywords in both cases and exit. Can not be used in combination with -p.\n"
|
||||
<< "-R Will allow comparison between a restarted simulation and a normal simulation for summary regression tests. The files must end at the same time.\n"
|
||||
<< "-s int Sets the number of spikes that are allowed for each keyword in summary integration tests.\n"
|
||||
<< "-t Specify ECLIPSE filetype to compare (unified restart is default). Can not be used in combination with -i or -I. Different possible arguments are:\n"
|
||||
<< " -t UNRST \t Compare two unified restart files (.UNRST). This the default value, so it is the same as not passing option -t.\n"
|
||||
<< " -t INIT \t Compare two initial files (.INIT).\n"
|
||||
<< " -t RFT \t Compare two RFT files (.RFT).\n"
|
||||
<< " -t RST \t Compare two cases consisting of restart files (.Xnnnn).\n"
|
||||
<< " -t SMRY \t Compare two cases consistent of (unified) summary files.\n"
|
||||
<< " -t RST1 \t Compare two cases where the first case consists of restart files (.Xnnnn), and the second case consists of a unified restart file (.UNRST).\n"
|
||||
<< " -t RST2 \t Compare two cases where the first case consists of a unified restart file (.UNRST), and the second case consists of restart files (.Xnnnn).\n"
|
||||
<< " Note that when dealing with restart files (.Xnnnn), the program concatenates all of them into one unified restart file, which is used for comparison and stored in the same directory as the restart files.\n"
|
||||
<< " This will overwrite any existing unified restart file in that directory.\n\n"
|
||||
<< "-v For the rate keywords WOPR, WGPR, WWPR and WBHP. Calculates the error volume of the two summary files. This is printed to screen.\n"
|
||||
<< "\nExample usage of the program: \n\n"
|
||||
<< "compareECL -k PRESSURE <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
|
||||
<< "compareECL -t INIT -k PORO <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
|
||||
<< "compareECL -i <path to first casefile> <path to second casefile> 0.01 1e-6\n\n"
|
||||
<< "Exceptions are thrown (and hence program exits) when deviations are larger than the specified "
|
||||
<< "tolerances, or when the number of cells does not match -- either in the grid file or for a "
|
||||
<< "specific keyword. Information about the keyword, keyword occurrence (zero based) and cell "
|
||||
<< "coordinate is printed when an exception is thrown. For more information about how the cases "
|
||||
<< "are compared, see the documentation of the EclFilesComparator class.\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void splitBasename(const std::string& basename, std::string& path, std::string& filename) {
|
||||
const size_t lastSlashIndex = basename.find_last_of("/\\");
|
||||
path = basename.substr(0,lastSlashIndex);
|
||||
filename = basename.substr(lastSlashIndex+1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inspired by the ecl_pack application in the ERT library
|
||||
void concatenateRestart(const std::string& basename) {
|
||||
std::string inputPath, inputBase;
|
||||
splitBasename(basename, inputPath, inputBase);
|
||||
stringlist_type* inputFiles = stringlist_alloc_new();
|
||||
const int numFiles = ecl_util_select_filelist(inputPath.c_str(), inputBase.c_str(), ECL_RESTART_FILE, false, inputFiles);
|
||||
|
||||
const char* target_file_name = ecl_util_alloc_filename(inputPath.c_str(), inputBase.c_str(), ECL_UNIFIED_RESTART_FILE, false, -1);
|
||||
fortio_type* target = fortio_open_writer(target_file_name, false, ECL_ENDIAN_FLIP);
|
||||
int dummy;
|
||||
ecl_kw_type* seqnum_kw = ecl_kw_alloc_new("SEQNUM", 1, ECL_INT, &dummy);
|
||||
|
||||
int reportStep = 0;
|
||||
for (int i = 0; i < numFiles; ++i) {
|
||||
ecl_util_get_file_type(stringlist_iget(inputFiles, i), nullptr, &reportStep);
|
||||
ecl_file_type* src_file = ecl_file_open(stringlist_iget(inputFiles, i), 0);
|
||||
ecl_kw_iset_int(seqnum_kw, 0, reportStep);
|
||||
ecl_kw_fwrite(seqnum_kw, target);
|
||||
ecl_file_fwrite_fortio(src_file, target, 0);
|
||||
ecl_file_close(src_file);
|
||||
}
|
||||
fortio_fclose(target);
|
||||
stringlist_free(inputFiles);
|
||||
}
|
||||
|
||||
//------------------------------------------------//
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Restart is default
|
||||
ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE;
|
||||
// RegressionTest is default
|
||||
bool integrationTest = false;
|
||||
bool allowDifferentAmount = true;
|
||||
bool checkNumKeywords = false;
|
||||
bool findGreatestErrorRatio = false;
|
||||
bool findVolumeError = false;
|
||||
bool onlyLastOccurrence = false;
|
||||
bool printKeywords = false;
|
||||
bool printKeywordsDifference = false;
|
||||
bool restartFile = false;
|
||||
bool specificKeyword = false;
|
||||
bool specificFileType = false;
|
||||
bool allowSpikes = false;
|
||||
bool throwOnError = true;
|
||||
bool throwTooGreatErrorRatio = true;
|
||||
bool acceptExtraKeywords = false;
|
||||
bool analysis = false;
|
||||
bool volumecheck = true;
|
||||
char* keyword = nullptr;
|
||||
char* fileTypeCstr = nullptr;
|
||||
const char* mainVariable = nullptr;
|
||||
int c = 0;
|
||||
int spikeLimit = -1;
|
||||
|
||||
while ((c = getopt(argc, argv, "hiIk:alnpPt:VRgs:m:vKx")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'g':
|
||||
findGreatestErrorRatio = true;
|
||||
throwTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
case 'i':
|
||||
integrationTest = true;
|
||||
break;
|
||||
case 'I':
|
||||
integrationTest = true;
|
||||
checkNumKeywords = true;
|
||||
break;
|
||||
case 'k':
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'K':
|
||||
allowDifferentAmount = false;
|
||||
break;
|
||||
case 'l':
|
||||
onlyLastOccurrence = true;
|
||||
break;
|
||||
case 'm':
|
||||
mainVariable = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
throwOnError = false;
|
||||
break;
|
||||
case 'p':
|
||||
printKeywords = true;
|
||||
break;
|
||||
case 'P':
|
||||
printKeywordsDifference = true;
|
||||
break;
|
||||
case 'R':
|
||||
restartFile = true;
|
||||
break;
|
||||
case 's':
|
||||
allowSpikes = true;
|
||||
spikeLimit = atof(optarg);
|
||||
break;
|
||||
case 't':
|
||||
specificFileType = true;
|
||||
fileTypeCstr = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
findVolumeError = true;
|
||||
break;
|
||||
case 'V':
|
||||
volumecheck = false;
|
||||
break;
|
||||
case 'x':
|
||||
acceptExtraKeywords = true;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 'k' || optopt == 'm' || optopt == 's') {
|
||||
std::cerr << "Option " << optopt << " requires a keyword as argument, see manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else if (optopt == 't') {
|
||||
std::cerr << "Option t requires an ECLIPSE filetype as argument, see manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cerr << "Unknown option." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
int argOffset = optind;
|
||||
if ((printKeywords && printKeywordsDifference) ||
|
||||
(integrationTest && specificFileType) ||
|
||||
(integrationTest && onlyLastOccurrence)) {
|
||||
std::cerr << "Error: Options given which can not be combined. "
|
||||
<< "Please see the manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc != argOffset + 4) {
|
||||
std::cerr << "Error: The number of options and arguments given is not correct. "
|
||||
<< "Please run compareECL -h to see manual." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::string basename1 = argv[argOffset];
|
||||
std::string basename2 = argv[argOffset + 1];
|
||||
double absTolerance = strtod(argv[argOffset + 2], nullptr);
|
||||
double relTolerance = strtod(argv[argOffset + 3], nullptr);
|
||||
|
||||
if (specificFileType) {
|
||||
std::string fileTypeString(fileTypeCstr);
|
||||
for (auto& ch: fileTypeString) ch = toupper(ch);
|
||||
if (fileTypeString== "UNRST") {} //Do nothing
|
||||
else if (fileTypeString == "RST") {
|
||||
concatenateRestart(basename1);
|
||||
concatenateRestart(basename2);
|
||||
}
|
||||
else if (fileTypeString == "RST1") {
|
||||
concatenateRestart(basename1);
|
||||
}
|
||||
else if (fileTypeString == "RST2") {
|
||||
concatenateRestart(basename2);
|
||||
}
|
||||
else if (fileTypeString == "INIT") {
|
||||
file_type = ECL_INIT_FILE;
|
||||
}
|
||||
else if (fileTypeString == "RFT") {
|
||||
file_type = ECL_RFT_FILE;
|
||||
}
|
||||
else if (fileTypeString == "SMRY")
|
||||
file_type = ECL_SUMMARY_FILE;
|
||||
else {
|
||||
std::cerr << "Unknown ECLIPSE filetype specified with option -t. Please run compareECL -h to see manual." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (restartFile && (file_type != ECL_SUMMARY_FILE || integrationTest)) {
|
||||
std::cerr << "Error: -R can only be used in for summary regression tests." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::cout << "Comparing '" << basename1 << "' to '" << basename2 << "'." << std::endl;
|
||||
try {
|
||||
if (file_type == ECL_SUMMARY_FILE) {
|
||||
if(!integrationTest){
|
||||
SummaryRegressionTest compare(basename1,basename2,absTolerance,relTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.doAnalysis(analysis);
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.setIsRestartFile(restartFile);
|
||||
if(specificKeyword){
|
||||
compare.getRegressionTest(keyword);
|
||||
}
|
||||
else{
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.getRegressionTest();
|
||||
}
|
||||
} else {
|
||||
SummaryIntegrationTest compare(basename1,basename2,absTolerance,relTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.setFindVectorWithGreatestErrorRatio(findGreatestErrorRatio);
|
||||
compare.setAllowSpikes(allowSpikes);
|
||||
if (mainVariable) {
|
||||
compare.setOneOfTheMainVariables(true);
|
||||
std::string str(mainVariable);
|
||||
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
|
||||
if(str == "WOPR" ||str=="WWPR" ||str=="WGPR" || str == "WBHP"){
|
||||
compare.setMainVariable(str);
|
||||
}else{
|
||||
throw std::invalid_argument("The input is not a main variable. -m option requires a valid main variable.");
|
||||
}
|
||||
}
|
||||
compare.setFindVolumeError(findVolumeError);
|
||||
if (spikeLimit != -1) {
|
||||
compare.setSpikeLimit(spikeLimit);
|
||||
}
|
||||
compare.setAllowDifferentAmountOfKeywords(allowDifferentAmount);
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.setThrowExceptionForTooGreatErrorRatio(throwTooGreatErrorRatio);
|
||||
if(specificKeyword){
|
||||
compare.setPrintSpecificKeyword(specificKeyword);
|
||||
compare.getIntegrationTest(keyword);
|
||||
return 0;
|
||||
}
|
||||
compare.getIntegrationTest();
|
||||
}
|
||||
}
|
||||
else if (integrationTest) {
|
||||
ECLIntegrationTest comparator(basename1, basename2, absTolerance, relTolerance);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
}
|
||||
if (printKeywordsDifference) {
|
||||
comparator.printKeywordsDifference();
|
||||
return 0;
|
||||
}
|
||||
if (checkNumKeywords) {
|
||||
comparator.equalNumKeywords();
|
||||
}
|
||||
if (specificKeyword) {
|
||||
if (comparator.elementInWhitelist(keyword)) {
|
||||
comparator.resultsForKeyword(keyword);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Keyword " << keyword << " is not supported for the integration test. Use SGAS, SWAT or PRESSURE." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
comparator.results();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ECLRegressionTest comparator(file_type, basename1, basename2, absTolerance, relTolerance);
|
||||
comparator.throwOnErrors(throwOnError);
|
||||
comparator.doAnalysis(analysis);
|
||||
comparator.setAcceptExtraKeywords(acceptExtraKeywords);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
}
|
||||
if (printKeywordsDifference) {
|
||||
comparator.printKeywordsDifference();
|
||||
return 0;
|
||||
}
|
||||
if (onlyLastOccurrence) {
|
||||
comparator.setOnlyLastOccurrence(true);
|
||||
}
|
||||
if (specificKeyword) {
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.resultsForKeyword(keyword);
|
||||
}
|
||||
else {
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.results();
|
||||
}
|
||||
if (comparator.getNoErrors() > 0)
|
||||
OPM_THROW(std::runtime_error, comparator.getNoErrors() << " errors encountered in comparisons.");
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Program threw an exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
229
examples/test_util/compareSummary.cpp
Normal file
229
examples/test_util/compareSummary.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "summaryRegressionTest.hpp"
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <getopt.h>
|
||||
|
||||
void printHelp(){
|
||||
std::cout << "\n\nThe program can handle both unified and non-unified summary files."<< std::endl;
|
||||
std::cout <<"In the case of non-unified summary files all the files must be located in the same directory. Only the basename (full path without extension) is needed as input." << std::endl << std::endl;
|
||||
std::cout << "\nThe program takes four arguments" << std::endl;
|
||||
std::cout << "1) <path to file1>/<base_name>, basename without extension" << std::endl;
|
||||
std::cout << "2) <path to file2>/<base_name>, basename without extension" << std::endl;
|
||||
std::cout << "3) absolute tolerance" << std::endl;
|
||||
std::cout << "4) relative tolerance (between 0 and 1)" << std::endl;
|
||||
std::cout << "The program will only throw an exception when both the absolute and relative tolerance are exceeded." << std::endl;
|
||||
std::cout << "The program is capable of performing both a regression test and an integration test, \nhowever only one type of test at a time. ";
|
||||
std::cout << "By default the program will run a regression test."<< std::endl;
|
||||
std::cout << "\nThe program have command line options:" << std::endl;
|
||||
std::cout << "-a \tRun a full analysis of errors." << std::endl;
|
||||
std::cout << "-h \t\tPrint help message." << std::endl << std::endl;
|
||||
std::cout << "For the regression test: " << std::endl;
|
||||
std::cout << "-r \t\tChoosing regression test (this is default)."<< std::endl;
|
||||
std::cout << "-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<< std::endl;
|
||||
std::cout << "-p \t\tWill print the keywords of the files." << std::endl;
|
||||
std::cout << "-R \t\tWill allow comparison between a restarted simulation and a normal simulation. The files must end at the same time." << std::endl << std::endl;
|
||||
std::cout << "For the integration test:"<< std::endl;
|
||||
std::cout << "-i \t\tChoosing integration test." << std::endl;
|
||||
std::cout << "-d \t\tThe program will not throw an exception when the volume error ratio exceeds the limit." << std::endl;
|
||||
std::cout << "-g \t\tWill print the vector with the greatest error ratio." << std::endl;
|
||||
std::cout << "-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<< std::endl;
|
||||
std::cout << "-K \t\tWill not allow different amount of keywords in the two files. Throws an exception if the amount are different." << std::endl;
|
||||
std::cout << "-m mainVar \tWill calculate the error ratio for one main variable. Valid input is WOPR, WWPR, WGPR or WBHP." << std::endl;
|
||||
std::cout << "-n \tDo not throw on errors." << std::endl;
|
||||
std::cout << "-p \t\tWill print the keywords of the files." << std::endl;
|
||||
std::cout << "-P keyword \tWill print the summary vectors of a specified kewyord, for example -P WOPR:B-3H." << std::endl;
|
||||
std::cout << "-s int \t\tSets the number of spikes that are allowed for each keyword, for example: -s 5." << std::endl;
|
||||
std::cout << "-v \t\tFor the rate keywords WOPR, WGPR, WWPR and WBHP. Calculates the error volume of \n\t\tthe two summary files. This is printed to screen." << std::endl;
|
||||
std::cout << "-V keyword \tWill calculate the error rate for a specific keyword." << std::endl << std::endl;
|
||||
std::cout << "Suggested combination of command line options:"<< std::endl;
|
||||
std::cout << " -i -g -m mainVariable, will print the vector which have the greatest error ratio of the main variable of interest.\n"<< std::endl;
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
|
||||
|
||||
int main (int argc, char ** argv){
|
||||
|
||||
//------------------------------------------------
|
||||
//Defines some constants
|
||||
bool specificKeyword = false;
|
||||
bool allowSpikes = false;
|
||||
bool findVolumeError = false;
|
||||
bool integrationTest = false;
|
||||
bool regressionTest = true;
|
||||
bool allowDifferentAmountOfKeywords = true;
|
||||
bool printKeywords = false;
|
||||
bool printSpecificKeyword = false;
|
||||
bool findVectorWithGreatestErrorRatio = false;
|
||||
bool oneOfTheMainVariables = false;
|
||||
bool throwExceptionForTooGreatErrorRatio = true;
|
||||
bool isRestartFile = false;
|
||||
bool throwOnError = true;
|
||||
bool analysis = false;
|
||||
const char* keyword = nullptr;
|
||||
const char* mainVariable = nullptr;
|
||||
int c = 0;
|
||||
int limit = -1;
|
||||
//------------------------------------------------
|
||||
|
||||
//------------------------------------------------
|
||||
//For setting the options selected
|
||||
while ((c = getopt(argc, argv, "dghik:Km:napP:rRs:vV:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'd':
|
||||
throwExceptionForTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'g':
|
||||
findVectorWithGreatestErrorRatio = true;
|
||||
throwExceptionForTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
case 'i':
|
||||
integrationTest = true;
|
||||
regressionTest = false;
|
||||
break;
|
||||
case 'k':
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'K':
|
||||
allowDifferentAmountOfKeywords = false;
|
||||
break;
|
||||
case 'm':
|
||||
oneOfTheMainVariables = true;
|
||||
mainVariable = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
throwOnError = false;
|
||||
break;
|
||||
case 'p':
|
||||
printKeywords = true;
|
||||
break;
|
||||
case 'P':
|
||||
specificKeyword = true;
|
||||
printSpecificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
integrationTest = false;
|
||||
regressionTest = true;
|
||||
break;
|
||||
case 'R':
|
||||
isRestartFile = true;
|
||||
break;
|
||||
case 's':
|
||||
allowSpikes = true;
|
||||
limit = atof(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
findVolumeError = true;
|
||||
break;
|
||||
case 'V':
|
||||
findVolumeError = true;
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 'k' || optopt == 'm' || optopt == 'P'
|
||||
|| optopt == 's' || optopt == 'V') {
|
||||
std::cout << "Option -"<<optopt<<" requires an keyword." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown option." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------
|
||||
|
||||
int argOffset = optind;
|
||||
if (argc != argOffset + 4) {
|
||||
printHelp();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const char * basename1 = argv[argOffset];
|
||||
const char * basename2 = argv[argOffset+1];
|
||||
double absoluteTolerance = strtod(argv[argOffset+2], nullptr);
|
||||
double relativeTolerance = strtod(argv[argOffset+3], nullptr);
|
||||
|
||||
std::cout << "Comparing '" << basename1 << "' to '" << basename2 << "'." << std::endl;
|
||||
|
||||
try {
|
||||
if(regressionTest){
|
||||
SummaryRegressionTest compare(basename1,basename2, absoluteTolerance, relativeTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.doAnalysis(analysis);
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
if(isRestartFile){compare.setIsRestartFile(true);}
|
||||
if(specificKeyword){
|
||||
compare.getRegressionTest(keyword);
|
||||
}
|
||||
else{
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
compare.getRegressionTest();
|
||||
}
|
||||
}
|
||||
if(integrationTest){
|
||||
SummaryIntegrationTest compare(basename1,basename2, absoluteTolerance, relativeTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
if(findVectorWithGreatestErrorRatio){compare.setFindVectorWithGreatestErrorRatio(true);}
|
||||
if(allowSpikes){compare.setAllowSpikes(true);}
|
||||
if(oneOfTheMainVariables){
|
||||
compare.setOneOfTheMainVariables(true);
|
||||
std::string str(mainVariable);
|
||||
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
|
||||
if(str == "WOPR" ||str=="WWPR" ||str=="WGPR" || str == "WBHP"){
|
||||
compare.setMainVariable(str);
|
||||
}else{
|
||||
throw std::invalid_argument("The input is not a main variable. -m option requires a valid main variable.");
|
||||
}
|
||||
}
|
||||
if(findVolumeError){compare.setFindVolumeError(true);}
|
||||
if(limit != -1){compare.setSpikeLimit(limit);}
|
||||
if(!allowDifferentAmountOfKeywords){compare.setAllowDifferentAmountOfKeywords(false);}
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
if(!throwExceptionForTooGreatErrorRatio){compare.setThrowExceptionForTooGreatErrorRatio(false);}
|
||||
if(specificKeyword){
|
||||
if(printSpecificKeyword){compare.setPrintSpecificKeyword(true);}
|
||||
compare.getIntegrationTest(keyword);
|
||||
return 0;
|
||||
}
|
||||
compare.getIntegrationTest();
|
||||
}
|
||||
}
|
||||
catch(const std::exception& e) {
|
||||
std::cerr << "Program threw an exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
240
examples/test_util/summaryComparator.cpp
Normal file
240
examples/test_util/summaryComparator.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "summaryComparator.hpp"
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/int_vector.h>
|
||||
#include <ert/util/bool_vector.h>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
SummaryComparator::SummaryComparator(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absoluteTol, double relativeTol){
|
||||
ecl_sum1 = ecl_sum_fread_alloc_case(basename1.c_str(), ":");
|
||||
ecl_sum2 = ecl_sum_fread_alloc_case(basename2.c_str(), ":");
|
||||
if (ecl_sum1 == nullptr || ecl_sum2 == nullptr) {
|
||||
OPM_THROW(std::runtime_error, "Not able to open files");
|
||||
}
|
||||
absoluteTolerance = absoluteTol;
|
||||
relativeTolerance = relativeTol;
|
||||
keys1 = stringlist_alloc_new();
|
||||
keys2 = stringlist_alloc_new();
|
||||
ecl_sum_select_matching_general_var_list( ecl_sum1 , "*" , this->keys1);
|
||||
stringlist_sort(this->keys1 , nullptr );
|
||||
ecl_sum_select_matching_general_var_list( ecl_sum2 , "*" , this->keys2);
|
||||
stringlist_sort(this->keys2 , nullptr );
|
||||
|
||||
if(stringlist_get_size(keys1) <= stringlist_get_size(keys2)){
|
||||
this->keysShort = this->keys1;
|
||||
this->keysLong = this->keys2;
|
||||
}else{
|
||||
this->keysShort = this->keys2;
|
||||
this->keysLong = this->keys1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SummaryComparator::~SummaryComparator(){
|
||||
ecl_sum_free(ecl_sum1);
|
||||
ecl_sum_free(ecl_sum2);
|
||||
stringlist_free(keys1);
|
||||
stringlist_free(keys2);
|
||||
}
|
||||
|
||||
|
||||
Deviation SummaryComparator::calculateDeviations(double val1, double val2){
|
||||
double absDev;
|
||||
Deviation deviation;
|
||||
absDev = std::abs(val1 - val2);
|
||||
deviation.abs = absDev;
|
||||
if (val1 != 0 || val2 != 0) {
|
||||
deviation.rel = absDev/double(std::max(std::abs(val1), std::abs(val2)));
|
||||
}
|
||||
return deviation;
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::setTimeVecs(std::vector<double> &timeVec1,
|
||||
std::vector<double> &timeVec2){
|
||||
timeVec1.reserve(ecl_sum_get_data_length(ecl_sum1));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum1); time_index++){
|
||||
timeVec1.push_back(ecl_sum_iget_sim_days(ecl_sum1 , time_index ));
|
||||
}
|
||||
timeVec2.reserve(ecl_sum_get_data_length(ecl_sum2));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum2); time_index++){
|
||||
timeVec2.push_back(ecl_sum_iget_sim_days(ecl_sum2 , time_index ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::getDataVecs(std::vector<double> &dataVec1,
|
||||
std::vector<double> &dataVec2,
|
||||
const char* keyword){
|
||||
dataVec1.reserve(ecl_sum_get_data_length(ecl_sum1));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum1); time_index++){
|
||||
dataVec1.push_back(ecl_sum_iget(ecl_sum1, time_index, ecl_sum_get_general_var_params_index( ecl_sum1 , keyword )));
|
||||
}
|
||||
dataVec2.reserve(ecl_sum_get_data_length(ecl_sum2));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum2); time_index++){
|
||||
|
||||
dataVec2.push_back(ecl_sum_iget(ecl_sum2, time_index, ecl_sum_get_general_var_params_index( ecl_sum2 , keyword )));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::setDataSets(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2){
|
||||
if(timeVec1.size() < timeVec2.size()){
|
||||
ecl_sum_fileShort = this->ecl_sum1;
|
||||
ecl_sum_fileLong = this->ecl_sum2;
|
||||
}
|
||||
else{
|
||||
ecl_sum_fileShort = this->ecl_sum2;
|
||||
ecl_sum_fileLong = this->ecl_sum1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::chooseReference(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& dataVec2){
|
||||
if(timeVec1.size() <= timeVec2.size()){
|
||||
referenceVec = &timeVec1; // time vector
|
||||
referenceDataVec = &dataVec1; //data vector
|
||||
checkVec = &timeVec2;
|
||||
checkDataVec = &dataVec2;
|
||||
}
|
||||
else{
|
||||
referenceVec = &timeVec2;
|
||||
referenceDataVec = &dataVec2;
|
||||
checkVec = &timeVec1;
|
||||
checkDataVec = &dataVec1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::getDeviation(size_t refIndex, size_t &checkIndex, Deviation &dev){
|
||||
if((*referenceVec)[refIndex] == (*checkVec)[checkIndex]){
|
||||
dev = SummaryComparator::calculateDeviations((*referenceDataVec)[refIndex], (*checkDataVec)[checkIndex]);
|
||||
checkIndex++;
|
||||
return;
|
||||
}
|
||||
else if((*referenceVec)[refIndex]<(*checkVec)[checkIndex]){
|
||||
double value = SummaryComparator::unitStep((*checkDataVec)[checkIndex]);
|
||||
/*Must be a little careful here. Flow writes out old value first,
|
||||
than changes value. Say there should be a change in production rate from A to B at timestep 300.
|
||||
Then the data of time step 300 is A and the next timestep will have value B. Must use the upper limit. */
|
||||
dev = SummaryComparator::calculateDeviations((*referenceDataVec)[refIndex], value);
|
||||
checkIndex++;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
checkIndex++;
|
||||
getDeviation(refIndex, checkIndex , dev);
|
||||
}
|
||||
if(checkIndex == checkVec->size() -1 ){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printUnits(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
std::cout << stringlist_iget(keysLong, jvar) << " unit: " << ecl_sum_get_unit(ecl_sum_fileShort, stringlist_iget(keysLong, jvar)) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Called only when the keywords are equal in the getDeviations()-function
|
||||
const char* SummaryComparator::getUnit(const char* keyword){
|
||||
return ecl_sum_get_unit(ecl_sum_fileShort, keyword);
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printKeywords(){
|
||||
int ivar = 0;
|
||||
std::vector<std::string> noMatchString;
|
||||
std::cout << "Keywords that are common for the files:" << std::endl;
|
||||
while(ivar < stringlist_get_size(keysLong)){
|
||||
const char* keyword = stringlist_iget(keysLong, ivar);
|
||||
if (stringlist_contains(keysLong, keyword) && stringlist_contains(keysShort, keyword)){
|
||||
std::cout << keyword << std::endl;
|
||||
ivar++;
|
||||
}
|
||||
else{
|
||||
noMatchString.push_back(keyword);
|
||||
ivar++;
|
||||
}
|
||||
}
|
||||
if(noMatchString.size() == 0){
|
||||
std::cout << "No keywords were different" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Keywords that are different: " << std::endl;
|
||||
for (const auto& it : noMatchString) std::cout << it << std::endl;
|
||||
|
||||
std::cout << "\nOf the " << stringlist_get_size(keysLong) << " keywords " << stringlist_get_size(keysLong)-noMatchString.size() << " were equal and " << noMatchString.size() << " were different" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printDataOfSpecificKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
size_t ivar = 0;
|
||||
size_t jvar = 0;
|
||||
const char separator = ' ';
|
||||
const int numWidth = 14;
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Time";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Ref data";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Check data" << std::endl;
|
||||
|
||||
while(ivar < referenceVec->size()){
|
||||
if(ivar == referenceVec->size() || jvar == checkVec->size() ){
|
||||
break;
|
||||
}
|
||||
if((*referenceVec)[ivar] == (*checkVec)[jvar]){
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceDataVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkDataVec)[jvar] << std::endl;
|
||||
ivar++;
|
||||
jvar++;
|
||||
}else if((*referenceVec)[ivar] < (*checkVec)[jvar]){
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceDataVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "" << std::endl;
|
||||
ivar++;
|
||||
}
|
||||
else{
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkVec)[jvar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkDataVec)[jvar] << std::endl;
|
||||
jvar++;
|
||||
}
|
||||
}
|
||||
}
|
||||
182
examples/test_util/summaryComparator.hpp
Normal file
182
examples/test_util/summaryComparator.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SUMMARYCOMPARATOR_HPP
|
||||
#define SUMMARYCOMPARATOR_HPP
|
||||
|
||||
#include "Deviation.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else \
|
||||
std::cerr << message << std::endl; \
|
||||
}
|
||||
|
||||
|
||||
//! \brief Prototyping struct, encapsuling the stringlist libraries.
|
||||
struct stringlist_struct;
|
||||
typedef struct stringlist_struct stringlist_type;
|
||||
|
||||
//! \brief Prototyping struct, encapsuling the ert libraries.
|
||||
struct ecl_sum_struct;
|
||||
typedef struct ecl_sum_struct ecl_sum_type;
|
||||
|
||||
|
||||
class SummaryComparator {
|
||||
private:
|
||||
double absoluteTolerance = 0; //!< The maximum absolute deviation that is allowed between two values.
|
||||
double relativeTolerance = 0; //!< The maximum relative deviation that is allowed between twi values.
|
||||
protected:
|
||||
ecl_sum_type * ecl_sum1 = nullptr; //!< Struct that contains file1
|
||||
ecl_sum_type * ecl_sum2 = nullptr; //!< Struct that contains file2
|
||||
ecl_sum_type * ecl_sum_fileShort = nullptr; //!< For keeping track of the file with most/fewest timesteps
|
||||
ecl_sum_type * ecl_sum_fileLong = nullptr; //!< For keeping track of the file with most/fewest timesteps
|
||||
stringlist_type* keys1 = nullptr; //!< For storing all the keywords of file1
|
||||
stringlist_type* keys2 = nullptr; //!< For storing all the keywords of file2
|
||||
stringlist_type * keysShort = nullptr; //!< For keeping track of the file with most/fewest keywords
|
||||
stringlist_type * keysLong = nullptr; //!< For keeping track of the file with most/fewest keywords
|
||||
const std::vector<double> * referenceVec = nullptr; //!< For storing the values of each time step for the file containing the fewer time steps.
|
||||
const std::vector<double> * referenceDataVec = nullptr; //!< For storing the data corresponding to each time step for the file containing the fewer time steps.
|
||||
const std::vector<double> * checkVec = nullptr; //!< For storing the values of each time step for the file containing the more time steps.
|
||||
const std::vector<double> * checkDataVec = nullptr; //!< For storing the data values corresponding to each time step for the file containing the more time steps.
|
||||
bool printKeyword = false; //!< Boolean value for choosing whether to print the keywords or not
|
||||
bool printSpecificKeyword = false; //!< Boolean value for choosing whether to print the vectors of a keyword or not
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
|
||||
//! \brief Calculate deviation between two data values and stores it in a Deviation struct.
|
||||
//! \param[in] refIndex Index in reference data
|
||||
//! \param[in] checkindex Index in data to be checked.
|
||||
//! \param[out] dev Holds the result from the comparison on return.
|
||||
//! \details Uses the #referenceVec as basis, and checks its values against the values in #checkDataVec. The function is reccursive, and will update the iterative index j of the #checkVec until #checkVec[j] >= #referenceVec[i]. \n When #referenceVec and #checkVec have the same time value (i.e. #referenceVec[i] == #checkVec[j]) a direct comparison is used, \n when this is not the case, when #referenceVec[i] do not excist as an element in #checkVec, a value is generated, either by the principle of unit step or by interpolation.
|
||||
void getDeviation(size_t refIndex, size_t &checkIndex, Deviation &dev);
|
||||
|
||||
//! \brief Figure out which data file contains the most / less timesteps and assign member variable pointers accordingly.
|
||||
//! \param[in] timeVec1 Data from first file
|
||||
//! \param[in] timeVec2 Data from second file
|
||||
//! \details Figure out which data file that contains the more/fewer time steps and assigns the private member variable pointers #ecl_sum_fileShort / #ecl_sum_fileLong to the correct data sets #ecl_sum1 / #ecl_sum2.
|
||||
void setDataSets(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2);
|
||||
|
||||
//! \brief Reads in the time values of each time step.
|
||||
//! \param[in] timeVec1 Vector for storing the time steps from file1
|
||||
//! \param[in] timeVec2 Vector for storing the time steps from file2
|
||||
void setTimeVecs(std::vector<double> &timeVec1,std::vector<double> &timeVec2);
|
||||
|
||||
//! \brief Read the data for one specific keyword into two separate vectors.
|
||||
//! \param[in] dataVec1 Vector for storing the data for one specific keyword from file1
|
||||
//! \param[in] dataVec2 Vector for storing the data for one specific keyword from file2
|
||||
//! \details The two data files do not necessarily have the same amount of data values, but the values must correspond to the same interval in time. Thus possible to interpolate values.
|
||||
void getDataVecs(std::vector<double> &dataVec1,
|
||||
std::vector<double> &dataVec2, const char* keyword);
|
||||
|
||||
//! \brief Sets one data set as a basis and the other as values to check against.
|
||||
//! \param[in] timeVec1 Used to figure out which dataset that have the more/fewer time steps.
|
||||
//! \param[in] timeVec2 Used to figure out which dataset that have the more/fewer time steps.
|
||||
//! \param[in] dataVec1 For assiging the the correct pointer to the data vector.
|
||||
//! \param[in] dataVec2 For assiging the the correct pointer to the data vector.
|
||||
//! \details Figures out which time vector that contains the fewer elements. Sets this as #referenceVec and its corresponding data as #referenceDataVec. \n The remaining data set is set as #checkVec (the time vector) and #checkDataVec.
|
||||
void chooseReference(const std::vector<double> &timeVec1,
|
||||
const std::vector<double> &timeVec2,
|
||||
const std::vector<double> &dataVec1,
|
||||
const std::vector<double> &dataVec2);
|
||||
|
||||
//! \brief Returns the relative tolerance.
|
||||
double getRelTolerance(){return this->relativeTolerance;}
|
||||
|
||||
//! \brief Returns the absolute tolerance.
|
||||
double getAbsTolerance(){return this->absoluteTolerance;}
|
||||
|
||||
//! \brief Returns the unit of the values of a keyword
|
||||
//! \param[in] keyword The keyword of interest.
|
||||
//! \param[out] ret The unit of the keyword as a const char*.
|
||||
const char* getUnit(const char* keyword);
|
||||
|
||||
//! \brief Prints the units of the files.
|
||||
void printUnits();
|
||||
|
||||
//! \brief Prints the keywords of the files.
|
||||
//! \details The function prints first the common keywords, than the keywords that are different.
|
||||
void printKeywords();
|
||||
|
||||
//! \brief Prints the summary vectors from the two files.
|
||||
//! \details The function requires that the summary vectors of the specific file have been read into the member variables referenceVec etc.
|
||||
void printDataOfSpecificKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword);
|
||||
|
||||
public:
|
||||
//! \brief Creates an SummaryComparator class object
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \param[in] absoluteTolerance The absolute tolerance which is to be used in the test.
|
||||
//! \param[in] relativeTolerance The relative tolerance which is to be used in the test.
|
||||
//! \details The constructor creates an object of the class, and openes the files, an exception is thrown if the opening of the files fails. \n It creates stringlists, in which keywords are to be stored, and figures out which keylist that contains the more/less keywords. \n Also the private member variables aboluteTolerance and relativeTolerance are set.
|
||||
SummaryComparator(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absoluteTolerance, double relativeTolerance);
|
||||
|
||||
//! \brief Destructor
|
||||
//! \details The destructor takes care of the allocated memory in which data has been stored.
|
||||
~SummaryComparator();
|
||||
|
||||
//! \brief Calculates the deviation between two values
|
||||
//! \param[in] val1 The first value of interest.
|
||||
//! \param[in] val2 The second value if interest.
|
||||
//! \param[out] ret Returns a Deviation struct.
|
||||
//! \details The function takes two values, calculates the absolute and relative deviation and returns the result as a Deviation struct.
|
||||
static Deviation calculateDeviations( double val1, double val2);
|
||||
|
||||
//! \brief Sets the private member variable printKeywords
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details The function sets the private member variable printKeywords. When it is true the function printKeywords will be called.
|
||||
void setPrintKeywords(bool boolean){this->printKeyword = boolean;}
|
||||
|
||||
//! \brief Sets the private member variable printSpecificKeyword
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details The function sets the private member variable printSpecificKeyword. When true, the summary vector of the keyword for both files will be printed.
|
||||
void setPrintSpecificKeyword(bool boolean){this->printSpecificKeyword = boolean;}
|
||||
|
||||
//! \brief Unit step function
|
||||
//! \param[in] value The input value should be the last know value
|
||||
//! \param[out] ret Return the unit-step-function value.
|
||||
//! \details In this case: The unit step function is used when the data from the two data set, which is to be compared, don't match in time. \n The unit step function is then to be called on the #checkDataVec 's value at the last time step which is before the time of comparison.
|
||||
|
||||
//! \brief Returns a value based on the unit step principle.
|
||||
static double unitStep(double value){return value;}
|
||||
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether or not to perform error analysis.
|
||||
void doAnalysis(bool analyse) { analysis = analyse; }
|
||||
};
|
||||
|
||||
#endif
|
||||
389
examples/test_util/summaryIntegrationTest.cpp
Normal file
389
examples/test_util/summaryIntegrationTest.cpp
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
void SummaryIntegrationTest::getIntegrationTest(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
|
||||
int ivar = 0;
|
||||
if(!allowDifferentAmountOfKeywords){
|
||||
if(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)){
|
||||
OPM_THROW(std::invalid_argument, "Different ammont of keywords in the two summary files.");
|
||||
}
|
||||
}
|
||||
if(printKeyword){
|
||||
printKeywords();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string keywordWithGreatestErrorRatio;
|
||||
double greatestRatio = 0;
|
||||
|
||||
//Iterates over all keywords from the restricted file, use iterator "ivar". Searches for a match in the file with more keywords, use the itarator "jvar".
|
||||
while(ivar < stringlist_get_size(keysShort)){
|
||||
const char* keyword = stringlist_iget(keysShort, ivar);
|
||||
|
||||
if(oneOfTheMainVariables){
|
||||
std::string keywordString(keyword);
|
||||
std::string substr = keywordString.substr(0,4);
|
||||
if(substr!= mainVariable){
|
||||
ivar++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
|
||||
if (strcmp(keyword, stringlist_iget(keysLong, jvar)) == 0){ //When the keywords are equal, proceed in comparing summary files.
|
||||
/* if(!checkUnits(keyword)){
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << " the unit of the two files is not equal. Not possible to compare.");
|
||||
} //Comparing the unit of the two vectors.*/
|
||||
checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
if(findVectorWithGreatestErrorRatio){
|
||||
WellProductionVolume volume = getSpecificWellVolume(timeVec1,timeVec2, keyword);
|
||||
findGreatestErrorRatio(volume,greatestRatio, keyword, keywordWithGreatestErrorRatio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//will only enter here if no keyword match
|
||||
if(jvar == stringlist_get_size(keysLong)-1){
|
||||
if(!allowDifferentAmountOfKeywords){
|
||||
OPM_THROW(std::invalid_argument, "No match on keyword");
|
||||
}
|
||||
}
|
||||
}
|
||||
ivar++;
|
||||
}
|
||||
if(findVectorWithGreatestErrorRatio){
|
||||
std::cout << "The keyword " << keywordWithGreatestErrorRatio << " had the greatest error ratio, which was " << greatestRatio << std::endl;
|
||||
}
|
||||
if((findVolumeError || oneOfTheMainVariables) && !findVectorWithGreatestErrorRatio){
|
||||
evaluateWellProductionVolume();
|
||||
}
|
||||
if(allowSpikes){
|
||||
std::cout << "checkWithSpikes succeeded." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::getIntegrationTest(const char* keyword){
|
||||
if(stringlist_contains(keysShort,keyword) && stringlist_contains(keysLong, keyword)){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
|
||||
if(printSpecificKeyword){
|
||||
printDataOfSpecificKeyword(timeVec1, timeVec2, keyword);
|
||||
}
|
||||
if(findVolumeError){
|
||||
WellProductionVolume volume = getSpecificWellVolume(timeVec1, timeVec2, keyword);
|
||||
if(volume.error == 0){
|
||||
std::cout << "For keyword " << keyword << " the total production volume is 0" << std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << "For keyword " << keyword << " the total production volume is "<< volume.total;
|
||||
std::cout << ", the error volume is " << volume.error << " the error ratio is " << volume.error/volume.total << std::endl;
|
||||
}
|
||||
}
|
||||
checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
return;
|
||||
}
|
||||
OPM_THROW(std::invalid_argument, "The keyword used is not common for the two files.");
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::checkForKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
if(allowSpikes){
|
||||
checkWithSpikes(keyword);
|
||||
}
|
||||
if(findVolumeError ||oneOfTheMainVariables ){
|
||||
volumeErrorCheck(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SummaryIntegrationTest::checkDeviation(const Deviation& deviation){
|
||||
double absTol = getAbsTolerance();
|
||||
double relTol = getRelTolerance();
|
||||
if (deviation.rel> relTol && deviation.abs > absTol){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
double &greatestRatio,
|
||||
const char* currentKeyword,
|
||||
std::string &greatestErrorRatio){
|
||||
if (volume.total != 0 && (volume.total - volume.error > getAbsTolerance()) ){
|
||||
if(volume.error/volume.total > greatestRatio){
|
||||
greatestRatio = volume.error/volume.total;
|
||||
std::string currentKeywordStr(currentKeyword);
|
||||
greatestErrorRatio = currentKeywordStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::volumeErrorCheck(const char* keyword){
|
||||
const smspec_node_type * node = ecl_sum_get_general_var_node (ecl_sum_fileShort ,keyword);//doesn't matter which ecl_sum_file one uses, the kewyord SHOULD be equal in terms of smspec data.
|
||||
bool hist = smspec_node_is_historical(node);
|
||||
/* returns true if the keyword corresponds to a summary vector "history".
|
||||
E.g. WOPRH, where the last character, 'H', indicates that it is a HISTORY vector.*/
|
||||
if(hist){
|
||||
return;//To make sure we do not include history vectors.
|
||||
}
|
||||
if (!mainVariable.empty()){
|
||||
std::string keywordString(keyword);
|
||||
std::string firstFour = keywordString.substr(0,4);
|
||||
|
||||
if(mainVariable == firstFour && firstFour == "WOPR"){
|
||||
if(firstFour == "WOPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WOP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WWPR"){
|
||||
if(firstFour == "WWPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WWP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WGPR"){
|
||||
if(firstFour == "WGPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WGP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WBHP"){
|
||||
if(firstFour == "WBHP"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WBHP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateVolumeError(keyword);
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::updateVolumeError(const char* keyword){
|
||||
std::string keywordString(keyword);
|
||||
std::string firstFour = keywordString.substr(0,4);
|
||||
|
||||
if(firstFour == "WOPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WOP += result;
|
||||
}
|
||||
if(firstFour == "WWPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WWP += result;
|
||||
}
|
||||
if(firstFour == "WGPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WGP += result;
|
||||
|
||||
}
|
||||
if(firstFour == "WBHP"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WBHP += result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WellProductionVolume SummaryIntegrationTest::getWellProductionVolume(const char * keyword){
|
||||
double total = integrate(*referenceVec, *referenceDataVec);
|
||||
double error = integrateError(*referenceVec, *referenceDataVec,
|
||||
*checkVec, *checkDataVec);
|
||||
WellProductionVolume wPV;
|
||||
wPV.total = total;
|
||||
wPV.error = error;
|
||||
if(wPV.total != 0 && wPV.total-wPV.error > getAbsTolerance()){
|
||||
if( (wPV.error/wPV.total > getRelTolerance()) && throwExceptionForTooGreatErrorRatio){
|
||||
OPM_THROW(std::runtime_error, "For the keyword "<< keyword << " the error ratio was " << wPV.error/wPV.total << " which is greater than the tolerance " << getRelTolerance());
|
||||
}
|
||||
}
|
||||
return wPV;
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::evaluateWellProductionVolume(){
|
||||
if(mainVariable.empty()){
|
||||
double ratioWOP, ratioWWP, ratioWGP, ratioWBHP;
|
||||
ratioWOP = WOP.error/WOP.total;
|
||||
ratioWWP = WWP.error/WWP.total;
|
||||
ratioWGP = WGP.error/WGP.total;
|
||||
ratioWBHP = WBHP.error/WBHP.total;
|
||||
std::cout << "\n The total oil volume is " << WOP.total << ". The error volume is "<< WOP.error << ". The error ratio is " << ratioWOP << std::endl;
|
||||
std::cout << "\n The total water volume is " << WWP.total << ". The error volume is "<< WWP.error << ". The error ratio is " << ratioWWP << std::endl;
|
||||
std::cout << "\n The total gas volume is " << WGP.total <<". The error volume is "<< WGP.error << ". The error ratio is " << ratioWGP << std::endl;
|
||||
std::cout << "\n The total area under the WBHP curve is " << WBHP.total << ". The area under the error curve is "<< WBHP.error << ". The error ratio is " << ratioWBHP << std::endl << std::endl;
|
||||
}
|
||||
if(mainVariable == "WOPR"){
|
||||
std::cout << "\nThe total oil volume is " << WOP.total << ". The error volume is "<< WOP.error << ". The error ratio is " << WOP.error/WOP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WWPR"){
|
||||
std::cout << "\nThe total water volume is " << WWP.total << ". The error volume is "<< WWP.error << ". The error ratio is " << WWP.error/WWP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WGPR"){
|
||||
std::cout << "\nThe total gas volume is " << WGP.total <<". The error volume is "<< WGP.error << ". The error ratio is " << WGP.error/WGP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WBHP"){
|
||||
std::cout << "\nThe total area under the WBHP curve " << WBHP.total << ". The area under the error curve is "<< WBHP.error << ". The error ratio is " << WBHP.error/WBHP.total << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::checkWithSpikes(const char* keyword){
|
||||
int errorOccurrences = 0;
|
||||
size_t jvar = 0 ;
|
||||
bool spikeCurrent = false;
|
||||
Deviation deviation;
|
||||
|
||||
for (size_t ivar = 0; ivar < referenceVec->size(); ivar++){
|
||||
int errorOccurrencesPrev = errorOccurrences;
|
||||
bool spikePrev = spikeCurrent;
|
||||
getDeviation(ivar,jvar, deviation);
|
||||
errorOccurrences += checkDeviation(deviation);
|
||||
if (errorOccurrences != errorOccurrencesPrev){
|
||||
spikeCurrent = true;
|
||||
} else{
|
||||
spikeCurrent = false;
|
||||
}
|
||||
if(spikePrev&&spikeCurrent){
|
||||
std::cout << "For keyword " << keyword << " at time step " << (*referenceVec)[ivar] <<std::endl;
|
||||
OPM_THROW(std::invalid_argument, "For keyword " << keyword << " at time step " << (*referenceVec)[ivar] << ", wwo deviations in a row exceed the limit. Not a spike value. Integration test fails." );
|
||||
}
|
||||
if(errorOccurrences > this->spikeLimit){
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
OPM_THROW(std::invalid_argument, "For keyword " << keyword << " too many spikes in the vector. Integration test fails.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WellProductionVolume
|
||||
SummaryIntegrationTest::getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
return getWellProductionVolume(keyword);
|
||||
}
|
||||
|
||||
|
||||
double SummaryIntegrationTest::integrate(const std::vector<double>& timeVec,
|
||||
const std::vector<double>& dataVec){
|
||||
double totalSum = 0;
|
||||
if(timeVec.size() != dataVec.size()){
|
||||
OPM_THROW(std::runtime_error, "The size of the time vector does not match the size of the data vector.");
|
||||
}
|
||||
for(size_t i = 0; i < timeVec.size()-1; i++){
|
||||
double width = timeVec[i+1] - timeVec[i];
|
||||
double height = dataVec[i+1];
|
||||
totalSum += getRectangleArea(height, width);
|
||||
}
|
||||
return totalSum;
|
||||
}
|
||||
|
||||
|
||||
double SummaryIntegrationTest::integrateError(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec2){
|
||||
// When the data corresponds to a rate the integration will become a Riemann
|
||||
// sum. This function calculates the Riemann sum of the error. The reason why
|
||||
// a Riemann sum is used is because of the way the data is written to file.
|
||||
// When a change occur (e.g. change of a rate), the data (value and time) is
|
||||
// written to file, THEN the change happens in the simulator, i.e., we will
|
||||
// notice the change at the next step.
|
||||
//
|
||||
// Keep in mind that the summary vector is NOT a continuous curve, only points
|
||||
// of data (time, value). We have to guess what happens between the data
|
||||
// points, we do this by saying: "There are no change, the only change happens
|
||||
// at the data points." As stated above, the value of this constant "height" of
|
||||
// the rectangle corresponds to the value of the last time step. Thus we have
|
||||
// to use the "right hand side value of the rectangle as height
|
||||
//
|
||||
// someDataVector[ivar] instead of someDataVector[ivar-1]
|
||||
//
|
||||
// (which intuition is saying is the correct value to use).
|
||||
|
||||
if(timeVec1.size() != dataVec1.size() || timeVec2.size() != dataVec2.size() ){
|
||||
OPM_THROW(std::runtime_error, "The size of the time vector does not match the size of the data vector.");
|
||||
}
|
||||
double errorSum = 0;
|
||||
double rightEdge, leftEdge, width;
|
||||
size_t i = 1;
|
||||
size_t j = 1;
|
||||
leftEdge = timeVec1[0];
|
||||
while(i < timeVec1.size()){
|
||||
if(j == timeVec2.size() ){
|
||||
break;
|
||||
}
|
||||
if(timeVec1[i] == timeVec2[j]){
|
||||
rightEdge = timeVec1[i];
|
||||
width = rightEdge - leftEdge;
|
||||
double dev = std::fabs(dataVec1[i] - dataVec2[j]);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
if(timeVec1[i] < timeVec2[j]){
|
||||
rightEdge = timeVec1[i];
|
||||
width = rightEdge - leftEdge;
|
||||
double value = unitStep(dataVec2[j]);
|
||||
double dev = std::fabs(dataVec1[i]-value);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(timeVec2[j] < timeVec1[i]){
|
||||
rightEdge = timeVec2[j];
|
||||
width = rightEdge - leftEdge;
|
||||
double value = unitStep(dataVec1[i]);
|
||||
double dev = std::fabs(dataVec2[j]-value);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return errorSum;
|
||||
}
|
||||
217
examples/test_util/summaryIntegrationTest.hpp
Normal file
217
examples/test_util/summaryIntegrationTest.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "summaryComparator.hpp"
|
||||
|
||||
//! \brief Struct for storing the total area under a graph.
|
||||
//! \details Used when plotting summary vector against time. In most cases this represents a volume.
|
||||
struct WellProductionVolume{
|
||||
double total=0; //!< The total area under the graph when plotting the summary vector against time. In most cases the total production volume.
|
||||
double error=0; //!< The total area under the graph when plotting the deviation vector against time. In most cases the total error volume.
|
||||
|
||||
//! \brief Overloaded operator
|
||||
//! \param[in] rhs WellProductionVolume struct
|
||||
WellProductionVolume& operator+=(const WellProductionVolume& rhs){
|
||||
this->total += rhs.total;
|
||||
this->error += rhs.error;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//! \details The class inherits from the SummaryComparator class, which takes care of all file reading. \n The IntegrationTest class compares values from the two different files and throws exceptions when the deviation is unsatisfying.
|
||||
class SummaryIntegrationTest: public SummaryComparator {
|
||||
private:
|
||||
bool allowSpikes = false; //!< Boolean value, when true checkForSpikes is included as a sub test in the integration test. By default: false.
|
||||
bool findVolumeError = false; //!< Boolean value, when true volumeErrorCheck() is included as a sub test in the integration test. By default: false.
|
||||
bool allowDifferentAmountOfKeywords = true; //!< Boolean value, when false the integration test will check wheter the two files have the same amount of keywords. \nIf they don't, an exception will be thrown. By default: true.
|
||||
bool findVectorWithGreatestErrorRatio = false; //!< Boolean value, when true the integration test will find the vector that has the greatest error ratio. By default: false.
|
||||
bool oneOfTheMainVariables = false; //!< Boolean value, when true the integration test will only check for one of the primary variables (WOPR, WGPR, WWPR. WBHP), which will be specified by user. By default: false.
|
||||
bool throwExceptionForTooGreatErrorRatio = true; //!< Boolean value, when true any volume error ratio that exceeds the relativeTolerance will cause an exception to be thrown. By default: true.
|
||||
std::string mainVariable; //!< String variable, where the name of the main variable of interest (one of WOPR, WBHP, WWPR, WGPR) is stored. Can be empty.
|
||||
int spikeLimit = 13370; //!< The limit for how many spikes to allow in the data set of a certain keyword. By default: Set to a high number, \n should not trig the (if spikeOccurrences > spikeLimit){ // throw exception }.
|
||||
|
||||
WellProductionVolume WOP; //!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WOPR
|
||||
WellProductionVolume WWP; //!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WWPR
|
||||
WellProductionVolume WGP;//!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WGPR
|
||||
WellProductionVolume WBHP; //!< WellProductionVolume struct for storing the value of the area under the graph when plotting summary vector/deviation vector against time.This is for keywords starting with WBHP. \nNote: the name of the struct may be misleading, this is not an actual volume.
|
||||
|
||||
|
||||
//! \brief The function gathers the correct data for comparison for a specific keyword
|
||||
//! \param[in] timeVec1 A std::vector<double> that contains the time steps of file 1.
|
||||
//! \param[in] timeVec2 A std::vector<double> that contains the time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \details The function requires an outer loop which iterates over the keywords of the files. It prepares an integration test by gathering the data, stroing it into two vectors, \n deciding which is to be used as a reference/basis and calling the test function.
|
||||
void checkForKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2, const char* keyword);
|
||||
|
||||
//! \brief The function compares the volume error to the total production volume of a certain type of keyword.
|
||||
//! param[in] keyword The keyword of interest.
|
||||
//! \details The function takes in a keyword and checks if it is of interest. Only keywords which say something about the well oil production, well water production, \n well gas production and the well BHP are of interest. The function sums up the total production in the cases where it is possible, \n and sums up the error volumes by a trapezoid integration method. The resulting values are stored in member variable structs of type WellProductionVolume, and double variables. For proper use of the function all the keywords of the file should be checked. This is satisfied if it is called by checkForKeyword.
|
||||
void volumeErrorCheck(const char* keyword);
|
||||
|
||||
//! \brief The function calculates the total production volume and total error volume of a specific keyword
|
||||
//! \param[in] timeVec1 A std::vector<double> that contains the time steps of file 1.
|
||||
//! \param[in] timeVec2 A std::vector<double> that contains the time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \param[out] ret Returns a WellProductionWolume struct
|
||||
//! \details The function reads the data from the two files into the member variable vectors (of the super class). It returns a WellProductionVolume struct calculated from the vectors corresponding to the keyword.
|
||||
WellProductionVolume getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword);
|
||||
|
||||
//! \brief The function is a regression test which allows spikes.
|
||||
//! \param[in] keyword The keyword of interest, the keyword the summary vectors "belong" to.
|
||||
//! \details The function requires the protected member variables referenceVec, referenceDataVec, checkVec and checkDataVec to be stored with data, which is staisfied if it is called by checkForKeyword. \n It compares the two vectors value by value, and if the deviation is unsatisfying, the errorOccurrenceCounter is incremented. If the errorOccurrenceCounter becomes greater than the errorOccurrenceLimit, \n a exception is thrown. The function will allow spike values, however, if two values in a row exceed the deviation limit, they are no longer spikes, and an exception is thrown.
|
||||
void checkWithSpikes(const char* keyword);
|
||||
|
||||
//! \brief Caluculates a deviation, throws exceptions and writes and error message.
|
||||
//! \param[in] deviation Deviation struct
|
||||
//! \param[out] int Returns 0/1, depending on wheter the deviation exceeded the limit or not.
|
||||
//! \details The function checks the values of the Deviation struct against the absolute and relative tolerance, which are private member values of the super class. \n When comparing against the relative tolerance an additional term is added, the absolute deviation has to be greater than 1e-6 for the function to throw an exception. \n When the deviations are too great, the function returns 1.
|
||||
int checkDeviation(const Deviation& deviation);
|
||||
|
||||
//! \brief Calculates the keyword's total production volume and error volume
|
||||
//! \param[in] keyword The keyword of interest.
|
||||
//! \param[out] wellProductionVolume A struct containing the total production volume and the total error volume.
|
||||
//! \details The function calculates the total production volume and total error volume of a keyword, by the trapezoid integral method. \n The function throws and exception if the total error volume is negative. The function returns the results as a struct.
|
||||
WellProductionVolume getWellProductionVolume(const char* keyword);
|
||||
|
||||
//! \brief The function function works properly when the private member variables are set (after running the integration test which findVolumeError = true). \n It prints out the total production volume, the total error volume and the error ratio.
|
||||
void evaluateWellProductionVolume();
|
||||
|
||||
//! \brief The function calculates the total production volume and total error volume
|
||||
//! \param keyword The keyword of interest
|
||||
//! \details The function uses the data that is stored in the member variable vectors. It calculates the total production volume \n and the total error volume of the specified keyword, and adds the result to the private member WellProductionVolume variables of the class.
|
||||
void updateVolumeError(const char* keyword);
|
||||
|
||||
//! \brief Finds the keyword which has the greates error volume ratio
|
||||
//! \param[in] volume WellProductionVolume struct which contains the data used for comparison
|
||||
//! \param[in] greatestRatio Double value taken in by reference. Stores the greatest error ratio value.
|
||||
//! \param[in] currentKeyword The keyword that is under evaluation
|
||||
//! \param[in] greatestErrorRatio String which contains the name of the keyword which has the greatest error ratio
|
||||
//! \details The function requires an outer loop which iterates over the keywords in the files, and calls the function for each keyword. \nThe valiables double greatestRatio and std::string keywordWithTheGreatestErrorRatio must be declared outside the loop. \nWhen the current error ratio is greater than the value stored in greatestRatio, the gratestRatio value is updated with the current error ratio.
|
||||
void findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
double &greatestRatio,
|
||||
const char* currentKeyword,
|
||||
std::string &greatestErrorRatio);
|
||||
|
||||
#if 0
|
||||
//! \brief Checks whether the unit of the two data vectors is the same
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \param[out] boolean True/false, depending on whether the units are equal or not
|
||||
bool checkUnits(const char* keyword);
|
||||
#endif
|
||||
public:
|
||||
//! \brief Constructor, creates an object of IntegrationTest class.
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \param[in] atol The absolute tolerance which is to be used in the test.
|
||||
//! \param[in] rtol The relative tolerance which is to be used in the test.
|
||||
//! \details The constructor calls the constructor of the super class.
|
||||
SummaryIntegrationTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double atol, double rtol) :
|
||||
SummaryComparator(basename1, basename2, atol, rtol) {}
|
||||
|
||||
//! \brief This function sets the private member variable allowSpikes.
|
||||
//! \param[in] allowSpikes Boolean value
|
||||
//! \details When allowSpikes is true, the integration test checkWithSpikes is excecuted.
|
||||
void setAllowSpikes(bool allowSpikesArg){this->allowSpikes = allowSpikesArg;}
|
||||
|
||||
//! \brief This function sets the private member variable findVolumeError.
|
||||
//! \param[in] findVolumeError Boolean value
|
||||
//! \details When findVolumeError is true, the integration test volumeErrorCheck and the function evaluateWellProductionVolume are excecuted.
|
||||
void setFindVolumeError(bool findVolumeErrorArg){this->findVolumeError = findVolumeErrorArg;}
|
||||
|
||||
//! \brief This function sets the private member variable oneOfTheMainVariables
|
||||
//! \param[in] oneOfTheMainVariables Boolean value
|
||||
//! \details When oneOfTheMainVariables is true, the integration test runs the substest volumeErrorCheckForOneSpecificVariable.
|
||||
void setOneOfTheMainVariables(bool oneOfTheMainVariablesArg){this->oneOfTheMainVariables = oneOfTheMainVariablesArg;}
|
||||
|
||||
//! \brief This function sets the member variable string #mainVariable
|
||||
//! \param[in] mainVar This is the string should contain one of the main variables. e.g. WOPR
|
||||
void setMainVariable(std::string mainVar){this->mainVariable = mainVar;}
|
||||
|
||||
//! \brief This function sets the private member variable spikeLimit.
|
||||
//! \param[in] lim The value which the spike limit is to be given.
|
||||
void setSpikeLimit(int lim){this->spikeLimit = lim;}
|
||||
|
||||
//! \brief This function sets the private member variable findVectorWithGreatestErrorRatio
|
||||
//! \param[in] findVolumeError Boolean value
|
||||
//! \details When findVectorWithGreatestErrorRatio is true, the integration test will print the vector with the greatest error ratio.
|
||||
void setFindVectorWithGreatestErrorRatio(bool boolean){this->findVectorWithGreatestErrorRatio = boolean;}
|
||||
|
||||
//! \brief This function sets the private member variable allowDifferentAmountsOfKeywords
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details When allowDifferentAmountOfKeywords is false, the amount of kewyord in the two files will be compared. \nIf the number of keywords are different an exception will be thrown.
|
||||
void setAllowDifferentAmountOfKeywords(bool boolean){this->allowDifferentAmountOfKeywords = boolean;}
|
||||
|
||||
//! \brief This function sets the private member variable throwExceptionForTooGreatErrorRatio
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details When throwExceptionForTooGreatErrorRatio is false, the function getWellProductionVolume will throw an exception.
|
||||
void setThrowExceptionForTooGreatErrorRatio(bool boolean){this->throwExceptionForTooGreatErrorRatio = boolean;}
|
||||
|
||||
//! \brief This function executes a integration test for all the keywords. If the two files do not match in amount of keywords, an exception is thrown. \n Uses the boolean member variables to know which tests to execute.
|
||||
void getIntegrationTest();
|
||||
|
||||
//! \brief This function executes a integration test for one specific keyword. If one or both of the files do not have the keyword, an exception is thorwn. \n Uses the boolean member variables to know which tests to execute.
|
||||
void getIntegrationTest(const char* keyword);
|
||||
|
||||
//! \brief This function calculates the area of an rectangle of height height and width time-timePrev
|
||||
//! \param[in] height The height of the rectangle. See important statement of use below.
|
||||
//! \param[in] width The width of the rectangle
|
||||
//! \param[out] area Returns the area of the rectangle
|
||||
//! \details This function is simple. When using it on a summary vector (data values plotted againt time), calculating the area between the two points i and i+1 note this:\nThe width is time_of_i+1 - time_of_i, the height is data_of_i+1 NOT data_of_i. The upper limit must be used.
|
||||
static double getRectangleArea(double height, double width){return height*width;}
|
||||
|
||||
//! \brief This function calculates the area under a graph by doing a Riemann sum
|
||||
//! \param[in] timeVec Contains the time values
|
||||
//! \param[in] dataVec Contains the data values
|
||||
//! \details The function does a Riemann sum integration of the graph formed
|
||||
//! by the points (timeVec[i] , dataVec[i]).
|
||||
//! In the case of a summary vector, the summary vector of quantity
|
||||
//! corresponding to a rate, is a piecewise continus function consisting
|
||||
//! of unit step functions. Thus the Riemann sum will become an
|
||||
//! exact expression for the integral of the graph.
|
||||
//! Important: For the data values correspoding to time i and i-1,
|
||||
//! the fixed value of the height of the rectangles in the Riemann sum
|
||||
//! is set by the data value i. The upper limit must be used.
|
||||
static double integrate(const std::vector<double>& timeVec,
|
||||
const std::vector<double>& dataVec);
|
||||
|
||||
//! \brief This function calculates the Riemann sum of the error between two graphs.
|
||||
//! \param[in] timeVec1 Contains the time values of graph 1
|
||||
//! \param[in] dataVec1 Contains the data values of graph 1
|
||||
//! \param[in] timeVec2 Contains the time values of graph 2
|
||||
//! \param[in] dataVec2 Contains the data values of graph 2
|
||||
//! \details This function takes in two graphs and returns the integrated error.
|
||||
//! In case of ecl summary vectors: if the vectors correspond to a
|
||||
//! quantity which is a rate, the vectors will be piecewise
|
||||
//! continous unit step functions. In this case the error will also
|
||||
//! be a piecewise continous unit step function. The function uses
|
||||
//! a Riemann sum when calculating the integral. Thus the integral
|
||||
//! will become exact. Important: For the data values corresponding
|
||||
//! to time i and i-1, the fixed value of the height of the rectangles
|
||||
//! in the Riemann sum is set by the data value i.
|
||||
//! The upper limit must be used.
|
||||
static double integrateError(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec2);
|
||||
};
|
||||
171
examples/test_util/summaryRegressionTest.cpp
Normal file
171
examples/test_util/summaryRegressionTest.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "summaryRegressionTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <string>
|
||||
|
||||
void SummaryRegressionTest::getRegressionTest(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2); //Figures which dataset that contains more/less values pr keyword vector.
|
||||
std::cout << "Comparing " << timeVec1.size() << " steps." << std::endl;
|
||||
int ivar = 0;
|
||||
if(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)){
|
||||
int missing_count = 0;
|
||||
std::cout << "Keywords missing from one case: " << std::endl;
|
||||
|
||||
for (int i=0; i < stringlist_get_size( keysLong); i++) {
|
||||
const char * key = stringlist_iget( keysLong , i );
|
||||
if (!stringlist_contains( keysShort , key)) {
|
||||
std::cout << key << " ";
|
||||
|
||||
missing_count++;
|
||||
if ((missing_count % 8) == 0)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
HANDLE_ERROR(std::runtime_error, "Different amount of keywords in the two summary files.");
|
||||
}
|
||||
if(printKeyword){
|
||||
printKeywords();
|
||||
}
|
||||
|
||||
|
||||
//Iterates over all keywords from the restricted file, use iterator "ivar". Searches for a match in the file with more keywords, use the iterator "jvar".
|
||||
bool throwAtEnd = false;
|
||||
while(ivar < stringlist_get_size(keysShort)){
|
||||
const char* keyword = stringlist_iget(keysShort, ivar);
|
||||
std::string keywordString(keyword);
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
if (strcmp(keyword, stringlist_iget(keysLong, jvar)) == 0){ //When the keywords are equal, proceed in comparing summary files.
|
||||
if (isRestartFile && keywordString.substr(3,1)=="T"){
|
||||
break;
|
||||
}
|
||||
throwAtEnd |= !checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
break;
|
||||
}
|
||||
//will only enter here if no keyword match
|
||||
if(jvar == stringlist_get_size(keysLong)-1){
|
||||
std::cout << "Could not find keyword: " << stringlist_iget(keysShort, ivar) << std::endl;
|
||||
OPM_THROW(std::runtime_error, "No match on keyword");
|
||||
}
|
||||
}
|
||||
ivar++;
|
||||
}
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " summary keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
size_t len = ecl_sum_get_data_length(ecl_sum1);
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " / " << len << " steps." << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
if (throwAtEnd)
|
||||
OPM_THROW(std::runtime_error, "Regression test failed.");
|
||||
else if (deviations.empty())
|
||||
std::cout << "Regression test succeeded." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SummaryRegressionTest::getRegressionTest(const char* keyword){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2); //Figures which dataset that contains more/less values pr keyword vector.
|
||||
std::string keywordString(keyword);
|
||||
if(stringlist_contains(keysShort,keyword) && stringlist_contains(keysLong, keyword)){
|
||||
if (isRestartFile && keywordString.substr(3,1)=="T"){
|
||||
return;
|
||||
}
|
||||
if (checkForKeyword(timeVec1, timeVec2, keyword))
|
||||
std::cout << "Regression test succeeded." << std::endl;
|
||||
else
|
||||
OPM_THROW(std::runtime_error, "Regression test failed");
|
||||
|
||||
return;
|
||||
}
|
||||
std::cout << "The keyword suggested, " << keyword << ", is not supported by one or both of the summary files. Please use a different keyword." << std::endl;
|
||||
OPM_THROW(std::runtime_error, "Input keyword from user does not exist in/is not common for the two summary files.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SummaryRegressionTest::checkDeviation(Deviation deviation, const char* keyword, int refIndex, int checkIndex){
|
||||
double absTol = getAbsTolerance();
|
||||
double relTol = getRelTolerance();
|
||||
|
||||
if (deviation.rel > relTol && deviation.abs > absTol){
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(deviation);
|
||||
} else {
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
std::cout << "(days, reference value) and (days, check value) = (" << (*referenceVec)[refIndex] << ", " << (*referenceDataVec)[refIndex]
|
||||
<< ") and (" << (*checkVec)[checkIndex-1] << ", " << (*checkDataVec)[checkIndex-1] << ")\n";
|
||||
// -1 in [checkIndex -1] because checkIndex is updated after leaving getDeviation function
|
||||
std::cout << "The absolute deviation is " << deviation.abs << ". The tolerance limit is " << absTol << std::endl;
|
||||
std::cout << "The relative deviation is " << deviation.rel << ". The tolerance limit is " << relTol << std::endl;
|
||||
HANDLE_ERROR(std::runtime_error, "Deviation exceed the limit.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SummaryRegressionTest::checkForKeyword(std::vector<double>& timeVec1, std::vector<double>& timeVec2, const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
return startTest(keyword);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SummaryRegressionTest::startTest(const char* keyword){
|
||||
size_t jvar = 0;
|
||||
Deviation deviation;
|
||||
bool result = true;
|
||||
for (size_t ivar = 0; ivar < referenceVec->size(); ivar++){
|
||||
getDeviation(ivar, jvar, deviation);//Reads from the protected member variables in the super class.
|
||||
result = checkDeviation(deviation, keyword,ivar, jvar);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
74
examples/test_util/summaryRegressionTest.hpp
Normal file
74
examples/test_util/summaryRegressionTest.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SUMMARYREGRESSIONTEST_HPP
|
||||
#define SUMMARYREGRESSIONTEST_HPP
|
||||
|
||||
#include "summaryComparator.hpp"
|
||||
|
||||
//! \details The class inherits from the SummaryComparator class, which takes care of all file reading. \n The RegressionTest class compares the values from the two different files and throws exceptions when the deviation is unsatisfying.
|
||||
class SummaryRegressionTest: public SummaryComparator {
|
||||
private:
|
||||
//! \brief Gathers the correct data for comparison for a specific keyword
|
||||
//! \param[in] timeVec1 The time steps of file 1.
|
||||
//! \param[in] timeVec2 The time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \details The function prepares a regression test by gathering the data, stroing it into two vectors, \n deciding which is to be used as a reference/basis and calling the test function.
|
||||
//! \return True if check passed, false otherwise.
|
||||
bool checkForKeyword(std::vector<double>& timeVec1, std::vector<double>& timeVec2, const char* keyword);
|
||||
|
||||
//! \brief The regression test
|
||||
//! \param[in] keyword The keyword common for both the files. The vectors associated with the keyword are used for comparison.
|
||||
//! \details Start test uses the private member variables, pointers of std::vector<double> type, which are set to point to the correct vectors in SummaryComparison::chooseReference(...). \n The function iterates over the referenceVev/basis and for each iteration it calculates the deviation with SummaryComparison::getDeviation(..) and stors it in a Deviation struct. \n SummaryComparison::getDeviation takes the int jvar as an reference input, and using it as an iterative index for the values which are to be compared with the basis. \n Thus, by updating the jvar variable every time a deviation is calculated, one keep track jvar and do not have to iterate over already checked values.
|
||||
bool startTest(const char* keyword);
|
||||
|
||||
//! \brief Caluculates a deviation, throws exceptions and writes and error message.
|
||||
//! \param[in] deviation Deviation struct
|
||||
//! \param[in] keyword The keyword that the data that are being compared belongs to.
|
||||
//! \param[in] refIndex The report step of which the deviation originates from in #referenceDataVec.
|
||||
//! \param[in] checkIndex The report step of which the deviation originates from in #checkDataVec.
|
||||
//! \details The function checks the values of the Deviation struct against the absolute and relative tolerance, which are private member values of the super class. \n When comparing against the relative tolerance an additional term is added, the absolute deviation has to be greater than 1e-6 for the function to throw an exception. \n When the deviations are too great, the function writes out which keyword, and at what report step the deviation is too great before optionally throwing an exception.
|
||||
//! \return True if check passed, false otherwise.
|
||||
bool checkDeviation(Deviation deviation, const char* keyword, int refIndex, int checkIndex);
|
||||
|
||||
bool isRestartFile = false; //!< Private member variable, when true the files that are being compared is a restart file vs a normal file
|
||||
public:
|
||||
//! \brief Constructor, creates an object of RefressionTest class.
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \param[in] relativeTol The relative tolerance which is to be used in the test.
|
||||
//! \param[in] absoluteTol The absolute tolerance which is to be used in the test.
|
||||
//! \details The constructor calls the constructor of the super class.
|
||||
SummaryRegressionTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double relativeTol, double absoluteTol) :
|
||||
SummaryComparator(basename1, basename2, relativeTol, absoluteTol) {}
|
||||
|
||||
//! \details The function executes a regression test for all the keywords. If the two files do not match in amount of keywords, an exception is thrown.
|
||||
void getRegressionTest();
|
||||
|
||||
//! \details The function executes a regression test for one specific keyword. If one or both of the files do not have the keyword, an exception is thrown.
|
||||
void getRegressionTest(const char* keyword);///< Regression test for a certain keyword of the files.
|
||||
|
||||
//! \brief This function sets the private member variable isRestartFiles
|
||||
//! \param[in] boolean Boolean value
|
||||
void setIsRestartFile(bool boolean){this->isRestartFile = boolean;}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
Copyright 2013, 2020 Equinor 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/Python/Python.hpp>
|
||||
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
#include <opm/common/OpmLog/StreamLog.hpp>
|
||||
#include <opm/common/OpmLog/LogUtil.hpp>
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
|
||||
|
||||
inline void createDot(const Opm::Schedule& schedule, const std::string& casename)
|
||||
{
|
||||
std::cout << "Writing " << casename << ".gv .... "; std::cout.flush();
|
||||
std::ofstream os(casename + ".gv");
|
||||
os << "// This file was written by the 'wellgraph' utility from OPM.\n";
|
||||
os << "// Find the source code at github.com/OPM.\n";
|
||||
os << "// Convert output to PDF with 'dot -Tpdf " << casename << ".gv > " << casename << ".pdf'\n";
|
||||
os << "strict digraph \"" << casename << "\"\n{\n";
|
||||
const auto groupnames = schedule.groupNames();
|
||||
const std::size_t last = schedule.size() - 1;
|
||||
// Group -> Group relations.
|
||||
for (const auto& gn : groupnames) {
|
||||
const auto& g = schedule.getGroup(gn, last);
|
||||
const auto& children = g.groups();
|
||||
if (!children.empty()) {
|
||||
os << " \"" << gn << "\" -> {";
|
||||
for (const auto& child : children) {
|
||||
os << " \"" << child << '"';
|
||||
}
|
||||
os << " }\n";
|
||||
}
|
||||
}
|
||||
// Group -> Well relations.
|
||||
os << " node [shape=box]\n";
|
||||
for (const auto& gn : groupnames) {
|
||||
const auto& g = schedule.getGroup(gn, last);
|
||||
const auto& children = g.wells();
|
||||
if (!children.empty()) {
|
||||
os << " \"" << gn << "\" -> {";
|
||||
for (const auto& child : children) {
|
||||
os << " \"" << child << '"';
|
||||
}
|
||||
os << " }\n";
|
||||
}
|
||||
}
|
||||
// Color wells by injector or producer.
|
||||
for (const auto& w : schedule.getWellsatEnd()) {
|
||||
os << " \"" << w.name() << '"';
|
||||
if (w.isProducer() && w.isInjector()) {
|
||||
os << " [color=purple]\n";
|
||||
} else if (w.isProducer()) {
|
||||
os << " [color=red]\n";
|
||||
} else {
|
||||
os << " [color=blue]\n";
|
||||
}
|
||||
}
|
||||
os << "}\n";
|
||||
std::cout << "complete." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
inline Opm::Schedule loadSchedule(const std::string& deck_file)
|
||||
{
|
||||
Opm::ParseContext parseContext({{Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputError::IGNORE},
|
||||
{Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputError::WARN},
|
||||
{Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputError::WARN},
|
||||
{Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputError::WARN}});
|
||||
Opm::ErrorGuard errors;
|
||||
Opm::Parser parser;
|
||||
auto python = std::make_shared<Opm::Python>();
|
||||
|
||||
std::cout << "Loading and parsing deck: " << deck_file << " ..... "; std::cout.flush();
|
||||
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
||||
std::cout << "complete.\n";
|
||||
|
||||
std::cout << "Creating EclipseState .... "; std::cout.flush();
|
||||
Opm::EclipseState state( deck );
|
||||
std::cout << "complete.\n";
|
||||
|
||||
std::cout << "Creating Schedule .... "; std::cout.flush();
|
||||
Opm::Schedule schedule( deck, state, python);
|
||||
std::cout << "complete." << std::endl;
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ostringstream os;
|
||||
std::shared_ptr<Opm::StreamLog> string_log = std::make_shared<Opm::StreamLog>(os, Opm::Log::DefaultMessageTypes);
|
||||
Opm::OpmLog::addBackend( "STRING" , string_log);
|
||||
try {
|
||||
for (int iarg = 1; iarg < argc; iarg++) {
|
||||
const std::string filename = argv[iarg];
|
||||
const auto sched = loadSchedule(filename);
|
||||
const auto casename = Opm::filesystem::path(filename).stem();
|
||||
createDot(sched, casename);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cout << "\n\n***** Caught an exception: " << e.what() << std::endl;
|
||||
std::cout << "\n\n***** Printing log: "<< std::endl;
|
||||
std::cout << os.str();
|
||||
std::cout << "\n\n***** Exiting due to errors." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
4
external/cjson/README.opm
vendored
4
external/cjson/README.opm
vendored
@@ -1,2 +1,4 @@
|
||||
This directory contains the the 1.7.10 version of the cJSON package from https://github.com/DaveGamble/cJSON
|
||||
This directory contains the cJSON package downloaded unchanged from:
|
||||
http://sourceforge.net/projects/cjson/. The cJSON package is plain C,
|
||||
the JsonObject class provides a minimal C++ wrapping of this.
|
||||
|
||||
|
||||
3165
external/cjson/cJSON.c
vendored
3165
external/cjson/cJSON.c
vendored
File diff suppressed because it is too large
Load Diff
290
external/cjson/cJSON.h
vendored
290
external/cjson/cJSON.h
vendored
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
@@ -23,260 +23,118 @@
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 10
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
27
external/fmtlib/LICENSE.rst
vendored
27
external/fmtlib/LICENSE.rst
vendored
@@ -1,27 +0,0 @@
|
||||
Copyright (c) 2012 - present, Victor Zverovich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--- Optional exception to the license ---
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into a machine-executable object form of such
|
||||
source code, you may redistribute such embedded portions in such object form
|
||||
without including the above copyright and permission notices.
|
||||
12
external/fmtlib/README.opm
vendored
12
external/fmtlib/README.opm
vendored
@@ -1,12 +0,0 @@
|
||||
The include/ directory is a copy of the include directory from version 7.0.3 of
|
||||
the fmtlib distribution. The fmtlib can be found at https://github.com/fmtlib/fmt
|
||||
|
||||
The fmtlib code embedded here should be compiled in header only mode, to ensure
|
||||
that the symbol FMT_HEADER_ONLY must be defined before the the fmt/format.h
|
||||
header is included:
|
||||
|
||||
#define FMT_HEADER_ONLY
|
||||
#include <fmt/format.h>
|
||||
|
||||
....
|
||||
auto msg = fmt::format("Hello {}", "world");
|
||||
1123
external/fmtlib/include/fmt/chrono.h
vendored
1123
external/fmtlib/include/fmt/chrono.h
vendored
File diff suppressed because it is too large
Load Diff
566
external/fmtlib/include/fmt/color.h
vendored
566
external/fmtlib/include/fmt/color.h
vendored
@@ -1,566 +0,0 @@
|
||||
// Formatting library for C++ - color support
|
||||
//
|
||||
// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_COLOR_H_
|
||||
#define FMT_COLOR_H_
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
enum class color : uint32_t {
|
||||
alice_blue = 0xF0F8FF, // rgb(240,248,255)
|
||||
antique_white = 0xFAEBD7, // rgb(250,235,215)
|
||||
aqua = 0x00FFFF, // rgb(0,255,255)
|
||||
aquamarine = 0x7FFFD4, // rgb(127,255,212)
|
||||
azure = 0xF0FFFF, // rgb(240,255,255)
|
||||
beige = 0xF5F5DC, // rgb(245,245,220)
|
||||
bisque = 0xFFE4C4, // rgb(255,228,196)
|
||||
black = 0x000000, // rgb(0,0,0)
|
||||
blanched_almond = 0xFFEBCD, // rgb(255,235,205)
|
||||
blue = 0x0000FF, // rgb(0,0,255)
|
||||
blue_violet = 0x8A2BE2, // rgb(138,43,226)
|
||||
brown = 0xA52A2A, // rgb(165,42,42)
|
||||
burly_wood = 0xDEB887, // rgb(222,184,135)
|
||||
cadet_blue = 0x5F9EA0, // rgb(95,158,160)
|
||||
chartreuse = 0x7FFF00, // rgb(127,255,0)
|
||||
chocolate = 0xD2691E, // rgb(210,105,30)
|
||||
coral = 0xFF7F50, // rgb(255,127,80)
|
||||
cornflower_blue = 0x6495ED, // rgb(100,149,237)
|
||||
cornsilk = 0xFFF8DC, // rgb(255,248,220)
|
||||
crimson = 0xDC143C, // rgb(220,20,60)
|
||||
cyan = 0x00FFFF, // rgb(0,255,255)
|
||||
dark_blue = 0x00008B, // rgb(0,0,139)
|
||||
dark_cyan = 0x008B8B, // rgb(0,139,139)
|
||||
dark_golden_rod = 0xB8860B, // rgb(184,134,11)
|
||||
dark_gray = 0xA9A9A9, // rgb(169,169,169)
|
||||
dark_green = 0x006400, // rgb(0,100,0)
|
||||
dark_khaki = 0xBDB76B, // rgb(189,183,107)
|
||||
dark_magenta = 0x8B008B, // rgb(139,0,139)
|
||||
dark_olive_green = 0x556B2F, // rgb(85,107,47)
|
||||
dark_orange = 0xFF8C00, // rgb(255,140,0)
|
||||
dark_orchid = 0x9932CC, // rgb(153,50,204)
|
||||
dark_red = 0x8B0000, // rgb(139,0,0)
|
||||
dark_salmon = 0xE9967A, // rgb(233,150,122)
|
||||
dark_sea_green = 0x8FBC8F, // rgb(143,188,143)
|
||||
dark_slate_blue = 0x483D8B, // rgb(72,61,139)
|
||||
dark_slate_gray = 0x2F4F4F, // rgb(47,79,79)
|
||||
dark_turquoise = 0x00CED1, // rgb(0,206,209)
|
||||
dark_violet = 0x9400D3, // rgb(148,0,211)
|
||||
deep_pink = 0xFF1493, // rgb(255,20,147)
|
||||
deep_sky_blue = 0x00BFFF, // rgb(0,191,255)
|
||||
dim_gray = 0x696969, // rgb(105,105,105)
|
||||
dodger_blue = 0x1E90FF, // rgb(30,144,255)
|
||||
fire_brick = 0xB22222, // rgb(178,34,34)
|
||||
floral_white = 0xFFFAF0, // rgb(255,250,240)
|
||||
forest_green = 0x228B22, // rgb(34,139,34)
|
||||
fuchsia = 0xFF00FF, // rgb(255,0,255)
|
||||
gainsboro = 0xDCDCDC, // rgb(220,220,220)
|
||||
ghost_white = 0xF8F8FF, // rgb(248,248,255)
|
||||
gold = 0xFFD700, // rgb(255,215,0)
|
||||
golden_rod = 0xDAA520, // rgb(218,165,32)
|
||||
gray = 0x808080, // rgb(128,128,128)
|
||||
green = 0x008000, // rgb(0,128,0)
|
||||
green_yellow = 0xADFF2F, // rgb(173,255,47)
|
||||
honey_dew = 0xF0FFF0, // rgb(240,255,240)
|
||||
hot_pink = 0xFF69B4, // rgb(255,105,180)
|
||||
indian_red = 0xCD5C5C, // rgb(205,92,92)
|
||||
indigo = 0x4B0082, // rgb(75,0,130)
|
||||
ivory = 0xFFFFF0, // rgb(255,255,240)
|
||||
khaki = 0xF0E68C, // rgb(240,230,140)
|
||||
lavender = 0xE6E6FA, // rgb(230,230,250)
|
||||
lavender_blush = 0xFFF0F5, // rgb(255,240,245)
|
||||
lawn_green = 0x7CFC00, // rgb(124,252,0)
|
||||
lemon_chiffon = 0xFFFACD, // rgb(255,250,205)
|
||||
light_blue = 0xADD8E6, // rgb(173,216,230)
|
||||
light_coral = 0xF08080, // rgb(240,128,128)
|
||||
light_cyan = 0xE0FFFF, // rgb(224,255,255)
|
||||
light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210)
|
||||
light_gray = 0xD3D3D3, // rgb(211,211,211)
|
||||
light_green = 0x90EE90, // rgb(144,238,144)
|
||||
light_pink = 0xFFB6C1, // rgb(255,182,193)
|
||||
light_salmon = 0xFFA07A, // rgb(255,160,122)
|
||||
light_sea_green = 0x20B2AA, // rgb(32,178,170)
|
||||
light_sky_blue = 0x87CEFA, // rgb(135,206,250)
|
||||
light_slate_gray = 0x778899, // rgb(119,136,153)
|
||||
light_steel_blue = 0xB0C4DE, // rgb(176,196,222)
|
||||
light_yellow = 0xFFFFE0, // rgb(255,255,224)
|
||||
lime = 0x00FF00, // rgb(0,255,0)
|
||||
lime_green = 0x32CD32, // rgb(50,205,50)
|
||||
linen = 0xFAF0E6, // rgb(250,240,230)
|
||||
magenta = 0xFF00FF, // rgb(255,0,255)
|
||||
maroon = 0x800000, // rgb(128,0,0)
|
||||
medium_aquamarine = 0x66CDAA, // rgb(102,205,170)
|
||||
medium_blue = 0x0000CD, // rgb(0,0,205)
|
||||
medium_orchid = 0xBA55D3, // rgb(186,85,211)
|
||||
medium_purple = 0x9370DB, // rgb(147,112,219)
|
||||
medium_sea_green = 0x3CB371, // rgb(60,179,113)
|
||||
medium_slate_blue = 0x7B68EE, // rgb(123,104,238)
|
||||
medium_spring_green = 0x00FA9A, // rgb(0,250,154)
|
||||
medium_turquoise = 0x48D1CC, // rgb(72,209,204)
|
||||
medium_violet_red = 0xC71585, // rgb(199,21,133)
|
||||
midnight_blue = 0x191970, // rgb(25,25,112)
|
||||
mint_cream = 0xF5FFFA, // rgb(245,255,250)
|
||||
misty_rose = 0xFFE4E1, // rgb(255,228,225)
|
||||
moccasin = 0xFFE4B5, // rgb(255,228,181)
|
||||
navajo_white = 0xFFDEAD, // rgb(255,222,173)
|
||||
navy = 0x000080, // rgb(0,0,128)
|
||||
old_lace = 0xFDF5E6, // rgb(253,245,230)
|
||||
olive = 0x808000, // rgb(128,128,0)
|
||||
olive_drab = 0x6B8E23, // rgb(107,142,35)
|
||||
orange = 0xFFA500, // rgb(255,165,0)
|
||||
orange_red = 0xFF4500, // rgb(255,69,0)
|
||||
orchid = 0xDA70D6, // rgb(218,112,214)
|
||||
pale_golden_rod = 0xEEE8AA, // rgb(238,232,170)
|
||||
pale_green = 0x98FB98, // rgb(152,251,152)
|
||||
pale_turquoise = 0xAFEEEE, // rgb(175,238,238)
|
||||
pale_violet_red = 0xDB7093, // rgb(219,112,147)
|
||||
papaya_whip = 0xFFEFD5, // rgb(255,239,213)
|
||||
peach_puff = 0xFFDAB9, // rgb(255,218,185)
|
||||
peru = 0xCD853F, // rgb(205,133,63)
|
||||
pink = 0xFFC0CB, // rgb(255,192,203)
|
||||
plum = 0xDDA0DD, // rgb(221,160,221)
|
||||
powder_blue = 0xB0E0E6, // rgb(176,224,230)
|
||||
purple = 0x800080, // rgb(128,0,128)
|
||||
rebecca_purple = 0x663399, // rgb(102,51,153)
|
||||
red = 0xFF0000, // rgb(255,0,0)
|
||||
rosy_brown = 0xBC8F8F, // rgb(188,143,143)
|
||||
royal_blue = 0x4169E1, // rgb(65,105,225)
|
||||
saddle_brown = 0x8B4513, // rgb(139,69,19)
|
||||
salmon = 0xFA8072, // rgb(250,128,114)
|
||||
sandy_brown = 0xF4A460, // rgb(244,164,96)
|
||||
sea_green = 0x2E8B57, // rgb(46,139,87)
|
||||
sea_shell = 0xFFF5EE, // rgb(255,245,238)
|
||||
sienna = 0xA0522D, // rgb(160,82,45)
|
||||
silver = 0xC0C0C0, // rgb(192,192,192)
|
||||
sky_blue = 0x87CEEB, // rgb(135,206,235)
|
||||
slate_blue = 0x6A5ACD, // rgb(106,90,205)
|
||||
slate_gray = 0x708090, // rgb(112,128,144)
|
||||
snow = 0xFFFAFA, // rgb(255,250,250)
|
||||
spring_green = 0x00FF7F, // rgb(0,255,127)
|
||||
steel_blue = 0x4682B4, // rgb(70,130,180)
|
||||
tan = 0xD2B48C, // rgb(210,180,140)
|
||||
teal = 0x008080, // rgb(0,128,128)
|
||||
thistle = 0xD8BFD8, // rgb(216,191,216)
|
||||
tomato = 0xFF6347, // rgb(255,99,71)
|
||||
turquoise = 0x40E0D0, // rgb(64,224,208)
|
||||
violet = 0xEE82EE, // rgb(238,130,238)
|
||||
wheat = 0xF5DEB3, // rgb(245,222,179)
|
||||
white = 0xFFFFFF, // rgb(255,255,255)
|
||||
white_smoke = 0xF5F5F5, // rgb(245,245,245)
|
||||
yellow = 0xFFFF00, // rgb(255,255,0)
|
||||
yellow_green = 0x9ACD32 // rgb(154,205,50)
|
||||
}; // enum class color
|
||||
|
||||
enum class terminal_color : uint8_t {
|
||||
black = 30,
|
||||
red,
|
||||
green,
|
||||
yellow,
|
||||
blue,
|
||||
magenta,
|
||||
cyan,
|
||||
white,
|
||||
bright_black = 90,
|
||||
bright_red,
|
||||
bright_green,
|
||||
bright_yellow,
|
||||
bright_blue,
|
||||
bright_magenta,
|
||||
bright_cyan,
|
||||
bright_white
|
||||
};
|
||||
|
||||
enum class emphasis : uint8_t {
|
||||
bold = 1,
|
||||
italic = 1 << 1,
|
||||
underline = 1 << 2,
|
||||
strikethrough = 1 << 3
|
||||
};
|
||||
|
||||
// rgb is a struct for red, green and blue colors.
|
||||
// Using the name "rgb" makes some editors show the color in a tooltip.
|
||||
struct rgb {
|
||||
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {}
|
||||
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
|
||||
FMT_CONSTEXPR rgb(uint32_t hex)
|
||||
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
|
||||
FMT_CONSTEXPR rgb(color hex)
|
||||
: r((uint32_t(hex) >> 16) & 0xFF),
|
||||
g((uint32_t(hex) >> 8) & 0xFF),
|
||||
b(uint32_t(hex) & 0xFF) {}
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// color is a struct of either a rgb color or a terminal color.
|
||||
struct color_type {
|
||||
FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {}
|
||||
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true),
|
||||
value{} {
|
||||
value.rgb_color = static_cast<uint32_t>(rgb_color);
|
||||
}
|
||||
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} {
|
||||
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) |
|
||||
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
|
||||
}
|
||||
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(),
|
||||
value{} {
|
||||
value.term_color = static_cast<uint8_t>(term_color);
|
||||
}
|
||||
bool is_rgb;
|
||||
union color_union {
|
||||
uint8_t term_color;
|
||||
uint32_t rgb_color;
|
||||
} value;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
// Experimental text formatting support.
|
||||
class text_style {
|
||||
public:
|
||||
FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT
|
||||
: set_foreground_color(),
|
||||
set_background_color(),
|
||||
ems(em) {}
|
||||
|
||||
FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) {
|
||||
if (!set_foreground_color) {
|
||||
set_foreground_color = rhs.set_foreground_color;
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
if (!set_background_color) {
|
||||
set_background_color = rhs.set_background_color;
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) |
|
||||
static_cast<uint8_t>(rhs.ems));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
|
||||
const text_style& rhs) {
|
||||
return lhs |= rhs;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style& operator&=(const text_style& rhs) {
|
||||
if (!set_foreground_color) {
|
||||
set_foreground_color = rhs.set_foreground_color;
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
if (!set_background_color) {
|
||||
set_background_color = rhs.set_background_color;
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
background_color.value.rgb_color &= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) &
|
||||
static_cast<uint8_t>(rhs.ems));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR text_style operator&(text_style lhs,
|
||||
const text_style& rhs) {
|
||||
return lhs &= rhs;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT {
|
||||
return set_foreground_color;
|
||||
}
|
||||
FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT {
|
||||
return set_background_color;
|
||||
}
|
||||
FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT {
|
||||
return static_cast<uint8_t>(ems) != 0;
|
||||
}
|
||||
FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_foreground(), "no foreground specified for this style");
|
||||
return foreground_color;
|
||||
}
|
||||
FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_background(), "no background specified for this style");
|
||||
return background_color;
|
||||
}
|
||||
FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
|
||||
return ems;
|
||||
}
|
||||
|
||||
private:
|
||||
FMT_CONSTEXPR text_style(bool is_foreground,
|
||||
detail::color_type text_color) FMT_NOEXCEPT
|
||||
: set_foreground_color(),
|
||||
set_background_color(),
|
||||
ems() {
|
||||
if (is_foreground) {
|
||||
foreground_color = text_color;
|
||||
set_foreground_color = true;
|
||||
} else {
|
||||
background_color = text_color;
|
||||
set_background_color = true;
|
||||
}
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground)
|
||||
FMT_NOEXCEPT;
|
||||
friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background)
|
||||
FMT_NOEXCEPT;
|
||||
|
||||
detail::color_type foreground_color;
|
||||
detail::color_type background_color;
|
||||
bool set_foreground_color;
|
||||
bool set_background_color;
|
||||
emphasis ems;
|
||||
};
|
||||
|
||||
FMT_CONSTEXPR text_style fg(detail::color_type foreground) FMT_NOEXCEPT {
|
||||
return text_style(/*is_foreground=*/true, foreground);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style bg(detail::color_type background) FMT_NOEXCEPT {
|
||||
return text_style(/*is_foreground=*/false, background);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style operator|(emphasis lhs, emphasis rhs) FMT_NOEXCEPT {
|
||||
return text_style(lhs) | rhs;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Char> struct ansi_color_escape {
|
||||
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
|
||||
const char* esc) FMT_NOEXCEPT {
|
||||
// If we have a terminal color, we need to output another escape code
|
||||
// sequence.
|
||||
if (!text_color.is_rgb) {
|
||||
bool is_background = esc == detail::data::background_color;
|
||||
uint32_t value = text_color.value.term_color;
|
||||
// Background ASCII codes are the same as the foreground ones but with
|
||||
// 10 more.
|
||||
if (is_background) value += 10u;
|
||||
|
||||
size_t index = 0;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
|
||||
if (value >= 100u) {
|
||||
buffer[index++] = static_cast<Char>('1');
|
||||
value %= 100u;
|
||||
}
|
||||
buffer[index++] = static_cast<Char>('0' + value / 10u);
|
||||
buffer[index++] = static_cast<Char>('0' + value % 10u);
|
||||
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
buffer[index++] = static_cast<Char>('\0');
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
buffer[i] = static_cast<Char>(esc[i]);
|
||||
}
|
||||
rgb color(text_color.value.rgb_color);
|
||||
to_esc(color.r, buffer + 7, ';');
|
||||
to_esc(color.g, buffer + 11, ';');
|
||||
to_esc(color.b, buffer + 15, 'm');
|
||||
buffer[19] = static_cast<Char>(0);
|
||||
}
|
||||
FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT {
|
||||
uint8_t em_codes[4] = {};
|
||||
uint8_t em_bits = static_cast<uint8_t>(em);
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::bold)) em_codes[0] = 1;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[1] = 3;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[2] = 4;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::strikethrough))
|
||||
em_codes[3] = 9;
|
||||
|
||||
size_t index = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!em_codes[i]) continue;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
}
|
||||
buffer[index++] = static_cast<Char>(0);
|
||||
}
|
||||
FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; }
|
||||
|
||||
FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; }
|
||||
FMT_CONSTEXPR const Char* end() const FMT_NOEXCEPT {
|
||||
return buffer + std::char_traits<Char>::length(buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
Char buffer[7u + 3u * 4u + 1u];
|
||||
|
||||
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
|
||||
char delimiter) FMT_NOEXCEPT {
|
||||
out[0] = static_cast<Char>('0' + c / 100);
|
||||
out[1] = static_cast<Char>('0' + c / 10 % 10);
|
||||
out[2] = static_cast<Char>('0' + c % 10);
|
||||
out[3] = static_cast<Char>(delimiter);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
|
||||
detail::color_type foreground) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(foreground, detail::data::foreground_color);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
|
||||
detail::color_type background) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(background, detail::data::background_color);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(em);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT {
|
||||
std::fputs(chars, stream);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void fputs<wchar_t>(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT {
|
||||
std::fputws(chars, stream);
|
||||
}
|
||||
|
||||
template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT {
|
||||
fputs(detail::data::reset_color, stream);
|
||||
}
|
||||
|
||||
template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT {
|
||||
fputs(detail::data::wreset_color, stream);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void reset_color(basic_memory_buffer<Char>& buffer) FMT_NOEXCEPT {
|
||||
const char* begin = data::reset_color;
|
||||
const char* end = begin + sizeof(data::reset_color) - 1;
|
||||
buffer.append(begin, end);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(basic_memory_buffer<Char>& buf, const text_style& ts,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<Char>> args) {
|
||||
bool has_style = false;
|
||||
if (ts.has_emphasis()) {
|
||||
has_style = true;
|
||||
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
|
||||
buf.append(emphasis.begin(), emphasis.end());
|
||||
}
|
||||
if (ts.has_foreground()) {
|
||||
has_style = true;
|
||||
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
|
||||
buf.append(foreground.begin(), foreground.end());
|
||||
}
|
||||
if (ts.has_background()) {
|
||||
has_style = true;
|
||||
auto background = detail::make_background_color<Char>(ts.get_background());
|
||||
buf.append(background.begin(), background.end());
|
||||
}
|
||||
detail::vformat_to(buf, format_str, args);
|
||||
if (has_style) detail::reset_color<Char>(buf);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
void vprint(std::FILE* f, const text_style& ts, const S& format,
|
||||
basic_format_args<buffer_context<Char>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
detail::vformat_to(buf, ts, to_string_view(format), args);
|
||||
buf.push_back(Char(0));
|
||||
detail::fputs(buf.data(), f);
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string and prints it to the specified file stream using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
Example:
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(std::FILE* f, const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
detail::check_format_string<Args...>(format_str);
|
||||
using context = buffer_context<char_t<S>>;
|
||||
format_arg_store<context, Args...> as{args...};
|
||||
vprint(f, ts, format_str, basic_format_args<context>(as));
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string and prints it to stdout using ANSI escape sequences to
|
||||
specify text formatting.
|
||||
Example:
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(const text_style& ts, const S& format_str, const Args&... args) {
|
||||
return print(stdout, ts, format_str, args...);
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vformat(
|
||||
const text_style& ts, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
detail::vformat_to(buf, ts, to_string_view(format_str), args);
|
||||
return fmt::to_string(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
|
||||
**Example**::
|
||||
|
||||
#include <fmt/color.h>
|
||||
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"The answer is {}", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
return vformat(ts, to_string_view(format_str),
|
||||
detail::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_COLOR_H_
|
||||
665
external/fmtlib/include/fmt/compile.h
vendored
665
external/fmtlib/include/fmt/compile.h
vendored
@@ -1,665 +0,0 @@
|
||||
// Formatting library for C++ - experimental format string compilation
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_COMPILE_H_
|
||||
#define FMT_COMPILE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// A compile-time string which is compiled into fast formatting code.
|
||||
class compiled_string {};
|
||||
|
||||
template <typename S>
|
||||
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Converts a string literal *s* into a format string that will be parsed at
|
||||
compile time and converted into efficient formatting code. Requires C++17
|
||||
``constexpr if`` compiler support.
|
||||
|
||||
**Example**::
|
||||
|
||||
// Converts 42 into std::string using the most efficient method and no
|
||||
// runtime format string processing.
|
||||
std::string s = fmt::format(FMT_COMPILE("{}"), 42);
|
||||
\endrst
|
||||
*/
|
||||
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string)
|
||||
|
||||
template <typename T, typename... Tail>
|
||||
const T& first(const T& value, const Tail&...) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Part of a compiled format string. It can be either literal text or a
|
||||
// replacement field.
|
||||
template <typename Char> struct format_part {
|
||||
enum class kind { arg_index, arg_name, text, replacement };
|
||||
|
||||
struct replacement {
|
||||
arg_ref<Char> arg_id;
|
||||
dynamic_format_specs<Char> specs;
|
||||
};
|
||||
|
||||
kind part_kind;
|
||||
union value {
|
||||
int arg_index;
|
||||
basic_string_view<Char> str;
|
||||
replacement repl;
|
||||
|
||||
FMT_CONSTEXPR value(int index = 0) : arg_index(index) {}
|
||||
FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {}
|
||||
FMT_CONSTEXPR value(replacement r) : repl(r) {}
|
||||
} val;
|
||||
// Position past the end of the argument id.
|
||||
const Char* arg_id_end = nullptr;
|
||||
|
||||
FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {})
|
||||
: part_kind(k), val(v) {}
|
||||
|
||||
static FMT_CONSTEXPR format_part make_arg_index(int index) {
|
||||
return format_part(kind::arg_index, index);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) {
|
||||
return format_part(kind::arg_name, name);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_text(basic_string_view<Char> text) {
|
||||
return format_part(kind::text, text);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_replacement(replacement repl) {
|
||||
return format_part(kind::replacement, repl);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct part_counter {
|
||||
unsigned num_parts = 0;
|
||||
|
||||
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
|
||||
if (begin != end) ++num_parts;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id() { return ++num_parts, 0; }
|
||||
FMT_CONSTEXPR int on_arg_id(int) { return ++num_parts, 0; }
|
||||
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char>) {
|
||||
return ++num_parts, 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
|
||||
|
||||
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
|
||||
const Char* end) {
|
||||
// Find the matching brace.
|
||||
unsigned brace_counter = 0;
|
||||
for (; begin != end; ++begin) {
|
||||
if (*begin == '{') {
|
||||
++brace_counter;
|
||||
} else if (*begin == '}') {
|
||||
if (brace_counter == 0u) break;
|
||||
--brace_counter;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char*) {}
|
||||
};
|
||||
|
||||
// Counts the number of parts in a format string.
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR unsigned count_parts(basic_string_view<Char> format_str) {
|
||||
part_counter<Char> counter;
|
||||
parse_format_string<true>(format_str, counter);
|
||||
return counter.num_parts;
|
||||
}
|
||||
|
||||
template <typename Char, typename PartHandler>
|
||||
class format_string_compiler : public error_handler {
|
||||
private:
|
||||
using part = format_part<Char>;
|
||||
|
||||
PartHandler handler_;
|
||||
part part_;
|
||||
basic_string_view<Char> format_str_;
|
||||
basic_format_parse_context<Char> parse_context_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR format_string_compiler(basic_string_view<Char> format_str,
|
||||
PartHandler handler)
|
||||
: handler_(handler),
|
||||
format_str_(format_str),
|
||||
parse_context_(format_str) {}
|
||||
|
||||
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
|
||||
if (begin != end)
|
||||
handler_(part::make_text({begin, to_unsigned(end - begin)}));
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id() {
|
||||
part_ = part::make_arg_index(parse_context_.next_arg_id());
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id(int id) {
|
||||
parse_context_.check_arg_id(id);
|
||||
part_ = part::make_arg_index(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char> id) {
|
||||
part_ = part::make_arg_name(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr) {
|
||||
part_.arg_id_end = ptr;
|
||||
handler_(part_);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
|
||||
const Char* end) {
|
||||
auto repl = typename part::replacement();
|
||||
dynamic_specs_handler<basic_format_parse_context<Char>> handler(
|
||||
repl.specs, parse_context_);
|
||||
auto it = parse_format_specs(begin, end, handler);
|
||||
if (*it != '}') on_error("missing '}' in format string");
|
||||
repl.arg_id = part_.part_kind == part::kind::arg_index
|
||||
? arg_ref<Char>(part_.val.arg_index)
|
||||
: arg_ref<Char>(part_.val.str);
|
||||
auto part = part::make_replacement(repl);
|
||||
part.arg_id_end = begin;
|
||||
handler_(part);
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
// Compiles a format string and invokes handler(part) for each parsed part.
|
||||
template <bool IS_CONSTEXPR, typename Char, typename PartHandler>
|
||||
FMT_CONSTEXPR void compile_format_string(basic_string_view<Char> format_str,
|
||||
PartHandler handler) {
|
||||
parse_format_string<IS_CONSTEXPR>(
|
||||
format_str,
|
||||
format_string_compiler<Char, PartHandler>(format_str, handler));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Context, typename Id>
|
||||
void format_arg(
|
||||
basic_format_parse_context<typename Context::char_type>& parse_ctx,
|
||||
Context& ctx, Id arg_id) {
|
||||
ctx.advance_to(visit_format_arg(
|
||||
arg_formatter<OutputIt, typename Context::char_type>(ctx, &parse_ctx),
|
||||
ctx.arg(arg_id)));
|
||||
}
|
||||
|
||||
// vformat_to is defined in a subnamespace to prevent ADL.
|
||||
namespace cf {
|
||||
template <typename Context, typename OutputIt, typename CompiledFormat>
|
||||
auto vformat_to(OutputIt out, CompiledFormat& cf,
|
||||
basic_format_args<Context> args) -> typename Context::iterator {
|
||||
using char_type = typename Context::char_type;
|
||||
basic_format_parse_context<char_type> parse_ctx(
|
||||
to_string_view(cf.format_str_));
|
||||
Context ctx(out, args);
|
||||
|
||||
const auto& parts = cf.parts();
|
||||
for (auto part_it = std::begin(parts); part_it != std::end(parts);
|
||||
++part_it) {
|
||||
const auto& part = *part_it;
|
||||
const auto& value = part.val;
|
||||
|
||||
using format_part_t = format_part<char_type>;
|
||||
switch (part.part_kind) {
|
||||
case format_part_t::kind::text: {
|
||||
const auto text = value.str;
|
||||
auto output = ctx.out();
|
||||
auto&& it = reserve(output, text.size());
|
||||
it = std::copy_n(text.begin(), text.size(), it);
|
||||
ctx.advance_to(output);
|
||||
break;
|
||||
}
|
||||
|
||||
case format_part_t::kind::arg_index:
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
detail::format_arg<OutputIt>(parse_ctx, ctx, value.arg_index);
|
||||
break;
|
||||
|
||||
case format_part_t::kind::arg_name:
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
detail::format_arg<OutputIt>(parse_ctx, ctx, value.str);
|
||||
break;
|
||||
|
||||
case format_part_t::kind::replacement: {
|
||||
const auto& arg_id_value = value.repl.arg_id.val;
|
||||
const auto arg = value.repl.arg_id.kind == arg_id_kind::index
|
||||
? ctx.arg(arg_id_value.index)
|
||||
: ctx.arg(arg_id_value.name);
|
||||
|
||||
auto specs = value.repl.specs;
|
||||
|
||||
handle_dynamic_spec<width_checker>(specs.width, specs.width_ref, ctx);
|
||||
handle_dynamic_spec<precision_checker>(specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
|
||||
error_handler h;
|
||||
numeric_specs_checker<error_handler> checker(h, arg.type());
|
||||
if (specs.align == align::numeric) checker.require_numeric_argument();
|
||||
if (specs.sign != sign::none) checker.check_sign();
|
||||
if (specs.alt) checker.require_numeric_argument();
|
||||
if (specs.precision >= 0) checker.check_precision();
|
||||
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
ctx.advance_to(
|
||||
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
|
||||
ctx, nullptr, &specs),
|
||||
arg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctx.out();
|
||||
}
|
||||
} // namespace cf
|
||||
|
||||
struct basic_compiled_format {};
|
||||
|
||||
template <typename S, typename = void>
|
||||
struct compiled_format_base : basic_compiled_format {
|
||||
using char_type = char_t<S>;
|
||||
using parts_container = std::vector<detail::format_part<char_type>>;
|
||||
|
||||
parts_container compiled_parts;
|
||||
|
||||
explicit compiled_format_base(basic_string_view<char_type> format_str) {
|
||||
compile_format_string<false>(format_str,
|
||||
[this](const format_part<char_type>& part) {
|
||||
compiled_parts.push_back(part);
|
||||
});
|
||||
}
|
||||
|
||||
const parts_container& parts() const { return compiled_parts; }
|
||||
};
|
||||
|
||||
template <typename Char, unsigned N> struct format_part_array {
|
||||
format_part<Char> data[N] = {};
|
||||
FMT_CONSTEXPR format_part_array() = default;
|
||||
};
|
||||
|
||||
template <typename Char, unsigned N>
|
||||
FMT_CONSTEXPR format_part_array<Char, N> compile_to_parts(
|
||||
basic_string_view<Char> format_str) {
|
||||
format_part_array<Char, N> parts;
|
||||
unsigned counter = 0;
|
||||
// This is not a lambda for compatibility with older compilers.
|
||||
struct {
|
||||
format_part<Char>* parts;
|
||||
unsigned* counter;
|
||||
FMT_CONSTEXPR void operator()(const format_part<Char>& part) {
|
||||
parts[(*counter)++] = part;
|
||||
}
|
||||
} collector{parts.data, &counter};
|
||||
compile_format_string<true>(format_str, collector);
|
||||
if (counter < N) {
|
||||
parts.data[counter] =
|
||||
format_part<Char>::make_text(basic_string_view<Char>());
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
template <typename T> constexpr const T& constexpr_max(const T& a, const T& b) {
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct compiled_format_base<S, enable_if_t<is_compile_string<S>::value>>
|
||||
: basic_compiled_format {
|
||||
using char_type = char_t<S>;
|
||||
|
||||
FMT_CONSTEXPR explicit compiled_format_base(basic_string_view<char_type>) {}
|
||||
|
||||
// Workaround for old compilers. Format string compilation will not be
|
||||
// performed there anyway.
|
||||
#if FMT_USE_CONSTEXPR
|
||||
static FMT_CONSTEXPR_DECL const unsigned num_format_parts =
|
||||
constexpr_max(count_parts(to_string_view(S())), 1u);
|
||||
#else
|
||||
static const unsigned num_format_parts = 1;
|
||||
#endif
|
||||
|
||||
using parts_container = format_part<char_type>[num_format_parts];
|
||||
|
||||
const parts_container& parts() const {
|
||||
static FMT_CONSTEXPR_DECL const auto compiled_parts =
|
||||
compile_to_parts<char_type, num_format_parts>(
|
||||
detail::to_string_view(S()));
|
||||
return compiled_parts.data;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S, typename... Args>
|
||||
class compiled_format : private compiled_format_base<S> {
|
||||
public:
|
||||
using typename compiled_format_base<S>::char_type;
|
||||
|
||||
private:
|
||||
basic_string_view<char_type> format_str_;
|
||||
|
||||
template <typename Context, typename OutputIt, typename CompiledFormat>
|
||||
friend auto cf::vformat_to(OutputIt out, CompiledFormat& cf,
|
||||
basic_format_args<Context> args) ->
|
||||
typename Context::iterator;
|
||||
|
||||
public:
|
||||
compiled_format() = delete;
|
||||
explicit constexpr compiled_format(basic_string_view<char_type> format_str)
|
||||
: compiled_format_base<S>(format_str), format_str_(format_str) {}
|
||||
};
|
||||
|
||||
#ifdef __cpp_if_constexpr
|
||||
template <typename... Args> struct type_list {};
|
||||
|
||||
// Returns a reference to the argument at index N from [first, rest...].
|
||||
template <int N, typename T, typename... Args>
|
||||
constexpr const auto& get(const T& first, const Args&... rest) {
|
||||
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
|
||||
if constexpr (N == 0)
|
||||
return first;
|
||||
else
|
||||
return get<N - 1>(rest...);
|
||||
}
|
||||
|
||||
template <int N, typename> struct get_type_impl;
|
||||
|
||||
template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
|
||||
using type = remove_cvref_t<decltype(get<N>(std::declval<Args>()...))>;
|
||||
};
|
||||
|
||||
template <int N, typename T>
|
||||
using get_type = typename get_type_impl<N, T>::type;
|
||||
|
||||
template <typename T> struct is_compiled_format : std::false_type {};
|
||||
|
||||
template <typename Char> struct text {
|
||||
basic_string_view<Char> data;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&...) const {
|
||||
return write<Char>(out, data);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_compiled_format<text<Char>> : std::true_type {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
|
||||
size_t size) {
|
||||
return {{&s[pos], size}};
|
||||
}
|
||||
|
||||
// A replacement field that refers to argument N.
|
||||
template <typename Char, typename T, int N> struct field {
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
// This ensures that the argument type is convertile to `const T&`.
|
||||
const T& arg = get<N>(args...);
|
||||
return write<Char>(out, arg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename T, int N>
|
||||
struct is_compiled_format<field<Char, T, N>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N and has format specifiers.
|
||||
template <typename Char, typename T, int N> struct spec_field {
|
||||
using char_type = Char;
|
||||
mutable formatter<T, Char> fmt;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
// This ensures that the argument type is convertile to `const T&`.
|
||||
const T& arg = get<N>(args...);
|
||||
basic_format_context<OutputIt, Char> ctx(out, {});
|
||||
return fmt.format(arg, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename T, int N>
|
||||
struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R> struct concat {
|
||||
L lhs;
|
||||
R rhs;
|
||||
using char_type = typename L::char_type;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
out = lhs.format(out, args...);
|
||||
return rhs.format(out, args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct is_compiled_format<concat<L, R>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R>
|
||||
constexpr concat<L, R> make_concat(L lhs, R rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
struct unknown_format {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
|
||||
for (size_t size = str.size(); pos != size; ++pos) {
|
||||
if (str[pos] == '{' || str[pos] == '}') break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str);
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename T, typename S>
|
||||
constexpr auto parse_tail(T head, S format_str) {
|
||||
if constexpr (POS !=
|
||||
basic_string_view<typename S::char_type>(format_str).size()) {
|
||||
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
|
||||
unknown_format>())
|
||||
return tail;
|
||||
else
|
||||
return make_concat(head, tail);
|
||||
} else {
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Char> struct parse_specs_result {
|
||||
formatter<T, Char> fmt;
|
||||
size_t end;
|
||||
};
|
||||
|
||||
template <typename T, typename Char>
|
||||
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
size_t pos) {
|
||||
str.remove_prefix(pos);
|
||||
auto ctx = basic_format_parse_context<Char>(str);
|
||||
auto f = formatter<T, Char>();
|
||||
auto end = f.parse(ctx);
|
||||
return {f, pos + (end - str.data()) + 1};
|
||||
}
|
||||
|
||||
// Compiles a non-empty format string and returns the compiled representation
|
||||
// or unknown_format() on unrecognized input.
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str) {
|
||||
using char_type = typename S::char_type;
|
||||
constexpr basic_string_view<char_type> str = format_str;
|
||||
if constexpr (str[POS] == '{') {
|
||||
if (POS + 1 == str.size())
|
||||
throw format_error("unmatched '{' in format string");
|
||||
if constexpr (str[POS + 1] == '{') {
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
} else if constexpr (str[POS + 1] == '}') {
|
||||
using type = get_type<ID, Args>;
|
||||
return parse_tail<Args, POS + 2, ID + 1>(field<char_type, type, ID>(),
|
||||
format_str);
|
||||
} else if constexpr (str[POS + 1] == ':') {
|
||||
using type = get_type<ID, Args>;
|
||||
constexpr auto result = parse_specs<type>(str, POS + 2);
|
||||
return parse_tail<Args, result.end, ID + 1>(
|
||||
spec_field<char_type, type, ID>{result.fmt}, format_str);
|
||||
} else {
|
||||
return unknown_format();
|
||||
}
|
||||
} else if constexpr (str[POS] == '}') {
|
||||
if (POS + 1 == str.size())
|
||||
throw format_error("unmatched '}' in format string");
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
} else {
|
||||
constexpr auto end = parse_text(str, POS + 1);
|
||||
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
|
||||
format_str);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args, typename S,
|
||||
FMT_ENABLE_IF(is_compile_string<S>::value ||
|
||||
detail::is_compiled_string<S>::value)>
|
||||
constexpr auto compile(S format_str) {
|
||||
constexpr basic_string_view<typename S::char_type> str = format_str;
|
||||
if constexpr (str.size() == 0) {
|
||||
return detail::make_text(str, 0, 0);
|
||||
} else {
|
||||
constexpr auto result =
|
||||
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
|
||||
format_str);
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(result)>,
|
||||
detail::unknown_format>()) {
|
||||
return detail::compiled_format<S, Args...>(to_string_view(format_str));
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
template <typename... Args, typename S,
|
||||
FMT_ENABLE_IF(is_compile_string<S>::value)>
|
||||
constexpr auto compile(S format_str) -> detail::compiled_format<S, Args...> {
|
||||
return detail::compiled_format<S, Args...>(to_string_view(format_str));
|
||||
}
|
||||
#endif // __cpp_if_constexpr
|
||||
|
||||
// Compiles the format string which must be a string literal.
|
||||
template <typename... Args, typename Char, size_t N>
|
||||
auto compile(const Char (&format_str)[N])
|
||||
-> detail::compiled_format<const Char*, Args...> {
|
||||
return detail::compiled_format<const Char*, Args...>(
|
||||
basic_string_view<Char>(format_str, N - 1));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// DEPRECATED! use FMT_COMPILE instead.
|
||||
template <typename... Args>
|
||||
FMT_DEPRECATED auto compile(const Args&... args)
|
||||
-> decltype(detail::compile(args...)) {
|
||||
return detail::compile(args...);
|
||||
}
|
||||
|
||||
#if FMT_USE_CONSTEXPR
|
||||
# ifdef __cpp_if_constexpr
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::buffer<Char>& base = buffer;
|
||||
cf.format(std::back_inserter(base), args...);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
return cf.format(out, args...);
|
||||
}
|
||||
# endif // __cpp_if_constexpr
|
||||
#endif // FMT_USE_CONSTEXPR
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
|
||||
CompiledFormat>::value)>
|
||||
std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
using context = buffer_context<Char>;
|
||||
detail::buffer<Char>& base = buffer;
|
||||
detail::cf::vformat_to<context>(std::back_inserter(base), cf,
|
||||
make_format_args<context>(args...));
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
|
||||
Args&&... args) {
|
||||
constexpr basic_string_view<typename S::char_type> str = S();
|
||||
if (str.size() == 2 && str[0] == '{' && str[1] == '}')
|
||||
return fmt::to_string(detail::first(args...));
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
return format(compiled, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
|
||||
CompiledFormat>::value)>
|
||||
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
using char_type = typename CompiledFormat::char_type;
|
||||
using context = format_context_t<OutputIt, char_type>;
|
||||
return detail::cf::vformat_to<context>(out, cf,
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
OutputIt format_to(OutputIt out, const S&, const Args&... args) {
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
return format_to(out, compiled, args...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&& std::is_base_of<
|
||||
detail::basic_compiled_format, CompiledFormat>::value)>
|
||||
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
|
||||
const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
auto it =
|
||||
format_to(detail::truncating_iterator<OutputIt>(out, n), cf, args...);
|
||||
return {it.base(), it.count()};
|
||||
}
|
||||
|
||||
template <typename CompiledFormat, typename... Args>
|
||||
size_t formatted_size(const CompiledFormat& cf, const Args&... args) {
|
||||
return format_to(detail::counting_iterator(), cf, args...).count();
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_COMPILE_H_
|
||||
1882
external/fmtlib/include/fmt/core.h
vendored
1882
external/fmtlib/include/fmt/core.h
vendored
File diff suppressed because it is too large
Load Diff
1453
external/fmtlib/include/fmt/format-inl.h
vendored
1453
external/fmtlib/include/fmt/format-inl.h
vendored
File diff suppressed because it is too large
Load Diff
3729
external/fmtlib/include/fmt/format.h
vendored
3729
external/fmtlib/include/fmt/format.h
vendored
File diff suppressed because it is too large
Load Diff
78
external/fmtlib/include/fmt/locale.h
vendored
78
external/fmtlib/include/fmt/locale.h
vendored
@@ -1,78 +0,0 @@
|
||||
// Formatting library for C++ - std::locale support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_LOCALE_H_
|
||||
#define FMT_LOCALE_H_
|
||||
|
||||
#include <locale>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
template <typename Char>
|
||||
typename buffer_context<Char>::iterator vformat_to(
|
||||
const std::locale& loc, buffer<Char>& buf,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
using af = arg_formatter<typename buffer_context<Char>::iterator, Char>;
|
||||
return vformat_to<af>(std::back_inserter(buf), to_string_view(format_str),
|
||||
args, detail::locale_ref(loc));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
std::basic_string<Char> vformat(
|
||||
const std::locale& loc, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(loc, buffer, format_str, args);
|
||||
return fmt::to_string(buffer);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vformat(
|
||||
const std::locale& loc, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
return detail::vformat(loc, to_string_view(format_str), args);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> format(const std::locale& loc,
|
||||
const S& format_str, Args&&... args) {
|
||||
return detail::vformat(
|
||||
loc, to_string_view(format_str),
|
||||
detail::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
template <typename S, typename OutputIt, typename... Args,
|
||||
typename Char = enable_if_t<
|
||||
detail::is_output_iterator<OutputIt>::value, char_t<S>>>
|
||||
inline OutputIt vformat_to(
|
||||
OutputIt out, const std::locale& loc, const S& format_str,
|
||||
format_args_t<type_identity_t<OutputIt>, Char> args) {
|
||||
using af = detail::arg_formatter<OutputIt, Char>;
|
||||
return vformat_to<af>(out, to_string_view(format_str), args,
|
||||
detail::locale_ref(loc));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&&
|
||||
detail::is_string<S>::value)>
|
||||
inline OutputIt format_to(OutputIt out, const std::locale& loc,
|
||||
const S& format_str, Args&&... args) {
|
||||
detail::check_format_string<Args...>(format_str);
|
||||
using context = format_context_t<OutputIt, char_t<S>>;
|
||||
format_arg_store<context, Args...> as{args...};
|
||||
return vformat_to(out, loc, to_string_view(format_str),
|
||||
basic_format_args<context>(as));
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_LOCALE_H_
|
||||
450
external/fmtlib/include/fmt/os.h
vendored
450
external/fmtlib/include/fmt/os.h
vendored
@@ -1,450 +0,0 @@
|
||||
// Formatting library for C++ - optional OS-specific functionality
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_OS_H_
|
||||
#define FMT_OS_H_
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
|
||||
# undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
#include <cerrno>
|
||||
#include <clocale> // for locale_t
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib> // for strtod_l
|
||||
|
||||
#if defined __APPLE__ || defined(__FreeBSD__)
|
||||
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
|
||||
// UWP doesn't provide _pipe.
|
||||
#if FMT_HAS_INCLUDE("winapifamily.h")
|
||||
# include <winapifamily.h>
|
||||
#endif
|
||||
#if FMT_HAS_INCLUDE("fcntl.h") && \
|
||||
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||
# include <fcntl.h> // for O_RDONLY
|
||||
# define FMT_USE_FCNTL 1
|
||||
#else
|
||||
# define FMT_USE_FCNTL 0
|
||||
#endif
|
||||
|
||||
#ifndef FMT_POSIX
|
||||
# if defined(_WIN32) && !defined(__MINGW32__)
|
||||
// Fix warnings about deprecated symbols.
|
||||
# define FMT_POSIX(call) _##call
|
||||
# else
|
||||
# define FMT_POSIX(call) call
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
|
||||
#ifdef FMT_SYSTEM
|
||||
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
||||
#else
|
||||
# define FMT_SYSTEM(call) ::call
|
||||
# ifdef _WIN32
|
||||
// Fix warnings about deprecated symbols.
|
||||
# define FMT_POSIX_CALL(call) ::_##call
|
||||
# else
|
||||
# define FMT_POSIX_CALL(call) ::call
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Retries the expression while it evaluates to error_result and errno
|
||||
// equals to EINTR.
|
||||
#ifndef _WIN32
|
||||
# define FMT_RETRY_VAL(result, expression, error_result) \
|
||||
do { \
|
||||
(result) = (expression); \
|
||||
} while ((result) == (error_result) && errno == EINTR)
|
||||
#else
|
||||
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
|
||||
#endif
|
||||
|
||||
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
/**
|
||||
\rst
|
||||
A reference to a null-terminated string. It can be constructed from a C
|
||||
string or ``std::string``.
|
||||
|
||||
You can use one of the following type aliases for common character types:
|
||||
|
||||
+---------------+-----------------------------+
|
||||
| Type | Definition |
|
||||
+===============+=============================+
|
||||
| cstring_view | basic_cstring_view<char> |
|
||||
+---------------+-----------------------------+
|
||||
| wcstring_view | basic_cstring_view<wchar_t> |
|
||||
+---------------+-----------------------------+
|
||||
|
||||
This class is most useful as a parameter type to allow passing
|
||||
different types of strings to a function, for example::
|
||||
|
||||
template <typename... Args>
|
||||
std::string format(cstring_view format_str, const Args & ... args);
|
||||
|
||||
format("{}", 42);
|
||||
format(std::string("{}"), 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename Char> class basic_cstring_view {
|
||||
private:
|
||||
const Char* data_;
|
||||
|
||||
public:
|
||||
/** Constructs a string reference object from a C string. */
|
||||
basic_cstring_view(const Char* s) : data_(s) {}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs a string reference from an ``std::string`` object.
|
||||
\endrst
|
||||
*/
|
||||
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
|
||||
|
||||
/** Returns the pointer to a C string. */
|
||||
const Char* c_str() const { return data_; }
|
||||
};
|
||||
|
||||
using cstring_view = basic_cstring_view<char>;
|
||||
using wcstring_view = basic_cstring_view<wchar_t>;
|
||||
|
||||
// An error code.
|
||||
class error_code {
|
||||
private:
|
||||
int value_;
|
||||
|
||||
public:
|
||||
explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {}
|
||||
|
||||
int get() const FMT_NOEXCEPT { return value_; }
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace detail {
|
||||
// A converter from UTF-16 to UTF-8.
|
||||
// It is only provided for Windows since other systems support UTF-8 natively.
|
||||
class utf16_to_utf8 {
|
||||
private:
|
||||
memory_buffer buffer_;
|
||||
|
||||
public:
|
||||
utf16_to_utf8() {}
|
||||
FMT_API explicit utf16_to_utf8(wstring_view s);
|
||||
operator string_view() const { return string_view(&buffer_[0], size()); }
|
||||
size_t size() const { return buffer_.size() - 1; }
|
||||
const char* c_str() const { return &buffer_[0]; }
|
||||
std::string str() const { return std::string(&buffer_[0], size()); }
|
||||
|
||||
// Performs conversion returning a system error code instead of
|
||||
// throwing exception on conversion error. This method may still throw
|
||||
// in case of memory allocation error.
|
||||
FMT_API int convert(wstring_view s);
|
||||
};
|
||||
|
||||
FMT_API void format_windows_error(buffer<char>& out, int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
} // namespace detail
|
||||
|
||||
/** A Windows error. */
|
||||
class windows_error : public system_error {
|
||||
private:
|
||||
FMT_API void init(int error_code, string_view format_str, format_args args);
|
||||
|
||||
public:
|
||||
/**
|
||||
\rst
|
||||
Constructs a :class:`fmt::windows_error` object with the description
|
||||
of the form
|
||||
|
||||
.. parsed-literal::
|
||||
*<message>*: *<system-message>*
|
||||
|
||||
where *<message>* is the formatted message and *<system-message>* is the
|
||||
system message corresponding to the error code.
|
||||
*error_code* is a Windows error code as given by ``GetLastError``.
|
||||
If *error_code* is not a valid error code such as -1, the system message
|
||||
will look like "error -1".
|
||||
|
||||
**Example**::
|
||||
|
||||
// This throws a windows_error with the description
|
||||
// cannot open file 'madeup': The system cannot find the file specified.
|
||||
// or similar (system message may vary).
|
||||
const char *filename = "madeup";
|
||||
LPOFSTRUCT of = LPOFSTRUCT();
|
||||
HFILE file = OpenFile(filename, &of, OF_READ);
|
||||
if (file == HFILE_ERROR) {
|
||||
throw fmt::windows_error(GetLastError(),
|
||||
"cannot open file '{}'", filename);
|
||||
}
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
windows_error(int error_code, string_view message, const Args&... args) {
|
||||
init(error_code, message, make_format_args(args...));
|
||||
}
|
||||
};
|
||||
|
||||
// Reports a Windows error without throwing an exception.
|
||||
// Can be used to report errors from destructors.
|
||||
FMT_API void report_windows_error(int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
#endif // _WIN32
|
||||
|
||||
// A buffered file.
|
||||
class buffered_file {
|
||||
private:
|
||||
FILE* file_;
|
||||
|
||||
friend class file;
|
||||
|
||||
explicit buffered_file(FILE* f) : file_(f) {}
|
||||
|
||||
public:
|
||||
buffered_file(const buffered_file&) = delete;
|
||||
void operator=(const buffered_file&) = delete;
|
||||
|
||||
// Constructs a buffered_file object which doesn't represent any file.
|
||||
buffered_file() FMT_NOEXCEPT : file_(nullptr) {}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~buffered_file() FMT_NOEXCEPT;
|
||||
|
||||
public:
|
||||
buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) {
|
||||
other.file_ = nullptr;
|
||||
}
|
||||
|
||||
buffered_file& operator=(buffered_file&& other) {
|
||||
close();
|
||||
file_ = other.file_;
|
||||
other.file_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Opens a file.
|
||||
FMT_API buffered_file(cstring_view filename, cstring_view mode);
|
||||
|
||||
// Closes the file.
|
||||
FMT_API void close();
|
||||
|
||||
// Returns the pointer to a FILE object representing this file.
|
||||
FILE* get() const FMT_NOEXCEPT { return file_; }
|
||||
|
||||
// We place parentheses around fileno to workaround a bug in some versions
|
||||
// of MinGW that define fileno as a macro.
|
||||
FMT_API int(fileno)() const;
|
||||
|
||||
void vprint(string_view format_str, format_args args) {
|
||||
fmt::vprint(file_, format_str, args);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void print(string_view format_str, const Args&... args) {
|
||||
vprint(format_str, make_format_args(args...));
|
||||
}
|
||||
};
|
||||
|
||||
#if FMT_USE_FCNTL
|
||||
// A file. Closed file is represented by a file object with descriptor -1.
|
||||
// Methods that are not declared with FMT_NOEXCEPT may throw
|
||||
// fmt::system_error in case of failure. Note that some errors such as
|
||||
// closing the file multiple times will cause a crash on Windows rather
|
||||
// than an exception. You can get standard behavior by overriding the
|
||||
// invalid parameter handler with _set_invalid_parameter_handler.
|
||||
class file {
|
||||
private:
|
||||
int fd_; // File descriptor.
|
||||
|
||||
// Constructs a file object with a given descriptor.
|
||||
explicit file(int fd) : fd_(fd) {}
|
||||
|
||||
public:
|
||||
// Possible values for the oflag argument to the constructor.
|
||||
enum {
|
||||
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
|
||||
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
|
||||
RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
|
||||
CREATE = FMT_POSIX(O_CREAT) // Create if the file doesn't exist.
|
||||
};
|
||||
|
||||
// Constructs a file object which doesn't represent any file.
|
||||
file() FMT_NOEXCEPT : fd_(-1) {}
|
||||
|
||||
// Opens a file and constructs a file object representing this file.
|
||||
FMT_API file(cstring_view path, int oflag);
|
||||
|
||||
public:
|
||||
file(const file&) = delete;
|
||||
void operator=(const file&) = delete;
|
||||
|
||||
file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
|
||||
|
||||
file& operator=(file&& other) FMT_NOEXCEPT {
|
||||
close();
|
||||
fd_ = other.fd_;
|
||||
other.fd_ = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~file() FMT_NOEXCEPT;
|
||||
|
||||
// Returns the file descriptor.
|
||||
int descriptor() const FMT_NOEXCEPT { return fd_; }
|
||||
|
||||
// Closes the file.
|
||||
FMT_API void close();
|
||||
|
||||
// Returns the file size. The size has signed type for consistency with
|
||||
// stat::st_size.
|
||||
FMT_API long long size() const;
|
||||
|
||||
// Attempts to read count bytes from the file into the specified buffer.
|
||||
FMT_API size_t read(void* buffer, size_t count);
|
||||
|
||||
// Attempts to write count bytes from the specified buffer to the file.
|
||||
FMT_API size_t write(const void* buffer, size_t count);
|
||||
|
||||
// Duplicates a file descriptor with the dup function and returns
|
||||
// the duplicate as a file object.
|
||||
FMT_API static file dup(int fd);
|
||||
|
||||
// Makes fd be the copy of this file descriptor, closing fd first if
|
||||
// necessary.
|
||||
FMT_API void dup2(int fd);
|
||||
|
||||
// Makes fd be the copy of this file descriptor, closing fd first if
|
||||
// necessary.
|
||||
FMT_API void dup2(int fd, error_code& ec) FMT_NOEXCEPT;
|
||||
|
||||
// Creates a pipe setting up read_end and write_end file objects for reading
|
||||
// and writing respectively.
|
||||
FMT_API static void pipe(file& read_end, file& write_end);
|
||||
|
||||
// Creates a buffered_file object associated with this file and detaches
|
||||
// this file object from the file.
|
||||
FMT_API buffered_file fdopen(const char* mode);
|
||||
};
|
||||
|
||||
// Returns the memory page size.
|
||||
long getpagesize();
|
||||
|
||||
class direct_buffered_file;
|
||||
|
||||
template <typename S, typename... Args>
|
||||
void print(direct_buffered_file& f, const S& format_str,
|
||||
const Args&... args);
|
||||
|
||||
// A buffered file with a direct buffer access and no synchronization.
|
||||
class direct_buffered_file {
|
||||
private:
|
||||
file file_;
|
||||
|
||||
enum { buffer_size = 4096 };
|
||||
char buffer_[buffer_size];
|
||||
int pos_;
|
||||
|
||||
void flush() {
|
||||
if (pos_ == 0) return;
|
||||
file_.write(buffer_, pos_);
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
int free_capacity() const { return buffer_size - pos_; }
|
||||
|
||||
public:
|
||||
direct_buffered_file(cstring_view path, int oflag)
|
||||
: file_(path, oflag), pos_(0) {}
|
||||
|
||||
~direct_buffered_file() {
|
||||
flush();
|
||||
}
|
||||
|
||||
void close() {
|
||||
flush();
|
||||
file_.close();
|
||||
}
|
||||
|
||||
template <typename S, typename... Args>
|
||||
friend void print(direct_buffered_file& f, const S& format_str,
|
||||
const Args&... args) {
|
||||
// We could avoid double buffering.
|
||||
auto buf = fmt::memory_buffer();
|
||||
fmt::format_to(std::back_inserter(buf), format_str, args...);
|
||||
auto remaining_pos = 0;
|
||||
auto remaining_size = buf.size();
|
||||
while (remaining_size > detail::to_unsigned(f.free_capacity())) {
|
||||
auto size = f.free_capacity();
|
||||
memcpy(f.buffer_ + f.pos_, buf.data() + remaining_pos, size);
|
||||
f.pos_ += size;
|
||||
f.flush();
|
||||
remaining_pos += size;
|
||||
remaining_size -= size;
|
||||
}
|
||||
memcpy(f.buffer_ + f.pos_, buf.data() + remaining_pos, remaining_size);
|
||||
f.pos_ += static_cast<int>(remaining_size);
|
||||
}
|
||||
};
|
||||
#endif // FMT_USE_FCNTL
|
||||
|
||||
#ifdef FMT_LOCALE
|
||||
// A "C" numeric locale.
|
||||
class locale {
|
||||
private:
|
||||
# ifdef _WIN32
|
||||
using locale_t = _locale_t;
|
||||
|
||||
static void freelocale(locale_t loc) { _free_locale(loc); }
|
||||
|
||||
static double strtod_l(const char* nptr, char** endptr, _locale_t loc) {
|
||||
return _strtod_l(nptr, endptr, loc);
|
||||
}
|
||||
# endif
|
||||
|
||||
locale_t locale_;
|
||||
|
||||
public:
|
||||
using type = locale_t;
|
||||
locale(const locale&) = delete;
|
||||
void operator=(const locale&) = delete;
|
||||
|
||||
locale() {
|
||||
# ifndef _WIN32
|
||||
locale_ = FMT_SYSTEM(newlocale(LC_NUMERIC_MASK, "C", nullptr));
|
||||
# else
|
||||
locale_ = _create_locale(LC_NUMERIC, "C");
|
||||
# endif
|
||||
if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
|
||||
}
|
||||
~locale() { freelocale(locale_); }
|
||||
|
||||
type get() const { return locale_; }
|
||||
|
||||
// Converts string to floating-point number and advances str past the end
|
||||
// of the parsed input.
|
||||
double strtod(const char*& str) const {
|
||||
char* end = nullptr;
|
||||
double result = strtod_l(str, &end, locale_);
|
||||
str = end;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
using Locale FMT_DEPRECATED_ALIAS = locale;
|
||||
#endif // FMT_LOCALE
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_OS_H_
|
||||
167
external/fmtlib/include/fmt/ostream.h
vendored
167
external/fmtlib/include/fmt/ostream.h
vendored
@@ -1,167 +0,0 @@
|
||||
// Formatting library for C++ - std::ostream support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_OSTREAM_H_
|
||||
#define FMT_OSTREAM_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename Char> class basic_printf_parse_context;
|
||||
template <typename OutputIt, typename Char> class basic_printf_context;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Char> class formatbuf : public std::basic_streambuf<Char> {
|
||||
private:
|
||||
using int_type = typename std::basic_streambuf<Char>::int_type;
|
||||
using traits_type = typename std::basic_streambuf<Char>::traits_type;
|
||||
|
||||
buffer<Char>& buffer_;
|
||||
|
||||
public:
|
||||
formatbuf(buffer<Char>& buf) : buffer_(buf) {}
|
||||
|
||||
protected:
|
||||
// The put-area is actually always empty. This makes the implementation
|
||||
// simpler and has the advantage that the streambuf and the buffer are always
|
||||
// in sync and sputc never writes into uninitialized memory. The obvious
|
||||
// disadvantage is that each call to sputc always results in a (virtual) call
|
||||
// to overflow. There is no disadvantage here for sputn since this always
|
||||
// results in a call to xsputn.
|
||||
|
||||
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
|
||||
if (!traits_type::eq_int_type(ch, traits_type::eof()))
|
||||
buffer_.push_back(static_cast<Char>(ch));
|
||||
return ch;
|
||||
}
|
||||
|
||||
std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE {
|
||||
buffer_.append(s, s + count);
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct test_stream : std::basic_ostream<Char> {
|
||||
private:
|
||||
// Hide all operator<< from std::basic_ostream<Char>.
|
||||
void_t<> operator<<(null<>);
|
||||
void_t<> operator<<(const Char*);
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_convertible<T, int>::value &&
|
||||
!std::is_enum<T>::value)>
|
||||
void_t<> operator<<(T);
|
||||
};
|
||||
|
||||
// Checks if T has a user-defined operator<< (e.g. not a member of
|
||||
// std::ostream).
|
||||
template <typename T, typename Char> class is_streamable {
|
||||
private:
|
||||
template <typename U>
|
||||
static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
|
||||
<< std::declval<U>()),
|
||||
void_t<>>::value>
|
||||
test(int);
|
||||
|
||||
template <typename> static std::false_type test(...);
|
||||
|
||||
using result = decltype(test<T>(0));
|
||||
|
||||
public:
|
||||
static const bool value = result::value;
|
||||
};
|
||||
|
||||
// Write the content of buf to os.
|
||||
template <typename Char>
|
||||
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
|
||||
const Char* buf_data = buf.data();
|
||||
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
|
||||
unsigned_streamsize size = buf.size();
|
||||
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
|
||||
do {
|
||||
unsigned_streamsize n = size <= max_size ? size : max_size;
|
||||
os.write(buf_data, static_cast<std::streamsize>(n));
|
||||
buf_data += n;
|
||||
size -= n;
|
||||
} while (size != 0);
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
void format_value(buffer<Char>& buf, const T& value,
|
||||
locale_ref loc = locale_ref()) {
|
||||
formatbuf<Char> format_buf(buf);
|
||||
std::basic_ostream<Char> output(&format_buf);
|
||||
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
||||
if (loc) output.imbue(loc.get<std::locale>());
|
||||
#endif
|
||||
output << value;
|
||||
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
|
||||
buf.resize(buf.size());
|
||||
}
|
||||
|
||||
// Formats an object of type T that has an overloaded ostream operator<<.
|
||||
template <typename T, typename Char>
|
||||
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
|
||||
: private formatter<basic_string_view<Char>, Char> {
|
||||
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
|
||||
-> decltype(ctx.begin()) {
|
||||
return formatter<basic_string_view<Char>, Char>::parse(ctx);
|
||||
}
|
||||
template <typename ParseCtx,
|
||||
FMT_ENABLE_IF(std::is_same<
|
||||
ParseCtx, basic_printf_parse_context<Char>>::value)>
|
||||
auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename OutputIt>
|
||||
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
|
||||
-> OutputIt {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
format_value(buffer, value, ctx.locale());
|
||||
basic_string_view<Char> str(buffer.data(), buffer.size());
|
||||
return formatter<basic_string_view<Char>, Char>::format(str, ctx);
|
||||
}
|
||||
template <typename OutputIt>
|
||||
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
|
||||
-> OutputIt {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
format_value(buffer, value, ctx.locale());
|
||||
return std::copy(buffer.begin(), buffer.end(), ctx.out());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename Char>
|
||||
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
detail::write_buffer(os, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the stream *os*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print(cerr, "Don't {}!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
|
||||
vprint(os, to_string_view(format_str),
|
||||
detail::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_OSTREAM_H_
|
||||
2
external/fmtlib/include/fmt/posix.h
vendored
2
external/fmtlib/include/fmt/posix.h
vendored
@@ -1,2 +0,0 @@
|
||||
#include "os.h"
|
||||
#warning "fmt/posix.h is deprecated; use fmt/os.h instead"
|
||||
751
external/fmtlib/include/fmt/printf.h
vendored
751
external/fmtlib/include/fmt/printf.h
vendored
@@ -1,751 +0,0 @@
|
||||
// Formatting library for C++ - legacy printf implementation
|
||||
//
|
||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_PRINTF_H_
|
||||
#define FMT_PRINTF_H_
|
||||
|
||||
#include <algorithm> // std::max
|
||||
#include <limits> // std::numeric_limits
|
||||
|
||||
#include "ostream.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||
// signed and unsigned integers.
|
||||
template <bool IsSigned> struct int_checker {
|
||||
template <typename T> static bool fits_in_int(T value) {
|
||||
unsigned max = max_value<int>();
|
||||
return value <= max;
|
||||
}
|
||||
static bool fits_in_int(bool) { return true; }
|
||||
};
|
||||
|
||||
template <> struct int_checker<true> {
|
||||
template <typename T> static bool fits_in_int(T value) {
|
||||
return value >= (std::numeric_limits<int>::min)() &&
|
||||
value <= max_value<int>();
|
||||
}
|
||||
static bool fits_in_int(int) { return true; }
|
||||
};
|
||||
|
||||
class printf_precision_handler {
|
||||
public:
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
int operator()(T value) {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
FMT_THROW(format_error("number is too big"));
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
int operator()(T) {
|
||||
FMT_THROW(format_error("precision is not integer"));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// An argument visitor that returns true iff arg is a zero integer.
|
||||
class is_zero_int {
|
||||
public:
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
bool operator()(T value) {
|
||||
return value == 0;
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
bool operator()(T) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
|
||||
|
||||
template <> struct make_unsigned_or_bool<bool> { using type = bool; };
|
||||
|
||||
template <typename T, typename Context> class arg_converter {
|
||||
private:
|
||||
using char_type = typename Context::char_type;
|
||||
|
||||
basic_format_arg<Context>& arg_;
|
||||
char_type type_;
|
||||
|
||||
public:
|
||||
arg_converter(basic_format_arg<Context>& arg, char_type type)
|
||||
: arg_(arg), type_(type) {}
|
||||
|
||||
void operator()(bool value) {
|
||||
if (type_ != 's') operator()<bool>(value);
|
||||
}
|
||||
|
||||
template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
|
||||
void operator()(U value) {
|
||||
bool is_signed = type_ == 'd' || type_ == 'i';
|
||||
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
|
||||
if (const_check(sizeof(target_type) <= sizeof(int))) {
|
||||
// Extra casts are used to silence warnings.
|
||||
if (is_signed) {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<int>(static_cast<target_type>(value)));
|
||||
} else {
|
||||
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<unsigned>(static_cast<unsigned_type>(value)));
|
||||
}
|
||||
} else {
|
||||
if (is_signed) {
|
||||
// glibc's printf doesn't sign extend arguments of smaller types:
|
||||
// std::printf("%lld", -42); // prints "4294967254"
|
||||
// but we don't have to do the same because it's a UB.
|
||||
arg_ = detail::make_arg<Context>(static_cast<long long>(value));
|
||||
} else {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<typename make_unsigned_or_bool<U>::type>(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
|
||||
void operator()(U) {} // No conversion needed for non-integral types.
|
||||
};
|
||||
|
||||
// Converts an integer argument to T for printf, if T is an integral type.
|
||||
// If T is void, the argument is converted to corresponding signed or unsigned
|
||||
// type depending on the type specifier: 'd' and 'i' - signed, other -
|
||||
// unsigned).
|
||||
template <typename T, typename Context, typename Char>
|
||||
void convert_arg(basic_format_arg<Context>& arg, Char type) {
|
||||
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
|
||||
}
|
||||
|
||||
// Converts an integer argument to char for printf.
|
||||
template <typename Context> class char_converter {
|
||||
private:
|
||||
basic_format_arg<Context>& arg_;
|
||||
|
||||
public:
|
||||
explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
void operator()(T value) {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<typename Context::char_type>(value));
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
void operator()(T) {} // No conversion needed for non-integral types.
|
||||
};
|
||||
|
||||
// An argument visitor that return a pointer to a C string if argument is a
|
||||
// string or null otherwise.
|
||||
template <typename Char> struct get_cstring {
|
||||
template <typename T> const Char* operator()(T) { return nullptr; }
|
||||
const Char* operator()(const Char* s) { return s; }
|
||||
};
|
||||
|
||||
// Checks if an argument is a valid printf width specifier and sets
|
||||
// left alignment if it is negative.
|
||||
template <typename Char> class printf_width_handler {
|
||||
private:
|
||||
using format_specs = basic_format_specs<Char>;
|
||||
|
||||
format_specs& specs_;
|
||||
|
||||
public:
|
||||
explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
unsigned operator()(T value) {
|
||||
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
|
||||
if (detail::is_negative(value)) {
|
||||
specs_.align = align::left;
|
||||
width = 0 - width;
|
||||
}
|
||||
unsigned int_max = max_value<int>();
|
||||
if (width > int_max) FMT_THROW(format_error("number is too big"));
|
||||
return static_cast<unsigned>(width);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
unsigned operator()(T) {
|
||||
FMT_THROW(format_error("width is not integer"));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Context>
|
||||
void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
basic_format_args<Context> args) {
|
||||
Context(std::back_inserter(buf), format, args).format();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// For printing into memory_buffer.
|
||||
template <typename Char, typename Context>
|
||||
FMT_DEPRECATED void printf(detail::buffer<Char>& buf,
|
||||
basic_string_view<Char> format,
|
||||
basic_format_args<Context> args) {
|
||||
return detail::vprintf(buf, format, args);
|
||||
}
|
||||
using detail::vprintf;
|
||||
|
||||
template <typename Char>
|
||||
class basic_printf_parse_context : public basic_format_parse_context<Char> {
|
||||
using basic_format_parse_context<Char>::basic_format_parse_context;
|
||||
};
|
||||
template <typename OutputIt, typename Char> class basic_printf_context;
|
||||
|
||||
/**
|
||||
\rst
|
||||
The ``printf`` argument formatter.
|
||||
\endrst
|
||||
*/
|
||||
template <typename OutputIt, typename Char>
|
||||
class printf_arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
|
||||
public:
|
||||
using iterator = OutputIt;
|
||||
|
||||
private:
|
||||
using char_type = Char;
|
||||
using base = detail::arg_formatter_base<OutputIt, Char>;
|
||||
using context_type = basic_printf_context<OutputIt, Char>;
|
||||
|
||||
context_type& context_;
|
||||
|
||||
void write_null_pointer(char) {
|
||||
this->specs()->type = 0;
|
||||
this->write("(nil)");
|
||||
}
|
||||
|
||||
void write_null_pointer(wchar_t) {
|
||||
this->specs()->type = 0;
|
||||
this->write(L"(nil)");
|
||||
}
|
||||
|
||||
public:
|
||||
using format_specs = typename base::format_specs;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an argument formatter object.
|
||||
*buffer* is a reference to the output buffer and *specs* contains format
|
||||
specifier information for standard argument types.
|
||||
\endrst
|
||||
*/
|
||||
printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
|
||||
: base(iter, &specs, detail::locale_ref()), context_(ctx) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(fmt::detail::is_integral<T>::value)>
|
||||
iterator operator()(T value) {
|
||||
// MSVC2013 fails to compile separate overloads for bool and char_type so
|
||||
// use std::is_same instead.
|
||||
if (std::is_same<T, bool>::value) {
|
||||
format_specs& fmt_specs = *this->specs();
|
||||
if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
|
||||
fmt_specs.type = 0;
|
||||
this->write(value != 0);
|
||||
} else if (std::is_same<T, char_type>::value) {
|
||||
format_specs& fmt_specs = *this->specs();
|
||||
if (fmt_specs.type && fmt_specs.type != 'c')
|
||||
return (*this)(static_cast<int>(value));
|
||||
fmt_specs.sign = sign::none;
|
||||
fmt_specs.alt = false;
|
||||
fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types.
|
||||
// align::numeric needs to be overwritten here since the '0' flag is
|
||||
// ignored for non-numeric types
|
||||
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
|
||||
fmt_specs.align = align::right;
|
||||
return base::operator()(value);
|
||||
} else {
|
||||
return base::operator()(value);
|
||||
}
|
||||
return this->out();
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
||||
iterator operator()(T value) {
|
||||
return base::operator()(value);
|
||||
}
|
||||
|
||||
/** Formats a null-terminated C string. */
|
||||
iterator operator()(const char* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
else if (this->specs()->type == 'p')
|
||||
write_null_pointer(char_type());
|
||||
else
|
||||
this->write("(null)");
|
||||
return this->out();
|
||||
}
|
||||
|
||||
/** Formats a null-terminated wide C string. */
|
||||
iterator operator()(const wchar_t* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
else if (this->specs()->type == 'p')
|
||||
write_null_pointer(char_type());
|
||||
else
|
||||
this->write(L"(null)");
|
||||
return this->out();
|
||||
}
|
||||
|
||||
iterator operator()(basic_string_view<char_type> value) {
|
||||
return base::operator()(value);
|
||||
}
|
||||
|
||||
iterator operator()(monostate value) { return base::operator()(value); }
|
||||
|
||||
/** Formats a pointer. */
|
||||
iterator operator()(const void* value) {
|
||||
if (value) return base::operator()(value);
|
||||
this->specs()->type = 0;
|
||||
write_null_pointer(char_type());
|
||||
return this->out();
|
||||
}
|
||||
|
||||
/** Formats an argument of a custom (user-defined) type. */
|
||||
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
|
||||
handle.format(context_.parse_context(), context_);
|
||||
return this->out();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct printf_formatter {
|
||||
printf_formatter() = delete;
|
||||
|
||||
template <typename ParseContext>
|
||||
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
detail::format_value(detail::get_container(ctx.out()), value);
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
This template formats data and writes the output through an output iterator.
|
||||
*/
|
||||
template <typename OutputIt, typename Char> class basic_printf_context {
|
||||
public:
|
||||
/** The character type for the output. */
|
||||
using char_type = Char;
|
||||
using iterator = OutputIt;
|
||||
using format_arg = basic_format_arg<basic_printf_context>;
|
||||
using parse_context_type = basic_printf_parse_context<Char>;
|
||||
template <typename T> using formatter_type = printf_formatter<T>;
|
||||
|
||||
private:
|
||||
using format_specs = basic_format_specs<char_type>;
|
||||
|
||||
OutputIt out_;
|
||||
basic_format_args<basic_printf_context> args_;
|
||||
parse_context_type parse_ctx_;
|
||||
|
||||
static void parse_flags(format_specs& specs, const Char*& it,
|
||||
const Char* end);
|
||||
|
||||
// Returns the argument with specified index or, if arg_index is -1, the next
|
||||
// argument.
|
||||
format_arg get_arg(int arg_index = -1);
|
||||
|
||||
// Parses argument index, flags and width and returns the argument index.
|
||||
int parse_header(const Char*& it, const Char* end, format_specs& specs);
|
||||
|
||||
public:
|
||||
/**
|
||||
\rst
|
||||
Constructs a ``printf_context`` object. References to the arguments are
|
||||
stored in the context object so make sure they have appropriate lifetimes.
|
||||
\endrst
|
||||
*/
|
||||
basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
|
||||
basic_format_args<basic_printf_context> args)
|
||||
: out_(out), args_(args), parse_ctx_(format_str) {}
|
||||
|
||||
OutputIt out() { return out_; }
|
||||
void advance_to(OutputIt it) { out_ = it; }
|
||||
|
||||
detail::locale_ref locale() { return {}; }
|
||||
|
||||
format_arg arg(int id) const { return args_.get(id); }
|
||||
|
||||
parse_context_type& parse_context() { return parse_ctx_; }
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
parse_ctx_.on_error(message);
|
||||
}
|
||||
|
||||
/** Formats stored arguments and writes the output to the range. */
|
||||
template <typename ArgFormatter = printf_arg_formatter<OutputIt, Char>>
|
||||
OutputIt format();
|
||||
};
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
|
||||
const Char*& it,
|
||||
const Char* end) {
|
||||
for (; it != end; ++it) {
|
||||
switch (*it) {
|
||||
case '-':
|
||||
specs.align = align::left;
|
||||
break;
|
||||
case '+':
|
||||
specs.sign = sign::plus;
|
||||
break;
|
||||
case '0':
|
||||
specs.fill[0] = '0';
|
||||
break;
|
||||
case ' ':
|
||||
if (specs.sign != sign::plus) {
|
||||
specs.sign = sign::space;
|
||||
}
|
||||
break;
|
||||
case '#':
|
||||
specs.alt = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
typename basic_printf_context<OutputIt, Char>::format_arg
|
||||
basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
|
||||
if (arg_index < 0)
|
||||
arg_index = parse_ctx_.next_arg_id();
|
||||
else
|
||||
parse_ctx_.check_arg_id(--arg_index);
|
||||
return detail::get_arg(*this, arg_index);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
int basic_printf_context<OutputIt, Char>::parse_header(const Char*& it,
|
||||
const Char* end,
|
||||
format_specs& specs) {
|
||||
int arg_index = -1;
|
||||
char_type c = *it;
|
||||
if (c >= '0' && c <= '9') {
|
||||
// Parse an argument index (if followed by '$') or a width possibly
|
||||
// preceded with '0' flag(s).
|
||||
detail::error_handler eh;
|
||||
int value = parse_nonnegative_int(it, end, eh);
|
||||
if (it != end && *it == '$') { // value is an argument index
|
||||
++it;
|
||||
arg_index = value;
|
||||
} else {
|
||||
if (c == '0') specs.fill[0] = '0';
|
||||
if (value != 0) {
|
||||
// Nonzero value means that we parsed width and don't need to
|
||||
// parse it or flags again, so return now.
|
||||
specs.width = value;
|
||||
return arg_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_flags(specs, it, end);
|
||||
// Parse width.
|
||||
if (it != end) {
|
||||
if (*it >= '0' && *it <= '9') {
|
||||
detail::error_handler eh;
|
||||
specs.width = parse_nonnegative_int(it, end, eh);
|
||||
} else if (*it == '*') {
|
||||
++it;
|
||||
specs.width = static_cast<int>(visit_format_arg(
|
||||
detail::printf_width_handler<char_type>(specs), get_arg()));
|
||||
}
|
||||
}
|
||||
return arg_index;
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
template <typename ArgFormatter>
|
||||
OutputIt basic_printf_context<OutputIt, Char>::format() {
|
||||
auto out = this->out();
|
||||
const Char* start = parse_ctx_.begin();
|
||||
const Char* end = parse_ctx_.end();
|
||||
auto it = start;
|
||||
while (it != end) {
|
||||
char_type c = *it++;
|
||||
if (c != '%') continue;
|
||||
if (it != end && *it == c) {
|
||||
out = std::copy(start, it, out);
|
||||
start = ++it;
|
||||
continue;
|
||||
}
|
||||
out = std::copy(start, it - 1, out);
|
||||
|
||||
format_specs specs;
|
||||
specs.align = align::right;
|
||||
|
||||
// Parse argument index, flags and width.
|
||||
int arg_index = parse_header(it, end, specs);
|
||||
if (arg_index == 0) on_error("argument not found");
|
||||
|
||||
// Parse precision.
|
||||
if (it != end && *it == '.') {
|
||||
++it;
|
||||
c = it != end ? *it : 0;
|
||||
if ('0' <= c && c <= '9') {
|
||||
detail::error_handler eh;
|
||||
specs.precision = parse_nonnegative_int(it, end, eh);
|
||||
} else if (c == '*') {
|
||||
++it;
|
||||
specs.precision = static_cast<int>(
|
||||
visit_format_arg(detail::printf_precision_handler(), get_arg()));
|
||||
} else {
|
||||
specs.precision = 0;
|
||||
}
|
||||
}
|
||||
|
||||
format_arg arg = get_arg(arg_index);
|
||||
// For d, i, o, u, x, and X conversion specifiers, if a precision is
|
||||
// specified, the '0' flag is ignored
|
||||
if (specs.precision >= 0 && arg.is_integral())
|
||||
specs.fill[0] =
|
||||
' '; // Ignore '0' flag for non-numeric types or if '-' present.
|
||||
if (specs.precision >= 0 && arg.type() == detail::type::cstring_type) {
|
||||
auto str = visit_format_arg(detail::get_cstring<Char>(), arg);
|
||||
auto str_end = str + specs.precision;
|
||||
auto nul = std::find(str, str_end, Char());
|
||||
arg = detail::make_arg<basic_printf_context>(basic_string_view<Char>(
|
||||
str,
|
||||
detail::to_unsigned(nul != str_end ? nul - str : specs.precision)));
|
||||
}
|
||||
if (specs.alt && visit_format_arg(detail::is_zero_int(), arg))
|
||||
specs.alt = false;
|
||||
if (specs.fill[0] == '0') {
|
||||
if (arg.is_arithmetic() && specs.align != align::left)
|
||||
specs.align = align::numeric;
|
||||
else
|
||||
specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types or if '-'
|
||||
// flag is also present.
|
||||
}
|
||||
|
||||
// Parse length and convert the argument to the required type.
|
||||
c = it != end ? *it++ : 0;
|
||||
char_type t = it != end ? *it : 0;
|
||||
using detail::convert_arg;
|
||||
switch (c) {
|
||||
case 'h':
|
||||
if (t == 'h') {
|
||||
++it;
|
||||
t = it != end ? *it : 0;
|
||||
convert_arg<signed char>(arg, t);
|
||||
} else {
|
||||
convert_arg<short>(arg, t);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (t == 'l') {
|
||||
++it;
|
||||
t = it != end ? *it : 0;
|
||||
convert_arg<long long>(arg, t);
|
||||
} else {
|
||||
convert_arg<long>(arg, t);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
convert_arg<intmax_t>(arg, t);
|
||||
break;
|
||||
case 'z':
|
||||
convert_arg<size_t>(arg, t);
|
||||
break;
|
||||
case 't':
|
||||
convert_arg<std::ptrdiff_t>(arg, t);
|
||||
break;
|
||||
case 'L':
|
||||
// printf produces garbage when 'L' is omitted for long double, no
|
||||
// need to do the same.
|
||||
break;
|
||||
default:
|
||||
--it;
|
||||
convert_arg<void>(arg, c);
|
||||
}
|
||||
|
||||
// Parse type.
|
||||
if (it == end) FMT_THROW(format_error("invalid format string"));
|
||||
specs.type = static_cast<char>(*it++);
|
||||
if (arg.is_integral()) {
|
||||
// Normalize type.
|
||||
switch (specs.type) {
|
||||
case 'i':
|
||||
case 'u':
|
||||
specs.type = 'd';
|
||||
break;
|
||||
case 'c':
|
||||
visit_format_arg(detail::char_converter<basic_printf_context>(arg),
|
||||
arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = it;
|
||||
|
||||
// Format argument.
|
||||
out = visit_format_arg(ArgFormatter(out, specs, *this), arg);
|
||||
}
|
||||
return std::copy(start, it, out);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
using basic_printf_context_t =
|
||||
basic_printf_context<std::back_insert_iterator<detail::buffer<Char>>, Char>;
|
||||
|
||||
using printf_context = basic_printf_context_t<char>;
|
||||
using wprintf_context = basic_printf_context_t<wchar_t>;
|
||||
|
||||
using printf_args = basic_format_args<printf_context>;
|
||||
using wprintf_args = basic_format_args<wprintf_context>;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an `~fmt::format_arg_store` object that contains references to
|
||||
arguments and can be implicitly converted to `~fmt::printf_args`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline format_arg_store<printf_context, Args...> make_printf_args(
|
||||
const Args&... args) {
|
||||
return {args...};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an `~fmt::format_arg_store` object that contains references to
|
||||
arguments and can be implicitly converted to `~fmt::wprintf_args`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
|
||||
const Args&... args) {
|
||||
return {args...};
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vsprintf(
|
||||
const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::string message = fmt::sprintf("The answer is %d", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vsprintf(to_string_view(format), make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vfprintf(
|
||||
std::FILE* f, const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
size_t size = buffer.size();
|
||||
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
|
||||
? -1
|
||||
: static_cast<int>(size);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the file *f*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::fprintf(stderr, "Don't %s!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vfprintf(f, to_string_view(format),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vprintf(
|
||||
const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
return vfprintf(stdout, to_string_view(format), args);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to ``stdout``.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::printf("Elapsed time: %.2f seconds", 1.23);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
inline int printf(const S& format_str, const Args&... args) {
|
||||
using context = basic_printf_context_t<char_t<S>>;
|
||||
return vprintf(to_string_view(format_str),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vfprintf(
|
||||
std::basic_ostream<Char>& os, const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
detail::write_buffer(os, buffer);
|
||||
return static_cast<int>(buffer.size());
|
||||
}
|
||||
|
||||
/** Formats arguments and writes the output to the range. */
|
||||
template <typename ArgFormatter, typename Char,
|
||||
typename Context =
|
||||
basic_printf_context<typename ArgFormatter::iterator, Char>>
|
||||
typename ArgFormatter::iterator vprintf(
|
||||
detail::buffer<Char>& out, basic_string_view<Char> format_str,
|
||||
basic_format_args<type_identity_t<Context>> args) {
|
||||
typename ArgFormatter::iterator iter(out);
|
||||
Context(iter, format_str, args).template format<ArgFormatter>();
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the stream *os*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::fprintf(cerr, "Don't %s!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
|
||||
const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vfprintf(os, to_string_view(format_str),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_PRINTF_H_
|
||||
386
external/fmtlib/include/fmt/ranges.h
vendored
386
external/fmtlib/include/fmt/ranges.h
vendored
@@ -1,386 +0,0 @@
|
||||
// Formatting library for C++ - experimental range support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
//
|
||||
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
|
||||
// All Rights Reserved
|
||||
// {fmt} support for ranges, containers and types tuple interface.
|
||||
|
||||
#ifndef FMT_RANGES_H_
|
||||
#define FMT_RANGES_H_
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
// output only up to N items from the range.
|
||||
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
|
||||
# define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename Char> struct formatting_base {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Enable = void>
|
||||
struct formatting_range : formatting_base<Char> {
|
||||
static FMT_CONSTEXPR_DECL const size_t range_length_limit =
|
||||
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the
|
||||
// range.
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_range() : prefix('{'), delimiter(','), postfix('}') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
|
||||
template <typename Char, typename Enable = void>
|
||||
struct formatting_tuple : formatting_base<Char> {
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_tuple() : prefix('('), delimiter(','), postfix(')') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename RangeT, typename OutputIterator>
|
||||
OutputIterator copy(const RangeT& range, OutputIterator out) {
|
||||
for (auto it = range.begin(), end = range.end(); it != end; ++it)
|
||||
*out++ = *it;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
OutputIterator copy(const char* str, OutputIterator out) {
|
||||
while (*str) *out++ = *str++;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
OutputIterator copy(char ch, OutputIterator out) {
|
||||
*out++ = ch;
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Return true value if T has std::string interface, like std::string_view.
|
||||
template <typename T> class is_like_std_string {
|
||||
template <typename U>
|
||||
static auto check(U* p)
|
||||
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
is_string<T>::value || !std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_like_std_string<fmt::basic_string_view<Char>> : std::true_type {};
|
||||
|
||||
template <typename... Ts> struct conditional_helper {};
|
||||
|
||||
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
|
||||
|
||||
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
|
||||
template <typename T>
|
||||
struct is_range_<
|
||||
T, conditional_t<false,
|
||||
conditional_helper<decltype(std::declval<T>().begin()),
|
||||
decltype(std::declval<T>().end())>,
|
||||
void>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/// tuple_size and tuple_element check.
|
||||
template <typename T> class is_tuple_like_ {
|
||||
template <typename U>
|
||||
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
// Check for integer_sequence
|
||||
#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900
|
||||
template <typename T, T... N>
|
||||
using integer_sequence = std::integer_sequence<T, N...>;
|
||||
template <size_t... N> using index_sequence = std::index_sequence<N...>;
|
||||
template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
|
||||
#else
|
||||
template <typename T, T... N> struct integer_sequence {
|
||||
using value_type = T;
|
||||
|
||||
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
|
||||
};
|
||||
|
||||
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
|
||||
|
||||
template <typename T, size_t N, T... Ns>
|
||||
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
|
||||
template <typename T, T... Ns>
|
||||
struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
|
||||
|
||||
template <size_t N>
|
||||
using make_index_sequence = make_integer_sequence<size_t, N>;
|
||||
#endif
|
||||
|
||||
template <class Tuple, class F, size_t... Is>
|
||||
void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) FMT_NOEXCEPT {
|
||||
using std::get;
|
||||
// using free function get<I>(T) now.
|
||||
const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
|
||||
(void)_; // blocks warnings
|
||||
}
|
||||
|
||||
template <class T>
|
||||
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes(
|
||||
T const&) {
|
||||
return {};
|
||||
}
|
||||
|
||||
template <class Tuple, class F> void for_each(Tuple&& tup, F&& f) {
|
||||
const auto indexes = get_indexes(tup);
|
||||
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename Arg, FMT_ENABLE_IF(!is_like_std_string<
|
||||
typename std::decay<Arg>::type>::value)>
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
|
||||
return add_space ? " {}" : "{}";
|
||||
}
|
||||
|
||||
template <typename Arg, FMT_ENABLE_IF(is_like_std_string<
|
||||
typename std::decay<Arg>::type>::value)>
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
|
||||
return add_space ? " \"{}\"" : "\"{}\"";
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char*) {
|
||||
return add_space ? " \"{}\"" : "\"{}\"";
|
||||
}
|
||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) {
|
||||
return add_space ? L" \"{}\"" : L"\"{}\"";
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char) {
|
||||
return add_space ? " '{}'" : "'{}'";
|
||||
}
|
||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
|
||||
return add_space ? L" '{}'" : L"'{}'";
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> struct is_tuple_like {
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
|
||||
};
|
||||
|
||||
template <typename TupleT, typename Char>
|
||||
struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> {
|
||||
private:
|
||||
// C++11 generic lambda for format()
|
||||
template <typename FormatContext> struct format_each {
|
||||
template <typename T> void operator()(const T& v) {
|
||||
if (i > 0) {
|
||||
if (formatting.add_prepostfix_space) {
|
||||
*out++ = ' ';
|
||||
}
|
||||
out = detail::copy(formatting.delimiter, out);
|
||||
}
|
||||
out = format_to(out,
|
||||
detail::format_str_quoted(
|
||||
(formatting.add_delimiter_spaces && i > 0), v),
|
||||
v);
|
||||
++i;
|
||||
}
|
||||
|
||||
formatting_tuple<Char>& formatting;
|
||||
size_t& i;
|
||||
typename std::add_lvalue_reference<decltype(
|
||||
std::declval<FormatContext>().out())>::type out;
|
||||
};
|
||||
|
||||
public:
|
||||
formatting_tuple<Char> formatting;
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return formatting.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext = format_context>
|
||||
auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
size_t i = 0;
|
||||
detail::copy(formatting.prefix, out);
|
||||
|
||||
detail::for_each(values, format_each<FormatContext>{formatting, i, out});
|
||||
if (formatting.add_prepostfix_space) {
|
||||
*out++ = ' ';
|
||||
}
|
||||
detail::copy(formatting.postfix, out);
|
||||
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Char> struct is_range {
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
detail::is_range_<T>::value && !detail::is_like_std_string<T>::value &&
|
||||
!std::is_convertible<T, std::basic_string<Char>>::value &&
|
||||
!std::is_constructible<detail::std_string_view<Char>, T>::value;
|
||||
};
|
||||
|
||||
template <typename RangeT, typename Char>
|
||||
struct formatter<RangeT, Char,
|
||||
enable_if_t<fmt::is_range<RangeT, Char>::value>> {
|
||||
formatting_range<Char> formatting;
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return formatting.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format(const RangeT& values,
|
||||
FormatContext& ctx) {
|
||||
auto out = detail::copy(formatting.prefix, ctx.out());
|
||||
size_t i = 0;
|
||||
auto it = values.begin();
|
||||
auto end = values.end();
|
||||
for (; it != end; ++it) {
|
||||
if (i > 0) {
|
||||
if (formatting.add_prepostfix_space) *out++ = ' ';
|
||||
out = detail::copy(formatting.delimiter, out);
|
||||
}
|
||||
out = format_to(out,
|
||||
detail::format_str_quoted(
|
||||
(formatting.add_delimiter_spaces && i > 0), *it),
|
||||
*it);
|
||||
if (++i > formatting.range_length_limit) {
|
||||
out = format_to(out, " ... <other elements>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (formatting.add_prepostfix_space) *out++ = ' ';
|
||||
return detail::copy(formatting.postfix, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename... T> struct tuple_arg_join : detail::view {
|
||||
const std::tuple<T...>& tuple;
|
||||
basic_string_view<Char> sep;
|
||||
|
||||
tuple_arg_join(const std::tuple<T...>& t, basic_string_view<Char> s)
|
||||
: tuple{t}, sep{s} {}
|
||||
};
|
||||
|
||||
template <typename Char, typename... T>
|
||||
struct formatter<tuple_arg_join<Char, T...>, Char> {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx) {
|
||||
return format(value, ctx, detail::make_index_sequence<sizeof...(T)>{});
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename FormatContext, size_t... N>
|
||||
typename FormatContext::iterator format(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
|
||||
detail::index_sequence<N...>) {
|
||||
return format_args(value, ctx, std::get<N>(value.tuple)...);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format_args(
|
||||
const tuple_arg_join<Char, T...>&, FormatContext& ctx) {
|
||||
// NOTE: for compilers that support C++17, this empty function instantiation
|
||||
// can be replaced with a constexpr branch in the variadic overload.
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
template <typename FormatContext, typename Arg, typename... Args>
|
||||
typename FormatContext::iterator format_args(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
|
||||
const Arg& arg, const Args&... args) {
|
||||
using base = formatter<typename std::decay<Arg>::type, Char>;
|
||||
auto out = ctx.out();
|
||||
out = base{}.format(arg, ctx);
|
||||
if (sizeof...(Args) > 0) {
|
||||
out = std::copy(value.sep.begin(), value.sep.end(), out);
|
||||
ctx.advance_to(out);
|
||||
return format_args(value, ctx, args...);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `tuple` with elements separated by `sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::tuple<int, char> t = {1, 'a'};
|
||||
fmt::print("{}", fmt::join(t, ", "));
|
||||
// Output: "1, a"
|
||||
\endrst
|
||||
*/
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR tuple_arg_join<char, T...> join(const std::tuple<T...>& tuple,
|
||||
string_view sep) {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR tuple_arg_join<wchar_t, T...> join(const std::tuple<T...>& tuple,
|
||||
wstring_view sep) {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `initializer_list` with elements separated by
|
||||
`sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
||||
// Output: "1, 2, 3"
|
||||
\endrst
|
||||
*/
|
||||
template <typename T>
|
||||
arg_join<const T*, const T*, char> join(std::initializer_list<T> list,
|
||||
string_view sep) {
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
arg_join<const T*, const T*, wchar_t> join(std::initializer_list<T> list,
|
||||
wstring_view sep) {
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_RANGES_H_
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
declare -A configurations
|
||||
|
||||
declare -A EXTRA_MODULE_FLAGS
|
||||
EXTRA_MODULE_FLAGS[opm-simulators]="-DBUILD_EBOS_EXTENSIONS=ON -DBUILD_EBOS_DEBUG_EXTENSIONS=ON -DBUILD_FLOW_VARIANTS=ON -DOPM_ENABLE_PYTHON=ON -DBUILD_FLOW_POLY_GRID=ON"
|
||||
EXTRA_MODULE_FLAGS[opm-common]="-DOPM_ENABLE_PYTHON=ON -DOPM_ENABLE_EMBEDDED_PYTHON=ON -DOPM_INSTALL_PYTHON=ON"
|
||||
|
||||
# Parse revisions from trigger comment and setup arrays
|
||||
# Depends on: 'upstreams', upstreamRev',
|
||||
# 'downstreams', 'downstreamRev',
|
||||
@@ -83,26 +79,10 @@ function printHeader {
|
||||
# $2 = 0 to build and install module, 1 to build and test module
|
||||
# $3 = Source root of module to build
|
||||
function build_module {
|
||||
CMAKE_PARAMS="$1"
|
||||
DO_TEST_FLAG="$2"
|
||||
MOD_SRC_DIR="$3"
|
||||
cmake "$MOD_SRC_DIR" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=$DO_TEST_FLAG -DCMAKE_TOOLCHAIN_FILE=${configurations[$configuration]} $CMAKE_PARAMS
|
||||
cmake $3 -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=$2 -DCMAKE_TOOLCHAIN_FILE=${configurations[$configuration]} $1
|
||||
test $? -eq 0 || exit 1
|
||||
if test $DO_TEST_FLAG -eq 1
|
||||
if test $2 -eq 1
|
||||
then
|
||||
|
||||
pushd "$CWD"
|
||||
cd "$MOD_SRC_DIR"
|
||||
if test -x "./jenkins/pre-build.sh"; then
|
||||
echo "Running pre-build script"
|
||||
if ! "./jenkins/pre-build.sh"; then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No pre-build script detected"
|
||||
fi
|
||||
popd
|
||||
|
||||
if [ ! -z $BUILDTHREADS ]
|
||||
then
|
||||
cmake --build . -- -j$BUILDTHREADS
|
||||
@@ -110,12 +90,11 @@ function build_module {
|
||||
cmake --build .
|
||||
fi
|
||||
test $? -eq 0 || exit 2
|
||||
TESTTHREADS=${TESTTHREADS:-1}
|
||||
if test -z "$CTEST_CONFIGURATION"
|
||||
then
|
||||
ctest -T Test --no-compress-output -j$TESTTHREADS
|
||||
ctest -T Test --no-compress-output
|
||||
else
|
||||
ctest -j$TESTTHREADS -C $CTEST_CONFIGURATION --timeout 5000 -T Test --no-compress-output
|
||||
ctest -C $CTEST_CONFIGURATION --timeout 5000 -T Test --no-compress-output
|
||||
fi
|
||||
|
||||
# Convert to junit format
|
||||
@@ -146,7 +125,12 @@ function clone_module {
|
||||
mkdir -p $WORKSPACE/deps/$1
|
||||
cd $WORKSPACE/deps/$1
|
||||
git init .
|
||||
git remote add origin https://github.com/OPM/$1
|
||||
if [ "$1" == "libecl" ]
|
||||
then
|
||||
git remote add origin https://github.com/Statoil/$1
|
||||
else
|
||||
git remote add origin https://github.com/OPM/$1
|
||||
fi
|
||||
git fetch --depth 1 origin $2:branch_to_build
|
||||
git checkout branch_to_build
|
||||
git log HEAD -1 | cat
|
||||
@@ -180,7 +164,7 @@ function build_upstreams {
|
||||
do
|
||||
echo "Building upstream $upstream=${upstreamRev[$upstream]} configuration=$configuration"
|
||||
# Build upstream and execute installation
|
||||
clone_and_build_module $upstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install ${EXTRA_MODULE_FLAGS[$upstream]}" ${upstreamRev[$upstream]} $WORKSPACE/$configuration
|
||||
clone_and_build_module $upstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install" ${upstreamRev[$upstream]} $WORKSPACE/$configuration
|
||||
test $? -eq 0 || exit 1
|
||||
done
|
||||
test $? -eq 0 || exit 1
|
||||
@@ -195,7 +179,7 @@ function build_downstreams {
|
||||
do
|
||||
echo "Building downstream $downstream=${downstreamRev[$downstream]} configuration=$configuration"
|
||||
# Build downstream and execute installation
|
||||
clone_and_build_module $downstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT ${EXTRA_MODULE_FLAGS[$downstream]}" ${downstreamRev[$downstream]} $WORKSPACE/$configuration 1
|
||||
clone_and_build_module $downstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT" ${downstreamRev[$downstream]} $WORKSPACE/$configuration 1
|
||||
test $? -eq 0 || exit 1
|
||||
|
||||
# Installation for downstream
|
||||
@@ -232,7 +216,7 @@ function build_module_full {
|
||||
mkdir -p $configuration/build-$1
|
||||
cd $configuration/build-$1
|
||||
echo "Building main module $1=$sha1 configuration=$configuration"
|
||||
build_module "-DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT ${EXTRA_MODULE_FLAGS[$1]}" 1 $WORKSPACE
|
||||
build_module "-DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT" 1 $WORKSPACE
|
||||
test $? -eq 0 || exit 1
|
||||
cmake --build . --target install
|
||||
test $? -eq 0 || exit 1
|
||||
|
||||
@@ -6,15 +6,17 @@ source `dirname $0`/build-opm-module.sh
|
||||
mkdir deps
|
||||
ln -sf $WORKSPACE deps/opm-common
|
||||
|
||||
# No upstreams
|
||||
declare -a upstreams
|
||||
upstreams=(libecl)
|
||||
|
||||
declare -A upstreamRev
|
||||
upstreamRev[libecl]=master
|
||||
|
||||
# Downstreams and revisions
|
||||
declare -a downstreams
|
||||
downstreams=(opm-material
|
||||
opm-grid
|
||||
opm-models
|
||||
ewoms
|
||||
opm-simulators
|
||||
opm-upscaling
|
||||
)
|
||||
@@ -22,7 +24,7 @@ downstreams=(opm-material
|
||||
declare -A downstreamRev
|
||||
downstreamRev[opm-material]=master
|
||||
downstreamRev[opm-grid]=master
|
||||
downstreamRev[opm-models]=master
|
||||
downstreamRev[ewoms]=master
|
||||
downstreamRev[opm-simulators]=master
|
||||
downstreamRev[opm-upscaling]=master
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user