Compare commits

..

4 Commits

Author SHA1 Message Date
Arne Morten Kvarving
8f297e2079 bump versions for final 2018-10-24 13:35:03 +02:00
Arne Morten Kvarving
1e77807ff0 correct packaging versions 2018-10-04 06:06:01 +02:00
Joakim Hove
a732ddeb50
Merge pull request #512 from joakim-hove/bump-versions
Bump versions to 2018.10-rc1
2018-10-02 15:50:58 +02:00
Joakim Hove
4768b5cd95 Bump versions to 2018.10-rc1 2018-10-02 15:27:41 +02:00
3479 changed files with 73992 additions and 1466378 deletions

View File

@ -1,19 +0,0 @@
{
BasedOnStyle: WebKit,
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
View File

@ -69,7 +69,3 @@ install
# emacs directory setting:
.dir-locals.el
*.pyc
*.eggs
*.egg-info

0
.gitmodules vendored
View File

View File

@ -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 "Install python bindings?" ON)
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)
@ -32,30 +27,27 @@ set(OPM_PROJECT_EXTRA_CODE_INSTALLED "#ENABLE_ECL_INPUT is needed by opm-common
set(ENABLE_ECL_INPUT ${ENABLE_ECL_INPUT})
set(OPM_MACROS_ROOT ${CMAKE_INSTALL_PREFIX}/share/opm)
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)
include(OpmPackage) #Make macros available after find_package(opm-common)")
include(OpmPackage) #Make macros availabe after find_package(opm-common)")
set(OPM_PROJECT_EXTRA_CODE_INTREE "#ENABLE_ECL_INPUT is needed by opm-common-prereq.cmake
set(ENABLE_ECL_INPUT ${ENABLE_ECL_INPUT})
set(OPM_MACROS_ROOT ${OPM_MACROS_ROOT})
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)
include(OpmPackage) #Make macros available after find_package(opm-common)")
include(OpmPackage) #Make macros availabe after find_package(opm-common)")
if(ENABLE_ECL_OUTPUT)
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
set(COMPARE_ECL_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/compareECL)
set(OPM_PACK_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/opmpack)
set(RST_DECK_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/rst_deck)")
set(OPM_PACK_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/opmpack)")
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
set(COMPARE_ECL_COMMAND ${PROJECT_BINARY_DIR}/bin/compareECL)
set(OPM_PACK_COMMAND ${PROJECT_BINARY_DIR}/bin/opmpack)
set(RST_DECK_COMMAND ${PROJECT_BINARY_DIR}/bin/rst_deck)")
set(OPM_PACK_COMMAND ${PROJECT_BINARY_DIR}/bin/opmpack)")
endif()
# project information is in dune.module. Read this file and set variables.
# 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.
@ -66,30 +58,18 @@ include(Findopm-tests)
# with the find module
include (${project}-prereqs)
# 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()
include(DownloadFmt)
endif()
if(OPM_ENABLE_EMBEDDED_PYTHON AND NOT OPM_ENABLE_PYTHON)
# This needs to be here to run before source_hook
message(WARNING "Inconsistent settings: OPM_ENABLE_PYTHON=OFF and "
"OPM_ENABLE_EMBEDDED_PYTHON=ON. Please use OPM_ENABLE_PYTHON=ON to "
"activate. Will disable embedded python in this run.")
set(OPM_ENABLE_EMBEDDED_PYTHON OFF CACHE BOOL "Enable embedded python?" FORCE)
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)
macro (config_hook)
if(ENABLE_ECL_INPUT)
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}
@ -99,7 +79,6 @@ macro (config_hook)
set(HAVE_ECL_INPUT 1)")
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
set(HAVE_ECL_INPUT 1)")
set(HAVE_ECL_INPUT 1)
endif()
if(ENABLE_ECL_OUTPUT)
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
@ -107,58 +86,27 @@ macro (config_hook)
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
set(HAVE_ECL_OUTPUT 1)")
endif()
# We need to use the correct search mode. Otherwise not finding one
# boost component beloq will mark the previously found ones as not
# found again. (Code stolen from UseDynamicBoost.cmake
if(Boost_DIR)
set(_Boost_CONFIG_MODE CONFIG)
endif()
find_package(Boost COMPONENTS filesystem regex system unit_test_framework ${_Boost_CONFIG_MODE})
# Configure boost targets for old cmake
include(cmake/Modules/BoostTargets.cmake)
if (HAVE_DYNAMIC_BOOST_TEST)
set_target_properties(Boost::unit_test_framework PROPERTIES INTERFACE_COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK=1)
endif()
endif()
endmacro (config_hook)
macro (prereqs_hook)
endmacro (prereqs_hook)
macro (sources_hook)
if(NOT cjson_FOUND)
include(DownloadCjson)
include_directories(${cjson_SOURCE_DIR})
list(APPEND opm-common_SOURCES ${cjson_SOURCE_DIR}/cJSON.c)
endif()
if(ENABLE_ECL_INPUT)
# Keyword generation
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)
list(INSERT opm-common_SOURCES 0 ${PROJECT_BINARY_DIR}/ParserKeywords/ParserInit${name}.cpp)
list(INSERT opm-common_SOURCES 0 ${PROJECT_BINARY_DIR}/ParserKeywords/Builtin${name}.cpp)
list(INSERT opm-common_HEADERS 0 ${PROJECT_BINARY_DIR}/include/opm/input/eclipse/Parser/ParserKeywords/${name}.hpp)
endforeach()
if (OPM_ENABLE_EMBEDDED_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/input/eclipse/Python/Python.cpp
PROPERTIES COMPILE_FLAGS -Wno-shadow)
if(QuadMath_FOUND)
get_target_property(qm_defs QuadMath::QuadMath INTERFACE_COMPILE_DEFINITIONS)
get_target_property(qm_options QuadMath::QuadMath INTERFACE_COMPILE_OPTIONS)
set_source_files_properties(src/opm/material/components/CO2.cpp
src/opm/material/densead/Evaluation.cpp
PROPERTIES COMPILE_DEFINITIONS "${qm_defs}"
COMPILE_OPTIONS "${qm_options}")
endif()
endmacro (sources_hook)
macro (fortran_hook)
@ -179,305 +127,40 @@ macro (install_hook)
PATTERN *.hpp)
endmacro (install_hook)
# Used to append entries from one list to another.
# The output list is suitable for use in setup.py subtitution
macro(append_quoted OUT IN)
foreach(ENTRY ${${IN}})
list(APPEND ${OUT} "'${ARGN}${ENTRY}'")
endforeach()
endmacro()
# 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
# OpmLibMain 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})
set(Python3_VERSION "${PYTHON_VERSION_STRING}")
set(Python3_VERSION_MINOR ${PYTHON_VERSION_MINOR})
else()
# Be backwards compatible.
if(PYTHON_EXECUTABLE AND NOT Python3_EXECUTABLE)
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
endif()
# We always need to search for Development as we use
# pybind11_add_module even if don't embed Python
if (NOT OPM_ENABLE_EMBEDDED_PYTHON)
if(${CMAKE_VERSION} VERSION_LESS "3.18.0")
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
else()
find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
endif()
else()
if(${CMAKE_VERSION} VERSION_LESS "3.18.0")
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
else()
find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Embed Development.Module)
endif()
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})
endif()
if(Python3_VERSION_MINOR LESS 3)
# Python native namespace packages requires python >= 3.3
message(SEND_ERROR "OPM requires python >= 3.3 but only version ${Python3_VERSION} was found")
endif()
# Compatibility settings for PythonInterp and PythonLibs
# used e.g. in FindCwrap, pybind11
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
# Directory to install common (for opm modules) python scripts
include (GNUInstallDirs)
set(OPM_PYTHON_COMMON_DIR "${CMAKE_INSTALL_DATAROOTDIR}/opm/python")
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
set(opm-common_PYTHON_COMMON_DIR ${PROJECT_SOURCE_DIR}/python)")
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
set(opm-common_PYTHON_COMMON_DIR ${CMAKE_INSTALL_PREFIX}/${OPM_PYTHON_COMMON_DIR})")
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)
include(DownloadPyBind11)
endif()
endif()
# all setup common to the OPM library modules is done here
include (OpmLibMain)
if (ENABLE_MOCKSIM AND ENABLE_ECL_INPUT)
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()
# 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(arraylist
test_util/arraylist.cpp
)
add_executable(rewriteEclFile
test_util/rewriteEclFile.cpp
)
foreach(target compareECL convertECL summary rewriteEclFile arraylist)
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
)
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()
# Explicitly link tests needing dune-common.
# To avoid pulling dune-common into the opm-common interface
find_package(dune-common REQUIRED)
opm_need_version_of ("dune-common")
target_include_directories(dunecommon INTERFACE ${dune-common_INCLUDE_DIRS})
string(REPLACE " " ";" dflags "${dune-common_CXX_FLAGS}")
target_compile_options(dunecommon INTERFACE ${dflags})
target_compile_definitions(dunecommon INTERFACE DUNE_COMMON_VERSION_MAJOR=${DUNE_COMMON_VERSION_MAJOR})
target_compile_definitions(dunecommon INTERFACE DUNE_COMMON_VERSION_MINOR=${DUNE_COMMON_VERSION_MINOR})
target_compile_definitions(dunecommon INTERFACE DUNE_COMMON_VERSION_REVISION=${DUNE_COMMON_VERSION_REVISION})
if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
foreach(src ${DUNE_TEST_SOURCE_FILES})
get_filename_component(tgt ${src} NAME_WE)
target_link_libraries(${tgt} dunecommon)
endforeach()
endif()
if(BUILD_EXAMPLES)
target_link_libraries(co2brinepvt dunecommon)
install(TARGETS co2brinepvt DESTINATION bin)
endif()
# Install build system files and documentation
install(DIRECTORY cmake
DESTINATION share/opm USE_SOURCE_PERMISSIONS
PATTERN "OPM-CMake.md" EXCLUDE)
install(FILES cmake/OPM-CMake.md
DESTINATION ${CMAKE_INSTALL_DOCDIR})
# Install build system files
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)
make_directory(${PROJECT_BINARY_DIR}/python)
set(opm-common_PYTHON_PACKAGE_VERSION ${OPM_PYTHON_PACKAGE_VERSION_TAG})
add_custom_target(copy_python ALL
COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/install.py ${PROJECT_SOURCE_DIR}/python ${PROJECT_BINARY_DIR} 0)
file(COPY ${PROJECT_SOURCE_DIR}/python/README.md DESTINATION ${PROJECT_BINARY_DIR}/python)
pybind11_add_module(opmcommon_python
${PYTHON_CXX_SOURCE_FILES}
${PROJECT_BINARY_DIR}/python/cxx/builtin_pybind11.cpp)
target_link_libraries(opmcommon_python PRIVATE
opmcommon)
if(TARGET pybind11::pybind11)
target_link_libraries(opmcommon_python PRIVATE
pybind11::pybind11)
else()
target_include_directories(opmcommon_python SYSTEM PRIVATE ${pybind11_INCLUDE_DIRS})
endif()
set_target_properties(opmcommon_python PROPERTIES
LIBRARY_OUTPUT_DIRECTORY python/opm)
add_dependencies(opmcommon_python copy_python)
# Generate versioned setup.py
configure_file(${PROJECT_SOURCE_DIR}/python/setup.py.in
${PROJECT_BINARY_DIR}/python/setup.py.tmp)
file(GENERATE OUTPUT ${PROJECT_BINARY_DIR}/python/setup.py
INPUT ${PROJECT_BINARY_DIR}/python/setup.py.tmp)
# 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)
include(PyInstallPrefix)
install(TARGETS opmcommon_python DESTINATION ${DEST_PREFIX}${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX}/opm)
install(
CODE "execute_process(
COMMAND ${PYTHON_EXECUTABLE}
python/install.py
${PROJECT_BINARY_DIR}/python/opm
${DEST_PREFIX}${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX} 1)")
## Need to install this Python script such that it can be used by opm-simulators when building against an installed
## opm-common
install( PROGRAMS "python/install.py" DESTINATION "${OPM_PYTHON_COMMON_DIR}" )
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} -m unittest discover
)
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-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()
endif()
install(DIRECTORY docs/man1 DESTINATION ${CMAKE_INSTALL_MANDIR}
FILES_MATCHING PATTERN "*.1")

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +1,21 @@
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/input/eclipse/Parser/ParserKeywords/Builtin.hpp
${BASE_DIR}/include/opm/input/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/input/eclipse/Parser/ParserKeywords/*.hpp)
file(GLOB HDRS ${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords/*.hpp)
foreach(HDR ${HDRS})
file(RELATIVE_PATH hdr ${BASE_DIR}/tmp_gen/include/opm/input/eclipse/Parser/ParserKeywords ${HDR})
file(RELATIVE_PATH hdr ${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords ${HDR})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
${HDR}
${BASE_DIR}/include/opm/input/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)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
${BASE_DIR}/tmp_gen/ParserKeywords/ParserInit${name}.cpp
${BASE_DIR}/ParserKeywords/ParserInit${name}.cpp)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
${BASE_DIR}/tmp_gen/ParserKeywords/Builtin${name}.cpp
${BASE_DIR}/ParserKeywords/Builtin${name}.cpp)
${BASE_DIR}/include/opm/parser/eclipse/Parser/ParserKeywords/${hdr})
endforeach()

View File

@ -1,30 +1,35 @@
# 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}
TEST_ARGS -- ${_testdir}/)
TEST_ARGS ${_testdir}/)
list(APPEND EXTRA_TESTS ParserTests)
opm_add_test(ParserIncludeTests
SOURCES tests/parser/ParserIncludeTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS -- ${_testdir}/parser/)
TEST_ARGS ${_testdir}/parser/)
target_compile_definitions(ParserIncludeTests PRIVATE
-DHAVE_CASE_SENSITIVE_FILESYSTEM=${HAVE_CASE_SENSITIVE_FILESYSTEM})
list(APPEND EXTRA_TESTS ParserIncludeTests)
@ -32,48 +37,36 @@ list(APPEND EXTRA_TESTS ParserIncludeTests)
opm_add_test(PvtxTableTests
SOURCES tests/parser/PvtxTableTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS -- ${_testdir}/integration_tests/)
TEST_ARGS ${_testdir}/integration_tests/)
list(APPEND EXTRA_TESTS PvtxTableTests)
opm_add_test(EclipseStateTests
SOURCES tests/parser/EclipseStateTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS -- ${_testdir}/integration_tests/)
TEST_ARGS ${_testdir}/integration_tests/)
list(APPEND EXTRA_TESTS EclipseStateTests)
foreach (test BoxTest
CarfinTest
CheckDeckValidity
EclipseGridCreateFromDeck
IncludeTest
IntegrationTests
IOConfigIntegrationTest
NNCTests
ParseKEYWORD
ParseDATAWithDefault
Polymer
ResinsightTest
ScheduleCreateFromDeck
TransMultIntegrationTests)
opm_add_test(${test}
SOURCES tests/parser/integration/${test}.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS -- ${_testdir}/integration_tests/)
TEST_ARGS ${_testdir}/integration_tests/)
list(APPEND EXTRA_TESTS ${test})
endforeach ()
add_test( NAME rst_deck_test
COMMAND ${PROJECT_SOURCE_DIR}/tests/rst_test_driver.sh ${PROJECT_BINARY_DIR}/bin/rst_deck ${PROJECT_BINARY_DIR}/bin/opmhash
${PROJECT_SOURCE_DIR}/tests/SPE1CASE2_INCLUDE.DATA)
add_test( NAME rst_deck_test2
COMMAND ${PROJECT_SOURCE_DIR}/tests/rst_test_driver2.sh
${PROJECT_BINARY_DIR}/bin/rst_deck
${PROJECT_BINARY_DIR}/bin/opmi
${PROJECT_SOURCE_DIR}/tests/ACTIONX_M1.DATA
${PROJECT_SOURCE_DIR}/tests/ACTIONX_M1_MULTIPLE.DATA
${PROJECT_SOURCE_DIR}/tests/ACTIONX_M1.UNRST
${PROJECT_SOURCE_DIR}/tests/ACTIONX_M1.X0010 )
# opm-tests dependent tests
if(HAVE_OPM_TESTS)
opm_add_test(parse_write ONLY_COMPILE
@ -93,44 +86,22 @@ 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.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}/spe10model1/SPE10_MODEL1.DATA
${OPM_TESTS_ROOT}/spe10model2/SPE10_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")
add_test( NAME rst_deck_test_norne
COMMAND ${PROJECT_SOURCE_DIR}/tests/rst_test_driver.sh ${PROJECT_BINARY_DIR}/bin/rst_deck ${PROJECT_BINARY_DIR}/bin/opmhash
${OPM_TESTS_ROOT}/norne/NORNE_ATW2013.DATA)
set_property(TEST rst_deck_test_norne
PROPERTY ENVIRONMENT "OPM_ERRORS_IGNORE=PARSE_RANDOM_SLASH")
endif()
# JSON tests
opm_add_test(jsonTests
SOURCES tests/json/jsonTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${PROJECT_SOURCE_DIR}/tests/json/example1.json)
list(APPEND EXTRA_TESTS jsonTests)
endif()

View File

@ -1,31 +1,23 @@
set(genkw_SOURCES src/opm/json/JsonObject.cpp
src/opm/input/eclipse/Parser/createDefaultKeywordList.cpp
src/opm/input/eclipse/Deck/UDAValue.cpp
src/opm/input/eclipse/Deck/DeckTree.cpp
src/opm/input/eclipse/Deck/DeckValue.cpp
src/opm/input/eclipse/Deck/Deck.cpp
src/opm/input/eclipse/Deck/DeckView.cpp
src/opm/input/eclipse/Deck/DeckItem.cpp
src/opm/input/eclipse/Deck/DeckKeyword.cpp
src/opm/input/eclipse/Deck/DeckRecord.cpp
src/opm/input/eclipse/Deck/DeckOutput.cpp
src/opm/input/eclipse/Generator/KeywordGenerator.cpp
src/opm/input/eclipse/Generator/KeywordLoader.cpp
src/opm/input/eclipse/Schedule/UDQ/UDQEnums.cpp
src/opm/input/eclipse/Parser/ErrorGuard.cpp
src/opm/input/eclipse/Parser/ParseContext.cpp
src/opm/input/eclipse/Parser/ParserEnums.cpp
src/opm/input/eclipse/Parser/ParserItem.cpp
src/opm/input/eclipse/Parser/ParserKeyword.cpp
src/opm/input/eclipse/Parser/ParserRecord.cpp
src/opm/input/eclipse/Parser/raw/RawKeyword.cpp
src/opm/input/eclipse/Parser/raw/RawRecord.cpp
src/opm/input/eclipse/Parser/raw/StarToken.cpp
src/opm/input/eclipse/Units/Dimension.cpp
src/opm/input/eclipse/Units/UnitSystem.cpp
src/opm/common/utility/OpmInputError.cpp
src/opm/common/utility/shmatch.cpp
src/opm/common/utility/String.cpp
src/opm/parser/eclipse/Parser/createDefaultKeywordList.cpp
src/opm/parser/eclipse/Deck/Deck.cpp
src/opm/parser/eclipse/Deck/DeckItem.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/Generator/KeywordGenerator.cpp
src/opm/parser/eclipse/Generator/KeywordLoader.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/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/Stringview.cpp
src/opm/common/OpmLog/OpmLog.cpp
src/opm/common/OpmLog/Logger.cpp
src/opm/common/OpmLog/StreamLog.cpp
@ -33,62 +25,30 @@ set(genkw_SOURCES src/opm/json/JsonObject.cpp
src/opm/common/OpmLog/LogUtil.cpp
)
if(NOT cjson_FOUND)
list(APPEND genkw_SOURCES ${cjson_SOURCE_DIR}/cJSON.c)
list(APPEND genkw_SOURCES external/cjson/cJSON.c)
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/input/eclipse/share/keywords/keyword_list.cmake)
string(REGEX REPLACE "([^;]+)" "${PROJECT_SOURCE_DIR}/src/opm/input/eclipse/share/keywords/\\1" keyword_files "${keywords}")
configure_file(src/opm/input/eclipse/keyword_list.argv.in keyword_list.argv)
include(src/opm/parser/eclipse/share/keywords/keyword_list.cmake)
string(REGEX REPLACE "([^;]+)" "${PROJECT_SOURCE_DIR}/src/opm/parser/eclipse/share/keywords/\\1" keyword_files "${keywords}")
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/input/eclipse/Parser/ParserKeywords
${PROJECT_BINARY_DIR}/tmp_gen/TestKeywords.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(APPEND _tmp_output ${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/${name}.cpp
${PROJECT_BINARY_DIR}/tmp_gen/include/opm/input/eclipse/Parser/ParserKeywords/${name}.hpp
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/ParserInit${name}.cpp
${PROJECT_BINARY_DIR}/tmp_gen/ParserKeywords/Builtin${name}.cpp
${PROJECT_BINARY_DIR}/tmp_gen/include/opm/input/eclipse/Parser/ParserKeywords/ParserInit${name}.hpp)
list(APPEND _target_output ${PROJECT_BINARY_DIR}/ParserKeywords/${name}.cpp
${PROJECT_BINARY_DIR}/include/opm/input/eclipse/Parser/ParserKeywords/${name}.hpp
${PROJECT_BINARY_DIR}/ParserKeywords/ParserInit${name}.cpp
${PROJECT_BINARY_DIR}/ParserKeywords/Builtin${name}.cpp
${PROJECT_BINARY_DIR}/include/opm/input/eclipse/Parser/ParserKeywords/ParserInit${name}.hpp)
endforeach()
foreach(name TestKeywords.cpp ParserInit.cpp)
list(APPEND _target_output ${PROJECT_BINARY_DIR}/${name})
list(APPEND _tmp_output ${PROJECT_BINARY_DIR}/tmp_gen/${name})
endforeach()
list(APPEND _target_output ${PROJECT_BINARY_DIR}/include/opm/input/eclipse/Parser/ParserKeywords/Builtin.hpp)
list(APPEND _tmp_output ${PROJECT_BINARY_DIR}/tmp_gen/include/opm/input/eclipse/Parser/ParserKeywords/Builtin.hpp)
set(GEN_DEPS ${_tmp_output})
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)
list(APPEND GEN_DEPS copy_python)
endif()
add_custom_command( OUTPUT
${_tmp_output}
COMMAND genkw ${genkw_argv}
DEPENDS genkw ${keyword_files} src/opm/input/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 ${GEN_DEPS}
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)

View File

@ -1,23 +1,3 @@
# opm-common: Tools for Eclipse reservoir simulation files
The Open Porous Media (OPM) software suite provides libraries and
tools for modeling and simulation of porous media processes,
especially for simulating CO2 sequestration and improved and enhanced
oil recovery. The Eclipse file format is widely used in the reservoir
simulation community. This package provides a library containing code
for processing files in Eclipse format, Python binding for accessing
Eclipse files and utility code used by other OPM modules (e.g. CMake
modules used).
License
-------
The library is distributed under the GNU General Public License,
version 3 or later (GPLv3+).
Requirements
-----------
- C++17 compatible compiler
- CMake >= 3.10
- Posix compatibility
# opm-common
Contains common components used throughout all of OPM,
in particular CMake modules for the build system.

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -0,0 +1,49 @@
# make targets for boost if find module did not do the job
if(NOT TARGET Boost::system)
add_library(Boost::system UNKNOWN IMPORTED)
set_target_properties(Boost::system PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
IMPORTED_LOCATION "${Boost_SYSTEM_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_SYSTEM_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_SYSTEM_LIBRARY_RELEASE}"
)
endif()
if(NOT TARGET Boost::filesystem)
add_library(Boost::filesystem UNKNOWN IMPORTED)
set_target_properties(Boost::filesystem PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_COMPILE_DEFINITIONS BOOST_FILESYSTEM_VERSION=3
INTERFACE_LINK_LIBRARIES "${boost_system}"
IMPORTED_LOCATION "${Boost_FILESYSTEM_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_FILESYSTEM_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_FILESYSTEM_LIBRARY_RELEASE}"
)
endif()
if(NOT TARGET Boost::regex)
add_library(Boost::regex UNKNOWN IMPORTED)
set_target_properties(Boost::regex PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${boost_system}"
IMPORTED_LOCATION "${Boost_REGEX_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_REGEX_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_REGEX_LIBRARY_RELEASE}"
)
endif()
if(NOT TARGET Boost::unit_test_framework)
add_library(Boost::unit_test_framework UNKNOWN IMPORTED)
set_target_properties(Boost::unit_test_framework PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${boost_system}"
IMPORTED_LOCATION "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}"
)
endif()

View File

@ -1,18 +0,0 @@
include(FetchContent)
FetchContent_Declare(cjson
DOWNLOAD_EXTRACT_TIMESTAMP ON
URL https://github.com/DaveGamble/cJSON/archive/refs/tags/v1.7.16.tar.gz
URL_HASH SHA512=3a894de03c33d89f1e7ee572418d5483c844d38e1e64aa4f6297ddaa01f4111f07601f8d26617b424b5af15d469e3955dae075d9f30b5c25e16ec348fdb06e6f)
FetchContent_Populate(cjson)
# set(ENABLE_CJSON_TEST OFF CACHE BOOL "")
# set(BUILD_SHARED_AND_STATIC_LIBS OFF CACHE BOOL "")
# set(CJSON_BUILD_SHARED_LIBS OFF CACHE BOOL "")
# set(CJSON_OVERRIDE_BUILD_SHARED_LIBS ON CACHE BOOL "")
# add_subdirectory(${cjson_SOURCE_DIR} ${cjson_BINARY_DIR})
# add_library(cjson::cjson STATIC IMPORTED)
# set_target_properties(cjson::cjson PROPERTIES
# INTERFACE_INCLUDE_DIRECTORIES ${cjson_SOURCE_DIR}
# IMPORTED_LOCATION lib/libcjson.a)

View File

@ -1,17 +0,0 @@
include(FetchContent)
if(NOT fmt_POPULATED)
FetchContent_Declare(fmt
DOWNLOAD_EXTRACT_TIMESTAMP ON
URL https://github.com/fmtlib/fmt/archive/refs/tags/10.1.1.tar.gz
URL_HASH SHA512=288c349baac5f96f527d5b1bed0fa5f031aa509b4526560c684281388e91909a280c3262a2474d963b5d1bf7064b1c9930c6677fe54a0d8f86982d063296a54c)
FetchContent_Populate(fmt)
endif()
# We do not want to use the target directly as that means it ends up
# in our depends list for downstream modules and the installation list.
# Instead, we just download and use header only mode.
add_compile_definitions(FMT_HEADER_ONLY)
include_directories(${fmt_SOURCE_DIR}/include)
set(fmt_POPULATED ${fmt_POPULATED} PARENT_SCOPE)
set(fmt_SOURCE_DIR ${fmt_SOURCE_DIR} PARENT_SCOPE)

View File

@ -1,6 +0,0 @@
include(FetchContent)
FetchContent_Declare(pybind11
DOWNLOAD_EXTRACT_TIMESTAMP ON
URL https://github.com/pybind/pybind11/archive/refs/tags/v2.11.1.tar.gz
URL_HASH SHA512=ed1512ff0bca3bc0a45edc2eb8c77f8286ab9389f6ff1d5cb309be24bc608abbe0df6a7f5cb18c8f80a3bfa509058547c13551c3cd6a759af708fd0cdcdd9e95)
FetchContent_MakeAvailable(pybind11)

View File

@ -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()

View 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()

View 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
View 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
)

View 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)

View File

@ -1,31 +0,0 @@
# - Find the GNU Multiprecision library.
#
# Will define the following imported target for usage:
# - GMP::gmp Target for linking/compiling with C library
# - GMP::gmpxx Target for linking/compiling with C++ library
find_path(GMP_INCLUDE_DIR gmp.h)
find_library(GMP_LIBRARY gmp)
find_path(GMPXX_INCLUDE_DIR gmpxx.h)
find_library(GMPXX_LIBRARY gmpxx)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GMP
DEFAULT_MSG
GMPXX_LIBRARY GMPXX_INCLUDE_DIR GMP_INCLUDE_DIR GMP_LIBRARY)
if(GMP_FOUND)
if(NOT TARGET GMP::gmp)
add_library(GMP::gmp UNKNOWN IMPORTED GLOBAL)
set_target_properties(GMP::gmp PROPERTIES
IMPORTED_LOCATION ${GMP_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${GMP_INCLUDE_DIR})
endif()
if(NOT TARGET GMP::gmpxx)
add_library(GMP::gmpxx UNKNOWN IMPORTED GLOBAL)
set_target_properties(GMP::gmpxx PROPERTIES
IMPORTED_LOCATION ${GMPXX_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${GMPXX_INCLUDE_DIR}
TARGET_LINK_LIBRARIES GMP::gmp)
endif()
endif()

View File

@ -8,11 +8,7 @@
# HAVE_METIS - like METIS_FOUND, but for the inclusion in config.h
# METIS_INCLUDE_DIRS - incude paths to use libMETIS
# METIS_LIBRARIES - Link these to use libMETIS
# METIS::METIS - Imported metis target needed for DUNE 2.8.0
# METIS_API_VERSION - The METIS api version scotch is supporting.
set(METIS_API_VERSION 0 CACHE STRING
"METIS API version provided by METIS or scotch-metis library")
set(METIS_SEARCH_PATH "/usr" "/usr/local" "/opt" "/opt/local")
set(METIS_NO_DEFAULT_PATH "")
if(METIS_ROOT)
@ -39,29 +35,9 @@ find_library(METIS_LIBRARIES
${METIS_NO_DEFAULT_PATH})
set (METIS_FOUND FALSE)
if (METIS_INCLUDE_DIRS OR METIS_LIBRARIES)
set(METIS_FOUND TRUE)
set(HAVE_METIS TRUE)
file(READ "${METIS_INCLUDE_DIRS}/metis.h" metisheader)
string(REGEX MATCH "#define METIS_VER_MAJOR[ ]+([0-9]+)" METIS_MAJOR_VERSION ${metisheader})
if(NOT METIS_API_VERSION AND METIS_MAJOR_VERSION)
string(REGEX REPLACE ".*#define METIS_VER_MAJOR[ ]+([0-9]+).*" "\\1"
METIS_MAJOR_VERSION "${metisheader}")
if(METIS_MAJOR_VERSION GREATER_EQUAL 3 AND METIS_MAJOR_VERSION LESS 5)
set(METIS_API_VERSION "3")
else()
set(METIS_API_VERSION "${METIS_MAJOR_VERSION}")
endif()
endif()
if (NOT TARGET METIS::METIS)
add_library(METIS::METIS UNKNOWN IMPORTED)
set_target_properties(METIS::METIS PROPERTIES
IMPORTED_LOCATION ${METIS_LIBRARIES}
INTERFACE_INCLUDE_DIRECTORIES ${METIS_INCLUDE_DIRS}
INTERFACE_COMPILE_DEFINITIONS METIS_API_VERSION=${METIS_API_VERSION})
endif()
endif()
# print a message to indicate status of this package

View File

@ -70,20 +70,6 @@ if(PTSCOTCH_FOUND)
set(PTSCOCH_LINK_FLAGS "${DUNE_MPI_LINK_FLAGS}"
CACHE STRING "PT-Scotch link flags")
set(HAVE_PTSCOTCH 1)
if(NOT TARGET PTScotch::Scotch)
add_library(PTScotch::Scotch UNKNOWN IMPORTED GLOBAL)
set_target_properties(PTScotch::Scotch PROPERTIES
IMPORTED_LOCATION "${SCOTCH_LIBRARY}"
INCLUDE_DIRECTORIES "${PTSCOTCH_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${PTSCOTCHERR_LIBRARY}")
endif()
if(NOT TARGET PTScotch::PTScotch)
add_library(PTScotch::PTScotch UNKNOWN IMPORTED GLOBAL)
set_target_properties(PTScotch::PTScotch PROPERTIES
IMPORTED_LOCATION "${PTSCOTCH_LIBRARY}"
INCLUDE_DIRECTORIES "${PTSCOTCH_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "PTScotch::Scotch;${MPI_DUNE_LIBRARIES}")
endif()
# log result
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determing location of PT-Scotch succeded:\n"

View File

@ -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}"
@ -102,13 +88,6 @@ if(PARMETIS_FOUND)
"Include directory: ${PARMETIS_INCLUDE_DIRS}\n"
"Library directory: ${PARMETIS_LIBRARIES}\n\n")
if(NOT TARGET ParMETIS::ParMETIS)
add_library(ParMETIS::ParMETIS UNKNOWN IMPORTED GLOBAL)
set_target_properties(ParMETIS::ParMETIS PROPERTIES
IMPORTED_LOCATION ${PARMETIS_LIBRARY}
INCLUDE_DIRECTORIES "${PARMETIS_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${METIS_LIBRARIES};${MPI_C_LIBRARIES}")
endif()
endif(PARMETIS_FOUND)
mark_as_advanced(PARMETIS_INCLUDE_DIRS PARMETIS_LIBRARIES HAVE_PARMETIS)

View File

@ -1,49 +0,0 @@
# Module that checks whether the compiler supports the
# quadruple precision floating point math
#
# Adds target QuadMath::QuadMath if found
#
# perform tests
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES quadmath)
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
set(CMAKE_REQUIRED_FLAGS "-fext-numeric-literals")
endif()
check_cxx_source_compiles("
#include <quadmath.h>
int main ()
{
__float128 r = 1.0q;
r = strtoflt128(\"1.2345678\", NULL);
return 0;
}" QuadMath_COMPILES)
cmake_pop_check_state() # Reset CMAKE_REQUIRED_XXX variables
if(QuadMath_COMPILES)
# Use additional variable for better report message
set(QuadMath_VAR "(Supported by compiler)")
endif()
# Report that package was found
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(QuadMath
DEFAULT_MSG
QuadMath_VAR QuadMath_COMPILES
)
# add imported target for quadmath
if(QuadMath_FOUND AND NOT TARGET QuadMath::QuadMath)
# Compiler supports QuadMath: Add appropriate linker flag
add_library(QuadMath::QuadMath INTERFACE IMPORTED)
target_link_libraries(QuadMath::QuadMath INTERFACE quadmath)
target_compile_definitions(QuadMath::QuadMath INTERFACE
_GLIBCXX_USE_FLOAT128 HAVE_QUAD=1
)
target_compile_options(QuadMath::QuadMath INTERFACE
$<$<CXX_COMPILER_ID:GNU>:-fext-numeric-literals>
)
endif()

View File

@ -0,0 +1,49 @@
# Module that checks whether the compiler supports the
# quadruple precision floating point math
#
# Sets the following variables:
# HAVE_QUAD
# QUADMATH_LIBRARIES
#
# perform tests
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
include(CheckCXXCompilerFlag)
if(NOT DEFINED USE_QUADMATH OR USE_QUADMATH)
if(NOT DEFINED HAVE_EXTENDED_NUMERIC_LITERALS)
check_cxx_compiler_flag("-Werror -fext-numeric-literals" HAVE_EXTENDED_NUMERIC_LITERALS)
endif()
if (HAVE_EXTENDED_NUMERIC_LITERALS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals")
endif()
cmake_push_check_state(RESET)
list(APPEND CMAKE_REQUIRED_LIBRARIES "quadmath")
CHECK_CXX_SOURCE_COMPILES("
#include <quadmath.h>
int main(void){
__float128 foo = sqrtq(123.456);
foo = FLT128_MIN;
}" QUADMATH_FOUND)
cmake_pop_check_state()
if (QUADMATH_FOUND)
set(QUADMATH_LIBRARIES "quadmath")
set(HAVE_QUAD "${QUADMATH_FOUND}")
endif()
endif()
if (USE_QUADMATH AND NOT QUADMATH_FOUND)
message(FATAL_ERROR "Quadruple precision math support was explicitly requested but is unavailable!")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Quadmath
DEFAULT_MSG
QUADMATH_LIBRARIES
HAVE_QUAD
)

View File

@ -259,9 +259,9 @@ foreach (module IN LISTS SuiteSparse_FIND_COMPONENTS)
set (SuiteSparse_FOUND FALSE)
# use empty string instead of zero, so it can be tested with #ifdef
# as well as #if in the source code
set (HAVE_SUITESPARSE_${MODULE}_H "" CACHE STRING "Is ${module} header present?")
set (HAVE_SUITESPARSE_${MODULE}_H "" CACHE INT "Is ${module} header present?")
else (NOT SuiteSparse_${MODULE}_FOUND)
set (HAVE_SUITESPARSE_${MODULE}_H 1 CACHE STRING "Is ${module} header present?")
set (HAVE_SUITESPARSE_${MODULE}_H 1 CACHE INT "Is ${module} header present?")
list (APPEND SuiteSparse_LIBRARIES "${${MODULE}_LIBRARIES}")
list (APPEND SuiteSparse_LINKER_FLAGS "${${MODULE}_LINKER_FLAGS}")
list (APPEND SuiteSparse_INCLUDE_DIRS "${${MODULE}_INCLUDE_DIRS}")
@ -280,32 +280,6 @@ if (SuiteSparse_LIBRARIES)
list (REVERSE SuiteSparse_LIBRARIES)
endif (SuiteSparse_LIBRARIES)
if(SuiteSparse_FOUND)
if(NOT TARGET SuiteSparse::SuiteSparse)
add_library(SuiteSparse::SuiteSparse INTERFACE IMPORTED GLOBAL)
set_property(TARGET SuiteSparse::SuiteSparse PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${SuiteSparse_INCLUDE_DIRS})
if(config_LIBRARY)
set_property(TARGET SuiteSparse::SuiteSparse PROPERTY
INTERFACE_LINK_LIBRARIES ${config_LIBRARY})
endif()
endif()
foreach(_module ${SuiteSparse_MODULES})
string (TOUPPER ${_module} _MODULE)
if(SuiteSparse_${_MODULE}_FOUND)
if(NOT TARGET SuiteSparse::${_module})
message(STATUS "Creating target SuiteSparse::${_module}")
add_library(SuiteSparse::${_module} UNKNOWN IMPORTED GLOBAL)
set_target_properties(SuiteSparse::${_module} PROPERTIES
IMPORTED_LOCATION ${${_MODULE}_LIBRARY}
INCLUDE_DIRECTORIES ${${_MODULE}_INCLUDE_DIRS}
INTERFACE_LINK_LIBRARIES "${config_LIBRARY}")
target_link_libraries(SuiteSparse::SuiteSparse
INTERFACE SuiteSparse::${_module})
endif()
endif()
endforeach(_module)
endif()
# print a message to indicate status of this package
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (SuiteSparse

View File

@ -180,16 +180,6 @@ if(SUPERLU_FOUND)
if (SUPERLU_BLAS_LIBRARY)
list(APPEND SUPERLU_LIBRARIES ${SUPERLU_BLAS_LIBRARY})
endif()
if(NOT TARGET SuperLU::SuperLU)
add_library(SuperLU::SuperLU UNKNOWN IMPORTED GLOBAL)
set_target_properties(SuperLU::SuperLU PROPERTIES
IMPORTED_LOCATION ${SUPERLU_LIBRARY}
INCLUDE_DIRECTORIES ${SUPERLU_INCLUDE_DIRS})
if(SUPERLU_BLAS_LIBRARY)
set_property(TARGET SuperLU::SuperLU PROPERTY
INTERFACE_LINK_LIBRARIES ${SUPERLU_BLAS_LIBRARY})
endif()
endif()
endif()
cmake_pop_check_state()

View File

@ -1,34 +0,0 @@
# Poor man's FindTBB that will create the CMake targets
# used by DUNE.
# If the TBB version is new enough it will ship its own
# TBBConfig.cmake and we are good
find_package(TBB QUIET CONFIG)
if(NOT TBB_FOUND)
# Fall back to using pkgconfig
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PkgConfigTBB IMPORTED_TARGET GLOBAL tbb QUIET)
if(NOT TARGET PkgConfig::PkgConfigTBB)
# workaround bug in old FindPkgConfig.cmake which adds
# pkgcfg_lib_PkgConfigTBB_atomic-NOTFOUND because it cannot
# find the atomic lib of the compiler (not in platforms default
# library path. It will therefore not create the target and we
# try that manually.
string(REPLACE ";pkgcfg_lib_PkgConfigTBB_atomic-NOTFOUND" "" _find_tbb_libs "${PkgConfigTBB_LINK_LIBRARIES}")
if(_find_tbb_libs)
add_library(PkgConfig::PkgConfigTBB INTERFACE IMPORTED GLOBAL)
set_property(TARGET PkgConfig::PkgConfigTBB PROPERTY
INTERFACE_LINK_LIBRARIES "${_find_tbb_libs}")
endif()
endif()
if(TARGET PkgConfig::PkgConfigTBB)
if(NOT TARGET TBB::tbb)
message(STATUS "Found TBB library using pkg config")
add_library(TBB::tbb ALIAS PkgConfig::PkgConfigTBB)
endif()
endif()
endif(PKG_CONFIG_FOUND)
else()
message(STATUS "Found TBB library using config mode")
endif(NOT TBB_FOUND)

View File

@ -3,10 +3,13 @@
# This module defines:
# VALGRIND_INCLUDE_DIR, where to find valgrind/memcheck.h, etc.
# VALGRIND_PROGRAM, the valgrind executable.
# Valgrind_FOUND, If false, do not try to use valgrind.
# VALGRIND_FOUND, If false, do not try to use valgrind.
#
# If you have valgrind installed in a non-standard place, you can define
# VALGRIND_ROOT to tell cmake where it is.
if (VALGRIND_FOUND)
return()
endif()
find_path(VALGRIND_INCLUDE_DIR valgrind/memcheck.h
/usr/include /usr/local/include ${VALGRIND_ROOT}/include)
@ -15,7 +18,7 @@ find_path(VALGRIND_INCLUDE_DIR valgrind/memcheck.h
# path, but this does not hurt...
find_program(VALGRIND_PROGRAM NAMES valgrind PATH ${VALGRIND_ROOT}/bin)
find_package_handle_standard_args(Valgrind DEFAULT_MSG
find_package_handle_standard_args(VALGRIND DEFAULT_MSG
VALGRIND_INCLUDE_DIR
VALGRIND_PROGRAM)

View File

@ -16,15 +16,12 @@ 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)
# search for files which implements this module
find_path (ZOLTAN_INCLUDE_DIR
find_path (ZOLTAN_INCLUDE_DIRS
NAMES "zoltan.h"
PATHS ${ZOLTAN_SEARCH_PATH}
PATH_SUFFIXES include trilinos
@ -35,35 +32,27 @@ if (CMAKE_SIZEOF_VOID_P)
math (EXPR _BITS "8 * ${CMAKE_SIZEOF_VOID_P}")
endif (CMAKE_SIZEOF_VOID_P)
find_library(ZOLTAN_LIBRARY
find_library(ZOLTAN_LIBRARIES
NAMES zoltan trilinos_zoltan
PATHS ${ZOLTAN_SEARCH_PATH}
PATH_SUFFIXES "lib/.libs" "lib" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
${ZOLTAN_NO_DEFAULT_PATH})
set (ZOLTAN_FOUND FALSE)
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_LIBRARY
ZOLTAN_INCLUDE_DIR
MPI_FOUND
ZOLTAN_LIBRARIES
ZOLTAN_INCLUDE_DIRS
)
if (ZOLTAN_FOUND)
set(HAVE_ZOLTAN 1)
set(ZOLTAN_LIBRARIES ${ZOLTAN_LIBRARY} ${PARMETIS_LIBRARIES} ${PTSCOTCH_LIBRARIES})
set(ZOLTAN_INCLUDE_DIRS ${ZOLTAN_INCLUDE_DIR} ${PARMETIS_INCLUDE_DIRS}
${PTSCOTCH_INCLUDE_DIRS})
# log result
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determing location of ZOLTAN succeeded:\n"
" Include directory: ${ZOLTAN_INCLUDE_DIRS}\n"
" Library directory: ${ZOLTAN_LIBRARIES}\n\n")
endif()

View File

@ -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,13 +36,17 @@ 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} )
# setup list of all required libraries to link with cjson
set (cjson_INCLUDE_DIRS ${CJSON_INCLUDE_DIR})
set (cjson_LIBRARIES ${CJSON_LIBRARY})
set (CJSON_INCLUDE_DIRS ${CJSON_INCLUDE_DIR})
set (CJSON_LIBRARIES ${CJSON_LIBRARY})
# math library (should exist on all unices; automatically linked on Windows)
if (UNIX)
@ -72,7 +81,10 @@ endif ()
# 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 (cjson
set (CJSON_FIND_REQUIRED ${cjson_FIND_REQUIRED})
set (CJSON_FIND_QUIETLY ${cjson_FIND_QUIETLY})
find_package_handle_standard_args (CJSON
DEFAULT_MSG
cjson_INCLUDE_DIRS cjson_LIBRARIES HAVE_CJSON
CJSON_INCLUDE_DIRS CJSON_LIBRARIES HAVE_CJSON
)
set (cjson_FOUND ${CJSON_FOUND})

View File

@ -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

View File

@ -16,12 +16,11 @@ find_opm_package (
"dune-common"
# dependencies
"BLAS REQUIRED;
"CXX11Features REQUIRED;
BLAS REQUIRED;
LAPACK REQUIRED;
CxaDemangle;
MPI;
TBB;
GMP
MPI
"
# header to search for
"dune/common/fvector.hh"
@ -30,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>

View File

@ -19,14 +19,13 @@ 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;
dune-polygongrid;
ZLIB;
ZOLTAN;
METIS;
QuadMath
METIS
"
# header to search for
"dune/fem/space/shapefunctionset/legendre.hh"

View File

@ -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;
}

View File

@ -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")

View File

@ -19,7 +19,7 @@ find_opm_package (
"dune-common REQUIRED;
ParMETIS;
SuperLU;
SuiteSparse COMPONENTS umfpack REQUIRED
SuiteSparse COMPONENTS umfpack
"
# header to search for
"dune/istl/bcrsmatrix.hh"

View File

@ -1,46 +0,0 @@
# - Find DUNE Fem library
#
# Defines the following variables:
# dune-polygongrid_INCLUDE_DIRS Directory of header files
# dune-polygongrid_LIBRARIES Directory of shared object files
# dune-polygongrid_DEFINITIONS Defines that must be set to compile
# dune-alugrid_CONFIG_VARS List of defines that should be in config.h
# HAVE_DUNE_POLYGONGRID Binary value to use in config.h
# Copyright (C) 2015 IRIS AS
# This code is licensed under The GNU General Public License v3.0
include (OpmPackage)
find_opm_package (
# module name
"dune-polygongrid"
# dependencies
# 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"
# header to search for
"dune/polygongrid/mesh.hh"
# library to search for
"dunepolygongrid"
# defines to be added to compilations
""
# test program
"#include <dune/polygongrid/mesh.hh>
int main (void) {
return 0;
}
"
# config variables
"HAVE_DUNE_POLYGONGRID
")
#debug_find_vars ("dune-polygongrid")
# make version number available in config.h
include (UseDuneVer)
find_dune_version ("dune" "polygongrid")

View File

@ -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
""

View File

@ -0,0 +1,169 @@
# translate a list of libraries into a command-line that can be passed to the
# compiler/linker. first parameter is the name of the variable that will
# receive this list, the rest is considered the list of libraries
function (linker_cmdline what INTO outvar FROM)
if (NOT (UNIX OR MSYS OR MINGW))
return ()
endif (NOT (UNIX OR MSYS OR MINGW))
# if we are going to put these in regexps, we must escape period
string (REPLACE "." "\\." esc_dl_pref "${CMAKE_SHARED_LIBRARY_PREFIX}")
string (REPLACE "." "\\." esc_dl_suff "${CMAKE_SHARED_LIBRARY_SUFFIX}")
string (REPLACE "." "\\." esc_ar_pref "${CMAKE_STATIC_LIBRARY_PREFIX}")
string (REPLACE "." "\\." esc_ar_suff "${CMAKE_STATIC_LIBRARY_PREFIX}")
# CMake loves absolute paths, whereas libtool won't have any of it!
# (you get an error message about argument not parsed). translate each
# of the libraries into a linker option
set (deplib_list "")
foreach (deplib IN LISTS ARGN)
# starts with a hyphen already? then just add it
string (SUBSTRING ${deplib} 0 1 dash)
if (${dash} STREQUAL "-")
list (APPEND deplib_list ${deplib})
else (${dash} STREQUAL "-")
# otherwise, parse the name into a directory and a name
get_filename_component (deplib_dir ${deplib} PATH)
get_filename_component (deplib_orig ${deplib} NAME)
string (REGEX REPLACE
"^${esc_dl_pref}(.*)${esc_dl_suff}$"
"\\1"
deplib_name
${deplib_orig}
)
string (REGEX REPLACE
"^${esc_ar_pref}(.*)${esc_ar_suff}$"
"\\1"
deplib_name
${deplib_name}
)
# directory and name each on their own; this is somewhat
# unsatisfactory because it may be that a system dir is specified
# by an earlier directory and you start picking up libraries from
# there instead of the "closest" path here. also, the soversion
# 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 "/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)
list (APPEND deplib_list "-l:${deplib_orig}")
else (deplib_orig STREQUAL deplib_name)
list (APPEND deplib_list "-l${deplib_name}")
endif (deplib_orig STREQUAL deplib_name)
endif (${dash} STREQUAL "-")
endforeach (deplib)
# caller determines whether we want it returned as a list or a string
if ("${what}" STREQUAL "LIST")
set (${outvar} ${deplib_list})
else ("${what}" STREQUAL "LIST")
set (${outvar} "${deplib_list}")
string (REPLACE ";" " " ${outvar} "${${outvar}}")
endif ("${what}" STREQUAL "LIST")
set (${outvar} "${${outvar}}" PARENT_SCOPE)
endfunction (linker_cmdline what INTO outvar FROM)
function (configure_la name target)
if (NOT (UNIX OR MSYS OR MINGW))
return ()
endif (NOT (UNIX OR MSYS OR MINGW))
# these generic variables are initialized from the project info
set (current "${${name}_VERSION_MAJOR}")
set (age "${${name}_VERSION_MINOR}")
set (inherited_linker_flags "${${name}_LINKER_FLAGS}")
set (dependency_libs "${${name}_LIBRARIES}")
# translate list of libraries to command line
linker_cmdline (LIST INTO dependency_libs FROM ${dependency_libs})
# convert from CMake list (i.e. semi-colon separated)
string (REPLACE ";" " " inherited_linker_flags "${inherited_linker_flags}")
string (REPLACE ";" " " dependency_libs "${dependency_libs}")
# this is the preferred installation path
set (libdir "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
# ${name}_LIBRARY_TYPE is either SHARED or STATIC
if (${name}_LIBRARY_TYPE STREQUAL "SHARED")
set (libprefix "${CMAKE_SHARED_LIBRARY_PREFIX}")
set (libsuffix "${CMAKE_SHARED_LIBRARY_SUFFIX}")
set (libname "${CMAKE_SHARED_LIBRARY_PREFIX}${target}${CMAKE_SHARED_LIBRARY_SUFFIX}")
# only Unix has soversion in library names
if (UNIX)
set (dlname "${libname}.${current}")
set (library_names "${libname}.${current}.${age} ${libname}.${current} ${libname}")
else (UNIX)
set (dlname "${libname}")
set (library_names "${libname}")
endif (UNIX)
set (old_library "")
else (${name}_LIBRARY_TYPE STREQUAL "SHARED")
set (dlname "")
set (library_names "")
set (old_library "${CMAKE_STATIC_LIBRARY_PREFIX}${target}${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif (${name}_LIBRARY_TYPE STREQUAL "SHARED")
# get the version of libtool installed on the system; this is
# necessary because libtool checks that the file contains its own
# signature(!)
if (NOT libtool_MAIN)
find_file (
libtool_MAIN
ltmain.sh
PATHS /usr
PATH_SUFFIXES share/libtool/config/
DOC "Location of libtool"
)
mark_as_advanced (libtool_MAIN)
# notify the user if it not found after we explicitly searched
if (NOT libtool_MAIN)
message (STATUS "Not generating libtool archive (.la) since libtool was not found")
endif (NOT libtool_MAIN)
endif (NOT libtool_MAIN)
if (libtool_MAIN)
file (STRINGS
${libtool_MAIN}
ltversion_STRING
REGEX "^VERSION=\".*\""
)
endif (libtool_MAIN)
if (ltversion_STRING)
string (REGEX REPLACE
"^VERSION=\"?(.*)\"?"
"\\1"
ltversion
${ltversion_STRING}
)
endif (ltversion_STRING)
# assume that we are in cmake/Modules, and that the template have been
# put in cmake/Templates. we cannot use CMAKE_CURRENT_LIST_DIR because
# this is in a function, and we cannot know who's calling us
set (templ_dir "${OPM_MACROS_ROOT}/cmake/Templates")
# only write an .la if libtool is found; otherwise we have no use
# for it.
if (ltversion)
set (la_file "lib${target}.la")
message (STATUS "Writing libtool archive for ${target}")
configure_file (
${templ_dir}/la.in
${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${la_file}
@ONLY@
)
else (ltversion)
set (la_file "")
endif (ltversion)
# return this variable to the caller
if (ARGV2)
set (${ARGV2} "${la_file}" PARENT_SCOPE)
endif (ARGV2)
endfunction (configure_la target)

View File

@ -1,16 +1,6 @@
# Installs bash tab completion for a product
macro(opm_add_bash_completion binary)
option(USE_BASH_COMPLETIONS_DIR
"Whether to use the new bash completion dir (/usr/share/bash-completion/completions) with load on demand"
OFF)
if(USE_BASH_COMPLETIONS_DIR)
set(_BASH_COMPLETION_FILE ${binary})
set(_BASH_COMPLETION_INSTALL_DIR ${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions)
else()
set(_BASH_COMPLETION_FILE ${binary}_bash_completion.sh)
set(_BASH_COMPLETION_INSTALL_DIR ${CMAKE_INSTALL_SYSCONFDIR}/bash_completion.d)
endif()
set(PRODUCT ${binary})
configure_file(${OPM_MACROS_ROOT}/etc/opm_bash_completion.sh.in ${_BASH_COMPLETION_FILE} @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/${_BASH_COMPLETION_FILE} DESTINATION ${_BASH_COMPLETION_INSTALL_DIR})
configure_file(${OPM_MACROS_ROOT}/etc/opm_bash_completion.sh.in ${binary}_bash_completion.sh @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/${binary}_bash_completion.sh DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/bash_completion.d)
endmacro()

View File

@ -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} ${${opm}_HEADERS})
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

View File

@ -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()

View File

@ -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.

View File

@ -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
@ -128,41 +153,46 @@ macro (find_and_append_package_to prefix name)
# We even need to repeat the search for opm-common once as this is done
# in the top most CMakeLists.txt without querying defines, setting dependencies
# and the likes which is only done via opm_find_package
string(REGEX MATCH "(opm)-.*" _is_opm ${name})
if(NOT _is_opm)
# When using Boost >= 1.70 and e.g. CMake 3.18 we need to make sure that
# subsequent searches are using config mode too. Otherwise the library
# list will be completely messed up. We use a set Boost_Dir to detect that
# previous searches were done using config mode.
if("${name}" STREQUAL "Boost" AND Boost_DIR)
set(_CONFIG_MODE CONFIG)
if ( (NOT DEFINED ${name}_FOUND AND NOT DEFINED ${NAME}_FOUND )
OR _search_components GREATER -1)
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()
set(_CONFIG_MODE "")
endif()
find_package (${name} ${ARGN} ${_CONFIG_MODE})
else()
if(${name}_DIR)
find_package (${name} ${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR} ${ARGN} NO_MODULE PATHS ${${name}_DIR} NO_DEFAULT_PATH)
else()
find_package (${name} ${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR} ${ARGN} NO_MODULE)
endif()
include(FindPackageHandleStandardArgs)
if( CMAKE_VERSION VERSION_GREATER_EQUAL "3.17")
# For some reason we will e.g. call
# find_package_handle_standard_args(opm-common)
# in a find_package(opm-material) call and this will
# usuallly print an annoying warnig. Prevent this at least
# for cmake >=3.17
# \todo Check why/whether these calls are even needed.
set(_NAME_MISMATCHED "NAME_MISMATCHED")
endif()
if(${name}_FOUND AND ${name}_LIBRARY STREQUAL "")
find_package_handle_standard_args(${name}
REQUIRED_VARS ${name}_INCLUDE_DIRS ${_NAME_MISMATCHED})
else()
find_package_handle_standard_args(${name}
REQUIRED_VARS ${name}_LIBRARY ${_NAME_MISMATCHED})
endif()
if(${name}_DIR)
find_package (${name} ${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR} ${ARGN} NO_MODULE PATHS ${${name}_DIR} NO_DEFAULT_PATH)
else()
find_package (${name} ${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR} ${ARGN} NO_MODULE)
endif()
include(FindPackageHandleStandardArgs)
if(${name}_FOUND AND ${name}_LIBRARY STREQUAL "")
find_package_handle_standard_args(${name}
REQUIRED_VARS ${name}_INCLUDE_DIRS)
else()
find_package_handle_standard_args(${name}
REQUIRED_VARS ${name}_LIBRARY)
endif()
endif ()
endif ()
if (NOT DEFINED ${name}_FOUND)
set (${name}_FOUND "${${NAME}_FOUND}")
@ -178,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

View File

@ -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}")
@ -110,10 +57,6 @@ macro (OpmInitDirVars)
endif (COMMAND dir_hook)
endmacro ()
if("${CMAKE_SIZEOF_VOID_P}" LESS 8)
message(FATAL_ERROR "OPM will only work correctly on 64bit (or higher) systems!")
endif()
OpmInitProjVars ()
OpmInitDirVars ()
@ -134,19 +77,14 @@ endif ()
# parallel computing must be explicitly enabled
# This needs to be in OpmInit as prereqs is called before OpmLibMain is included.
option (USE_MPI "Use Message Passing Interface for parallel computing" ON)
option (USE_MPI "Use Message Passing Interface for parallel computing" OFF)
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
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option (USE_SUPERLU "Use SuperLU direct solvers for AMG (if umfpack is not found)" ON)
if (NOT USE_SUPERLU)
set (CMAKE_DISABLE_FIND_PACKAGE_SuperLU TRUE)
# 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)
if (NOT USE_QUADMATH)
set (CMAKE_DISABLE_FIND_PACKAGE_QuadMath TRUE)
endif ()

View File

@ -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}/")

View File

@ -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)
@ -63,6 +96,9 @@ find_openmp (${project})
include (UseThreads)
find_threads (${project})
# SuperLU is optional
option (USE_SUPERLU "Use SuperLU direct solvers" OFF)
# PETSc is optional
option (USE_PETSC "Use PETSc iterative solvers" OFF)
@ -220,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

View File

@ -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,37 +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) # always evaluates to false, but makes tests with DUNE 2.6-2.7 work
# 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()
if(${module}_FOUND)
# No test code provided, mark compilation as successful
# if module was found
# Has to be cached because of scope. Otherwise it is not accessible
# where it is used.
set(HAVE_${MODULE} 1 CACHE BOOL "${module} found")
mark_as_advanced(HAVE_${MODULE})
endif(${module}_FOUND)
endif()
# 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
@ -182,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}")

View File

@ -1,5 +1,39 @@
# - Helper routines for opm-core like projects
include (LibtoolArchives) # linker_cmdline
# convert a list back to a command-line string
function (unseparate_args var_name prefix value)
separate_arguments (value)
foreach (item IN LISTS value)
set (prefixed_item "${prefix}${item}")
if (${var_name})
set (${var_name} "${${var_name}} ${prefixed_item}")
else (${var_name})
set (${var_name} "${prefixed_item}")
endif (${var_name})
endforeach (item)
set (${var_name} "${${var_name}}" PARENT_SCOPE)
endfunction (unseparate_args var_name prefix value)
# wrapper to set variables in pkg-config file
function (configure_pc_file name source dest prefix libdir includedir)
# escape set of standard strings
unseparate_args (includes "-I" "${${name}_INCLUDE_DIRS}")
unseparate_args (defs "" "${${name}_DEFINITIONS}")
linker_cmdline (STRING INTO libs FROM ${${name}_LIBRARIES})
# necessary to make these variables visible to configure_file
set (name "${${name}_NAME}")
set (description "${${name}_DESCRIPTION}")
set (major "${${name}_VERSION_MAJOR}")
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)
function (configure_cmake_file name variant version)
# declarative list of the variable names that are used in the template
# and that must be defined in the project to be exported
@ -21,12 +55,6 @@ function (configure_cmake_file name variant version)
foreach (suffix IN LISTS variable_suffices)
set (opm-project_${suffix} "${${name}_${suffix}}")
endforeach (suffix)
if (BUILD_SHARED_LIBS)
# No need to list shared libraries as the linker information is alread
# in the shared lib
string(REGEX REPLACE ";?[^;]*.so" "" opm-project_LIBRARIES "${opm-project_LIBRARIES}")
endif()
set (opm-project_NAME "${${name}_NAME}")
set (opm-project_NAME_UC "${${name}_NAME}")
string(TOUPPER "${opm-project_NAME}" opm-project_NAME_UC)
@ -58,29 +86,31 @@ function (opm_cmake_config name)
APPEND "${${name}_CONFIG_VARS}"
)
# config-mode .pc file; use this to find the build tree
configure_pc_file (
${name}
${template_dir}/opm-project.pc.in
${PROJECT_BINARY_DIR}/${${name}_NAME}.pc
${PROJECT_BINARY_DIR}
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
${PROJECT_SOURCE_DIR}
)
# The next replace will result in bogus entries if install directory is
# a subdirectory of source tree,
# 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}"
@ -111,4 +141,28 @@ function (opm_cmake_config name)
FILES ${PROJECT_BINARY_DIR}/${${name}_NAME}-config-version.cmake
DESTINATION share/cmake${${name}_VER_DIR}/${${name}_NAME}
)
# find-mode .pc file; use this to locate system installation
configure_pc_file (
${name}
${template_dir}/opm-project.pc.in
${PROJECT_BINARY_DIR}/${${name}_NAME}-install.pc
${CMAKE_INSTALL_PREFIX}
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${${name}_VER_DIR}
${CMAKE_INSTALL_PREFIX}/include${${name}_VER_DIR}
)
# put this in the right system location; if we have binaries then it
# should go in the arch-specific lib/ directory, otherwise use the
# common/noarch lib/ directory (these targets come from UseMultiArch)
if (${name}_TARGET)
set (_pkg_dir ${CMAKE_INSTALL_LIBDIR})
else ()
set (_pkg_dir lib)
endif ()
install (
FILES ${PROJECT_BINARY_DIR}/${${name}_NAME}-install.pc
DESTINATION ${CMAKE_INSTALL_PREFIX}/${_pkg_dir}/pkgconfig${${name}_VER_DIR}/
RENAME ${${name}_NAME}.pc
)
endfunction (opm_cmake_config name)

View File

@ -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,12 +303,7 @@ 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(HAVE_DYNAMIC_BOOST_TEST)
set_target_properties (${CURTEST_EXE_NAME} PROPERTIES
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
endif()
if(TARGET ${project}_prepare)
add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare)
endif()
@ -321,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})
@ -341,7 +330,7 @@ macro(opm_add_test TestName)
# has been specified to supervise the test binary, use it else
# run the test binary "naked".
if (CURTEST_DRIVER)
set(CURTEST_COMMAND ${CURTEST_DRIVER} ${CURTEST_DRIVER_ARGS} -e ${CURTEST_EXE_NAME} -- ${CURTEST_TEST_ARGS})
set(CURTEST_COMMAND ${CURTEST_DRIVER} ${CURTEST_DRIVER_ARGS} ${CURTEST_EXE_NAME} ${CURTEST_TEST_ARGS})
else()
set(CURTEST_COMMAND ${PROJECT_BINARY_DIR}/bin/${CURTEST_EXE_NAME})
if (CURTEST_TEST_ARGS)
@ -351,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()
@ -371,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()

View File

@ -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()

View File

@ -0,0 +1,103 @@
####################################################################
# #
# Setup static targets for all submodules. #
# Useful when building a static benchmark executable #
# #
####################################################################
# Macros
# Clone a git and build it statically
# If ARGN is specified installation is skipped, ARGN0 is
# a build-system target name and the rest of ARGN are build tool parameters
function(opm_from_git repo name revision)
if(ARGN)
list(GET ARGN 0 target)
list(REMOVE_AT ARGN 0)
# This is used for top build of benchmarks.
# Clones the local source tree and builds it against the static libraries,
# skipping the install step. Note that in pricinple URL instead of GIT_REPOSITORY
# could have been used, but externalproject cannot handle build directories
# which are a subdirectory of the source tree, and since that is typically the case
# we work-around by re-cloning the local git.
# The ommision of GIT_TAG ensures that we build the tip of the local git.
set(COMMANDS BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target ${target} -- ${ARGN}
GIT_TAG ${revision}
INSTALL_COMMAND)
else()
# This is used with "normal" static builds.
set(COMMANDS GIT_TAG ${revision})
endif()
externalproject_add(${name}-static
GIT_REPOSITORY ${repo}
PREFIX static/${name}
CONFIGURE_COMMAND PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/static/installed/lib/pkgconfig:${CMAKE_BINARY_DIR}/static/installed/${CMAKE_INSTALL_LIBDIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}
${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/static/installed
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DBUILD_SHARED_LIBS=0
-DBUILD_TESTING=0 -DBUILD_EXAMPLES=0 <SOURCE_DIR>
-G ${CMAKE_GENERATOR}
${COMMANDS} "")
set_target_properties(${name}-static PROPERTIES EXCLUDE_FROM_ALL 1)
endfunction()
# Convenience macro for adding dependencies without having to include the -static all over
macro(opm_static_add_dependencies target)
foreach(arg ${ARGN})
add_dependencies(${target}-static ${arg}-static)
endforeach()
endmacro()
include(ExternalProject)
include(GNUInstallDirs)
# Defaults to building master
if(NOT OPM_BENCHMARK_VERSION)
set(OPM_BENCHMARK_VERSION "origin/master")
endif()
# ERT
externalproject_add(ert-static
GIT_REPOSITORY https://github.com/Ensembles/ert
PREFIX static/ert
GIT_TAG ${revision}
CONFIGURE_COMMAND ${CMAKE_COMMAND}
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/static/installed
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DBUILD_SHARED_LIBS=0 <SOURCE_DIR>/devel)
set_target_properties(ert-static PROPERTIES EXCLUDE_FROM_ALL 1)
# 2015.04 release used dune v2.3.1
if(OPM_BENCHMARK_VERSION STREQUAL "release/2015.04/final")
set(DUNE_VERSION v2.3.1)
endif()
# Master currently uses dune v2.3.1
if(OPM_BENCHMARK_VERSION STREQUAL "origin/master")
set(DUNE_VERSION v2.3.1)
endif()
# Fallback
if(NOT DUNE_VERSION)
set(DUNE_VERSION v2.3.1)
endif()
# Dune
foreach(dune_repo dune-common dune-geometry dune-grid dune-istl)
opm_from_git(http://git.dune-project.org/repositories/${dune_repo} ${dune_repo} ${DUNE_VERSION})
endforeach()
opm_static_add_dependencies(dune-istl dune-common)
opm_static_add_dependencies(dune-geometry dune-common)
opm_static_add_dependencies(dune-grid dune-geometry)
# OPM
foreach(opm_repo opm-common opm-parser opm-core opm-output opm-grid opm-material
opm-upscaling)
opm_from_git(https://github.com/OPM/${opm_repo} ${opm_repo} ${OPM_BENCHMARK_VERSION})
endforeach()
opm_static_add_dependencies(opm-parser opm-common ert)
opm_static_add_dependencies(opm-core opm-parser dune-istl)
opm_static_add_dependencies(opm-grid opm-core dune-grid)
opm_static_add_dependencies(opm-material opm-core)
opm_static_add_dependencies(opm-upscaling opm-grid opm-material)

View File

@ -1,28 +0,0 @@
# We make this a cmake module so it can be used from opm-simulators' CMakeLists.txt also
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
import site, sys
try:
sys.stdout.write(site.getsitepackages()[-1])
except e:
sys.stdout.write('')" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_PATH)
# -------------------------------------------------------------------------
# 1: Wrap C++ functionality in Python
if (PYTHON_SITE_PACKAGES_PATH MATCHES ".*/dist-packages/?" AND
CMAKE_INSTALL_PREFIX MATCHES "^/usr.*")
# dist-packages is only used if we install below /usr and python's site packages
# path matches dist-packages
set(PYTHON_PACKAGE_PATH "dist-packages")
else()
set(PYTHON_PACKAGE_PATH "site-packages")
endif()
if(PYTHON_VERSION_MAJOR)
set(PY_MAJOR ${PYTHON_VERSION_MAJOR})
else()
set(PY_MAJOR ${Python3_VERSION_MAJOR})
endif()
if(PYTHON_VERSION_MINOR)
set(PY_MINOR ${PYTHON_VERSION_MINOR})
else()
set(PY_MINOR ${Python3_VERSION_MINOR})
endif()
set(PYTHON_INSTALL_PREFIX "lib/python${PY_MAJOR}.${PY_MINOR}/${PYTHON_PACKAGE_PATH}" CACHE STRING "Subdirectory to install Python modules in")

View File

@ -1,27 +0,0 @@
if(USE_DAMARIS_LIB AND MPI_FOUND)
if (Damaris_FOUND)
set(HAVE_DAMARIS 1)
message(STATUS "The Damaris library was found: ${Damaris_VERSION} ${Damaris_DIR}")
if (Damaris_HAS_HDF5)
message(STATUS "The Damaris library has HDF5 support: ${HDF5_VERSION}")
else()
message(STATUS "The Damaris library does NOT have HDF5 support")
endif()
if (Damaris_HAS_VISIT)
message(STATUS "The Damaris library has VisIt support: ${VisIt_VERSION}")
else()
message(STATUS "The Damaris library does NOT have VisIt support")
endif()
if (Damaris_HAS_CATALYST)
message(STATUS "The Damaris library has Catalyst support: ${Catalyst_VERSION} ${Paraview_VERSION}")
else()
message(STATUS "The Damaris library does NOT have Catalyst support")
endif()
else()
message(FATAL_ERROR "The Damaris library was requested but NOT found")
endif()
else() # User did not request Damaris support
unset(HAVE_DAMARIS)
endif()
mark_as_advanced(HAVE_DAMARIS)

View File

@ -1,11 +1,4 @@
# When using Boost >= 1.70 and e.g. CMake 3.18 we need to make sure that
# subsequent searches are using config mode too. Otherwise the library
# list will be completely messed up. We use a set Boost_Dir to detect that
# previous searches were done using config mode.
if(Boost_DIR)
set(_Boost_CONFIG_MODE CONFIG)
endif()
find_package (Boost 1.44.0 COMPONENTS unit_test_framework QUIET ${_Boost_CONFIG_MODE})
find_package (Boost 1.44.0 COMPONENTS unit_test_framework QUIET)
if (Boost_UNIT_TEST_FRAMEWORK_FOUND)
# setup to do a test compile

View File

@ -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}")

View File

@ -63,16 +63,9 @@ if (CXX_COMPAT_GCC)
# use these options for release builds - full optimization
add_options (ALL_LANGUAGES "${_prof_RELEASE}" ${_opt_rel} ${_opt_flags})
option(WITH_NDEBUG "Disable asserts in release mode" OFF)
option(WITH_NDEBUG "Disable asserts in release mode" ON)
if(WITH_NDEBUG)
foreach(type ${_prof_RELEASE})
string(TOUPPER ${type} type)
string(REPLACE -UNDEBUG "" CMAKE_CXX_FLAGS_${type} "${CMAKE_CXX_FLAGS_${type}}")
string(REPLACE -UNDEBUG "" CMAKE_C_FLAGS_${type} "${CMAKE_C_FLAGS_${type}}")
string(REPLACE -UNDEBUG "" CMAKE_Fortran_FLAGS_${type} "${CMAKE_Fortran_FLAGS_${type}}")
endforeach()
else()
add_options (ALL_LANGUAGES "${_prof_RELEASE}" -UNDEBUG)
add_options (ALL_LANGUAGES "${_prof_RELEASE}" -DNDEBUG)
endif()
else ()

View File

@ -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()

View File

@ -14,12 +14,8 @@
# 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_)
set(OPM_BINARY_PACKAGE_VERSION "" CACHE STRING
"Version of the binary Linux package built (will be printed in PRT file of flow if not empty)")
string(LENGTH "${OPM_BINARY_PACKAGE_VERSION}" _BINARY_PACKAGE_VERSION_LENGTH)
if (cmake_build_type_upper_ MATCHES DEBUG)
file (WRITE "${PROJECT_BINARY_DIR}/project-version.h"
"#ifndef OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
@ -29,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)
@ -46,30 +34,15 @@ else ()
# system, so there is "no" way we can update the SHA. notice
# that this is a slightly different version of the label than
# above.
if (NOT GIT_FOUND OR NOT EXISTS ${PROJECT_SOURCE_DIR}/.git)
if(_BINARY_PACKAGE_VERSION_LENGTH GREATER 0)
set(_PROJECT_VERSION_HASH "${OPM_BINARY_PACKAGE_VERSION}")
else()
set(_PROJECT_VERSION_HASH "unknown git version")
endif()
file (WRITE "${PROJECT_BINARY_DIR}/project-version.h"
"#ifndef OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
"#define OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
"#define PROJECT_VERSION_NAME \"${${project}_LABEL}\"\n"
"#define PROJECT_VERSION_HASH \"${_PROJECT_VERSION_HASH}\"\n"
"#define PROJECT_VERSION \"${${project}_LABEL} (${_PROJECT_VERSION_HASH})\"\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")
if (_BINARY_PACKAGE_VERSION_LENGTH EQUAL 0)
file(APPEND "${PROJECT_BINARY_DIR}/project-timestamp.h"
"#define BUILD_TIMESTAMP \"${build_timestamp}\"\n")
endif()
file(APPEND "${PROJECT_BINARY_DIR}/project-timestamp.h"
"#endif // OPM_GENERATED_OPM_TIMESTAMP_HEADER_INCLUDED\n")
if (NOT GIT_FOUND)
file (WRITE "${PROJECT_BINARY_DIR}/project-version.h"
"#ifndef OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
"#define OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
"#define PROJECT_VERSION_NAME \"${${project}_LABEL}\"\n"
"#define PROJECT_VERSION_HASH \"unknown git version\"\n"
"#define PROJECT_VERSION \"${${project}_LABEL} (unknown git version)\"\n"
"#endif // OPM_GENERATED_OPM_VERSION_HEADER_INCLUDED\n"
)
else ()
add_custom_target (update-version ALL
COMMAND ${CMAKE_COMMAND}

View File

@ -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}")

View 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)

View 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)

View 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)

View 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})

View 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})

View File

@ -0,0 +1,20 @@
# -*- mode: cmake; tab-width: 2; indent-tabs-mode: t; truncate-lines: t; compile-command: "cmake -Wdev" -*-
# vim: set filetype=cmake autoindent tabstop=2 shiftwidth=2 noexpandtab softtabstop=2 nowrap:
# defines that must be present in config.h for our headers
set (opm-verteq_CONFIG_VAR
)
# dependencies
set (opm-verteq_DEPS
# compile with C99 support if available
"C99"
# compile with C++0x/11 support if available
"CXX11Features"
# various runtime library enhancements
"Boost 1.44.0
COMPONENTS date_time filesystem system unit_test_framework REQUIRED"
# OPM dependency
"opm-common;
opm-core REQUIRED"
)

View File

@ -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

View File

@ -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"
)

View File

@ -816,7 +816,7 @@ HTML_COLORSTYLE_GAMMA = 80
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = NO
HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the

View File

@ -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@")
@ -58,7 +53,6 @@ if(NOT @opm-project_NAME@_FOUND)
string(REPLACE ${@opm-project_NAME@_PREFIX} ${DEST_PREFIX} @opm-project_NAME@_INCLUDE_DIRS "${@opm-project_NAME@_INCLUDE_DIRS}")
string(REPLACE ${@opm-project_NAME@_PREFIX} ${DEST_PREFIX} @opm-project_NAME@_LIBRARY_DIRS "${@opm-project_NAME@_LIBRARY_DIRS}")
string(REPLACE ${@opm-project_NAME@_PREFIX} ${DEST_PREFIX} @opm-project_NAME@_LIBRARY "${@opm-project_NAME@_LIBRARY}")
string(REPLACE ${@opm-project_NAME@_PREFIX} ${DEST_PREFIX} @opm-project_NAME@_PYTHON_COMMON_DIR "${@opm-project_NAME@_PYTHON_COMMON_DIR}")
endif()
@ -75,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)
@ -94,39 +94,17 @@ if(NOT @opm-project_NAME@_FOUND)
# this is the contents of config.h as far as our probes can tell:
# Require correct CMake standard. Needed for user modules as
# some software will add incompatible compile switches like
# -std=gnu++11 otherwise when search for (I guess because of
# imported targets using INTERFACE_COMPILE_FEATURES), and will
# break compilation because of missing c++17 features.
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD @CMAKE_CXX_STANDARD@)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
# The settings in this block do not mix well with the DEST_PREFIX
# setting.
if (NOT DEST_PREFIX)
# if this file is not processed using the OPM CMake system but
# simply by a call to find_package(module) then the CMAKE_MODULE_PATH
# might not include the location of the OPM cmake module yet.
# Hence we search for opm-common using config mode to set it up.
# The check for opm-common_PREFIX is there to not do this in
# opm-common-config.cmake
if(NOT opm-common_PREFIX
AND NOT opm-common_FOUND)
# This needed to find the path to the CMake modules
find_package(opm-common CONFIG)
endif()
# This is required to include OpmPackage /opm-common-prereq.cmake
# This is required to include OpmPackage
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" @PREREQ_LOCATION@)
# extra code from variable OPM_PROJECT_EXTRA_CODE
@OPM_PROJECT_EXTRA_CODE@
# end extra code
include(OpmPackage)
include(@opm-project_NAME@-prereqs)
endif()
endif()

View File

@ -9,6 +9,5 @@ Name: @name@
Description: @description@ @major@.@minor@
Version: @major@.@minor@
URL: http://opm-project.org
Libs.private: @libs@
Libs: @target@
Libs: @target@ @libs@
Cflags: @includes@ @defs@

View File

@ -1,4 +1,4 @@
/* Userspecific CSS for doxygen */
/* Userspesific CSS for doxygen */
body, table, div, p, dl {
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
font-size: 16px;

5
debian/changelog vendored Normal file
View File

@ -0,0 +1,5 @@
opm-common (2018.10-rfinal-2~xenial) xenial; urgency=medium
* New release
-- Arne Morten Kvarving <arne.morten.kvarving@sintef.no> Mon, 19 Oct 2015 10:49:00 +0200

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
9

44
debian/control vendored Normal file
View File

@ -0,0 +1,44 @@
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,
texlive-latex-extra, texlive-latex-recommended,
ghostscript, libboost-system-dev, libboost-test-dev,
libecl-dev, libboost-regex-dev, libboost-filesystem-dev,
zlib1g-dev
Standards-Version: 3.9.2
Section: libs
Homepage: http://opm-project.org
Vcs-Git: git://github.com/OPM/opm-common.git
Vcs-Browser: https://github.com/OPM/opm-common
Package: libopm-common1
Section: libs
Pre-Depends: ${misc:Pre-Depends}, multiarch-support
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: libopm-common
Description: OPM common library
The OPM common library contains generic code shared across all OPM modules.
Package: libopm-common1-dev
Section: libdevel
Architecture: any
Multi-Arch: foreign
Provides: libopm-common-dev
Suggests: libopm-common1-doc
Depends: libopm-common1 (= ${binary:Version})
Description: OPM common library -- development files
The OPM common library contains the shared buildsystem
and helpers shared across all OPM modules.
Package: libopm-common1-doc
Section: doc
Architecture: all
Multi-Arch: foreign
Provides: libopm-common-doc
Description: OPM common library -- documentation
The OPM common library contains the shared buildsystem
and helpers shared across all OPM modules.

13
debian/copyright vendored Normal file
View File

@ -0,0 +1,13 @@
License: GPL-3+
This package 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.
This package 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 this program. If not, see <http://www.gnu.org/licenses/>

2
debian/docs vendored Normal file
View File

@ -0,0 +1,2 @@
LICENSE
README.md

6
debian/libopm-common1-dev.install vendored Normal file
View File

@ -0,0 +1,6 @@
usr/include/*
usr/lib/dunecontrol/*
usr/lib/*/pkgconfig/*
usr/share/cmake/*
usr/share/opm/*
usr/lib/*/lib*.so

1
debian/libopm-common1-doc.install vendored Normal file
View File

@ -0,0 +1 @@
usr/share/doc/*

1
debian/libopm-common1.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/lib*.so.*

29
debian/rules vendored Executable file
View File

@ -0,0 +1,29 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
override_dh_auto_clean:
dh_auto_clean --buildsystem=cmake
override_dh_auto_build:
dh_auto_build --buildsystem=cmake
# 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
override_dh_auto_install:
dh_auto_install -- install-html
override_dh_installdocs:
dh_installdocs --link-doc=libopm-common1

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
1.0

View File

@ -153,7 +153,7 @@ we currently have five different categories:
To infer the number of records in the keyword based on an
internal calculation is not supported, hence for these keywords
size is given as unknown, and the keywords are terminated when the
size is given as unkown, and the keywords are terminated when the
next valid keyword is found:
{"name" : "VFPPROD" , "size" : "UNKNOWN", ....
@ -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"}]}
@ -297,7 +297,7 @@ composite units based on the dimension of the composite quantity. As a
consequence the list of dimensions supported by the parser is long,
and growing. The current list can be found in the source file:
opm/input/eclipse/Units/UnitSystem.cpp
opm/parser/eclipse/Units/UnitSystem.cpp

View File

@ -1,14 +0,0 @@
.TH SUMMARY "1" "October 2023" "arraylist 2023.10" "User Commands"
.SH NAME
arraylist \- Printer for list of arrays in Eclipse summary files
.SH SYNOPSIS
.B arraylist
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
.SH DESCRIPTION
List all arrays found in an EclFile specified on the command line.
.PP
.SH OPTIONS
\fB\-h\fR Print help and exit.
.TP
\fB\-r\fR List array for a specific report time step number. Option only valid for a unified restart file.
.PP

View File

@ -1,33 +0,0 @@
.TH CO2BRINEPVT "1" "October 2023" "co2brinepvt" "User Commands"
.SH NAME
co2brinepvt \- compute and print pvt properties for co2 with brine
.SH SYNOPSIS
.B co2brinepvt
[\fI\,OPTIONS\/\fR] \fI\,PROPERTY\/\fR \fI\,PHASE\/\fR
\fI\,PRESSURE\/\fR \fI\,TEMPERATURE\/\fR [\fI\,SALINITY\/\fR] [\fI\,RS\/\fR]
.SH DESCRIPTION
co2brinepvt computes PVT properties of a brine/co2 system
for a given phase (oil or brine), pressure, temperature, salinity and rs.
The properties support are: density, the inverse phase formation volume factor (invB), viscosity,
saturated dissolution factor (rsSat)
See CO2STORE in the OPM manual for more details.
.PP
.SH Synopsis
co2brinepvt <prop> <phase> <p> <T> <salinity> <rs>
.br
where
.br
prop = {density, invB, B, viscosity, rsSat, diffusionCoefficient}
.br
phase = {CO2, brine}
.br
p: pressure in pascal
.br
T: temperature in kelvin
.br
salinity(optional): salt molality in mol/kg
.nr
rs(optional): amount of dissolved CO2 in Brine in SM3/SM3
.PP
.SH OPTIONS
\fB\-\-h\fR/\-\-help Print help and exit.

View File

@ -1,69 +0,0 @@
.TH COMPAREECL "1" "October 2023" "compareECL 2023.10" "User Commands"
.SH NAME
compareECL \- Comparator for Eclipse files
.SH SYNOPSIS
.B convertECL
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME_1\/\fR \fI\,ECL_DECK_FILENAME_2\/\fR
.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
.SH OPTIONS
.HP
In addition, the program takes these options (which must be given before the arguments):
.PP
\fB\-a\fR Run a full analysis of errors.
.TP
\fB\-h\fR Print help and exit.
.TP
\fB\-d\fR Use report steps only when comparing results from summary files.
.TP
\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
.TP
\fB\-l\fR Only do comparison for the last Report Step. This option is only valid for restart files.
.TP
\fB\-n\fR Do not throw on errors.
.TP
\fB\-p\fR Print keywords in both cases and exit.
.TP
\fB\-r\fR compare a specific report time step number in a restart file.
.TP
\fB\-t\fR Specify ECLIPSE filetype to compare, (default behaviour is that all files are compared if found). Different possible arguments are:
.IP
\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.
.IP
\fB\-t\fR EGRID
Compare two EGrid files (.EGRID).
.IP
\fB\-t\fR INIT
Compare two initial files (.INIT).
.IP
\fB\-t\fR RFT
Compare two RFT files (.RFT).
.IP
\fB\-t\fR SMRY
Compare two cases consistent of (unified) summary files.
.IP
\fB\-t\fR RSM
Compare RSM file against a summary file.
.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
.SH 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.

View File

@ -1,22 +0,0 @@
.TH CONVERTECL "1" "October 2023" "convertECL 2023.10" "User Commands"
.SH NAME
convertECL \- Converter for Eclipse files (binary <-> formatted
format)
.SH SYNOPSIS
.B convertECL
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
.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
.SH OPTIONS
.HP
\fB\-h\fR Print help and exit.
.TP
\fB\-l\fR list report step numbers in the selected restart file.
.TP
\fB\-i\fR Enforce IX standard on output file.
.TP
\fB\-r\fR extract and convert a specific report time step number from a unified restart file.
.PP

View File

@ -1,52 +0,0 @@
.TH OPMHASH "1" "October 2023" "opmhash 2023.10" "User Commands"
.SH NAME
opmhash \- Hasher for summary keywords in Eclipse files
.SH SYNOPSIS
.B opmhash
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
[\fI\,ECL_DECK_FILENAME_2\/\fR] [\fI\,ECL_DECK_FILENAME_3\/\fR] ...
.SH DESCRIPTION
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.
.HP
\fB\-S\fR : Silent form \- will not print any deck output.
.PP
It is possible to add multiple deck arguments, they are then scanned repeatedly,
and the decks are compared. In the case of multiple deck arguments the exit
status of the program will be zero if all are equal and nonzero in case of
differences.

View File

@ -1,31 +0,0 @@
.TH OPMPACK "1" "October 2023" "opmpack 2023.10" "User Commands"
.SH NAME
opmpack \- Validator and printer of deck in Eclipse files without comments
.SH SYNOPSIS
.B opmpack
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
.SH DESCRIPTION
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.

View File

@ -1,92 +0,0 @@
.TH RST_DECK: "1" "October 2023" "rst_deck 2023.10" "User Commands"
.SH NAME
rst_deck \- Convert simulation deck to a deck ready for restart
.SH SYNOPSIS
.B rst_deck
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
\fI\,RESTART_SOURCE\/\fR [\fI\,BASENAME_RESTART_DECK\/\fR
.SH DESCRIPTION
The rst_deck program will load a simulation deck and parameters for a restart
and reformat the deck to become a restart deck. Before the updated deck is
output the program will update the SOLUTION and SCHEDULE sections. All keywords
from the SOLUTION section will be cleared out(1) and a RESTART keyword will be
inserted. In the SCHEDULE section the program can either remove all keywords up
until the restart date, or alternatively insert SKIPREST immediately following
the SCHEDULE keyword.
.PP
When creating the updated restart deck the program can either link to unmodified
include files with INCLUDE statements, create a copy of deck structure in an
alternative location or create one large file with all keywords in the same
file. Apart from the alterations to support restart the output deck will be
equivalent to the input deck, but formatting is not retained and comments have
been stripped away.
.PP
Arguments:
.PP
1. The data file we are starting with.
.PP
2. The restart source; this can either be a basename with an optional path
.IP
prefix and a :N to restart from step N; alternatively you can point to an
existing restart file. If you point to an existing restart file the input
will be validated in several ways:
.IP
a) Unified/multiple files will be checked against the UNIFIN setting of
.IP
the deck.
.IP
b) Formatted/unformatted will be checked against the FMTIn setting of the
.IP
deck.
.IP
c) If a single file like \fI\,/path/to/case/HISTORY.X0067\/\fP is given as argument the
.IP
:N notation to denote report step should not be used.
.IP
If the restart argument is given as the path to an existing file the content
of the RESTART keyword will be updated to contain the correct path from the
location of the restart deck to the location of the restart file. This path
awareness will be fooled if the restart deck is redirected from stdout to a
path different from cwd. If the restart argument is given as an absolute
filename the RESTART keyword will have an absolute path, if the restart
argument is a relative path the RESTART keyword will get a relative path \-
although an absolute path will be used if the restart file and the output
deck have different roots. If the restart argument is given as a string not
pointing to an existing file it will be inserted verbatim in the restart
deck.
.IP
A restart step value of 0 is interpreted as a dry run \- a deck which has not
been set up for restart will be written out.
.PP
3. Basename of the restart deck we create, can optionally contain a path prefix;
.IP
the path will be created if it does not already exist. This argument is
optional, if it is not provided the program will dump a restart deck on
stdout. If the argument corresponds to an existing directory the restart case
will get the same name as the base case.
.SH OPTIONS
\fB\-s\fR: Manipulate the SCHEDULE section by inserting a SKIPREST keyword immediately
.IP
following the SCHEDULE keyword. If the \fB\-s\fR option is not used the SCHEDULE
section will be modified by removing all keywords until we reach the restart
date.
.PP
\fB\-m\fR: [share|inline|copy] The restart deck can reuse the unmodified include files
.IP
from the base case, this is mode 'share' and is the default. With mode
\&'inline' the restart deck will be one long file and with mode 'copy' the
file structure of the base case will be retained. The default if no \fB\-m\fR
option is given is the 'share' mode.
.IP
In the case of 'share' and 'copy' the correct path to include files will be
negotiated based on the path given to the output case in the third argument.
If the restart deck is passed to stdout the include files will be resolved
based on output in cwd.
.PP
Example:
.IP
rst_deck \fI\,/path/to/history/HISTORY.DATA\/\fP rst/HISTORY:30 \fI\,/path/to/rst/RESTART\/\fP \fB\-s\fR
.PP
1: The program has a compiled list of keywords which will be retained in the
.IP
SOLUTION section. The current value of that list is: RPTRST

View File

@ -1,19 +0,0 @@
.TH SUMMARY "1" "October 2023" "summary 2023.10" "User Commands"
.SH NAME
summary \- Printer for summary keys in Eclipse summary files
.SH SYNOPSIS
.B summary
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
\fI\,SUMMARY_KEY1\/\fR [\fI\,SUMMARY_KEY2\/\fR] ...
.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
.SH OPTIONS
\fB\-h\fR Print help and exit.
.TP
\fB\-l\fR list all summary vectors.
.TP
\fB\-r\fR extract data only for report steps.
.PP

View File

@ -1,27 +0,0 @@
\documentclass[a4paper,11pt]{book}
\usepackage{verbatim}
\newcommand{\kw}[1]{\texttt{#1}}
\newcommand{\inlinecode}[1]{\texttt{#1}}
\newcommand{\flow}[0]{\texttt{flow}}
\newcommand{\eclipse}[0]{\texttt{Eclipse}}
\newcommand{\path}[1]{\texttt{#1}}
\newenvironment{deck}[0]{\verbatim}{\endverbatim}
\newenvironment{code}[0]{\verbatim}{\endverbatim}
\begin{document}
\begin{titlepage}
\begin{center}
\Huge
\textbf{Technical manual}
\end{center}
\end{titlepage}
\tableofcontents
\input{udq_actionx/udq}
\input{udq_actionx/actionx}
\input{udq_actionx/pyaction}
\end{document}

View File

@ -1,437 +0,0 @@
\newcommand{\actionx}{\kw{ACTIONX}}
\chapter{Programming in the deck: \actionx}
\label{actionx}
The \actionx{} keyword is the most direct way to \emph{program} in the deck. The
\actionx{} functionality consist of the \actionx{} keyword itself, with some
metadata and a condition and then a list of keywords which are injected into the
in-memory representation of the \kw{SCHEDULE} section at the point in time where
the condition evaluates to true. The \actionx{} statement is evaluated at the
end of every timestep, and if it evaluates to true the new keywords should take
effect immediately. The \actionx{} conditions are less sophisticated than the
expressions used in \udq{}, this implies that a common pattern is to make
involved calculations as \udq{} expressions, and then use a simple test as
\actionx{} condition.
The \actionx{} keyword is also documented in section 12.3.6 in the \flow{}
reference manual.
\section{Structure of the \actionx{} keyword}
\label{actionx_structure}
The \actionx{} keyword itself consist of multiple records. The first record is
metadata with name of the action, the number of times the action can be
triggered and the minimum time elapsed before an action is eligible for a second
run. The subsequent records are \emph{conditions}, all the conditions are of the
same form
\begin{code}
lhs comparison rhs
\end{code}
and subsequent conditions are combined with \inlinecode{AND} or \inlinecode{OR}.
The \inlinecode{lhs} is a field, well or group quantity, in addition you can use
time variables \kw{DAY}, \kw{MNTH} and \kw{YEAR} as left hand
side\footnote{\eclipse{} supports a wider list of summary variables like region,
block and aquifer quantities on both left and right hand side.}. As with the
\udq{} variables the well and group variables are \emph{sets}, and the
evaluation status is maintained individually for each well and group.
The comparison is one of the ordinary mathematical comparison operators
\inlinecode{>,<,=,!=, <=} and \inlinecode{>=}. Numerical comparisons are done
with the corresponding plain C++ operators, this is in contrast to the \udq{}
implementation where an epsilon defined in \kw{UDQPARAMS} is used in floating
point comparisons.
The \inlinecode{rhs} is a numerical scalar, or a field, well or group quantity.
If your \inlinecode{rhs} is a well or group quantity the \inlinecode{lhs} and
\inlinecode{rhs} must be of the same type. If you use the symbol \kw{MNTH} as
\inlinecode{lhs} you can compare with named months, i.e. the following will
trigger on leap days
\begin{deck}
ACTIONX
LEAP 1000 /
MNTH=FEB AND /
DAY=29 /
/
...
...
ENDACTIO
\end{deck}
When there is a well/group quantity as \inlinecode{lhs} the evaluation status is
maintained individually for each well/group. The complete condition evaluates to
true if \emph{any} of the wells/groups satisfy the condition. In the case of
wells the wells matching the condition can subsequently be accessed with
wellname '?' in the \kw{ACTIONX} keywords, this is a quite common pattern to
e.g. close the well with highest watercut.
If there are more conditions they must be joined with a trailing \kw{AND} or
\kw{OR}, furthermore conditions can be grouped with paranthesis. The \actionx{}
expressions can only contain the four arithmetic operators $+,-,*,/$ and not
mathematical functions like $\log()$, for more advanced expressions the natural
approach is to first define a \udq{} and then use the \udq{} symbol in the
\actionx{}, this is illustrated in section \ref{uda}. When multiple conditions
involving the same well set are evaluated, the list of matching wells available
in '?' will contain all the wells from the final condition, i.e. for
\begin{code}
WWCT = {"OP1": 0.25, "OP2": 0.50, "OP3": 0.75}
\end{code}
and the action
\begin{deck}
ACTIONX
WWCT /
WWCT > 0.33 AND /
WWCT < 0.66 /
/
...
ENDACTIO
\end{deck}
the set of wells available for further use in '?' are \emph{all} the wells
matching the condition \inlinecode{WWCT < 0.66} i.e. OP1 and OP2 and \emph{not}
the wells matching the combined expression \inlinecode{0.33 < WWCT < 0.66}. In
order to select wells in a range as attempted here you will have to create an
indicator variable with \udq{} first and then select based on that indicator -
e.g. something like
\begin{deck}
UDQ
DEFINE WUCTR (WWCT < 0.66) * (WWCT > 0.33) /
/
ACTIONX
WUCTR /
WUCTR = 1 /
/
...
ENDACTIO
\end{deck}
The \actionx{} implementation is located in
\path{opm/input/eclipse/Schedule/Action} and all the classes are in namespace
\inlinecode{Action::}. As with the \udq{} the input parser needs some special
case to handle '/' and '*' as division operator and multiplier respectively, but
that is the only code shared between the \udq{} and the \actionx{}
implementation\footnote{It might be possible to share more code between the two,
in particular both have an internal recursive descent parser, but both \udq{}
and \actionx{} have so much ``personality'' that at least initially separate
implementations was the simplest.}.
The condition part of the \actionx{} keyword is internalized while the
\kw{SCHEDULE} section is parsed, the final product is maintained in a class
\inlinecode{Action::ActionX} which has a \inlinecode{eval()} method waiting to
be called. The keywords in the \actionx{} block are stored in the
\inlinecode{Action::ActionX} keyword for future use. All of the \actionx{}
keywords are stored in a container \inlinecode{Action::Actions} which will
eventually manage the book keeping of which actions are eligible for evaluation.
\section{The structure of the \inlinecode{Schedule} implementation}
\label{schedule_design}
\flow{} internalizes all keywords from the input deck and passes fully baked
datastructures to the simulator, whereas our impression is that \eclipse{} works
more like a reservoir model interepreter, executing one keywords at a time.
Mostly the \flow{} approach has worked out well, however for the \actionx{}
functionality the difference in execution model is quite acute, and the nature
of the \actionx{} keyword has had quite strong influence on the final Schedule
implementation. Although not required for use of \actionx{} it is valuable to
understand how the \actionx{} functionality has influenced the design of the
Schedule class, that way you will hopefully better understand problems or bugs
which might arise in the future.
At the very first pass the \kw{SCHEDULE} section is split in \emph{blocks}, with
one block for each report step. The blocks are implemented with the class
\inlinecode{ScheduleBlock}. Each block has a starting time and a list of
keywords, the keywords are maintained in the input format
\inlinecode{DeckKeyword}. Then the entire \kw{SCHEDULE} section is internalized
in the class \inlinecode{ScheduleDeck} which essentially contains a list of
\inlinecode{ScheduleBlock} instances. Consider the \kw{SCHEDULE} section
\begin{deck}
START
1 'JAN' 2020 /
...
...
SCHEDULE
WELSPECS
'PROD' 'G1' 10 10 8400 'OIL' /
'INJ' 'G1' 1 1 8335 'GAS' /
/
COMPDAT
'PROD' 10 10 3 3 'OPEN' 1* 1* 0.5 /
'INJ' 1 1 1 1 'OPEN' 1* 1* 0.5 /
/
-- End of block 0
DATES
1 'FEB' 2020 /
/
WCONPROD
'PROD' 'OPEN' 'ORAT' 20000 4* 1000 /
/
WCONINJE
'INJ' 'GAS' 'OPEN' 'RATE' 100000 1* 9014 /
/
-- End of block 1
DATES
1 'MAR' 2020 /
/
-- End of block 2
END
\end{deck}
When this is internalized we get a \inlinecode{ScheduleDeck} instance with three
\inlinecode{ScheduleBlock} values:
\begin{code}
ScheduleDeck sched_deck = [
ScheduleBlock {
start = "2020-01-01",
keywords = ["WELSPECS","COMPDAT"]
},
ScheduleBlock {
start = "2020-02-01",
keywords = ["WCONPROD","WCONINJE"]
},
ScheduleBlock {
start = "2020-03-01",
keywords = []
}
]
\end{code}
The \inlinecode{Schedule} class has a \inlinecode{ScheduleDeck} member. The
processed content of the \inlinecode{Schedule} class is managed in vector of
\inlinecode{ScheduleState} instances, where one \inlinecode{ScheduleState}
represents the complete dynamic input state at a particular report step. The
processed \kw{SCHEDULE} code is created with the method
\begin{code}
Schedule::iterateScheduleSection().
\end{code}
When \inlinecode{Schedule::iterateScheduleSection(report\_step)} is called it
starts by clearing the vector of \inlinecode{ScheduleState} instances from
\inlinecode{report\_step} to the end of the simulation, and then recreates those
by treating the \inlinecode{ScheduleBlock}. The advantage of this approach is
that the \inlinecode{Schedule::iterateScheduleSection(report\_step)} method is
idempotent - it can be called repeatedly, from an arbitrary point in the
timeseries.
The implementation of the \actionx{} functionality is just to append the
\actionx{} keywords in the \inlinecode{ScheduleBlock} instance corresponding to
the current report step and then rerun the
\inlinecode{Schedule::iterateScheduleSection()} from this report step.
\section{Forward references of wells and groups}
When a well or group is defined as an \actionx{} keyword and then
unconditionally referenced in the deck we get a challenge at the first pass
through the \kw{SCHEDULE} section. In the example below a new well \kw{W1} is
defined with the \kw{WELSPECS} keyword when the action \inlinecode{NEW\_WELL}
evaluates to true. At 1.st of January 2025 the well \kw{W1} is opened with the
\kw{WCONPROD} keyword. The engineer making this model assumes that the
\inlinecode{NEW\_WELL} action will evaluate to true sometime before 1.st of
January 2025, and thereby ensure that the well is fully defined when it is
eventually opened with \kw{WCONPROD}:
\begin{deck}
ACTIONX
'NEW_WELL/
WWCT OPX > 0.75 /
/
WELSPECS
'W1' 'OP' 1 1 3.33 'OIL' 7*/
/
ENDACTIO
TSTEP
10*30 /
DATES
1 'JAN' 2025 /
/
WCONPROD
'W1' 'OPEN' 'ORAT' 0.000 0.000 0.000 5* /
/
TSTEP
10*30 /
\end{deck}
For \flow{} this creates problems because the entire \kw{SCHEDULE} section is
parsed when the simulator starts, and at first pass the well \kw{W1} is unknown
in the \kw{WCONPROD} keyword. This is ``solved'' in the following way:
\begin{enumerate}
\item At first pass we inspect the keywords inside the \actionx{} block and if
we discover \kw{WELSPECS} we store the name of the well which will be defined
at a later stage through \actionx{}.
\item When we parse further on as part of the first pass and said well is
referenced e.g. in a \kw{WCONPROD} keyword, we verify that the well will
eventually appear via \actionx{} - we issue a warning and ignore the well in
the \kw{WCONPROD} keyword\footnote{If the well is not registered as ``will
appear through \actionx{}'' there will be a runtime error with unknown well
name when parsing \kw{WCONPROD}.}.
\item When the \actionx{} evaluates to true the well will be properly defined,
and when reiterating over the Schedule keywords the \kw{WCONPROD} keyword will
now be properly internalized. If the \actionx{} never evaluates to true the
\kw{WCONPROD} keyword will never be applied, and the warning from point 2 will
be the only trace of this well.
\end{enumerate}
It should be mentioned that the functionality with forward referencing of well
names is quite new\footnote{In January 2022}, there might be well keywords in
the \kw{SCHEDULE} section where the implementation is not yet prepared for this.
Furthermore the forward referencing is not at all implemented for groups. The
relevant data structure is the member \inlinecode{Action::WGNames
action\_wgnames} in the \inlinecode{Schedule} class.
\section{To enable a new keyword for \actionx}
The keywords must be explicitly enabled to be available in an \actionx{} block,
and enabling a new keyword requires recompiling \flow{}. The keywords available
as \actionx{} keywords are listed in the static method
\inlinecode{ActionX::valid\_keyword()} in
\path{opm/input/eclipse/Schedule/Action/ActionX.cpp}. In principle it should
just be to add the keyword to the \inlinecode{ActionX::valid\_keyword()} method
and rebuild \flow{}, but experience has unfortunately shown that problems of
various kinds have had a tendency to pop up when new keywords are tried out as
\actionx{} keywords. Most commonly the problems have been in the interaction
between the \inlinecode{Schedule} class in opm-common and the simulator - things
have a tendency to go out of sync.
\section{Running \actionx{} during simulation}
The first part of the \actionx{} treatment is parsing the keyword and conditions
and assemble a syntax tree which can be used to evaluate the conditions. This
parsing takes place when the \kw{SCHEDULE} section is parsed for the first time.
This takes place fully within the realms of the opm-common codebase, and is
quite mature.
When the simulation actually runs the \actionx{} behavior consists of three
distinct parts, taking place in the simulator, in opm-common and again in the
simulator. The simulator will manage an instance of \inlinecode{Action::State}
which will hold on to the time of last run and the latest results for the
various actions.
\subsection{Prepare and evaluate}
As with \udq{} the \inlinecode{SummaryState} instance is the most important
variable to provide context to the \actionx{} evaluation, i.e. the
\inlinecode{SummaryState} variable must be evaluated before \actionx{}. In
addition the \udq{} variables must be evaluated and available in the
\inlinecode{SummaryState} instance before we invoke the \actionx{}
functionality.
The evaluation of actions is called from the method \inlinecode{applyActions()}
in \path{eclproblem.hh}. The method will evaluate which actions are eligible for
running by inspecting the \inlinecode{Action::Actions} variable and call the
\inlinecode{ActionX::eval()} method.
\subsection{Recreate \inlinecode{Schedule}}
When an \actionx{} has evaluated to \inlinecode{true} the simulator will call
into the opm-common method \inlinecode{Schedule::applyAction(report\_step)}.
That function will add the keywords from the \actionx{} keyword to the
\inlinecode{ScheduleBlock} for the correct report step, and then reiterate
through the \kw{SCHEDULE} section to the end of the simulation.
This reiterate process will recreate all internal members in the
\inlinecode{Schedule} class, i.e. if the simulator was holding on to a reference
to an internal \inlinecode{Schedule} datastructure that will be invalidated.
While recreating the \inlinecode{Schedule} instance there is some book keeping
as to which datastructures need to be recalculated in the simulator as a
consequence of the \actionx{}. That information is maintained in the data
structure \inlinecode{Action::SimulatorUpdate} which is returned back to the
simulator.
\subsection{Updating simulator data structures}
The \actionx{} implementation is in the module opm-common, whereas when the
simulation is proceeding it is the simulator code which is clearly in control.
If an action has evaluated to true and new keywords are injected in the Schedule
object the complete simulator state is updated. This is complex, and many of the
bugs in \actionx{} functionality have been in the interaction between the
simulator and opm-common, in particular when an action has evaluated to true.
An assumption permeating the simulator code is that changes to the well and
group configuration only take place at report steps, and in between those the
simulator ``owns'' the well and group data. Unfortunately this is no longer the
case when \actionx{} is active, and depending on the keywords in the \actionx{}
block we need to update the simulator data structures after \actionx{} has been
evaluated to true. Some details of what is currently updated is decsribed below.
This update mechanism will probably need to be continously updated in the
future.
The simulator code makes \emph{copies} of many of the objects like wells and
connections from the \inlinecode{Schedule} class, and also assembles many
simulator specific data structures which to a large extent consist of extracts
of information from the internals of the \inlinecode{Schedule} object. Some of
the interaction between the simulator and the input layer could probably be
simplified if the simulator would call the \inlinecode{Schedule} object when
e.g. a well or connection is needed, instead of storing references or copies to
the \inlinecode{Schedule} objects internally.
There are currently three categories of changes that can take place due to
\actionx{}:
\subsubsection{General changes in well status}
\label{actionx_change_well}
When there is well related keyword in the \actionx{} block - e.g. \kw{WELOPEN}
to open or close a well or \kw{WCONPROD} to adjust rates, the simulator is
required update it's internal data structures with the updated input information.
This will be communicated by flagging all the wells which need an update in the
\inlinecode{Action::SimulatorUpdate} instance which is passed from the
simulator.
\subsubsection{Changes in geo properties}
The grid keywords are in general not permitted in the \kw{SCHEDULE} section,
however there are a few geo multipliers like \kw{MULTZ} and \kw{MULTFLT} which
are allowed in the \kw{SCHEDULE} section, and thereby also in \actionx{}. If one
of these keywords are encountered in the \actionx{} block we set the flag
\inlinecode{Action::SimulatorUpdate::tran\_update = true} to encourage the
simulator to recalculate the transmissibilities.
\subsubsection{WELPI}
\label{actionx_welpi}
The \kw{WELPI} keyword is quite complex from the outset, when it is included as
an \actionx{} keyword it gets even more complicated. In order to support
\kw{WELPI} in \actionx{} the simulator needs to inspect the \actionx{} keywords
before invoking them, and if \kw{WELPI} is included the PI values must be
assembled from the simulator and passed to the
\inlinecode{Schedule::applyAction()}. This is implemented and works, but it is
complex and the special treatment in order to support the combination \kw{WELPI}
+ \actionx{} is quite considerable.
\section{Problems in parallel}
\label{actionx_paralle}
The operation environment for \actionx{} is quite similar to \udq{} when it
comes to parallel behavior - see section \ref{udq_parallel}, in addition we
need to be aware of parallel challenges after the \actionx{} has completed. If
the \actionx{} keyword changes the well structure there will be problems with
with the parallel well distribution in the simulator. \emph{As of Januarry 2022
this will fail undetected.}
\section{\actionx{} restart output}
As with the \udq{} keyword some of the structure and complexity of the
\actionx{} datastructures are there primarily to enable \eclipse{} compatible
restart. Regarding restart of \actionx{} related data:
\begin{enumerate}
\item The restart output contains the result of parsing an \actionx{}
condition in an intermediate representation which has been reverse
engineered, this is complex and might not be 100\% correct.
\item When restarting \flow{} from an \eclipse{} formatted restart file the
\actionx{} conditions are reparsed based on string data in the restart file
and the intermediate representation mentioned in point 1 is not utilised.
\end{enumerate}

View File

@ -1,405 +0,0 @@
\newcommand{\pyaction}{\kw{PYACTION}}
\chapter{Programming in the deck: \pyaction{}}
\label{pyaction}
The \pyaction{} keyword is a \flow{} specific keyword which allows for Python
programming in the \kw{SCHEDULE} section. The \pyaction{} keyword is inspired by
the \actionx{} keyword, but instead of a \inlinecode{.DATA} formatted condition
you are allowed to implement the condition with a general Python script. The
\actionx{} keywords are very clearly separated in a condition part and an action
part in the form of a list of keywords which are effectively injected in the
\kw{SCHEDULE} section when the condition evaluates to true. This is not so for
\pyaction{} where there is only one Python script which can both evaluate
conditions and apply changes. In principle the script can run arbitrary code,
but due to the complexity of the \kw{SCHEDULE} datamodel the ``current best''
way to actually change the course of the simulation is through the use of an
additional dummy \actionx{} keyword.
In order to enable the \pyaction{} keyword \flow{} must be compiled with the
\path{cmake} switches \inlinecode{-DOPM\_ENABLE\_EMBEDDED\_PYTHON=ON} and
\inlinecode{-DOPM\_ENABLE\_PYTHON=ON}, the default is to build with these switches
set to \inlinecode{OFF}. Before you enable \pyaction{} in your \flow{}
installation please read carefully through section \ref{pyaction_security} for
security implications of \pyaction{}.
\section{Python - wrapping and embedding}
Python is present in the \flow{} codebase in two different ways. For many of
the classes in the \flow{} codebase - in particular in opm-common, there are
\emph{Python wrappers} available. That means that you can invoke the C++
functionality in \flow{} classes from Python - e.g. this Python script can be used to
load a deck and print all the keywords:
\begin{code}
import sys
from opm.io.parser import Parser
input_file = sys.argv[1]
parser = Parser()
deck = parser.parse_file(input_file)
for kw in deck:
print(kw.name)
\end{code}
When used this way the Python interpreter is the main program running, and the
\flow{} classes like \inlinecode{Opm::Parser} are loaded to extend the Python
interpreter. This can also be flipped around, the Python interpreter can be
\emph{embedded} in the \flow{} executable. When Python is embedded, \flow{} is
the main program running, and with help of the embedded interpreter the \flow{}
program can be extended with Python plugins. The \pyaction{} keyword can be
perceived as a Python plugin. To really interact with the state of the \flow{}
simulation the plugin needs to utilize the functionality which wraps the C++
functionality, so for \pyaction{} both wrapping and embedding is at play.
Exporting more functionality from C++ to Python in the form of new and updated
wrappers is a quite simple and mechanical process. If you need a particular
functionality which is already available in C++ also in Python it will probably
be a quite limited effort for a developer who is already familiar with the code.
\section{The \pyaction{} keyword}
The \pyaction{} keyword is in the \kw{SCHEDULE} section like \actionx{}. The
first record is the name of the action and a string identifier for how many
times the action should run, then there is a path to a Python module:
\begin{deck}
PYACTION
PYTEST 'FIRST_TRUE' /
'pytest.py' /
\end{deck}
This keyword defines a \pyaction{} called \kw{PYTEST} which will run at the end
of every timestep until the first time a \inlinecode{true} value is returned. In
addition to \kw{FIRST\_TRUE} you can choose \kw{SINGLE} to run exactly once and
\kw{UNLIMITED} to continue running at the end of every timestep for the entire
simulation. The second record is the path to a file with Python code which will
run when this \pyaction{} is invoked. The path to the module will be interpreted
relative to the location of the \path{.DATA} file.
The python module can be quite arbitrary, but it must contain a function
\inlinecode{run} with the correct signature:
\begin{code}
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
print('Running python code in PYACTION')
return True
\end{code}
The \pyaction{} machinery is not as robust as the simulator proper: while
loading the \kw{PYACTION} keyword \flow{} will check that the Python module
contains syntactically valid Python code, and that it contains a
\inlinecode{run()} function, but it will \emph{not} check the signature of the
\inlinecode{run()} function. If the signature is wrong you will get a hard to
diagnose runtime error.
When the Python module is loaded it does so in an environment where the path to
the \path{.DATA} file has been appended to the Python load path by manipulating
the internal \inlinecode{sys.path} variable.
\subsection{The different arguments}
The \inlinecode{run()} function will be called with exactly five arguments which
your implementation can use. These arguments point to datastructures in the
simulator, and is the way to interact with the state of the simulation. The five
arguments are:
\begin{description}
\item[\inlinecode{ecl\_state}:] An instance of the \inlinecode{Opm::EclipseState}
class - this is a representation of \emph{all static properties} in the model,
ranging from porosity to relperm tables. The content of the
\inlinecode{ecl\_state} is immutable - you are not allowed to change the static
properties at runtime\footnote{This could certainly be interesting, but this
is beyond the scope of the \pyaction{} keyword.}.
\item[\inlinecode{schedule}:] An instance of the \inlinecode{Opm::Schedule}
class - this is a representation of all the content from the \kw{SCHEDULE}
section, notably all well and group information and the timestepping. Being
able to change the \kw{SCHEDULE} information runtime is certainly one of the
main motivations for this functionality, however due to the complexity of
the \inlinecode{Opm::Schedule} class (section \ref{schedule_design})
the recommended way to actually mutate the \inlinecode{Opm::Schedule} is
through the use of a dummy \actionx{} keyword (section
\ref{pyaction_actionx}).
\item[\inlinecode{report\_step}:] This is an integer for the report step we
are currently working on. Observe that the \pyaction{} is called for every
simulator timestep, i.e. it will typically be called multiple times with
the same value for the $\mathrm{report\_step}$ argument.
\item[\inlinecode{summary\_state}:] An instance of the
\inlinecode{Opm::SummaryState} class, this is where the current summary
results of the simulator are stored. The \inlinecode{SummaryState} class has
methods to get hold of well, group and general variables
\begin{code}
# Print all well names
for well in summary_state.wells:
print(well)
# Assign all group names to the variable group_names
group_names = summary_state.groups
# Sum the oil rate from all wells.
sum_wopr = 0
for well in summary_state.wells:
sum_wopr += summary_state.well_var(well, 'WOPR')
# Directly fetch the FOPR from the summary_state
fopr = summary_state['FOPR']
\end{code}
The \inlinecode{summary\_state} variable can also be updated with the
\inlinecode{update()}, \inlinecode{update\_well\_var()} and
\inlinecode{update\_group\_var()} methods.
\item[\inlinecode{actionx\_callback}:] The \inlinecode{actionx\_callback} is a
specialized function which is used to update the \inlinecode{Schedule} object
by applying the keywords from a normal \actionx{} keyword. This is described
in detail in section \ref{pyaction_actionx}.
\end{description}
\subsection{Holding state}
The \pyaction{} keywords will often be invoked multiple times, a Python
dictionary \inlinecode{state} has been injected in the module - that dictionary
can be used to maintain state between invocations. Let us assume we want to
detect when the field oil production starts curving down - i.e. when
$\partial^2_{t} \mathrm{FOPR} < 0$, in order to calculate that we need to keep
track of the timesteps and the $\mathrm{FOPR}$ as function of time - this is one
possible implementation:
\begin{code}
def diff(pair1, pair2):
return (pair1[0] - pair2[0], pair1[1] - pair2[1])
def fopr_diff2(summary_state):
fopr = summary_state.get('FOPR')
sim_time = summary_state.get('TIME')
if not 'fopr' in state:
state['fopr'] = []
fopr_series = state['fopr']
fopr_series.append( (sim_time, fopr) )
if len(fopr_series) < 2:
return None
pair0 = fopr_series[-1]
pair1 = fopr_series[-2]
pair2 = fopr_series[-3]
dt1, df1 = diff(pair0, pair1)
dt2, df2 = diff(pair1, pair2)
return 2*(df1/dt1 - df2/dt2)/(dt1 + dt2)
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
fopr_d2 = fopr_diff2(summary_state)
if not fopr_d2 is None:
if fopr_d2 < 0:
print('Hmmm - this is going the wrong way')
else:
print('All good - sky is the limit!')
\end{code}
\section{Changing the \inlinecode{Schedule} object - using a ``normal'' \actionx{}}
\label{pyaction_actionx}
Before reading this section you should make sure to understand the
\inlinecode{Schedule} design described in section \ref{schedule_design}. The
initial plan when implementing the \pyaction{} keyword was to be able to make
function calls like
\begin{code}
schedule.close_well(w1, report_step)
schedule.set_orat(w2, 1000, report_step)
\end{code}
to close a well and set the oil rate of another well. Unfortunately it proved
very complex to get good semantics for combining such runtime changes with the
keyword based model for \kw{SCHEDULE} section. The current recommendation is to
apply changes to the \kw{SCHEDULE} section using callbacks to \kw{ACTIONX}
keywords from Python code, this is illustrated in the example
below\footnote{From a programmers point of view the solution seems very
unsatisfactory, but it works and it plays nicely with the \kw{ACTIONX} behavior.
If/when the underlying \inlinecode{Schedule} implementation changes there is
nothing per se in the \pyaction{} design which inhibits use of a better
\inlinecode{Schedule} api in the future.}.
The recommended way to achieve this is to create a normal \actionx{} keyword
which is set up to run zero times, and then explicitly invoke that from the
Python \inlinecode{run()} function. In the example below we create an \actionx{}
\inlinecode{CLOSEWELLS} which will close all matching wells (the wellname '?')
\begin{deck}
ACTIONX
CLOSEWELLS 0 /
/
/
WELOPEN
'?' 'CLOSE' /
/
ENDACTIO
\end{deck}
The \inlinecode{CLOSEWELLS} action is set up to run zero times, so the normal
\actionx{} machinery will never run this action\footnote{The \kw{CLOSEWELL}
action has an \emph{empty condition}, the \actionx{} keywords with empty
condition will always evaluate as false.}. Then in the Python run function we go
through all the wells and call the \inlinecode{CLOSEWELL} action to close those
with \inlinecode{OPR < 1000}:
\begin{code}
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
close_wells = []
for well in summary_state.wells:
if summary_state.well_var(well, 'WOPR') < 1000:
close_wells.append(well)
if close_wells:
actionx_callback('CLOSEWELLS', close_wells)
\end{code}
The implementation of this is quite complex with thread of execution going from
C++ to Python, then invoking a callback to C++ which will call
\inlinecode{Schedule::iterateScheduleSection()}, going back to Python to
complete the \inlinecode{run()} method before the function pointers pops back to
C++ and continues the simulator execution\footnote{This is documented in some
detail as code comments of \inlinecode{Schedule::applyPyAction()} in the
\path{Schedule.cpp} file.}.
\section{Implementing \udq{} like behavior}
The \udq{} keyword has three different purposes - all based on defining
complex quantities from the current state of the simulation:
\begin{enumerate}
\item Define a complex quantity to be used in a \actionx{} condition.
\item Define a complex quantity for reporting in the summary file.
\item Define a quantity which can used as a control in \kw{UDA}.
\end{enumerate}
All of these can be achieved by using the \pyaction{} keyword, although for the
two latter alternatives you must specify the \udq{} keyword in the deck first,
but you can let the \pyaction{} implementation override the value:
\begin{deck}
-- Observe that this UDQ will be assigned from a PYACTION keyword,
-- the value used in the ASSIGN statement below is pure dummy.
UDQ
ASSIGN WUGOOD 1 /
ASSIGN FUGOOD 1 /
/
\end{deck}
\subsection{Using \pyaction{} instead of \udq{} + \actionx{}}
Towards the end of section \ref{actionx_structure} it is demonstrated how \udq{}
and \actionx{} can be combined to implement an action in case a complicated
condition applies. As described in section \ref{pyaction_actionx} the best way
to actually invoke changes on the \kw{SCHEDULE} section is through the use of a
dummy \actionx{} keyword, but \pyaction{} is very well suited to evaluate
complex conditions. In the example below we close all wells which have
consistently produced less than 1000 $\mathrm{m^3/day}$ for more than 60 days:
\begin{code}
wopr_limit = 1000
time_limit = 60 * 3600 * 24
def init_state(summary_state):
if 'closed_wells' in state:
return
state['closed_wells'] = set()
bad_wells = {}
for well in summary_state.wells:
bad_wells[well] = None
state['bad_wells'] = bad_wells
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
shut_wells = []
init_state(summary_state)
for well in summary_state.wells:
if well in state['closed_wells']:
continue
if summary_state.well_var(well, 'WOPR') < wopr_limit:
elapsed = summary_state.elapsed()
if state['bad_wells'][well] is None:
state['bad_wells'][well] = elapsed
else:
bad_time = elapsed - state['bad_wells'][well]
if bad_time > time_limit:
shut_wells.append(well)
state['closed_wells'].add( well )
else:
state['bad_wells'][well] = None
if shut_wells:
actionx_callback(shut_wells)
\end{code}
\subsection{Using \pyaction{} to report to the summary file}
The important point when using \pyaction{} to report complex results to the
summary file is just that the \inlinecode{summary\_state} argument to the
\inlinecode{run()} function is \emph{writable} with \inlinecode{updata\_xxx}
calls. Assuming dummy \udq{} variables \kw{WUGOOD} and \kw{FUGOOD} have been
defined as per the example above, we can use \pyaction{} to set variable
\kw{FUGOOD} to one for all wells with rate above a limit, and the \kw{FUGOOD}
variable can be the count of such wells:
\begin{code}
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
good_count = 0
opr_limit = 1000
for wname in schedule.well_names():
if summary_state.well_var(wname, 'FOPR') > opr_limit:
good_count += 1
summary_state.update_well_var(wname, 'WUGOOD', 1)
else:
summary_state.update_well_var(wname, 'WUGOOD', 0)
summary_state.update_var('FUGOOD', good_count)
\end{code}
\subsection{Using \pyaction{} to set a \kw{UDA} control}
Using \pyaction{} to set \kw{UDA} controls is quite simple. Again the \udq{}
keyword must have been defined with a dummy value in the \kw{SCHEDULE} section,
and the \kw{UDA} keyword used in e.g. a \kw{WCONDPROD} keyword. Then the
\inlinecode{run()} function can just be used to assign to the \udq{} variable.
In the example below we use a \kw{UDA} to control the oil production rate, and
the value is set to the average value of the producing wells:
\begin{deck}
-- Define dummy UDQ WUOPR to be used as control in the WCONPROD
-- keyword. The actual value for this UDQ is assigned in a PYACTION
-- keyword
UDQ
ASSIGN WUOPR 0 /
/
...
...
-- Need to define a well list with all the production wells.
-- This is to ensure that the WCONPROD keyword is only applied
-- to producers.
WLIST
'PROD' P1 P2 P3 .../
WCONPROD
'*PROD' 'OPEN' 'ORAT' 'WUOPR' /
/
\end{deck}
This can then be combined with the python code:
\begin{code}
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
num_prod_wells = 0
for wname in schedule.well_names():
if summary_state.well_var(wname, 'WOPR') > 0:
num_prod_wells += 1
fopr = summary_state['FOPR']
new_rate = fopr / num_prod_wells
for wname in schedule.well_names():
summary_state.update_well_var(wname, 'WUOPR', new_rate)
\end{code}
\section{Security implications of \pyaction{}}
\label{pyaction_security}
The \pyaction{} keyword allows for execution of arbitrary user supplied Python
code, with the priviliges of the user actually running \flow{}. If you have a
setup where \flow{} runs with a different user account than the person
submitting the simulation you should be \emph{very careful} about enabling the
embedded Python functionality and the \pyaction{} keyword. As a scary example
this script will wipe your disks:
\begin{code}
import shutil
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
shutil.rmtree('/')
\end{code}
If the user running \flow{} has different security credentials than the user
submits the job, this has significant security implications.

View File

@ -1,599 +0,0 @@
\newcommand{\udq}{\kw{UDQ}}
\chapter{Programming in the deck: \udq{}}
\udq{} and \kw{ACTIONX} are two keywords which offer a sort of
\emph{programming} in the input deck. \udq{} is an acronym for \emph{User
Defined Quantity}, and the essence of the \udq{} keyword is the ability to
define arithmetic expressions based on the result vectors of the ongoing
simulation. The quantites evaluated with \udq{} can then be output as summary
variables, and they can be used as controls in keywords like \kw{WCONPROD} and
\kw{GCONINJE}. When used as controls the \udq{} variables are called \emph{User
Defined Arguments} (UDA).
For both the \udq{} and \kw{ACTIONX} keywords evaluating an arithmetic
expression based on the current results of the ongoing simulation is an
important part of the concept, and they are often referenced in pair as
\udq{}/\kw{ACTIONX}, this is slightly misleading as the two are fully
independent and share very little both as concepts in \flow{} and in the C++
implementation. The \kw{ACTIONX} keyword is described in chapter \ref{actionx}.
The \udq{} keyword is also documented in section 12.3.233 in the \flow{}
reference manual.
\section{Defining a new \udq{} keyword}
New \udq{} variables are defined with the \udq{} keyword in the \kw{SCHEDULE}
section. The \udq{} keyword is a sort of a super keyword with four additional
subcommands: \kw{DEFINE}, \kw{ASSIGN}, \kw{UNIT} and \kw{UPDATE}. The
\kw{DEFINE} subcommand is the most important command, that is used to
\emph{define} an arithmetic expression for a \udq{} variable, which is evaluated
at the end of every simulator time step. \kw{ASSIGN} is used to define a \udq{}
variable with a constant numerical value, in addition the \kw{ASSIGN} subcommand
is often used as a ``forward reference'' to enable using a \udq{} keyword in
another \kw{DEFINE} expression. The \kw{UNIT} command is used to assign a unit
string to a \udq{} variable, see section \ref{udq_units} for more details about
\udq{} variables and units. The \kw{UPDATE ON} and \kw{UPDATE OFF} commands can
be used to switch updating of \udq{} variables on and off. The \udq{} variables
are created in mode \kw{ON}.
All \udq{} keywords must have the letter \emph{U} as their second character, the
first character should be 'F', 'G' or 'W' to indicate whether this is a field,
group or well quantity\footnote{In \eclipse{} also the characters 'S', 'C', 'A'
and 'B' are used to denote \emph{segment}, \emph{connection} \emph{aquifer} and
\emph{block} variables respectively. None of these are supported in \flow{}.}.
The simplest way to define a \udq{} is just using the \kw{ASSIGN} subcommand of
the \udq{} keyword:
\begin{deck}
UDQ
ASSIGN FUVAR1 123 /
ASSIGN FUVAR2 456 /
/
\end{deck}
This way we will assign to variables \inlinecode{FUVAR1} and \inlinecode{FUVAR2}
with values 123 and 456 respectively. These values can output to the summary
file, be used as control values in a control keyword like \kw{WELTARG} and be
used to recursively define another \udq{} keyword.
The more interesting \udq{} subcommand is \kw{DEFINE} which is used to define an
arithmetic expression for a \udq{} variable, the arithmetic expression will be
evaluated at the end of every timestep. The expressions are built from the
normal arithmetic operators +,-,*,/, a predefined set of available functions
(see \ref{udq_functions}) and results from the ongoing simulation.
In the example below we create \udq{} variables \kw{FUWCT1} and \kw{FUWCT2} as
user defined field water cut, one based on the summary variables \kw{FWPR} and
\kw{FOPR} and one based on summing \kw{WOPR} and \kw{WWPR} over all wells
\begin{deck}
UDQ
DEFINE FUWCT1 FWPR/(FWPR + FOPR) /
DEFINE FUWCT2 SUM(WWPR)/(SUM(WWPR) + SUM(WOPR)) /
/
\end{deck}
A \udq{} variable can be redefined during the simulation, and also change from
constant \kw{ASSIGN} to variable \kw{DEFINE}. Observe that \udq{} values are
always evaluated in order of occurence in the input deck. For instance for this
input
\begin{deck}
UDQ
ASSIGN FU1 100 /
DEFINE FU2 FU1 + FOPR /
DEFINE FU1 FWPR /
/
\end{deck}
the evaluation order will be \{\kw{FU1}, \kw{FU2}\}\footnote{Maintaining the
input order and whether a certain \udq{} symbol is now a \kw{ASSIGN} or
\kw{DEFINE} keyword is also very important for the restart code.}. \kw{ASSIGN}
statements take effect at input time, making the newly defined symbol
immediately available for reuse in a subsequent defintion. This is utilized in
the \udq{} keyword above where the symbol \kw{FU1} is referenced in the
defintion of \kw{FU2}. As used in this example the \kw{ASSIGN FU1 100} can be
seen as a \emph{forward reference}. When we have completed the first timestep
and it is time to evalute the \udq{} expressions they will be evaluated in order
of \emph{first appearance}, i.e. \{\kw{FU1}, \kw{FU2}\}. At this stage the
active definition of \kw{FU1} is \inlinecode{FU1 = FWPR}, i.e. the value
\inlinecode{100} from the initial definition \inlinecode{FU1 = 100} is never
actually used.
\section{Different types of \udq{} - field, group and well}
The \udq{} keywords can be of different types, \flow{} supports \emph{field},
\emph{well} and \emph{group} keywords\footnote{\eclipse{} also supports
connection, segment and aquifer variables.}. The field keywords are scalar,
whereas the well and group keywords are sets with values for every well/group.
The type of a \udq{} keyword is inferred from the name in the same manner as the
summary keywords, i.e. for this \udq{} keyword
\begin{deck}
UDQ
ASSIGN FU1 100 /
ASSIGN WU1 200 /
ASSIGN GU1 300 /
/
\end{deck}
we will define one scalar keyword \kw{FU1}, one well set \kw{WU1} and one group
set \kw{GU1}. The well sets will have one slot for each well in the model, it is
not possible to create a well set with only a subset of wells, but the well set
can have \emph{undefined} value for a subset of wells. The set maintains a
\inlinecode{is\_defined()} status for each element and most operations only
apply to the defined elements\footnote{The C++ implementation of the \udq{}
value set is the equivalent of \texttt{std::map<std::string,
std::optional<double>>}.}.
As indicated with \kw{ASSIGN WU1 200} you can assign a scalar value to a set
keyword, then all elements in the set will have the same value. Assuming we have
a model with wells OP1, OP2, WI and GI the \kw{WU1} will look like
\begin{code}
WU1 = {"OP1": 100, "OP2": 100, "WI": 100, "GI": 100}.
\end{code}
When defining a well \udq{} it is natural to refer to well summary variables, in
the example below we define \kw{WUBHP} which is the bottom hole pressure
for each well, \kw{WUOPR1} which is the oil production rate for a subset of
wells and \kw{WUOPR2} which is the oil production rate for well OP1 \emph{broadcasted to all wells}.
\begin{deck}
UDQ
DEFINE WUBHP WBHP /
DEFINE WUOPR1 WOPR 'OP*' /
DEFINE WUOPR2 WOPR OP1 /
/
\end{deck}
After evaluation these \udq{} values will be\footnote{The numerical values are
arbitrary, just to illustrate that they are \emph{defined}, in contrast to the
[ ] which is used to illustrate an \emph{undefined} value.}:
\begin{code}
WUBHP = {"OP1": 20, "OP2": 30, "WI": 10, "GI": 15}
WUOPR1 = {"OP1": 13, "OP2": 17, "WI": [ ], "GI": [ ]}
WUOPR2 = {"OP1": 13, "OP2": 13, "WI": 13, "GI": 13}
\end{code}
Observe how well variables like \kw{WBHP} and \kw{WOPR} can be qualified with a
wellname pattern. If no wellname is supplied the expression will be evaluated
for all wells, as for \kw{WUBHP}, for \kw{WUOPR1} the pattern 'OP*' will select
wells \{OP1, OP2\} and leave the injectors \{WI, GI\} undefined. For \kw{WUOPR2}
the well pattern 'OP1' specifies a well completely, i.e. this will be evaluated
as a scalar, and then the scalar value \inlinecode{WOPR:OP1 == 13} is
broadcasted to all the wells in \kw{WUOPR2}.
\udq{} sets with different sets of defined wells can be combined, in most cases
the operations will be applied to the intersection of all defined wells,
consider for example\label{udq_diff}:
\begin{deck}
UDQ
DEFINE WUBHP WBHP /
DEFINE WUTHP WTHP OP* /
DEFINE WUPDIFF WUBHP - WUTHP
/
\end{deck}
When these \udq{} statements are evaluated we will get:
\begin{code}
WUBHP = {"OP1": 20, "OP2": 30, "WI": 10, "GI": 15}
WUTHP = {"OP1": 13, "OP2": 17, "WI": [ ], "GI": [ ]}
WUPDIFF = {"OP1": 7, "OP2": 13, "WI": [ ], "GI": [ ]}
\end{code}
As we see the undefined property for wells GI and WI in \kw{WUTHP} is contagious
when the two expressions are combined with \inlinecode{WUPDIFF = WUBHP - WUTHP},
see however section \ref{udq_union_functions} for a collection of functions
which operate on the union of values.
When an undefined variable is output to the summary file it will get a value
given as item 3 of the \kw{UDQPARAM} keyword. Summary output is the \emph{only}
point where the undefined value can be dereferenced, the numerical value given
in \kw{UDQPARAM} will not be available either for \udq{} nor \kw{ACTIONX}
evaluations.
\section{Functions available in \udq{} defintions}
\label{udq_functions}
\flow{} supports all the \udq{} functions available in \eclipse{}, for the
future it would be a quite simple C++ task to extend the list of available
functions, although that will affect \eclipse{} compatibility.
\subsection{Ordinary binary functions}
The \udq{} framework supports all the ordinary arithmetic operators +,-,*,/ and
\^{} and the comparison operators $>, \ge, <, \le, \ne, ==$. For all of these
operations sets and scalars can be combined freely. When combining a scalar and
a set the scalar will be promoted to a set with all values equal, i.e. for
\begin{deck}
UDQ
ASSIGN WULIMIT 100 /
/
\end{deck}
the numerical value 100 will be broadcasted to all wells:
\begin{code}
WULIMIT = {"OP1": 100, "OP2": 100, "WI": 100, "GI": 100}.
\end{code}
In the case of set arguments the operations are only applied to the union of
values which are defined in both argument sets. The comparison operators produce
numerical 0 or 1 depending on the result of the comparison, the result from a
comparison operation can be used numerically in further computations. In the
following example \kw{FUWCNT} will be the number of wells producing with oil
production rate above 1000\footnote{Remember: 1000 has the units of the
deck, i.e. $\mathrm{stb/day}$ in FIELD units and $\mathrm{m^3/day}$ in metric
units.}.
\begin{deck}
UDQ
DEFINE FUWCNT SUM( WOPR > 1000 ) /
/
\end{deck}
\subsection{Functions over a set returning a scalar}
The \udq{} framework has several functions which iterate over all the defined
members of a set and return a scalar. In the example
\begin{deck}
UDQ
DEFINE FU1 SUM(WOPR 'OP*') /
/
\end{deck}
The scalar variable \kw{FU1} will be equal to the sum of oil production rates
for all wells matching the pattern \kw{OP*}, the wells with a name not matching
\kw{OP*} will not contribute to the sum. The complete list of functions iterating
over a set and returning a scalar are:
\begin{description}
\item[SUM] Sum all defined elements in the argument set and return a scalar.
\item[AVEA] The arithmetic average of the elements in the set.
\item[AVEG] The geometric average of the elements in the set.
\item[AVEH] The harmonic average of the elements in the set.
\item[MAX] The maximum element in the set.
\item[MIN] The minimum element in the set.
\item[NORM1] The $\mathrm{L^1}$ norm of the elements in the set.
\item[NORM2] The $\mathrm{L^2}$ norm of the elements in the set.
\item[NORMI] The $\mathrm{L^\infty}$ norm of the elements in the set.
\item[PROD] The product of all the elements in the set.
\end{description}
\subsection{Elemental functions}
There is a family of functions which take a vector or scalar as argument, run
through all the elements in the argument and return a result of the same shape
as the argument, where a function has been applied to all the defined elements.
Assume that the \kw{WU1} has the following value:
\begin{code}
WU1 = {"OP1": -2, "OP2": -1, "WI": 1, "GI": []},
\end{code}
then \kw{DEFINE WUABS ABS(WU1)} will give
\begin{code}
WUABS = {"OP1": 2, "OP2": 1, "WI": 1, "GI": []}.
\end{code}
The available elemental functions of this kind come in different categories:
\subsubsection*{Mathematical functions}
\begin{description}
\item[EXP] Return a new set where all defined elements have been exponentiated.
\item[ABS] Return a new set with the absolute value of all elements.
\item[LN] Return a new set with the \emph{natural logarithm} of all elements.
\item[LOG] Return a new set with $\log_{10}$ of all elements.
\item[NINT] Return a new set where all elements have been converted to the
nearest integer.
\end{description}
\subsubsection*{Sorting functions}
The \udq{} functionality supports functions \kw{SORTA} and \kw{SORTD} to sort a
set in ascending or descending order respectively. Observe that these functions
do not sort the sets in place - the udqset does not have any notion of ordering,
rather they create a permutation set with values 1,2,3, ... The following
combination of \udq{} and \kw{ACTIONX} will use the \kw{SORTD} function to close
the two wells with the highest watercut:
\begin{deck}
UDQ
DEFINE WUWCTS SORTD(WWCT OP*) /
/
\end{deck}
assuming the \kw{WWCT} looks like
\begin{code}
WWCT = {"OP1": 0.5, "OP2": 0.2, "OP3": 0.1, "OP4":0.7, "WI": 0, "GI": 0}
\end{code}
then the \kw{WUWCTS} set will look like
\begin{code}
WUWCTS = {"OP1": 2, "OP2": 3, "OP3": 4, "OP4":1 "WI": [], "GI": []}
\end{code}
When this is combined with the \kw{ACTIONX}(see chapter \ref{actionx})
\begin{code}
ACTIONX
CW /
WUWCTS <= 2 /
/
WELOPEN
'?' 'CLOSE' /
/
ENDACTIO
\end{code}
the two wells with highest watercut will be selected in the \inlinecode{WUWCTS
<= 2} statement and that will be expanded to \{OP4, OP1\} by the '?'
expression in the \kw{WELOPEN} keyword.
\subsubsection*{Random functions}
The \udq{} machinery has functionality to sample random numbers, there are one
set of random number functions which are seeded deterministically by item 1 of
\kw{UDQPARAMS} and an alternative set which is seeded by the clock. The random
number functions take a \udq{} variable as argument, that is only to ensure that
the shape of the result value is correct.
\begin{description}
\item[RANDN] Random numbers from distribution $N(0,1)$ seeded deterministically
by item 1 in \kw{UDQPARAMS}.
\item[RANDU] Random numbers from distribution $U(-1,1)$ seeded deterministically
by item 1 in \kw{UDQPARAMS}.
\item[RRNDN] Random numbers from distribution $N(0,1)$ seeded by the clock.
\item[RRNDU] Random numbers from distribution $U(-1,1)$ seeded by the clock.
\end{description}
Assuming the argument vector \kw{WU1} looks like
\begin{code}
WU1 = {"OP1": -2, "OP2": [], "WI": 1, "GI": []},
\end{code}
the result of \kw{DEFINE WURAND RANDU(WU1)} could be like
\begin{code}
WURAND = {"OP1": 0.576, "OP2": [], "WI": -0.132, "GI": []}.
\end{code}
\subsubsection*{Work with defined status}
The functions \kw{DEF}, \kw{UNDEF} and \kw{IDV} can be used to inspect the
defined/not defined status of the elements in a \udq{} set.
\begin{description}
\item[DEF] Return a set with value 1 for all defined elements.
\item[UNDEF] Return a set with value 1 for all undefined elements.
\item[IDV] Return a set with value 1 for all defined elements and value 0 for
all undefined elements.
\end{description}
Assuming the input argument
\begin{code}
WU1 = {"OP1": -2, "OP2": [], "WI": 1, "GI": []},
\end{code}
the \udq{} assignments
\begin{deck}
UDQ
DEFINE WUDEF DEF(WU1) /
DEFINE WUUNDEF UNDEF(WU1) /
DEFINE WUIDV IDV(WU1) /
/
\end{deck}
will produce:
\begin{code}
WUDEF = {"OP1": 1, "OP2": [], "WI": 1, "GI": []},
WUUNDEF = {"OP1": [], "OP2": 1, "WI": [], "GI": 1},
WUIDV = {"OP1": 1, "OP2": 0, "WI": 1, "GI": 0},
\end{code}
\subsection{Union functions}
\label{udq_union_functions}
There are a list of functions \kw{Uxxx} which operate on the union of the values
found in the two sets, i.e. a result is assigned if at at least one set has
defined value for this well/group.
\begin{description}
\item[UADD] Will add the items from the two sets.
\item[UMUL] Will multiply the items from the two sets.
\item[UMAX] The maximum value from the two sets.
\item[UMIN] The minumum value from the two sets.
\end{description}
In the case where only one of the sets has a defined value the operation will be
performed \emph{as if} the function \kw{Uxxx} is the identity function.
As an example consider the two sets:
\begin{code}
WU1 = {"OP1": 1, "OP2": [], "WI": 2, "GI": []},
WU2 = {"OP1": 6, "OP2": 5, "WI": [], "GI": []},
\end{code}
and the \udq{} expression \kw{DEFINE WUUADD WU1 UADD WU2}, then the resulting
set \kw{WUUADD} will be
\begin{code}
WUUADD = {"OP1": 7, "OP2": 5, "WI": 2, "GI": []}.
\end{code}
This in contrast to a normal $+$ which only operates on the intersection of the
two sets, only well OP1 would have a defined value in this case.
\section{Used as a control: UDA}
\label{uda}
Probably one of the most important uses of the \udq{} functionality is the
ability to use a \udq{} as control in e.g. the \kw{WCONINJE} keyword. In the
example below we calculate the produced liquid volume from a group of wells and
use that as injection target for a water injector:
\begin{deck}
UDQ
DEFINE FULPR (WOPR P* + WWPR P*) * 1.25 /
/
...
...
WCONINJE
WI 'WATER' 'OPEN' 'RATE' 'FULPR' /
/
\end{deck}
In the following insane example we distribute the current oil production rate
randomly among the producers and use that as target for the next timestep - do
not try this at home:
\begin{deck}
UDQ
-- Create a 0 / 1 mask with 0 for injectors and 1 for producers.
DEFINE WUPROD WOPR > 0 /
-- Create a vector of random numbers [0,1] for all producers
DEFINE WURAND 0.5 * (RANDU(WUPROD) + 1) * WUPROD /
-- Create a vector where all producers get a random fraction of
-- the current total oil production rate
DEFINE WUOPR FOPR * WURAND / SUM(WURAND) /
/
-- Need to have a well list or similar to select all producers for
-- the WCONPROD keyword.
WLIST
'P' 'ADD' ..... /
WCONPROD
'*P' 'OPEN' 'ORAT' 'WUOPR' /
/
\end{deck}
One point about this example is that the \udq{} variable \kw{WUOPR} which is
used as as control in the \kw{WCONPROD} is a well set, the lookup machinery will
automatically use the correct well index when assigning control value to a
particular well.
From an implementation point of view the \kw{UDA} functionality creates a
significant complexity, because the actual rate to use in the simulation must be
evaluated \emph{just in time}.
\section{\udq{} units}
\label{udq_units}
The \udq{} subcommand \kw{UNIT} can be used to assign a string which is used as
output unit when the \udq{} variable is output to the summary file. This is
\emph{only} a string and does not induce any unit conversion. All \udq{}
evaluations are in terms of the corre deck units - irrespective of the \kw{UNIT}
subcommand. Consider the following
\begin{deck}
RUNSPEC
FIELD
...
...
SCHEDULE
UDQ
DEFINE WUI WWIR - 100 /
/
\end{deck}
\begin{enumerate}
\item The simulation runs in SI units; hence the water injection rate is
calculated in $\mathrm{m^3/s}$.
\item As part of the summary evaluation the \inlinecode{SummaryState} will
contain the water injection rate converted to field units.
\item The \udq{} variable \kw{WUI} is evaluated as the water injection rate from
\inlinecode{SummaryState} subtracted numerical value 100, \emph{it is solely the users
responsability that the numerical value 100 represents water injection rate in
field units.}
\end{enumerate}
Observe that the units are complicated, and non intuitive for \kw{UDA} values.
The \kw{UDA} evaluation is based on the \inlinecode{SummaryState} class which is
in deck units, the controls determined by \kw{UDA} evaluation must therefor be
converted to SI units just when it is passed to the simulator. The initial
design ambition was to block the deck units at the IO boundary, keeping the
internals fully in SI. The \kw{UDA} concept is the exception which manages to
inject deck units quite far into the code.
\section{Implementation details}
The significant part of the UDQ implementation is in classes located in
\path{opm/input/eclipse/Schedule/UDQ}, in addition the restart output of
\udq{}/\kw{UDA} values is in \path{opm/output/eclipse/AggregateUDQData.cpp}.
Finally the \udq{} parser makes use of the type \inlinecode{RawString} to treat
literal ``/'' and ``*'' different from ordinary parsing where ``/'' signifies
end of line and ``*'' is either a default or part of a multiplier expression.
\subsection*{\inlinecode{UDQConfig}}
The class \inlinecode{UDQConfig} internalizes the parsing of the \udq{} keywords
from the input deck. The \inlinecode{UDQConfig} instance is time-versioned and
managed by the \inlinecode{ScheduleState} class. The \inlinecode{UDQConfig} is
immutable while the simulator is executing. The \inlinecode{UDQConfig} contains
two main classes \inlinecode{UDQDefine} and \inlinecode{UDQAssign} in addition
to book-keeping code to keep track of what type of expression a \udq{} keyword
is at the time. A significant part of the book-keeping is only required to be
able to output restart files in \eclipse{} format.
\subsection*{\inlinecode{UDQDefine} and \inlinecode{UDQASTNode}}
The \inlinecode{UDQDefine} manages a parsed \udq{} expresssion along with a
chunck of metadata. The parsed \udq{} expression is managed in an instance of
\inlinecode{UDQASTNode}. The \inlinecode{UDQASTNode} contains a parsed tree
representation of the \udq{} input expression. The parsing of \udq{} expressions
happens at input time, and for the rest of the simulation the
\inlinecode{UDQASTnode} instances are immutable.
Many scalar \udq{} types are defined in the file \path{UDQEenums.hpp} and in the
namespace \inlinecode{UDQ} there are many small utility functions to work with
these enums.
\subsection*{\inlinecode{SummaryState}}
\label{summarystate}
The \inlinecode{SummaryState} class is not part of the \udq{} implementation,
but it is a very important class for the \udq{} functionality. At the end of
every timestep the simulator will call the method \inlinecode{evalSummary} which
will call into opm-common and evaluate all summary variables and store them in a
\inlinecode{SummaryState} instance\footnote{Observe that during initialization
the \udq{} expressions are inspected, and we make sure that all summary
variables needed to evaulate \udq{} expressions are evaluated in the Summary
evaluation.}. The \inlinecode{SummaryState} class manages a set of maps with
well, group and field variables, when evaluating e.g. the \kw{WOPR} the results
will be stored in a two level map first indexed with keyword \kw{WOPR} and then
with well name. Afterwards the \udq{} layer can fetch values with
\inlinecode{SummaryState::get\_well\_var()}. The values in the
\inlinecode{SummaryState} have been converted to output units, this is important
for the \kw{UDA} evaluation.
At the end of every timestep the \inlinecode{UDQConfig::eval()} method is called
to evaluate all the \udq{} expressions, the evaluated values will end up in the
active \inlinecode{SummaryState} instance, i.e. for this \udq{}
\begin{deck}
UDQ
DEFINE FUOPR SUM(WOPR) /
DEFINE WUGWR WGPR / WWPR /
/
\end{deck}
we will get \inlinecode{SummaryState} entries for \kw{FUOPR} and \kw{WUGWR} for
\emph{all} wells in the model. These \inlinecode{SummaryState} values can then
be output to the summary file, be used when evaluating \kw{ACTIONX} keywords or
to evaluate \kw{UDA} control values.
In addition to the \inlinecode{SummaryState} variable there is an instance of
type \inlinecode{UDQState} which is updated runtime, the \inlinecode{UDQState}
instance holds on to the results of \udq{} evaluations with more context than
\inlinecode{SummaryState} and is used to output \udq{} and \kw{UDA} state to the
restart files. While evaluating the simulator will create a \kw{UDQContext}
variable which will manage both the \inlinecode{SummaryState},
\inlinecode{UDQState} and also some \udq{} parameters from the \kw{RUNSPEC}
section. The lifetime of the \kw{UDQContext} instance is only one \udq{}
evaluation.
While evaluating the \udq{} expressions the results will be instances of
\inlinecode{UDQSet} which is a small container class which keeps track of
well/group names and whether a value is defined or not. The \inlinecode{UDQSet}
class overrides the arithmetic operators like \inlinecode{UDQSet::operator+()}
so that expressions like \kw{2 * WOPR 'OP*'} can be easily evaluated in code.
\subsection*{Paralell awareness}
\label{udq_parallel}
The opm-common code where the \udq{} functionality is implemented is totally
unaware of parallel execution, so to be certain that this works for a parallel
simulator care must be taken. In flow this is handled as:
\begin{enumerate}
\item The \inlinecode{Schedule} class as a whole is identical on all
processes.
\item The state variables \inlinecode{UDQState} and \inlinecode{SummaryState}
are distributed so they are equal on all processes before the \udq{}
evaluation. This communication is performed in the simulator.
\end{enumerate}
The \udq{} evaluation is invoked from
\path{opm-simulators/ebos/eclgenericwriter.cc} function
\inlinecode{evalSummary()}.

View File

@ -5,9 +5,9 @@
Module: opm-common
Description: Open Porous Media Initiative shared infrastructure
Version: 2024.04-pre
Label: 2024.04-pre
Version: 2018.10
Label: 2018.10
Maintainer: opm@opm-project.org
MaintainerName: OPM community
Url: http://opm-project.org
Depends: dune-common (>= 2.7)
Depends: dune-common

View File

@ -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" ) || \

View File

@ -1,194 +0,0 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief This is the unit test for the co2 brine PVT model
*
*/
#include "config.h"
#include <opm/material/fluidsystems/blackoilpvt/Co2GasPvt.hpp>
#include <opm/material/fluidsystems/blackoilpvt/BrineCo2Pvt.hpp>
#include <iostream>
template <class Co2Pvt>
double densityGas(const Co2Pvt& co2Pvt, const double p, const double T, const double Rv)
{
return co2Pvt.inverseFormationVolumeFactor(/*regionIdx=*/0,
T,
p,
Rv,
/*Rvw=*/0.0) * co2Pvt.gasReferenceDensity(0);
}
template <class BrinePvt>
double densityBrine(const BrinePvt& brinePvt, const double p, const double T, const double Rs)
{
double bo = brinePvt.inverseFormationVolumeFactor(/*regionIdx=*/0,
T,
p,
Rs);
return bo * (brinePvt.oilReferenceDensity(0) + Rs * brinePvt.gasReferenceDensity(0));
}
int main(int argc, char **argv)
{
bool help = false;
for (int i = 1; i < argc; ++i) {
std::string tmp = argv[i];
help = help || (tmp == "--h") || (tmp == "--help");
}
if (argc < 5 || help) {
std::cout << "USAGE:" << std::endl;
std::cout << "co2brinepvt <prop> <phase> <p> <T> <salinity> <rs> "<< std::endl;
std::cout << "prop = {density, invB, B, viscosity, rsSat, internalEnergy, enthalpy, diffusionCoefficient}" << std::endl;
std::cout << "phase = {CO2, brine}" << std::endl;
std::cout << "p: pressure in pascal" << std::endl;
std::cout << "T: temperature in kelvin" << std::endl;
std::cout << "salinity(optional): salt molality in mol/kg" << std::endl;
std::cout << "rs(optional): amount of dissolved CO2 in Brine in SM3/SM3" << std::endl;
std::cout << "OPTIONS:" << std::endl;
std::cout << "--h/--help Print help and exit." << std::endl;
std::cout << "DESCRIPTION:" << std::endl;
std::cout << "co2brinepvt computes PVT properties of a brine/co2 system " << std::endl;
std::cout << "for a given phase (oil or brine), pressure, temperature, salinity and rs." << std::endl;
std::cout << "The properties support are: density, the inverse phase formation volume factor (invB), viscosity, " << std::endl;
std::cout << "saturated dissolution factor (rsSat) " << std::endl;
std::cout << "See CO2STORE in the OPM manual for more details." << std::endl;
return EXIT_FAILURE;
}
std::string prop = argv[1];
std::string phase = argv[2];
double p = atof(argv[3]);
double T = atof(argv[4]);
double molality = 0.0;
double rs = 0.0;
double rv = 0.0; // only support 0.0 for now
if (argc > 5)
molality = atof(argv[5]);
if (argc > 6)
rs = atof(argv[6]);
const double MmNaCl = 58.44e-3; // molar mass of NaCl [kg/mol]
// convert to mass fraction
std::vector<double> salinity = {0.0};
if (molality > 0.0)
salinity[0] = 1 / ( 1 + 1 / (molality*MmNaCl));
Opm::BrineCo2Pvt<double> brineCo2Pvt(salinity);
Opm::Co2GasPvt<double> co2Pvt(salinity);
double value;
if (prop == "density") {
if (phase == "CO2") {
value = densityGas(co2Pvt, p, T, rv);
} else if (phase == "brine") {
value = densityBrine(brineCo2Pvt, p, T, rs);
} else {
throw std::runtime_error("phase " + phase + " not recognized. Use either CO2 or brine");
}
} else if (prop == "invB" || prop == "B") {
if (phase == "CO2") {
value = co2Pvt.inverseFormationVolumeFactor(/*regionIdx=*/0,
T,
p,
rv,
/*Rvw=*/0.0);
} else if (phase == "brine") {
value = brineCo2Pvt.inverseFormationVolumeFactor(/*regionIdx=*/0,
T,
p,
rs);
} else {
throw std::runtime_error("phase " + phase + " not recognized. Use either CO2 or brine");
}
if (prop == "B")
value = 1 / value;
} else if (prop == "viscosity") {
if (phase == "CO2") {
value = co2Pvt.viscosity(/*regionIdx=*/0,
T,
p,
rv,
/*Rvw=*/0.0);
} else if (phase == "brine") {
value = brineCo2Pvt.viscosity(/*regionIdx=*/0,
T,
p,
rs);
} else {
throw std::runtime_error("phase " + phase + " not recognized. Use either CO2 or brine");
}
} else if (prop == "rsSat") {
if (phase == "CO2") {
value = co2Pvt.saturatedWaterVaporizationFactor(/*regionIdx=*/0,
T,
p);
} else if (phase == "brine") {
value = brineCo2Pvt.saturatedGasDissolutionFactor(/*regionIdx=*/0,
T,
p);
} else {
throw std::runtime_error("phase " + phase + " not recognized. Use either CO2 or brine");
}
} else if (prop == "diffusionCoefficient") {
size_t comp_idx = 0; // not used
if (phase == "CO2") {
value = co2Pvt.diffusionCoefficient(T,p, comp_idx);
} else if (phase == "brine") {
value = brineCo2Pvt.diffusionCoefficient(T,p, comp_idx);
} else {
throw std::runtime_error("phase " + phase + " not recognized. Use either CO2 or brine");
}
} else if (prop == "internalEnergy") {
if (phase == "CO2") {
value = co2Pvt.internalEnergy(/*regionIdx=*/0 ,T,p, rv, 0.0);
} else if (phase == "brine") {
value = brineCo2Pvt.internalEnergy(/*regionIdx=*/0 ,T,p, rs);
} else {
throw std::runtime_error("phase " + phase + " not recognized. Use either CO2 or brine");
}
} else if (prop == "enthalpy") {
if (phase == "CO2") {
value = p / densityGas(co2Pvt, p, T, rv) + co2Pvt.internalEnergy(/*regionIdx=*/0 ,T,p, rv, 0.0);
} else if (phase == "brine") {
value = p / densityBrine(brineCo2Pvt, p, T, rs) + brineCo2Pvt.internalEnergy(/*regionIdx=*/0 ,T,p, rs);
} else {
throw std::runtime_error("phase " + phase + " not recognized. Use either CO2 or brine");
}
} else {
throw std::runtime_error("prop " + prop + " not recognized. "
+ "Use either density, visosity, invB, B, internalEnergy, enthalpy or diffusionCoefficient");
}
std::cout << value << std::endl;
return 0;
}

Some files were not shown because too many files have changed in this diff Show More