Compare commits
4 Commits
release/20
...
release/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
faab33a051 | ||
|
|
513893eb59 | ||
|
|
62dc95e894 | ||
|
|
8e11e44559 |
25
.gitignore
vendored
25
.gitignore
vendored
@@ -44,28 +44,3 @@ Testing/
|
||||
|
||||
# Build directory in source.
|
||||
build/
|
||||
|
||||
gmon.out
|
||||
log.log
|
||||
build
|
||||
install
|
||||
.cproject
|
||||
.project
|
||||
/testdata/statoil
|
||||
.idea
|
||||
/Debug/
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
|
||||
# Mac OS X debug info
|
||||
*.dSYM
|
||||
|
||||
# emacs directory setting:
|
||||
.dir-locals.el
|
||||
|
||||
31
.travis.yml
Normal file
31
.travis.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
language: cpp
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- boost-latest
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- libboost1.55-all-dev
|
||||
- gcc-4.8
|
||||
- g++-4.8
|
||||
- gfortran-4.8
|
||||
- liblapack-dev
|
||||
- libgmp3-dev
|
||||
- libsuitesparse-dev
|
||||
- libeigen3-dev
|
||||
- bc
|
||||
|
||||
before_script:
|
||||
- export CXX="g++-4.8" CC="gcc-4.8" FC="gfortran-4.8"
|
||||
- cd ..
|
||||
- opm-common/travis/build-prereqs.sh
|
||||
- opm-common/travis/clone-opm.sh opm-common
|
||||
|
||||
|
||||
script: opm-common/travis/build-and-test.sh opm-common
|
||||
|
||||
|
||||
120
CMakeLists.txt
120
CMakeLists.txt
@@ -1,58 +1,25 @@
|
||||
project(opm-common C CXX)
|
||||
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)
|
||||
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)
|
||||
|
||||
# Output implies input
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
set(ENABLE_ECL_INPUT ON)
|
||||
endif()
|
||||
|
||||
# And likewise, no input means no output
|
||||
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)
|
||||
|
||||
# We need to define this variable in the installed cmake config file.
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "#ENABLE_ECL_INPUT is needed by opm-common-prereq.cmake
|
||||
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 availabe after find_package(opm-common)")
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "set(OPM_MACROS_ROOT ${CMAKE_INSTALL_PREFIX}/share/opm)
|
||||
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)")
|
||||
|
||||
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 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(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)")
|
||||
endif()
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "set(OPM_MACROS_ROOT ${OPM_MACROS_ROOT})
|
||||
list(APPEND CMAKE_MODULE_PATH \${OPM_MACROS_ROOT}/cmake/Modules)")
|
||||
|
||||
# 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)
|
||||
|
||||
# Look for the opm-tests repository; if found the variable
|
||||
# HAVE_OPM_TESTS will be set to true.
|
||||
include(Findopm-tests)
|
||||
|
||||
# list of prerequisites for this particular project; this is in a
|
||||
# separate file (in cmake/Modules sub-directory) because it is shared
|
||||
# with the find module
|
||||
@@ -63,50 +30,12 @@ include (${project}-prereqs)
|
||||
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}
|
||||
list(APPEND opm-common_INCLUDE_DIRS ${EXTRA_INCLUDES})")
|
||||
if(ENABLE_ECL_INPUT)
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
|
||||
set(HAVE_ECL_INPUT 1)")
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
|
||||
set(HAVE_ECL_INPUT 1)")
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
|
||||
set(HAVE_ECL_OUTPUT 1)")
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
|
||||
set(HAVE_ECL_OUTPUT 1)")
|
||||
endif()
|
||||
|
||||
# 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(ENABLE_ECL_INPUT)
|
||||
# Keyword generation
|
||||
include(GenerateKeywords.cmake)
|
||||
|
||||
# Append generated sources
|
||||
list(APPEND opm-common_SOURCES ${PROJECT_BINARY_DIR}/ParserKeywords.cpp)
|
||||
endif()
|
||||
endmacro (sources_hook)
|
||||
|
||||
macro (fortran_hook)
|
||||
@@ -116,51 +45,10 @@ macro (files_hook)
|
||||
endmacro (files_hook)
|
||||
|
||||
macro (tests_hook)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
include(ExtraTests.cmake)
|
||||
endif()
|
||||
endmacro (tests_hook)
|
||||
|
||||
macro (install_hook)
|
||||
install(DIRECTORY ${PROJECT_BINARY_DIR}/include/
|
||||
DESTINATION include
|
||||
PATTERN *.hpp)
|
||||
endmacro (install_hook)
|
||||
|
||||
# all setup common to the OPM library modules is done here
|
||||
include (OpmLibMain)
|
||||
|
||||
# Build the compare utilities
|
||||
if(ENABLE_ECL_INPUT)
|
||||
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 testutil opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
opm_add_test(test_compareSummary CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs})
|
||||
opm_add_test(test_EclFilesComparator CONDITION ENABLE_ECL_INPUT
|
||||
LIBRARIES ${_libs})
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties(test_compareSummary PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
set_target_properties(test_EclFilesComparator PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
install(TARGETS compareECL DESTINATION bin)
|
||||
endif()
|
||||
|
||||
# Install build system files
|
||||
install(DIRECTORY cmake DESTINATION share/opm)
|
||||
|
||||
# Install tab completion skeleton
|
||||
install(FILES etc/opm_bash_completion.sh.in DESTINATION share/opm/etc)
|
||||
|
||||
@@ -21,284 +21,42 @@
|
||||
# the library needs it.
|
||||
|
||||
list (APPEND MAIN_SOURCE_FILES
|
||||
src/opm/common/data/SimulationDataContainer.cpp
|
||||
src/opm/common/OpmLog/CounterLog.cpp
|
||||
src/opm/common/OpmLog/EclipsePRTLog.cpp
|
||||
src/opm/common/OpmLog/LogBackend.cpp
|
||||
src/opm/common/OpmLog/Logger.cpp
|
||||
src/opm/common/OpmLog/LogUtil.cpp
|
||||
src/opm/common/OpmLog/OpmLog.cpp
|
||||
src/opm/common/OpmLog/StreamLog.cpp
|
||||
src/opm/common/OpmLog/TimerLog.cpp
|
||||
src/opm/common/utility/numeric/MonotCubicInterpolator.cpp
|
||||
src/opm/common/utility/parameters/Parameter.cpp
|
||||
src/opm/common/utility/parameters/ParameterGroup.cpp
|
||||
src/opm/common/utility/parameters/ParameterTools.cpp
|
||||
src/opm/common/utility/numeric/calculateCellVol.cpp
|
||||
opm/common/data/SimulationDataContainer.cpp
|
||||
opm/common/OpmLog/CounterLog.cpp
|
||||
opm/common/OpmLog/EclipsePRTLog.cpp
|
||||
opm/common/OpmLog/LogBackend.cpp
|
||||
opm/common/OpmLog/Logger.cpp
|
||||
opm/common/OpmLog/LogUtil.cpp
|
||||
opm/common/OpmLog/OpmLog.cpp
|
||||
opm/common/OpmLog/StreamLog.cpp
|
||||
opm/common/OpmLog/TimerLog.cpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND MAIN_SOURCE_FILES
|
||||
src/opm/json/JsonObject.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/Deck/Section.cpp
|
||||
src/opm/parser/eclipse/EclipseState/AquiferCT.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Aquancon.cpp
|
||||
src/opm/parser/eclipse/EclipseState/checkDeck.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EclipseConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EclipseState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/EndpointScaling.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/Box.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/BoxManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/FaceDir.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/FaultCollection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/Fault.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/FaultFace.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/GridDims.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/GridProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/NNC.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/PinchMode.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/setKeywordBox.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Grid/TransMult.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/Equil.cpp
|
||||
src/opm/parser/eclipse/EclipseState/InitConfig/InitConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Runspec.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ActionX.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/GroupTree.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MessageLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/ColumnSchema.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/JFunc.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/PvtxTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/SimpleTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableColumn.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableContainer.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableIndex.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/TableSchema.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Tables/Tables.cpp
|
||||
src/opm/parser/eclipse/EclipseState/UDQConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQExpression.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp
|
||||
src/opm/parser/eclipse/Parser/ParseContext.cpp
|
||||
src/opm/parser/eclipse/Parser/Parser.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserEnums.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserItem.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserKeyword.cpp
|
||||
src/opm/parser/eclipse/Parser/ParserRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawKeyword.cpp
|
||||
src/opm/parser/eclipse/RawDeck/RawRecord.cpp
|
||||
src/opm/parser/eclipse/RawDeck/StarToken.cpp
|
||||
src/opm/parser/eclipse/Units/Dimension.cpp
|
||||
src/opm/parser/eclipse/Units/UnitSystem.cpp
|
||||
src/opm/parser/eclipse/Utility/Functional.cpp
|
||||
src/opm/parser/eclipse/Utility/Stringview.cpp
|
||||
)
|
||||
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND MAIN_SOURCE_FILES external/cjson/cJSON.c)
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list( APPEND MAIN_SOURCE_FILES
|
||||
src/opm/output/eclipse/AggregateConnectionData.cpp
|
||||
src/opm/output/eclipse/AggregateGroupData.cpp
|
||||
src/opm/output/eclipse/AggregateMSWData.cpp
|
||||
src/opm/output/eclipse/AggregateWellData.cpp
|
||||
src/opm/output/eclipse/CreateDoubHead.cpp
|
||||
src/opm/output/eclipse/CreateInteHead.cpp
|
||||
src/opm/output/eclipse/CreateLogiHead.cpp
|
||||
src/opm/output/eclipse/WellDataSerializers.cpp
|
||||
src/opm/output/eclipse/DoubHEAD.cpp
|
||||
src/opm/output/eclipse/EclipseGridInspector.cpp
|
||||
src/opm/output/eclipse/EclipseIO.cpp
|
||||
src/opm/output/eclipse/InteHEAD.cpp
|
||||
src/opm/output/eclipse/libECLRestart.cpp
|
||||
src/opm/output/eclipse/LinearisedOutputTable.cpp
|
||||
src/opm/output/eclipse/LoadRestart.cpp
|
||||
src/opm/output/eclipse/LogiHEAD.cpp
|
||||
src/opm/output/eclipse/RestartIO.cpp
|
||||
src/opm/output/eclipse/Summary.cpp
|
||||
src/opm/output/eclipse/SummaryState.cpp
|
||||
src/opm/output/eclipse/Tables.cpp
|
||||
src/opm/output/eclipse/RegionCache.cpp
|
||||
src/opm/output/eclipse/RestartValue.cpp
|
||||
src/opm/output/data/Solution.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_calculateCellVol.cpp
|
||||
tests/test_cmp.cpp
|
||||
tests/test_cubic.cpp
|
||||
tests/test_messagelimiter.cpp
|
||||
tests/test_nonuniformtablelinear.cpp
|
||||
tests/test_OpmLog.cpp
|
||||
tests/test_param.cpp
|
||||
tests/test_SimulationDataContainer.cpp
|
||||
tests/test_sparsevector.cpp
|
||||
tests/test_uniformtablelinear.cpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
tests/parser/ACTIONX.cpp
|
||||
tests/parser/ADDREGTests.cpp
|
||||
tests/parser/AquiferCTTests.cpp
|
||||
tests/parser/AqudimsTests.cpp
|
||||
tests/parser/AquanconTests.cpp
|
||||
tests/parser/BoxTests.cpp
|
||||
tests/parser/ColumnSchemaTests.cpp
|
||||
tests/parser/ConnectionTests.cpp
|
||||
tests/parser/COMPSEGUnits.cpp
|
||||
tests/parser/CopyRegTests.cpp
|
||||
tests/parser/DeckTests.cpp
|
||||
tests/parser/DynamicStateTests.cpp
|
||||
tests/parser/DynamicVectorTests.cpp
|
||||
tests/parser/Eclipse3DPropertiesTests.cpp
|
||||
tests/parser/EclipseGridTests.cpp
|
||||
tests/parser/EqualRegTests.cpp
|
||||
tests/parser/EventTests.cpp
|
||||
tests/parser/FaceDirTests.cpp
|
||||
tests/parser/FaultTests.cpp
|
||||
tests/parser/FunctionalTests.cpp
|
||||
tests/parser/GeomodifierTests.cpp
|
||||
tests/parser/GridPropertyTests.cpp
|
||||
tests/parser/GroupTests.cpp
|
||||
tests/parser/InitConfigTest.cpp
|
||||
tests/parser/IOConfigTests.cpp
|
||||
tests/parser/MessageLimitTests.cpp
|
||||
tests/parser/MultiRegTests.cpp
|
||||
tests/parser/MultisegmentWellTests.cpp
|
||||
tests/parser/MULTREGTScannerTests.cpp
|
||||
tests/parser/OrderedMapTests.cpp
|
||||
tests/parser/ParseContextTests.cpp
|
||||
tests/parser/PORVTests.cpp
|
||||
tests/parser/RawKeywordTests.cpp
|
||||
tests/parser/RestartConfigTests.cpp
|
||||
tests/parser/RunspecTests.cpp
|
||||
tests/parser/SatfuncPropertyInitializersTests.cpp
|
||||
tests/parser/ScheduleTests.cpp
|
||||
tests/parser/SectionTests.cpp
|
||||
tests/parser/SimpleTableTests.cpp
|
||||
tests/parser/SimulationConfigTest.cpp
|
||||
tests/parser/StarTokenTests.cpp
|
||||
tests/parser/StringTests.cpp
|
||||
tests/parser/SummaryConfigTests.cpp
|
||||
tests/parser/TabdimsTests.cpp
|
||||
tests/parser/TableColumnTests.cpp
|
||||
tests/parser/TableContainerTests.cpp
|
||||
tests/parser/TableManagerTests.cpp
|
||||
tests/parser/TableSchemaTests.cpp
|
||||
tests/parser/ThresholdPressureTest.cpp
|
||||
tests/parser/TimeMapTest.cpp
|
||||
tests/parser/TransMultTests.cpp
|
||||
tests/parser/TuningTests.cpp
|
||||
tests/parser/UDQTests.cpp
|
||||
tests/parser/UnitTests.cpp
|
||||
tests/parser/ValueTests.cpp
|
||||
tests/parser/WellSolventTests.cpp
|
||||
tests/parser/WellTests.cpp
|
||||
tests/parser/WTEST.cpp)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_AggregateWellData.cpp
|
||||
tests/test_CharArrayNullTerm.cpp
|
||||
tests/test_EclipseIO.cpp
|
||||
tests/test_DoubHEAD.cpp
|
||||
tests/test_InteHEAD.cpp
|
||||
tests/test_LinearisedOutputTable.cpp
|
||||
tests/test_LogiHEAD.cpp
|
||||
tests/test_regionCache.cpp
|
||||
tests/test_Restart.cpp
|
||||
tests/test_RFT.cpp
|
||||
tests/test_Solution.cpp
|
||||
tests/test_Summary.cpp
|
||||
tests/test_Tables.cpp
|
||||
tests/test_Wells.cpp
|
||||
tests/test_WindowedArray.cpp
|
||||
tests/test_writenumwells.cpp
|
||||
tests/test_serialize_ICON.cpp
|
||||
tests/test_serialize_SCON.cpp
|
||||
tests/test_cmp.cpp
|
||||
tests/test_OpmLog.cpp
|
||||
tests/test_messagelimiter.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/testdata.param
|
||||
)
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/FIRST_SIM.DATA
|
||||
tests/FIRST_SIM_THPRES.DATA
|
||||
tests/summary_deck.DATA
|
||||
tests/group_group.DATA
|
||||
tests/testblackoilstate3.DATA
|
||||
tests/testrft.DATA
|
||||
tests/table_deck.DATA
|
||||
tests/summary_deck_non_constant_porosity.DATA
|
||||
tests/SUMMARY_EFF_FAC.DATA
|
||||
tests/SPE1CASE1.DATA
|
||||
tests/SPE9_CP_PACKED.DATA
|
||||
)
|
||||
endif()
|
||||
)
|
||||
|
||||
list (APPEND EXAMPLE_SOURCE_FILES
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list (APPEND EXAMPLE_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
)
|
||||
endif()
|
||||
)
|
||||
|
||||
# programs listed here will not only be compiled, but also marked for
|
||||
# installation
|
||||
list (APPEND PROGRAM_SOURCE_FILES
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list (APPEND PROGRAM_SOURCE_FILES
|
||||
examples/opmi.cpp
|
||||
examples/opmpack.cpp
|
||||
)
|
||||
endif()
|
||||
)
|
||||
|
||||
|
||||
list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/ErrorMacros.hpp
|
||||
opm/common/Exceptions.hpp
|
||||
opm/common/ResetLocale.hpp
|
||||
opm/common/Unused.hpp
|
||||
opm/common/Valgrind.hpp
|
||||
opm/common/data/SimulationDataContainer.hpp
|
||||
opm/common/OpmLog/CounterLog.hpp
|
||||
opm/common/OpmLog/EclipsePRTLog.hpp
|
||||
@@ -310,206 +68,6 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/OpmLog/OpmLog.hpp
|
||||
opm/common/OpmLog/StreamLog.hpp
|
||||
opm/common/OpmLog/TimerLog.hpp
|
||||
opm/common/utility/numeric/cmp.hpp
|
||||
opm/common/util/numeric/cmp.hpp
|
||||
opm/common/utility/platform_dependent/disable_warnings.h
|
||||
opm/common/utility/platform_dependent/reenable_warnings.h
|
||||
opm/common/utility/numeric/blas_lapack.h
|
||||
opm/common/utility/numeric/buildUniformMonotoneTable.hpp
|
||||
opm/common/utility/numeric/linearInterpolation.hpp
|
||||
opm/common/utility/numeric/MonotCubicInterpolator.hpp
|
||||
opm/common/utility/numeric/NonuniformTableLinear.hpp
|
||||
opm/common/utility/numeric/RootFinders.hpp
|
||||
opm/common/utility/numeric/SparseVector.hpp
|
||||
opm/common/utility/numeric/UniformTableLinear.hpp
|
||||
opm/common/utility/parameters/ParameterGroup.hpp
|
||||
opm/common/utility/parameters/ParameterGroup_impl.hpp
|
||||
opm/common/utility/parameters/Parameter.hpp
|
||||
opm/common/utility/parameters/ParameterMapItem.hpp
|
||||
opm/common/utility/parameters/ParameterRequirement.hpp
|
||||
opm/common/utility/parameters/ParameterStrings.hpp
|
||||
opm/common/utility/parameters/ParameterTools.hpp
|
||||
opm/common/utility/numeric/calculateCellVol.hpp
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
opm/json/JsonObject.hpp
|
||||
opm/parser/eclipse/Utility/Stringview.hpp
|
||||
opm/parser/eclipse/Utility/Functional.hpp
|
||||
opm/parser/eclipse/Utility/Typetools.hpp
|
||||
opm/parser/eclipse/Utility/String.hpp
|
||||
opm/parser/eclipse/Generator/KeywordGenerator.hpp
|
||||
opm/parser/eclipse/Generator/KeywordLoader.hpp
|
||||
opm/parser/eclipse/Units/UnitSystem.hpp
|
||||
opm/parser/eclipse/Units/Units.hpp
|
||||
opm/parser/eclipse/Units/Dimension.hpp
|
||||
opm/parser/eclipse/Parser/ParserItem.hpp
|
||||
opm/parser/eclipse/Parser/Parser.hpp
|
||||
opm/parser/eclipse/Parser/ParserRecord.hpp
|
||||
opm/parser/eclipse/Parser/ParserKeyword.hpp
|
||||
opm/parser/eclipse/Parser/InputErrorAction.hpp
|
||||
opm/parser/eclipse/Parser/ParserEnums.hpp
|
||||
opm/parser/eclipse/Parser/ParseContext.hpp
|
||||
opm/parser/eclipse/Parser/ParserConst.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/InitConfig/Equil.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/Value.hpp
|
||||
opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp
|
||||
opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridDims.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/TransMult.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/PinchMode.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/Fault.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/Box.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/NNC.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/MinpvMode.hpp
|
||||
opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/EndpointScaling.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PdvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TlpmixpaTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvdgTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/MsfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/GasvisctTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Regdims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Eqldims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SpecrockTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlydhflfTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyshlogTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RsvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SpecheatTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgcwmisTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Sof2Table.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SwfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/EnptvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SwofTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/FlatTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Aqudims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/JFunc.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableIndex.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtgTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableSchema.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RocktabTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/EnkrvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyrockTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtxTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/WatvisctTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableEnums.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RvvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/AqutabTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyadsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PbvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SorwmisTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlymaxTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PlyviscTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TableColumn.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SsfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvdoTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/OilvisctTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/MiscTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgwfnTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvdsTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PvtoTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/ColumnSchema.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/PmiscTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/RtempvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SlgofTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/ImptvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/ImkrvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Sof3Table.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgofTable.hpp
|
||||
opm/parser/eclipse/EclipseState/EclipseState.hpp
|
||||
opm/parser/eclipse/EclipseState/EclipseConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquancon.hpp
|
||||
opm/parser/eclipse/EclipseState/AquiferCT.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Events.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Connection.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/checkDeck.hpp
|
||||
opm/parser/eclipse/EclipseState/Runspec.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp
|
||||
opm/parser/eclipse/EclipseState/UDQConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQExpression.hpp
|
||||
opm/parser/eclipse/Deck/DeckItem.hpp
|
||||
opm/parser/eclipse/Deck/Deck.hpp
|
||||
opm/parser/eclipse/Deck/Section.hpp
|
||||
opm/parser/eclipse/Deck/DeckOutput.hpp
|
||||
opm/parser/eclipse/Deck/DeckKeyword.hpp
|
||||
opm/parser/eclipse/Deck/DeckRecord.hpp
|
||||
opm/parser/eclipse/RawDeck/StarToken.hpp
|
||||
opm/parser/eclipse/RawDeck/RawEnums.hpp
|
||||
opm/parser/eclipse/RawDeck/RawRecord.hpp
|
||||
opm/parser/eclipse/RawDeck/RawKeyword.hpp
|
||||
opm/parser/eclipse/RawDeck/RawConsts.hpp)
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
opm/output/data/Cells.hpp
|
||||
opm/output/data/Solution.hpp
|
||||
opm/output/data/Wells.hpp
|
||||
opm/output/eclipse/VectorItems/connection.hpp
|
||||
opm/output/eclipse/VectorItems/intehead.hpp
|
||||
opm/output/eclipse/VectorItems/well.hpp
|
||||
opm/output/eclipse/AggregateGroupData.hpp
|
||||
opm/output/eclipse/AggregateConnectionData.hpp
|
||||
opm/output/eclipse/AggregateMSWData.hpp
|
||||
opm/output/eclipse/AggregateWellData.hpp
|
||||
opm/output/eclipse/CharArrayNullTerm.hpp
|
||||
opm/output/eclipse/DoubHEAD.hpp
|
||||
opm/output/eclipse/EclipseGridInspector.hpp
|
||||
opm/output/eclipse/EclipseIO.hpp
|
||||
opm/output/eclipse/EclipseIOUtil.hpp
|
||||
opm/output/eclipse/InteHEAD.hpp
|
||||
opm/output/eclipse/libECLRestart.hpp
|
||||
opm/output/eclipse/LinearisedOutputTable.hpp
|
||||
opm/output/eclipse/LogiHEAD.hpp
|
||||
opm/output/eclipse/RegionCache.hpp
|
||||
opm/output/eclipse/RestartIO.hpp
|
||||
opm/output/eclipse/RestartValue.hpp
|
||||
opm/output/eclipse/Summary.hpp
|
||||
opm/output/eclipse/SummaryState.hpp
|
||||
opm/output/eclipse/Tables.hpp
|
||||
opm/output/eclipse/WindowedArray.hpp
|
||||
opm/output/eclipse/WriteRestartHelpers.hpp
|
||||
opm/output/OutputWriter.hpp
|
||||
)
|
||||
endif()
|
||||
opm/common/utility/platform_dependent/reenable_warnings.h)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/ParserKeywords.cpp
|
||||
${BASE_DIR}/ParserKeywords.cpp)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/inlinekw.cpp
|
||||
${BASE_DIR}/inlinekw.cpp)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${BASE_DIR}/tmp_gen/include/opm/parser/eclipse/Parser/ParserKeywords.hpp
|
||||
${BASE_DIR}/include/opm/parser/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/parser/eclipse/Parser/ParserKeywords ${HDR})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${HDR}
|
||||
${BASE_DIR}/include/opm/parser/eclipse/Parser/ParserKeywords/${hdr})
|
||||
endforeach()
|
||||
107
ExtraTests.cmake
107
ExtraTests.cmake
@@ -1,107 +0,0 @@
|
||||
# Libs to link tests against
|
||||
set(TEST_LIBS opmcommon ecl Boost::unit_test_framework)
|
||||
set(EXTRA_TESTS)
|
||||
|
||||
# Generated source, needs to be here
|
||||
opm_add_test(InlineKeywordTest
|
||||
EXE_NAME inlinekw
|
||||
SOURCES ${PROJECT_BINARY_DIR}/inlinekw.cpp
|
||||
LIBRARIES ${TEST_LIBS})
|
||||
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}/)
|
||||
list(APPEND EXTRA_TESTS ParserTests)
|
||||
|
||||
opm_add_test(ParserIncludeTests
|
||||
SOURCES tests/parser/ParserIncludeTests.cpp
|
||||
LIBRARIES ${TEST_LIBS}
|
||||
TEST_ARGS ${_testdir}/parser/)
|
||||
target_compile_definitions(ParserIncludeTests PRIVATE
|
||||
-DHAVE_CASE_SENSITIVE_FILESYSTEM=${HAVE_CASE_SENSITIVE_FILESYSTEM})
|
||||
list(APPEND EXTRA_TESTS ParserIncludeTests)
|
||||
|
||||
opm_add_test(PvtxTableTests
|
||||
SOURCES tests/parser/PvtxTableTests.cpp
|
||||
LIBRARIES ${TEST_LIBS}
|
||||
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/)
|
||||
list(APPEND EXTRA_TESTS EclipseStateTests)
|
||||
|
||||
foreach (test BoxTest
|
||||
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/)
|
||||
list(APPEND EXTRA_TESTS ${test})
|
||||
endforeach ()
|
||||
|
||||
# opm-tests dependent tests
|
||||
if(HAVE_OPM_TESTS)
|
||||
opm_add_test(parse_write ONLY_COMPILE
|
||||
SOURCES tests/parser/integration/parse_write.cpp
|
||||
LIBRARIES ${TEST_LIBS})
|
||||
list(APPEND EXTRA_TESTS parse_write)
|
||||
foreach (deck ${OPM_TESTS_ROOT}/norne/NORNE_ATW2013.DATA
|
||||
${OPM_TESTS_ROOT}/spe1_solvent/SPE1CASE2_SOLVENT.DATA
|
||||
${OPM_TESTS_ROOT}/spe9_solvent/SPE9_CP_SOLVENT_CO2.DATA
|
||||
${OPM_TESTS_ROOT}/spe5/SPE5CASE1.DATA
|
||||
${OPM_TESTS_ROOT}/polymer_simple2D/2D_THREEPHASE_POLY_HETER.DATA
|
||||
${OPM_TESTS_ROOT}/spe1/SPE1CASE1.DATA
|
||||
${OPM_TESTS_ROOT}/spe1/SPE1CASE2.DATA
|
||||
${OPM_TESTS_ROOT}/spe1/SPE1CASE2_FAMII.DATA
|
||||
${OPM_TESTS_ROOT}/spe1/SPE1CASE2_SLGOF.DATA
|
||||
${OPM_TESTS_ROOT}/spe3/SPE3CASE1.DATA
|
||||
${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.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()
|
||||
set_property(TEST NORNE_ATW2013
|
||||
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)
|
||||
@@ -1,54 +0,0 @@
|
||||
set(genkw_SOURCES src/opm/json/JsonObject.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
|
||||
src/opm/common/OpmLog/LogBackend.cpp
|
||||
src/opm/common/OpmLog/LogUtil.cpp
|
||||
)
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND genkw_SOURCES external/cjson/cJSON.c)
|
||||
endif()
|
||||
add_executable(genkw ${genkw_SOURCES})
|
||||
|
||||
target_link_libraries(genkw ecl Boost::regex Boost::filesystem Boost::system)
|
||||
|
||||
# Generate keyword list
|
||||
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
|
||||
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 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)
|
||||
@@ -1,3 +1,3 @@
|
||||
# opm-common
|
||||
# opm-common 
|
||||
Contains common components used throughout all of OPM,
|
||||
in particular CMake modules for the build system.
|
||||
|
||||
45
changelog.md
45
changelog.md
@@ -1,45 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
A short month-by-month synopsis of change highlights. Most bugfixes won't make
|
||||
it in here, only the bigger features and interface changes.
|
||||
|
||||
# 2016.12
|
||||
* ZCORN adjustments improved, considers cell-cell relations
|
||||
* Slightly more robust compilation - won't crash if locales are broken
|
||||
* Accessing the PVTW table has a richer interface
|
||||
* FAULTS face direction accepts X+, I+, Y+, J+, Z+ and K+
|
||||
* WELOPEN can be controlled with completion numbers (last two parameters)
|
||||
* COMPLUMP is now supported
|
||||
* Don't crash on aquifer keywords
|
||||
* GMWSET and FMWSET are expanded properly
|
||||
* Don't crash on DEBUG
|
||||
* Read support for COORDSYS, GRUPRIG, LGR, PRORDER, TRACERS, TUNINGDP,
|
||||
WDFACCOR, WEFAC, and WORKLIM, no longer crashes.
|
||||
* RS and RV support.
|
||||
* Support for DENSITY, PVTW, and ROCK tables
|
||||
* JFUNC is understood and exposed
|
||||
|
||||
# 2016.11
|
||||
* A new class, Runspec, for the RUNSPEC section, has been introduced
|
||||
* Nodes in the FIELD group are no longer added to the Summary config
|
||||
* WCONHIST only adds phases present in the deck
|
||||
* cJSON can now be installed externally
|
||||
* DeckItem and ParserItem internals refactored
|
||||
* Build time reduced by only giving necessary source files to the json compiler
|
||||
* Support for OPERATE, WSEGITER and GCONPROD
|
||||
* Internal shared_ptrs removed from Schedule and children; interface updated
|
||||
* Schedule is now copyable with regular C++ copy semantics - no internal refs
|
||||
* Well head I/J is now time step dependent
|
||||
* Well reference depth is time step dependent
|
||||
* Some ZCORN issues fixed
|
||||
* gas/oil and oil/gas ratio unit fixed for FIELD units
|
||||
|
||||
# 2016.10
|
||||
* Significant improvements in overall parser performance
|
||||
* shared_ptr has largely been removed from all public interfaces
|
||||
* JFUNC keyword can be parsed
|
||||
* Boolean conversions are explicit
|
||||
* The Units.hpp header from core is moved here, replacing ConversionFactors
|
||||
* The ConstPtr and Ptr shared pointer aliases are removed
|
||||
* UnitSystem, Eclipse3DProperties, and OilVaporizationProperties are default
|
||||
constructible
|
||||
@@ -1,49 +0,0 @@
|
||||
# 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()
|
||||
@@ -1,29 +0,0 @@
|
||||
#
|
||||
# Module to check whether the file system is case sensitive or not
|
||||
#
|
||||
# Sets the following variable:
|
||||
#
|
||||
# HAVE_CASE_SENSITIVE_FILESYSTEM True if the file system honors the case of files
|
||||
|
||||
message(STATUS "Checking whether the file system is case-sensitive")
|
||||
# create a file containing uppercase characters
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/UPPER" "Foo")
|
||||
|
||||
# check if the all-lowercase file with the same name can be opened
|
||||
set(FooContents "")
|
||||
if (EXISTS "${CMAKE_BINARY_DIR}/upper")
|
||||
file(READ "${CMAKE_BINARY_DIR}/upper" FooContents)
|
||||
endif()
|
||||
|
||||
# remove the file again in order not to have it dangling around...
|
||||
file(REMOVE "${CMAKE_BINARY_DIR}/UPPER")
|
||||
|
||||
# check the contents of the file opened with lower-case. If it is
|
||||
# empty, the file system is case sensitive.
|
||||
if ("${FooContents}" STREQUAL "Foo")
|
||||
message(STATUS "File system is not case-sensitive")
|
||||
set(HAVE_CASE_SENSITIVE_FILESYSTEM 0)
|
||||
else()
|
||||
message(STATUS "File system is case-sensitive")
|
||||
set(HAVE_CASE_SENSITIVE_FILESYSTEM 1)
|
||||
endif()
|
||||
@@ -78,17 +78,7 @@ function (configure_vars obj syntax filename verb)
|
||||
# write a CMake statements that warns if the value has changed
|
||||
if ("${syntax}" STREQUAL "CMAKE")
|
||||
set (_db "\${") # to avoid parsing problems
|
||||
# special case: if we have a truth variable HAVE_ and this is
|
||||
# either just defined (as is), or set to 1 explicitly, then both
|
||||
# of these count as "true", so put in a check that also accepts
|
||||
# both of these values.
|
||||
if (("${_var}" MATCHES "^HAVE_.*") AND
|
||||
(("${${_var}}" STREQUAL "") OR ("${${_var}}" STREQUAL "1")))
|
||||
set (_cond "(\"${_db}${_var}}\" STREQUAL \"\") OR (\"${_db}${_var}}\" STREQUAL \"1\")")
|
||||
else ()
|
||||
set (_cond "\"${_db}${_var}}\" STREQUAL \"${${_var}}\"")
|
||||
endif ()
|
||||
file (APPEND "${filename}" "if (DEFINED ${_var} AND NOT (${_cond}))\n")
|
||||
file (APPEND "${filename}" "if (DEFINED ${_var} AND NOT \"${_db}${_var}}\" STREQUAL \"${${_var}}\")\n")
|
||||
file (APPEND "${filename}" "\tmessage (WARNING \"Incompatible value \\\"${_db}${_var}}\\\" of variable \\\"${_var}\\\"\")\n")
|
||||
file (APPEND "${filename}" "endif ()\n")
|
||||
endif ()
|
||||
|
||||
47
cmake/Modules/DuneCompat.cmake
Normal file
47
cmake/Modules/DuneCompat.cmake
Normal file
@@ -0,0 +1,47 @@
|
||||
# - Dunecontrol compatibility
|
||||
#
|
||||
# Enables this build to be a part of a dunecontrol chain. The
|
||||
# DUNE_CHECK_MODULES macro greps the top-level Makefile for the
|
||||
# presence of the abs_top_srcdir variable (!) and uses that as
|
||||
# the include directory of a module. Also, the contents are not
|
||||
# checked so if the variable is not present, it generates an
|
||||
# invalid command line (-I without argument) which causes the
|
||||
# autoconf probe to fail. This module patches our Makefile (!!)
|
||||
# so the necessary string will be there; in itself this string
|
||||
# has no use for us, it is solemnly to satisfy the M4 scripts.
|
||||
|
||||
if (CMAKE_GENERATOR MATCHES "Unix Makefiles")
|
||||
# we need an up-to-date, patched Makefile. this is always checked when
|
||||
# the makefile is run, thus the need for a marker file to keep a
|
||||
# timestamp to see when it was last patched (by us)
|
||||
# amazingly, nothing depends on the generated Makefile, so this can be
|
||||
# run whenever in the build without trigging a compile of e.g. config.h
|
||||
add_custom_target (dune-compat ALL
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_HOME_DIRECTORY=${CMAKE_HOME_DIRECTORY} -P ${OPM_MACROS_ROOT}/cmake/Scripts/DuneCompat2.cmake
|
||||
COMMENT "Patching Makefile to be DUNE compatible"
|
||||
)
|
||||
endif (CMAKE_GENERATOR MATCHES "Unix Makefiles")
|
||||
|
||||
# dunecontrol refuses to use a build tree as module directory unless
|
||||
# there is a dune.module in it. however, if we are in a sub-dir. of
|
||||
# the source, we are probably using dunecontrol with a --build-dir
|
||||
# argument, and won't call dunecontrol from the parent (which is the
|
||||
# source dir and most likely doesn't contain other projects) anyway,
|
||||
# i.e. we only copy if we are truly out-of-source
|
||||
string (LENGTH "${PROJECT_SOURCE_DIR}/" _src_dir_len)
|
||||
string (LENGTH "${PROJECT_BINARY_DIR}/" _bin_dir_len)
|
||||
if (_src_dir_len GREATER _bin_dir_len)
|
||||
set (_not_substring TRUE)
|
||||
else (_src_dir_len GREATER _bin_dir_len)
|
||||
string (SUBSTRING "${PROJECT_BINARY_DIR}/" 0 ${_src_dir_len} _proj_prefix)
|
||||
if ("${PROJECT_SOURCE_DIR}/" STREQUAL "${_proj_prefix}")
|
||||
set (_not_substring FALSE)
|
||||
else ("${PROJECT_SOURCE_DIR}/" STREQUAL "${_proj_prefix}")
|
||||
set (_not_substring TRUE)
|
||||
endif ("${PROJECT_SOURCE_DIR}/" STREQUAL "${_proj_prefix}")
|
||||
endif (_src_dir_len GREATER _bin_dir_len)
|
||||
if (_not_substring)
|
||||
execute_process (COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/dune.module ${PROJECT_BINARY_DIR}/dune.module
|
||||
)
|
||||
endif (_not_substring)
|
||||
@@ -1,11 +0,0 @@
|
||||
# Find clang-check.
|
||||
#
|
||||
# This module defines:
|
||||
# CLANGCHECK_PROGRAM, the clang-check executable.
|
||||
# CLANGHCECK_FOUND, If false, do not try to use cppcheck.
|
||||
#
|
||||
find_program(CLANGCHECK_PROGRAM NAMES clang-check clang-check-3.8)
|
||||
|
||||
find_package_handle_standard_args(ClangCheck DEFAULT_MSG CLANGCHECK_PROGRAM)
|
||||
|
||||
mark_as_advanced(CLANGCHECK_PROGRAM)
|
||||
@@ -1,11 +0,0 @@
|
||||
# Find CppCheck.
|
||||
#
|
||||
# This module defines:
|
||||
# CPPCHECK_PROGRAM, the cppcheck executable.
|
||||
# CPPCHECK_FOUND, If false, do not try to use cppcheck.
|
||||
#
|
||||
find_program(CPPCHECK_PROGRAM NAMES cppcheck)
|
||||
|
||||
find_package_handle_standard_args(CppCheck DEFAULT_MSG CPPCHECK_PROGRAM)
|
||||
|
||||
mark_as_advanced(CPPCHECK_PROGRAM)
|
||||
@@ -33,7 +33,7 @@ endif (ERT_ROOT)
|
||||
find_path (ERT_ECL_INCLUDE_DIR
|
||||
NAMES "ert/ecl/ecl_util.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libecl/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
@@ -41,7 +41,7 @@ find_path (ERT_ECL_INCLUDE_DIR
|
||||
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"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libecl_well/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
@@ -49,7 +49,7 @@ find_path (ERT_ECL_WELL_INCLUDE_DIR
|
||||
find_path (ERT_ECLXX_INCLUDE_DIR
|
||||
NAMES "ert/ecl/EclKW.hpp"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libeclxx/include/" "include"
|
||||
DOC "Path to ERT Eclipse C++ library header files"
|
||||
${_no_default_path}
|
||||
@@ -57,7 +57,7 @@ find_path (ERT_ECLXX_INCLUDE_DIR
|
||||
find_path (ERT_UTIL_INCLUDE_DIR
|
||||
NAMES "ert/util/stringlist.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_util/include/" "include"
|
||||
DOC "Path to ERT Eclipse library header files"
|
||||
${_no_default_path}
|
||||
@@ -65,7 +65,7 @@ find_path (ERT_UTIL_INCLUDE_DIR
|
||||
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"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATH_SUFFIXES "libert_utilxx/include/" "include"
|
||||
DOC "Path to ERT Eclipse C++ library header files"
|
||||
${_no_default_path}
|
||||
@@ -73,7 +73,7 @@ find_path (ERT_UTILXX_INCLUDE_DIR
|
||||
find_path (ERT_GEN_INCLUDE_DIR
|
||||
NAMES "ert/util/int_vector.h"
|
||||
HINTS "${ERT_ROOT}"
|
||||
PATHS "${PROJECT_SOURCE_DIR}/../libecl" "${PROJECT_SOURCE_DIR}/../ert"
|
||||
PATHS "${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"
|
||||
@@ -88,10 +88,7 @@ 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"
|
||||
PATHS "${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}"
|
||||
@@ -101,10 +98,7 @@ find_library (ERT_LIBRARY_ECL
|
||||
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"
|
||||
PATHS "${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}"
|
||||
@@ -114,10 +108,7 @@ find_library (ERT_LIBRARY_ECLXX
|
||||
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"
|
||||
PATHS "${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}"
|
||||
@@ -127,10 +118,7 @@ find_library (ERT_LIBRARY_ECL_WELL
|
||||
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"
|
||||
PATHS "${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}"
|
||||
@@ -140,10 +128,7 @@ find_library (ERT_LIBRARY_GEOMETRY
|
||||
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"
|
||||
PATHS "${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}"
|
||||
@@ -153,10 +138,7 @@ find_library (ERT_LIBRARY_UTIL
|
||||
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"
|
||||
PATHS "${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}"
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
|
||||
# find out the size of a pointer. this is required to only search for
|
||||
# libraries in the directories relevant for the architecture
|
||||
|
||||
if(NOT USE_PETSC)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P)
|
||||
math (EXPR _BITS "8 * ${CMAKE_SIZEOF_VOID_P}")
|
||||
endif (CMAKE_SIZEOF_VOID_P)
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
# SUPERLU_LIBRARIES Name to the SuperLU library.
|
||||
#
|
||||
|
||||
if(NOT USE_SUPERLU)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
include(CMakePushCheckState)
|
||||
include(CheckCSourceCompiles)
|
||||
@@ -122,19 +118,6 @@ int main(void)
|
||||
return 0;
|
||||
}"
|
||||
SUPERLU_POST_2005_VERSION)
|
||||
|
||||
# check whether version is at least 5.0
|
||||
CHECK_C_SOURCE_COMPILES("
|
||||
typedef int int_t;
|
||||
#include <supermatrix.h>
|
||||
#include <slu_util.h>
|
||||
int main(void)
|
||||
{
|
||||
GlobalLU_t glu;
|
||||
return 0;
|
||||
}"
|
||||
SUPERLU_MIN_VERSION_5)
|
||||
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(SUPERLU_MIN_VERSION_4_3)
|
||||
@@ -145,17 +128,6 @@ else()
|
||||
"Human readable string containing SuperLU version information.")
|
||||
endif()
|
||||
|
||||
if(SUPERLU_MIN_VERSION_5)
|
||||
include(UseDuneVer)
|
||||
find_dune_version("dune" "istl")
|
||||
set(DUNE_ISTL_VERSION ${DUNE_ISTL_VERSION_MAJOR}.${DUNE_ISTL_VERSION_MINOR}.${DUNE_ISTL_VERSION_REVISION})
|
||||
if(DUNE_ISTL_VERSION VERSION_LESS 2.5)
|
||||
message(STATUS "SuperLU requested, but version found not compatible with dune-istl ${DUNE_ISTL_VERSION}")
|
||||
set(SUPERLU_LIBRARY "")
|
||||
set(SUPERLU_INCLUDE_DIR "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# behave like a CMake module is supposed to behave
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
@@ -170,13 +142,7 @@ mark_as_advanced(SUPERLU_INCLUDE_DIR SUPERLU_LIBRARY)
|
||||
if(SUPERLU_FOUND)
|
||||
set(SUPERLU_INCLUDE_DIRS ${SUPERLU_INCLUDE_DIR})
|
||||
set(SUPERLU_LIBRARIES ${SUPERLU_LIBRARY})
|
||||
set(SUPERLU_INT_TYPE int)
|
||||
if(SUPERLU_MIN_VERSION_4_3)
|
||||
set(HAVE_SLU_DDEFS_H 1)
|
||||
check_include_files(slu_sdefs.h HAVE_SLU_SDEFS_H)
|
||||
check_include_files(slu_cdefs.h HAVE_SLU_CDEFS_H)
|
||||
check_include_files(slu_zdefs.h HAVE_SLU_ZDEFS_H)
|
||||
endif()
|
||||
|
||||
if (SUPERLU_BLAS_LIBRARY)
|
||||
list(APPEND SUPERLU_LIBRARIES ${SUPERLU_BLAS_LIBRARY})
|
||||
endif()
|
||||
|
||||
37
cmake/Modules/FindTinyXML.cmake
Normal file
37
cmake/Modules/FindTinyXML.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
# - Find TinyXML library
|
||||
#
|
||||
# Defines the following variables:
|
||||
# TinyXML_INCLUDE_DIRS Directory of header files
|
||||
# TinyXML_LIBRARIES Directory of shared object files
|
||||
# TinyXML_DEFINITIONS Defines that must be set to compile
|
||||
|
||||
# Copyright (C) 2012 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
# use the generic find routine
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"TinyXML"
|
||||
|
||||
# dependencies
|
||||
""
|
||||
|
||||
# header to search for
|
||||
"tinyxml.h"
|
||||
|
||||
# library to search for
|
||||
"tinyxml"
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
"#include <tinyxml.h>
|
||||
int main (void) {
|
||||
TiXmlDocument doc;
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
# config variables
|
||||
"")
|
||||
@@ -25,7 +25,6 @@ find_opm_package (
|
||||
"CXX11Features REQUIRED;
|
||||
dune-common REQUIRED;
|
||||
dune-geometry REQUIRED;
|
||||
dune-uggrid;
|
||||
MPI;
|
||||
UG
|
||||
"
|
||||
|
||||
@@ -52,14 +52,7 @@ int main (void) {
|
||||
HAVE_PARMETIS;
|
||||
HAVE_SUPERLU;
|
||||
HAVE_UMFPACK;
|
||||
HAVE_SUITESPARSE_UMFPACK;
|
||||
SUPERLU_INT_TYPE;
|
||||
HAVE_SLU_CDEFS_H;
|
||||
HAVE_SLU_DDEFS_H;
|
||||
HAVE_SLU_SDEFS_H;
|
||||
HAVE_SLU_ZDEFS_H;
|
||||
SUPERLU_MIN_VERSION_4_3;
|
||||
SUPERLU_MIN_VERSION_5;
|
||||
SUPERLU_POST_2005_VERSION
|
||||
")
|
||||
#debug_find_vars ("dune-istl")
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
include (OpmPackage)
|
||||
|
||||
find_opm_package (
|
||||
# module name
|
||||
"dune-uggrid"
|
||||
|
||||
# dependencies
|
||||
# TODO: we should probe for all the HAVE_* values listed below;
|
||||
# however, we don't actually use them in our implementation, so
|
||||
"CXX11Features REQUIRED;
|
||||
dune-common REQUIRED
|
||||
"
|
||||
# header to search for
|
||||
""
|
||||
|
||||
# library to search for
|
||||
"duneuggrid"
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
""
|
||||
# config variable
|
||||
"")
|
||||
|
||||
#debug_find_vars ("dune-uggrid")
|
||||
|
||||
# make version number available in config.h
|
||||
include (UseDuneVer)
|
||||
find_dune_version ("dune" "uggrid")
|
||||
|
||||
# deactivate search for UG
|
||||
set(UG_FOUND ${dune-uggrid_FOUND})
|
||||
42
cmake/Modules/Findewoms.cmake
Normal file
42
cmake/Modules/Findewoms.cmake
Normal file
@@ -0,0 +1,42 @@
|
||||
# - Find OPM eWoms module
|
||||
#
|
||||
# Defines the following variables:
|
||||
# ewoms_INCLUDE_DIRS Directory of header files
|
||||
# ewoms_LIBRARIES Directory of shared object files
|
||||
# ewoms_DEFINITIONS Defines that must be set to compile
|
||||
# ewoms_CONFIG_VARS List of defines that should be in config.h
|
||||
# HAVE_EWOMS Binary value to use in config.h
|
||||
|
||||
# Copyright (C) 2012 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
# use the generic find routine
|
||||
include (ewoms-prereqs)
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"ewoms"
|
||||
|
||||
# dependencies
|
||||
"${ewoms_DEPS}"
|
||||
|
||||
# header to search for
|
||||
"ewoms/common/start.hh"
|
||||
|
||||
# library to search for
|
||||
""
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
"#include <ewoms/common/start.hh>
|
||||
int main (void) {
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
# config variables
|
||||
"${ewoms_CONFIG_VAR}"
|
||||
)
|
||||
#include (UseDynamicBoost)
|
||||
#debug_find_vars ("ewoms")
|
||||
43
cmake/Modules/Findopm-common.cmake
Normal file
43
cmake/Modules/Findopm-common.cmake
Normal file
@@ -0,0 +1,43 @@
|
||||
# - Find the opm-common module
|
||||
#
|
||||
# Defines the following variables:
|
||||
# opm-common_INCLUDE_DIRS Directory of header files
|
||||
# opm-common_LIBRARIES Directory of shared object files
|
||||
# opm-common_DEFINITIONS Defines that must be set to compile
|
||||
# opm-common_CONFIG_VARS List of defines that should be in config.h
|
||||
# HAVE_OPM_COMMON Binary value to use in config.h
|
||||
|
||||
# Copyright (C) 2013 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
# use the generic find routine
|
||||
include (opm-common-prereqs)
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"opm-common"
|
||||
|
||||
# dependencies
|
||||
"${opm-common_DEPS}"
|
||||
|
||||
# header to search for
|
||||
"opm/common/utility/platform_dependent/disable_warnings.h"
|
||||
|
||||
# library to search for
|
||||
"opmcommon"
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
"#include <opm/common/utility/platform_dependent/disable_warnings.h>
|
||||
int main (void) {
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
|
||||
# config variables
|
||||
"${opm-common_CONFIG_VAR}"
|
||||
)
|
||||
include (UseDynamicBoost)
|
||||
#debug_find_vars ("opm-common")
|
||||
46
cmake/Modules/Findopm-core.cmake
Normal file
46
cmake/Modules/Findopm-core.cmake
Normal file
@@ -0,0 +1,46 @@
|
||||
# - Find OPM core library
|
||||
#
|
||||
# Defines the following variables:
|
||||
# opm-core_INCLUDE_DIRS Directory of header files
|
||||
# opm-core_LIBRARIES Directory of shared object files
|
||||
# opm-core_DEFINITIONS Defines that must be set to compile
|
||||
# opm-core_CONFIG_VARS List of defines that should be in config.h
|
||||
# HAVE_OPM_CORE Binary value to use in config.h
|
||||
|
||||
# Copyright (C) 2012 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
# use the generic find routine
|
||||
include (opm-core-prereqs)
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"opm-core"
|
||||
|
||||
# dependencies
|
||||
"${opm-core_DEPS}"
|
||||
|
||||
# header to search for
|
||||
"opm/core/wells.h"
|
||||
|
||||
# library to search for
|
||||
"opmcore"
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
"
|
||||
#include <opm/core/utility/parameters/ParameterGroup.hpp>
|
||||
int main()
|
||||
{
|
||||
Opm::parameter::ParameterGroup parameters;
|
||||
parameters.insertParameter(\"number\", \"7\");
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
# config variables
|
||||
"${opm-core_CONFIG_VAR}"
|
||||
)
|
||||
include (UseDynamicBoost)
|
||||
#debug_find_vars ("opm-core")
|
||||
24
cmake/Modules/Findopm-data.cmake
Normal file
24
cmake/Modules/Findopm-data.cmake
Normal file
@@ -0,0 +1,24 @@
|
||||
# This module searches for the opm-data repository. Since the opm-data
|
||||
# has no libraries or header files the find implementation is quite
|
||||
# naive.
|
||||
#
|
||||
# If the opm-data repository is found, the following variables are set:
|
||||
#
|
||||
# HAVE_OPM_DATA
|
||||
# OPM_DATA_ROOT
|
||||
|
||||
if (OPM_DATA_ROOT)
|
||||
set( _opm_data_root ${OPM_DATA_ROOT})
|
||||
else()
|
||||
set( _opm_data_root "${PROJECT_SOURCE_DIR}/../opm-data")
|
||||
endif()
|
||||
|
||||
|
||||
if (EXISTS "${_opm_data_root}/norne/NORNE_ATW2013.DATA")
|
||||
set( HAVE_OPM_DATA True )
|
||||
set( OPM_DATA_ROOT ${_opm_data_root} )
|
||||
message(STATUS "Setting OPM_DATA_ROOT: ${OPM_DATA_ROOT}")
|
||||
else()
|
||||
set( HAVE_OPM_DATA False )
|
||||
message(WARNING "opm-data not found - integration tests using opm-data will be skipped.")
|
||||
endif()
|
||||
42
cmake/Modules/Findopm-grid.cmake
Normal file
42
cmake/Modules/Findopm-grid.cmake
Normal file
@@ -0,0 +1,42 @@
|
||||
# - Find OPM corner-point grid library
|
||||
#
|
||||
# Defines the following variables:
|
||||
# opm-grid_INCLUDE_DIRS Directory of header files
|
||||
# opm-grid_LIBRARIES Directory of shared object files
|
||||
# opm-grid_DEFINITIONS Defines that must be set to compile
|
||||
# opm-grid_CONFIG_VARS List of defines that should be in config.h
|
||||
# HAVE_OPM_GRID Binary value to use in config.h
|
||||
|
||||
# Copyright (C) 2013 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
include (opm-grid-prereqs)
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"opm-grid"
|
||||
|
||||
# dependencies
|
||||
"${opm-grid_DEPS}"
|
||||
|
||||
# header to search for
|
||||
"dune/grid/CpGrid.hpp"
|
||||
|
||||
# library to search for
|
||||
"opmgrid"
|
||||
|
||||
# defines to be added to compilations
|
||||
"HAVE_OPM_GRID"
|
||||
|
||||
# test program
|
||||
"#include <dune/grid/CpGrid.hpp>
|
||||
int main (void) {
|
||||
Dune::CpGrid g;
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
# config variables
|
||||
"${opm-grid_CONFIG_VAR}"
|
||||
)
|
||||
|
||||
#debug_find_vars ("opm-grid")
|
||||
43
cmake/Modules/Findopm-material.cmake
Normal file
43
cmake/Modules/Findopm-material.cmake
Normal file
@@ -0,0 +1,43 @@
|
||||
# - Find OPM materials library
|
||||
#
|
||||
# Defines the following variables:
|
||||
# opm-material_INCLUDE_DIRS Directory of header files
|
||||
# opm-material_LIBRARIES Directory of shared object files
|
||||
# opm-material_DEFINITIONS Defines that must be set to compile
|
||||
# opm-material_CONFIG_VARS List of defines that should be in config.h
|
||||
# HAVE_OPM_MATERIAL Binary value to use in config.h
|
||||
|
||||
# Copyright (C) 2013 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
# use the generic find routine
|
||||
include (opm-material-prereqs)
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"opm-material"
|
||||
|
||||
# dependencies
|
||||
"${opm-material_DEPS}"
|
||||
|
||||
# header to search for
|
||||
"opm/material/Constants.hpp"
|
||||
|
||||
# library to search for
|
||||
""
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
"#include <opm/material/Constants.hpp>
|
||||
int main (void) {
|
||||
double c = Opm::Constants<double>::c;
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
# config variables
|
||||
"${opm-material_CONFIG_VAR}"
|
||||
)
|
||||
include (UseDynamicBoost)
|
||||
#debug_find_vars ("opm-material")
|
||||
55
cmake/Modules/Findopm-output.cmake
Normal file
55
cmake/Modules/Findopm-output.cmake
Normal file
@@ -0,0 +1,55 @@
|
||||
# - Find OPM output library
|
||||
#
|
||||
# Defines the following variables:
|
||||
# opm-output_INCLUDE_DIRS Directory of header files
|
||||
# opm-output_LIBRARIES Directory of shared object files
|
||||
# opm-output_DEFINITIONS Defines that must be set to compile
|
||||
# opm-output_CONFIG_VARS List of defines that should be in config.h
|
||||
# HAVE_OPM_OUTPUT Binary value to use in config.h
|
||||
|
||||
# Copyright (C) 2012 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
# use the generic find routine
|
||||
include (opm-output-prereqs)
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"opm-output"
|
||||
|
||||
# dependencies
|
||||
"${opm-output_DEPS}"
|
||||
|
||||
# header to search for
|
||||
"opm/output/OutputWriter.hpp"
|
||||
|
||||
# library to search for
|
||||
"opmoutput"
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
"#include <opm/output/eclipse/Summary.hpp>
|
||||
int main (void) {
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
# config variables
|
||||
"${opm-output_CONFIG_VAR}"
|
||||
)
|
||||
include (UseDynamicBoost)
|
||||
#debug_find_vars ("opm-output")
|
||||
|
||||
|
||||
if(OPM_OUTPUT_FOUND)
|
||||
get_filename_component(opm-output_PREFIX_DIR ${opm-output_LIBRARY} PATH)
|
||||
find_program(COMPARE_SUMMARY_COMMAND compareSummary
|
||||
PATHS ${opm-output_PREFIX_DIR}/../bin
|
||||
${opm-output_PREFIX_DIR}/../../bin)
|
||||
find_program(COMPARE_ECL_COMMAND compareECL
|
||||
PATHS ${opm-output_PREFIX_DIR}/../bin
|
||||
${opm-output_PREFIX_DIR}/../../bin)
|
||||
|
||||
endif()
|
||||
|
||||
184
cmake/Modules/Findopm-parser.cmake
Normal file
184
cmake/Modules/Findopm-parser.cmake
Normal file
@@ -0,0 +1,184 @@
|
||||
# Find the OPM Eclipse input parser.
|
||||
#
|
||||
# Set the cache variable OPM_PARSER_ROOT to the install location of the
|
||||
# library, or OPM_ROOT to the parent directory of the build tree.
|
||||
#
|
||||
# If found, it sets these variables:
|
||||
#
|
||||
# HAVE_OPM_PARSER Defined if a test program compiled
|
||||
# OPM_PARSER_INCLUDE_DIRS Header file directories
|
||||
# OPM_PARSER_LIBRARIES Archives and shared objects
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
# variables to pass on to other packages
|
||||
if (FIND_QUIETLY)
|
||||
set (OPM_PARSER_QUIET "QUIET")
|
||||
else ()
|
||||
set (OPM_PARSER_QUIET "")
|
||||
endif ()
|
||||
|
||||
# use lowercase versions of the variables if those are set
|
||||
if (opm-parser_ROOT)
|
||||
set (OPM_PARSER_ROOT ${opm-parser_ROOT})
|
||||
endif ()
|
||||
if (opm_ROOT)
|
||||
set (OPM_ROOT ${opm_ROOT})
|
||||
endif ()
|
||||
|
||||
# inherit "suite" root if not specifically set for this library
|
||||
if ((NOT OPM_PARSER_ROOT) AND OPM_ROOT)
|
||||
set (OPM_PARSER_ROOT "${OPM_ROOT}/opm-parser")
|
||||
endif ()
|
||||
|
||||
# Detect the build dir suffix or subdirectory
|
||||
string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/?(.*)" "\\1" BUILD_DIR_SUFFIX "${PROJECT_BINARY_DIR}")
|
||||
|
||||
# if a root is specified, then don't search in system directories
|
||||
# or in relative directories to this one
|
||||
if (OPM_PARSER_ROOT)
|
||||
set (_no_default_path "NO_DEFAULT_PATH")
|
||||
set (_opm_parser_source "")
|
||||
set (_opm_parser_build "")
|
||||
else ()
|
||||
set (_no_default_path "")
|
||||
set (_opm_parser_source
|
||||
"${PROJECT_SOURCE_DIR}/../opm-parser")
|
||||
set (_opm_parser_build
|
||||
"${PROJECT_BINARY_DIR}/../opm-parser"
|
||||
"${PROJECT_BINARY_DIR}/../opm-parser${BUILD_DIR_SUFFIX}"
|
||||
"${PROJECT_BINARY_DIR}/../../opm-parser/${BUILD_DIR_SUFFIX}")
|
||||
endif ()
|
||||
|
||||
# use this header as signature
|
||||
find_path (OPM_PARSER_INCLUDE_DIR
|
||||
NAMES "opm/parser/eclipse/Parser/Parser.hpp"
|
||||
HINTS "${OPM_PARSER_ROOT}"
|
||||
PATHS ${_opm_parser_source}
|
||||
PATH_SUFFIXES "include"
|
||||
DOC "Path to OPM parser header files"
|
||||
${_no_default_path} )
|
||||
|
||||
find_path (OPM_PARSER_GEN_INCLUDE_DIR
|
||||
NAMES "opm/parser/eclipse/Parser/ParserKeywords.hpp"
|
||||
HINTS "${OPM_PARSER_ROOT}"
|
||||
PATHS ${_opm_parser_build}
|
||||
PATH_SUFFIXES "generated-source/include" "include"
|
||||
DOC "Path to OPM parser generated header files"
|
||||
${_no_default_path} )
|
||||
|
||||
|
||||
# backup: if we didn't find any headers there, but a CMakeCache.txt,
|
||||
# then it is probably a build directory; read the CMake cache of
|
||||
# opm-parser to figure out where the source directory is
|
||||
if ((NOT OPM_PARSER_INCLUDE_DIR) AND
|
||||
(OPM_PARSER_ROOT AND (EXISTS "${OPM_PARSER_ROOT}/CMakeCache.txt")))
|
||||
set (_regex "^OPMParser_SOURCE_DIR:STATIC=\(.*\)$")
|
||||
file (STRINGS
|
||||
"${OPM_PARSER_ROOT}/CMakeCache.txt"
|
||||
_cache_entry
|
||||
REGEX "${_regex}")
|
||||
string(REGEX REPLACE "${_regex}" "\\1"
|
||||
OPM_PARSER_INCLUDE_DIR
|
||||
"${_cache_entry}")
|
||||
if (OPM_PARSER_INCLUDE_DIR)
|
||||
set (OPM_PARSER_INCLUDE_DIR "${OPM_PARSER_INCLUDE_DIR}"
|
||||
CACHE PATH "Path to OPM parser header files" FORCE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# find out the size of a pointer. this is required to only search for
|
||||
# libraries in the directories relevant for the architecture
|
||||
if (CMAKE_SIZEOF_VOID_P)
|
||||
math (EXPR _BITS "8 * ${CMAKE_SIZEOF_VOID_P}")
|
||||
endif ()
|
||||
|
||||
# these libraries constitute the parser core
|
||||
find_library (OPM_PARSER_LIBRARY
|
||||
NAMES "opmparser"
|
||||
HINTS "${OPM_PARSER_ROOT}"
|
||||
PATHS ${_opm_parser_build}
|
||||
PATH_SUFFIXES "lib" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
"opm/parser/eclipse"
|
||||
DOC "Path to OPM parser library archive/shared object files"
|
||||
${_no_default_path} )
|
||||
|
||||
# find the OPM-parser wrapper library around cJSON
|
||||
find_library (OPM_JSON_LIBRARY
|
||||
NAMES "opmjson"
|
||||
HINTS "${OPM_PARSER_ROOT}"
|
||||
PATHS ${_opm_parser_build}
|
||||
PATH_SUFFIXES "lib" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
||||
"opm/json"
|
||||
DOC "Path to OPM JSON library archive/shared object files"
|
||||
${_no_default_path} )
|
||||
|
||||
# get the prerequisite ERT libraries
|
||||
if (NOT ERT_FOUND)
|
||||
find_package(ERT ${OPM_PARSER_QUIET})
|
||||
endif ()
|
||||
|
||||
# get the prerequisite Boost libraries
|
||||
find_package(Boost 1.44.0 COMPONENTS filesystem date_time system unit_test_framework regex ${OPM_PARSER_QUIET})
|
||||
|
||||
if (ERT_FOUND AND Boost_FOUND AND
|
||||
OPM_PARSER_LIBRARY AND OPM_JSON_LIBRARY AND OPM_PARSER_INCLUDE_DIR)
|
||||
# setup list of all required libraries to link with opm-parser. notice that
|
||||
# we use the plural form to get *all* the libraries needed by cjson
|
||||
set (opm-parser_INCLUDE_DIRS
|
||||
${OPM_PARSER_INCLUDE_DIR}
|
||||
${OPM_PARSER_GEN_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${ERT_INCLUDE_DIRS})
|
||||
|
||||
set (opm-parser_LIBRARIES
|
||||
${OPM_PARSER_LIBRARY}
|
||||
${OPM_JSON_LIBRARY}
|
||||
${Boost_LIBRARIES}
|
||||
${ERT_LIBRARIES})
|
||||
|
||||
# We might be using an external cJSON library
|
||||
# but we have to unset the OPM_PARSER_ROOT stuff to find it
|
||||
# (other NO_DEFAULT_PATH will be set).
|
||||
set(_OPM_PARSER_ROOT_bak ${OPM_PARSER_ROOT})
|
||||
set(OPM_PARSER_ROOT "")
|
||||
find_package(cjson)
|
||||
set(OPM_PARSER_ROOT ${OPM_PARSER_ROOT_bak})
|
||||
|
||||
if (CJSON_FOUND)
|
||||
# If we do we need to add it to the libs.
|
||||
set (opm-parser_LIBRARIES
|
||||
${opm-parser_LIBRARIES}
|
||||
${CJSON_LIBRARY})
|
||||
endif (CJSON_FOUND)
|
||||
|
||||
# see if we can compile a minimum example
|
||||
# CMake logical test doesn't handle lists (sic)
|
||||
include (CMakePushCheckState)
|
||||
include (CheckCSourceCompiles)
|
||||
cmake_push_check_state ()
|
||||
set (CMAKE_REQUIRED_INCLUDES ${opm-parser_INCLUDE_DIRS})
|
||||
set (CMAKE_REQUIRED_LIBRARIES ${opm-parser_LIBRARIES})
|
||||
|
||||
check_cxx_source_compiles (
|
||||
"#include <cstdlib>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
|
||||
int main (void) {
|
||||
return EXIT_SUCCESS;
|
||||
}" HAVE_OPM_PARSER)
|
||||
cmake_pop_check_state ()
|
||||
endif()
|
||||
|
||||
# if the test program didn't compile, but was required to do so, bail
|
||||
# out now and display an error; otherwise limp on
|
||||
set (OPM_PARSER_FIND_REQUIRED ${opm-parser_FIND_REQUIRED})
|
||||
find_package_handle_standard_args (opm-parser
|
||||
DEFAULT_MSG
|
||||
opm-parser_INCLUDE_DIRS opm-parser_LIBRARIES HAVE_OPM_PARSER
|
||||
)
|
||||
|
||||
set (opm-parser_CONFIG_VARS "HAVE_OPM_PARSER;HAVE_REGEX")
|
||||
set (opm-parser_FOUND ${OPM-PARSER_FOUND})
|
||||
|
||||
mark_as_advanced(opm-parser_LIBRARIES opm-parser_INCLUDE_DIRS OPM-PARSER_FOUND)
|
||||
44
cmake/Modules/Findopm-simulators.cmake
Normal file
44
cmake/Modules/Findopm-simulators.cmake
Normal file
@@ -0,0 +1,44 @@
|
||||
# - Find OPM automatic differentiation library
|
||||
#
|
||||
# Defines the following variables:
|
||||
# opm-simulators_INCLUDE_DIRS Directory of header files
|
||||
# opm-simulators_LIBRARIES Directory of shared object files
|
||||
# opm-simulators_DEFINITIONS Defines that must be set to compile
|
||||
# opm-simulators_CONFIG_VARS List of defines that should be in config.h
|
||||
# HAVE_OPM_SIMULATORS Binary value to use in config.h
|
||||
|
||||
# Copyright (C) 2012 Uni Research AS
|
||||
# This code is licensed under The GNU General Public License v3.0
|
||||
|
||||
# use the generic find routine
|
||||
include (opm-simulators-prereqs)
|
||||
include (OpmPackage)
|
||||
find_opm_package (
|
||||
# module name
|
||||
"opm-simulators"
|
||||
|
||||
# dependencies
|
||||
"${opm-simulators_DEPS}"
|
||||
|
||||
# header to search for
|
||||
"opm/autodiff/AutoDiff.hpp"
|
||||
|
||||
# library to search for
|
||||
"opmsimulators"
|
||||
|
||||
# defines to be added to compilations
|
||||
""
|
||||
|
||||
# test program
|
||||
"#include <opm/autodiff/AutoDiff.hpp>
|
||||
int main (void) {
|
||||
Opm::AutoDiff<double> x = Opm::AutoDiff<double>::constant(42.);
|
||||
(void) x;
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
# config variables
|
||||
"${opm-simulators_CONFIG_VAR}"
|
||||
)
|
||||
include (UseDynamicBoost)
|
||||
#debug_find_vars ("opm-simulators")
|
||||
@@ -1,27 +0,0 @@
|
||||
# This module searches for the opm-tests repository. Since opm-tests
|
||||
# has no libraries or header files the find implementation is quite
|
||||
# naive.
|
||||
#
|
||||
# If the opm-tests repository is found, the following variables are set:
|
||||
#
|
||||
# HAVE_OPM_TESTS
|
||||
# OPM_TESTS_ROOT
|
||||
|
||||
if (OPM_TESTS_ROOT)
|
||||
set( _opm_tests_root ${OPM_TESTS_ROOT})
|
||||
else()
|
||||
set( _opm_tests_root "${PROJECT_SOURCE_DIR}/../opm-tests")
|
||||
endif()
|
||||
|
||||
|
||||
if (EXISTS "${_opm_tests_root}/norne/NORNE_ATW2013.DATA")
|
||||
set( HAVE_OPM_DATA True )
|
||||
set( HAVE_OPM_TESTS True )
|
||||
set( OPM_TESTS_ROOT ${_opm_tests_root} )
|
||||
set( OPM_DATA_ROOT ${_opm_tests_root} )
|
||||
message(STATUS "Setting OPM_TESTS_ROOT: ${OPM_TESTS_ROOT}")
|
||||
else()
|
||||
set( HAVE_OPM_TESTS False )
|
||||
set( HAVE_OPM_DATA False )
|
||||
message(WARNING "opm-tests not found - integration tests using opm-tests will be skipped.")
|
||||
endif()
|
||||
@@ -123,7 +123,7 @@ function (configure_la name target)
|
||||
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")
|
||||
message (STATUS "Libtool not found!")
|
||||
endif (NOT libtool_MAIN)
|
||||
endif (NOT libtool_MAIN)
|
||||
if (libtool_MAIN)
|
||||
|
||||
@@ -9,7 +9,6 @@ function (set_aliases)
|
||||
# are separated by space
|
||||
set (aliases
|
||||
"HAVE_UMFPACK HAVE_SUITESPARSE_UMFPACK_H"
|
||||
"HAVE_SUITESPARSE_UMFPACK HAVE_SUITESPARSE_UMFPACK_H"
|
||||
"HAVE_DUNE_BOOST HAVE_BOOST"
|
||||
)
|
||||
foreach (alias IN LISTS aliases)
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# Installs bash tab completion for a product
|
||||
macro(opm_add_bash_completion binary)
|
||||
set(PRODUCT ${binary})
|
||||
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()
|
||||
@@ -18,8 +18,6 @@ macro (opm_compile opm)
|
||||
if (SILENCE_CROSSMODULE_WARNINGS)
|
||||
include_directories("${PROJECT_SOURCE_DIR}")
|
||||
include_directories (SYSTEM ${${opm}_INCLUDE_DIRS})
|
||||
set (${opm}_INCLUDE_DIR "${PROJECT_SOURCE_DIR}")
|
||||
set (${opm}_INCLUDE_DIRS ${${opm}_INCLUDE_DIR} ${${opm}_INCLUDE_DIRS})
|
||||
else()
|
||||
set (${opm}_INCLUDE_DIR "${PROJECT_SOURCE_DIR}")
|
||||
set (${opm}_INCLUDE_DIRS ${${opm}_INCLUDE_DIR} ${${opm}_INCLUDE_DIRS})
|
||||
@@ -32,34 +30,19 @@ macro (opm_compile opm)
|
||||
add_definitions (${${opm}_DEFINITIONS})
|
||||
set (${opm}_VERSION "${${opm}_VERSION_MAJOR}.${${opm}_VERSION_MINOR}")
|
||||
if (${opm}_SOURCES)
|
||||
add_library (${${opm}_TARGET} ${${opm}_LIBRARY_TYPE} ${${opm}_SOURCES})
|
||||
set_target_properties (${${opm}_TARGET} PROPERTIES
|
||||
SOVERSION ${${opm}_VERSION_MAJOR}
|
||||
VERSION ${${opm}_VERSION}
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
|
||||
add_library (${${opm}_TARGET} ${${opm}_LIBRARY_TYPE} ${${opm}_SOURCES})
|
||||
set_target_properties (${${opm}_TARGET} PROPERTIES
|
||||
SOVERSION ${${opm}_VERSION_MAJOR}
|
||||
VERSION ${${opm}_VERSION}
|
||||
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
|
||||
POSITION_INDEPENDENT_CODE TRUE
|
||||
)
|
||||
if (${${opm}_LIBRARY_TYPE} STREQUAL "SHARED")
|
||||
# libs that will be linked with the main lib
|
||||
string(REGEX REPLACE "([;^])[^;]+\\.a[;$]" "\\1" _public_libs
|
||||
"${${opm}_LIBRARIES}")
|
||||
# libs that will not actually linked to the library but
|
||||
# transitively linked to binaries that link to the main library
|
||||
string(REGEX REPLACE "([^;]+\\.[^a][a-zA-Z0-9]*|-[a-z]*)[;$]" "" _interface_libs
|
||||
"${${opm}_LIBRARIES}")
|
||||
else()
|
||||
# Use all libs for real and transitive linking
|
||||
set(_public_libs ${${opm}_LIBRARIES})
|
||||
unset(_interface)
|
||||
endif()
|
||||
target_link_libraries (${${opm}_TARGET} PUBLIC ${_public_libs}
|
||||
INTERFACE ${_interface_libs})
|
||||
target_link_libraries (${${opm}_TARGET} ${${opm}_LIBRARIES})
|
||||
|
||||
if (STRIP_DEBUGGING_SYMBOLS)
|
||||
# queue this executable to be stripped
|
||||
strip_debug_symbols (${${opm}_TARGET} ${opm}_DEBUG)
|
||||
endif()
|
||||
add_static_analysis_tests(${opm}_SOURCES ${opm}_INCLUDE_DIRS)
|
||||
else (${opm}_SOURCES)
|
||||
# unset this variable to signal that no library is generated
|
||||
set (${opm}_TARGET)
|
||||
|
||||
@@ -47,7 +47,7 @@ macro (opm_defaults opm)
|
||||
endif(NOT PRECOMPILE_HEADERS)
|
||||
|
||||
# Use of OpenMP is considered experimental
|
||||
set (USE_OPENMP_DEFAULT ON)
|
||||
set (USE_OPENMP_DEFAULT OFF)
|
||||
|
||||
# if we are on a system where CMake 2.6 is the default (Hi RHEL 6!),
|
||||
# the configuration files for Boost will trip up the library paths
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
|
||||
macro (opm_out_dirs)
|
||||
# put libraries in lib/ (no multi-arch support in build tree)
|
||||
if(MAIN_SOURCE_FILES)
|
||||
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
endif()
|
||||
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
|
||||
set (CMAKE_Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/CMakeFiles")
|
||||
endmacro (opm_out_dirs)
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
# )
|
||||
|
||||
include (Duplicates)
|
||||
include (OpmSiblingSearch)
|
||||
|
||||
# list of suffixes for all the project variables
|
||||
set (_opm_proj_vars
|
||||
@@ -54,16 +53,13 @@ foreach (name IN LISTS _opm_proj_vars)
|
||||
endif (NOT DEFINED ${CMAKE_PROJECT_NAME}_${name})
|
||||
endforeach (name)
|
||||
|
||||
# these dependencies needs special treatment
|
||||
# these dependencies must always be handled by the find module
|
||||
set (_opm_proj_exemptions
|
||||
dune-common
|
||||
dune-istl
|
||||
dune-grid
|
||||
dune-geometry
|
||||
dune-uggrid
|
||||
dune-alugrid
|
||||
dune-localfunctions
|
||||
dune-fem
|
||||
opm-parser
|
||||
)
|
||||
|
||||
# although a DUNE module, it is delivered in the OPM suite
|
||||
@@ -139,67 +135,24 @@ macro (find_and_append_package_to prefix name)
|
||||
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
|
||||
# will hold the index of the string COMPONENTS in the list
|
||||
set(_ARGN_LIST ${ARGN}) # Create a real list to use with list commands
|
||||
list(FIND _ARGN_LIST "COMPONENTS" _search_components)
|
||||
|
||||
# using config mode is better than using module (aka. find) mode
|
||||
# because then the package has already done all its probes and
|
||||
# stored them in the config file for us
|
||||
# For dune and opm modules and exempted packages we force module mode.
|
||||
# For dune and opm it will use config mode underneath.
|
||||
# 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
|
||||
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()
|
||||
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}")
|
||||
endif ()
|
||||
if (NOT DEFINED ${NAME}_FOUND)
|
||||
set (${NAME}_FOUND "${${name}_FOUND}")
|
||||
endif ()
|
||||
# using config mode is better than using module (aka. find) mode
|
||||
# because then the package has already done all its probes and
|
||||
# stored them in the config file for us
|
||||
if (NOT DEFINED ${name}_FOUND AND NOT DEFINED ${NAME}_FOUND)
|
||||
if (${name}_DIR)
|
||||
message (STATUS "Finding package ${name} using config mode")
|
||||
find_package (${name} ${ARGN} NO_MODULE PATHS ${${name}_DIR} NO_DEFAULT_PATH)
|
||||
else ()
|
||||
message (STATUS "Finding package ${name} using module mode")
|
||||
find_package (${name} ${ARGN})
|
||||
endif ()
|
||||
endif ()
|
||||
if (NOT DEFINED ${name}_FOUND)
|
||||
set (${name}_FOUND "${${NAME}_FOUND}")
|
||||
endif ()
|
||||
if (NOT DEFINED ${NAME}_FOUND)
|
||||
set (${NAME}_FOUND "${${name}_FOUND}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# the variable "NAME" may be replaced during find_package (as this is
|
||||
|
||||
@@ -60,9 +60,6 @@ endmacro ()
|
||||
OpmInitProjVars ()
|
||||
OpmInitDirVars ()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
|
||||
include(OpmPackage)
|
||||
|
||||
# if we are backporting this release to a system which already have an
|
||||
# earlier version, set this flag to have everything scoped into a directory
|
||||
# which incorporates the label of the release. this is done by interjecting
|
||||
@@ -74,17 +71,3 @@ if (USE_VERSIONED_DIR)
|
||||
else ()
|
||||
set (${project}_VER_DIR "")
|
||||
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" OFF)
|
||||
if (NOT USE_MPI)
|
||||
set (CMAKE_DISABLE_FIND_PACKAGE_MPI TRUE)
|
||||
endif ()
|
||||
|
||||
# quadmath must be explicitly enabled
|
||||
# This needs to be in OpmInit as prereqs is called before OpmLibMain is included.
|
||||
option (USE_QUADMATH "Use high precision floating point library (slow)" OFF)
|
||||
if (NOT USE_QUADMATH)
|
||||
set (CMAKE_DISABLE_FIND_PACKAGE_QuadMath TRUE)
|
||||
endif ()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# _TARGET CMake target which builds the library
|
||||
# _LIBRARY_TYPE Static or shared library
|
||||
# _DEBUG File containing debug symbols
|
||||
include (GNUInstallDirs)
|
||||
include (UseMultiArch)
|
||||
|
||||
macro (opm_install opm)
|
||||
foreach (_hdr IN LISTS ${opm}_HEADERS)
|
||||
@@ -20,16 +20,10 @@ macro (opm_install opm)
|
||||
)
|
||||
endforeach (_hdr)
|
||||
install (
|
||||
TARGETS ${${opm}_TARGET} ${${opm}_EXTRA_TARGETS}
|
||||
EXPORT ${opm}-targets
|
||||
TARGETS ${${opm}_TARGET}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${${opm}_VER_DIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${${opm}_VER_DIR}
|
||||
)
|
||||
if(NOT "${${opm}_TARGET}" STREQUAL "")
|
||||
export(TARGETS ${${opm}_TARGET} ${${opm}_EXTRA_TARGETS}
|
||||
FILE ${opm}-targets.cmake)
|
||||
install(EXPORT ${opm}-targets DESTINATION "share/cmake/${opm}")
|
||||
endif()
|
||||
# only /usr/lib/debug seems to be searched for debug info; if we have
|
||||
# write access to that directory (package installation), then default
|
||||
# to use it; otherwise put the debug files together with the library
|
||||
@@ -65,10 +59,6 @@ macro (opm_install opm)
|
||||
# multiarch-aware and will thus put in lib64/ on RHEL and lib/ on Debian
|
||||
install (
|
||||
FILES ${PROJECT_SOURCE_DIR}/dune.module
|
||||
DESTINATION lib/${${opm}_VER_DIR}/dunecontrol/${${opm}_NAME}
|
||||
DESTINATION ${LIBDIR_MULTIARCH_UNAWARE}${${opm}_VER_DIR}/dunecontrol/${${opm}_NAME}
|
||||
)
|
||||
install (
|
||||
FILES ${PROJECT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}-prereqs.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/opm/cmake/Modules
|
||||
)
|
||||
endmacro (opm_install opm)
|
||||
|
||||
@@ -90,22 +90,18 @@ include (UseOptimization)
|
||||
# dependencies, in case they alter the list of warnings
|
||||
include (UseWarnings)
|
||||
|
||||
# parallel computing must be explicitly enabled
|
||||
option (USE_MPI "Use Message Passing Interface for parallel computing" OFF)
|
||||
if (NOT USE_MPI)
|
||||
set (CMAKE_DISABLE_FIND_PACKAGE_MPI TRUE)
|
||||
endif (NOT USE_MPI)
|
||||
|
||||
# parallel programming
|
||||
include (UseOpenMP)
|
||||
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)
|
||||
|
||||
# static code analysis
|
||||
include(UseStaticAnalysis)
|
||||
setup_static_analysis_tools()
|
||||
|
||||
# callback hook to setup additional dependencies
|
||||
if (COMMAND prereqs_hook)
|
||||
prereqs_hook ()
|
||||
@@ -132,7 +128,7 @@ include (UseDebugSymbols)
|
||||
include (UseDynamicBoost)
|
||||
|
||||
# needed for Debian installation scheme
|
||||
include (GNUInstallDirs)
|
||||
include (UseMultiArch)
|
||||
|
||||
# Run conditional file hook
|
||||
files_hook()
|
||||
@@ -270,11 +266,10 @@ if (COMMAND tests_hook)
|
||||
endif (COMMAND tests_hook)
|
||||
|
||||
# make datafiles necessary for tests available in output directory
|
||||
opm_data (tests datafiles "${tests_DIR}")
|
||||
if(NOT BUILD_TESTING)
|
||||
set(excl_all EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
opm_compile_satellites (${project} tests "${excl_all}" "${tests_REGEXP}")
|
||||
if (BUILD_TESTING)
|
||||
opm_data (tests datafiles "${tests_DIR}")
|
||||
opm_compile_satellites (${project} tests "" "${tests_REGEXP}")
|
||||
endif (BUILD_TESTING)
|
||||
|
||||
# use this target to check local git commits
|
||||
add_custom_target(check-commits
|
||||
@@ -288,6 +283,9 @@ add_custom_target(check-commits
|
||||
include (OpmDoc)
|
||||
opm_doc (${project} ${doxy_dir})
|
||||
|
||||
# provide compatibility with using this build in dunecontrol
|
||||
include (DuneCompat)
|
||||
|
||||
### clean in-source builds ###
|
||||
include (OpmDistClean)
|
||||
opm_dist_clean (${project})
|
||||
|
||||
@@ -37,7 +37,9 @@
|
||||
# <http://www.vtk.org/Wiki/CMake:How_To_Find_Libraries>
|
||||
|
||||
include (OpmFind)
|
||||
include (OpmSiblingSearch)
|
||||
|
||||
option (SIBLING_SEARCH "Search sibling directories before system paths" ON)
|
||||
mark_as_advanced (SIBLING_SEARCH)
|
||||
|
||||
# append all items from src into dst; both must be *names* of lists
|
||||
macro (append_found src dst)
|
||||
@@ -55,11 +57,8 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
string (REPLACE "-" "_" MODULE "${MODULE_UPPER}")
|
||||
|
||||
# if someone else has included this test, don't do it again
|
||||
# one exception is opm-common which is already found in the
|
||||
# top most CMakeLists.txt but we still need to search for its
|
||||
# dependencies
|
||||
if (${MODULE}_FOUND OR ${module}_FOUND)
|
||||
return ()
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
# variables to pass on to other packages
|
||||
@@ -74,17 +73,222 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
set (_${module}_required "")
|
||||
endif (${module}_FIND_REQUIRED)
|
||||
|
||||
create_module_dir_var(${module})
|
||||
# see if there is a pkg-config entry for this package, and use those
|
||||
# settings as a starting point
|
||||
find_package (PkgConfig)
|
||||
pkg_check_modules (PkgConf_${module} QUIET ${module})
|
||||
|
||||
# This will also set all the needed variables with the exception of
|
||||
# ${module}_CONFIG_VARS for dune modules.
|
||||
find_package(${module} ${_${module}_quiet} ${_${module}_required} CONFIG)
|
||||
# these variables have non-standard names in FindPkgConfig (sic)
|
||||
set (${module}_DEFINITIONS ${PkgConf_${module}_CFLAGS_OTHER})
|
||||
set (${module}_LINKER_FLAG ${PkgConf_${module}_LDFLAGS_OTHER})
|
||||
|
||||
if(NOT ${module}_DEPS)
|
||||
# set the dependencies used in find_package_deps
|
||||
set(${module}_DEPS "${deps}")
|
||||
# try to figure out whether we are in a subdir build tree, and attempt
|
||||
# to put the same name as the appropriate build tree for the module
|
||||
get_filename_component (_build_dir "${CMAKE_CURRENT_BINARY_DIR}" NAME)
|
||||
|
||||
# don't bother if we are in a project specific directory already
|
||||
# (assuming no-one wants to name the build dir after another module!)
|
||||
if ("${_build_dir}" STREQUAL "${PROJECT_NAME}")
|
||||
set (_build_dir "")
|
||||
endif ("${_build_dir}" STREQUAL "${PROJECT_NAME}")
|
||||
|
||||
# if the user hasn't specified any location, and it isn't found
|
||||
# in standard system locations either, then start to wander
|
||||
# about and look for it in proximity to ourself. Qt Creator likes
|
||||
# to put the build-directories as siblings to the source trees,
|
||||
# but with a -build suffix, DUNE likes to have the the build tree
|
||||
# in a "build-cmake" sub-directory of each module
|
||||
set(workaround_cmake_bug 0)
|
||||
if(${module}_DIR})
|
||||
set(workaround_cmake_bug 1)
|
||||
endif()
|
||||
find_package_deps(${module})
|
||||
if(${module}_ROOT})
|
||||
set(workaround_cmake_bug 1)
|
||||
endif()
|
||||
if(${MODULE}_ROOT})
|
||||
set(workaround_cmake_bug 1)
|
||||
endif()
|
||||
if (NOT workaround_cmake_bug)
|
||||
string (TOLOWER "${module}" _module_lower)
|
||||
set (_guess
|
||||
"../${module}"
|
||||
"../${_module_lower}"
|
||||
)
|
||||
set (_guess_bin_only
|
||||
"../${module}-build"
|
||||
"../${_module_lower}-build"
|
||||
)
|
||||
|
||||
# look in similar dirs for the other module
|
||||
if (_build_dir)
|
||||
list (APPEND _guess_bin_only
|
||||
"../../${module}/${_build_dir}"
|
||||
"../../${_module_lower}/${_build_dir}"
|
||||
)
|
||||
endif (_build_dir)
|
||||
|
||||
# generate items that are in the build, not source dir
|
||||
set (_guess_bin)
|
||||
foreach (_item IN ITEMS ${_guess} ${_guess_bin_only})
|
||||
list (APPEND _guess_bin "${PROJECT_BINARY_DIR}/${_item}")
|
||||
endforeach (_item)
|
||||
set (_no_system "")
|
||||
else ()
|
||||
# start looking at the paths in this order
|
||||
set (_guess_bin
|
||||
${${module}_DIR}
|
||||
${${module}_ROOT}
|
||||
${${MODULE}_ROOT}
|
||||
)
|
||||
# if every package is installed directly in the "suite" directory
|
||||
# (e.g. /usr) then allow us to back-track one directory from the
|
||||
# module sub-dir that was added by OpmFind (this happens incidently
|
||||
# already for the source do to the out-of-source support)
|
||||
if ("${${MODULE}_ROOT}" MATCHES "/${module}$")
|
||||
get_filename_component (_suite_parent ${${MODULE}_ROOT} PATH)
|
||||
list (APPEND _guess_bin
|
||||
${_suite_parent}
|
||||
${_suite_parent}/${module}
|
||||
${_suite_parent}/${module}/${_build_dir}
|
||||
)
|
||||
endif ("${${MODULE}_ROOT}" MATCHES "/${module}$")
|
||||
# when we look for the source, it may be that we have been specified
|
||||
# a build directory which is a sub-dir of the source, so we look in
|
||||
# the parent also
|
||||
set (_guess
|
||||
${${module}_DIR}
|
||||
${${module}_ROOT}
|
||||
${${MODULE}_ROOT}
|
||||
)
|
||||
# only add parent directories for those variants that are actually set
|
||||
# (otherwise, we'll inadvertedly add the root directory (=all))
|
||||
if (${module}_DIR)
|
||||
list (APPEND _guess ${${module}_DIR}/..)
|
||||
endif (${module}_DIR)
|
||||
if (${module}_ROOT)
|
||||
list (APPEND _guess ${${module}_ROOT}/..)
|
||||
endif (${module}_ROOT)
|
||||
if (${MODULE}_ROOT)
|
||||
list (APPEND _guess ${${MODULE}_ROOT}/..)
|
||||
endif (${MODULE}_ROOT)
|
||||
# don't search the system paths! that would be dangerous; if there
|
||||
# is a problem in our own specified directory, we don't necessarily
|
||||
# want an old version that is left in one of the system paths!
|
||||
set (_no_system "NO_DEFAULT_PATH")
|
||||
endif ()
|
||||
|
||||
# by specifying _guess in the HINTS section, it gets searched before
|
||||
# the system locations as well. the CMake documentation has a cloudy
|
||||
# recommendation, but it ends up like this: if NO_DEFAULT_PATH is
|
||||
# specified, then PATHS is used. Otherwise, it looks in HINTS, then in
|
||||
# system paths, and the finally in PATHS (!)
|
||||
if (SIBLING_SEARCH)
|
||||
set (_guess_hints ${_guess})
|
||||
set (_guess_hints_bin ${_guess_bin})
|
||||
else (SIBLING_SEARCH)
|
||||
set (_guess_hints)
|
||||
set (_guess_hints_bin)
|
||||
endif (SIBLING_SEARCH)
|
||||
|
||||
# if an include directory is specified directly (e.g. OPM_CORE_INCLUDE_DIR=
|
||||
# /usr/include/opm-2013.03) then this overrides everything else. Notice that
|
||||
# this variable uses the fully capitalized version of the name.
|
||||
if (${MODULE}_INCLUDE_DIR)
|
||||
set (_guess "${${MODULE}_INCLUDE_DIR}")
|
||||
set (_no_system_incl "NO_DEFAULT_PATH")
|
||||
else ()
|
||||
set (_no_system_incl "${_no_system}")
|
||||
endif ()
|
||||
|
||||
# search for this include and library file to get the installation
|
||||
# directory of the package; hints are searched before the system locations,
|
||||
# paths are searched afterwards
|
||||
find_path (${module}_INCLUDE_DIR
|
||||
NAMES "${header}"
|
||||
PATHS ${_guess}
|
||||
HINTS ${PkgConf_${module}_INCLUDE_DIRS} ${_guess_hints}
|
||||
PATH_SUFFIXES "include"
|
||||
${_no_system_incl}
|
||||
)
|
||||
|
||||
# some modules are all in headers
|
||||
if (NOT "${lib}" STREQUAL "")
|
||||
if (CMAKE_SIZEOF_VOID_P)
|
||||
math (EXPR _BITS "8 * ${CMAKE_SIZEOF_VOID_P}")
|
||||
endif (CMAKE_SIZEOF_VOID_P)
|
||||
|
||||
# again, we may directly override the location of the library alone by
|
||||
# specifying e.g. OPM_CORE_LIB_DIR. notice that this is a *directory*
|
||||
# and not the name of the library
|
||||
if (${MODULE}_LIB_DIR)
|
||||
set (_guess_bin "${${MODULE}_LIB_DIR}")
|
||||
set (_no_system_lib "NO_DEFAULT_PATH")
|
||||
else ()
|
||||
set (_no_system_lib "${_no_system}")
|
||||
endif ()
|
||||
|
||||
# if there is more than one library, then look for all of them, putting
|
||||
# them in variables with the name of the library appended. however, the
|
||||
# first entry is assumed to be the "primary" library and will be named
|
||||
# like the module. thus, with a lib entry of "foo;bar", the first library
|
||||
# is called ${module}_LIBRARY and the second ${module}_LIBRARY_bar
|
||||
foreach (_lib IN ITEMS ${lib})
|
||||
# don't include any suffix if it is the first one
|
||||
if ("${lib}" MATCHES "^${_lib}")
|
||||
set (_which)
|
||||
else ()
|
||||
set (_which "_${_lib}")
|
||||
endif ()
|
||||
find_library (${module}_LIBRARY${_which}
|
||||
NAMES "${_lib}"
|
||||
PATHS ${_guess_bin}
|
||||
HINTS ${PkgConf_${module}_LIBRARY_DIRS} ${_guess_hints_bin}
|
||||
PATH_SUFFIXES "lib" "lib/Debug" "lib/Release" "lib/.libs" ".libs" "lib${_BITS}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}" "build-cmake/lib"
|
||||
${_no_system_lib}
|
||||
)
|
||||
# debug info if we didn't find the desired library
|
||||
if (NOT ${module}_LIBRARY${_which})
|
||||
message (STATUS "Failed to find library \"${_lib}\" for module ${module}")
|
||||
endif ()
|
||||
endforeach (_lib)
|
||||
else (NOT "${lib}" STREQUAL "")
|
||||
set (${module}_LIBRARY "")
|
||||
endif (NOT "${lib}" STREQUAL "")
|
||||
|
||||
# add dependencies so that our result variables are complete
|
||||
# list of necessities to build with the software
|
||||
set (${module}_INCLUDE_DIRS "${${module}_INCLUDE_DIR}")
|
||||
foreach (_lib IN ITEMS ${lib})
|
||||
if ("${lib}" MATCHES "^${_lib}")
|
||||
set (${module}_LIBRARIES "${${module}_LIBRARY}")
|
||||
else ()
|
||||
list (APPEND ${module}_LIBRARIES "${${module}_LIBRARY_${_lib}}")
|
||||
endif ()
|
||||
endforeach (_lib)
|
||||
# period because it should be something that evaluates to true
|
||||
# in find_package_handle_standard_args
|
||||
set (${module}_ALL_PREREQS ".")
|
||||
foreach (_dep IN ITEMS ${deps})
|
||||
separate_arguments (_${module}_args UNIX_COMMAND ${_dep})
|
||||
if (_${module}_args)
|
||||
# keep REQUIRED in the arguments only if we were required ourself
|
||||
# "required-ness" is not transitive as far as CMake is concerned
|
||||
# (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}")
|
||||
find_and_append_package_to (${module} ${_args_req} ${_${module}_quiet})
|
||||
list (GET _${module}_args 0 _name_only)
|
||||
string (TOUPPER "${_name_only}" _NAME_ONLY)
|
||||
string (REPLACE "-" "_" _NAME_ONLY "${_NAME_ONLY}")
|
||||
# check manually if it was found if REQUIRED; otherwise poison the
|
||||
# dependency list which is checked later (so that it will fail)
|
||||
if (("${_${module}_args}" MATCHES "REQUIRED") AND NOT (${_name_only}_FOUND OR ${_NAME_ONLY}_FOUND))
|
||||
list (APPEND ${module}_ALL_PREREQS "${_name_only}-NOTFOUND")
|
||||
endif ()
|
||||
else ()
|
||||
message (WARNING "Empty dependency in find module for ${module} (check for trailing semi-colon)")
|
||||
endif ()
|
||||
endforeach (_dep)
|
||||
|
||||
# since find_and_append_package_to is a macro, this variable have
|
||||
# probably been overwritten (due to its common name); it is now
|
||||
@@ -105,10 +309,10 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
# these defines are used in dune/${module} headers, and should be put
|
||||
# in config.h when we include those
|
||||
foreach (_var IN ITEMS ${conf})
|
||||
# massage the name to remove source code formatting
|
||||
string (REGEX REPLACE "^[\n\t\ ]+" "" _var "${_var}")
|
||||
string (REGEX REPLACE "[\n\t\ ]+$" "" _var "${_var}")
|
||||
list (APPEND ${module}_CONFIG_VARS ${_var})
|
||||
# massage the name to remove source code formatting
|
||||
string (REGEX REPLACE "^[\n\t\ ]+" "" _var "${_var}")
|
||||
string (REGEX REPLACE "[\n\t\ ]+$" "" _var "${_var}")
|
||||
list (APPEND ${module}_CONFIG_VARS ${_var})
|
||||
endforeach (_var)
|
||||
|
||||
# these are the defines that should be set when compiling
|
||||
@@ -131,82 +335,57 @@ macro (find_opm_package module deps header lib defs prog conf)
|
||||
|
||||
# write status message in the same manner as everyone else
|
||||
include (FindPackageHandleStandardArgs)
|
||||
if ("${lib}" STREQUAL "")
|
||||
set (_lib_var "")
|
||||
set (_and_lib_var)
|
||||
else ("${lib}" STREQUAL "")
|
||||
foreach (_lib IN ITEMS ${lib})
|
||||
if ("${lib}" MATCHES "^${_lib}")
|
||||
set (_lib_var "${module}_LIBRARY")
|
||||
set (_and_lib_var AND ${_lib_var})
|
||||
else ()
|
||||
list (APPEND _lib_var "${module}_LIBRARY_${_lib}")
|
||||
set (_and_lib_var ${_and_lib_var} AND "${module}_LIBRARY_${_lib}")
|
||||
endif ()
|
||||
endforeach (_lib)
|
||||
endif ("${lib}" STREQUAL "")
|
||||
# if the search is going to fail, then write these variables to
|
||||
# the console as well as a diagnostics
|
||||
if ((NOT (${module}_INCLUDE_DIR ${_and_lib_var} AND HAVE_${MODULE}))
|
||||
AND (_${module}_required OR NOT _${module}_quiet))
|
||||
if (DEFINED ${module}_DIR)
|
||||
message (STATUS "${module}_DIR = ${${module}_DIR}")
|
||||
elseif (DEFINED ${module}_ROOT)
|
||||
message (STATUS "${module}_ROOT = ${${module}_ROOT}")
|
||||
elseif (DEFINED ${MODULE}_ROOT)
|
||||
message (STATUS "${MODULE}_ROOT = ${${MODULE}_ROOT}")
|
||||
endif (DEFINED ${module}_DIR)
|
||||
endif ((NOT (${module}_INCLUDE_DIR ${_and_lib_var} AND HAVE_${MODULE}))
|
||||
AND (_${module}_required OR NOT _${module}_quiet))
|
||||
if ("${${module}_ALL_PREREQS}" MATCHES "-NOTFOUND")
|
||||
message (STATUS "${module} prereqs: ${${module}_ALL_PREREQS}")
|
||||
endif ()
|
||||
find_package_handle_standard_args (
|
||||
${module}
|
||||
DEFAULT_MSG
|
||||
${module}_INCLUDE_DIRS ${module}_LIBRARIES ${module}_FOUND ${module}_ALL_PREREQS
|
||||
)
|
||||
${module}
|
||||
DEFAULT_MSG
|
||||
${module}_INCLUDE_DIR ${_lib_var} HAVE_${MODULE} ${module}_ALL_PREREQS
|
||||
)
|
||||
|
||||
# allow the user to override these from user interface
|
||||
mark_as_advanced (${module}_INCLUDE_DIR)
|
||||
mark_as_advanced (${module}_LIBRARY)
|
||||
|
||||
# some genius that coded the FindPackageHandleStandardArgs figured out
|
||||
# that the module name should be in uppercase (?!)
|
||||
set (${module}_FOUND "${${MODULE_UPPER}_FOUND}")
|
||||
set (${MODULE}_FOUND "${${MODULE_UPPER}_FOUND}")
|
||||
|
||||
# This variable is used by UseDuneVer
|
||||
list(GET ${module}_INCLUDE_DIRS 0 ${module}_INCLUDE_DIR)
|
||||
# print everything out if we're asked to
|
||||
if (${module}_DEBUG)
|
||||
debug_find_vars (${module})
|
||||
endif (${module}_DEBUG)
|
||||
endmacro (find_opm_package module deps header lib defs prog conf)
|
||||
|
||||
macro (find_package_deps module)
|
||||
# period because it should be something that evaluates to true
|
||||
# in find_package_handle_standard_args
|
||||
set (${module}_ALL_PREREQS ".")
|
||||
foreach (_dep IN ITEMS ${${module}_DEPS})
|
||||
separate_arguments (_${module}_args UNIX_COMMAND "${_dep}")
|
||||
if (_${module}_args)
|
||||
# keep REQUIRED in the arguments only if we were required ourself
|
||||
# "required-ness" is not transitive as far as CMake is concerned
|
||||
# (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-" OR _dep MATCHES "ewoms")
|
||||
set(deplist ${_dep})
|
||||
string(STRIP "${_dep}" _dep)
|
||||
string(REPLACE " " ";" deplist "${_dep}")
|
||||
list(GET deplist 0 depname)
|
||||
create_module_dir_var(${depname})
|
||||
endif()
|
||||
find_and_append_package_to (${module} ${_${module}_args} ${_${module}_quiet})
|
||||
list (GET _${module}_args 0 _name_only)
|
||||
string (TOUPPER "${_name_only}" _NAME_ONLY)
|
||||
string (REPLACE "-" "_" _NAME_ONLY "${_NAME_ONLY}")
|
||||
# check manually if it was found if REQUIRED; otherwise poison the
|
||||
# dependency list which is checked later (so that it will fail)
|
||||
if (("${_${module}_args}" MATCHES "REQUIRED") AND NOT (${_name_only}_FOUND OR ${_NAME_ONLY}_FOUND))
|
||||
list (APPEND ${module}_ALL_PREREQS "${_name_only}-NOTFOUND")
|
||||
endif ()
|
||||
else ()
|
||||
message (WARNING "Empty dependency in find module for ${module} (check for trailing semi-colon)")
|
||||
endif ()
|
||||
endforeach (_dep)
|
||||
|
||||
# tidy the lists before returning them
|
||||
remove_dup_deps (${module})
|
||||
|
||||
# these defines are used in dune/${module} headers, and should be put
|
||||
# in config.h when we include those
|
||||
foreach (_var IN ITEMS ${conf})
|
||||
# massage the name to remove source code formatting
|
||||
string (REGEX REPLACE "^[\n\t\ ]+" "" _var "${_var}")
|
||||
string (REGEX REPLACE "[\n\t\ ]+$" "" _var "${_var}")
|
||||
list (APPEND ${module}_CONFIG_VARS ${_var})
|
||||
endforeach (_var)
|
||||
|
||||
# these are the defines that should be set when compiling
|
||||
# without config.h
|
||||
config_cmd_line (${module}_CMD_CONFIG ${module}_CONFIG_VARS)
|
||||
|
||||
# This variable is used by UseDuneVer
|
||||
list(GET ${module}_INCLUDE_DIRS 0 ${module}_INCLUDE_DIR)
|
||||
# print everything out if we're asked to
|
||||
if (${module}_DEBUG)
|
||||
debug_find_vars (${module})
|
||||
endif (${module}_DEBUG)
|
||||
endmacro ()
|
||||
|
||||
# print all variables defined by the above macro
|
||||
function (debug_find_vars module)
|
||||
message (STATUS "${module}_FOUND = ${${module}_FOUND}")
|
||||
@@ -216,7 +395,7 @@ function (debug_find_vars module)
|
||||
message (STATUS "${module}_CONFIG_VARS = ${${module}_CONFIG_VARS}")
|
||||
message (STATUS "${module}_LINKER_FLAGS = ${${module}_LINKER_FLAGS}")
|
||||
string (TOUPPER ${module} MODULE)
|
||||
string (REPLACE "-" "_" MODULE ${MODULE})
|
||||
string (REPLACE "-" "_" MODULE ${MODULE})
|
||||
message (STATUS "HAVE_${MODULE} = ${HAVE_${MODULE}}")
|
||||
endfunction (debug_find_vars module)
|
||||
|
||||
|
||||
@@ -56,9 +56,6 @@ function (configure_cmake_file name variant version)
|
||||
set (opm-project_${suffix} "${${name}_${suffix}}")
|
||||
endforeach (suffix)
|
||||
set (opm-project_NAME "${${name}_NAME}")
|
||||
set (opm-project_NAME_UC "${${name}_NAME}")
|
||||
string(TOUPPER "${opm-project_NAME}" opm-project_NAME_UC)
|
||||
string(REPLACE "-" "_" opm-project_NAME_UC "${opm-project_NAME_UC}")
|
||||
|
||||
# make the file substitutions
|
||||
configure_file (
|
||||
@@ -76,9 +73,7 @@ function (opm_cmake_config name)
|
||||
set (template_dir "${OPM_MACROS_ROOT}/cmake/Templates")
|
||||
|
||||
# write configuration file to locate library
|
||||
set(DUNE_PREFIX ${PROJECT_SOURCE_DIR})
|
||||
set(OPM_PROJECT_EXTRA_CODE ${OPM_PROJECT_EXTRA_CODE_INTREE})
|
||||
set(PREREQ_LOCATION "${PROJECT_SOURCE_DIR}")
|
||||
configure_cmake_file (${name} "config" "")
|
||||
configure_cmake_file (${name} "config" "-version")
|
||||
configure_vars (
|
||||
@@ -92,17 +87,10 @@ function (opm_cmake_config name)
|
||||
${template_dir}/opm-project.pc.in
|
||||
${PROJECT_BINARY_DIR}/${${name}_NAME}.pc
|
||||
${PROJECT_BINARY_DIR}
|
||||
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
|
||||
${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.
|
||||
string(REPLACE "${CMAKE_INSTALL_PREFIX}/include${${name}_VER_DIR}" "" ${name}_INCLUDE_DIRS "${${name}_INCLUDE_DIRS}")
|
||||
|
||||
# replace the build directory with the target directory in the
|
||||
# variables that contains build paths
|
||||
string (REPLACE
|
||||
@@ -123,8 +111,6 @@ function (opm_cmake_config name)
|
||||
# create a config mode file which targets the install directory instead
|
||||
# of the build directory (using the same input template)
|
||||
set(OPM_PROJECT_EXTRA_CODE ${OPM_PROJECT_EXTRA_CODE_INSTALLED})
|
||||
set(PREREQ_LOCATION "${CMAKE_INSTALL_PREFIX}/share/opm/cmake/Modules")
|
||||
set(DUNE_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
configure_cmake_file (${name} "install" "")
|
||||
configure_vars (
|
||||
FILE CMAKE "${PROJECT_BINARY_DIR}/${${name}_NAME}-install.cmake"
|
||||
@@ -158,7 +144,7 @@ function (opm_cmake_config name)
|
||||
if (${name}_TARGET)
|
||||
set (_pkg_dir ${CMAKE_INSTALL_LIBDIR})
|
||||
else ()
|
||||
set (_pkg_dir lib)
|
||||
set (_pkg_dir ${LIBDIR_MULTIARCH_UNAWARE})
|
||||
endif ()
|
||||
install (
|
||||
FILES ${PROJECT_BINARY_DIR}/${${name}_NAME}-install.pc
|
||||
|
||||
@@ -65,11 +65,6 @@ macro (opm_compile_satellites opm satellite excl_all test_regexp)
|
||||
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
|
||||
@@ -77,7 +72,6 @@ macro (opm_compile_satellites opm satellite excl_all test_regexp)
|
||||
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)
|
||||
@@ -87,14 +81,11 @@ macro (opm_compile_satellites opm satellite excl_all test_regexp)
|
||||
|
||||
# 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()
|
||||
endif ("${_sat_NAME}" MATCHES "${_regexp}")
|
||||
endforeach (_regexp)
|
||||
get_target_property (_sat_LOC ${_sat_NAME} LOCATION)
|
||||
# Run tests through mpi-run. Ubuntu 14.04 provided mpi libs will crash
|
||||
@@ -147,7 +138,7 @@ 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}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${dirname}
|
||||
)
|
||||
|
||||
# if ever huge test datafiles are necessary, then change this
|
||||
@@ -228,13 +219,6 @@ macro(opm_add_test TestName)
|
||||
set(CURTEST_EXE_NAME ${TestName})
|
||||
endif()
|
||||
|
||||
# Strip test_ prefix from name
|
||||
if ("${TestName}" MATCHES "^test_([^/]*)$")
|
||||
string (REGEX REPLACE "^test_([^/]*)$" "\\1" _FANCY "${TestName}")
|
||||
else()
|
||||
set(_FANCY ${TestName})
|
||||
endif()
|
||||
|
||||
# try to auto-detect the name of the source file if SOURCES are not
|
||||
# explicitly specified.
|
||||
if (NOT CURTEST_SOURCES)
|
||||
@@ -282,7 +266,7 @@ macro(opm_add_test TestName)
|
||||
|
||||
# the libraries to link against
|
||||
if (NOT CURTEST_LIBRARIES)
|
||||
SET(CURTEST_LIBRARIES "${${project}_LIBRARIES}")
|
||||
SET(CURTEST_LIBRARIES "${${CMAKE_PROJECT_NAME}_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
# determine if the test should be completely ignored, i.e., the
|
||||
@@ -304,9 +288,6 @@ macro(opm_add_test TestName)
|
||||
add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES})
|
||||
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
||||
|
||||
if(TARGET ${project}_prepare)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare)
|
||||
endif()
|
||||
if(CURTEST_DEPENDS)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS})
|
||||
endif()
|
||||
@@ -321,9 +302,11 @@ macro(opm_add_test TestName)
|
||||
if(CURTEST_DEPENDS)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS})
|
||||
endif()
|
||||
if(TARGET ${project}_prepare)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare)
|
||||
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
endif()
|
||||
add_dependencies(test-suite "${CURTEST_EXE_NAME}")
|
||||
endif()
|
||||
|
||||
# figure out how the test should be run. if a test driver script
|
||||
@@ -338,7 +321,7 @@ macro(opm_add_test TestName)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test(NAME ${_FANCY}
|
||||
add_test(NAME ${TestName}
|
||||
WORKING_DIRECTORY "${CURTEST_WORKING_DIRECTORY}"
|
||||
COMMAND ${CURTEST_COMMAND})
|
||||
|
||||
@@ -353,20 +336,13 @@ macro(opm_add_test TestName)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT CURTEST_NO_COMPILE)
|
||||
if(NOT TARGET test-suite)
|
||||
add_custom_target(test-suite)
|
||||
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)
|
||||
add_test(${TestName} skip_test_dummy)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
option (SIBLING_SEARCH "Search sibling directories before system paths" ON)
|
||||
mark_as_advanced (SIBLING_SEARCH)
|
||||
|
||||
macro(create_module_dir_var module)
|
||||
if(SIBLING_SEARCH AND NOT ${module}_DIR)
|
||||
# guess the sibling dir
|
||||
get_filename_component(_leaf_dir_name ${PROJECT_BINARY_DIR} NAME)
|
||||
get_filename_component(_parent_full_dir ${PROJECT_BINARY_DIR} DIRECTORY)
|
||||
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)
|
||||
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()
|
||||
string(REPLACE ${PROJECT_NAME} ${_clone_dir} _module_leaf ${_leaf_dir_name})
|
||||
if(NOT _leaf_dir_name STREQUAL _module_leaf
|
||||
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})
|
||||
# All modules are in a common build dir
|
||||
set(${module}_DIR "${_parent_full_dir}/${_clone_dir}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(${module}_DIR AND NOT IS_DIRECTORY ${${module}_DIR})
|
||||
message(WARNING "Value ${${module}_DIR} passed to variable"
|
||||
" ${module}_DIR is not a directory")
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -50,7 +50,7 @@ macro(opm_static_add_dependencies target)
|
||||
endmacro()
|
||||
|
||||
include(ExternalProject)
|
||||
include(GNUInstallDirs)
|
||||
include(UseMultiArch)
|
||||
|
||||
# Defaults to building master
|
||||
if(NOT OPM_BENCHMARK_VERSION)
|
||||
|
||||
@@ -14,19 +14,139 @@
|
||||
# Add these variables to ${project}_CONFIG_IMPL_VARS in CMakeLists.txt
|
||||
# if you need these in the code.
|
||||
|
||||
include (UseMultiArch)
|
||||
|
||||
function (find_dune_version suite module)
|
||||
# CMake's find_package will set <package>_VERSION_(MAJOR|MINOR|REVISION)
|
||||
# we simply rely on that.
|
||||
# the _ROOT variable may or may not be set, but the include
|
||||
# variable should always be; get the prefix from the header path
|
||||
# if we have a multilib installation where the package maintainer
|
||||
# have installed it in e.g. /usr/include/dune-2.2/dune/istl, then
|
||||
# stash this extra indirection and add it back later in lib/
|
||||
set (_inc_path "${${suite}-${module}_INCLUDE_DIR}")
|
||||
file (TO_CMAKE_PATH _inc_path "${_inc_path}")
|
||||
set (_multilib_regexp "(.*)/include(/${suite}[^/]+)?")
|
||||
if (_inc_path MATCHES "${_multilib_regexp}")
|
||||
set (_orig_inc "${_inc_path}")
|
||||
string (REGEX REPLACE "${_multilib_regexp}" "\\1" _inc_path "${_orig_inc}")
|
||||
# only get the second group if it is really there (there is
|
||||
# probably a better way to do this in CMake)
|
||||
if ("${_inc_path}/include" STREQUAL "${_orig_inc}")
|
||||
set (_multilib "")
|
||||
else ()
|
||||
string (REGEX REPLACE "${_multilib_regexp}" "\\2" _multilib "${_orig_inc}")
|
||||
endif ()
|
||||
else ()
|
||||
set (_multilib "")
|
||||
endif ()
|
||||
|
||||
# some modules does not have a library, use the directory of the
|
||||
# header files to find what would be the library dir.
|
||||
# note that when we refer to a build tree, then the libraries always
|
||||
# go into lib/, but we don't care about that because in that case,
|
||||
# dune.module isn't in the lib/ directory anyway but must be retrieved
|
||||
# from the source. hence, we only have to worry about the library
|
||||
# directory of a system installation here.
|
||||
if (NOT ${suite}-${module}_LIBRARY)
|
||||
# this suffix is gotten from UseMultiArch.cmake
|
||||
set (_lib_path "${_inc_path}/${CMAKE_INSTALL_LIBDIR}")
|
||||
else ()
|
||||
get_filename_component (_lib_path "${${suite}-${module}_LIBRARY}" PATH)
|
||||
endif ()
|
||||
|
||||
# if we have a source tree, dune.module is available there
|
||||
set (_dune_mod "${_inc_path}/dune.module")
|
||||
if (NOT EXISTS "${_dune_mod}")
|
||||
set (_last_dune_mod_src "${_dune_mod}")
|
||||
set (_dune_mod "")
|
||||
endif ()
|
||||
|
||||
if (NOT _dune_mod)
|
||||
# look for the build tree; if we found the library, then the
|
||||
# dune.module file should be in a sub-directory
|
||||
get_filename_component (_immediate "${_lib_path}" NAME)
|
||||
if ("${_immediate}" STREQUAL ".libs")
|
||||
# remove autotools internal path
|
||||
get_filename_component (_lib_path "${_lib_path}" PATH)
|
||||
endif ()
|
||||
get_filename_component (_immediate "${_lib_path}" NAME)
|
||||
if ("${_immediate}" STREQUAL "${CMAKE_LIBRARY_ARCHITECTURE}")
|
||||
# remove multi-arch part of the library path to get parent
|
||||
get_filename_component (_lib_path "${_lib_path}" PATH)
|
||||
endif ()
|
||||
get_filename_component (_immediate "${_lib_path}" NAME)
|
||||
if (("${_immediate}" STREQUAL "${CMAKE_INSTALL_LIBDIR}")
|
||||
OR ("${_immediate}" STREQUAL "lib")
|
||||
OR ("${_immediate}" STREQUAL "${LIBDIR_MULTIARCH_UNAWARE}"))
|
||||
# remove library part of the path; this also undo the suffix
|
||||
# we added if we used the library as a standin
|
||||
get_filename_component (_lib_path "${_lib_path}" PATH)
|
||||
endif ()
|
||||
# from this point on, _lib_path does not contain an architecture-
|
||||
# specific component anymore; dune.module is always put in straight
|
||||
# noarch lib/ since it does not contain any paths to binaries
|
||||
set (_suffix "${_multilib}/dunecontrol/${suite}-${module}/dune.module")
|
||||
set (_dune_mod "${_lib_path}/${LIBDIR_MULTIARCH_UNAWARE}${_suffix}")
|
||||
if (NOT EXISTS "${_dune_mod}")
|
||||
set (_last_dune_mod_bld "${_dune_mod}")
|
||||
# one more try, if we have a private install, then it doesn't use
|
||||
# e.g. lib64 but always lib (!)
|
||||
if ("${LIBDIR_MULTIARCH_UNAWARE}" STREQUAL "lib")
|
||||
set (_dune_mod "")
|
||||
else ()
|
||||
set (_dune_mod "${_lib_path}/lib${_suffix}")
|
||||
if (NOT EXISTS "${_dune_mod}")
|
||||
set (_last_dune_mod_pri "${_dune_mod}")
|
||||
# use the name itself as a flag for whether it was found or not
|
||||
set (_dune_mod "")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# if it is not available, it may make havoc having empty defines in the source
|
||||
# code later, so we bail out early
|
||||
if (NOT _dune_mod)
|
||||
if (${suite}-${module}_FOUND)
|
||||
set (_searched_paths "\"${_last_dune_mod_src}\"")
|
||||
if (NOT ("${_last_dune_mod_bld}" STREQUAL ""))
|
||||
set (_searched_paths "either ${_searched_paths} or \"${_last_dune_mod_bld}\"")
|
||||
endif ()
|
||||
if (NOT ("${_last_dune_mod_pri}" STREQUAL ""))
|
||||
set (_searched_paths "${_searched_paths} or \"${_last_dune_mod_pri}\"")
|
||||
endif ()
|
||||
message (FATAL_ERROR "Failed to locate dune.module for ${suite}-${module} (looking for ${_searched_paths})")
|
||||
else ()
|
||||
return ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# parse the file for the Version: field
|
||||
set (_ver_regexp "[ ]*Version:[ ]*([0-9]+)\\.([0-9]+)(.*)")
|
||||
file (STRINGS "${_dune_mod}" _ver_field REGEX "${_ver_regexp}")
|
||||
string (REGEX REPLACE "${_ver_regexp}" "\\1" _major "${_ver_field}")
|
||||
string (REGEX REPLACE "${_ver_regexp}" "\\2" _minor "${_ver_field}")
|
||||
string (REGEX REPLACE "${_ver_regexp}" "\\3" _revision "${_ver_field}")
|
||||
|
||||
# revision may or may not be there
|
||||
set (_rev_regexp "\\.([0-9]+).*")
|
||||
if (_revision MATCHES "${_rev_regexp}")
|
||||
string (REGEX REPLACE "${_rev_regexp}" "\\1" _revision "${_revision}")
|
||||
else ()
|
||||
set (_revision "0")
|
||||
endif ()
|
||||
|
||||
# generate variable for what we have found
|
||||
string (TOUPPER "${suite}" _SUITE)
|
||||
string (TOUPPER "${module}" _MODULE)
|
||||
string (REPLACE "-" "_" _MODULE "${_MODULE}")
|
||||
set (${_SUITE}_${_MODULE}_VERSION_MAJOR "${${suite}-${module}_VERSION_MAJOR}" PARENT_SCOPE)
|
||||
set (${_SUITE}_${_MODULE}_VERSION_MINOR "${${suite}-${module}_VERSION_MINOR}" PARENT_SCOPE)
|
||||
set (${_SUITE}_${_MODULE}_VERSION_REVISION "${${suite}-${module}_VERSION_PATCH}" PARENT_SCOPE)
|
||||
if ((NOT DEFINED ${_SUITE}_${_MODULE}_VERSION_MAJOR) AND
|
||||
(NOT DEFINED ${_SUITE}_${_MODULE}_VERSION_MINOR) AND
|
||||
(NOT DEFINED ${_SUITE}_${_MODULE}_VERSION_REVISION))
|
||||
set (${_SUITE}_${_MODULE}_VERSION_MAJOR "${_major}" PARENT_SCOPE)
|
||||
set (${_SUITE}_${_MODULE}_VERSION_MINOR "${_minor}" PARENT_SCOPE)
|
||||
set (${_SUITE}_${_MODULE}_VERSION_REVISION "${_revision}" PARENT_SCOPE)
|
||||
endif ()
|
||||
|
||||
if( ${suite}-${module}_FOUND )
|
||||
# print the version number we detected in the configuration log
|
||||
message (STATUS "Version ${${suite}-${module}_VERSION_MAJOR}.${${suite}-${module}_VERSION_MINOR}.${${suite}-${module}_VERSION_PATCH} of ${suite}-${module} from ${${suite}-${module}_DIR}")
|
||||
endif()
|
||||
# print the version number we detected in the configuration log
|
||||
message (STATUS "Version ${_major}.${_minor}.${_revision} of ${suite}-${module} from ${_dune_mod}")
|
||||
endfunction (find_dune_version suite module)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
find_package (Boost 1.44.0 COMPONENTS unit_test_framework QUIET)
|
||||
if (NOT Boost_UNIT_TEST_FRAMEWORK_FOUND)
|
||||
find_package (Boost 1.44.0 COMPONENTS unit_test_framework QUIET)
|
||||
endif ()
|
||||
|
||||
if (Boost_UNIT_TEST_FRAMEWORK_FOUND)
|
||||
# setup to do a test compile
|
||||
|
||||
35
cmake/Modules/UseMultiArch.cmake
Normal file
35
cmake/Modules/UseMultiArch.cmake
Normal file
@@ -0,0 +1,35 @@
|
||||
# - Multiarch support in object code library directories
|
||||
#
|
||||
# This module sets the following variable
|
||||
# CMAKE_INSTALL_LIBDIR to lib, lib64 or lib/x86_64-linux-gnu
|
||||
# depending on the platform; use this path
|
||||
# for platform-specific binaries.
|
||||
#
|
||||
# Note that it will override the results of GNUInstallDirs if included after
|
||||
# that module.
|
||||
|
||||
# default if we need to put something in the library directory for a
|
||||
# component that is *not* multiarch-aware
|
||||
set (LIBDIR_MULTIARCH_UNAWARE "lib")
|
||||
|
||||
# Fedora uses lib64/ for 64-bit systems, Debian uses lib/x86_64-linux-gnu
|
||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||
# Debian or Ubuntu?
|
||||
if (EXISTS "/etc/debian_version")
|
||||
set (_libdir_def "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
|
||||
else (EXISTS "/etc/debian_version")
|
||||
# 64-bit system?
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set (_libdir_def "lib64")
|
||||
set (LIBDIR_MULTIARCH_UNAWARE "${_libdir_def}")
|
||||
else (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set (_libdir_def "lib")
|
||||
endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif (EXISTS "/etc/debian_version")
|
||||
else ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||
set (_libdir_def "lib")
|
||||
endif ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||
|
||||
# let the user override if somewhere else is desirable
|
||||
set (CMAKE_INSTALL_LIBDIR "${_libdir_def}" CACHE PATH "Object code libraries")
|
||||
mark_as_advanced (CMAKE_INSTALL_LIBDIR)
|
||||
@@ -21,28 +21,10 @@ if (CXX_COMPAT_GCC)
|
||||
# disabled due to widespread bugs in the linker plugin
|
||||
option (WHOLE_PROG_OPTIM "Whole program optimization (lto)" OFF)
|
||||
if (WHOLE_PROG_OPTIM)
|
||||
check_cxx_accepts_flag ("-flto" HAVE_LINK_OPTS)
|
||||
check_cxx_accepts_flag ("-fuse-linker-plugin" HAVE_LINK_PLUGIN)
|
||||
if (HAVE_LINK_OPTS)
|
||||
list (APPEND _opt_flags "-flto")
|
||||
endif (HAVE_LINK_OPTS)
|
||||
if (HAVE_LINK_PLUGIN)
|
||||
list (APPEND _opt_flags "-fuse-linker-plugin")
|
||||
endif (HAVE_LINK_PLUGIN)
|
||||
if(HAVE_LINK_OPTS AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
string(REPLACE "." ";" VERSION_LIST "${CMAKE_C_COMPILER_VERSION}")
|
||||
list(GET VERSION_LIST 0 VER_MAJOR)
|
||||
find_program(LTO_AR_COMMAND NAMES ${CMAKE_C_COMPILER}-ar gcc-ar-${VER_MAJOR} gcc-ar)
|
||||
find_program(LTO_RANLIB_COMMAND NAMES ${CMAKE_C_COMPILER}-ranlib gcc-ranlib-${VER_MAJOR} gcc-ranlib)
|
||||
if(LTO_AR_COMMAND)
|
||||
set(CMAKE_AR ${LTO_AR_COMMAND})
|
||||
message(STATUS "Using LTO-enabled ar: ${CMAKE_AR}")
|
||||
endif()
|
||||
if(LTO_RANLIB_COMMAND)
|
||||
set(CMAKE_RANLIB ${LTO_RANLIB_COMMAND})
|
||||
message(STATUS "Using LTO-enabled ranlib: ${CMAKE_RANLIB}")
|
||||
endif()
|
||||
endif()
|
||||
check_cxx_accepts_flag ("-flto" HAVE_LINK_OPTS)
|
||||
if (HAVE_LINK_OPTS)
|
||||
list (APPEND _opt_flags "-flto")
|
||||
endif (HAVE_LINK_OPTS)
|
||||
endif (WHOLE_PROG_OPTIM)
|
||||
|
||||
# native instruction set tuning
|
||||
@@ -56,17 +38,13 @@ if (CXX_COMPAT_GCC)
|
||||
|
||||
# default optimization flags, if not set by user
|
||||
set_default_option (CXX _opt_dbg "-O0" "(^|\ )-O")
|
||||
set_default_option (CXX _opt_rel "-O3" "(^|\ )-O")
|
||||
set_default_option (CXX _opt_rel "-O2" "(^|\ )-O")
|
||||
|
||||
# use these options for debug builds - no optimizations
|
||||
add_options (ALL_LANGUAGES "${_prof_DEBUG}" ${_opt_dbg} "-DDEBUG")
|
||||
|
||||
# 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" ON)
|
||||
if(WITH_NDEBUG)
|
||||
add_options (ALL_LANGUAGES "${_prof_RELEASE}" -DNDEBUG)
|
||||
endif()
|
||||
add_options (ALL_LANGUAGES "${_prof_RELEASE}" ${_opt_rel} "-DNDEBUG" ${_opt_flags})
|
||||
|
||||
else ()
|
||||
# default information from system
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# Add static analysis tests for a given source file
|
||||
|
||||
macro(setup_static_analysis_tools)
|
||||
find_package(CppCheck)
|
||||
if(CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
find_package(ClangCheck)
|
||||
else()
|
||||
message(STATUS "Disabling clang-check as CMAKE_EXPORT_COMPILE_COMMANDS is not enabled")
|
||||
endif()
|
||||
if(OPM_COMMON_ROOT)
|
||||
set(DIR ${OPM_COMMON_ROOT})
|
||||
elseif(OPM_MACROS_ROOT)
|
||||
set(DIR ${OPM_MACROS_ROOT})
|
||||
else()
|
||||
set(DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
if(CPPCHECK_FOUND)
|
||||
file(COPY ${DIR}/cmake/Scripts/cppcheck-test.sh
|
||||
DESTINATION bin
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
endif()
|
||||
if(CLANGCHECK_FOUND AND CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
configure_file(${DIR}/cmake/Scripts/clang-check-test.sh.in
|
||||
${CMAKE_BINARY_DIR}/CMakeFiles/clang-check-test.sh)
|
||||
file(COPY ${CMAKE_BINARY_DIR}/CMakeFiles/clang-check-test.sh
|
||||
DESTINATION bin
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(add_static_analysis_tests sources includes)
|
||||
if(CPPCHECK_FOUND OR (CLANGCHECK_FOUND AND CMAKE_EXPORT_COMPILE_COMMANDS))
|
||||
foreach(dep ${${includes}})
|
||||
list(APPEND IPATHS -I ${dep})
|
||||
endforeach()
|
||||
foreach(src ${${sources}})
|
||||
file(RELATIVE_PATH name ${PROJECT_SOURCE_DIR} ${src})
|
||||
if(CPPCHECK_FOUND)
|
||||
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)
|
||||
add_test(NAME clang-check+${name}
|
||||
COMMAND bin/clang-check-test.sh ${CLANGCHECK_PROGRAM} ${src}
|
||||
CONFIGURATIONS analyze clang-check)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
45
cmake/Modules/ewoms-prereqs.cmake
Normal file
45
cmake/Modules/ewoms-prereqs.cmake
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- 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:
|
||||
|
||||
# this avoids an annoying deprecation warning on DUNE 2.4 (which we
|
||||
# are not interested in anyway)
|
||||
set(DUNE_AVOID_CAPABILITIES_IS_PARALLEL_DEPRECATION_WARNING 1)
|
||||
|
||||
# defines that must be present in config.h for our headers
|
||||
set (ewoms_CONFIG_VAR
|
||||
HAVE_QUAD
|
||||
HAVE_VALGRIND
|
||||
HAVE_DUNE_COMMON
|
||||
HAVE_DUNE_GEOMETRY
|
||||
HAVE_DUNE_GRID
|
||||
HAVE_DUNE_LOCALFUNCTIONS
|
||||
HAVE_DUNE_ISTL
|
||||
HAVE_DUNE_ALUGRID
|
||||
HAVE_DUNE_FEM
|
||||
DUNE_AVOID_CAPABILITIES_IS_PARALLEL_DEPRECATION_WARNING
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (ewoms_DEPS
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
# DUNE prerequisites
|
||||
"dune-common REQUIRED"
|
||||
"dune-geometry REQUIRED"
|
||||
"dune-grid REQUIRED"
|
||||
"dune-istl REQUIRED"
|
||||
"opm-common REQUIRED"
|
||||
"opm-material REQUIRED"
|
||||
"dune-localfunctions"
|
||||
"dune-alugrid"
|
||||
"dune-fem"
|
||||
"opm-parser"
|
||||
"opm-grid"
|
||||
"opm-core"
|
||||
# librt (on some systems necessary for clock_gettime())
|
||||
"librt REQUIRED"
|
||||
# valgrind client requests
|
||||
"Valgrind"
|
||||
# quadruple precision floating point calculations
|
||||
"Quadmath"
|
||||
)
|
||||
19
cmake/Modules/opm-benchmarks-prereqs.cmake
Normal file
19
cmake/Modules/opm-benchmarks-prereqs.cmake
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- 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-benchmarks_CONFIG_VAR
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-benchmarks_DEPS
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
# various runtime library enhancements
|
||||
"Boost 1.44.0
|
||||
COMPONENTS date_time filesystem system unit_test_framework REQUIRED"
|
||||
# OPM dependency
|
||||
"opm-common"
|
||||
"opm-core REQUIRED"
|
||||
"opm-upscaling REQUIRED"
|
||||
)
|
||||
17
cmake/Modules/opm-common-prereqs.cmake
Normal file
17
cmake/Modules/opm-common-prereqs.cmake
Normal file
@@ -0,0 +1,17 @@
|
||||
# -*- 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-common_CONFIG_VAR
|
||||
"HAS_ATTRIBUTE_UNUSED")
|
||||
|
||||
# dependencies
|
||||
set (opm-common_DEPS
|
||||
# compile with C99 support if available
|
||||
"C99"
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
# various runtime library enhancements
|
||||
"Boost 1.44.0
|
||||
COMPONENTS system unit_test_framework REQUIRED"
|
||||
)
|
||||
52
cmake/Modules/opm-core-prereqs.cmake
Normal file
52
cmake/Modules/opm-core-prereqs.cmake
Normal file
@@ -0,0 +1,52 @@
|
||||
# -*- 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-core_CONFIG_VAR
|
||||
HAVE_ERT
|
||||
HAVE_SUITESPARSE_UMFPACK_H
|
||||
HAVE_DUNE_ISTL
|
||||
HAVE_MPI
|
||||
HAVE_PETSC
|
||||
DUNE_ISTL_VERSION_MAJOR
|
||||
DUNE_ISTL_VERSION_MINOR
|
||||
DUNE_ISTL_VERSION_REVISION
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-core_DEPS
|
||||
# compile with C99 support if available
|
||||
"C99"
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
# various runtime library enhancements
|
||||
"Boost 1.44.0
|
||||
COMPONENTS date_time filesystem system unit_test_framework REQUIRED"
|
||||
# matrix library
|
||||
"BLAS REQUIRED"
|
||||
"LAPACK REQUIRED"
|
||||
# Tim Davis' SuiteSparse archive
|
||||
"SuiteSparse COMPONENTS umfpack"
|
||||
# solver
|
||||
"SuperLU"
|
||||
# xml processing (for config parsing)
|
||||
"TinyXML"
|
||||
# Ensembles-based Reservoir Tools (ERT)
|
||||
"ERT REQUIRED"
|
||||
# Look for MPI support
|
||||
"MPI"
|
||||
# PETSc numerical backend
|
||||
"PETSc"
|
||||
# DUNE dependency
|
||||
"dune-common"
|
||||
"dune-istl"
|
||||
"opm-common REQUIRED"
|
||||
# Parser library for ECL-type simulation models
|
||||
"opm-parser REQUIRED"
|
||||
# the code which implements the material laws
|
||||
"opm-material REQUIRED"
|
||||
# the code which implements the output routines
|
||||
"opm-output REQUIRED"
|
||||
# the code which implements grids
|
||||
"opm-grid REQUIRED"
|
||||
)
|
||||
21
cmake/Modules/opm-flowdiagnostics-applications-prereqs.cmake
Normal file
21
cmake/Modules/opm-flowdiagnostics-applications-prereqs.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- 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-flowdiagnostics-applications_CONFIG_VAR
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-flowdiagnostics-applications_DEPS
|
||||
# compile with C99 support if available
|
||||
"C99"
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
"Boost 1.44.0
|
||||
COMPONENTS filesystem regex system unit_test_framework REQUIRED"
|
||||
"ERT REQUIRED"
|
||||
# prerequisite OPM modules
|
||||
"opm-common REQUIRED;
|
||||
opm-flowdiagnostics REQUIRED;
|
||||
opm-core REQUIRED"
|
||||
)
|
||||
18
cmake/Modules/opm-flowdiagnostics-prereqs.cmake
Normal file
18
cmake/Modules/opm-flowdiagnostics-prereqs.cmake
Normal file
@@ -0,0 +1,18 @@
|
||||
# -*- 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-flowdiagnostics_CONFIG_VAR
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-flowdiagnostics_DEPS
|
||||
# compile with C99 support if available
|
||||
"C99"
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
"Boost 1.44.0
|
||||
COMPONENTS unit_test_framework REQUIRED"
|
||||
# prerequisite OPM modules
|
||||
"opm-common REQUIRED"
|
||||
)
|
||||
33
cmake/Modules/opm-grid-prereqs.cmake
Normal file
33
cmake/Modules/opm-grid-prereqs.cmake
Normal file
@@ -0,0 +1,33 @@
|
||||
# -*- 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-grid_CONFIG_VAR
|
||||
DUNE_GRID_VERSION_MAJOR
|
||||
DUNE_GRID_VERSION_MINOR
|
||||
DUNE_GRID_VERSION_REVISION
|
||||
DUNE_COMMON_VERSION_MAJOR
|
||||
DUNE_COMMON_VERSION_MINOR
|
||||
DUNE_COMMON_VERSION_REVISION
|
||||
HAVE_DUNE_ISTL
|
||||
HAVE_MPI
|
||||
HAVE_ZOLTAN
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-grid_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"
|
||||
"MPI"
|
||||
"dune-common"
|
||||
"dune-grid REQUIRED"
|
||||
"dune-istl"
|
||||
"opm-common REQUIRED"
|
||||
"opm-parser REQUIRED"
|
||||
"ZOLTAN"
|
||||
)
|
||||
25
cmake/Modules/opm-material-prereqs.cmake
Normal file
25
cmake/Modules/opm-material-prereqs.cmake
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- 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-material_CONFIG_VAR
|
||||
HAVE_MPI
|
||||
HAVE_TYPE_TRAITS
|
||||
HAVE_VALGRIND
|
||||
HAVE_FINAL
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-material_DEPS
|
||||
# compile with C99 support if available
|
||||
"C99"
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
# prerequisite OPM modules
|
||||
"opm-parser"
|
||||
"opm-common REQUIRED"
|
||||
# DUNE dependency
|
||||
"dune-common REQUIRED"
|
||||
# valgrind client requests
|
||||
"Valgrind"
|
||||
)
|
||||
24
cmake/Modules/opm-output-prereqs.cmake
Normal file
24
cmake/Modules/opm-output-prereqs.cmake
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- 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-output_CONFIG_VAR
|
||||
HAVE_ERT
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-output_DEPS
|
||||
# compile with C99 support if available
|
||||
"C99"
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features REQUIRED"
|
||||
# various runtime library enhancements
|
||||
"Boost 1.44.0
|
||||
COMPONENTS unit_test_framework REQUIRED"
|
||||
# Ensembles-based Reservoir Tools (ERT)
|
||||
"ERT REQUIRED"
|
||||
# Look for MPI support
|
||||
"opm-common REQUIRED"
|
||||
# Parser library for ECL-type simulation models
|
||||
"opm-parser REQUIRED"
|
||||
)
|
||||
36
cmake/Modules/opm-simulators-prereqs.cmake
Normal file
36
cmake/Modules/opm-simulators-prereqs.cmake
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- 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-simulators_CONFIG_VAR
|
||||
HAVE_OPM_GRID
|
||||
HAVE_PTHREAD
|
||||
HAVE_EWOMS
|
||||
DUNE_ISTL_VERSION_MAJOR
|
||||
DUNE_ISTL_VERSION_MINOR
|
||||
DUNE_ISTL_VERSION_REVISION
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-simulators_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"
|
||||
# DUNE prerequisites
|
||||
"dune-common REQUIRED;
|
||||
dune-istl REQUIRED"
|
||||
"ERTPython"
|
||||
# OPM dependency
|
||||
"opm-common REQUIRED;
|
||||
opm-parser REQUIRED;
|
||||
opm-grid REQUIRED;
|
||||
opm-core REQUIRED;
|
||||
opm-output REQUIRED;
|
||||
ewoms REQUIRED"
|
||||
# Eigen
|
||||
"Eigen3 3.2.0"
|
||||
)
|
||||
32
cmake/Modules/opm-upscaling-prereqs.cmake
Normal file
32
cmake/Modules/opm-upscaling-prereqs.cmake
Normal file
@@ -0,0 +1,32 @@
|
||||
# -*- 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-upscaling_CONFIG_VAR
|
||||
HAVE_SUPERLU
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-upscaling_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 iostreams unit_test_framework REQUIRED"
|
||||
# matrix library
|
||||
"BLAS REQUIRED"
|
||||
"LAPACK REQUIRED"
|
||||
# solver
|
||||
"SuperLU"
|
||||
# DUNE dependency
|
||||
"dune-common REQUIRED;
|
||||
dune-istl REQUIRED;
|
||||
dune-geometry REQUIRED;
|
||||
dune-grid REQUIRED;
|
||||
opm-common REQUIRED;
|
||||
opm-grid REQUIRED;
|
||||
opm-core REQUIRED;
|
||||
opm-output REQUIRED"
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script performs a single analysis using clang-check
|
||||
# It is used by the 'make test' target in the buildsystems
|
||||
# Usually you should use 'ctest -C clang-check' rather than calling this script directly
|
||||
#
|
||||
# Parameters: $1 = Application binary
|
||||
# $2 = Source file to process
|
||||
|
||||
clangcheck_cmd=$1
|
||||
source_file=$2
|
||||
|
||||
tmpfil=`mktemp`
|
||||
$clangcheck_cmd -p @CMAKE_BINARY_DIR@ -analyze $source_file &> $tmpfil
|
||||
cat $tmpfil
|
||||
if test -s $tmpfil
|
||||
then
|
||||
rm $tmpfil
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm $tmpfil
|
||||
exit 0
|
||||
553
cmake/Scripts/configure
vendored
Executable file
553
cmake/Scripts/configure
vendored
Executable file
@@ -0,0 +1,553 @@
|
||||
#!/bin/bash
|
||||
|
||||
# where is the source tree located by default relative to here
|
||||
srcdir=$(dirname "$(dirname "$(dirname "$0")")")
|
||||
|
||||
# display help text
|
||||
usage () {
|
||||
cat <<EOF
|
||||
Installation directories:
|
||||
--prefix=PREFIX install architecture-independent files in PREFIX
|
||||
[/usr/local]. Note: set DESTDIR=PATH when doing
|
||||
\`make install' to install to a different sysroot.
|
||||
|
||||
Optional Features:
|
||||
--disable-FEATURE do not include FEATURE
|
||||
--disable-gxx11check do not try flag -std=c++11 to enable C++11 features
|
||||
--enable-shared build a shared library [default=yes]
|
||||
--enable-static build a static library [default=no]. Note: only one
|
||||
of the options shared and static may be built.
|
||||
--enable-debug build a non-optimized version of the library
|
||||
[default=no]
|
||||
--disable-runpath do not use RUNPATH in installed library [default=yes]
|
||||
--enable-lto use whole program optimization [default=no]
|
||||
--enable-strip-debug separate the executable code and the debugging symbols [default=no]
|
||||
--disable-tests do not compile and enable unit tests [default=yes]
|
||||
--disable-examples do not compile example programs [default=yes]
|
||||
--disable-pch do not use precompiled headers (if buggy compiler)
|
||||
--disable-silent-rules print every compilation statement as executed
|
||||
--enable-system-debug put .debug files in global GDB debug dir
|
||||
[default=yes if prefix=/usr, no otherwise]
|
||||
--enable-parallel process in parallel using MPI [default=no]
|
||||
--enable-openmp activate experimental support for OpenMP
|
||||
--disable-option-checking ignore unrecognized --enable/--with options
|
||||
--enable-underscoring assume Fortran routines have _ suffix [default=no]
|
||||
--enable-ninja use Ninja build generator [default=no]
|
||||
(automatically implies --enable-underscoring)
|
||||
--config-cache Reuse build configuration cache from a previous run
|
||||
|
||||
Optional Packages:
|
||||
--with-ug=PATH use the UG libraries from a specified location
|
||||
--with-alugrid=PATH use the ALUGrid library from a specified location
|
||||
--with-metis=PATH use the METIS graph partitioning library from a specified location
|
||||
--with-boost=PATH use Boost library from a specified location
|
||||
--with-dune=PATH specify parent of all DUNE modules not specified
|
||||
--with-dune-MODULE=PATH use given DUNE module from a specified location
|
||||
--with-opm=PATH specify parent of all OPM modules not specified
|
||||
--with-opm-MODULE=PATH use given OPM module from a specified location
|
||||
--with-superlu=PATH user defined path to SuperLU library
|
||||
--with-umfpack=PATH use UMFPACK/SuiteSparse from a specified location
|
||||
--with-ert=PATH Use ERT libraries
|
||||
--with-zoltan=PATH Use ZOLTAN libraries
|
||||
--with-tinyxml=PATH use TinyXML library from a specified location
|
||||
(Note: if not found, then a bundled library will
|
||||
be used)
|
||||
--with-cmake=PROGRAM use this program instead of \`cmake' to configure
|
||||
--with-buildname=TEXT description passed to the CDash configuration
|
||||
--with-site=TEXT site passed to the CDash configuration
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
CFLAGS C compiler flags
|
||||
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
||||
nonstandard directory <lib dir>
|
||||
LIBS libraries to pass to the linker, e.g. -l<library>
|
||||
CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
|
||||
you have headers in a nonstandard directory <include dir>
|
||||
CPP C preprocessor
|
||||
CXX C++ compiler command
|
||||
CXXFLAGS C++ compiler flags
|
||||
CXXCPP C++ preprocessor
|
||||
F77 Fortran 77 compiler command
|
||||
FFLAGS Fortran 77 compiler flags
|
||||
FC Fortran compiler command
|
||||
FCFLAGS Fortran compiler flags
|
||||
CMAKE_COMMAND Executable used to run cmake scripts
|
||||
|
||||
Use these variables to override the choices made by \`configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
EOF
|
||||
}
|
||||
|
||||
# report an error regarding the arguments
|
||||
invalid_arg () {
|
||||
cat <<EOF
|
||||
configure: error: unrecognized option: \`$1'
|
||||
Try \`$0 --help' for more information
|
||||
EOF
|
||||
}
|
||||
|
||||
# notify the user that this argument is not known
|
||||
unknown_arg () {
|
||||
cat <<EOF
|
||||
configure: warning: unrecognized option: \`$1'
|
||||
EOF
|
||||
}
|
||||
|
||||
# warn only if option checking is enabled
|
||||
invalid_opt () {
|
||||
if [ "${option_check}" = "yes" ]; then
|
||||
unknown_arg "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# default values
|
||||
prefix=/usr/local
|
||||
#c_compiler=" -DCMAKE_C_COMPILER=cc"
|
||||
c_compiler=
|
||||
c_opts=
|
||||
#cxx_compiler=" -DCMAKE_CXX_COMPILER=c++"
|
||||
cxx_compiler=
|
||||
cxx_opts=
|
||||
#fort_compiler=" -DCMAKE_Fortran_COMPILER=fc"
|
||||
fort_compiler=
|
||||
fort_opts=
|
||||
#buildtype=" -DCMAKE_BUILD_TYPE=Debug"
|
||||
buildtype=
|
||||
#pch_use=" -DPRECOMPILE_HEADERS:BOOL=ON"
|
||||
pch_use=
|
||||
#use_openmp=" -DUSE_OPENMP=OFF"
|
||||
use_openmp=
|
||||
use_mpi=
|
||||
#silent_rules=" -DCMAKE_VERBOSE_MAKEFILE=OFF"
|
||||
silent_rules=
|
||||
#debug_loc=" -DSYSTEM_DEBUG=OFF"
|
||||
debug_loc=
|
||||
#use_lto=" -DWHOLE_PROG_OPTIM=OFF"
|
||||
use_lto=
|
||||
#strip_debug=" -DSTRIP_DEBUGGING_SYMBOLS=OFF"
|
||||
strip_debug=
|
||||
#use_runpath=" -DUSE_RUNPATH=OFF"
|
||||
use_runpath=
|
||||
#use_tests=" -DBUILD_TESTING=ON"
|
||||
use_tests=
|
||||
#use_samples=" -DBUILD_EXAMPLES=ON"
|
||||
use_samples=
|
||||
#use_ninja="-G\"Unix Makefiles\" "
|
||||
use_ninja=
|
||||
#use_underscoring=" -DUSE_UNDERSCORING=OFF"
|
||||
use_underscoring=
|
||||
# boost_root=""
|
||||
boost_root=
|
||||
boost_libdir=
|
||||
boost_opts=
|
||||
# configuration that is passed on to CTest/CDash
|
||||
buildname=
|
||||
site=
|
||||
# if set, this prevents the previous CMake cache from being deleted
|
||||
config_cache=
|
||||
|
||||
# default is to warn for unknown options, but this can be disabled
|
||||
option_check=yes
|
||||
|
||||
# this variable will get feature options
|
||||
FEATURES=
|
||||
|
||||
# this array will get all variable assignments from command-line
|
||||
VARS=()
|
||||
|
||||
# command that launches cmake; look for 2.8 if available
|
||||
if [ "${CMAKE_COMMAND}" = "" ]; then
|
||||
if [ -x "$(command -v cmake28)" ]; then
|
||||
CMAKE_COMMAND=cmake28
|
||||
else
|
||||
CMAKE_COMMAND=cmake
|
||||
fi
|
||||
fi
|
||||
|
||||
# helper routine
|
||||
uppercase () {
|
||||
echo "$@" | tr "a-z-" "A-Z_"
|
||||
}
|
||||
|
||||
for OPT in "$@"; do
|
||||
case "$OPT" in
|
||||
--*)
|
||||
OPTARG=${OPT#--}
|
||||
# OPTARG now contains everything after double dashes
|
||||
case "${OPTARG}" in
|
||||
config-cache|cache-file=*)
|
||||
# prevent the previous CMake cache from being deleted. The
|
||||
# second option is only here for Dune/autotools compatibility
|
||||
config_cache="1"
|
||||
;;
|
||||
src-dir=*)
|
||||
# allow the user to use these build macros for another
|
||||
# project (so source-dir is not relative to us)
|
||||
srcdir=${OPTARG#*=}
|
||||
;;
|
||||
prefix=*)
|
||||
# remove prefix consisting of everything up to equal sign
|
||||
prefix=${OPTARG#*=}
|
||||
;;
|
||||
help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
with-*)
|
||||
# get the name of the package; everything before equal sign
|
||||
pkgname=${OPTARG%=*}
|
||||
pkgname=${pkgname#with-}
|
||||
# get the location of the package; everyhing after equal sign
|
||||
test -n "${OPTARG#with-${pkgname}}" && pkgloc=${OPTARG#*=} || pkgloc=""
|
||||
# the parameter to this option is an executable program, so
|
||||
# skip the directory test in that case. if we match any of
|
||||
# these special options, then stop further processing (the
|
||||
# argument is not a directory anyway)
|
||||
case "${pkgname}" in
|
||||
cmake)
|
||||
CMAKE_COMMAND="${pkgloc}"
|
||||
continue
|
||||
;;
|
||||
buildname)
|
||||
buildname=" -DBUILDNAME=\"${pkgloc}\""
|
||||
continue
|
||||
;;
|
||||
site)
|
||||
site=" -DSITE=\"${pkgloc}\""
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
# tilde expansion; quote safely before running eval on it
|
||||
eval pkgloc=$(printf "%q" "${pkgloc}")
|
||||
# expand to full path since CMake changes to source directory (!)
|
||||
# this also normalize the path name wrt. not having a trailing slash
|
||||
test -d "${pkgloc}" && pkgloc=$(sh -c "cd \"${pkgloc}\"; pwd")
|
||||
# special aliases
|
||||
case "${pkgname}" in
|
||||
umfpack)
|
||||
pkgname="SuiteSparse"
|
||||
;;
|
||||
tinyxml)
|
||||
pkgname="TinyXML"
|
||||
;;
|
||||
esac
|
||||
# packages need different suffix for their root (sic)
|
||||
case "${pkgname}" in
|
||||
pch)
|
||||
pch_use=" -DPRECOMPILE_HEADERS:BOOL=ON"
|
||||
rootvar=""
|
||||
;;
|
||||
mpi |\
|
||||
mpi-prefix)
|
||||
# specifying path implies use of package
|
||||
use_mpi=" -DUSE_MPI=ON"
|
||||
# only set prefix if specified, i.e. setting doubles as flag
|
||||
test -n "${pkgloc}" && rootvar="_MPI_PREFIX_PATH" || rootvar=""
|
||||
;;
|
||||
boost)
|
||||
# special handling of this package, see further below
|
||||
boost_root="${pkgloc}"
|
||||
rootvar=""
|
||||
;;
|
||||
boost-libdir)
|
||||
boost_libdir="${pkgloc}"
|
||||
rootvar=""
|
||||
;;
|
||||
alugrid |\
|
||||
eigen3 |\
|
||||
ert |\
|
||||
metis |\
|
||||
superlu |\
|
||||
SuiteSparse |\
|
||||
TinyXML |\
|
||||
ug |\
|
||||
opm |\
|
||||
opm-* |\
|
||||
dune |\
|
||||
dune-* |\
|
||||
zoltan |\
|
||||
zlib)
|
||||
rootvar="$(uppercase ${pkgname})_ROOT"
|
||||
rootvar="${rootvar/-/_}"
|
||||
;;
|
||||
*)
|
||||
invalid_opt --with-${pkgname}
|
||||
rootvar=""
|
||||
;;
|
||||
esac
|
||||
# add this to the list of existing features
|
||||
test -n "${rootvar}" && \
|
||||
FEATURES="${FEATURES} \"-D${rootvar}=${pkgloc}\""
|
||||
;;
|
||||
without-* | \
|
||||
disable-*)
|
||||
# get the name of the package
|
||||
pkgname=$OPTARG
|
||||
pkgname=${pkgname#disable-}
|
||||
pkgname=${pkgname#without-}
|
||||
# casing is of course different
|
||||
case "${pkgname}" in
|
||||
option-checking)
|
||||
option_check=no
|
||||
# special flag: don't disable any particular package
|
||||
pkgname=""
|
||||
;;
|
||||
debug)
|
||||
buildtype=" -DCMAKE_BUILD_TYPE=Release"
|
||||
# special flag: don't disable any particular package
|
||||
pkgname=""
|
||||
;;
|
||||
pch)
|
||||
pch_use=" -DPRECOMPILE_HEADERS:BOOL=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
runpath)
|
||||
use_runpath=" -DUSE_RUNPATH=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
silent-rules)
|
||||
silent_rules=" -DCMAKE_VERBOSE_MAKEFILE=ON"
|
||||
pkgname=""
|
||||
;;
|
||||
system-debug)
|
||||
debug_loc=" -DSYSTEM_DEBUG=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
wpo |\
|
||||
lto )
|
||||
use_lto=" -DWHOLE_PROG_OPTIM=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
strip-debug )
|
||||
strip_debug=" -DSTRIP_DEBUGGING_SYMBOLS=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
openmp)
|
||||
use_openmp=" -DUSE_OPENMP=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
mpi | \
|
||||
parallel)
|
||||
use_mpi=" -DUSE_MPI=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
tests)
|
||||
use_tests=" -DBUILD_TESTING=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
examples)
|
||||
use_samples=" -DBUILD_EXAMPLES=OFF"
|
||||
pkgname=""
|
||||
;;
|
||||
ninja)
|
||||
# just for symmetry with the --enable-ninja option
|
||||
use_ninja=""
|
||||
pkgname=""
|
||||
;;
|
||||
ert |\
|
||||
superlu)
|
||||
pkgname="$(uppercase ${pkgname})"
|
||||
;;
|
||||
openmp)
|
||||
pkgname="OpenMP"
|
||||
;;
|
||||
gxx11check)
|
||||
pkgname="CXX11Features"
|
||||
;;
|
||||
umfpack)
|
||||
pkgname="SuiteSparse"
|
||||
;;
|
||||
tinyxml)
|
||||
pkgname="TinyXML"
|
||||
;;
|
||||
*)
|
||||
invalid_opt --disable-${pkgname}
|
||||
pkgname=""
|
||||
;;
|
||||
esac
|
||||
# only disable packages if the flag refers to a proper one
|
||||
test -n "${pkgname}" && \
|
||||
FEATURES="${FEATURES} -DCMAKE_DISABLE_FIND_PACKAGE_${pkgname}=TRUE"
|
||||
;;
|
||||
enable-*)
|
||||
# what kind of library are we building; shared or static?
|
||||
kind=${OPTARG#enable-}
|
||||
case "${kind}" in
|
||||
system-debug)
|
||||
debug_loc=" -DSYSTEM_DEBUG=ON"
|
||||
# special flag; don't set shared/static
|
||||
shared=""
|
||||
;;
|
||||
openmp)
|
||||
use_openmp=" -DUSE_OPENMP=ON"
|
||||
# special flag; don't set shared/static
|
||||
shared=""
|
||||
;;
|
||||
mpi | \
|
||||
parallel)
|
||||
use_mpi=" -DUSE_MPI=ON"
|
||||
# special flag; don't set shared/static
|
||||
shared=""
|
||||
;;
|
||||
debug)
|
||||
buildtype=" -DCMAKE_BUILD_TYPE=Debug"
|
||||
shared=""
|
||||
;;
|
||||
pch)
|
||||
pch_use=" -DPRECOMPILE_HEADERS:BOOL=ON"
|
||||
shared=""
|
||||
;;
|
||||
runpath)
|
||||
use_runpath=" -DUSE_RUNPATH=ON"
|
||||
shared=""
|
||||
;;
|
||||
lto)
|
||||
use_lto=" -DWHOLE_PROG_OPTIM=ON"
|
||||
shared=""
|
||||
;;
|
||||
strip-debug )
|
||||
strip_debug=" -DSTRIP_DEBUGGING_SYMBOLS=ON"
|
||||
pkgname=""
|
||||
;;
|
||||
tests)
|
||||
use_tests=" -DBUILD_TESTING=ON"
|
||||
pkgname=""
|
||||
;;
|
||||
examples)
|
||||
use_samples=" -DBUILD_EXAMPLES=ON"
|
||||
pkgname=""
|
||||
;;
|
||||
underscoring)
|
||||
use_underscoring=" -DUSE_UNDERSCORING=ON"
|
||||
pkgname=""
|
||||
;;
|
||||
ninja)
|
||||
# Ninja doesn't support using the Fortran compiler, so
|
||||
# we'll have to resort to making this assumption
|
||||
use_underscoring=" -DUSE_UNDERSCORING=ON"
|
||||
use_ninja="-GNinja "
|
||||
pkgname=""
|
||||
;;
|
||||
# this flag is just for compatibility with the deprecation
|
||||
# flag in DUNE, so we can build without warnings
|
||||
fieldvector-size-is-method)
|
||||
shared=""
|
||||
;;
|
||||
shared)
|
||||
shared="ON"
|
||||
;;
|
||||
static)
|
||||
shared="OFF"
|
||||
;;
|
||||
*)
|
||||
invalid_opt "--enable-${kind}"
|
||||
shared=""
|
||||
;;
|
||||
esac
|
||||
test -n "${shared}" && \
|
||||
FEATURES="${FEATURES} -DBUILD_SHARED_LIBS:BOOL=${shared}"
|
||||
# once we have added this, reset so we don't add again for next opt
|
||||
shared=""
|
||||
;;
|
||||
*)
|
||||
# remove everything *after* the equal sign
|
||||
arg=${OPTARG%=*}
|
||||
invalid_arg "--$arg"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
[A-Za-z0-9_]*=*)
|
||||
# collect for further processing later
|
||||
VARS+=("$OPT")
|
||||
;;
|
||||
*)
|
||||
invalid_arg "$OPT"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# remove all arguments processed by getopts
|
||||
shift $((OPTIND-1))
|
||||
|
||||
# special handling of Boost: if --with-boost-libdir has been used,
|
||||
# then the --with-boost turns into specifying the header directory
|
||||
# and not the search root. this mirrors the functionality in the
|
||||
# Autotools ax_boost_base.m4. necessary because FindBoost in CMake
|
||||
# uses two different variables if you want to specify them separately
|
||||
if [ -n "${boost_libdir}" ]; then
|
||||
boost_opts=" -DBOOST_LIBRARYDIR=\"${boost_libdir}\""
|
||||
if [ -n "${boost_root}" ]; then
|
||||
boost_opts="${boost_opts} -DBOOST_INCLUDEDIR=\"${boost_root}\""
|
||||
fi
|
||||
else
|
||||
if [ -n "${boost_root}" ]; then
|
||||
boost_opts=" -DBOOST_ROOT=\"${boost_root}\""
|
||||
else
|
||||
boost_opts=""
|
||||
fi
|
||||
fi
|
||||
|
||||
# notice the usage of a quoted array: each element will be returned
|
||||
# even with spaces.
|
||||
for a in "${VARS[@]}"; do
|
||||
case "$a" in
|
||||
ACLOCAL_*=*)
|
||||
# remove Autotools-specific variables.
|
||||
;;
|
||||
CC=*)
|
||||
# special processing for compiler options
|
||||
a=${a#CC=}
|
||||
[ -x "$(command -v "$a")" ] && a=$(command -v "$a")
|
||||
c_compiler=" -DCMAKE_C_COMPILER=\"${a/\"/\\\"}\""
|
||||
;;
|
||||
CXX=*)
|
||||
a=${a#CXX=}
|
||||
[ -x "$(command -v "$a")" ] && a=$(command -v "$a")
|
||||
cxx_compiler=" -DCMAKE_CXX_COMPILER=\"${a/\"/\\\"}\""
|
||||
;;
|
||||
CFLAGS=*)
|
||||
a=${a#CFLAGS=}
|
||||
c_opts=" -DCMAKE_BUILD_TYPE=Custom -DCMAKE_C_FLAGS=\"${a/\"/\\\"}\""
|
||||
;;
|
||||
CXXFLAGS=*)
|
||||
a=${a#CXXFLAGS=}
|
||||
cxx_opts=" -DCMAKE_BUILD_TYPE=Custom -DCMAKE_CXX_FLAGS=\"${a/\"/\\\"}\""
|
||||
;;
|
||||
FC=*)
|
||||
a=${a#FC=}
|
||||
[ -x "$(command -v "$a")" ] && a=$(command -v "$a")
|
||||
fort_compiler=" -DCMAKE_Fortran_COMPILER=\"${a/\"/\\\"}\""
|
||||
;;
|
||||
FFLAGS=*)
|
||||
a=${a#FFLAGS=}
|
||||
fort_opts=" -DCMAKE_BUILD_TYPE=Custom -DCMAKE_Fortran_FLAGS=\"${a/\"/\\\"}\""
|
||||
;;
|
||||
*)
|
||||
ENVVARS="$ENVVARS \"${a/\"/\\\"}\""
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# only wrap in env command if any variable were actually passed
|
||||
[ -n "${ENVVARS}" ] && ENVVARS="env ${ENVVARS} "
|
||||
|
||||
# delete the previous 'CMakeFiles' directory. this prevents an endless
|
||||
# loop if variables that require a full regeneration of the cache are
|
||||
# set (most notably 'CXX' and 'CXX_FLAGS').
|
||||
# For more details, see http://www.cmake.org/Bug/view.php?id=14119
|
||||
if test "$config_cache" = ""; then
|
||||
echo "--- deleting previous CMake files ---"
|
||||
rm -rf CMakeFiles
|
||||
rm -f CMakeCache.txt
|
||||
elif test "$c_compiler$c_opts$cxx_compiler$cxx_opts$fort_compiler$fort_opts" != ""; then
|
||||
echo "--- WARNING '--config-cache' option specified but a compiler was set"
|
||||
echo "--- from the command line. This may lead to an infinite loop!"
|
||||
fi
|
||||
|
||||
# pass everything on to CMake
|
||||
CMDLINE="${ENVVARS}${CMAKE_COMMAND} \"${srcdir}\" ${use_ninja}\"-DCMAKE_INSTALL_PREFIX=$prefix\" -DSIBLING_SEARCH=OFF${buildtype}${pch_use}${silent_rules}${debug_loc}${use_openmp}${use_mpi}${use_lto}${strip_debug}${use_runpath}${use_tests}${use_samples}${use_underscoring}${c_compiler}${c_opts}${cxx_compiler}${cxx_opts}${fort_compiler}${fort_opts}${boost_opts}${buildname}${site} ${FEATURES}"
|
||||
echo --- calling CMake ---
|
||||
echo "${CMDLINE}"
|
||||
eval exec "${CMDLINE}"
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script performs a single analysis using cppcheck
|
||||
# It is used by the 'make test' target in the buildsystems
|
||||
# Usually you should use 'ctest -C cppcheck' rather than calling this script directly
|
||||
#
|
||||
# Parameters: $1 = Application binary
|
||||
# $2 = Source file to process
|
||||
# $3..$N = include path parameters (-I dir1 -I dir2 ...)
|
||||
|
||||
cppcheck_cmd=$1
|
||||
source_file=$2
|
||||
shift 2
|
||||
|
||||
tmpfil=`mktemp`
|
||||
$cppcheck_cmd $@ --enable=all --suppress=unusedFunction $source_file &> $tmpfil
|
||||
nmatch=`cat $tmpfil | grep "\[.*\]" | wc -l`
|
||||
nsys=`cat $tmpfil | grep "\[/usr.*\]" | wc -l`
|
||||
nnone=`cat $tmpfil | grep "\[\\*]" | wc -l`
|
||||
ndef=`cat $tmpfil | grep "\[.*Too many #ifdef" | wc -l`
|
||||
let "nval=$nmatch-$nsys-$nnone-$ndef"
|
||||
if test $nval -gt 0
|
||||
then
|
||||
cat $tmpfil
|
||||
rm $tmpfil
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm $tmpfil
|
||||
exit 0
|
||||
@@ -19,92 +19,51 @@
|
||||
|
||||
# <http://www.vtk.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file>
|
||||
|
||||
# Prevent multiple inclusions
|
||||
if(NOT @opm-project_NAME@_FOUND)
|
||||
# propagate these properties from one build system to the other
|
||||
set (@opm-project_NAME@_PREFIX "@DUNE_PREFIX@")
|
||||
set (@opm-project_NAME@_VERSION "@opm-project_VERSION@")
|
||||
set (@opm-project_NAME@_DEFINITIONS "@opm-project_DEFINITIONS@")
|
||||
set (@opm-project_NAME@_INCLUDE_DIRS "@opm-project_INCLUDE_DIRS@")
|
||||
set (@opm-project_NAME@_LIBRARY_DIRS "@opm-project_LIBRARY_DIRS@" "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@")
|
||||
set (@opm-project_NAME@_LINKER_FLAGS "@opm-project_LINKER_FLAGS@")
|
||||
set (@opm-project_NAME@_CONFIG_VARS "@opm-project_CONFIG_VARS@")
|
||||
# propagate these properties from one build system to the other
|
||||
set (@opm-project_NAME@_VERSION "@opm-project_VERSION@")
|
||||
set (@opm-project_NAME@_DEFINITIONS "@opm-project_DEFINITIONS@")
|
||||
set (@opm-project_NAME@_INCLUDE_DIRS "@opm-project_INCLUDE_DIRS@")
|
||||
set (@opm-project_NAME@_LIBRARY_DIRS "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@")
|
||||
set (@opm-project_NAME@_LINKER_FLAGS "@opm-project_LINKER_FLAGS@")
|
||||
set (@opm-project_NAME@_CONFIG_VARS "@opm-project_CONFIG_VARS@")
|
||||
|
||||
# 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@")
|
||||
# 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@")
|
||||
mark_as_advanced (@opm-project_NAME@_LIBRARY)
|
||||
|
||||
# The purpose of this string replacement operation is to enable use of the
|
||||
# generated opm-project-config.cmake file also in the situation where 'make
|
||||
# install' has been invoked with the DESTDIR option:
|
||||
#
|
||||
# opm-common/build> cmake .. -DCMAKE_INSTALL_PREFIX=/real/prefix
|
||||
# opm-common/budil> make install DESTDIR=/tmp/prefix
|
||||
#
|
||||
# downstream/build> cmake .. -DDEST_PREFIX=/tmp/prefix -DCMAKE_PREFIX_PATH=/tmp/prefix
|
||||
# downstream/build> make install
|
||||
#
|
||||
# That way the downstream dependency can still use find_package( opm-common )
|
||||
# even though the opm-common-config.cmake file is not internally consistent
|
||||
# with it's own location in the filesystem.
|
||||
# not all projects have targets; conditionally add this part
|
||||
if (NOT "@opm-project_TARGET@" STREQUAL "")
|
||||
# add the library as a target, so that other things in the project including
|
||||
# this file may depend on it and get rebuild if this library changes.
|
||||
add_library (@opm-project_TARGET@ UNKNOWN IMPORTED)
|
||||
set_property (TARGET @opm-project_TARGET@ PROPERTY IMPORTED_LOCATION "${@opm-project_NAME@_LIBRARY}")
|
||||
endif (NOT "@opm-project_TARGET@" STREQUAL "")
|
||||
|
||||
if(DEST_PREFIX)
|
||||
set(DEST_PREFIX "${DEST_PREFIX}${@opm-project_NAME@_PREFIX}")
|
||||
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}")
|
||||
endif()
|
||||
# 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)
|
||||
set (CMAKE_C_FLAG "@C_STD99_FLAGS@ ${CMAKE_C_FLAGS}")
|
||||
|
||||
set (HAVE_@opm-project_NAME_UC@ 1)
|
||||
mark_as_advanced (@opm-project_NAME@_LIBRARY)
|
||||
|
||||
# not all projects have targets; conditionally add this part
|
||||
if (NOT "@opm-project_TARGET@" STREQUAL "")
|
||||
# add the library as a target, so that other things in the project including
|
||||
# this file may depend on it and get rebuild if this library changes.
|
||||
if(NOT TARGET @opm-project_TARGET@)
|
||||
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
include("${_dir}/@opm-project_NAME@-targets.cmake")
|
||||
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}")
|
||||
# build with OpenMP if that was found
|
||||
if (NOT "@OpenMP_C_FLAGS@" STREQUAL "")
|
||||
string (REPLACE "@OpenMP_C_FLAGS@" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string (STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS)
|
||||
set (CMAKE_C_FLAG "@C_STD99_FLAGS@ ${CMAKE_C_FLAGS}")
|
||||
set (CMAKE_C_FLAG "@OpenMP_C_FLAGS@ ${CMAKE_C_FLAGS}")
|
||||
endif (NOT "@OpenMP_C_FLAGS@" STREQUAL "")
|
||||
if (NOT "@OpenMP_CXX_FLAGS@" STREQUAL "")
|
||||
string (REPLACE "@OpenMP_CXX_FLAGS@" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string (STRIP "${CMAKE_CXX_FLAGS}" CMAKE_CXX_FLAGS)
|
||||
set (CMAKE_C_FLAG "@OpenMP_CXX_FLAGS@ ${CMAKE_CXX_FLAGS}")
|
||||
endif (NOT "@OpenMP_CXX_FLAGS@" STREQUAL "")
|
||||
|
||||
# build with OpenMP if that was found
|
||||
if (NOT "@OpenMP_C_FLAGS@" STREQUAL "")
|
||||
string (REPLACE "@OpenMP_C_FLAGS@" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string (STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS)
|
||||
set (CMAKE_C_FLAG "@OpenMP_C_FLAGS@ ${CMAKE_C_FLAGS}")
|
||||
endif (NOT "@OpenMP_C_FLAGS@" STREQUAL "")
|
||||
if (NOT "@OpenMP_CXX_FLAGS@" STREQUAL "")
|
||||
string (REPLACE "@OpenMP_CXX_FLAGS@" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string (STRIP "${CMAKE_CXX_FLAGS}" CMAKE_CXX_FLAGS)
|
||||
set (CMAKE_C_FLAG "@OpenMP_CXX_FLAGS@ ${CMAKE_CXX_FLAGS}")
|
||||
endif (NOT "@OpenMP_CXX_FLAGS@" STREQUAL "")
|
||||
# this is the contents of config.h as far as our probes can tell:
|
||||
|
||||
# this is the contents of config.h as far as our probes can tell:
|
||||
|
||||
|
||||
# The settings in this block do not mix well with the DEST_PREFIX
|
||||
# setting.
|
||||
if (NOT DEST_PREFIX)
|
||||
# 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(@opm-project_NAME@-prereqs)
|
||||
endif()
|
||||
endif()
|
||||
# extra code
|
||||
@OPM_PROJECT_EXTRA_CODE@
|
||||
|
||||
42
configure
vendored
Executable file
42
configure
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
# this file is supposed to be located in the source directory
|
||||
src_dir=$(dirname $0)
|
||||
|
||||
# scan the arguments and set this if build macros could be specified
|
||||
mod_dir=
|
||||
for OPT in "$@"; do
|
||||
case "$OPT" in
|
||||
--with-opm-common=*)
|
||||
# remove everything before equal sign and assign the rest
|
||||
mod_dir=${OPT#*=}
|
||||
# tilde expansion; note that doing eval may have side effects
|
||||
mod_dir=$(eval echo $mod_dir)
|
||||
# absolute path
|
||||
[ -d "$mod_dir" ] && mod_dir=$(cd $mod_dir ; pwd)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# special work around the fact that dunecontrol does not specify
|
||||
# --with-$MODULE for the module it attempts to build
|
||||
ADDITIONAL_PARAMS=""
|
||||
if test -z "$mod_dir"; then
|
||||
ADDITIONAL_PARAMS="--with-opm-common=\"$(pwd)\""
|
||||
fi
|
||||
|
||||
# if it isn't specified, the look around in other known places
|
||||
conf_file=cmake/Scripts/configure
|
||||
if [ -z "$mod_dir" ]; then
|
||||
if [ -r "$src_dir/$conf_file" ]; then
|
||||
mod_dir="$src_dir"
|
||||
fi
|
||||
fi
|
||||
|
||||
# terminate with error message here if the module directory is not found
|
||||
if [ ! -r "$mod_dir/$conf_file" ]; then
|
||||
echo Build macros not located in \"$mod_dir\", use --with-opm-common= to specify! 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# forward to the corresponding script in the cmake/Scripts/ directory
|
||||
exec "$mod_dir/$conf_file" --src-dir="$src_dir" "$@" $ADDITIONAL_PARAMS
|
||||
2
debian/changelog
vendored
2
debian/changelog
vendored
@@ -1,4 +1,4 @@
|
||||
opm-common (2018.10-rc1-1~xenial) xenial; urgency=medium
|
||||
opm-common (2017.04-rfinal-1~xenial) xenial; urgency=medium
|
||||
|
||||
* New release
|
||||
|
||||
|
||||
4
debian/control
vendored
4
debian/control
vendored
@@ -4,9 +4,7 @@ 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
|
||||
ghostscript, libboost-system-dev, libboost-test-dev
|
||||
Standards-Version: 3.9.2
|
||||
Section: libs
|
||||
Homepage: http://opm-project.org
|
||||
|
||||
2
debian/rules
vendored
2
debian/rules
vendored
@@ -20,7 +20,7 @@ override_dh_auto_build:
|
||||
|
||||
# consider using -DUSE_VERSIONED_DIR=ON if backporting
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSTRIP_DEBUGGING_SYMBOLS=ON -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_DOCDIR=share/doc/libopm-common1 -DWHOLE_PROG_OPTIM=ON -DUSE_RUNPATH=OFF -DWITH_NATIVE=OFF
|
||||
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
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install -- install-html
|
||||
|
||||
@@ -1,336 +0,0 @@
|
||||
Keywords is the most important aspect of the ECLIPSE datafile
|
||||
parser.
|
||||
|
||||
1. The structure of a keyword
|
||||
-----------------------------
|
||||
|
||||
A keyword is the fundamental unit when parsing. Keywords are added to
|
||||
the parser by schema definitions. The schema definition of the keywords
|
||||
are given as Json files under the opm/share/keywords directory. Json
|
||||
can be thought of as a lean alternative to XML, you will find it described
|
||||
here: http://www.json.org/
|
||||
As part of the build process these keyword definitions are compiled
|
||||
to ParserKeyword instances.
|
||||
|
||||
|
||||
1.1 Starting a keyword
|
||||
----------------------
|
||||
The keywords are defined as follows:
|
||||
|
||||
1. The keyword should start in column 0; everything beyond character
|
||||
8 is ignored.
|
||||
|
||||
2. The keyword should start with a alphabet character, subsequent
|
||||
characters should be alphanumeric or in the set [-,_,+].
|
||||
|
||||
3. We think ECLIPSE is case insensitive.
|
||||
|
||||
This is cehcked by the static method:
|
||||
ParserKeyword::validDeckName(). An important part of the parsing of
|
||||
keywords is to detect when the keyword specification is complete. For
|
||||
most keywords we can detect that either by a terminating '/' or the
|
||||
keywords have a predefined size, but for some odd keywords we can not
|
||||
reliably detect the end-of-keyword condition and instead we terminate
|
||||
keyword1 when we find a string which corresponds to the start of a new
|
||||
keyword. Examples of such oddball keywords include: VFPPROD and
|
||||
VFPINJ.
|
||||
|
||||
|
||||
1.2 Records
|
||||
-----------
|
||||
|
||||
The data content of a keyword comes as a collection of
|
||||
records. Records are a collection of 'data', terminated by a '/'. Here
|
||||
are three examples of records:
|
||||
|
||||
'METRES' /
|
||||
|
||||
1 'OFF' 100 '*' 24.0 /
|
||||
|
||||
0.26 0.27 0.26 0.78
|
||||
0.82 0.66 0.27 0.78
|
||||
0.76 0.56 0.23 0.67 /
|
||||
|
||||
From these examples we see that:
|
||||
|
||||
1. One record can contain a mix of integer, float and string values.
|
||||
2. Records typically correspond to one line in the data-file, but
|
||||
that is purely convention; the records can be sprinkled with
|
||||
newlines.
|
||||
3. Each record is terminated with a '/'
|
||||
|
||||
|
||||
1.3 How many records in a keyword
|
||||
---------------------------------
|
||||
|
||||
One of the first structural elements which must be configured into the
|
||||
the parser keywords is the number of records in the different
|
||||
keywords, this is closely related to how the keyboard is
|
||||
terminated. Here comes some typical examples of keywords:
|
||||
|
||||
|
||||
GRID
|
||||
|
||||
|
||||
WCONHIST
|
||||
... /
|
||||
... /
|
||||
... /
|
||||
/
|
||||
|
||||
---\
|
||||
EQLDIMS |
|
||||
.... / |
|
||||
|
|
||||
EQUIL |
|
||||
.... / |
|
||||
.... / |
|
||||
---/
|
||||
|
||||
VFPPROD
|
||||
A .. /
|
||||
B... /
|
||||
.... /
|
||||
.... /
|
||||
|
||||
|
||||
PVGO
|
||||
/
|
||||
/
|
||||
|
||||
|
||||
In the list above here the GRID keyword has zero records, i.e. no data
|
||||
at all. The WCONHIST keyword has three records of data, the EQLDIMS
|
||||
keyword has one record, the EQUIL keyword has two records and finally
|
||||
the VFPPROD keyword has four records. The number of records, or how to
|
||||
infer it, must be configured with the "size" attribute in the JSON
|
||||
configuration. When it comes to the number of records and termination
|
||||
we currently have five different categories:
|
||||
|
||||
1. Keywords with a fixed number of records. Both the GRID keyword
|
||||
and the EQLDIMS keyword have a fixed number of records, zero and
|
||||
one respectively. These keywords are therefor not explicitly
|
||||
terminated in any way, and the "size" attribute has the numerical
|
||||
explicitly:
|
||||
|
||||
{"name" : "EQLDIMS" , "size" : 1 , ....}
|
||||
{"name" : "GRID" , "size" : 0, .... }
|
||||
|
||||
|
||||
2. Keywords with a variable number of records like the
|
||||
WCONHIST. Becase the number of records is not known in advance
|
||||
this keyword must be explicitly terminated with a '/'. This is
|
||||
the most common configuration and for keywords of this type it is
|
||||
not necessary to specify a size attribute at all:
|
||||
|
||||
{"name" : "WCONHIST" , .... }
|
||||
|
||||
|
||||
3. Keywords where the number of records is inferred from the content
|
||||
of another keyword; this is the case with EQUIL which reads the
|
||||
number of records from the xxx item of the EQLDIMS keyword. Since
|
||||
the number of records is known in advance (indirectly through the
|
||||
EQLDIMS keyword) the EQUIL keyword is not explicitly terminated
|
||||
with a '/'. In the json file this is specified with the "size"
|
||||
attribute being an object containing the name and item of keyword
|
||||
which should be consulted to infer the size; so for the EQUIL
|
||||
keyword the size attribute looks like:
|
||||
|
||||
{"name" : "EQUIL" ,
|
||||
"size" : {"keyword" : "EQLDIMS" , "item" : "NTEQUL"} , ...
|
||||
|
||||
When parsing the EQUIL keyword the parser will consult the
|
||||
already parsed content of the 'EQLDIMS' keyword (i.e. a
|
||||
DeckKeyword instance) and get the numerical value of the 'NTEQUL'
|
||||
item.
|
||||
|
||||
|
||||
4. For some keywords the number of records should be calculated
|
||||
run-time based based on the content of the first records in the
|
||||
keyword - this at least applies to VFPPROD and VFPINJ. Since the
|
||||
size of the keyword is deterministic - given the first few
|
||||
records - the keyword is not slash terminated.
|
||||
|
||||
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 unkown, and the keywords are terminated when the
|
||||
next valid keyword is found:
|
||||
|
||||
{"name" : "VFPPROD" , "size" : "UNKNOWN", ....
|
||||
|
||||
|
||||
|
||||
5. Tables PVTG and PVTO: The two tables PVTG and PVTO are special
|
||||
cased. The special casing should probably be removed, and the
|
||||
"size" : "UNKNOWN" could be used for these two keyword.
|
||||
|
||||
|
||||
|
||||
|
||||
1.4 The content of a record: items
|
||||
----------------------------------
|
||||
|
||||
A record consist of one or several items. An item can consist of one
|
||||
or several values from the record, for items with more than one value
|
||||
it is not possible to specify the exact number of values - the item
|
||||
will just consume the remaining values in the input stream. An item
|
||||
has a name, a data type and optionally a default value. For instance
|
||||
the WCONHIST keyword has the the following items specification:
|
||||
|
||||
"items":
|
||||
[{"name" : "WELL" , "value_type" : "STRING"},
|
||||
{"name" : "STATUS" , "value_type" : "STRING" , "default" : "OPEN"},
|
||||
{"name" : "CMODE" , "value_type" : "STRING"},
|
||||
{"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" : "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"}]}
|
||||
|
||||
Here we can see the following:
|
||||
|
||||
1. The items can be of types string, integer and float, the type is
|
||||
specified with the "value_type" attribute which must equal
|
||||
"STRING", "DOUBLE" or "INT".
|
||||
|
||||
2. You can optionally specify a default value, see the discussion of
|
||||
the parsing workflow below for the treatment of defaults.
|
||||
|
||||
3. For items of type double you can specify a dimension, see XXXX for
|
||||
the available dimensions. For quantities with a dimension the
|
||||
parser will convert to SI units, and the DeckDoubleItem class has
|
||||
a getSIDouble() and getRawDouble() method.
|
||||
|
||||
|
||||
Items consuming the rest of the record
|
||||
--------------------------------------
|
||||
|
||||
Most of the items will consume exactly one value from the input deck,
|
||||
but it is also possible that the last item consumes the remaining
|
||||
items in the input deck, these typically correspond to table keywords
|
||||
or lists of memnonics. In the input deck the PVTG keyword will
|
||||
typically appear like this:
|
||||
|
||||
PVTG
|
||||
200 0.15 0.15 10
|
||||
0.20 0.20 12
|
||||
0.25 0.20 15 /
|
||||
250 0.05 0.05 20
|
||||
0.15 0.10 40 /
|
||||
...
|
||||
|
||||
In the manual this is described as two tables with three columns, one
|
||||
with three rows and one with two rows. The leading values of 200 and
|
||||
250 are the pressure values where the two tables apply. The visual
|
||||
formatting in the deck, and also the written desciption in the manual,
|
||||
strongly hints at a table structure - however from a parsing point of
|
||||
view this corresponds to just two records of different length. Both
|
||||
records start with a pressure value, and then follows 3n consecutive
|
||||
values. The item configuration of PVTG looks like this:
|
||||
|
||||
"items" : [
|
||||
{"name":"GAS_PRESSURE", "value_type" : "DOUBLE", "dimension":"Pressure" },
|
||||
{"name":"DATA", "size_type" : "ALL" , "value_type":"DOUBLE" ,
|
||||
"dimension" : ["OilDissolutionFactor","OilDissolutionFactor","Viscosity"]}
|
||||
]
|
||||
|
||||
I.e. first we consume one value from the input deck and assign it to
|
||||
the GAS_PRESSURE item, then the DATA item has "size_type" : "ALL" -
|
||||
meaning that this item will consume the the rest of the values in the
|
||||
input record. Also observe that for the "DATA" item the dimension is a
|
||||
vector of three elements, when converting to SI the dimension applied
|
||||
to element i is given as:
|
||||
|
||||
dim[i] = dimension[i % 3]
|
||||
|
||||
In addition to tables the grid property keywords use items which
|
||||
consume the rest of the record. For instance the PORO keyword will
|
||||
typcially look like this in the input deck:
|
||||
|
||||
PORO
|
||||
0.14 0.15 0.0 0.10
|
||||
0.16 0.25 0.1 0.11
|
||||
0.14 0.15 0.0 0.09
|
||||
...
|
||||
0.21 0.07 0.1 0.13
|
||||
/
|
||||
|
||||
From a parsing point of view this is one single record; which contains
|
||||
one item consuming all of the values in the input deck. In the
|
||||
configuration this could have been configured as:
|
||||
|
||||
"items" : [{"name" : "DATA",
|
||||
"value_type" : "DOUBLE" ,
|
||||
"size_type" : "ALL" ,
|
||||
"default" : 0 ,
|
||||
"dimension" : "1"}]
|
||||
|
||||
However, since keywords containing large data arrays, like e.g. COORD
|
||||
and PERMX are quite common a shortcut has been created for such
|
||||
keywords, for instance the PORO keyword is configures as:
|
||||
|
||||
{"name" : "PORO" , "sections" : ["GRID"],
|
||||
"data" : {"value_type" : "DOUBLE" , "default" : 0 , "dimension":"1"}}
|
||||
|
||||
i.e. the "data" attribute is used as shorthand to configure a keyword
|
||||
with one record and one item which consumes all the data of the input
|
||||
deck.
|
||||
|
||||
|
||||
Multirecord keyword configuration
|
||||
---------------------------------
|
||||
|
||||
|
||||
Units and dimensions
|
||||
--------------------
|
||||
|
||||
The values given in the input dataset are generally dimensionfull, and
|
||||
before the simulator can start we must convert to internal SI values
|
||||
based on the unit system used in the input deck. In the input deck the
|
||||
different physical quantities are generally expressed with
|
||||
per-quantity units. The unit system is *not* based on selecting a unit
|
||||
for the fundamental dimensions length, mass and time and then deriving
|
||||
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/parser/eclipse/Units/UnitSystem.cpp
|
||||
|
||||
|
||||
|
||||
Default values
|
||||
--------------
|
||||
|
||||
|
||||
|
||||
|
||||
Classes:
|
||||
--------
|
||||
|
||||
The library contains classes along two dimensions:
|
||||
|
||||
+----------------+ +----------------+ +----------------+
|
||||
| Parser | | RawDeck | | Deck |
|
||||
+----------------+ +----------------+ +----------------+
|
||||
|
||||
+----------------+ +----------------+ +----------------+
|
||||
| ParserKeyword | | Rawkeyword | | DeckKeyword |
|
||||
+----------------+ +----------------+ +----------------+
|
||||
|
||||
+----------------+ +----------------+ +----------------+
|
||||
| ParserRecord | | RawRecord | | DeckRecord |
|
||||
+----------------+ +----------------+ +----------------+
|
||||
|
||||
+----------------+ +----------------+
|
||||
| ParserItem | | DeckItem |
|
||||
+----------------+ +----------------+
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
|
||||
Module: opm-common
|
||||
Description: Open Porous Media Initiative shared infrastructure
|
||||
Version: 2018.10-rc1
|
||||
Label: 2018.10-rc1
|
||||
Version: 2017.04
|
||||
Label: 2017.04
|
||||
Maintainer: opm@opm-project.org
|
||||
MaintainerName: OPM community
|
||||
Url: http://opm-project.org
|
||||
Depends: dune-common
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# this snippet enables parameter completion via the tabulator key
|
||||
# for bash for opm products.
|
||||
|
||||
# this is a bash readline completer for the case where a binary is
|
||||
# already known to be an eWoms simulator.
|
||||
_ewoms_parameter_completor()
|
||||
{
|
||||
if test "$COMP_WORDS" == ""; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
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}") )
|
||||
}
|
||||
|
||||
# this is a bash readline default completer which attempts to find out
|
||||
# if a given binary is an eWoms simulation. this needs to be set as a
|
||||
# default completer because the name of eWoms binaries cannot be known
|
||||
# a-priori.
|
||||
_ewoms_generic_parameter_completor()
|
||||
{
|
||||
if test "$COMP_WORDS" == ""; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
COMPREPLY=()
|
||||
local cmd cur ALL_OPTS
|
||||
cmd="${COMP_WORDS[0]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
fullcmd="$(which "$cmd")"
|
||||
if test -z "$fullcmd" || \
|
||||
! test -x "$fullcmd" || \
|
||||
(! test -f "$fullcmd" && ! test -h "$fullcmd" ) || \
|
||||
! test -r "$fullcmd" || \
|
||||
! grep -q "Ewoms[a-zA-Z0-9]*Simulator[a-zA-Z0-0]" "$fullcmd"
|
||||
then
|
||||
if test -n "$DEFAULT_COMPLETION_LOADER"; then
|
||||
"$DEFAULT_COMPLETION_LOADER" $@
|
||||
elif type -t _completion_loader 2>&1 > /dev/null; then
|
||||
# the default DEFAULT_COMPLETION_LOADER variable has not
|
||||
# been set and the _completion_loader function exists, so
|
||||
# we use _completion_loader as the default completer.
|
||||
_completion_loader $@
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
return $?
|
||||
fi
|
||||
|
||||
_ewoms_parameter_completor $@
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -o nospace -F _ewoms_parameter_completor @PRODUCT@
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
|
||||
inline void loadDeck( const char * deck_file) {
|
||||
Opm::ParseContext parseContext;
|
||||
Opm::Parser parser;
|
||||
|
||||
std::cout << "Loading deck: " << deck_file << " ..... "; std::cout.flush();
|
||||
auto deck = parser.parseFile(deck_file, parseContext);
|
||||
std::cout << "parse complete - creating EclipseState .... "; std::cout.flush();
|
||||
Opm::EclipseState state( deck, parseContext );
|
||||
Opm::Schedule schedule( deck, state.getInputGrid(), state.get3DProperties(), state.runspec().phases(), parseContext);
|
||||
Opm::SummaryConfig summary( deck, schedule, state.getTableManager( ), parseContext );
|
||||
std::cout << "complete." << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
for (int iarg = 1; iarg < argc; iarg++)
|
||||
loadDeck( argv[iarg] );
|
||||
}
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <getopt.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
|
||||
|
||||
inline void pack_deck( const char * deck_file, std::ostream& os) {
|
||||
Opm::ParseContext parseContext(Opm::InputError::WARN);
|
||||
Opm::Parser parser;
|
||||
|
||||
auto deck = parser.parseFile(deck_file, parseContext);
|
||||
os << deck;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void print_help_and_exit() {
|
||||
const char * help_text = R"(
|
||||
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.
|
||||
|
||||
By passing the option -o you can redirect the output to a file
|
||||
or a directory.
|
||||
|
||||
Print on stdout:
|
||||
|
||||
opmpack /path/to/case/CASE.DATA
|
||||
|
||||
|
||||
Print MY_CASE.DATA in /tmp:
|
||||
|
||||
opmpack -o /tmp /path/to/MY_CASE.DATA
|
||||
|
||||
|
||||
Print NEW_CASE in cwd:
|
||||
|
||||
opmpack -o NEW_CASE.DATA path/to/MY_CASE.DATA
|
||||
|
||||
|
||||
)";
|
||||
std::cerr << help_text << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int arg_offset = 1;
|
||||
bool stdout_output = true;
|
||||
const char * coutput_arg;
|
||||
|
||||
while (true) {
|
||||
int c;
|
||||
c = getopt(argc, argv, "o:");
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch(c) {
|
||||
case 'o':
|
||||
stdout_output = false;
|
||||
coutput_arg = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
arg_offset = optind;
|
||||
if (arg_offset >= argc)
|
||||
print_help_and_exit();
|
||||
|
||||
if (stdout_output)
|
||||
pack_deck(argv[arg_offset], std::cout);
|
||||
else {
|
||||
std::ofstream os;
|
||||
using path = boost::filesystem::path;
|
||||
path input_arg(argv[arg_offset]);
|
||||
path output_arg(coutput_arg);
|
||||
if (boost::filesystem::is_directory(output_arg)) {
|
||||
path output_path = output_arg / input_arg.filename();
|
||||
os.open(output_path.string());
|
||||
} else
|
||||
os.open(output_arg.string());
|
||||
|
||||
pack_deck(argv[arg_offset], os);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEVIATION_HPP
|
||||
#define DEVIATION_HPP
|
||||
|
||||
/*! \brief Deviation struct.
|
||||
\details The member variables are default initialized to -1,
|
||||
which is an invalid deviation value.
|
||||
*/
|
||||
struct Deviation {
|
||||
double abs = -1; //!< Absolute deviation
|
||||
double rel = -1; //!< Relative deviation
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/common/utility/numeric/calculateCellVol.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
/*
|
||||
This is just a basic survival test; we verify that the ERT well
|
||||
loader which is used in Resinsight can load the well description
|
||||
from the restart file.
|
||||
*/
|
||||
|
||||
void loadWells( const ecl_grid_type * grid , ecl_file_type * rst_file ) {
|
||||
well_info_type * well_info = well_info_alloc( grid );
|
||||
well_info_add_UNRST_wells2( well_info , ecl_file_get_global_view( rst_file ), true );
|
||||
well_info_free( well_info );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ECLFilesComparator::keywordValidForComparing(const std::string& keyword) const {
|
||||
auto it = std::find(keywords1.begin(), keywords1.end(), keyword);
|
||||
if (it == keywords1.end()) {
|
||||
OPM_THROW(std::runtime_error, "Keyword " << keyword << " does not exist in first file.");
|
||||
}
|
||||
it = find(keywords2.begin(), keywords2.end(), keyword);
|
||||
if (it == keywords2.end()) {
|
||||
OPM_THROW(std::runtime_error, "Keyword " << keyword << " does not exist in second file.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int ECLFilesComparator::getEclKeywordData(ecl_kw_type*& ecl_kw1, ecl_kw_type*& ecl_kw2, const std::string& keyword, int occurrence1, int occurrence2) const {
|
||||
ecl_kw1 = ecl_file_iget_named_kw(ecl_file1, keyword.c_str(), occurrence1);
|
||||
ecl_kw2 = ecl_file_iget_named_kw(ecl_file2, keyword.c_str(), occurrence2);
|
||||
const unsigned int numCells1 = ecl_kw_get_size(ecl_kw1);
|
||||
const unsigned int numCells2 = ecl_kw_get_size(ecl_kw2);
|
||||
if (numCells1 != numCells2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nOccurrence in first file " << occurrence1
|
||||
<< "\nOccurrence in second file " << occurrence2
|
||||
<< "\nCells in first file: " << numCells1
|
||||
<< "\nCells in second file: " << numCells2
|
||||
<< "\nThe number of cells differ.");
|
||||
}
|
||||
return numCells1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
void ECLFilesComparator::printValuesForCell(const std::string& /*keyword*/, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const T& value1, const T& value2) const {
|
||||
if (kw_size == static_cast<size_t>(ecl_grid_get_active_size(ecl_grid1))) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1A(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "Grid coordinate = (" << i << ", " << j << ", " << k << ")" << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (kw_size == static_cast<size_t>(ecl_grid_get_global_size(ecl_grid1))) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "Grid coordinate = (" << i << ", " << j << ", " << k << ")" << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Occurrence in first file = " << occurrence1 << "\n"
|
||||
<< "Occurrence in second file = " << occurrence2 << "\n"
|
||||
<< "Value index = " << cell << "\n"
|
||||
<< "(first value, second value) = (" << value1 << ", " << value2 << ")\n\n";
|
||||
}
|
||||
|
||||
template void ECLFilesComparator::printValuesForCell<bool> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const bool& value1, const bool& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<int> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const int& value1, const int& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<double> (const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const double& value1, const double& value2) const;
|
||||
template void ECLFilesComparator::printValuesForCell<std::string>(const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const std::string& value1, const std::string& value2) const;
|
||||
|
||||
|
||||
ECLFilesComparator::ECLFilesComparator(int file_type_arg, const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absToleranceArg, double relToleranceArg) :
|
||||
file_type(file_type_arg), absTolerance(absToleranceArg), relTolerance(relToleranceArg) {
|
||||
|
||||
std::string file1, file2;
|
||||
if (file_type == ECL_UNIFIED_RESTART_FILE) {
|
||||
file1 = basename1 + ".UNRST";
|
||||
file2 = basename2 + ".UNRST";
|
||||
}
|
||||
else if (file_type == ECL_INIT_FILE) {
|
||||
file1 = basename1 + ".INIT";
|
||||
file2 = basename2 + ".INIT";
|
||||
}
|
||||
else if (file_type == ECL_RFT_FILE) {
|
||||
file1 = basename1 + ".RFT";
|
||||
file2 = basename2 + ".RFT";
|
||||
}
|
||||
else {
|
||||
OPM_THROW(std::invalid_argument, "Unsupported filetype sent to ECLFilesComparator's constructor."
|
||||
<< "Only unified restart (.UNRST), initial (.INIT) and .RFT files are supported.");
|
||||
}
|
||||
ecl_file1 = ecl_file_open(file1.c_str(), 0);
|
||||
ecl_file2 = ecl_file_open(file2.c_str(), 0);
|
||||
ecl_grid1 = ecl_grid_load_case(basename1.c_str());
|
||||
ecl_grid2 = ecl_grid_load_case(basename2.c_str());
|
||||
if (ecl_file1 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening first file: " << file1);
|
||||
}
|
||||
if (ecl_file2 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening second file: " << file2);
|
||||
}
|
||||
if (ecl_grid1 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening first grid file: " << basename1);
|
||||
}
|
||||
if (ecl_grid2 == nullptr) {
|
||||
OPM_THROW(std::invalid_argument, "Error opening second grid file. " << basename2);
|
||||
}
|
||||
unsigned int numKeywords1 = ecl_file_get_num_distinct_kw(ecl_file1);
|
||||
unsigned int numKeywords2 = ecl_file_get_num_distinct_kw(ecl_file2);
|
||||
keywords1.reserve(numKeywords1);
|
||||
keywords2.reserve(numKeywords2);
|
||||
for (unsigned int i = 0; i < numKeywords1; ++i) {
|
||||
std::string keyword(ecl_file_iget_distinct_kw(ecl_file1, i));
|
||||
keywords1.push_back(keyword);
|
||||
}
|
||||
for (unsigned int i = 0; i < numKeywords2; ++i) {
|
||||
std::string keyword(ecl_file_iget_distinct_kw(ecl_file2, i));
|
||||
keywords2.push_back(keyword);
|
||||
}
|
||||
|
||||
if (file_type == ECL_UNIFIED_RESTART_FILE) {
|
||||
loadWells( ecl_grid1 , ecl_file1 );
|
||||
loadWells( ecl_grid2 , ecl_file2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ECLFilesComparator::~ECLFilesComparator() {
|
||||
ecl_file_close(ecl_file1);
|
||||
ecl_file_close(ecl_file2);
|
||||
ecl_grid_free(ecl_grid1);
|
||||
ecl_grid_free(ecl_grid2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLFilesComparator::printKeywords() const {
|
||||
std::cout << "\nKeywords in the first file:\n";
|
||||
for (const auto& it : keywords1) {
|
||||
std::cout << std::setw(15) << std::left << it << " of type " << ecl_type_get_name( ecl_file_iget_named_data_type(ecl_file1, it.c_str(), 0)) << std::endl;
|
||||
}
|
||||
std::cout << "\nKeywords in second file:\n";
|
||||
for (const auto& it : keywords2) {
|
||||
std::cout << std::setw(15) << std::left << it << " of type " << ecl_type_get_name( ecl_file_iget_named_data_type(ecl_file2, it.c_str(), 0)) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLFilesComparator::printKeywordsDifference() const {
|
||||
std::vector<std::string> common;
|
||||
std::vector<std::string> uncommon;
|
||||
const std::vector<std::string>* keywordsShort = &keywords1;
|
||||
const std::vector<std::string>* keywordsLong = &keywords2;
|
||||
if (keywords1.size() > keywords2.size()) {
|
||||
keywordsLong = &keywords1;
|
||||
keywordsShort = &keywords2;
|
||||
}
|
||||
for (const auto& it : *keywordsLong) {
|
||||
const auto position = std::find(keywordsShort->begin(), keywordsShort->end(), it);
|
||||
if (position != keywordsShort->end()) {
|
||||
common.push_back(*position);
|
||||
}
|
||||
else {
|
||||
uncommon.push_back(it);
|
||||
}
|
||||
}
|
||||
std::cout << "\nCommon keywords for the two cases:\n";
|
||||
for (const auto& it : common) std::cout << it << std::endl;
|
||||
std::cout << "\nUncommon keywords for the two cases:\n";
|
||||
for (const auto& it : uncommon) std::cout << it << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Deviation ECLFilesComparator::calculateDeviations(double val1, double val2) {
|
||||
val1 = std::abs(val1);
|
||||
val2 = std::abs(val2);
|
||||
Deviation deviation;
|
||||
if (val1 != 0 || val2 != 0) {
|
||||
deviation.abs = std::abs(val1 - val2);
|
||||
if (val1 != 0 && val2 != 0) {
|
||||
deviation.rel = deviation.abs/(std::max(val1, val2));
|
||||
}
|
||||
}
|
||||
return deviation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::median(std::vector<double> vec) {
|
||||
if (vec.empty()) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
size_t n = vec.size()/2;
|
||||
nth_element(vec.begin(), vec.begin() + n, vec.end());
|
||||
if (vec.size() % 2 == 0) {
|
||||
return 0.5*(vec[n-1]+vec[n]);
|
||||
}
|
||||
else {
|
||||
return vec[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::average(const std::vector<double>& vec) {
|
||||
if (vec.empty()) {
|
||||
return 0;
|
||||
}
|
||||
double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
|
||||
return sum/vec.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ECLFilesComparator::getCellVolume(const ecl_grid_type* ecl_grid,
|
||||
const int globalIndex) {
|
||||
std::vector<double> x(8, 0.0);
|
||||
std::vector<double> y(8, 0.0);
|
||||
std::vector<double> z(8, 0.0);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ecl_grid_get_cell_corner_xyz1(ecl_grid, globalIndex, i, &x.data()[i], &y.data()[i], &z.data()[i]);
|
||||
}
|
||||
return calculateCellVol(x,y,z);
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLFILESCOMPARATOR_HPP
|
||||
#define ECLFILESCOMPARATOR_HPP
|
||||
|
||||
#include "Deviation.hpp"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct ecl_file_struct; //!< Prototype for eclipse file struct, from ERT library.
|
||||
typedef struct ecl_file_struct ecl_file_type;
|
||||
|
||||
struct ecl_grid_struct; //!< Prototype for eclipse grid struct, from ERT library.
|
||||
typedef struct ecl_grid_struct ecl_grid_type;
|
||||
struct ecl_kw_struct; //!< Prototype for eclipse keyword struct, from ERT library.
|
||||
typedef struct ecl_kw_struct ecl_kw_type;
|
||||
|
||||
|
||||
/*! \brief A class for comparing ECLIPSE files.
|
||||
\details ECLFilesComparator opens ECLIPSE files
|
||||
(unified restart, initial and RFT in addition to grid file)
|
||||
from two simulations. This class has only the functions
|
||||
printKeywords() and printKeywordsDifference(), in addition to a
|
||||
couple of get-functions: the comparison logic is implemented in
|
||||
the subclasses RegressionTest and IntegrationTest. */
|
||||
class ECLFilesComparator {
|
||||
private:
|
||||
int file_type;
|
||||
double absTolerance = 0;
|
||||
double relTolerance = 0;
|
||||
protected:
|
||||
ecl_file_type* ecl_file1 = nullptr;
|
||||
ecl_grid_type* ecl_grid1 = nullptr;
|
||||
ecl_file_type* ecl_file2 = nullptr;
|
||||
ecl_grid_type* ecl_grid2 = nullptr;
|
||||
std::vector<std::string> keywords1, keywords2;
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform full error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
mutable size_t num_errors = 0;
|
||||
|
||||
//! \brief Checks if the keyword exists in both cases.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
//! \details If the keyword does not exist in one of the cases, the function throws an exception.
|
||||
void keywordValidForComparing(const std::string& keyword) const;
|
||||
//! \brief Stores keyword data for a given occurrence
|
||||
//! \param[out] ecl_kw1 Pointer to a ecl_kw_type, which stores keyword data for first case given the occurrence.
|
||||
//! \param[out] ecl_kw2 Pointer to a ecl_kw_type, which stores keyword data for second case given the occurrence.
|
||||
//! \param[in] keyword Which keyword to consider.
|
||||
//! \param[in] occurrence Which keyword occurrence to consider.
|
||||
//! \details This function stores keyword data for the given keyword and occurrence in #ecl_kw1 and #ecl_kw2, and returns the number of cells (for which the keyword has a value at the occurrence). If the number of cells differ for the two cases, an exception is thrown.
|
||||
unsigned int getEclKeywordData(ecl_kw_type*& ecl_kw1, ecl_kw_type*& ecl_kw2, const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
//! \brief Prints values for a given keyword, occurrence and cell
|
||||
//! \param[in] keyword Which keyword to consider.
|
||||
//! \param[in] occurrence Which keyword occurrence to consider.
|
||||
//! \param[in] cell Which cell occurrence to consider (numbered by global index).
|
||||
//! \param[in] value1 Value for first file, the data type can be bool, int, double or std::string.
|
||||
//! \param[in] value2 Value for second file, the data type can be bool, int, double or std::string.
|
||||
//! \details Templatefunction for printing values when exceptions are thrown. The function is defined for bool, int, double and std::string.
|
||||
template <typename T>
|
||||
void printValuesForCell(const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, const T& value1, const T& value2) const;
|
||||
|
||||
public:
|
||||
//! \brief Open ECLIPSE files and set tolerances and keywords.
|
||||
//! \param[in] file_type Specifies which filetype to be compared, possible inputs are UNRSTFILE, INITFILE and RFTFILE.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details The content of the ECLIPSE files specified in the input is stored in the ecl_file_type and ecl_grid_type member variables. In addition the keywords and absolute and relative tolerances (member variables) are set. If the constructor is unable to open one of the ECLIPSE files, an exception will be thrown.
|
||||
ECLFilesComparator(int file_type, const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance);
|
||||
//! \brief Closing the ECLIPSE files.
|
||||
~ECLFilesComparator();
|
||||
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether to perform a full error analysis.
|
||||
void doAnalysis(bool analize) { analysis = analize; }
|
||||
|
||||
//! \brief Returns the number of errors encountered in the performed comparisons.
|
||||
size_t getNoErrors() const { return num_errors; }
|
||||
|
||||
//! \brief Returns the ECLIPSE filetype of this
|
||||
int getFileType() const {return file_type;}
|
||||
//! \brief Returns the absolute tolerance stored as a private member variable in the class
|
||||
double getAbsTolerance() const {return absTolerance;}
|
||||
//! \brief Returns the relative tolerance stored as a private member variable in the class
|
||||
double getRelTolerance() const {return relTolerance;}
|
||||
|
||||
//! \brief Print all keywords and their respective Eclipse type for the two input cases.
|
||||
void printKeywords() const;
|
||||
//! \brief Print common and uncommon keywords for the two input cases.
|
||||
void printKeywordsDifference() const;
|
||||
|
||||
//! \brief Calculate deviations for two values.
|
||||
//! \details Using absolute values of the input arguments: If one of the values are non-zero, the Deviation::abs returned is the difference between the two input values. In addition, if both values are non-zero, the Deviation::rel returned is the absolute deviation divided by the largest value.
|
||||
static Deviation calculateDeviations(double val1, double val2);
|
||||
//! \brief Calculate median of a vector.
|
||||
//! \details Returning the median of the input vector, i.e. the middle value of the sorted vector if the number of elements is odd or the mean of the two middle values if the number of elements are even.
|
||||
static double median(std::vector<double> vec);
|
||||
//! \brief Calculate average of a vector.
|
||||
//! \details Returning the average of the input vector, i.e. the sum of all values divided by the number of elements.
|
||||
static double average(const std::vector<double>& vec);
|
||||
//! \brief Obtain the volume of a cell.
|
||||
static double getCellVolume(const ecl_grid_type* ecl_grid, const int globalIndex);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclIntegrationTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
void ECLIntegrationTest::setCellVolumes() {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
const unsigned int globalGridCount1 = ecl_grid_get_global_size(ecl_grid1);
|
||||
const unsigned int activeGridCount1 = ecl_grid_get_active_size(ecl_grid1);
|
||||
const unsigned int globalGridCount2 = ecl_grid_get_global_size(ecl_grid2);
|
||||
const unsigned int activeGridCount2 = ecl_grid_get_active_size(ecl_grid2);
|
||||
if (globalGridCount1 != globalGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << globalGridCount1
|
||||
<< "\nCells in second file: " << globalGridCount2
|
||||
<< "\nThe number of global cells differ.");
|
||||
}
|
||||
if (activeGridCount1 != activeGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << activeGridCount1
|
||||
<< "\nCells in second file: " << activeGridCount2
|
||||
<< "\nThe number of active cells differ.");
|
||||
}
|
||||
for (unsigned int cell = 0; cell < globalGridCount1; ++cell) {
|
||||
const double cellVolume1 = getCellVolume(ecl_grid1, cell);
|
||||
const double cellVolume2 = getCellVolume(ecl_grid2, cell);
|
||||
Deviation dev = calculateDeviations(cellVolume1, cellVolume2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
OPM_THROW(std::runtime_error, "In grid file: Deviations of cell volume exceed tolerances. "
|
||||
<< "\nFor cell with coordinate (" << i << ", " << j << ", " << k << "):"
|
||||
<< "\nCell volume in first file: " << cellVolume1
|
||||
<< "\nCell volume in second file: " << cellVolume2
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
} // The second input case is used as reference.
|
||||
cellVolumes.push_back(cellVolume2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::initialOccurrenceCompare(const std::string& keyword) {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, 0, 0);
|
||||
std::vector<double> values1(numCells);
|
||||
initialCellValues.resize(numCells);
|
||||
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, initialCellValues.data());
|
||||
|
||||
// This variable sums up the difference between the keyword value for the first case and the keyword value for the second case, for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedDifference = 0;
|
||||
// This variable sums up the keyword value for the first case for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedTotal = 0;
|
||||
for (size_t cell = 0; cell < initialCellValues.size(); ++cell) {
|
||||
weightedTotal += initialCellValues[cell]*cellVolumes[cell];
|
||||
weightedDifference += std::abs(values1[cell] - initialCellValues[cell])*cellVolumes[cell];
|
||||
}
|
||||
if (weightedTotal != 0) {
|
||||
double ratioValue = weightedDifference/weightedTotal;
|
||||
if ((ratioValue) > getRelTolerance()) {
|
||||
OPM_THROW(std::runtime_error, "\nFor keyword " << keyword << " and occurrence 0:"
|
||||
<< "\nThe ratio of the deviation and the total value is " << ratioValue
|
||||
<< ", which exceeds the relative tolerance of " << getRelTolerance() << "."
|
||||
<< "\nSee the docs for more information about how the ratio is computed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::occurrenceCompare(const std::string& keyword, int occurrence) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence, occurrence);
|
||||
std::vector<double> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, values2.data());
|
||||
|
||||
// This variable sums up the difference between the keyword value for the first case and the keyword value for the second case, for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double weightedDifference = 0;
|
||||
// This variable sums up the difference between the keyword value for the occurrence and the initial keyword value for each cell. The sum is weighted with respect to the cell volume of each cell.
|
||||
double relativeWeightedTotal = 0;
|
||||
|
||||
for (size_t cell = 0; cell < values1.size(); ++cell) {
|
||||
relativeWeightedTotal += std::abs(values1[cell] - initialCellValues[cell])*cellVolumes[cell];
|
||||
weightedDifference += std::abs(values1[cell] - values2[cell])*cellVolumes[cell];
|
||||
}
|
||||
|
||||
if (relativeWeightedTotal != 0) {
|
||||
double ratioValue = weightedDifference/relativeWeightedTotal;
|
||||
if ((ratioValue) > getRelTolerance()) {
|
||||
OPM_THROW(std::runtime_error, "\nFor keyword " << keyword << " and occurrence " << occurrence << ":"
|
||||
<< "\nThe ratio of the deviation and the total value is " << ratioValue
|
||||
<< ", which exceeds the relative tolerance of " << getRelTolerance() << "."
|
||||
<< "\nSee the docs for more information about how the ratio is computed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ECLIntegrationTest::ECLIntegrationTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absTolerance, double relTolerance) :
|
||||
ECLFilesComparator(ECL_UNIFIED_RESTART_FILE, basename1, basename2, absTolerance, relTolerance) {
|
||||
std::cout << "\nUsing cell volumes and keyword values from case " << basename2
|
||||
<< " as reference." << std::endl << std::endl;
|
||||
setCellVolumes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ECLIntegrationTest::elementInWhitelist(const std::string& keyword) const {
|
||||
auto it = std::find(keywordWhitelist.begin(), keywordWhitelist.end(), keyword);
|
||||
return it != keywordWhitelist.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::equalNumKeywords() const {
|
||||
if (keywords1.size() != keywords2.size()) {
|
||||
OPM_THROW(std::runtime_error, "\nKeywords in first file: " << keywords1.size()
|
||||
<< "\nKeywords in second file: " << keywords2.size()
|
||||
<< "\nThe number of keywords differ.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::results() {
|
||||
for (const auto& it : keywordWhitelist)
|
||||
resultsForKeyword(it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLIntegrationTest::resultsForKeyword(const std::string& keyword) {
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
keywordValidForComparing(keyword);
|
||||
const unsigned int occurrences1 = ecl_file_get_num_named_kw(ecl_file1, keyword.c_str());
|
||||
const unsigned int occurrences2 = ecl_file_get_num_named_kw(ecl_file2, keyword.c_str());
|
||||
if (occurrences1 != occurrences2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nKeyword occurrences in first file: " << occurrences1
|
||||
<< "\nKeyword occurrences in second file: " << occurrences2
|
||||
<< "\nThe number of occurrences differ.");
|
||||
}
|
||||
initialOccurrenceCompare(keyword);
|
||||
for (unsigned int occurrence = 1; occurrence < occurrences1; ++occurrence) {
|
||||
occurrenceCompare(keyword, occurrence);
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLINTEGRATIONTEST_HPP
|
||||
#define ECLINTEGRATIONTEST_HPP
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
|
||||
/*! \brief A class for executing a integration test for two ECLIPSE files.
|
||||
\details This class inherits from ECLFilesComparator, which opens and closes
|
||||
the input cases and stores keywordnames. The three public functions
|
||||
equalNumKeywords(), results() and resultsForKeyword() can be invoked
|
||||
to compare griddata or keyworddata for all keywords or a given
|
||||
keyword (resultsForKeyword()).
|
||||
*/
|
||||
class ECLIntegrationTest: public ECLFilesComparator {
|
||||
private:
|
||||
std::vector<double> cellVolumes; //!< Vector of cell volumes in second input case (indexed by global index)
|
||||
std::vector<double> initialCellValues; //!< Keyword values for all cells at first occurrence (index by global index)
|
||||
|
||||
// These are the only keywords which are compared, since SWAT should be "1 - SOIL - SGAS", this keyword is omitted.
|
||||
const std::vector<std::string> keywordWhitelist = {"SGAS", "SWAT", "PRESSURE"};
|
||||
|
||||
void setCellVolumes();
|
||||
void initialOccurrenceCompare(const std::string& keyword);
|
||||
void occurrenceCompare(const std::string& keyword, int occurrence) const;
|
||||
public:
|
||||
//! \brief Sets up the integration test.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details This constructor calls the constructor of the superclass, with input filetype unified restart. See the docs for ECLFilesComparator for more information.
|
||||
ECLIntegrationTest(const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance);
|
||||
|
||||
//! \brief Checks if a keyword is supported for comparison.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
bool elementInWhitelist(const std::string& keyword) const;
|
||||
//! \brief Checks if the number of keywords equal in the two input cases.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
void equalNumKeywords() const;
|
||||
|
||||
//! \brief Finds deviations for all supported keywords.
|
||||
//! \details results() loops through all supported keywords for integration test (defined in keywordWhitelist -- this is SGAS, SWAT and PRESSURE) and calls resultsForKeyword() for each keyword.
|
||||
void results();
|
||||
//! \brief Finds deviations for a specific keyword.
|
||||
//! \param[in] keyword Keyword to check.
|
||||
/*! \details First, resultsForKeyword() checks if the keyword exits in both cases, and if the number of keyword occurrences in the two cases differ. If these tests fail, an exception is thrown. Then deviaitons are calculated as described below for each occurrence, and an exception is thrown if the relative error ratio \f$E\f$ is larger than the relative tolerance.
|
||||
* Calculation:\n
|
||||
* Let the keyword values for occurrence \f$n\f$ and cell \f$i\f$ be \f$p_{n,i}\f$ and \f$q_{n,i}\f$ for input case 1 and 2, respectively.
|
||||
* Consider first the initial occurrence (\f$n=0\f$). The function uses the second cases as reference, and calculates the volume weighted sum of \f$q_{0,i}\f$ over all cells \f$i\f$:
|
||||
* \f[ S_0 = \sum_{i} q_{0,i} v_i \f]
|
||||
* where \f$v_{i}\f$ is the volume of cell \f$i\f$ in case 2. Then, the deviations between the cases for each cell are calculated:
|
||||
* \f[ \Delta = \sum_{i} |p_{0,i} - q_{0,i}| v_i.\f]
|
||||
* The error ratio is then \f$E = \Delta/S_0\f$.\n
|
||||
* For all other occurrences \f$n\f$, the deviation value \f$\Delta\f$ is calculated the same way, but the total value \f$S\f$ is calculated relative to the initial occurrence total \f$S_0\f$:
|
||||
* \f[ S = \sum_{i} |q_{n,i} - q_{0,i}| v_i. \f]
|
||||
* The error ratio is \f$ E = \Delta/S\f$. */
|
||||
void resultsForKeyword(const std::string& keyword);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclRegressionTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_type.h>
|
||||
|
||||
#include <ert/ecl_well/well_info.h>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else { \
|
||||
std::cerr << message << std::endl; \
|
||||
++num_errors; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
void ECLRegressionTest::printResultsForKeyword(const std::string& keyword) const {
|
||||
std::cout << "Deviation results for keyword " << keyword << " of type "
|
||||
<< ecl_type_get_name(ecl_file_iget_named_data_type(ecl_file1, keyword.c_str(), 0))
|
||||
<< ":\n";
|
||||
const double absDeviationAverage = average(absDeviation);
|
||||
const double relDeviationAverage = average(relDeviation);
|
||||
std::cout << "Average absolute deviation = " << absDeviationAverage << std::endl;
|
||||
std::cout << "Median absolute deviation = " << median(absDeviation) << std::endl;
|
||||
std::cout << "Average relative deviation = " << relDeviationAverage << std::endl;
|
||||
std::cout << "Median relative deviation = " << median(relDeviation) << "\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::boolComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
for (size_t cell = 0; cell < numCells; cell++) {
|
||||
bool data1 = ecl_kw_iget_bool(ecl_kw1, cell);
|
||||
bool data2 = ecl_kw_iget_bool(ecl_kw2, cell);
|
||||
if (data1 != data2) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, numCells, cell, data1, data2);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of bool type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::charComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
for (size_t cell = 0; cell < numCells; cell++) {
|
||||
std::string data1(ecl_kw_iget_char_ptr(ecl_kw1, cell));
|
||||
std::string data2(ecl_kw_iget_char_ptr(ecl_kw2, cell));
|
||||
if (data1.compare(data2) != 0) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, numCells, cell, data1, data2);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of char type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::intComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) const {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
std::vector<int> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_memcpy_int_data(ecl_kw1, values1.data());
|
||||
ecl_kw_get_memcpy_int_data(ecl_kw2, values2.data());
|
||||
for (size_t cell = 0; cell < values1.size(); cell++) {
|
||||
if (values1[cell] != values2[cell]) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, values1.size(), cell, values1[cell], values2[cell]);
|
||||
HANDLE_ERROR(std::runtime_error, "Values of int type differ.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::doubleComparisonForOccurrence(const std::string& keyword,
|
||||
int occurrence1, int occurrence2) {
|
||||
ecl_kw_type* ecl_kw1 = nullptr;
|
||||
ecl_kw_type* ecl_kw2 = nullptr;
|
||||
const unsigned int numCells = getEclKeywordData(ecl_kw1, ecl_kw2, keyword, occurrence1, occurrence2);
|
||||
std::vector<double> values1(numCells), values2(numCells);
|
||||
ecl_kw_get_data_as_double(ecl_kw1, values1.data());
|
||||
ecl_kw_get_data_as_double(ecl_kw2, values2.data());
|
||||
|
||||
auto it = std::find(keywordDisallowNegatives.begin(), keywordDisallowNegatives.end(), keyword);
|
||||
for (size_t cell = 0; cell < values1.size(); cell++) {
|
||||
deviationsForCell(values1[cell], values2[cell], keyword, occurrence1, occurrence2, cell, it == keywordDisallowNegatives.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::deviationsForCell(double val1, double val2,
|
||||
const std::string& keyword,
|
||||
int occurrence1, int occurrence2,
|
||||
size_t kw_size, size_t cell,
|
||||
bool allowNegativeValues) {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
if (!allowNegativeValues) {
|
||||
if (val1 < 0) {
|
||||
if (std::abs(val1) > absTolerance) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Negative value in first file, "
|
||||
<< "which in absolute value exceeds the absolute tolerance of " << absTolerance << ".");
|
||||
}
|
||||
val1 = 0;
|
||||
}
|
||||
if (val2 < 0) {
|
||||
if (std::abs(val2) > absTolerance) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Negative value in second file, "
|
||||
<< "which in absolute value exceeds the absolute tolerance of " << absTolerance << ".");
|
||||
}
|
||||
val2 = 0;
|
||||
}
|
||||
}
|
||||
Deviation dev = calculateDeviations(val1, val2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(dev);
|
||||
} else {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Deviations exceed tolerances."
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
}
|
||||
}
|
||||
if (dev.abs != -1) {
|
||||
absDeviation.push_back(dev.abs);
|
||||
}
|
||||
if (dev.rel != -1) {
|
||||
relDeviation.push_back(dev.rel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::gridCompare(const bool volumecheck) const {
|
||||
double absTolerance = getAbsTolerance();
|
||||
double relTolerance = getRelTolerance();
|
||||
const unsigned int globalGridCount1 = ecl_grid_get_global_size(ecl_grid1);
|
||||
const unsigned int activeGridCount1 = ecl_grid_get_active_size(ecl_grid1);
|
||||
const unsigned int globalGridCount2 = ecl_grid_get_global_size(ecl_grid2);
|
||||
const unsigned int activeGridCount2 = ecl_grid_get_active_size(ecl_grid2);
|
||||
if (globalGridCount1 != globalGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << globalGridCount1
|
||||
<< "\nCells in second file: " << globalGridCount2
|
||||
<< "\nThe number of global cells differ.");
|
||||
}
|
||||
if (activeGridCount1 != activeGridCount2) {
|
||||
OPM_THROW(std::runtime_error, "In grid file:"
|
||||
<< "\nCells in first file: " << activeGridCount1
|
||||
<< "\nCells in second file: " << activeGridCount2
|
||||
<< "\nThe number of active cells differ.");
|
||||
}
|
||||
|
||||
if (!volumecheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int cell = 0; cell < globalGridCount1; ++cell) {
|
||||
const bool active1 = ecl_grid_cell_active1(ecl_grid1, cell);
|
||||
const bool active2 = ecl_grid_cell_active1(ecl_grid2, cell);
|
||||
if (active1 != active2) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
HANDLE_ERROR(std::runtime_error, "Grid cell with one-based indices ( "
|
||||
<< i << ", " << j << ", " << k << " ) is "
|
||||
<< (active1 ? "active" : "inactive") << " in first grid, but "
|
||||
<< (active2 ? "active" : "inactive") << " in second grid.");
|
||||
}
|
||||
const double cellVolume1 = getCellVolume(ecl_grid1, cell);
|
||||
const double cellVolume2 = getCellVolume(ecl_grid2, cell);
|
||||
Deviation dev = calculateDeviations(cellVolume1, cellVolume2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
int i, j, k;
|
||||
ecl_grid_get_ijk1(ecl_grid1, cell, &i, &j, &k);
|
||||
// Coordinates from this function are zero-based, hence incrementing
|
||||
i++, j++, k++;
|
||||
HANDLE_ERROR(std::runtime_error, "In grid file: Deviations of cell volume exceed tolerances. "
|
||||
<< "\nFor cell with one-based indices (" << i << ", " << j << ", " << k << "):"
|
||||
<< "\nCell volume in first file: " << cellVolume1
|
||||
<< "\nCell volume in second file: " << cellVolume2
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << "."
|
||||
<< "\nCell 1 active: " << active1
|
||||
<< "\nCell 2 active: " << active2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::results() {
|
||||
if (!this->acceptExtraKeywords) {
|
||||
if (keywords1.size() != keywords2.size()) {
|
||||
std::set<std::string> keys(keywords1.begin() , keywords1.end());
|
||||
for (const auto& key2: keywords2)
|
||||
keys.insert( key2 );
|
||||
|
||||
for (const auto& key : keys)
|
||||
fprintf(stderr," %8s:%3d %8s:%3d \n",key.c_str() , ecl_file_get_num_named_kw( ecl_file1 , key.c_str()),
|
||||
key.c_str() , ecl_file_get_num_named_kw( ecl_file2 , key.c_str()));
|
||||
|
||||
|
||||
OPM_THROW(std::runtime_error, "\nKeywords in first file: " << keywords1.size()
|
||||
<< "\nKeywords in second file: " << keywords2.size()
|
||||
<< "\nThe number of keywords differ.");
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& it : keywords1)
|
||||
resultsForKeyword(it);
|
||||
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " entries" << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ECLRegressionTest::resultsForKeyword(const std::string& keyword) {
|
||||
keywordValidForComparing(keyword);
|
||||
const unsigned int occurrences1 = ecl_file_get_num_named_kw(ecl_file1, keyword.c_str());
|
||||
const unsigned int occurrences2 = ecl_file_get_num_named_kw(ecl_file2, keyword.c_str());
|
||||
if (!onlyLastOccurrence && occurrences1 != occurrences2) {
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << ":"
|
||||
<< "\nKeyword occurrences in first file: " << occurrences1
|
||||
<< "\nKeyword occurrences in second file: " << occurrences2
|
||||
<< "\nThe number of occurrences differ.");
|
||||
}
|
||||
// Assuming keyword type is constant for every occurrence:
|
||||
const ecl_type_enum kw_type = ecl_type_get_type( ecl_file_iget_named_data_type(ecl_file1, keyword.c_str(), 0) );
|
||||
switch(kw_type) {
|
||||
case ECL_DOUBLE_TYPE:
|
||||
case ECL_FLOAT_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
doubleComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
doubleComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
printResultsForKeyword(keyword);
|
||||
absDeviation.clear();
|
||||
relDeviation.clear();
|
||||
return;
|
||||
case ECL_INT_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
intComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
intComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_CHAR_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
charComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
charComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_BOOL_TYPE:
|
||||
std::cout << "Comparing " << keyword << "...";
|
||||
if (onlyLastOccurrence) {
|
||||
boolComparisonForOccurrence(keyword, occurrences1 - 1, occurrences2 - 1);
|
||||
}
|
||||
else {
|
||||
for (unsigned int occurrence = 0; occurrence < occurrences1; ++occurrence) {
|
||||
boolComparisonForOccurrence(keyword, occurrence, occurrence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ECL_MESS_TYPE:
|
||||
std::cout << "\nKeyword " << keyword << " is of type MESS"
|
||||
<< ", which is not supported in regression test." << "\n\n";
|
||||
return;
|
||||
default:
|
||||
std::cout << "\nKeyword " << keyword << "has undefined type." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLREGRESSIONTEST_HPP
|
||||
#define ECLREGRESSIONTEST_HPP
|
||||
|
||||
#include "EclFilesComparator.hpp"
|
||||
|
||||
/*! \brief A class for executing a regression test for two ECLIPSE files.
|
||||
\details This class inherits from ECLFilesComparator, which opens and
|
||||
closes the input cases and stores keywordnames.
|
||||
The three public functions gridCompare(), results() and
|
||||
resultsForKeyword() can be invoked to compare griddata
|
||||
or keyworddata for all keywords or a given keyword (resultsForKeyword()).
|
||||
*/
|
||||
|
||||
class ECLRegressionTest: public ECLFilesComparator {
|
||||
private:
|
||||
// These vectors store absolute and relative deviations, respecively. Note that they are whiped clean for every new keyword comparison.
|
||||
std::vector<double> absDeviation, relDeviation;
|
||||
// Keywords which should not contain negative values, i.e. uses allowNegativeValues = false in deviationsForCell():
|
||||
const std::vector<std::string> keywordDisallowNegatives = {"SGAS", "SWAT", "PRESSURE"};
|
||||
|
||||
// Only compare last occurrence
|
||||
bool onlyLastOccurrence = false;
|
||||
|
||||
// Accept extra keywords in the restart file of the 'new' simulation.
|
||||
bool acceptExtraKeywords = false;
|
||||
|
||||
|
||||
// Prints results stored in absDeviation and relDeviation.
|
||||
void printResultsForKeyword(const std::string& keyword) const;
|
||||
|
||||
// Function which compares data at specific occurrences and for a specific keyword type. The functions takes two occurrence inputs to also be able to
|
||||
// compare keywords which are shifted relative to each other in the two files. This is for instance handy when running flow with restart from different timesteps,
|
||||
// and comparing the last timestep from the two runs.
|
||||
void boolComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void charComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void intComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2) const;
|
||||
void doubleComparisonForOccurrence(const std::string& keyword, int occurrence1, int occurrence2);
|
||||
// deviationsForCell throws an exception if both the absolute deviation AND the relative deviation
|
||||
// are larger than absTolerance and relTolerance, respectively. In addition,
|
||||
// if allowNegativeValues is passed as false, an exception will be thrown when the absolute value
|
||||
// of a negative value exceeds absTolerance. If no exceptions are thrown, the absolute and relative deviations are added to absDeviation and relDeviation.
|
||||
void deviationsForCell(double val1, double val2, const std::string& keyword, int occurrence1, int occurrence2, size_t kw_size, size_t cell, bool allowNegativeValues = true);
|
||||
public:
|
||||
//! \brief Sets up the regression test.
|
||||
//! \param[in] file_type Specifies which filetype to be compared, possible inputs are UNRSTFILE, INITFILE and RFTFILE.
|
||||
//! \param[in] basename1 Full path without file extension to the first case.
|
||||
//! \param[in] basename2 Full path without file extension to the second case.
|
||||
//! \param[in] absTolerance Tolerance for absolute deviation.
|
||||
//! \param[in] relTolerance Tolerance for relative deviation.
|
||||
//! \details This constructor only calls the constructor of the superclass, see the docs for ECLFilesComparator for more information.
|
||||
ECLRegressionTest(int file_type, const std::string& basename1, const std::string& basename2, double absTolerance, double relTolerance):
|
||||
ECLFilesComparator(file_type, basename1, basename2, absTolerance, relTolerance) {}
|
||||
|
||||
//! \brief Option to only compare last occurrence
|
||||
void setOnlyLastOccurrence(bool onlyLastOccurrenceArg) {this->onlyLastOccurrence = onlyLastOccurrenceArg;}
|
||||
|
||||
// Accept extra keywords: If this switch is set to true the comparison
|
||||
// of restart files will ignore extra keywords which are only present
|
||||
// in the new simulation.
|
||||
void setAcceptExtraKeywords(bool acceptExtraKeywords) { this->acceptExtraKeywords = acceptExtraKeywords; }
|
||||
|
||||
//! \brief Compares grid properties of the two cases.
|
||||
// gridCompare() checks if both the number of active and global cells in the two cases are the same. If they are, and volumecheck is true, all cells are looped over to calculate the cell volume deviation for the two cases. If the both the relative and absolute deviation exceeds the tolerances, an exception is thrown.
|
||||
void gridCompare(const bool volumecheck) const;
|
||||
//! \brief Calculates deviations for all keywords.
|
||||
// This function checks if the number of keywords of the two cases are equal, and if it is, resultsForKeyword() is called for every keyword. If not, an exception is thrown.
|
||||
void results();
|
||||
//! \brief Calculates deviations for a specific keyword.
|
||||
//! \param[in] keyword Keyword which should be compared, if this keyword is absent in one of the cases, an exception will be thrown.
|
||||
//! \details This function loops through every report step and every cell and compares the values for the given keyword from the two input cases. If the absolute or relative deviation between the two values for each step exceeds both the absolute tolerance and the relative tolerance (stored in ECLFilesComparator), an exception is thrown. In addition, some keywords are marked for "disallow negative values" -- these are SGAS, SWAT and PRESSURE. An exception is thrown if a value of one of these keywords is both negative and has an absolute value larger than the absolute tolerance. If no exceptions are thrown, resultsForKeyword() uses the private member funtion printResultsForKeyword to print the average and median deviations.
|
||||
void resultsForKeyword(const std::string& keyword);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,380 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EclIntegrationTest.hpp"
|
||||
#include "EclRegressionTest.hpp"
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include "summaryRegressionTest.hpp"
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/ecl/ecl_endian_flip.h>
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <getopt.h>
|
||||
|
||||
static void printHelp() {
|
||||
std::cout << "\ncompareECL compares ECLIPSE files (restart (.RST), unified restart (.UNRST), initial (.INIT), summary (.SMRY), unified summary (.UNSMRY) or .RFT) and gridsizes (from .EGRID or .GRID file) from two simulations.\n"
|
||||
<< "The program takes four arguments:\n\n"
|
||||
<< "1. Case number 1 (full path without extension)\n"
|
||||
<< "2. Case number 2 (full path without extension)\n"
|
||||
<< "3. Absolute tolerance\n"
|
||||
<< "4. Relative tolerance (between 0 and 1)\n\n"
|
||||
<< "In addition, the program takes these options (which must be given before the arguments):\n\n"
|
||||
<< "-a Run a full analysis of errors.\n"
|
||||
<< "-g Will print the vector with the greatest error ratio.\n"
|
||||
<< "-h Print help and exit.\n"
|
||||
<< "-i Execute integration test (regression test is default).\n"
|
||||
<< " The integration test compares SGAS, SWAT and PRESSURE in unified restart files, so this option can not be used in combination with -t.\n"
|
||||
<< "-I Same as -i, but throws an exception when the number of keywords in the two cases differ. Can not be used in combination with -t.\n"
|
||||
<< "-k Specify specific keyword to compare (capitalized), for example -k PRESSURE.\n"
|
||||
<< "-K Will not allow different amount of keywords in the two files. Throws an exception if the amount are different.\n"
|
||||
<< "-l Only do comparison for the last occurrence. This option is only for the regression test, and can therefore not be used in combination with -i or -I.\n"
|
||||
<< "-m mainVar. Will calculate the error ratio for one main variable. Valid input is WOPR, WWPR, WGPR or WBHP.\n"
|
||||
<< "-n Do not throw on errors.\n"
|
||||
<< "-p Print keywords in both cases and exit. Can not be used in combination with -P.\n"
|
||||
<< "-P Print common and uncommon keywords in both cases and exit. Can not be used in combination with -p.\n"
|
||||
<< "-R Will allow comparison between a restarted simulation and a normal simulation for summary regression tests. The files must end at the same time.\n"
|
||||
<< "-s int Sets the number of spikes that are allowed for each keyword in summary integration tests.\n"
|
||||
<< "-t Specify ECLIPSE filetype to compare (unified restart is default). Can not be used in combination with -i or -I. Different possible arguments are:\n"
|
||||
<< " -t UNRST \t Compare two unified restart files (.UNRST). This the default value, so it is the same as not passing option -t.\n"
|
||||
<< " -t INIT \t Compare two initial files (.INIT).\n"
|
||||
<< " -t RFT \t Compare two RFT files (.RFT).\n"
|
||||
<< " -t RST \t Compare two cases consisting of restart files (.Xnnnn).\n"
|
||||
<< " -t SMRY \t Compare two cases consistent of (unified) summary files.\n"
|
||||
<< " -t RST1 \t Compare two cases where the first case consists of restart files (.Xnnnn), and the second case consists of a unified restart file (.UNRST).\n"
|
||||
<< " -t RST2 \t Compare two cases where the first case consists of a unified restart file (.UNRST), and the second case consists of restart files (.Xnnnn).\n"
|
||||
<< " Note that when dealing with restart files (.Xnnnn), the program concatenates all of them into one unified restart file, which is used for comparison and stored in the same directory as the restart files.\n"
|
||||
<< " This will overwrite any existing unified restart file in that directory.\n\n"
|
||||
<< "-v For the rate keywords WOPR, WGPR, WWPR and WBHP. Calculates the error volume of the two summary files. This is printed to screen.\n"
|
||||
<< "\nExample usage of the program: \n\n"
|
||||
<< "compareECL -k PRESSURE <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
|
||||
<< "compareECL -t INIT -k PORO <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
|
||||
<< "compareECL -i <path to first casefile> <path to second casefile> 0.01 1e-6\n\n"
|
||||
<< "Exceptions are thrown (and hence program exits) when deviations are larger than the specified "
|
||||
<< "tolerances, or when the number of cells does not match -- either in the grid file or for a "
|
||||
<< "specific keyword. Information about the keyword, keyword occurrence (zero based) and cell "
|
||||
<< "coordinate is printed when an exception is thrown. For more information about how the cases "
|
||||
<< "are compared, see the documentation of the EclFilesComparator class.\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void splitBasename(const std::string& basename, std::string& path, std::string& filename) {
|
||||
const size_t lastSlashIndex = basename.find_last_of("/\\");
|
||||
path = basename.substr(0,lastSlashIndex);
|
||||
filename = basename.substr(lastSlashIndex+1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inspired by the ecl_pack application in the ERT library
|
||||
void concatenateRestart(const std::string& basename) {
|
||||
std::string inputPath, inputBase;
|
||||
splitBasename(basename, inputPath, inputBase);
|
||||
stringlist_type* inputFiles = stringlist_alloc_new();
|
||||
const int numFiles = ecl_util_select_filelist(inputPath.c_str(), inputBase.c_str(), ECL_RESTART_FILE, false, inputFiles);
|
||||
|
||||
const char* target_file_name = ecl_util_alloc_filename(inputPath.c_str(), inputBase.c_str(), ECL_UNIFIED_RESTART_FILE, false, -1);
|
||||
fortio_type* target = fortio_open_writer(target_file_name, false, ECL_ENDIAN_FLIP);
|
||||
int dummy;
|
||||
ecl_kw_type* seqnum_kw = ecl_kw_alloc_new("SEQNUM", 1, ECL_INT, &dummy);
|
||||
|
||||
int reportStep = 0;
|
||||
for (int i = 0; i < numFiles; ++i) {
|
||||
ecl_util_get_file_type(stringlist_iget(inputFiles, i), nullptr, &reportStep);
|
||||
ecl_file_type* src_file = ecl_file_open(stringlist_iget(inputFiles, i), 0);
|
||||
ecl_kw_iset_int(seqnum_kw, 0, reportStep);
|
||||
ecl_kw_fwrite(seqnum_kw, target);
|
||||
ecl_file_fwrite_fortio(src_file, target, 0);
|
||||
ecl_file_close(src_file);
|
||||
}
|
||||
fortio_fclose(target);
|
||||
stringlist_free(inputFiles);
|
||||
}
|
||||
|
||||
//------------------------------------------------//
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Restart is default
|
||||
ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE;
|
||||
// RegressionTest is default
|
||||
bool integrationTest = false;
|
||||
bool allowDifferentAmount = true;
|
||||
bool checkNumKeywords = false;
|
||||
bool findGreatestErrorRatio = false;
|
||||
bool findVolumeError = false;
|
||||
bool onlyLastOccurrence = false;
|
||||
bool printKeywords = false;
|
||||
bool printKeywordsDifference = false;
|
||||
bool restartFile = false;
|
||||
bool specificKeyword = false;
|
||||
bool specificFileType = false;
|
||||
bool allowSpikes = false;
|
||||
bool throwOnError = true;
|
||||
bool throwTooGreatErrorRatio = true;
|
||||
bool acceptExtraKeywords = false;
|
||||
bool analysis = false;
|
||||
bool volumecheck = true;
|
||||
char* keyword = nullptr;
|
||||
char* fileTypeCstr = nullptr;
|
||||
const char* mainVariable = nullptr;
|
||||
int c = 0;
|
||||
int spikeLimit = -1;
|
||||
|
||||
while ((c = getopt(argc, argv, "hiIk:alnpPt:VRgs:m:vKx")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'g':
|
||||
findGreatestErrorRatio = true;
|
||||
throwTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
case 'i':
|
||||
integrationTest = true;
|
||||
break;
|
||||
case 'I':
|
||||
integrationTest = true;
|
||||
checkNumKeywords = true;
|
||||
break;
|
||||
case 'k':
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'K':
|
||||
allowDifferentAmount = false;
|
||||
break;
|
||||
case 'l':
|
||||
onlyLastOccurrence = true;
|
||||
break;
|
||||
case 'm':
|
||||
mainVariable = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
throwOnError = false;
|
||||
break;
|
||||
case 'p':
|
||||
printKeywords = true;
|
||||
break;
|
||||
case 'P':
|
||||
printKeywordsDifference = true;
|
||||
break;
|
||||
case 'R':
|
||||
restartFile = true;
|
||||
break;
|
||||
case 's':
|
||||
allowSpikes = true;
|
||||
spikeLimit = atof(optarg);
|
||||
break;
|
||||
case 't':
|
||||
specificFileType = true;
|
||||
fileTypeCstr = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
findVolumeError = true;
|
||||
break;
|
||||
case 'V':
|
||||
volumecheck = false;
|
||||
break;
|
||||
case 'x':
|
||||
acceptExtraKeywords = true;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 'k' || optopt == 'm' || optopt == 's') {
|
||||
std::cerr << "Option " << optopt << " requires a keyword as argument, see manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else if (optopt == 't') {
|
||||
std::cerr << "Option t requires an ECLIPSE filetype as argument, see manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cerr << "Unknown option." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
int argOffset = optind;
|
||||
if ((printKeywords && printKeywordsDifference) ||
|
||||
(integrationTest && specificFileType) ||
|
||||
(integrationTest && onlyLastOccurrence)) {
|
||||
std::cerr << "Error: Options given which can not be combined. "
|
||||
<< "Please see the manual (-h) for more information." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc != argOffset + 4) {
|
||||
std::cerr << "Error: The number of options and arguments given is not correct. "
|
||||
<< "Please run compareECL -h to see manual." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::string basename1 = argv[argOffset];
|
||||
std::string basename2 = argv[argOffset + 1];
|
||||
double absTolerance = strtod(argv[argOffset + 2], nullptr);
|
||||
double relTolerance = strtod(argv[argOffset + 3], nullptr);
|
||||
|
||||
if (specificFileType) {
|
||||
std::string fileTypeString(fileTypeCstr);
|
||||
for (auto& ch: fileTypeString) ch = toupper(ch);
|
||||
if (fileTypeString== "UNRST") {} //Do nothing
|
||||
else if (fileTypeString == "RST") {
|
||||
concatenateRestart(basename1);
|
||||
concatenateRestart(basename2);
|
||||
}
|
||||
else if (fileTypeString == "RST1") {
|
||||
concatenateRestart(basename1);
|
||||
}
|
||||
else if (fileTypeString == "RST2") {
|
||||
concatenateRestart(basename2);
|
||||
}
|
||||
else if (fileTypeString == "INIT") {
|
||||
file_type = ECL_INIT_FILE;
|
||||
}
|
||||
else if (fileTypeString == "RFT") {
|
||||
file_type = ECL_RFT_FILE;
|
||||
}
|
||||
else if (fileTypeString == "SMRY")
|
||||
file_type = ECL_SUMMARY_FILE;
|
||||
else {
|
||||
std::cerr << "Unknown ECLIPSE filetype specified with option -t. Please run compareECL -h to see manual." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (restartFile && (file_type != ECL_SUMMARY_FILE || integrationTest)) {
|
||||
std::cerr << "Error: -R can only be used in for summary regression tests." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::cout << "Comparing '" << basename1 << "' to '" << basename2 << "'." << std::endl;
|
||||
try {
|
||||
if (file_type == ECL_SUMMARY_FILE) {
|
||||
if(!integrationTest){
|
||||
SummaryRegressionTest compare(basename1,basename2,absTolerance,relTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.doAnalysis(analysis);
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.setIsRestartFile(restartFile);
|
||||
if(specificKeyword){
|
||||
compare.getRegressionTest(keyword);
|
||||
}
|
||||
else{
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.getRegressionTest();
|
||||
}
|
||||
} else {
|
||||
SummaryIntegrationTest compare(basename1,basename2,absTolerance,relTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.setFindVectorWithGreatestErrorRatio(findGreatestErrorRatio);
|
||||
compare.setAllowSpikes(allowSpikes);
|
||||
if (mainVariable) {
|
||||
compare.setOneOfTheMainVariables(true);
|
||||
std::string str(mainVariable);
|
||||
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
|
||||
if(str == "WOPR" ||str=="WWPR" ||str=="WGPR" || str == "WBHP"){
|
||||
compare.setMainVariable(str);
|
||||
}else{
|
||||
throw std::invalid_argument("The input is not a main variable. -m option requires a valid main variable.");
|
||||
}
|
||||
}
|
||||
compare.setFindVolumeError(findVolumeError);
|
||||
if (spikeLimit != -1) {
|
||||
compare.setSpikeLimit(spikeLimit);
|
||||
}
|
||||
compare.setAllowDifferentAmountOfKeywords(allowDifferentAmount);
|
||||
compare.setPrintKeywords(printKeywords);
|
||||
compare.setThrowExceptionForTooGreatErrorRatio(throwTooGreatErrorRatio);
|
||||
if(specificKeyword){
|
||||
compare.setPrintSpecificKeyword(specificKeyword);
|
||||
compare.getIntegrationTest(keyword);
|
||||
return 0;
|
||||
}
|
||||
compare.getIntegrationTest();
|
||||
}
|
||||
}
|
||||
else if (integrationTest) {
|
||||
ECLIntegrationTest comparator(basename1, basename2, absTolerance, relTolerance);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
}
|
||||
if (printKeywordsDifference) {
|
||||
comparator.printKeywordsDifference();
|
||||
return 0;
|
||||
}
|
||||
if (checkNumKeywords) {
|
||||
comparator.equalNumKeywords();
|
||||
}
|
||||
if (specificKeyword) {
|
||||
if (comparator.elementInWhitelist(keyword)) {
|
||||
comparator.resultsForKeyword(keyword);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Keyword " << keyword << " is not supported for the integration test. Use SGAS, SWAT or PRESSURE." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
comparator.results();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ECLRegressionTest comparator(file_type, basename1, basename2, absTolerance, relTolerance);
|
||||
comparator.throwOnErrors(throwOnError);
|
||||
comparator.doAnalysis(analysis);
|
||||
comparator.setAcceptExtraKeywords(acceptExtraKeywords);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
}
|
||||
if (printKeywordsDifference) {
|
||||
comparator.printKeywordsDifference();
|
||||
return 0;
|
||||
}
|
||||
if (onlyLastOccurrence) {
|
||||
comparator.setOnlyLastOccurrence(true);
|
||||
}
|
||||
if (specificKeyword) {
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.resultsForKeyword(keyword);
|
||||
}
|
||||
else {
|
||||
comparator.gridCompare(volumecheck);
|
||||
comparator.results();
|
||||
}
|
||||
if (comparator.getNoErrors() > 0)
|
||||
OPM_THROW(std::runtime_error, comparator.getNoErrors() << " errors encountered in comparisons.");
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Program threw an exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms
|
||||
of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "summaryRegressionTest.hpp"
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <getopt.h>
|
||||
|
||||
void printHelp(){
|
||||
std::cout << "\n\nThe program can handle both unified and non-unified summary files."<< std::endl;
|
||||
std::cout <<"In the case of non-unified summary files all the files must be located in the same directory. Only the basename (full path without extension) is needed as input." << std::endl << std::endl;
|
||||
std::cout << "\nThe program takes four arguments" << std::endl;
|
||||
std::cout << "1) <path to file1>/<base_name>, basename without extension" << std::endl;
|
||||
std::cout << "2) <path to file2>/<base_name>, basename without extension" << std::endl;
|
||||
std::cout << "3) absolute tolerance" << std::endl;
|
||||
std::cout << "4) relative tolerance (between 0 and 1)" << std::endl;
|
||||
std::cout << "The program will only throw an exception when both the absolute and relative tolerance are exceeded." << std::endl;
|
||||
std::cout << "The program is capable of performing both a regression test and an integration test, \nhowever only one type of test at a time. ";
|
||||
std::cout << "By default the program will run a regression test."<< std::endl;
|
||||
std::cout << "\nThe program have command line options:" << std::endl;
|
||||
std::cout << "-a \tRun a full analysis of errors." << std::endl;
|
||||
std::cout << "-h \t\tPrint help message." << std::endl << std::endl;
|
||||
std::cout << "For the regression test: " << std::endl;
|
||||
std::cout << "-r \t\tChoosing regression test (this is default)."<< std::endl;
|
||||
std::cout << "-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<< std::endl;
|
||||
std::cout << "-p \t\tWill print the keywords of the files." << std::endl;
|
||||
std::cout << "-R \t\tWill allow comparison between a restarted simulation and a normal simulation. The files must end at the same time." << std::endl << std::endl;
|
||||
std::cout << "For the integration test:"<< std::endl;
|
||||
std::cout << "-i \t\tChoosing integration test." << std::endl;
|
||||
std::cout << "-d \t\tThe program will not throw an exception when the volume error ratio exceeds the limit." << std::endl;
|
||||
std::cout << "-g \t\tWill print the vector with the greatest error ratio." << std::endl;
|
||||
std::cout << "-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<< std::endl;
|
||||
std::cout << "-K \t\tWill not allow different amount of keywords in the two files. Throws an exception if the amount are different." << std::endl;
|
||||
std::cout << "-m mainVar \tWill calculate the error ratio for one main variable. Valid input is WOPR, WWPR, WGPR or WBHP." << std::endl;
|
||||
std::cout << "-n \tDo not throw on errors." << std::endl;
|
||||
std::cout << "-p \t\tWill print the keywords of the files." << std::endl;
|
||||
std::cout << "-P keyword \tWill print the summary vectors of a specified kewyord, for example -P WOPR:B-3H." << std::endl;
|
||||
std::cout << "-s int \t\tSets the number of spikes that are allowed for each keyword, for example: -s 5." << std::endl;
|
||||
std::cout << "-v \t\tFor the rate keywords WOPR, WGPR, WWPR and WBHP. Calculates the error volume of \n\t\tthe two summary files. This is printed to screen." << std::endl;
|
||||
std::cout << "-V keyword \tWill calculate the error rate for a specific keyword." << std::endl << std::endl;
|
||||
std::cout << "Suggested combination of command line options:"<< std::endl;
|
||||
std::cout << " -i -g -m mainVariable, will print the vector which have the greatest error ratio of the main variable of interest.\n"<< std::endl;
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
|
||||
|
||||
int main (int argc, char ** argv){
|
||||
|
||||
//------------------------------------------------
|
||||
//Defines some constants
|
||||
bool specificKeyword = false;
|
||||
bool allowSpikes = false;
|
||||
bool findVolumeError = false;
|
||||
bool integrationTest = false;
|
||||
bool regressionTest = true;
|
||||
bool allowDifferentAmountOfKeywords = true;
|
||||
bool printKeywords = false;
|
||||
bool printSpecificKeyword = false;
|
||||
bool findVectorWithGreatestErrorRatio = false;
|
||||
bool oneOfTheMainVariables = false;
|
||||
bool throwExceptionForTooGreatErrorRatio = true;
|
||||
bool isRestartFile = false;
|
||||
bool throwOnError = true;
|
||||
bool analysis = false;
|
||||
const char* keyword = nullptr;
|
||||
const char* mainVariable = nullptr;
|
||||
int c = 0;
|
||||
int limit = -1;
|
||||
//------------------------------------------------
|
||||
|
||||
//------------------------------------------------
|
||||
//For setting the options selected
|
||||
while ((c = getopt(argc, argv, "dghik:Km:napP:rRs:vV:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'd':
|
||||
throwExceptionForTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'g':
|
||||
findVectorWithGreatestErrorRatio = true;
|
||||
throwExceptionForTooGreatErrorRatio = false;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
case 'i':
|
||||
integrationTest = true;
|
||||
regressionTest = false;
|
||||
break;
|
||||
case 'k':
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'K':
|
||||
allowDifferentAmountOfKeywords = false;
|
||||
break;
|
||||
case 'm':
|
||||
oneOfTheMainVariables = true;
|
||||
mainVariable = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
throwOnError = false;
|
||||
break;
|
||||
case 'p':
|
||||
printKeywords = true;
|
||||
break;
|
||||
case 'P':
|
||||
specificKeyword = true;
|
||||
printSpecificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
integrationTest = false;
|
||||
regressionTest = true;
|
||||
break;
|
||||
case 'R':
|
||||
isRestartFile = true;
|
||||
break;
|
||||
case 's':
|
||||
allowSpikes = true;
|
||||
limit = atof(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
findVolumeError = true;
|
||||
break;
|
||||
case 'V':
|
||||
findVolumeError = true;
|
||||
specificKeyword = true;
|
||||
keyword = optarg;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 'k' || optopt == 'm' || optopt == 'P'
|
||||
|| optopt == 's' || optopt == 'V') {
|
||||
std::cout << "Option -"<<optopt<<" requires an keyword." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown option." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------
|
||||
|
||||
int argOffset = optind;
|
||||
if (argc != argOffset + 4) {
|
||||
printHelp();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const char * basename1 = argv[argOffset];
|
||||
const char * basename2 = argv[argOffset+1];
|
||||
double absoluteTolerance = strtod(argv[argOffset+2], nullptr);
|
||||
double relativeTolerance = strtod(argv[argOffset+3], nullptr);
|
||||
|
||||
std::cout << "Comparing '" << basename1 << "' to '" << basename2 << "'." << std::endl;
|
||||
|
||||
try {
|
||||
if(regressionTest){
|
||||
SummaryRegressionTest compare(basename1,basename2, absoluteTolerance, relativeTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.doAnalysis(analysis);
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
if(isRestartFile){compare.setIsRestartFile(true);}
|
||||
if(specificKeyword){
|
||||
compare.getRegressionTest(keyword);
|
||||
}
|
||||
else{
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
compare.getRegressionTest();
|
||||
}
|
||||
}
|
||||
if(integrationTest){
|
||||
SummaryIntegrationTest compare(basename1,basename2, absoluteTolerance, relativeTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
if(findVectorWithGreatestErrorRatio){compare.setFindVectorWithGreatestErrorRatio(true);}
|
||||
if(allowSpikes){compare.setAllowSpikes(true);}
|
||||
if(oneOfTheMainVariables){
|
||||
compare.setOneOfTheMainVariables(true);
|
||||
std::string str(mainVariable);
|
||||
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
|
||||
if(str == "WOPR" ||str=="WWPR" ||str=="WGPR" || str == "WBHP"){
|
||||
compare.setMainVariable(str);
|
||||
}else{
|
||||
throw std::invalid_argument("The input is not a main variable. -m option requires a valid main variable.");
|
||||
}
|
||||
}
|
||||
if(findVolumeError){compare.setFindVolumeError(true);}
|
||||
if(limit != -1){compare.setSpikeLimit(limit);}
|
||||
if(!allowDifferentAmountOfKeywords){compare.setAllowDifferentAmountOfKeywords(false);}
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
if(!throwExceptionForTooGreatErrorRatio){compare.setThrowExceptionForTooGreatErrorRatio(false);}
|
||||
if(specificKeyword){
|
||||
if(printSpecificKeyword){compare.setPrintSpecificKeyword(true);}
|
||||
compare.getIntegrationTest(keyword);
|
||||
return 0;
|
||||
}
|
||||
compare.getIntegrationTest();
|
||||
}
|
||||
}
|
||||
catch(const std::exception& e) {
|
||||
std::cerr << "Program threw an exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "summaryComparator.hpp"
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/int_vector.h>
|
||||
#include <ert/util/bool_vector.h>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
SummaryComparator::SummaryComparator(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absoluteTol, double relativeTol){
|
||||
ecl_sum1 = ecl_sum_fread_alloc_case(basename1.c_str(), ":");
|
||||
ecl_sum2 = ecl_sum_fread_alloc_case(basename2.c_str(), ":");
|
||||
if (ecl_sum1 == nullptr || ecl_sum2 == nullptr) {
|
||||
OPM_THROW(std::runtime_error, "Not able to open files");
|
||||
}
|
||||
absoluteTolerance = absoluteTol;
|
||||
relativeTolerance = relativeTol;
|
||||
keys1 = stringlist_alloc_new();
|
||||
keys2 = stringlist_alloc_new();
|
||||
ecl_sum_select_matching_general_var_list( ecl_sum1 , "*" , this->keys1);
|
||||
stringlist_sort(this->keys1 , nullptr );
|
||||
ecl_sum_select_matching_general_var_list( ecl_sum2 , "*" , this->keys2);
|
||||
stringlist_sort(this->keys2 , nullptr );
|
||||
|
||||
if(stringlist_get_size(keys1) <= stringlist_get_size(keys2)){
|
||||
this->keysShort = this->keys1;
|
||||
this->keysLong = this->keys2;
|
||||
}else{
|
||||
this->keysShort = this->keys2;
|
||||
this->keysLong = this->keys1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SummaryComparator::~SummaryComparator(){
|
||||
ecl_sum_free(ecl_sum1);
|
||||
ecl_sum_free(ecl_sum2);
|
||||
stringlist_free(keys1);
|
||||
stringlist_free(keys2);
|
||||
}
|
||||
|
||||
|
||||
Deviation SummaryComparator::calculateDeviations(double val1, double val2){
|
||||
double absDev;
|
||||
Deviation deviation;
|
||||
absDev = std::abs(val1 - val2);
|
||||
deviation.abs = absDev;
|
||||
if (val1 != 0 || val2 != 0) {
|
||||
deviation.rel = absDev/double(std::max(std::abs(val1), std::abs(val2)));
|
||||
}
|
||||
return deviation;
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::setTimeVecs(std::vector<double> &timeVec1,
|
||||
std::vector<double> &timeVec2){
|
||||
timeVec1.reserve(ecl_sum_get_data_length(ecl_sum1));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum1); time_index++){
|
||||
timeVec1.push_back(ecl_sum_iget_sim_days(ecl_sum1 , time_index ));
|
||||
}
|
||||
timeVec2.reserve(ecl_sum_get_data_length(ecl_sum2));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum2); time_index++){
|
||||
timeVec2.push_back(ecl_sum_iget_sim_days(ecl_sum2 , time_index ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::getDataVecs(std::vector<double> &dataVec1,
|
||||
std::vector<double> &dataVec2,
|
||||
const char* keyword){
|
||||
dataVec1.reserve(ecl_sum_get_data_length(ecl_sum1));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum1); time_index++){
|
||||
dataVec1.push_back(ecl_sum_iget(ecl_sum1, time_index, ecl_sum_get_general_var_params_index( ecl_sum1 , keyword )));
|
||||
}
|
||||
dataVec2.reserve(ecl_sum_get_data_length(ecl_sum2));
|
||||
for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum2); time_index++){
|
||||
|
||||
dataVec2.push_back(ecl_sum_iget(ecl_sum2, time_index, ecl_sum_get_general_var_params_index( ecl_sum2 , keyword )));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::setDataSets(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2){
|
||||
if(timeVec1.size() < timeVec2.size()){
|
||||
ecl_sum_fileShort = this->ecl_sum1;
|
||||
ecl_sum_fileLong = this->ecl_sum2;
|
||||
}
|
||||
else{
|
||||
ecl_sum_fileShort = this->ecl_sum2;
|
||||
ecl_sum_fileLong = this->ecl_sum1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::chooseReference(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& dataVec2){
|
||||
if(timeVec1.size() <= timeVec2.size()){
|
||||
referenceVec = &timeVec1; // time vector
|
||||
referenceDataVec = &dataVec1; //data vector
|
||||
checkVec = &timeVec2;
|
||||
checkDataVec = &dataVec2;
|
||||
}
|
||||
else{
|
||||
referenceVec = &timeVec2;
|
||||
referenceDataVec = &dataVec2;
|
||||
checkVec = &timeVec1;
|
||||
checkDataVec = &dataVec1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::getDeviation(size_t refIndex, size_t &checkIndex, Deviation &dev){
|
||||
if((*referenceVec)[refIndex] == (*checkVec)[checkIndex]){
|
||||
dev = SummaryComparator::calculateDeviations((*referenceDataVec)[refIndex], (*checkDataVec)[checkIndex]);
|
||||
checkIndex++;
|
||||
return;
|
||||
}
|
||||
else if((*referenceVec)[refIndex]<(*checkVec)[checkIndex]){
|
||||
double value = SummaryComparator::unitStep((*checkDataVec)[checkIndex]);
|
||||
/*Must be a little careful here. Flow writes out old value first,
|
||||
than changes value. Say there should be a change in production rate from A to B at timestep 300.
|
||||
Then the data of time step 300 is A and the next timestep will have value B. Must use the upper limit. */
|
||||
dev = SummaryComparator::calculateDeviations((*referenceDataVec)[refIndex], value);
|
||||
checkIndex++;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
checkIndex++;
|
||||
getDeviation(refIndex, checkIndex , dev);
|
||||
}
|
||||
if(checkIndex == checkVec->size() -1 ){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printUnits(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
std::cout << stringlist_iget(keysLong, jvar) << " unit: " << ecl_sum_get_unit(ecl_sum_fileShort, stringlist_iget(keysLong, jvar)) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Called only when the keywords are equal in the getDeviations()-function
|
||||
const char* SummaryComparator::getUnit(const char* keyword){
|
||||
return ecl_sum_get_unit(ecl_sum_fileShort, keyword);
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printKeywords(){
|
||||
int ivar = 0;
|
||||
std::vector<std::string> noMatchString;
|
||||
std::cout << "Keywords that are common for the files:" << std::endl;
|
||||
while(ivar < stringlist_get_size(keysLong)){
|
||||
const char* keyword = stringlist_iget(keysLong, ivar);
|
||||
if (stringlist_contains(keysLong, keyword) && stringlist_contains(keysShort, keyword)){
|
||||
std::cout << keyword << std::endl;
|
||||
ivar++;
|
||||
}
|
||||
else{
|
||||
noMatchString.push_back(keyword);
|
||||
ivar++;
|
||||
}
|
||||
}
|
||||
if(noMatchString.size() == 0){
|
||||
std::cout << "No keywords were different" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Keywords that are different: " << std::endl;
|
||||
for (const auto& it : noMatchString) std::cout << it << std::endl;
|
||||
|
||||
std::cout << "\nOf the " << stringlist_get_size(keysLong) << " keywords " << stringlist_get_size(keysLong)-noMatchString.size() << " were equal and " << noMatchString.size() << " were different" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void SummaryComparator::printDataOfSpecificKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
size_t ivar = 0;
|
||||
size_t jvar = 0;
|
||||
const char separator = ' ';
|
||||
const int numWidth = 14;
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Time";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Ref data";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "Check data" << std::endl;
|
||||
|
||||
while(ivar < referenceVec->size()){
|
||||
if(ivar == referenceVec->size() || jvar == checkVec->size() ){
|
||||
break;
|
||||
}
|
||||
if((*referenceVec)[ivar] == (*checkVec)[jvar]){
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceDataVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkDataVec)[jvar] << std::endl;
|
||||
ivar++;
|
||||
jvar++;
|
||||
}else if((*referenceVec)[ivar] < (*checkVec)[jvar]){
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*referenceDataVec)[ivar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "" << std::endl;
|
||||
ivar++;
|
||||
}
|
||||
else{
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkVec)[jvar];
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << "";
|
||||
std::cout << std::left << std::setw(numWidth) << std::setfill(separator) << (*checkDataVec)[jvar] << std::endl;
|
||||
jvar++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SUMMARYCOMPARATOR_HPP
|
||||
#define SUMMARYCOMPARATOR_HPP
|
||||
|
||||
#include "Deviation.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
|
||||
// helper macro to handle error throws or not
|
||||
#define HANDLE_ERROR(type, message) \
|
||||
{ \
|
||||
if (throwOnError) \
|
||||
OPM_THROW(type, message); \
|
||||
else \
|
||||
std::cerr << message << std::endl; \
|
||||
}
|
||||
|
||||
|
||||
//! \brief Prototyping struct, encapsuling the stringlist libraries.
|
||||
struct stringlist_struct;
|
||||
typedef struct stringlist_struct stringlist_type;
|
||||
|
||||
//! \brief Prototyping struct, encapsuling the ert libraries.
|
||||
struct ecl_sum_struct;
|
||||
typedef struct ecl_sum_struct ecl_sum_type;
|
||||
|
||||
|
||||
class SummaryComparator {
|
||||
private:
|
||||
double absoluteTolerance = 0; //!< The maximum absolute deviation that is allowed between two values.
|
||||
double relativeTolerance = 0; //!< The maximum relative deviation that is allowed between twi values.
|
||||
protected:
|
||||
ecl_sum_type * ecl_sum1 = nullptr; //!< Struct that contains file1
|
||||
ecl_sum_type * ecl_sum2 = nullptr; //!< Struct that contains file2
|
||||
ecl_sum_type * ecl_sum_fileShort = nullptr; //!< For keeping track of the file with most/fewest timesteps
|
||||
ecl_sum_type * ecl_sum_fileLong = nullptr; //!< For keeping track of the file with most/fewest timesteps
|
||||
stringlist_type* keys1 = nullptr; //!< For storing all the keywords of file1
|
||||
stringlist_type* keys2 = nullptr; //!< For storing all the keywords of file2
|
||||
stringlist_type * keysShort = nullptr; //!< For keeping track of the file with most/fewest keywords
|
||||
stringlist_type * keysLong = nullptr; //!< For keeping track of the file with most/fewest keywords
|
||||
const std::vector<double> * referenceVec = nullptr; //!< For storing the values of each time step for the file containing the fewer time steps.
|
||||
const std::vector<double> * referenceDataVec = nullptr; //!< For storing the data corresponding to each time step for the file containing the fewer time steps.
|
||||
const std::vector<double> * checkVec = nullptr; //!< For storing the values of each time step for the file containing the more time steps.
|
||||
const std::vector<double> * checkDataVec = nullptr; //!< For storing the data values corresponding to each time step for the file containing the more time steps.
|
||||
bool printKeyword = false; //!< Boolean value for choosing whether to print the keywords or not
|
||||
bool printSpecificKeyword = false; //!< Boolean value for choosing whether to print the vectors of a keyword or not
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
|
||||
//! \brief Calculate deviation between two data values and stores it in a Deviation struct.
|
||||
//! \param[in] refIndex Index in reference data
|
||||
//! \param[in] checkindex Index in data to be checked.
|
||||
//! \param[out] dev Holds the result from the comparison on return.
|
||||
//! \details Uses the #referenceVec as basis, and checks its values against the values in #checkDataVec. The function is reccursive, and will update the iterative index j of the #checkVec until #checkVec[j] >= #referenceVec[i]. \n When #referenceVec and #checkVec have the same time value (i.e. #referenceVec[i] == #checkVec[j]) a direct comparison is used, \n when this is not the case, when #referenceVec[i] do not excist as an element in #checkVec, a value is generated, either by the principle of unit step or by interpolation.
|
||||
void getDeviation(size_t refIndex, size_t &checkIndex, Deviation &dev);
|
||||
|
||||
//! \brief Figure out which data file contains the most / less timesteps and assign member variable pointers accordingly.
|
||||
//! \param[in] timeVec1 Data from first file
|
||||
//! \param[in] timeVec2 Data from second file
|
||||
//! \details Figure out which data file that contains the more/fewer time steps and assigns the private member variable pointers #ecl_sum_fileShort / #ecl_sum_fileLong to the correct data sets #ecl_sum1 / #ecl_sum2.
|
||||
void setDataSets(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2);
|
||||
|
||||
//! \brief Reads in the time values of each time step.
|
||||
//! \param[in] timeVec1 Vector for storing the time steps from file1
|
||||
//! \param[in] timeVec2 Vector for storing the time steps from file2
|
||||
void setTimeVecs(std::vector<double> &timeVec1,std::vector<double> &timeVec2);
|
||||
|
||||
//! \brief Read the data for one specific keyword into two separate vectors.
|
||||
//! \param[in] dataVec1 Vector for storing the data for one specific keyword from file1
|
||||
//! \param[in] dataVec2 Vector for storing the data for one specific keyword from file2
|
||||
//! \details The two data files do not necessarily have the same amount of data values, but the values must correspond to the same interval in time. Thus possible to interpolate values.
|
||||
void getDataVecs(std::vector<double> &dataVec1,
|
||||
std::vector<double> &dataVec2, const char* keyword);
|
||||
|
||||
//! \brief Sets one data set as a basis and the other as values to check against.
|
||||
//! \param[in] timeVec1 Used to figure out which dataset that have the more/fewer time steps.
|
||||
//! \param[in] timeVec2 Used to figure out which dataset that have the more/fewer time steps.
|
||||
//! \param[in] dataVec1 For assiging the the correct pointer to the data vector.
|
||||
//! \param[in] dataVec2 For assiging the the correct pointer to the data vector.
|
||||
//! \details Figures out which time vector that contains the fewer elements. Sets this as #referenceVec and its corresponding data as #referenceDataVec. \n The remaining data set is set as #checkVec (the time vector) and #checkDataVec.
|
||||
void chooseReference(const std::vector<double> &timeVec1,
|
||||
const std::vector<double> &timeVec2,
|
||||
const std::vector<double> &dataVec1,
|
||||
const std::vector<double> &dataVec2);
|
||||
|
||||
//! \brief Returns the relative tolerance.
|
||||
double getRelTolerance(){return this->relativeTolerance;}
|
||||
|
||||
//! \brief Returns the absolute tolerance.
|
||||
double getAbsTolerance(){return this->absoluteTolerance;}
|
||||
|
||||
//! \brief Returns the unit of the values of a keyword
|
||||
//! \param[in] keyword The keyword of interest.
|
||||
//! \param[out] ret The unit of the keyword as a const char*.
|
||||
const char* getUnit(const char* keyword);
|
||||
|
||||
//! \brief Prints the units of the files.
|
||||
void printUnits();
|
||||
|
||||
//! \brief Prints the keywords of the files.
|
||||
//! \details The function prints first the common keywords, than the keywords that are different.
|
||||
void printKeywords();
|
||||
|
||||
//! \brief Prints the summary vectors from the two files.
|
||||
//! \details The function requires that the summary vectors of the specific file have been read into the member variables referenceVec etc.
|
||||
void printDataOfSpecificKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword);
|
||||
|
||||
public:
|
||||
//! \brief Creates an SummaryComparator class object
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \param[in] absoluteTolerance The absolute tolerance which is to be used in the test.
|
||||
//! \param[in] relativeTolerance The relative tolerance which is to be used in the test.
|
||||
//! \details The constructor creates an object of the class, and openes the files, an exception is thrown if the opening of the files fails. \n It creates stringlists, in which keywords are to be stored, and figures out which keylist that contains the more/less keywords. \n Also the private member variables aboluteTolerance and relativeTolerance are set.
|
||||
SummaryComparator(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double absoluteTolerance, double relativeTolerance);
|
||||
|
||||
//! \brief Destructor
|
||||
//! \details The destructor takes care of the allocated memory in which data has been stored.
|
||||
~SummaryComparator();
|
||||
|
||||
//! \brief Calculates the deviation between two values
|
||||
//! \param[in] val1 The first value of interest.
|
||||
//! \param[in] val2 The second value if interest.
|
||||
//! \param[out] ret Returns a Deviation struct.
|
||||
//! \details The function takes two values, calculates the absolute and relative deviation and returns the result as a Deviation struct.
|
||||
static Deviation calculateDeviations( double val1, double val2);
|
||||
|
||||
//! \brief Sets the private member variable printKeywords
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details The function sets the private member variable printKeywords. When it is true the function printKeywords will be called.
|
||||
void setPrintKeywords(bool boolean){this->printKeyword = boolean;}
|
||||
|
||||
//! \brief Sets the private member variable printSpecificKeyword
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details The function sets the private member variable printSpecificKeyword. When true, the summary vector of the keyword for both files will be printed.
|
||||
void setPrintSpecificKeyword(bool boolean){this->printSpecificKeyword = boolean;}
|
||||
|
||||
//! \brief Unit step function
|
||||
//! \param[in] value The input value should be the last know value
|
||||
//! \param[out] ret Return the unit-step-function value.
|
||||
//! \details In this case: The unit step function is used when the data from the two data set, which is to be compared, don't match in time. \n The unit step function is then to be called on the #checkDataVec 's value at the last time step which is before the time of comparison.
|
||||
|
||||
//! \brief Returns a value based on the unit step principle.
|
||||
static double unitStep(double value){return value;}
|
||||
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether or not to perform error analysis.
|
||||
void doAnalysis(bool analyse) { analysis = analyse; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,389 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under the terms of
|
||||
the GNU General Public License as published by the Free Software Foundation, either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "summaryIntegrationTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
void SummaryIntegrationTest::getIntegrationTest(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
|
||||
int ivar = 0;
|
||||
if(!allowDifferentAmountOfKeywords){
|
||||
if(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)){
|
||||
OPM_THROW(std::invalid_argument, "Different ammont of keywords in the two summary files.");
|
||||
}
|
||||
}
|
||||
if(printKeyword){
|
||||
printKeywords();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string keywordWithGreatestErrorRatio;
|
||||
double greatestRatio = 0;
|
||||
|
||||
//Iterates over all keywords from the restricted file, use iterator "ivar". Searches for a match in the file with more keywords, use the itarator "jvar".
|
||||
while(ivar < stringlist_get_size(keysShort)){
|
||||
const char* keyword = stringlist_iget(keysShort, ivar);
|
||||
|
||||
if(oneOfTheMainVariables){
|
||||
std::string keywordString(keyword);
|
||||
std::string substr = keywordString.substr(0,4);
|
||||
if(substr!= mainVariable){
|
||||
ivar++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
|
||||
if (strcmp(keyword, stringlist_iget(keysLong, jvar)) == 0){ //When the keywords are equal, proceed in comparing summary files.
|
||||
/* if(!checkUnits(keyword)){
|
||||
OPM_THROW(std::runtime_error, "For keyword " << keyword << " the unit of the two files is not equal. Not possible to compare.");
|
||||
} //Comparing the unit of the two vectors.*/
|
||||
checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
if(findVectorWithGreatestErrorRatio){
|
||||
WellProductionVolume volume = getSpecificWellVolume(timeVec1,timeVec2, keyword);
|
||||
findGreatestErrorRatio(volume,greatestRatio, keyword, keywordWithGreatestErrorRatio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//will only enter here if no keyword match
|
||||
if(jvar == stringlist_get_size(keysLong)-1){
|
||||
if(!allowDifferentAmountOfKeywords){
|
||||
OPM_THROW(std::invalid_argument, "No match on keyword");
|
||||
}
|
||||
}
|
||||
}
|
||||
ivar++;
|
||||
}
|
||||
if(findVectorWithGreatestErrorRatio){
|
||||
std::cout << "The keyword " << keywordWithGreatestErrorRatio << " had the greatest error ratio, which was " << greatestRatio << std::endl;
|
||||
}
|
||||
if((findVolumeError || oneOfTheMainVariables) && !findVectorWithGreatestErrorRatio){
|
||||
evaluateWellProductionVolume();
|
||||
}
|
||||
if(allowSpikes){
|
||||
std::cout << "checkWithSpikes succeeded." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::getIntegrationTest(const char* keyword){
|
||||
if(stringlist_contains(keysShort,keyword) && stringlist_contains(keysLong, keyword)){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2);
|
||||
|
||||
if(printSpecificKeyword){
|
||||
printDataOfSpecificKeyword(timeVec1, timeVec2, keyword);
|
||||
}
|
||||
if(findVolumeError){
|
||||
WellProductionVolume volume = getSpecificWellVolume(timeVec1, timeVec2, keyword);
|
||||
if(volume.error == 0){
|
||||
std::cout << "For keyword " << keyword << " the total production volume is 0" << std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << "For keyword " << keyword << " the total production volume is "<< volume.total;
|
||||
std::cout << ", the error volume is " << volume.error << " the error ratio is " << volume.error/volume.total << std::endl;
|
||||
}
|
||||
}
|
||||
checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
return;
|
||||
}
|
||||
OPM_THROW(std::invalid_argument, "The keyword used is not common for the two files.");
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::checkForKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
if(allowSpikes){
|
||||
checkWithSpikes(keyword);
|
||||
}
|
||||
if(findVolumeError ||oneOfTheMainVariables ){
|
||||
volumeErrorCheck(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SummaryIntegrationTest::checkDeviation(const Deviation& deviation){
|
||||
double absTol = getAbsTolerance();
|
||||
double relTol = getRelTolerance();
|
||||
if (deviation.rel> relTol && deviation.abs > absTol){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
double &greatestRatio,
|
||||
const char* currentKeyword,
|
||||
std::string &greatestErrorRatio){
|
||||
if (volume.total != 0 && (volume.total - volume.error > getAbsTolerance()) ){
|
||||
if(volume.error/volume.total > greatestRatio){
|
||||
greatestRatio = volume.error/volume.total;
|
||||
std::string currentKeywordStr(currentKeyword);
|
||||
greatestErrorRatio = currentKeywordStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::volumeErrorCheck(const char* keyword){
|
||||
const smspec_node_type * node = ecl_sum_get_general_var_node (ecl_sum_fileShort ,keyword);//doesn't matter which ecl_sum_file one uses, the kewyord SHOULD be equal in terms of smspec data.
|
||||
bool hist = smspec_node_is_historical(node);
|
||||
/* returns true if the keyword corresponds to a summary vector "history".
|
||||
E.g. WOPRH, where the last character, 'H', indicates that it is a HISTORY vector.*/
|
||||
if(hist){
|
||||
return;//To make sure we do not include history vectors.
|
||||
}
|
||||
if (!mainVariable.empty()){
|
||||
std::string keywordString(keyword);
|
||||
std::string firstFour = keywordString.substr(0,4);
|
||||
|
||||
if(mainVariable == firstFour && firstFour == "WOPR"){
|
||||
if(firstFour == "WOPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WOP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WWPR"){
|
||||
if(firstFour == "WWPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WWP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WGPR"){
|
||||
if(firstFour == "WGPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WGP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mainVariable == firstFour && firstFour == "WBHP"){
|
||||
if(firstFour == "WBHP"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WBHP += result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateVolumeError(keyword);
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::updateVolumeError(const char* keyword){
|
||||
std::string keywordString(keyword);
|
||||
std::string firstFour = keywordString.substr(0,4);
|
||||
|
||||
if(firstFour == "WOPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WOP += result;
|
||||
}
|
||||
if(firstFour == "WWPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WWP += result;
|
||||
}
|
||||
if(firstFour == "WGPR"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WGP += result;
|
||||
|
||||
}
|
||||
if(firstFour == "WBHP"){
|
||||
WellProductionVolume result = getWellProductionVolume(keyword);
|
||||
WBHP += result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WellProductionVolume SummaryIntegrationTest::getWellProductionVolume(const char * keyword){
|
||||
double total = integrate(*referenceVec, *referenceDataVec);
|
||||
double error = integrateError(*referenceVec, *referenceDataVec,
|
||||
*checkVec, *checkDataVec);
|
||||
WellProductionVolume wPV;
|
||||
wPV.total = total;
|
||||
wPV.error = error;
|
||||
if(wPV.total != 0 && wPV.total-wPV.error > getAbsTolerance()){
|
||||
if( (wPV.error/wPV.total > getRelTolerance()) && throwExceptionForTooGreatErrorRatio){
|
||||
OPM_THROW(std::runtime_error, "For the keyword "<< keyword << " the error ratio was " << wPV.error/wPV.total << " which is greater than the tolerance " << getRelTolerance());
|
||||
}
|
||||
}
|
||||
return wPV;
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::evaluateWellProductionVolume(){
|
||||
if(mainVariable.empty()){
|
||||
double ratioWOP, ratioWWP, ratioWGP, ratioWBHP;
|
||||
ratioWOP = WOP.error/WOP.total;
|
||||
ratioWWP = WWP.error/WWP.total;
|
||||
ratioWGP = WGP.error/WGP.total;
|
||||
ratioWBHP = WBHP.error/WBHP.total;
|
||||
std::cout << "\n The total oil volume is " << WOP.total << ". The error volume is "<< WOP.error << ". The error ratio is " << ratioWOP << std::endl;
|
||||
std::cout << "\n The total water volume is " << WWP.total << ". The error volume is "<< WWP.error << ". The error ratio is " << ratioWWP << std::endl;
|
||||
std::cout << "\n The total gas volume is " << WGP.total <<". The error volume is "<< WGP.error << ". The error ratio is " << ratioWGP << std::endl;
|
||||
std::cout << "\n The total area under the WBHP curve is " << WBHP.total << ". The area under the error curve is "<< WBHP.error << ". The error ratio is " << ratioWBHP << std::endl << std::endl;
|
||||
}
|
||||
if(mainVariable == "WOPR"){
|
||||
std::cout << "\nThe total oil volume is " << WOP.total << ". The error volume is "<< WOP.error << ". The error ratio is " << WOP.error/WOP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WWPR"){
|
||||
std::cout << "\nThe total water volume is " << WWP.total << ". The error volume is "<< WWP.error << ". The error ratio is " << WWP.error/WWP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WGPR"){
|
||||
std::cout << "\nThe total gas volume is " << WGP.total <<". The error volume is "<< WGP.error << ". The error ratio is " << WGP.error/WGP.total << std::endl<< std::endl;
|
||||
}
|
||||
if(mainVariable == "WBHP"){
|
||||
std::cout << "\nThe total area under the WBHP curve " << WBHP.total << ". The area under the error curve is "<< WBHP.error << ". The error ratio is " << WBHP.error/WBHP.total << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SummaryIntegrationTest::checkWithSpikes(const char* keyword){
|
||||
int errorOccurrences = 0;
|
||||
size_t jvar = 0 ;
|
||||
bool spikeCurrent = false;
|
||||
Deviation deviation;
|
||||
|
||||
for (size_t ivar = 0; ivar < referenceVec->size(); ivar++){
|
||||
int errorOccurrencesPrev = errorOccurrences;
|
||||
bool spikePrev = spikeCurrent;
|
||||
getDeviation(ivar,jvar, deviation);
|
||||
errorOccurrences += checkDeviation(deviation);
|
||||
if (errorOccurrences != errorOccurrencesPrev){
|
||||
spikeCurrent = true;
|
||||
} else{
|
||||
spikeCurrent = false;
|
||||
}
|
||||
if(spikePrev&&spikeCurrent){
|
||||
std::cout << "For keyword " << keyword << " at time step " << (*referenceVec)[ivar] <<std::endl;
|
||||
OPM_THROW(std::invalid_argument, "For keyword " << keyword << " at time step " << (*referenceVec)[ivar] << ", wwo deviations in a row exceed the limit. Not a spike value. Integration test fails." );
|
||||
}
|
||||
if(errorOccurrences > this->spikeLimit){
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
OPM_THROW(std::invalid_argument, "For keyword " << keyword << " too many spikes in the vector. Integration test fails.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WellProductionVolume
|
||||
SummaryIntegrationTest::getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
return getWellProductionVolume(keyword);
|
||||
}
|
||||
|
||||
|
||||
double SummaryIntegrationTest::integrate(const std::vector<double>& timeVec,
|
||||
const std::vector<double>& dataVec){
|
||||
double totalSum = 0;
|
||||
if(timeVec.size() != dataVec.size()){
|
||||
OPM_THROW(std::runtime_error, "The size of the time vector does not match the size of the data vector.");
|
||||
}
|
||||
for(size_t i = 0; i < timeVec.size()-1; i++){
|
||||
double width = timeVec[i+1] - timeVec[i];
|
||||
double height = dataVec[i+1];
|
||||
totalSum += getRectangleArea(height, width);
|
||||
}
|
||||
return totalSum;
|
||||
}
|
||||
|
||||
|
||||
double SummaryIntegrationTest::integrateError(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec2){
|
||||
// When the data corresponds to a rate the integration will become a Riemann
|
||||
// sum. This function calculates the Riemann sum of the error. The reason why
|
||||
// a Riemann sum is used is because of the way the data is written to file.
|
||||
// When a change occur (e.g. change of a rate), the data (value and time) is
|
||||
// written to file, THEN the change happens in the simulator, i.e., we will
|
||||
// notice the change at the next step.
|
||||
//
|
||||
// Keep in mind that the summary vector is NOT a continuous curve, only points
|
||||
// of data (time, value). We have to guess what happens between the data
|
||||
// points, we do this by saying: "There are no change, the only change happens
|
||||
// at the data points." As stated above, the value of this constant "height" of
|
||||
// the rectangle corresponds to the value of the last time step. Thus we have
|
||||
// to use the "right hand side value of the rectangle as height
|
||||
//
|
||||
// someDataVector[ivar] instead of someDataVector[ivar-1]
|
||||
//
|
||||
// (which intuition is saying is the correct value to use).
|
||||
|
||||
if(timeVec1.size() != dataVec1.size() || timeVec2.size() != dataVec2.size() ){
|
||||
OPM_THROW(std::runtime_error, "The size of the time vector does not match the size of the data vector.");
|
||||
}
|
||||
double errorSum = 0;
|
||||
double rightEdge, leftEdge, width;
|
||||
size_t i = 1;
|
||||
size_t j = 1;
|
||||
leftEdge = timeVec1[0];
|
||||
while(i < timeVec1.size()){
|
||||
if(j == timeVec2.size() ){
|
||||
break;
|
||||
}
|
||||
if(timeVec1[i] == timeVec2[j]){
|
||||
rightEdge = timeVec1[i];
|
||||
width = rightEdge - leftEdge;
|
||||
double dev = std::fabs(dataVec1[i] - dataVec2[j]);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
if(timeVec1[i] < timeVec2[j]){
|
||||
rightEdge = timeVec1[i];
|
||||
width = rightEdge - leftEdge;
|
||||
double value = unitStep(dataVec2[j]);
|
||||
double dev = std::fabs(dataVec1[i]-value);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(timeVec2[j] < timeVec1[i]){
|
||||
rightEdge = timeVec2[j];
|
||||
width = rightEdge - leftEdge;
|
||||
double value = unitStep(dataVec1[i]);
|
||||
double dev = std::fabs(dataVec2[j]-value);
|
||||
errorSum += getRectangleArea(dev, width);
|
||||
leftEdge = rightEdge;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return errorSum;
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "summaryComparator.hpp"
|
||||
|
||||
//! \brief Struct for storing the total area under a graph.
|
||||
//! \details Used when plotting summary vector against time. In most cases this represents a volume.
|
||||
struct WellProductionVolume{
|
||||
double total=0; //!< The total area under the graph when plotting the summary vector against time. In most cases the total production volume.
|
||||
double error=0; //!< The total area under the graph when plotting the deviation vector against time. In most cases the total error volume.
|
||||
|
||||
//! \brief Overloaded operator
|
||||
//! \param[in] rhs WellProductionVolume struct
|
||||
WellProductionVolume& operator+=(const WellProductionVolume& rhs){
|
||||
this->total += rhs.total;
|
||||
this->error += rhs.error;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//! \details The class inherits from the SummaryComparator class, which takes care of all file reading. \n The IntegrationTest class compares values from the two different files and throws exceptions when the deviation is unsatisfying.
|
||||
class SummaryIntegrationTest: public SummaryComparator {
|
||||
private:
|
||||
bool allowSpikes = false; //!< Boolean value, when true checkForSpikes is included as a sub test in the integration test. By default: false.
|
||||
bool findVolumeError = false; //!< Boolean value, when true volumeErrorCheck() is included as a sub test in the integration test. By default: false.
|
||||
bool allowDifferentAmountOfKeywords = true; //!< Boolean value, when false the integration test will check wheter the two files have the same amount of keywords. \nIf they don't, an exception will be thrown. By default: true.
|
||||
bool findVectorWithGreatestErrorRatio = false; //!< Boolean value, when true the integration test will find the vector that has the greatest error ratio. By default: false.
|
||||
bool oneOfTheMainVariables = false; //!< Boolean value, when true the integration test will only check for one of the primary variables (WOPR, WGPR, WWPR. WBHP), which will be specified by user. By default: false.
|
||||
bool throwExceptionForTooGreatErrorRatio = true; //!< Boolean value, when true any volume error ratio that exceeds the relativeTolerance will cause an exception to be thrown. By default: true.
|
||||
std::string mainVariable; //!< String variable, where the name of the main variable of interest (one of WOPR, WBHP, WWPR, WGPR) is stored. Can be empty.
|
||||
int spikeLimit = 13370; //!< The limit for how many spikes to allow in the data set of a certain keyword. By default: Set to a high number, \n should not trig the (if spikeOccurrences > spikeLimit){ // throw exception }.
|
||||
|
||||
WellProductionVolume WOP; //!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WOPR
|
||||
WellProductionVolume WWP; //!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WWPR
|
||||
WellProductionVolume WGP;//!< WellProductionVolume struct for storing the total production volume and total error volume of all the keywords which start with WGPR
|
||||
WellProductionVolume WBHP; //!< WellProductionVolume struct for storing the value of the area under the graph when plotting summary vector/deviation vector against time.This is for keywords starting with WBHP. \nNote: the name of the struct may be misleading, this is not an actual volume.
|
||||
|
||||
|
||||
//! \brief The function gathers the correct data for comparison for a specific keyword
|
||||
//! \param[in] timeVec1 A std::vector<double> that contains the time steps of file 1.
|
||||
//! \param[in] timeVec2 A std::vector<double> that contains the time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \details The function requires an outer loop which iterates over the keywords of the files. It prepares an integration test by gathering the data, stroing it into two vectors, \n deciding which is to be used as a reference/basis and calling the test function.
|
||||
void checkForKeyword(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2, const char* keyword);
|
||||
|
||||
//! \brief The function compares the volume error to the total production volume of a certain type of keyword.
|
||||
//! param[in] keyword The keyword of interest.
|
||||
//! \details The function takes in a keyword and checks if it is of interest. Only keywords which say something about the well oil production, well water production, \n well gas production and the well BHP are of interest. The function sums up the total production in the cases where it is possible, \n and sums up the error volumes by a trapezoid integration method. The resulting values are stored in member variable structs of type WellProductionVolume, and double variables. For proper use of the function all the keywords of the file should be checked. This is satisfied if it is called by checkForKeyword.
|
||||
void volumeErrorCheck(const char* keyword);
|
||||
|
||||
//! \brief The function calculates the total production volume and total error volume of a specific keyword
|
||||
//! \param[in] timeVec1 A std::vector<double> that contains the time steps of file 1.
|
||||
//! \param[in] timeVec2 A std::vector<double> that contains the time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \param[out] ret Returns a WellProductionWolume struct
|
||||
//! \details The function reads the data from the two files into the member variable vectors (of the super class). It returns a WellProductionVolume struct calculated from the vectors corresponding to the keyword.
|
||||
WellProductionVolume getSpecificWellVolume(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const char* keyword);
|
||||
|
||||
//! \brief The function is a regression test which allows spikes.
|
||||
//! \param[in] keyword The keyword of interest, the keyword the summary vectors "belong" to.
|
||||
//! \details The function requires the protected member variables referenceVec, referenceDataVec, checkVec and checkDataVec to be stored with data, which is staisfied if it is called by checkForKeyword. \n It compares the two vectors value by value, and if the deviation is unsatisfying, the errorOccurrenceCounter is incremented. If the errorOccurrenceCounter becomes greater than the errorOccurrenceLimit, \n a exception is thrown. The function will allow spike values, however, if two values in a row exceed the deviation limit, they are no longer spikes, and an exception is thrown.
|
||||
void checkWithSpikes(const char* keyword);
|
||||
|
||||
//! \brief Caluculates a deviation, throws exceptions and writes and error message.
|
||||
//! \param[in] deviation Deviation struct
|
||||
//! \param[out] int Returns 0/1, depending on wheter the deviation exceeded the limit or not.
|
||||
//! \details The function checks the values of the Deviation struct against the absolute and relative tolerance, which are private member values of the super class. \n When comparing against the relative tolerance an additional term is added, the absolute deviation has to be greater than 1e-6 for the function to throw an exception. \n When the deviations are too great, the function returns 1.
|
||||
int checkDeviation(const Deviation& deviation);
|
||||
|
||||
//! \brief Calculates the keyword's total production volume and error volume
|
||||
//! \param[in] keyword The keyword of interest.
|
||||
//! \param[out] wellProductionVolume A struct containing the total production volume and the total error volume.
|
||||
//! \details The function calculates the total production volume and total error volume of a keyword, by the trapezoid integral method. \n The function throws and exception if the total error volume is negative. The function returns the results as a struct.
|
||||
WellProductionVolume getWellProductionVolume(const char* keyword);
|
||||
|
||||
//! \brief The function function works properly when the private member variables are set (after running the integration test which findVolumeError = true). \n It prints out the total production volume, the total error volume and the error ratio.
|
||||
void evaluateWellProductionVolume();
|
||||
|
||||
//! \brief The function calculates the total production volume and total error volume
|
||||
//! \param keyword The keyword of interest
|
||||
//! \details The function uses the data that is stored in the member variable vectors. It calculates the total production volume \n and the total error volume of the specified keyword, and adds the result to the private member WellProductionVolume variables of the class.
|
||||
void updateVolumeError(const char* keyword);
|
||||
|
||||
//! \brief Finds the keyword which has the greates error volume ratio
|
||||
//! \param[in] volume WellProductionVolume struct which contains the data used for comparison
|
||||
//! \param[in] greatestRatio Double value taken in by reference. Stores the greatest error ratio value.
|
||||
//! \param[in] currentKeyword The keyword that is under evaluation
|
||||
//! \param[in] greatestErrorRatio String which contains the name of the keyword which has the greatest error ratio
|
||||
//! \details The function requires an outer loop which iterates over the keywords in the files, and calls the function for each keyword. \nThe valiables double greatestRatio and std::string keywordWithTheGreatestErrorRatio must be declared outside the loop. \nWhen the current error ratio is greater than the value stored in greatestRatio, the gratestRatio value is updated with the current error ratio.
|
||||
void findGreatestErrorRatio(const WellProductionVolume& volume,
|
||||
double &greatestRatio,
|
||||
const char* currentKeyword,
|
||||
std::string &greatestErrorRatio);
|
||||
|
||||
#if 0
|
||||
//! \brief Checks whether the unit of the two data vectors is the same
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \param[out] boolean True/false, depending on whether the units are equal or not
|
||||
bool checkUnits(const char* keyword);
|
||||
#endif
|
||||
public:
|
||||
//! \brief Constructor, creates an object of IntegrationTest class.
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \param[in] atol The absolute tolerance which is to be used in the test.
|
||||
//! \param[in] rtol The relative tolerance which is to be used in the test.
|
||||
//! \details The constructor calls the constructor of the super class.
|
||||
SummaryIntegrationTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double atol, double rtol) :
|
||||
SummaryComparator(basename1, basename2, atol, rtol) {}
|
||||
|
||||
//! \brief This function sets the private member variable allowSpikes.
|
||||
//! \param[in] allowSpikes Boolean value
|
||||
//! \details When allowSpikes is true, the integration test checkWithSpikes is excecuted.
|
||||
void setAllowSpikes(bool allowSpikesArg){this->allowSpikes = allowSpikesArg;}
|
||||
|
||||
//! \brief This function sets the private member variable findVolumeError.
|
||||
//! \param[in] findVolumeError Boolean value
|
||||
//! \details When findVolumeError is true, the integration test volumeErrorCheck and the function evaluateWellProductionVolume are excecuted.
|
||||
void setFindVolumeError(bool findVolumeErrorArg){this->findVolumeError = findVolumeErrorArg;}
|
||||
|
||||
//! \brief This function sets the private member variable oneOfTheMainVariables
|
||||
//! \param[in] oneOfTheMainVariables Boolean value
|
||||
//! \details When oneOfTheMainVariables is true, the integration test runs the substest volumeErrorCheckForOneSpecificVariable.
|
||||
void setOneOfTheMainVariables(bool oneOfTheMainVariablesArg){this->oneOfTheMainVariables = oneOfTheMainVariablesArg;}
|
||||
|
||||
//! \brief This function sets the member variable string #mainVariable
|
||||
//! \param[in] mainVar This is the string should contain one of the main variables. e.g. WOPR
|
||||
void setMainVariable(std::string mainVar){this->mainVariable = mainVar;}
|
||||
|
||||
//! \brief This function sets the private member variable spikeLimit.
|
||||
//! \param[in] lim The value which the spike limit is to be given.
|
||||
void setSpikeLimit(int lim){this->spikeLimit = lim;}
|
||||
|
||||
//! \brief This function sets the private member variable findVectorWithGreatestErrorRatio
|
||||
//! \param[in] findVolumeError Boolean value
|
||||
//! \details When findVectorWithGreatestErrorRatio is true, the integration test will print the vector with the greatest error ratio.
|
||||
void setFindVectorWithGreatestErrorRatio(bool boolean){this->findVectorWithGreatestErrorRatio = boolean;}
|
||||
|
||||
//! \brief This function sets the private member variable allowDifferentAmountsOfKeywords
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details When allowDifferentAmountOfKeywords is false, the amount of kewyord in the two files will be compared. \nIf the number of keywords are different an exception will be thrown.
|
||||
void setAllowDifferentAmountOfKeywords(bool boolean){this->allowDifferentAmountOfKeywords = boolean;}
|
||||
|
||||
//! \brief This function sets the private member variable throwExceptionForTooGreatErrorRatio
|
||||
//! \param[in] boolean Boolean value
|
||||
//! \details When throwExceptionForTooGreatErrorRatio is false, the function getWellProductionVolume will throw an exception.
|
||||
void setThrowExceptionForTooGreatErrorRatio(bool boolean){this->throwExceptionForTooGreatErrorRatio = boolean;}
|
||||
|
||||
//! \brief This function executes a integration test for all the keywords. If the two files do not match in amount of keywords, an exception is thrown. \n Uses the boolean member variables to know which tests to execute.
|
||||
void getIntegrationTest();
|
||||
|
||||
//! \brief This function executes a integration test for one specific keyword. If one or both of the files do not have the keyword, an exception is thorwn. \n Uses the boolean member variables to know which tests to execute.
|
||||
void getIntegrationTest(const char* keyword);
|
||||
|
||||
//! \brief This function calculates the area of an rectangle of height height and width time-timePrev
|
||||
//! \param[in] height The height of the rectangle. See important statement of use below.
|
||||
//! \param[in] width The width of the rectangle
|
||||
//! \param[out] area Returns the area of the rectangle
|
||||
//! \details This function is simple. When using it on a summary vector (data values plotted againt time), calculating the area between the two points i and i+1 note this:\nThe width is time_of_i+1 - time_of_i, the height is data_of_i+1 NOT data_of_i. The upper limit must be used.
|
||||
static double getRectangleArea(double height, double width){return height*width;}
|
||||
|
||||
//! \brief This function calculates the area under a graph by doing a Riemann sum
|
||||
//! \param[in] timeVec Contains the time values
|
||||
//! \param[in] dataVec Contains the data values
|
||||
//! \details The function does a Riemann sum integration of the graph formed
|
||||
//! by the points (timeVec[i] , dataVec[i]).
|
||||
//! In the case of a summary vector, the summary vector of quantity
|
||||
//! corresponding to a rate, is a piecewise continus function consisting
|
||||
//! of unit step functions. Thus the Riemann sum will become an
|
||||
//! exact expression for the integral of the graph.
|
||||
//! Important: For the data values correspoding to time i and i-1,
|
||||
//! the fixed value of the height of the rectangles in the Riemann sum
|
||||
//! is set by the data value i. The upper limit must be used.
|
||||
static double integrate(const std::vector<double>& timeVec,
|
||||
const std::vector<double>& dataVec);
|
||||
|
||||
//! \brief This function calculates the Riemann sum of the error between two graphs.
|
||||
//! \param[in] timeVec1 Contains the time values of graph 1
|
||||
//! \param[in] dataVec1 Contains the data values of graph 1
|
||||
//! \param[in] timeVec2 Contains the time values of graph 2
|
||||
//! \param[in] dataVec2 Contains the data values of graph 2
|
||||
//! \details This function takes in two graphs and returns the integrated error.
|
||||
//! In case of ecl summary vectors: if the vectors correspond to a
|
||||
//! quantity which is a rate, the vectors will be piecewise
|
||||
//! continous unit step functions. In this case the error will also
|
||||
//! be a piecewise continous unit step function. The function uses
|
||||
//! a Riemann sum when calculating the integral. Thus the integral
|
||||
//! will become exact. Important: For the data values corresponding
|
||||
//! to time i and i-1, the fixed value of the height of the rectangles
|
||||
//! in the Riemann sum is set by the data value i.
|
||||
//! The upper limit must be used.
|
||||
static double integrateError(const std::vector<double>& timeVec1,
|
||||
const std::vector<double>& dataVec1,
|
||||
const std::vector<double>& timeVec2,
|
||||
const std::vector<double>& dataVec2);
|
||||
};
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "summaryRegressionTest.hpp"
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <string>
|
||||
|
||||
void SummaryRegressionTest::getRegressionTest(){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2); //Figures which dataset that contains more/less values pr keyword vector.
|
||||
std::cout << "Comparing " << timeVec1.size() << " steps." << std::endl;
|
||||
int ivar = 0;
|
||||
if(stringlist_get_size(keysShort) != stringlist_get_size(keysLong)){
|
||||
int missing_count = 0;
|
||||
std::cout << "Keywords missing from one case: " << std::endl;
|
||||
|
||||
for (int i=0; i < stringlist_get_size( keysLong); i++) {
|
||||
const char * key = stringlist_iget( keysLong , i );
|
||||
if (!stringlist_contains( keysShort , key)) {
|
||||
std::cout << key << " ";
|
||||
|
||||
missing_count++;
|
||||
if ((missing_count % 8) == 0)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
HANDLE_ERROR(std::runtime_error, "Different amount of keywords in the two summary files.");
|
||||
}
|
||||
if(printKeyword){
|
||||
printKeywords();
|
||||
}
|
||||
|
||||
|
||||
//Iterates over all keywords from the restricted file, use iterator "ivar". Searches for a match in the file with more keywords, use the iterator "jvar".
|
||||
bool throwAtEnd = false;
|
||||
while(ivar < stringlist_get_size(keysShort)){
|
||||
const char* keyword = stringlist_iget(keysShort, ivar);
|
||||
std::string keywordString(keyword);
|
||||
for (int jvar = 0; jvar < stringlist_get_size(keysLong); jvar++){
|
||||
if (strcmp(keyword, stringlist_iget(keysLong, jvar)) == 0){ //When the keywords are equal, proceed in comparing summary files.
|
||||
if (isRestartFile && keywordString.substr(3,1)=="T"){
|
||||
break;
|
||||
}
|
||||
throwAtEnd |= !checkForKeyword(timeVec1, timeVec2, keyword);
|
||||
break;
|
||||
}
|
||||
//will only enter here if no keyword match
|
||||
if(jvar == stringlist_get_size(keysLong)-1){
|
||||
std::cout << "Could not find keyword: " << stringlist_iget(keysShort, ivar) << std::endl;
|
||||
OPM_THROW(std::runtime_error, "No match on keyword");
|
||||
}
|
||||
}
|
||||
ivar++;
|
||||
}
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " summary keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
size_t len = ecl_sum_get_data_length(ecl_sum1);
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " / " << len << " steps." << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
if (throwAtEnd)
|
||||
OPM_THROW(std::runtime_error, "Regression test failed.");
|
||||
else if (deviations.empty())
|
||||
std::cout << "Regression test succeeded." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SummaryRegressionTest::getRegressionTest(const char* keyword){
|
||||
std::vector<double> timeVec1, timeVec2;
|
||||
setTimeVecs(timeVec1, timeVec2); // Sets the time vectors, they are equal for all keywords (WPOR:PROD01 etc)
|
||||
setDataSets(timeVec1, timeVec2); //Figures which dataset that contains more/less values pr keyword vector.
|
||||
std::string keywordString(keyword);
|
||||
if(stringlist_contains(keysShort,keyword) && stringlist_contains(keysLong, keyword)){
|
||||
if (isRestartFile && keywordString.substr(3,1)=="T"){
|
||||
return;
|
||||
}
|
||||
if (checkForKeyword(timeVec1, timeVec2, keyword))
|
||||
std::cout << "Regression test succeeded." << std::endl;
|
||||
else
|
||||
OPM_THROW(std::runtime_error, "Regression test failed");
|
||||
|
||||
return;
|
||||
}
|
||||
std::cout << "The keyword suggested, " << keyword << ", is not supported by one or both of the summary files. Please use a different keyword." << std::endl;
|
||||
OPM_THROW(std::runtime_error, "Input keyword from user does not exist in/is not common for the two summary files.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SummaryRegressionTest::checkDeviation(Deviation deviation, const char* keyword, int refIndex, int checkIndex){
|
||||
double absTol = getAbsTolerance();
|
||||
double relTol = getRelTolerance();
|
||||
|
||||
if (deviation.rel > relTol && deviation.abs > absTol){
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(deviation);
|
||||
} else {
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
std::cout << "(days, reference value) and (days, check value) = (" << (*referenceVec)[refIndex] << ", " << (*referenceDataVec)[refIndex]
|
||||
<< ") and (" << (*checkVec)[checkIndex-1] << ", " << (*checkDataVec)[checkIndex-1] << ")\n";
|
||||
// -1 in [checkIndex -1] because checkIndex is updated after leaving getDeviation function
|
||||
std::cout << "The absolute deviation is " << deviation.abs << ". The tolerance limit is " << absTol << std::endl;
|
||||
std::cout << "The relative deviation is " << deviation.rel << ". The tolerance limit is " << relTol << std::endl;
|
||||
HANDLE_ERROR(std::runtime_error, "Deviation exceed the limit.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SummaryRegressionTest::checkForKeyword(std::vector<double>& timeVec1, std::vector<double>& timeVec2, const char* keyword){
|
||||
std::vector<double> dataVec1, dataVec2;
|
||||
getDataVecs(dataVec1,dataVec2,keyword);
|
||||
chooseReference(timeVec1, timeVec2,dataVec1,dataVec2);
|
||||
return startTest(keyword);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SummaryRegressionTest::startTest(const char* keyword){
|
||||
size_t jvar = 0;
|
||||
Deviation deviation;
|
||||
bool result = true;
|
||||
for (size_t ivar = 0; ivar < referenceVec->size(); ivar++){
|
||||
getDeviation(ivar, jvar, deviation);//Reads from the protected member variables in the super class.
|
||||
result = checkDeviation(deviation, keyword,ivar, jvar);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SUMMARYREGRESSIONTEST_HPP
|
||||
#define SUMMARYREGRESSIONTEST_HPP
|
||||
|
||||
#include "summaryComparator.hpp"
|
||||
|
||||
//! \details The class inherits from the SummaryComparator class, which takes care of all file reading. \n The RegressionTest class compares the values from the two different files and throws exceptions when the deviation is unsatisfying.
|
||||
class SummaryRegressionTest: public SummaryComparator {
|
||||
private:
|
||||
//! \brief Gathers the correct data for comparison for a specific keyword
|
||||
//! \param[in] timeVec1 The time steps of file 1.
|
||||
//! \param[in] timeVec2 The time steps of file 2.
|
||||
//! \param[in] keyword The keyword of interest
|
||||
//! \details The function prepares a regression test by gathering the data, stroing it into two vectors, \n deciding which is to be used as a reference/basis and calling the test function.
|
||||
//! \return True if check passed, false otherwise.
|
||||
bool checkForKeyword(std::vector<double>& timeVec1, std::vector<double>& timeVec2, const char* keyword);
|
||||
|
||||
//! \brief The regression test
|
||||
//! \param[in] keyword The keyword common for both the files. The vectors associated with the keyword are used for comparison.
|
||||
//! \details Start test uses the private member variables, pointers of std::vector<double> type, which are set to point to the correct vectors in SummaryComparison::chooseReference(...). \n The function iterates over the referenceVev/basis and for each iteration it calculates the deviation with SummaryComparison::getDeviation(..) and stors it in a Deviation struct. \n SummaryComparison::getDeviation takes the int jvar as an reference input, and using it as an iterative index for the values which are to be compared with the basis. \n Thus, by updating the jvar variable every time a deviation is calculated, one keep track jvar and do not have to iterate over already checked values.
|
||||
bool startTest(const char* keyword);
|
||||
|
||||
//! \brief Caluculates a deviation, throws exceptions and writes and error message.
|
||||
//! \param[in] deviation Deviation struct
|
||||
//! \param[in] keyword The keyword that the data that are being compared belongs to.
|
||||
//! \param[in] refIndex The report step of which the deviation originates from in #referenceDataVec.
|
||||
//! \param[in] checkIndex The report step of which the deviation originates from in #checkDataVec.
|
||||
//! \details The function checks the values of the Deviation struct against the absolute and relative tolerance, which are private member values of the super class. \n When comparing against the relative tolerance an additional term is added, the absolute deviation has to be greater than 1e-6 for the function to throw an exception. \n When the deviations are too great, the function writes out which keyword, and at what report step the deviation is too great before optionally throwing an exception.
|
||||
//! \return True if check passed, false otherwise.
|
||||
bool checkDeviation(Deviation deviation, const char* keyword, int refIndex, int checkIndex);
|
||||
|
||||
bool isRestartFile = false; //!< Private member variable, when true the files that are being compared is a restart file vs a normal file
|
||||
public:
|
||||
//! \brief Constructor, creates an object of RefressionTest class.
|
||||
//! \param[in] basename1 Path to file1 without extension.
|
||||
//! \param[in] basename1 Path to file2 without extension.
|
||||
//! \param[in] relativeTol The relative tolerance which is to be used in the test.
|
||||
//! \param[in] absoluteTol The absolute tolerance which is to be used in the test.
|
||||
//! \details The constructor calls the constructor of the super class.
|
||||
SummaryRegressionTest(const std::string& basename1,
|
||||
const std::string& basename2,
|
||||
double relativeTol, double absoluteTol) :
|
||||
SummaryComparator(basename1, basename2, relativeTol, absoluteTol) {}
|
||||
|
||||
//! \details The function executes a regression test for all the keywords. If the two files do not match in amount of keywords, an exception is thrown.
|
||||
void getRegressionTest();
|
||||
|
||||
//! \details The function executes a regression test for one specific keyword. If one or both of the files do not have the keyword, an exception is thrown.
|
||||
void getRegressionTest(const char* keyword);///< Regression test for a certain keyword of the files.
|
||||
|
||||
//! \brief This function sets the private member variable isRestartFiles
|
||||
//! \param[in] boolean Boolean value
|
||||
void setIsRestartFile(bool boolean){this->isRestartFile = boolean;}
|
||||
};
|
||||
|
||||
#endif
|
||||
247
external/cjson/README
vendored
247
external/cjson/README
vendored
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
Welcome to cJSON.
|
||||
|
||||
cJSON aims to be the dumbest possible parser that you can get your job done with.
|
||||
It's a single file of C, and a single header file.
|
||||
|
||||
JSON is described best here: http://www.json.org/
|
||||
It's like XML, but fat-free. You use it to move data around, store things, or just
|
||||
generally represent your program's state.
|
||||
|
||||
|
||||
First up, how do I build?
|
||||
Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
|
||||
For example, to build the test app:
|
||||
|
||||
gcc cJSON.c test.c -o test -lm
|
||||
./test
|
||||
|
||||
|
||||
As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
|
||||
As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
|
||||
in one of two modes: Auto and Manual. Let's have a quick run-through.
|
||||
|
||||
|
||||
I lifted some JSON from this page: http://www.json.org/fatfree.html
|
||||
That page inspired me to write cJSON, which is a parser that tries to share the same
|
||||
philosophy as JSON itself. Simple, dumb, out of the way.
|
||||
|
||||
Some JSON:
|
||||
{
|
||||
"name": "Jack (\"Bee\") Nimble",
|
||||
"format": {
|
||||
"type": "rect",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"interlace": false,
|
||||
"frame rate": 24
|
||||
}
|
||||
}
|
||||
|
||||
Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
|
||||
you have a char * to it. Everything is a cJSON struct.
|
||||
Get it parsed:
|
||||
cJSON *root = cJSON_Parse(my_json_string);
|
||||
|
||||
This is an object. We're in C. We don't have objects. But we do have structs.
|
||||
What's the framerate?
|
||||
|
||||
cJSON *format = cJSON_GetObjectItem(root,"format");
|
||||
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
|
||||
|
||||
|
||||
Want to change the framerate?
|
||||
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
|
||||
|
||||
Back to disk?
|
||||
char *rendered=cJSON_Print(root);
|
||||
|
||||
Finished? Delete the root (this takes care of everything else).
|
||||
cJSON_Delete(root);
|
||||
|
||||
That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
|
||||
before you dereference them. If you want to see how you'd build this struct in code?
|
||||
cJSON *root,*fmt;
|
||||
root=cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
|
||||
cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(fmt,"type", "rect");
|
||||
cJSON_AddNumberToObject(fmt,"width", 1920);
|
||||
cJSON_AddNumberToObject(fmt,"height", 1080);
|
||||
cJSON_AddFalseToObject (fmt,"interlace");
|
||||
cJSON_AddNumberToObject(fmt,"frame rate", 24);
|
||||
|
||||
Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
|
||||
Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
|
||||
a few from elsewhere.
|
||||
|
||||
What about manual mode? First up you need some detail.
|
||||
Let's cover how the cJSON objects represent the JSON data.
|
||||
cJSON doesn't distinguish arrays from objects in handling; just type.
|
||||
Each cJSON has, potentially, a child, siblings, value, a name.
|
||||
|
||||
The root object has: Object Type and a Child
|
||||
The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
|
||||
Sibling has type Object, name "format", and a child.
|
||||
That child has type String, name "type", value "rect", and a sibling:
|
||||
Sibling has type Number, name "width", value 1920, and a sibling:
|
||||
Sibling has type Number, name "height", value 1080, and a sibling:
|
||||
Sibling hs type False, name "interlace", and a sibling:
|
||||
Sibling has type Number, name "frame rate", value 24
|
||||
|
||||
Here's the structure:
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev;
|
||||
struct cJSON *child;
|
||||
|
||||
int type;
|
||||
|
||||
char *valuestring;
|
||||
int valueint;
|
||||
double valuedouble;
|
||||
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
By default all values are 0 unless set by virtue of being meaningful.
|
||||
|
||||
next/prev is a doubly linked list of siblings. next takes you to your sibling,
|
||||
prev takes you back from your sibling to you.
|
||||
Only objects and arrays have a "child", and it's the head of the doubly linked list.
|
||||
A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
|
||||
The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
|
||||
cJSON.h
|
||||
|
||||
A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
|
||||
valuedouble.
|
||||
|
||||
Any entry which is in the linked list which is the child of an object will have a "string"
|
||||
which is the "name" of the entry. When I said "name" in the above example, that's "string".
|
||||
"string" is the JSON name for the 'variable name' if you will.
|
||||
|
||||
Now you can trivially walk the lists, recursively, and parse as you please.
|
||||
You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
|
||||
the root object, and traverse the structure (which is, formally, an N-tree),
|
||||
and tokenise as you please. If you wanted to build a callback style parser, this is how
|
||||
you'd do it (just an example, since these things are very specific):
|
||||
|
||||
void parse_and_callback(cJSON *item,const char *prefix)
|
||||
{
|
||||
while (item)
|
||||
{
|
||||
char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
|
||||
sprintf(newprefix,"%s/%s",prefix,item->name);
|
||||
int dorecurse=callback(newprefix, item->type, item);
|
||||
if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
|
||||
item=item->next;
|
||||
free(newprefix);
|
||||
}
|
||||
}
|
||||
|
||||
The prefix process will build you a separated list, to simplify your callback handling.
|
||||
The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
|
||||
let you invoke it per-item. For the item above, your callback might look like this:
|
||||
|
||||
int callback(const char *name,int type,cJSON *item)
|
||||
{
|
||||
if (!strcmp(name,"name")) { /* populate name */ }
|
||||
else if (!strcmp(name,"format/type") { /* handle "rect" */ }
|
||||
else if (!strcmp(name,"format/width") { /* 800 */ }
|
||||
else if (!strcmp(name,"format/height") { /* 600 */ }
|
||||
else if (!strcmp(name,"format/interlace") { /* false */ }
|
||||
else if (!strcmp(name,"format/frame rate") { /* 24 */ }
|
||||
return 1;
|
||||
}
|
||||
|
||||
Alternatively, you might like to parse iteratively.
|
||||
You'd use:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
int i; for (i=0;i<cJSON_GetArraySize(item);i++)
|
||||
{
|
||||
cJSON *subitem=cJSON_GetArrayItem(item,i);
|
||||
// handle subitem.
|
||||
}
|
||||
}
|
||||
|
||||
Or, for PROPER manual mode:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
cJSON *subitem=item->child;
|
||||
while (subitem)
|
||||
{
|
||||
// handle subitem
|
||||
if (subitem->child) parse_object(subitem->child);
|
||||
|
||||
subitem=subitem->next;
|
||||
}
|
||||
}
|
||||
|
||||
Of course, this should look familiar, since this is just a stripped-down version
|
||||
of the callback-parser.
|
||||
|
||||
This should cover most uses you'll find for parsing. The rest should be possible
|
||||
to infer.. and if in doubt, read the source! There's not a lot of it! ;)
|
||||
|
||||
|
||||
In terms of constructing JSON data, the example code above is the right way to do it.
|
||||
You can, of course, hand your sub-objects to other functions to populate.
|
||||
Also, if you find a use for it, you can manually build the objects.
|
||||
For instance, suppose you wanted to build an array of objects?
|
||||
|
||||
cJSON *objects[24];
|
||||
|
||||
cJSON *Create_array_of_anything(cJSON **items,int num)
|
||||
{
|
||||
int i;cJSON *prev, *root=cJSON_CreateArray();
|
||||
for (i=0;i<24;i++)
|
||||
{
|
||||
if (!i) root->child=objects[i];
|
||||
else prev->next=objects[i], objects[i]->prev=prev;
|
||||
prev=objects[i];
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
and simply: Create_array_of_anything(objects,24);
|
||||
|
||||
cJSON doesn't make any assumptions about what order you create things in.
|
||||
You can attach the objects, as above, and later add children to each
|
||||
of those objects.
|
||||
|
||||
As soon as you call cJSON_Print, it renders the structure to text.
|
||||
|
||||
|
||||
|
||||
The test.c code shows how to handle a bunch of typical cases. If you uncomment
|
||||
the code, it'll load, parse and print a bunch of test files, also from json.org,
|
||||
which are more complex than I'd care to try and stash into a const char array[].
|
||||
|
||||
|
||||
Enjoy cJSON!
|
||||
|
||||
|
||||
- Dave Gamble, Aug 2009
|
||||
4
external/cjson/README.opm
vendored
4
external/cjson/README.opm
vendored
@@ -1,4 +0,0 @@
|
||||
This directory contains the cJSON package downloaded unchanged from:
|
||||
http://sourceforge.net/projects/cjson/. The cJSON package is plain C,
|
||||
the JsonObject class provides a minimal C++ wrapping of this.
|
||||
|
||||
569
external/cjson/cJSON.c
vendored
569
external/cjson/cJSON.c
vendored
@@ -1,569 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* cJSON */
|
||||
/* JSON parser in C. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *ep;
|
||||
|
||||
const char *cJSON_GetErrorPtr(void) {return ep;}
|
||||
|
||||
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||
{
|
||||
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
|
||||
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
|
||||
}
|
||||
|
||||
static void *(*cJSON_malloc)(size_t sz) = malloc;
|
||||
static void (*cJSON_free)(void *ptr) = free;
|
||||
|
||||
static char* cJSON_strdup(const char* str)
|
||||
{
|
||||
size_t len;
|
||||
char* copy;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if (!(copy = (char*)cJSON_malloc(len))) return 0;
|
||||
memcpy(copy,str,len);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
{
|
||||
if (!hooks) { /* Reset hooks */
|
||||
cJSON_malloc = malloc;
|
||||
cJSON_free = free;
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
|
||||
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
|
||||
}
|
||||
|
||||
/* Internal constructor. */
|
||||
static cJSON *cJSON_New_Item(void)
|
||||
{
|
||||
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
|
||||
if (node) memset(node,0,sizeof(cJSON));
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Delete a cJSON structure. */
|
||||
void cJSON_Delete(cJSON *c)
|
||||
{
|
||||
cJSON *next;
|
||||
while (c)
|
||||
{
|
||||
next=c->next;
|
||||
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
|
||||
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
|
||||
if (c->string) cJSON_free(c->string);
|
||||
cJSON_free(c);
|
||||
c=next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
static const char *parse_number(cJSON *item,const char *num)
|
||||
{
|
||||
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
|
||||
|
||||
/* Could use sscanf for this? */
|
||||
if (*num=='-') sign=-1,num++; /* Has sign? */
|
||||
if (*num=='0') num++; /* is zero */
|
||||
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
|
||||
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
|
||||
if (*num=='e' || *num=='E') /* Exponent? */
|
||||
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
|
||||
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
|
||||
}
|
||||
|
||||
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
|
||||
|
||||
item->valuedouble=n;
|
||||
item->valueint=(int)n;
|
||||
item->type=cJSON_Number;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static char *print_number(cJSON *item)
|
||||
{
|
||||
char *str;
|
||||
double d=item->valuedouble;
|
||||
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
|
||||
{
|
||||
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
|
||||
if (str) sprintf(str,"%d",item->valueint);
|
||||
}
|
||||
else
|
||||
{
|
||||
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
|
||||
if (str)
|
||||
{
|
||||
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
|
||||
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
|
||||
else sprintf(str,"%f",d);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Parse the input text into an unescaped cstring, and populate item. */
|
||||
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
static const char *parse_string(cJSON *item,const char *str)
|
||||
{
|
||||
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
|
||||
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
||||
|
||||
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
|
||||
if (!out) return 0;
|
||||
|
||||
ptr=str+1;ptr2=out;
|
||||
while (*ptr!='\"' && *ptr)
|
||||
{
|
||||
if (*ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case 'b': *ptr2++='\b'; break;
|
||||
case 'f': *ptr2++='\f'; break;
|
||||
case 'n': *ptr2++='\n'; break;
|
||||
case 'r': *ptr2++='\r'; break;
|
||||
case 't': *ptr2++='\t'; break;
|
||||
case 'u': /* transcode utf16 to utf8. */
|
||||
sscanf(ptr+1,"%4x",&uc);ptr+=4; /* get the unicode char. */
|
||||
|
||||
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
|
||||
|
||||
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
|
||||
{
|
||||
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
|
||||
sscanf(ptr+3,"%4x",&uc2);ptr+=6;
|
||||
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
|
||||
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
|
||||
}
|
||||
|
||||
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
|
||||
|
||||
switch (len) {
|
||||
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
||||
}
|
||||
ptr2+=len;
|
||||
break;
|
||||
default: *ptr2++=*ptr; break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*ptr2=0;
|
||||
if (*ptr=='\"') ptr++;
|
||||
item->valuestring=out;
|
||||
item->type=cJSON_String;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Render the cstring provided to an escaped version that can be printed. */
|
||||
static char *print_string_ptr(const char *str)
|
||||
{
|
||||
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
|
||||
|
||||
if (!str) return cJSON_strdup("");
|
||||
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
|
||||
|
||||
out=(char*)cJSON_malloc(len+3);
|
||||
if (!out) return 0;
|
||||
|
||||
ptr2=out;ptr=str;
|
||||
*ptr2++='\"';
|
||||
while (*ptr)
|
||||
{
|
||||
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
*ptr2++='\\';
|
||||
switch (token=*ptr++)
|
||||
{
|
||||
case '\\': *ptr2++='\\'; break;
|
||||
case '\"': *ptr2++='\"'; break;
|
||||
case '\b': *ptr2++='b'; break;
|
||||
case '\f': *ptr2++='f'; break;
|
||||
case '\n': *ptr2++='n'; break;
|
||||
case '\r': *ptr2++='r'; break;
|
||||
case '\t': *ptr2++='t'; break;
|
||||
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2++='\"';*ptr2++=0;
|
||||
return out;
|
||||
}
|
||||
/* Invote print_string_ptr (which is useful) on an item. */
|
||||
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
|
||||
|
||||
/* Predeclare these prototypes. */
|
||||
static const char *parse_value(cJSON *item,const char *value);
|
||||
static char *print_value(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_array(cJSON *item,const char *value);
|
||||
static char *print_array(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_object(cJSON *item,const char *value);
|
||||
static char *print_object(cJSON *item,int depth,int fmt);
|
||||
|
||||
/* Utility to jump whitespace and cr/lf */
|
||||
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
|
||||
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
|
||||
{
|
||||
const char *end=0;
|
||||
cJSON *c=cJSON_New_Item();
|
||||
ep=0;
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
end=parse_value(c,skip(value));
|
||||
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
|
||||
|
||||
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
|
||||
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
|
||||
if (return_parse_end) *return_parse_end=end;
|
||||
return c;
|
||||
}
|
||||
/* Default options for cJSON_Parse */
|
||||
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
|
||||
|
||||
/* Render a cJSON item/entity/structure to text. */
|
||||
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
|
||||
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char *parse_value(cJSON *item,const char *value)
|
||||
{
|
||||
if (!value) return 0; /* Fail on null. */
|
||||
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
|
||||
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
|
||||
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
|
||||
if (*value=='\"') { return parse_string(item,value); }
|
||||
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
|
||||
if (*value=='[') { return parse_array(item,value); }
|
||||
if (*value=='{') { return parse_object(item,value); }
|
||||
|
||||
ep=value;return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Render a value to text. */
|
||||
static char *print_value(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char *out=0;
|
||||
if (!item) return 0;
|
||||
switch ((item->type)&255)
|
||||
{
|
||||
case cJSON_NULL: out=cJSON_strdup("null"); break;
|
||||
case cJSON_False: out=cJSON_strdup("false");break;
|
||||
case cJSON_True: out=cJSON_strdup("true"); break;
|
||||
case cJSON_Number: out=print_number(item);break;
|
||||
case cJSON_String: out=print_string(item);break;
|
||||
case cJSON_Array: out=print_array(item,depth,fmt);break;
|
||||
case cJSON_Object: out=print_object(item,depth,fmt);break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char *parse_array(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='[') {ep=value;return 0;} /* not an array! */
|
||||
|
||||
item->type=cJSON_Array;
|
||||
value=skip(value+1);
|
||||
if (*value==']') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0; /* memory fail */
|
||||
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_value(child,skip(value+1)));
|
||||
if (!value) return 0; /* memory fail */
|
||||
}
|
||||
|
||||
if (*value==']') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an array to text */
|
||||
static char *print_array(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries;
|
||||
char *out=0,*ptr,*ret;int len=5;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,i=0,fail=0;
|
||||
|
||||
/* How many entries in the array? */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle numentries==0 */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(3);
|
||||
if (out) strcpy(out,"[]");
|
||||
return out;
|
||||
}
|
||||
/* Allocate an array to hold the values for each */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
memset(entries,0,numentries*sizeof(char*));
|
||||
/* Retrieve all the results: */
|
||||
child=item->child;
|
||||
while (child && !fail)
|
||||
{
|
||||
ret=print_value(child,depth+1,fmt);
|
||||
entries[i++]=ret;
|
||||
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* If we didn't fail, try to malloc the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
/* If that fails, we fail. */
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure. */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
|
||||
cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output array. */
|
||||
*out='[';
|
||||
ptr=out+1;*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
|
||||
cJSON_free(entries[i]);
|
||||
}
|
||||
cJSON_free(entries);
|
||||
*ptr++=']';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char *parse_object(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='{') {ep=value;return 0;} /* not an object! */
|
||||
|
||||
item->type=cJSON_Object;
|
||||
value=skip(value+1);
|
||||
if (*value=='}') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0;
|
||||
value=skip(parse_string(child,skip(value)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_string(child,skip(value+1)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value=='}') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an object to text. */
|
||||
static char *print_object(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries=0,**names=0;
|
||||
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,fail=0;
|
||||
/* Count the number of entries. */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle empty object case */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(fmt?depth+3:3);
|
||||
if (!out) return 0;
|
||||
ptr=out;*ptr++='{';
|
||||
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
/* Allocate space for the names and the objects */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
names=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!names) {cJSON_free(entries);return 0;}
|
||||
memset(entries,0,sizeof(char*)*numentries);
|
||||
memset(names,0,sizeof(char*)*numentries);
|
||||
|
||||
/* Collect all the results into our arrays: */
|
||||
child=item->child;depth++;if (fmt) len+=depth;
|
||||
while (child)
|
||||
{
|
||||
names[i]=str=print_string_ptr(child->string);
|
||||
entries[i++]=ret=print_value(child,depth,fmt);
|
||||
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* Try to allocate the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output: */
|
||||
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
|
||||
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
|
||||
*ptr++=':';if (fmt) *ptr++='\t';
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) *ptr++=',';
|
||||
if (fmt) *ptr++='\n';*ptr=0;
|
||||
cJSON_free(names[i]);cJSON_free(entries[i]);
|
||||
}
|
||||
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Get Array size/item / object item. */
|
||||
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
|
||||
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
|
||||
|
||||
/* Utility for array list handling. */
|
||||
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
|
||||
/* Utility for handling references. */
|
||||
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
|
||||
|
||||
/* Add item to array/object. */
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
|
||||
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
|
||||
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
|
||||
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
|
||||
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
|
||||
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
|
||||
|
||||
/* Replace array/object items with new ones. */
|
||||
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
|
||||
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
|
||||
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
|
||||
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
|
||||
|
||||
/* Create basic types: */
|
||||
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
|
||||
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
|
||||
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
|
||||
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
|
||||
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
|
||||
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
|
||||
|
||||
/* Create Arrays: */
|
||||
cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
|
||||
/* Duplication */
|
||||
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
|
||||
{
|
||||
cJSON *newitem,*cptr,*nptr=0,*newchild;
|
||||
/* Bail on bad ptr */
|
||||
if (!item) return 0;
|
||||
/* Create new item */
|
||||
newitem=cJSON_New_Item();
|
||||
if (!newitem) return 0;
|
||||
/* Copy over all vars */
|
||||
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
|
||||
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
|
||||
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
|
||||
/* If non-recursive, then we're done! */
|
||||
if (!recurse) return newitem;
|
||||
/* Walk the ->next chain for the child. */
|
||||
cptr=item->child;
|
||||
while (cptr)
|
||||
{
|
||||
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
|
||||
if (!newchild) {cJSON_Delete(newitem);return 0;}
|
||||
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
|
||||
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
|
||||
cptr=cptr->next;
|
||||
}
|
||||
return newitem;
|
||||
}
|
||||
|
||||
|
||||
143
external/cjson/cJSON.h
vendored
143
external/cjson/cJSON.h
vendored
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -36,7 +36,7 @@ function parseRevisions {
|
||||
declare -a BTYPES_ARRAY
|
||||
for btype in $BTYPES
|
||||
do
|
||||
BTYPES_ARRAY=(${BTYPES_ARRAY[*]} $btype)
|
||||
BTYPES_ARRAY=($BTYPES_ARRAY $btype)
|
||||
done
|
||||
TOOLCHAIN_ARRAY=($CMAKE_TOOLCHAIN_FILES)
|
||||
for index in ${!BTYPES_ARRAY[*]}
|
||||
@@ -90,12 +90,7 @@ function build_module {
|
||||
cmake --build .
|
||||
fi
|
||||
test $? -eq 0 || exit 2
|
||||
if test -z "$CTEST_CONFIGURATION"
|
||||
then
|
||||
ctest -T Test --no-compress-output
|
||||
else
|
||||
ctest -C $CTEST_CONFIGURATION --timeout 5000 -T Test --no-compress-output
|
||||
fi
|
||||
ctest -T Test --no-compress-output
|
||||
|
||||
# Convert to junit format
|
||||
$WORKSPACE/deps/opm-common/jenkins/convert.py -x $WORKSPACE/deps/opm-common/jenkins/conv.xsl -t . > testoutput.xml
|
||||
@@ -112,7 +107,6 @@ function build_module {
|
||||
else
|
||||
cmake --build . --target install
|
||||
fi
|
||||
test $? -eq 0 || exit 3
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -125,15 +119,14 @@ function clone_module {
|
||||
mkdir -p $WORKSPACE/deps/$1
|
||||
cd $WORKSPACE/deps/$1
|
||||
git init .
|
||||
if [ "$1" == "libecl" ]
|
||||
if [ "$1" == "ert" ]
|
||||
then
|
||||
git remote add origin https://github.com/Statoil/$1
|
||||
git remote add origin https://github.com/Ensembles/$1
|
||||
else
|
||||
git remote add origin https://github.com/OPM/$1
|
||||
fi
|
||||
git fetch --depth 1 origin $2:branch_to_build
|
||||
git checkout branch_to_build
|
||||
git log HEAD -1 | cat
|
||||
test $? -eq 0 || exit 1
|
||||
popd
|
||||
}
|
||||
@@ -174,12 +167,17 @@ function build_upstreams {
|
||||
# Uses pre-filled arrays downstreams, and associativ array downstreamRev
|
||||
# which holds the default revisions to use for downstreams
|
||||
function build_downstreams {
|
||||
pushd .
|
||||
cd $WORKSPACE/$configuration/build-$1
|
||||
cmake --build . --target install
|
||||
popd
|
||||
|
||||
egrep_cmd="xml_grep --wrap testsuites --cond testsuite $WORKSPACE/$configuration/build-$1/testoutput.xml"
|
||||
for downstream in ${downstreams[*]}
|
||||
do
|
||||
echo "Building downstream $downstream=${downstreamRev[$downstream]} configuration=$configuration"
|
||||
# Build downstream and execute installation
|
||||
clone_and_build_module $downstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT" ${downstreamRev[$downstream]} $WORKSPACE/$configuration 1
|
||||
clone_and_build_module $downstream "-DCMAKE_PREFIX_PATH=$WORKSPACE/$configuration/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_DATA_ROOT=$OPM_DATA_ROOT" ${downstreamRev[$downstream]} $WORKSPACE/$configuration 1
|
||||
test $? -eq 0 || exit 1
|
||||
|
||||
# Installation for downstream
|
||||
@@ -216,9 +214,7 @@ function build_module_full {
|
||||
mkdir -p $configuration/build-$1
|
||||
cd $configuration/build-$1
|
||||
echo "Building main module $1=$sha1 configuration=$configuration"
|
||||
build_module "-DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_TESTS_ROOT=$OPM_TESTS_ROOT" 1 $WORKSPACE
|
||||
test $? -eq 0 || exit 1
|
||||
cmake --build . --target install
|
||||
build_module "-DCMAKE_INSTALL_PREFIX=$WORKSPACE/$configuration/install -DOPM_DATA_ROOT=$OPM_DATA_ROOT" 1 $WORKSPACE
|
||||
test $? -eq 0 || exit 1
|
||||
popd
|
||||
|
||||
|
||||
@@ -6,24 +6,26 @@ source `dirname $0`/build-opm-module.sh
|
||||
mkdir deps
|
||||
ln -sf $WORKSPACE deps/opm-common
|
||||
|
||||
declare -a upstreams
|
||||
upstreams=(libecl)
|
||||
|
||||
declare -A upstreamRev
|
||||
upstreamRev[libecl]=master
|
||||
|
||||
# Downstreams and revisions
|
||||
declare -a downstreams
|
||||
downstreams=(opm-material
|
||||
downstreams=(ert
|
||||
opm-parser
|
||||
opm-output
|
||||
opm-material
|
||||
opm-grid
|
||||
opm-core
|
||||
ewoms
|
||||
opm-simulators
|
||||
opm-upscaling
|
||||
)
|
||||
|
||||
declare -A downstreamRev
|
||||
downstreamRev[ert]=master
|
||||
downstreamRev[opm-parser]=master
|
||||
downstreamRev[opm-material]=master
|
||||
downstreamRev[opm-core]=master
|
||||
downstreamRev[opm-grid]=master
|
||||
downstreamRev[opm-output]=master
|
||||
downstreamRev[ewoms]=master
|
||||
downstreamRev[opm-simulators]=master
|
||||
downstreamRev[opm-upscaling]=master
|
||||
@@ -31,7 +33,10 @@ downstreamRev[opm-upscaling]=master
|
||||
parseRevisions
|
||||
printHeader opm-common
|
||||
|
||||
# Setup opm-data
|
||||
source $WORKSPACE/deps/opm-common/jenkins/setup-opm-tests.sh
|
||||
# Setup opm-data if necessary
|
||||
if grep -q "with downstreams" <<< $ghprbCommentBody
|
||||
then
|
||||
source $WORKSPACE/deps/opm-common/jenkins/setup-opm-data.sh
|
||||
fi
|
||||
|
||||
build_module_full opm-common
|
||||
|
||||
29
jenkins/setup-opm-data.sh
Executable file
29
jenkins/setup-opm-data.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Predefined by environment
|
||||
if test -z "$OPM_DATA_ROOT"
|
||||
then
|
||||
OPM_DATA_REVISION="master"
|
||||
if grep -q "opm-data=" <<< $ghprbCommentBody
|
||||
then
|
||||
OPM_DATA_REVISION=pull/`echo $ghprbCommentBody | sed -r 's/.*opm-data=([0-9]+).*/\1/g'`/merge
|
||||
fi
|
||||
# Not specified in trigger, use shared copy
|
||||
if [[ "$OPM_DATA_REVISION" = "master" ]] && [[ ! "$OPM_DATA_ROOT_PREDEFINED" = "" ]]
|
||||
then
|
||||
if ! test -d $WORKSPACE/deps/opm-data
|
||||
then
|
||||
cp $OPM_DATA_ROOT_PREDEFINED $WORKSPACE/deps/opm-data -R
|
||||
fi
|
||||
else
|
||||
# Specified in trigger, download it
|
||||
source $WORKSPACE/deps/opm-common/jenkins/build-opm-module.sh
|
||||
clone_module opm-data $OPM_DATA_REVISION
|
||||
fi
|
||||
else
|
||||
if ! test -d $WORKSPACE/deps/opm-data
|
||||
then
|
||||
cp $OPM_DATA_ROOT $WORKSPACE/deps/opm-data -R
|
||||
fi
|
||||
fi
|
||||
OPM_DATA_ROOT=$WORKSPACE/deps/opm-data
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Predefined by environment
|
||||
if test -z "$OPM_TESTS_ROOT"
|
||||
then
|
||||
OPM_TESTS_REVISION="master"
|
||||
if grep -q "opm-tests=" <<< $ghprbCommentBody
|
||||
then
|
||||
OPM_TESTS_REVISION=pull/`echo $ghprbCommentBody | sed -r 's/.*opm-tests=([0-9]+).*/\1/g'`/merge
|
||||
fi
|
||||
# Not specified in trigger, use shared copy
|
||||
if [[ "$OPM_TESTS_REVISION" = "master" ]] && [[ ! "$OPM_TESTS_ROOT_PREDEFINED" = "" ]]
|
||||
then
|
||||
if ! test -d $WORKSPACE/deps/opm-tests
|
||||
then
|
||||
cp $OPM_TESTS_ROOT_PREDEFINED $WORKSPACE/deps/opm-tests -R
|
||||
fi
|
||||
else
|
||||
# We need a full repo checkout
|
||||
cp $OPM_TESTS_ROOT_PREDEFINED $WORKSPACE/deps/opm-tests -R
|
||||
pushd $WORKSPACE/deps/opm-tests
|
||||
# Then we fetch the PR branch
|
||||
git remote add PR https://github.com/OPM/opm-tests
|
||||
git fetch --depth 1 PR $OPM_TESTS_REVISION:branch_to_build
|
||||
git checkout branch_to_build
|
||||
popd
|
||||
fi
|
||||
else
|
||||
if ! test -d $WORKSPACE/deps/opm-tests
|
||||
then
|
||||
cp $OPM_TESTS_ROOT $WORKSPACE/deps/opm-tests -R
|
||||
fi
|
||||
fi
|
||||
OPM_TESTS_ROOT=$WORKSPACE/deps/opm-tests
|
||||
58
jenkins/update-opm-data.sh
Executable file
58
jenkins/update-opm-data.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
MAIN_REPO=$1 # The repo the update was triggered from
|
||||
|
||||
source $WORKSPACE/deps/opm-common/jenkins/build-opm-module.sh
|
||||
|
||||
declare -a upstreams # Everything is considered an upstream to aid code reuse
|
||||
upstreams=(ert
|
||||
opm-common
|
||||
opm-parser
|
||||
opm-output
|
||||
opm-material
|
||||
opm-grid
|
||||
opm-core
|
||||
ewoms
|
||||
opm-simulators
|
||||
opm-upscaling
|
||||
)
|
||||
|
||||
declare -A upstreamRev
|
||||
upstreamRev[ert]=master
|
||||
upstreamRev[opm-common]=master
|
||||
upstreamRev[opm-parser]=master
|
||||
upstreamRev[opm-material]=master
|
||||
upstreamRev[opm-core]=master
|
||||
upstreamRev[opm-grid]=master
|
||||
upstreamRev[opm-output]=master
|
||||
upstreamRev[ewoms]=master
|
||||
upstreamRev[opm-simulators]=master
|
||||
upstreamRev[opm-upscaling]=master
|
||||
|
||||
# Setup revision tables
|
||||
parseRevisions
|
||||
upstreamRev[$MAIN_REPO]=$sha1
|
||||
|
||||
# Create branch name
|
||||
BRANCH_NAME="update"
|
||||
for repo in ${upstreams[*]}
|
||||
do
|
||||
if [ "${upstreamRev[$repo]}" != "master" ]
|
||||
then
|
||||
rev=${upstreamRev[$repo]}
|
||||
prnumber=${rev//[!0-9]/}
|
||||
BRANCH_NAME="${BRANCH_NAME}_${repo}_$prnumber"
|
||||
test -n "$REASON" && REASON+=" "
|
||||
REASON+="https://github.com/OPM/$repo/pull/$prnumber\n"
|
||||
fi
|
||||
done
|
||||
|
||||
# Do the commit
|
||||
export REASON
|
||||
export BRANCH_NAME
|
||||
$WORKSPACE/deps/opm-simulators/tests/update_reference_data.sh $OPM_DATA_ROOT
|
||||
|
||||
# Finally open the pull request
|
||||
cd $OPM_DATA_ROOT
|
||||
git remote add jenkins4opm git@github.com:jenkins4opm/opm-data
|
||||
git-open-pull -u jenkins4opm --base-account OPM --base-repo opm-data -r /tmp/cmsg $BRANCH_NAME
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user